commit abbbb1a956de73866eca328808cd1cfe3868479d
parent c967acce6fb580505f5946bb0617bb239860251d
Author: Matsuda Kenji <info@mtkn.jp>
Date: Wed, 15 Nov 2023 15:07:57 +0900
add CreaterFS
Diffstat:
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