diff --git a/frontend/fs.go b/frontend/fs.go index 4ce3e5c..637d134 100644 --- a/frontend/fs.go +++ b/frontend/fs.go @@ -7,14 +7,20 @@ import ( type FS struct { *cryptfs.FS + backing string } -func New(key [16]byte) *FS { +func New(key [16]byte, b string) *FS { return &FS { FS: cryptfs.NewFS(key), + backing: b, } } func (fs *FS) Root() (fs.Node, error) { - return nil, nil + n := Node{ + backing: "", + parentFS: fs, + } + return n, nil } diff --git a/frontend/node.go b/frontend/node.go new file mode 100644 index 0000000..53ffb26 --- /dev/null +++ b/frontend/node.go @@ -0,0 +1,79 @@ +package frontend + +import ( + "fmt" + "os" + "time" + "syscall" + "io/ioutil" + "path" + + "golang.org/x/net/context" + + //"github.com/rfjakob/gocryptfs/cryptfs" + "bazil.org/fuse" + "bazil.org/fuse/fs" +) + + +type Node struct { + fs.NodeRef + backing string + parentFS *FS +} + +func StatToAttr(s *syscall.Stat_t, a *fuse.Attr) { + a.Inode = s.Ino + a.Size = uint64(s.Size) + a.Blocks = uint64(s.Blocks) + a.Atime = time.Unix(s.Atim.Sec, s.Atim.Nsec) + a.Mtime = time.Unix(s.Mtim.Sec, s.Mtim.Nsec) + a.Ctime = time.Unix(s.Ctim.Sec, s.Ctim.Nsec) + a.Mode = os.FileMode(s.Mode) | os.ModeDir + a.Nlink = uint32(s.Nlink) + a.Uid = uint32(s.Uid) + a.Gid = uint32(s.Gid) + a.Rdev = uint32(s.Rdev) +} + +func (n Node) Attr(ctx context.Context, attr *fuse.Attr) error { + var err error + var st syscall.Stat_t + if n.backing == "" { + // When GetAttr is called for the toplevel directory, we always want + // to look through symlinks. + fmt.Printf("Attr %s\n", n.parentFS.backing) + //err = syscall.Stat(n.parentFS.backing, &st) + err = syscall.Stat("/", &st) + } else { + fmt.Printf("Attr %s\n", path.Join(n.parentFS.backing, n.backing)) + p := path.Join(n.parentFS.backing, n.backing) + err = syscall.Lstat(p, &st) + } + if err != nil { + return err + } + StatToAttr(&st, attr) + return nil +} + +func (n *Node) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { + entries, err := ioutil.ReadDir(n.backing) + if err != nil { + return nil, err + } + var fuseEntries []fuse.Dirent + for _, e := range entries { + var d fuse.Dirent + d.Name = e.Name() + fuseEntries = append(fuseEntries, d) + } + return fuseEntries, err +} + +func (n *Node) Lookup(ctx context.Context, name string) (fs.Node, error) { + if name == "hello" { + return Node{}, nil + } + return nil, fuse.ENOENT +} diff --git a/main.go b/main.go index 1183fec..a3159f3 100644 --- a/main.go +++ b/main.go @@ -18,11 +18,11 @@ import ( ) // debug flag enables logging of debug messages to stderr. -var debug = flag.Bool("debug", false, "enable debug log messages to stderr") +var debug = flag.Bool("debug", true, "enable debug log messages to stderr") func usage() { fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) - fmt.Fprintf(os.Stderr, " %s MOUNTPOINT\n", os.Args[0]) + fmt.Fprintf(os.Stderr, " %s BACKING MOUNTPOINT\n", os.Args[0]) flag.PrintDefaults() } @@ -34,18 +34,19 @@ func main() { flag.Usage = usage flag.Parse() - if flag.NArg() != 1 { + if flag.NArg() != 2 { usage() os.Exit(2) } - mountpoint := flag.Arg(0) + backing := flag.Arg(0) + mountpoint := flag.Arg(1) c, err := fuse.Mount( mountpoint, - fuse.FSName("memfs"), - fuse.Subtype("memfs"), + fuse.FSName("gocryptfs"), + fuse.Subtype("gocryptfs"), fuse.LocalVolume(), - fuse.VolumeName("Memory FS"), + fuse.VolumeName("gocryptfs"), ) if err != nil { log.Fatal(err) @@ -59,7 +60,7 @@ func main() { srv := fs.New(c, cfg) var key [16]byte - filesys := frontend.New(key) + filesys := frontend.New(key, backing) if err := srv.Serve(filesys); err != nil { log.Fatal(err)