commit 58b13a91f04f113dc47ac97a78a1331a3bc7a760
parent 8303c2b714afbea1393c4934e4bf60a80b2b4cdc
Author: Matsuda Kenji <info@mtkn.jp>
Date: Fri, 28 Jul 2023 11:10:48 +0900
add walk message
Diffstat:
| M | fcall.go | | | 113 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- |
| M | fid.go | | | 7 | +++++++ |
| M | file.go | | | 2 | +- |
| M | server.go | | | 39 | ++++++++++++++++++++++++++++----------- |
4 files changed, 146 insertions(+), 15 deletions(-)
diff --git a/fcall.go b/fcall.go
@@ -272,6 +272,113 @@ func (msg RError) String() string {
return fmt.Sprintf("Rerror tag %d ename %v", msg.Tag(), msg.EName())
}
+type TWalk struct {
+ size uint32
+ tag uint16
+ fid uint32
+ newFid uint32
+ wname []string
+}
+
+func newTWalk(buf []byte) *TWalk {
+ msg := new(TWalk)
+ msg.size = gbit32(buf[0:4])
+ msg.tag = gbit16(buf[5:7])
+ msg.fid = gbit32(buf[7:11])
+ msg.newFid = gbit32(buf[11:15])
+ nwname := gbit16(buf[15:17])
+ msg.wname = make([]string, nwname)
+ cur := 17
+ for i := 0; i < int(nwname); i++ {
+ size := int(gbit16(buf[cur : cur+2]))
+ cur += 2
+ msg.wname = append(msg.wname, string(buf[cur:cur+size]))
+ cur += size
+ }
+ return msg
+}
+
+func (msg *TWalk) Size() uint32 { return msg.size }
+func (msg *TWalk) Type() MsgType { return Twalk }
+func (msg *TWalk) Tag() uint16 { return msg.tag }
+func (msg *TWalk) Fid() uint32 { return msg.fid }
+func (msg *TWalk) NewFid() uint32 { return msg.newFid }
+func (msg *TWalk) NWName() uint16 { return uint16(len(msg.wname)) }
+func (msg *TWalk) WName() []string { return msg.wname }
+func (msg *TWalk) conv2M() []byte {
+ cur := 0
+ buf := make([]byte, msg.Size())
+ pbit32(buf[cur:cur+4], msg.Size())
+ cur += 4
+ buf[cur] = uint8(Twalk)
+ cur += 1
+ pbit16(buf[cur:cur+2], msg.Tag())
+ cur += 2
+ pbit32(buf[cur:cur+4], msg.Fid())
+ cur += 4
+ pbit32(buf[cur:cur+4], msg.NewFid())
+ cur += 4
+ nwname := msg.NWName()
+ pbit16(buf[cur:cur+2], nwname)
+ cur += 2
+ for _, wname := range msg.WName() {
+ pbit16(buf[cur:cur+2], uint16(len(wname)))
+ cur += 2
+ for i := 0; i < len(wname); i++ {
+ buf[cur+i] = wname[i]
+ }
+ cur += len(wname)
+ }
+ return buf
+}
+
+func (msg *TWalk) String() string {
+ s := fmt.Sprintf("Twalk tag %d fid %d newfid %d nwname %d",
+ msg.Tag(), msg.Fid(), msg.NewFid(), msg.NWName())
+ for i, wname := range msg.WName() {
+ s += fmt.Sprintf(" %d:%s", i, wname)
+ }
+ return s
+}
+
+type RWalk struct {
+ tag uint16
+ qid []*Qid
+}
+
+func (msg *RWalk) Size() uint32 {
+ return uint32(4 + 1 + 2 + 2 + len(msg.Qid())*13)
+}
+func (msg *RWalk) Type() MsgType { return Rwalk }
+func (msg *RWalk) Tag() uint16 { return msg.tag }
+func (msg *RWalk) Qid() []*Qid { return msg.qid }
+func (msg *RWalk) conv2M() []byte {
+ cur := 0
+ buf := make([]byte, msg.Size())
+ pbit32(buf[cur:cur+4], msg.Size())
+ cur += 4
+ buf[cur] = uint8(msg.Type())
+ cur += 1
+ pbit16(buf[cur:cur+2], msg.Tag())
+ cur += 2
+ pbit16(buf[cur:cur+2], uint16(len(msg.Qid())))
+ cur += 2
+ for _, qid := range msg.Qid() {
+ for i, bit := range qid.conv2M() {
+ buf[cur+i] = bit
+ }
+ cur += 13
+ }
+ return buf
+}
+func (msg *RWalk) String() string {
+ s := fmt.Sprintf("Rwalk tag %d nwqid %d", msg.Tag(), len(msg.Qid()))
+ for i, q := range msg.Qid() {
+ s += fmt.Sprintf(" %d:%v", i, q)
+ }
+ return s
+}
+
type TStat struct {
size uint32
tag uint16
@@ -307,9 +414,9 @@ type RStat struct {
stat *stat
}
-func (msg *RStat) Size() uint32 { return uint32(4 + 1 + 2 + 2 + 2 + msg.stat.size()) } // TODO: collect ?
-func (msg *RStat) Type() MsgType { return Rstat }
-func (msg *RStat) Tag() uint16 { return msg.tag }
+func (msg *RStat) Size() uint32 { return uint32(4 + 1 + 2 + 2 + 2 + msg.stat.size()) } // TODO: collect ?
+func (msg *RStat) Type() MsgType { return Rstat }
+func (msg *RStat) Tag() uint16 { return msg.tag }
func (msg *RStat) conv2M() []byte {
buf := make([]byte, msg.Size())
pbit32(buf[0:4], msg.Size())
diff --git a/fid.go b/fid.go
@@ -76,6 +76,13 @@ func (q *Qid) Vers() uint32 { return q.vers }
func (q *Qid) SetVers(v uint32) { q.vers = v }
func (q *Qid) Path() uint64 { return q.path }
func (q *Qid) SetPath(p uint64) { q.path = p }
+func (q *Qid) conv2M() []byte {
+ buf := make([]byte, 13)
+ buf[0] = uint8(q.t)
+ pbit32(buf[1:5], q.vers)
+ pbit64(buf[5:13], q.path)
+ return buf
+}
func (q *Qid) String() string {
return fmt.Sprintf("(%016d %d %s)", q.Path(), q.Vers(), q.typeStr())
}
diff --git a/file.go b/file.go
@@ -78,7 +78,7 @@ func (s *stat) conv2M() []byte {
}
func (s *stat) String() string {
- return fmt.Sprintf("'%s' '%s' '%s' '%s' q %v m %012o at %d mt %d l %d t %d d %d",
+ return fmt.Sprintf("'%s' '%s' '%s' '%s' q %v m %#o at %d mt %d l %d t %d d %d",
s.name, s.uid, s.gid, s.muid, s.qid, uint32(s.mode),
s.aTime.Unix(), s.mTime.Unix(), s.length, s.t, s.dev)
}
diff --git a/server.go b/server.go
@@ -53,10 +53,12 @@ func (s *Server) getReq() (*Req, error) {
return &r, fmt.Errorf("unknown message type %d", t)
case Tversion:
r.ifcall = newTVersion(buf)
- case Tattach:
- r.ifcall = TAttach(buf)
case Tauth:
r.ifcall = TAuth(buf)
+ case Tattach:
+ r.ifcall = TAttach(buf)
+ case Twalk:
+ r.ifcall = newTWalk(buf)
case Tstat:
r.ifcall = newTStat(buf)
}
@@ -146,6 +148,26 @@ func sAttach(s *Server, r *Req) {
func rAttach(r *Req, err error) {}
+func sWalk(s *Server, r *Req) {
+ // TODO: wip
+ ofcall := &RWalk{
+ tag: r.ifcall.Tag(),
+ }
+ r.ofcall = ofcall
+ respond(r, nil)
+}
+
+func rWalk(r *Req, err error) {}
+
+func rError(r *Req, err error) {
+ size := uint32(4 + 1 + 2 + 2 + len(err.Error()))
+ ofcall := RError(make([]byte, size))
+ ofcall.SetSize(size)
+ ofcall.SetType(Rerror)
+ ofcall.SetEName(err)
+ r.ofcall = ofcall
+}
+
func sStat(s *Server, r *Req) {
ifcall, ok := r.ifcall.(*TStat)
if !ok {
@@ -175,15 +197,6 @@ func sStat(s *Server, r *Req) {
func rStat(r *Req, err error) {}
-func rError(r *Req, err error) {
- size := uint32(4 + 1 + 2 + 2 + len(err.Error()))
- ofcall := RError(make([]byte, size))
- ofcall.SetSize(size)
- ofcall.SetType(Rerror)
- ofcall.SetEName(err)
- r.ofcall = ofcall
-}
-
func (s *Server) Serve() {
for {
r, err := s.getReq()
@@ -205,6 +218,8 @@ func (s *Server) Serve() {
sAuth(s, r)
case TAttach:
sAttach(s, r)
+ case *TWalk:
+ sWalk(s, r)
case *TStat:
sStat(s, r)
}
@@ -228,6 +243,8 @@ func respond(r *Req, err error) {
rAuth(r, err)
case RAttach:
rAttach(r, err)
+ case *RWalk:
+ rWalk(r, err)
case *RStat:
rStat(r, err)
}