lib9p

Go 9P library.
Log | Files | Refs

commit d56d187be5ac61be68b72c82192bd93a5546b082
parent d9c8ccc2a1b6fbc98ff1d934e98c73662411c036
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sat, 15 Jul 2023 09:51:14 +0900

implement version

Diffstat:
Mcmd/disk.go | 53+++++++++++++++++++++++++++++++++++++----------------
Mserver.go | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 96 insertions(+), 20 deletions(-)

diff --git a/cmd/disk.go b/cmd/disk.go @@ -2,30 +2,52 @@ package main import ( + "flag" "fmt" "io/fs" + "log" + "net" "os" - "strings" - // "lib9p" + + "lib9p" ) +var dFlag = flag.Bool("D", false, "Prints chatty message to the stderr.") + func main() { - if len(os.Args) != 2 { - fmt.Fprintf(os.Stderr, "usage: %s root\n", os.Args[0]) + flag.Parse() + if *dFlag { + lib9p.Chatty() + } + + if flag.NArg() != 1 { + fmt.Fprintf(os.Stderr, "usage: %s [-D] <root>\n", os.Args[0]) os.Exit(1) } - disk := os.DirFS(os.Args[1]) - fs.WalkDir(disk, ".", walkTo("cmd/disk.go")) -} + listener, err := net.Listen("tcp", "127.0.0.1:5640") + if err != nil { + log.Fatalf("listen tcp: %v", err) + } -func walkTo(wpath string) fs.WalkDirFunc { - return func(path string, d fs.DirEntry, err error) error { - fmt.Println("walk:", path) - if path == "." || strings.HasPrefix(wpath, path) { - return nil - } else { - return fs.SkipDir + for { + conn, err := listener.Accept() + if err != nil { + log.Printf("accept connection: %v", err) + continue } + disk := os.DirFS(os.Args[1]) + go handle(conn, disk) } -} -\ No newline at end of file +} + +func handle(conn net.Conn, disk fs.FS) { + srv := &lib9p.Srv{ + disk, + 8 * 1024, + conn, + conn, + } + + lib9p.Serve(srv) +} diff --git a/server.go b/server.go @@ -6,13 +6,18 @@ import ( "io/fs" "log" "os" + "strings" ) var chatty9P = false +func Chatty() { + chatty9P = true +} + type Srv struct { - FS fs.FS - MsgSize uint32 + FS fs.FS + MSize uint32 io.Reader io.Writer } @@ -43,7 +48,39 @@ func getReq(s *Srv) (*Req, error) { return &r, nil } -func srv(s *Srv) { +func sVersion(s *Srv, r *Req) { + ifcall, ok := r.ifcall.(TVersion) + if !ok { + panic("not TVersion") + } + version := ifcall.Version() + if ok := strings.HasPrefix(version, "9P2000"); !ok { + version = "unknown" + } else { + version = "9P2000" + } + msize := ifcall.MSize() + if msize < s.MSize { + s.MSize = msize + } else { + msize = s.MSize + } + + size := uint32(4 + 1 + 2 + 4 + 2 + len(version)) + ofcall := RVersion(make([]byte, size)) + ofcall.SetSize(size) + ofcall.SetType(Rversion) + ofcall.SetTag(ifcall.Tag()) + ofcall.SetMSize(msize) + ofcall.SetVersion(version) + + r.ofcall = ofcall + respond(r, nil) +} + +func rVersion(r *Req, err error) {} + +func Serve(s *Srv) { for { r, err := getReq(s) if err != nil { @@ -53,7 +90,24 @@ func srv(s *Srv) { switch r.ifcall.Type() { default: log.Print("unknown message type") - continue + case Tversion: + sVersion(s, r) } } } + +func respond(r *Req, err error) { + switch ofcall := r.ofcall.(type) { + default: + // TODO: Respond with Rerror. + log.Fatalf("unknown message type: %v", ofcall) + case RVersion: + rVersion(r, err) + } + + if chatty9P { + fmt.Fprintf(os.Stderr, "--> %s\n", r.ofcall) + } + r.srv.Write(r.ofcall.conv2M()) + +} +\ No newline at end of file