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 buglvl, 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('/')
44 log('cache: %r\n' % cache.keys())
48 log('cache trying: %r\n' % pre)
49 c = cache.get(tuple(pre))
54 log('resolving %r from %r\n' % (r, c.fullname()))
56 key = tuple(pre + [r])
58 log('saving: %r\n' % (key,))
65 class BupFs(fuse.Fuse):
66 def __init__(self, top, meta=False, verbose=0):
67 fuse.Fuse.__init__(self)
70 self.verbose = verbose
72 def getattr(self, path):
74 log('--getattr(%r)\n' % path)
76 node = cache_get(self.top, path)
78 st.st_mode = node.mode
79 st.st_nlink = node.nlinks()
80 st.st_size = node.size() # Until/unless we store the size in m.
87 st.st_atime = max(0, xstat.fstime_floor_secs(m.atime))
88 st.st_mtime = max(0, xstat.fstime_floor_secs(m.mtime))
89 st.st_ctime = max(0, xstat.fstime_floor_secs(m.ctime))
91 except vfs.NoSuchFile:
94 def readdir(self, path, offset):
96 log('--readdir(%r)\n' % path)
97 node = cache_get(self.top, path)
98 yield fuse.Direntry('.')
99 yield fuse.Direntry('..')
100 for sub in node.subs():
101 yield fuse.Direntry(sub.name)
103 def readlink(self, path):
105 log('--readlink(%r)\n' % path)
106 node = cache_get(self.top, path)
107 return node.readlink()
109 def open(self, path, flags):
111 log('--open(%r)\n' % path)
112 node = cache_get(self.top, path)
113 accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
114 if (flags & accmode) != os.O_RDONLY:
118 def release(self, path, flags):
120 log('--release(%r)\n' % path)
122 def read(self, path, size, offset):
124 log('--read(%r)\n' % path)
125 n = cache_get(self.top, path)
131 if not hasattr(fuse, '__version__'):
132 raise RuntimeError, "your fuse module is too old for fuse.__version__"
133 fuse.fuse_python_api = (0, 2)
137 bup fuse [-d] [-f] <mountpoint>
139 f,foreground run in foreground
140 d,debug run in the foreground and display FUSE debug information
141 o,allow-other allow other users to access the filesystem
142 meta report original metadata for paths when available
143 v,verbose increase log output (can be used more than once)
145 o = options.Options(optspec)
146 (opt, flags, extra) = o.parse(sys.argv[1:])
149 o.fatal("exactly one argument expected")
151 git.check_repo_or_die()
152 top = vfs.RefList(None)
153 f = BupFs(top, meta=opt.meta, verbose=opt.verbose)
154 f.fuse_args.mountpoint = extra[0]
156 f.fuse_args.add('debug')
158 f.fuse_args.setmod('foreground')
159 print f.multithreaded
160 f.multithreaded = False
162 f.fuse_args.add('allow_other')