diff options
Diffstat (limited to 'internal/fusefrontend_reverse/node.go')
-rw-r--r-- | internal/fusefrontend_reverse/node.go | 59 |
1 files changed, 53 insertions, 6 deletions
diff --git a/internal/fusefrontend_reverse/node.go b/internal/fusefrontend_reverse/node.go index 8af7bed..0b2df12 100644 --- a/internal/fusefrontend_reverse/node.go +++ b/internal/fusefrontend_reverse/node.go @@ -9,6 +9,8 @@ import ( "github.com/hanwen/go-fuse/v2/fs" "github.com/hanwen/go-fuse/v2/fuse" + "github.com/rfjakob/gocryptfs/internal/configfile" + "github.com/rfjakob/gocryptfs/internal/pathiv" "github.com/rfjakob/gocryptfs/internal/syscallcompat" ) @@ -19,13 +21,56 @@ type Node struct { } // Lookup - FUSE call for discovering a file. -// TODO handle virtual files func (n *Node) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (ch *fs.Inode, errno syscall.Errno) { - dirfd, pName, errno := n.prepareAtSyscall(name) - if errno != 0 { + dirfd := int(-1) + pName := "" + t := n.lookupFileType(name) + // gocryptfs.conf + if t == typeConfig { + var err error + rn := n.rootNode() + dirfd, err = syscallcompat.OpenDirNofollow(rn.args.Cipherdir, "") + if err != nil { + errno = fs.ToErrno(err) + return + } + defer syscall.Close(dirfd) + pName = configfile.ConfReverseName + } else if t == typeDiriv { + // gocryptfs.diriv + dirfd, pName, errno = n.prepareAtSyscall("") + if errno != 0 { + return + } + defer syscall.Close(dirfd) + st, err := syscallcompat.Fstatat2(dirfd, pName, unix.AT_SYMLINK_NOFOLLOW) + if err != nil { + errno = fs.ToErrno(err) + return + } + content := pathiv.Derive(n.Path(), pathiv.PurposeDirIV) + var vf *virtualFile + vf, errno = n.newVirtualFile(content, st, inoTagDirIV) + if errno != 0 { + return nil, errno + } + out.Attr = vf.attr + // Create child node + id := fs.StableAttr{Mode: uint32(vf.attr.Mode), Gen: 1, Ino: vf.attr.Ino} + ch = n.NewInode(ctx, vf, id) return + } else if t == typeName { + // gocryptfs.longname.*.name + + // TODO + } else if t == typeReal { + // real file + dirfd, pName, errno = n.prepareAtSyscall(name) + if errno != 0 { + return + } + defer syscall.Close(dirfd) } - defer syscall.Close(dirfd) // Get device number and inode number into `st` st, err := syscallcompat.Fstatat2(dirfd, pName, unix.AT_SYMLINK_NOFOLLOW) @@ -36,8 +81,10 @@ func (n *Node) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (ch // Create new inode and fill `out` ch = n.newChild(ctx, st, out) - // Translate ciphertext size in `out.Attr.Size` to plaintext size - n.translateSize(dirfd, pName, &out.Attr) + if t == typeReal { + // Translate ciphertext size in `out.Attr.Size` to plaintext size + n.translateSize(dirfd, pName, &out.Attr) + } return ch, 0 } |