3 bup_python="$(dirname "$0")/bup-python" || exit $?
4 exec "$bup_python" "$0" ${1+"$@"}
10 from bup import options, git, vfs, xstat
11 from bup.helpers import log
16 log('error: cannot find the python "fuse" module; please install it\n')
20 class Stat(fuse.Stat):
38 def cache_get(top, path):
39 parts = path.split('/')
43 #log('cache: %r\n' % cache.keys())
46 #log('cache trying: %r\n' % pre)
47 c = cache.get(tuple(pre))
51 #log('resolving %r from %r\n' % (r, c.fullname()))
53 key = tuple(pre + [r])
54 #log('saving: %r\n' % (key,))
62 class BupFs(fuse.Fuse):
63 def __init__(self, top, meta=False):
64 fuse.Fuse.__init__(self)
68 def getattr(self, path):
69 log('--getattr(%r)\n' % path)
71 node = cache_get(self.top, path)
73 st.st_mode = node.mode
74 st.st_nlink = node.nlinks()
75 st.st_size = node.size() # Until/unless we store the size in m.
82 st.st_atime = max(0, xstat.fstime_floor_secs(m.atime))
83 st.st_mtime = max(0, xstat.fstime_floor_secs(m.mtime))
84 st.st_ctime = max(0, xstat.fstime_floor_secs(m.ctime))
86 except vfs.NoSuchFile:
89 def readdir(self, path, offset):
90 log('--readdir(%r)\n' % path)
91 node = cache_get(self.top, path)
92 yield fuse.Direntry('.')
93 yield fuse.Direntry('..')
94 for sub in node.subs():
95 yield fuse.Direntry(sub.name)
97 def readlink(self, path):
98 log('--readlink(%r)\n' % path)
99 node = cache_get(self.top, path)
100 return node.readlink()
102 def open(self, path, flags):
103 log('--open(%r)\n' % path)
104 node = cache_get(self.top, path)
105 accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
106 if (flags & accmode) != os.O_RDONLY:
110 def release(self, path, flags):
111 log('--release(%r)\n' % path)
113 def read(self, path, size, offset):
114 log('--read(%r)\n' % path)
115 n = cache_get(self.top, path)
121 if not hasattr(fuse, '__version__'):
122 raise RuntimeError, "your fuse module is too old for fuse.__version__"
123 fuse.fuse_python_api = (0, 2)
127 bup fuse [-d] [-f] <mountpoint>
129 d,debug increase debug level
130 f,foreground run in foreground
131 o,allow-other allow other users to access the filesystem
132 meta report original metadata for paths when available
134 o = options.Options(optspec)
135 (opt, flags, extra) = o.parse(sys.argv[1:])
138 o.fatal("exactly one argument expected")
140 git.check_repo_or_die()
141 top = vfs.RefList(None)
142 f = BupFs(top, meta=opt.meta)
143 f.fuse_args.mountpoint = extra[0]
145 f.fuse_args.add('debug')
147 f.fuse_args.setmod('foreground')
148 print f.multithreaded
149 f.multithreaded = False
151 f.fuse_args.add('allow_other')