package ffs import ( "context" "fmt" "os" "syscall" "time" "bazil.org/fuse" "bazil.org/fuse/fs" ) /////////////////////////////////////////////////////////////////////////////////////////////////// // CONSTANTS ////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// const ( DREAMS_DIR_INODE_BASE = 0x2000 DREAMS_DIR_MAX_INODES = 0x1000 ) /////////////////////////////////////////////////////////////////////////////////////////////////// // TYPE: DreamsDir //////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// type DreamsDir struct { _attr fuse.Attr _entries []fuse.Dirent } func NewDreamsDir(inodeBase uint64, rootUID, rootGID uint32) *DreamsDir { now := time.Now() dir := &DreamsDir{ _attr: fuse.Attr{ Inode: inodeBase, Nlink: 1, Mode: os.ModeDir | 0500, Uid: rootUID, Gid: rootGID, Atime: now, Ctime: now, Mtime: now, }, } // add basic entries dir._entries = append( dir._entries, fuse.Dirent{Inode: dir._attr.Inode, Name: ".", Type: fuse.DT_Dir}, fuse.Dirent{Inode: ROOT_INODE, Name: "..", Type: fuse.DT_Dir}, ) return dir } func (d *DreamsDir) GetAttr() *fuse.Attr { return &d._attr } func (d *DreamsDir) Attr(ctx context.Context, a *fuse.Attr) error { *a = d._attr return nil } func (d *DreamsDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { pounce := G_FS._pounce dreams := pounce.Dreams items := make([]fuse.Dirent, len(dreams)+2) items[0] = fuse.Dirent{Inode: d._attr.Inode, Name: ".", Type: fuse.DT_Dir} items[1] = fuse.Dirent{Inode: ROOT_INODE, Name: "..", Type: fuse.DT_Dir} i := 2 for shortURL := range dreams { items[i] = fuse.Dirent{ Inode: uint64(2000 + i), Name: shortURL, Type: fuse.DT_File, } i++ } return items, nil } func (d *DreamsDir) Lookup(ctx context.Context, name string) (fs.Node, error) { if name == "." { return d, nil } dreams := G_FS._pounce.Dreams dream, exists := dreams[name] if !exists { fmt.Printf("[D] DreamsDir().Lookup('%v'): ENOENT\n", name) return nil, syscall.ENOENT } fmt.Printf("[D] DreamsDir().Lookup('%v'): OK\n", name) now := time.Now() return &DreamFile{ Dream: dream, _attr: fuse.Attr{ Inode: 0, Nlink: 1, Mode: 0400, Size: 0, Ctime: now, Atime: now, Mtime: now, Uid: d._attr.Uid, Gid: d._attr.Gid, }, }, nil }