summaryrefslogtreecommitdiffstats
path: root/back/cmd/authfs/rootdir.go
diff options
context:
space:
mode:
Diffstat (limited to 'back/cmd/authfs/rootdir.go')
-rw-r--r--back/cmd/authfs/rootdir.go112
1 files changed, 112 insertions, 0 deletions
diff --git a/back/cmd/authfs/rootdir.go b/back/cmd/authfs/rootdir.go
new file mode 100644
index 0000000..870a5a8
--- /dev/null
+++ b/back/cmd/authfs/rootdir.go
@@ -0,0 +1,112 @@
+package main
+
+import (
+ "bytes"
+
+ p9 "github.com/Harvey-OS/ninep/protocol"
+
+ "git.samanthony.xyz/buth/back/qver"
+)
+
+type RootDir struct {
+ *qver.Version
+ *UsersDir
+ *SessionsDir
+}
+
+func NewRootDir(path string) (*RootDir, error) {
+ ver := qver.New()
+ users, err := NewUsersDir(path, ver)
+ if err != nil {
+ ver.Close()
+ return nil, err
+ }
+ sessions := NewSessionsDir(ver)
+ return &RootDir{ver, users, sessions}, nil
+}
+
+func (r *RootDir) Close() {
+ r.Version.Close()
+ r.UsersDir.Close()
+ r.SessionsDir.Close()
+}
+
+func (r *RootDir) Qid() (p9.QID, error) {
+ ver, err := r.Version.Get()
+ if err != nil {
+ return p9.QID{}, err
+ }
+ return p9.QID{
+ Type: p9.QTDIR,
+ Version: ver,
+ Path: rootQidPath,
+ }, nil
+}
+
+func (r *RootDir) Stat() (p9.Dir, error) {
+ qid, err := r.Qid()
+ if err != nil {
+ return p9.Dir{}, err
+ }
+ return p9.Dir{
+ QID: qid,
+ Mode: p9.DMDIR | p9.DMREAD,
+ // TODO: atime, mtime
+ Name: "/",
+ }, nil
+}
+
+func (r *RootDir) Remove() error { return ErrPerm }
+
+func (r *RootDir) Open(mode p9.Mode) error {
+ if mode != p9.OREAD {
+ return ErrPerm
+ }
+ return nil
+}
+
+func (r *RootDir) Read(off p9.Offset, n p9.Count) ([]byte, error) {
+ userInfo, err := r.UsersDir.Stat()
+ if err != nil {
+ return nil, err
+ }
+ sessInfo, err := r.SessionsDir.Stat()
+ if err != nil {
+ return nil, err
+ }
+
+ buf := new(bytes.Buffer)
+ p9.Marshaldir(buf, userInfo)
+ p9.Marshaldir(buf, sessInfo)
+
+ b := buf.Bytes()
+ lenb := uint64(len(b))
+ lo := clamp(uint64(off), 0, lenb)
+ hi := clamp(lo+uint64(n), 0, lenb)
+ return b[lo:hi], nil
+}
+
+func (r *RootDir) Write(off p9.Offset, b []byte) (p9.Count, error) { return 0, ErrPerm }
+
+func (r *RootDir) Create(name string, perm p9.Perm, mode p9.Mode) (File, error) { return nil, ErrPerm }
+
+func (r *RootDir) Walk(name string) (File, error) {
+ switch name {
+ case "users":
+ return r.UsersDir, nil
+ case "sessions":
+ return r.SessionsDir, nil
+ default:
+ return nil, ErrFileNotExist
+ }
+}
+
+func clamp(x, min, max uint64) uint64 {
+ if x < min {
+ x = min
+ }
+ if x > max {
+ x = max
+ }
+ return x
+}