diff --git a/src/examples/loopback.py b/src/examples/loopback.py new file mode 100644 index 0000000..9f5248c --- /dev/null +++ b/src/examples/loopback.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +from __future__ import print_function, absolute_import, division + +import logging +import os + +from errno import EACCES +from os.path import realpath +from threading import Lock + +from refuse.high import FUSE, FuseOSError, Operations, LoggingMixIn + +def no_op(self, *args, **kwargs): + pass # NOOP + +class Loopback(LoggingMixIn, Operations): + def __init__(self, root): + self.root = realpath(root) + self.rwlock = Lock() + + def __call__(self, op, path, *args): + return super(Loopback, self).__call__(op, self.root + path, *args) + + def access(self, path, mode): + if not os.access(path, mode): + raise FuseOSError(EACCES) + + chmod = os.chmod + try: + chown = os.chown + except AttributeError: + # Probably Windows + chown = no_op + + def create(self, path, mode): + return os.open(path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, mode) + + def flush(self, path, fh): + return os.fsync(fh) + + def fsync(self, path, datasync, fh): + if datasync != 0: + return os.fdatasync(fh) + else: + return os.fsync(fh) + + def getattr(self, path, fh=None): + st = os.lstat(path) + return dict((key, getattr(st, key)) for key in ( + 'st_atime', 'st_ctime', 'st_gid', 'st_mode', 'st_mtime', + 'st_nlink', 'st_size', 'st_uid')) + + getxattr = None + + def link(self, target, source): + return os.link(self.root + source, target) + + listxattr = None + mkdir = os.mkdir + try: + mknod = os.mknod + except AttributeError: + # Probably Windows + mknod = no_op + open = os.open + + def read(self, path, size, offset, fh): + with self.rwlock: + os.lseek(fh, offset, 0) + return os.read(fh, size) + + def readdir(self, path, fh): + return ['.', '..'] + os.listdir(path) + + readlink = os.readlink + + def release(self, path, fh): + return os.close(fh) + + def rename(self, old, new): + return os.rename(old, self.root + new) + + rmdir = os.rmdir + + def statfs(self, path): + try: + stv = os.statvfs(path) + return dict((key, getattr(stv, key)) for key in ( + 'f_bavail', 'f_bfree', 'f_blocks', 'f_bsize', 'f_favail', + 'f_ffree', 'f_files', 'f_flag', 'f_frsize', 'f_namemax')) + except AttributeError: + # Windows, sigh... + return dict((key, 0) for key in ( + 'f_bavail', 'f_bfree', 'f_blocks', 'f_bsize', 'f_favail', + 'f_ffree', 'f_files', 'f_flag', 'f_frsize', 'f_namemax')) + + def symlink(self, target, source): + return os.symlink(source, target) + + def truncate(self, path, length, fh=None): + with open(path, 'r+') as f: + f.truncate(length) + + unlink = os.unlink + utimens = os.utime + + def write(self, path, data, offset, fh): + with self.rwlock: + os.lseek(fh, offset, 0) + return os.write(fh, data) + + +if __name__ == '__main__': + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('root') + parser.add_argument('mount') + args = parser.parse_args() + + logging.basicConfig(level=logging.DEBUG) + fuse = FUSE( + Loopback(args.root), args.mount, foreground=True, allow_other=True)