lib9p

Go 9P library.
Log | Files | Refs

commit 58b13a91f04f113dc47ac97a78a1331a3bc7a760
parent 8303c2b714afbea1393c4934e4bf60a80b2b4cdc
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Fri, 28 Jul 2023 11:10:48 +0900

add walk message

Diffstat:
Mfcall.go | 113++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mfid.go | 7+++++++
Mfile.go | 2+-
Mserver.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) }