]> arthur.barton.de Git - bup.git/blobdiff - cmd/fuse-cmd.py
Add vfs2 and rewrite restore to use it
[bup.git] / cmd / fuse-cmd.py
index 64655d472c4d08233aa0437da5e28c28fdeb8715..66e2b87acdde63142b96a4431b7af0e316b1ab99 100755 (executable)
@@ -1,79 +1,82 @@
-#!/usr/bin/env python
-import sys, os, stat, errno, re, time, tempfile
-from bup import options, git, vfs
-from bup.helpers import *
+#!/bin/sh
+"""": # -*-python-*-
+bup_python="$(dirname "$0")/bup-python" || exit $?
+exec "$bup_python" "$0" ${1+"$@"}
+"""
+# end of bup preamble
+
+import sys, os, errno
+
+from bup import options, git, vfs, xstat
+from bup.helpers import buglvl, log
+
 try:
     import fuse
 except ImportError:
-    log('bup: error: The python "fuse" module is missing.\n' +
-        'To use bup fuse, first install the python-fuse package.\n')
+    log('error: cannot find the python "fuse" module; please install it\n')
     sys.exit(1)
 
 
-class Stat(fuse.Stat):
-    def __init__(self):
-        self.st_mode = 0
-        self.st_ino = 0
-        self.st_dev = 0
-        self.st_nlink = 0
-        self.st_uid = 0
-        self.st_gid = 0
-        self.st_size = 0
-        self.st_atime = 0
-        self.st_mtime = 0
-        self.st_ctime = 0
-        self.st_blocks = 0
-        self.st_blksize = 0
-        self.st_rdev = 0
-
-
 cache = {}
 def cache_get(top, path):
     parts = path.split('/')
     cache[('',)] = top
     c = None
     max = len(parts)
-    #log('cache: %r\n' % cache.keys())
+    if buglvl >= 1:
+        log('cache: %r\n' % cache.keys())
     for i in range(max):
         pre = parts[:max-i]
-        #log('cache trying: %r\n' % pre)
+        if buglvl >= 1:
+            log('cache trying: %r\n' % pre)
         c = cache.get(tuple(pre))
         if c:
             rest = parts[max-i:]
             for r in rest:
-                #log('resolving %r from %r\n' % (r, c.fullname()))
+                if buglvl >= 1:
+                    log('resolving %r from %r\n' % (r, c.fullname()))
                 c = c.lresolve(r)
                 key = tuple(pre + [r])
-                #log('saving: %r\n' % (key,))
+                if buglvl >= 1:
+                    log('saving: %r\n' % (key,))
                 cache[key] = c
             break
     assert(c)
     return c
-        
-    
+
 
 class BupFs(fuse.Fuse):
-    def __init__(self, top):
+    def __init__(self, top, meta=False, verbose=0):
         fuse.Fuse.__init__(self)
         self.top = top
+        self.meta = meta
+        self.verbose = verbose
     
     def getattr(self, path):
-        log('--getattr(%r)\n' % path)
+        if self.verbose > 0:
+            log('--getattr(%r)\n' % path)
         try:
             node = cache_get(self.top, path)
-            st = Stat()
-            st.st_mode = node.mode
-            st.st_nlink = node.nlinks()
-            st.st_size = node.size()
-            st.st_mtime = node.mtime
-            st.st_ctime = node.ctime
-            st.st_atime = node.atime
+            st = fuse.Stat(st_mode=node.mode,
+                           st_nlink=node.nlinks(),
+                           # Until/unless we store the size in m.
+                           st_size=node.size())
+            if self.meta:
+                m = node.metadata()
+                if m:
+                    st.st_mode = m.mode
+                    st.st_uid = m.uid
+                    st.st_gid = m.gid
+                    st.st_atime = max(0, xstat.fstime_floor_secs(m.atime))
+                    st.st_mtime = max(0, xstat.fstime_floor_secs(m.mtime))
+                    st.st_ctime = max(0, xstat.fstime_floor_secs(m.ctime))
             return st
         except vfs.NoSuchFile:
             return -errno.ENOENT
 
     def readdir(self, path, offset):
-        log('--readdir(%r)\n' % path)
+        if self.verbose > 0:
+            log('--readdir(%r)\n' % path)
         node = cache_get(self.top, path)
         yield fuse.Direntry('.')
         yield fuse.Direntry('..')
@@ -81,12 +84,14 @@ class BupFs(fuse.Fuse):
             yield fuse.Direntry(sub.name)
 
     def readlink(self, path):
-        log('--readlink(%r)\n' % path)
+        if self.verbose > 0:
+            log('--readlink(%r)\n' % path)
         node = cache_get(self.top, path)
         return node.readlink()
 
     def open(self, path, flags):
-        log('--open(%r)\n' % path)
+        if self.verbose > 0:
+            log('--open(%r)\n' % path)
         node = cache_get(self.top, path)
         accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
         if (flags & accmode) != os.O_RDONLY:
@@ -94,10 +99,12 @@ class BupFs(fuse.Fuse):
         node.open()
 
     def release(self, path, flags):
-        log('--release(%r)\n' % path)
+        if self.verbose > 0:
+            log('--release(%r)\n' % path)
 
     def read(self, path, size, offset):
-        log('--read(%r)\n' % path)
+        if self.verbose > 0:
+            log('--read(%r)\n' % path)
         n = cache_get(self.top, path)
         o = n.open()
         o.seek(offset)
@@ -112,10 +119,13 @@ fuse.fuse_python_api = (0, 2)
 optspec = """
 bup fuse [-d] [-f] <mountpoint>
 --
-d,debug   increase debug level
 f,foreground  run in foreground
+d,debug       run in the foreground and display FUSE debug information
+o,allow-other allow other users to access the filesystem
+meta          report original metadata for paths when available
+v,verbose     increase log output (can be used more than once)
 """
-o = options.Options('bup fuse', optspec)
+o = options.Options(optspec)
 (opt, flags, extra) = o.parse(sys.argv[1:])
 
 if len(extra) != 1:
@@ -123,7 +133,7 @@ if len(extra) != 1:
 
 git.check_repo_or_die()
 top = vfs.RefList(None)
-f = BupFs(top)
+f = BupFs(top, meta=opt.meta, verbose=opt.verbose)
 f.fuse_args.mountpoint = extra[0]
 if opt.debug:
     f.fuse_args.add('debug')
@@ -131,6 +141,7 @@ if opt.foreground:
     f.fuse_args.setmod('foreground')
 print f.multithreaded
 f.multithreaded = False
-f.fuse_args.add('allow_other')
+if opt.allow_other:
+    f.fuse_args.add('allow_other')
 
 f.main()