lib9p

Go 9P library.
Log | Files | Refs | LICENSE

commit abbbb1a956de73866eca328808cd1cfe3868479d
parent c967acce6fb580505f5946bb0617bb239860251d
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Wed, 15 Nov 2023 15:07:57 +0900

add CreaterFS

Diffstat:
Mdiskfs/fs.go | 40++++++++++++++++++++++++++++++++++++++++
Mfs.go | 8++++++++
Mserver.go | 7+++++--
3 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/diskfs/fs.go b/diskfs/fs.go @@ -4,8 +4,10 @@ package diskfs import ( "fmt" + "io/fs" "os" "path/filepath" + "strings" "git.mtkn.jp/lib9p" ) @@ -60,3 +62,40 @@ func (fsys *FS) OpenFile(name string, omode lib9p.OpenMode) (lib9p.File, error) } return &File{fs: fsys, path: name, file: osf}, nil } + +// TODO: check uid +// BUG: check uid. it can be a security hole. +func (fsys *FS) Create(name string, uid string, omode lib9p.OpenMode, perm lib9p.FileMode) (lib9p.File, error) { + paths := append([]string{fsys.rootPath}, strings.Split(name, "/")...) + ospath := filepath.Join(paths...) + var flag int + switch omode&3 { + case lib9p.OREAD, lib9p.OEXEC: + flag = os.O_RDONLY + case lib9p.OWRITE: + flag = os.O_WRONLY + case lib9p.ORDWR: + flag = os.O_RDWR + } + if omode&lib9p.OTRUNC != 0 { + flag |= os.O_TRUNC + } + if omode&lib9p.ORCLOSE != 0 { + return nil, fmt.Errorf("orclose not implemented in os package") + } + flag |= os.O_CREATE + if perm&fs.ModeDir != 0 { + if err := os.Mkdir(ospath, perm); err != nil { + return nil, fmt.Errorf("mkdir: %v", err) + } + } + osfile, err := os.OpenFile(ospath, flag, perm) + if err != nil { + return nil, fmt.Errorf("openfile: %v", err) + } + return &File{ + fs: fsys, + path: name, + file: osfile, + }, nil +} +\ No newline at end of file diff --git a/fs.go b/fs.go @@ -12,6 +12,14 @@ type FS interface { OpenFile(name string, omode OpenMode) (File, error) } +type CreaterFS interface { + FS + // Create creates a file named name. + // It sets the owner of newly created file to the specified uid, + // and file mode to the specified perm. + Create(name string, uid string, mode OpenMode, perm FileMode) (File, error) +} + // getChildren returns the child files in the directory specified by dirpath. func getChildren(fsys FS, dirpath string) ([]File, error) { dir0, err := fsys.OpenFile(dirpath, OREAD) diff --git a/server.go b/server.go @@ -499,7 +499,8 @@ func sCreate(ctx context.Context, s *Server, r *Req) { Respond(ctx, r, ErrPerm) return } - cfdir, ok := r.Fid.File.(CreaterFile) +// cfdir, ok := r.Fid.File.(CreaterFile) + cffs, ok := s.fs.(CreaterFS) if !ok { Respond(ctx, r, ErrOperation) return @@ -511,7 +512,9 @@ func sCreate(ctx context.Context, s *Server, r *Req) { } else { perm &= ^FileMode(0777) | (dirperm & FileMode(0777)) } - file, err := cfdir.Create(ifcall.Name, r.Fid.Uid, ifcall.Mode, perm) + //file, err := cfdir.Create(ifcall.Name, r.Fid.Uid, ifcall.Mode, perm) + cpath := path.Join(r.Fid.path, ifcall.Name) + file, err := cffs.Create(cpath, r.Fid.Uid, ifcall.Mode, perm) if err != nil { Respond(ctx, r, fmt.Errorf("create: %v", err)) return