From b321eed99f512dd076758f62607d5c3e9ee6587d Mon Sep 17 00:00:00 2001 From: Ollie Agent Date: Sun, 16 Aug 2026 19:00:48 +0200 Subject: [PATCH] use 9fans client directly --- client/client.go | 198 ------------------------ cmd/olliesrv/internal/agent/agent.go | 32 +++- cmd/olliesrv/internal/agent/commands.go | 40 ++++- cmd/toolsrv/main.go | 24 ++- kde/lib9p/lib9p.go | 173 +++++++++++++++++++-- 5 files changed, 246 insertions(+), 221 deletions(-) delete mode 100644 client/client.go diff --git a/client/client.go b/client/client.go deleted file mode 100644 index da2c194..0000000 --- a/client/client.go +++ /dev/null @@ -1,198 +0,0 @@ -package client - -import ( - "fmt" - "io" - "os" - "strings" - - "9fans.net/go/plan9" - p9client "9fans.net/go/plan9/client" -) - -// Fsys is an attached 9P filesystem handle. -type Fsys struct { - fsys *p9client.Fsys -} - -// Dial connects to the 9P server at the given address and attaches with the -// specified user identity and attach name. Address format: "unix!/path" or -// "/path" for unix sockets, "tcp!host:port" or "host:port" for TCP. -func Dial(address, user, aname string) (*Fsys, error) { - network := "unix" - dialAddr := address - if strings.HasPrefix(address, "tcp!") { - network = "tcp" - dialAddr = strings.TrimPrefix(address, "tcp!") - } else if strings.HasPrefix(address, "unix!") { - dialAddr = strings.TrimPrefix(address, "unix!") - } else if strings.Contains(address, ":") && !strings.HasPrefix(address, "/") { - network = "tcp" - } - conn, err := p9client.Dial(network, dialAddr) - if err != nil { - return nil, err - } - fsys, err := conn.Attach(nil, user, aname) - if err != nil { - conn.Close() - return nil, err - } - return &Fsys{fsys: fsys}, nil -} - -// DialDefault connects using NAMESPACE env var (falls back to plan9 client -// namespace) and USER/OLLIE_UNAME for identity. -func DialDefault() (*Fsys, error) { - ns := os.Getenv("NAMESPACE") - if ns == "" { - ns = p9client.Namespace() - } - if ns == "" { - return nil, fmt.Errorf("cannot determine namespace; use -a flag or set $NAMESPACE") - } - address := ns + "/ollie" - - user := os.Getenv("USER") - if user == "" { - user = "none" - } - aname := os.Getenv("OLLIE_UNAME") - if aname == "" { - aname = user - } - return Dial(address, user, aname) -} - -// Close releases the filesystem attachment. -func (f *Fsys) Close() error { - return f.fsys.Close() -} - -// Read reads a file's contents. -func (f *Fsys) Read(path string) ([]byte, error) { - fid, err := f.fsys.Open(path, plan9.OREAD) - if err != nil { - return nil, err - } - defer fid.Close() - return io.ReadAll(fid) -} - -// OpenRead opens a file for reading and returns an io.ReadCloser. -// The caller is responsible for closing it. Used for streaming reads -// where data should be consumed incrementally. -func (f *Fsys) OpenRead(path string) (io.ReadCloser, error) { - fid, err := f.fsys.Open(path, plan9.OREAD) - if err != nil { - return nil, err - } - return fid, nil -} - -// Write writes data to a file. Opens OWRITE, writes, then closes (flush). -func (f *Fsys) Write(path string, data []byte) error { - fid, err := f.fsys.Open(path, plan9.OWRITE) - if err != nil { - return err - } - if _, err := fid.Write(data); err != nil { - fid.Close() - return err - } - return fid.Close() -} - -// Rdwr performs write-then-read on a request/response file. -func (f *Fsys) Rdwr(path string, data []byte) ([]byte, error) { - fid, err := f.fsys.Open(path, plan9.ORDWR) - if err != nil { - return nil, err - } - if _, err := fid.Write(data); err != nil { - fid.Close() - return nil, err - } - if _, err := fid.Seek(0, 0); err != nil { - fid.Close() - return nil, err - } - resp, err := io.ReadAll(fid) - fid.Close() - if err != nil { - return nil, err - } - return resp, nil -} - -// Stat returns file metadata. -func (f *Fsys) Stat(path string) (*plan9.Dir, error) { - return f.fsys.Stat(path) -} - -// Ls lists directory contents, returning entry names. -func (f *Fsys) Ls(path string) ([]string, error) { - fid, err := f.fsys.Open(path, plan9.OREAD) - if err != nil { - return nil, err - } - defer fid.Close() - dirs, err := fid.Dirreadall() - if err != nil { - return nil, err - } - names := make([]string, len(dirs)) - for i, d := range dirs { - names[i] = d.Name - } - return names, nil -} - -// Create creates a file with the given permissions. -func (f *Fsys) Create(path string, perm plan9.Perm) error { - fid, err := f.fsys.Create(path, plan9.OWRITE, perm) - if err != nil { - return err - } - return fid.Close() -} - -// Remove removes a file. -func (f *Fsys) Remove(path string) error { - return f.fsys.Remove(path) -} - -// Mkdir creates a directory. -func (f *Fsys) Mkdir(path string) error { - fid, err := f.fsys.Create(path, plan9.OREAD, plan9.DMDIR|0755) - if err != nil { - return err - } - return fid.Close() -} - -// Rename renames a file (Twstat with new name). -func (f *Fsys) Rename(oldPath, newName string) error { - return f.fsys.Wstat(oldPath, &plan9.Dir{Name: newName}) -} - -// ModeString returns a human-readable permission string like "-rw-r--r--". -func ModeString(mode plan9.Perm) string { - var buf [10]byte - if mode&plan9.DMDIR != 0 { - buf[0] = 'd' - } else { - buf[0] = '-' - } - const rwx = "rwx" - for i := 0; i < 3; i++ { - for j := 0; j < 3; j++ { - if mode&(1<