def mknod(self, path, mode, rdev): """ Creates a non-directory file (or a device node). mode: Unix file mode flags for the file being created. rdev: Special properties for creation of character or block special devices (I've never gotten this to work). Always 0 for regular files or FIFO buffers. """ # Note: mode & 0770000 gives you the non-permission bits. # Common ones: # S_IFREG: 0100000 (A regular file) # S_IFIFO: 010000 (A fifo buffer, created with mkfifo) # Potential ones (I have never seen them): # Note that these could be made by copying special devices or sockets # or using mknod, but I've never gotten FUSE to pass such a request # along. # S_IFCHR: 020000 (A character special device, created with mknod) # S_IFBLK: 060000 (A block special device, created with mknod) # S_IFSOCK: 0140000 (A socket, created with mkfifo) # Also note: You can use self.GetContext() to get a dictionary # {'uid': ?, 'gid': ?}, which tells you the uid/gid of the user # executing the current syscall. This should be handy when creating # new files and directories, because they should be owned by this # user/group. with ewrap("mknod"): logging.debug("mknod: %s (mode %s, rdev %s)" % (path, oct(mode), rdev)) Xmp.mknod(self, path, mode, rdev)
def mknod(self, path, mode, rdev): """ Creates a non-directory file (or a device node). mode: Unix file mode flags for the file being created. rdev: Special properties for creation of character or block special devices (I've never gotten this to work). Always 0 for regular files or FIFO buffers. """ # Note: mode & 0770000 gives you the non-permission bits. # Common ones: # S_IFREG: 0100000 (A regular file) # S_IFIFO: 010000 (A fifo buffer, created with mkfifo) # Potential ones (I have never seen them): # Note that these could be made by copying special devices or sockets # or using mknod, but I've never gotten FUSE to pass such a request # along. # S_IFCHR: 020000 (A character special device, created with mknod) # S_IFBLK: 060000 (A block special device, created with mknod) # S_IFSOCK: 0140000 (A socket, created with mkfifo) # Also note: You can use self.GetContext() to get a dictionary # {'uid': ?, 'gid': ?}, which tells you the uid/gid of the user # executing the current syscall. This should be handy when creating # new files and directories, because they should be owned by this # user/group. with ewrap("mknod"): logging.debug("mknod: %s (mode %s, rdev %s)" % (path, oct(mode), rdev)) Xmp.mknod(self, path, mode, rdev)
def __init__(self, *args, **kw): Xmp.__init__(self, *args, **kw) # Initialize so we can look for this option even if the user didn't specify it self.rescan = False # Null all the other options so we can correctly handle errors if they are missing self.database = None self.root = None self.useMd5 = False
def link(self, target, name): """ Creates a hard link from name to target. Note that both paths are relative to the mounted file system. Hard-links across systems are not supported. """ with ewrap("link"): logging.debug("link: target %s, name: %s" % (target, name)) Xmp.link(self, target, name)
def link(self, target, name): """ Creates a hard link from name to target. Note that both paths are relative to the mounted file system. Hard-links across systems are not supported. """ with ewrap("link"): logging.debug("link: target %s, name: %s" % (target, name)) Xmp.link(self, target, name)
def __init__(self, *args, **kw): Xmp.__init__(self, *args, **kw) # Initialize so we can look for this option even if the user didn't specify it self.rescan = False # Null all the other options so we can correctly handle errors if they are missing self.database = None self.root = None self.useMd5 = False
def utime(self, path, times): """ Sets the access and modification times on a file. times: (atime, mtime) pair. Both ints, in seconds since epoch. Deprecated in favour of utimens. """ with ewrap("utime"): atime, mtime = times logging.debug("utime: %s (atime %s, mtime %s)" % (path, atime, mtime)) Xmp.utime(self, path, times)
def mkdir(self, path, mode): """ Creates a directory. mode: Unix file mode flags for the directory being created. """ # Note: mode & 0770000 gives you the non-permission bits. # Should be S_IDIR (040000); I guess you can assume this. # Also see note about self.GetContext() in mknod. with ewrap("mkdir"): logging.debug("mkdir: %s (mode %s)" % (path, oct(mode))) Xmp.mkdir(self, path, mode)
def mkdir(self, path, mode): """ Creates a directory. mode: Unix file mode flags for the directory being created. """ # Note: mode & 0770000 gives you the non-permission bits. # Should be S_IDIR (040000); I guess you can assume this. # Also see note about self.GetContext() in mknod. with ewrap("mkdir"): logging.debug("mkdir: %s (mode %s)" % (path, oct(mode))) Xmp.mkdir(self, path, mode)
def utime(self, path, times): """ Sets the access and modification times on a file. times: (atime, mtime) pair. Both ints, in seconds since epoch. Deprecated in favour of utimens. """ with ewrap("utime"): atime, mtime = times logging.debug("utime: %s (atime %s, mtime %s)" % (path, atime, mtime)) Xmp.utime(self, path, times)
def rename(self, old, new): """ Moves a file from old to new. (old and new are both full paths, and may not be in the same directory). Note that both paths are relative to the mounted file system. If the operating system needs to move files across systems, it will manually copy and delete the file, and this method will not be called. """ with ewrap("rename"): logging.debug("rename: target %s, name: %s" % (self.root + old, self.root + new)) Xmp.rename(self, old, new) self.sha1db.updatePath(self.root + old, self.root + new)
def rename(self, old, new): """ Moves a file from old to new. (old and new are both full paths, and may not be in the same directory). Note that both paths are relative to the mounted file system. If the operating system needs to move files across systems, it will manually copy and delete the file, and this method will not be called. """ with ewrap("rename"): logging.debug("rename: target %s, name: %s" % (self.root + old, self.root + new)) Xmp.rename(self, old, new) self.sha1db.updatePath(self.root + old, self.root + new)
def readlink(self, path): """ Get the target of a symlink. Returns a bytestring with the contents of a symlink (its target). May also return an int error code. """ with ewrap("readlink"): logging.debug("readlink: %s" % path) return Xmp.readlink(self, path)
def readlink(self, path): """ Get the target of a symlink. Returns a bytestring with the contents of a symlink (its target). May also return an int error code. """ with ewrap("readlink"): logging.debug("readlink: %s" % path) return Xmp.readlink(self, path)
def symlink(self, target, name): """ Creates a symbolic link from path to target. The 'name' is a regular path like any other method (absolute, but relative to the filesystem root). The 'target' is special - it works just like any symlink target. It may be absolute, in which case it is absolute on the user's system, NOT the mounted filesystem, or it may be relative. It should be treated as an opaque string - the filesystem implementation should not ever need to follow it (that is handled by the OS). Hence, if the operating system creates a link FROM this system TO another system, it will call this method with a target pointing outside the filesystem. If the operating system creates a link FROM some other system TO this system, it will not touch this system at all (symlinks do not depend on the target system unless followed). """ with ewrap("symlink"): logging.debug("symlink: target %s, name: %s" % (target, name)) Xmp.symlink(self, target, name)
def symlink(self, target, name): """ Creates a symbolic link from path to target. The 'name' is a regular path like any other method (absolute, but relative to the filesystem root). The 'target' is special - it works just like any symlink target. It may be absolute, in which case it is absolute on the user's system, NOT the mounted filesystem, or it may be relative. It should be treated as an opaque string - the filesystem implementation should not ever need to follow it (that is handled by the OS). Hence, if the operating system creates a link FROM this system TO another system, it will call this method with a target pointing outside the filesystem. If the operating system creates a link FROM some other system TO this system, it will not touch this system at all (symlinks do not depend on the target system unless followed). """ with ewrap("symlink"): logging.debug("symlink: target %s, name: %s" % (target, name)) Xmp.symlink(self, target, name)
def fsinit(self): """ Will be called after the command line arguments are successfully parsed. It doesn't have to exist or do anything, but as options to the filesystem are not available in __init__, fsinit is more suitable for the mounting logic than __init__. To access the command line passed options and nonoption arguments, use cmdline. The mountpoint is not stored in cmdline. """ with ewrap("fsinit"): logging.debug("Nonoption arguments: " + str(self.cmdline[1])) #self.xyz = self.cmdline[0].xyz #if self.xyz != None: # logging.debug("xyz set to '" + self.xyz + "'") #else: # logging.debug("xyz not set") Xmp.fsinit(self) logging.debug("Filesystem %s mounted" % self.root)
def fsinit(self): """ Will be called after the command line arguments are successfully parsed. It doesn't have to exist or do anything, but as options to the filesystem are not available in __init__, fsinit is more suitable for the mounting logic than __init__. To access the command line passed options and nonoption arguments, use cmdline. The mountpoint is not stored in cmdline. """ with ewrap("fsinit"): logging.debug("Nonoption arguments: " + str(self.cmdline[1])) #self.xyz = self.cmdline[0].xyz #if self.xyz != None: # logging.debug("xyz set to '" + self.xyz + "'") #else: # logging.debug("xyz not set") Xmp.fsinit(self) logging.debug("Filesystem %s mounted" % self.root)
def readdir(self, path, offset): """ Generator function. Produces a directory listing. Yields individual fuse.Direntry objects, one per file in the directory. Should always yield at least "." and "..". Should yield nothing if the file is not a directory or does not exist. (Does not need to raise an error). offset: I don't know what this does, but I think it allows the OS to request starting the listing partway through (which I clearly don't yet support). Seems to always be 0 anyway. """ with ewrap("readdir"): logging.debug("readdir: %s (offset %s)" % (path, offset)) return Xmp.readdir(self, path, offset)
def getattr(self, path): """ Retrieves information about a file (the "stat" of a file). Returns a fuse.Stat object containing details about the file or directory. Returns -errno.ENOENT if the file is not found, or another negative errno code if another error occurs. """ with ewrap("getattr"): if os.path.exists("." + path): logging.debug("getattr: %s" % path) return Xmp.getattr(self, path) else: logging.debug("Skipping getattr for nonexistent path %s" % path) return -ENOENT
def readdir(self, path, offset): """ Generator function. Produces a directory listing. Yields individual fuse.Direntry objects, one per file in the directory. Should always yield at least "." and "..". Should yield nothing if the file is not a directory or does not exist. (Does not need to raise an error). offset: I don't know what this does, but I think it allows the OS to request starting the listing partway through (which I clearly don't yet support). Seems to always be 0 anyway. """ with ewrap("readdir"): logging.debug("readdir: %s (offset %s)" % (path, offset)) return Xmp.readdir(self, path, offset)
def getattr(self, path): """ Retrieves information about a file (the "stat" of a file). Returns a fuse.Stat object containing details about the file or directory. Returns -errno.ENOENT if the file is not found, or another negative errno code if another error occurs. """ with ewrap("getattr"): if os.path.exists("." + path): logging.debug("getattr: %s" % path) return Xmp.getattr(self, path) else: logging.debug("Skipping getattr for nonexistent path %s" % path) return -ENOENT
def statfs(self): """ Should return an object with statvfs attributes (f_bsize, f_frsize...). Eg., the return value of os.statvfs() is such a thing (since py 2.2). If you are not reusing an existing statvfs object, start with fuse.StatVFS(), and define the attributes. To provide usable information (ie., you want sensible df(1) output, you are suggested to specify the following attributes: - f_bsize - preferred size of file blocks, in bytes - f_frsize - fundamental size of file blcoks, in bytes [if you have no idea, use the same as blocksize] - f_blocks - total number of blocks in the filesystem - f_bfree - number of free blocks - f_files - total number of file inodes - f_ffree - nunber of free file inodes """ with ewrap("statfs"): return Xmp.statfs(self)
def statfs(self): """ Should return an object with statvfs attributes (f_bsize, f_frsize...). Eg., the return value of os.statvfs() is such a thing (since py 2.2). If you are not reusing an existing statvfs object, start with fuse.StatVFS(), and define the attributes. To provide usable information (ie., you want sensible df(1) output, you are suggested to specify the following attributes: - f_bsize - preferred size of file blocks, in bytes - f_frsize - fundamental size of file blcoks, in bytes [if you have no idea, use the same as blocksize] - f_blocks - total number of blocks in the filesystem - f_bfree - number of free blocks - f_files - total number of file inodes - f_ffree - nunber of free file inodes """ with ewrap("statfs"): return Xmp.statfs(self)
def unlink(self, path): """Deletes a file.""" with ewrap("unlink"): logging.debug("unlink: %s" % path) Xmp.unlink(self, path) self.sha1db.removeChecksum(self.root + path)
def chmod(self, path, mode): """Changes the mode of a file or directory.""" with ewrap("chmod"): logging.debug("chmod: %s (mode %s)" % (path, oct(mode))) Xmp.chmod(self, path, mode)
def chown(self, path, user, group): """Changes the owner of a file or directory.""" with ewrap("chown"): logging.debug("chown: %s (uid %s, gid %s)" % (path, user, group)) Xmp.chown(self, path, user, group)
def rmdir(self, path): """Deletes a directory.""" with ewrap("rmdir"): logging.debug("rmdir: %s" % path) Xmp.rmdir(self, path)
def unlink(self, path): """Deletes a file.""" with ewrap("unlink"): logging.debug("unlink: %s" % path) Xmp.unlink(self, path) self.sha1db.removeChecksum(self.root + path)
def chown(self, path, user, group): """Changes the owner of a file or directory.""" with ewrap("chown"): logging.debug("chown: %s (uid %s, gid %s)" % (path, user, group)) Xmp.chown(self, path, user, group)
def chmod(self, path, mode): """Changes the mode of a file or directory.""" with ewrap("chmod"): logging.debug("chmod: %s (mode %s)" % (path, oct(mode))) Xmp.chmod(self, path, mode)
def rmdir(self, path): """Deletes a directory.""" with ewrap("rmdir"): logging.debug("rmdir: %s" % path) Xmp.rmdir(self, path)