]> arthur.barton.de Git - bup.git/blob - cmd/fuse-cmd.py
fuse-cmd.py: match the style of the import failure message in web-cmd.py.
[bup.git] / cmd / fuse-cmd.py
1 #!/usr/bin/env python
2 import sys, os, errno
3 from bup import options, git, vfs
4 from bup.helpers import *
5 try:
6     import fuse
7 except ImportError:
8     log('error: cannot find the python "fuse" module; please install it\n')
9     sys.exit(1)
10
11
12 class Stat(fuse.Stat):
13     def __init__(self):
14         self.st_mode = 0
15         self.st_ino = 0
16         self.st_dev = 0
17         self.st_nlink = 0
18         self.st_uid = 0
19         self.st_gid = 0
20         self.st_size = 0
21         self.st_atime = 0
22         self.st_mtime = 0
23         self.st_ctime = 0
24         self.st_blocks = 0
25         self.st_blksize = 0
26         self.st_rdev = 0
27
28
29 cache = {}
30 def cache_get(top, path):
31     parts = path.split('/')
32     cache[('',)] = top
33     c = None
34     max = len(parts)
35     #log('cache: %r\n' % cache.keys())
36     for i in range(max):
37         pre = parts[:max-i]
38         #log('cache trying: %r\n' % pre)
39         c = cache.get(tuple(pre))
40         if c:
41             rest = parts[max-i:]
42             for r in rest:
43                 #log('resolving %r from %r\n' % (r, c.fullname()))
44                 c = c.lresolve(r)
45                 key = tuple(pre + [r])
46                 #log('saving: %r\n' % (key,))
47                 cache[key] = c
48             break
49     assert(c)
50     return c
51         
52     
53
54 class BupFs(fuse.Fuse):
55     def __init__(self, top):
56         fuse.Fuse.__init__(self)
57         self.top = top
58     
59     def getattr(self, path):
60         log('--getattr(%r)\n' % path)
61         try:
62             node = cache_get(self.top, path)
63             st = Stat()
64             st.st_mode = node.mode
65             st.st_nlink = node.nlinks()
66             st.st_size = node.size()
67             st.st_mtime = node.mtime
68             st.st_ctime = node.ctime
69             st.st_atime = node.atime
70             return st
71         except vfs.NoSuchFile:
72             return -errno.ENOENT
73
74     def readdir(self, path, offset):
75         log('--readdir(%r)\n' % path)
76         node = cache_get(self.top, path)
77         yield fuse.Direntry('.')
78         yield fuse.Direntry('..')
79         for sub in node.subs():
80             yield fuse.Direntry(sub.name)
81
82     def readlink(self, path):
83         log('--readlink(%r)\n' % path)
84         node = cache_get(self.top, path)
85         return node.readlink()
86
87     def open(self, path, flags):
88         log('--open(%r)\n' % path)
89         node = cache_get(self.top, path)
90         accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
91         if (flags & accmode) != os.O_RDONLY:
92             return -errno.EACCES
93         node.open()
94
95     def release(self, path, flags):
96         log('--release(%r)\n' % path)
97
98     def read(self, path, size, offset):
99         log('--read(%r)\n' % path)
100         n = cache_get(self.top, path)
101         o = n.open()
102         o.seek(offset)
103         return o.read(size)
104
105
106 if not hasattr(fuse, '__version__'):
107     raise RuntimeError, "your fuse module is too old for fuse.__version__"
108 fuse.fuse_python_api = (0, 2)
109
110
111 optspec = """
112 bup fuse [-d] [-f] <mountpoint>
113 --
114 d,debug   increase debug level
115 f,foreground  run in foreground
116 o,allow-other allow other users to access the filesystem
117 """
118 o = options.Options(optspec)
119 (opt, flags, extra) = o.parse(sys.argv[1:])
120
121 if len(extra) != 1:
122     o.fatal("exactly one argument expected")
123
124 git.check_repo_or_die()
125 top = vfs.RefList(None)
126 f = BupFs(top)
127 f.fuse_args.mountpoint = extra[0]
128 if opt.debug:
129     f.fuse_args.add('debug')
130 if opt.foreground:
131     f.fuse_args.setmod('foreground')
132 print f.multithreaded
133 f.multithreaded = False
134 if opt.allow_other:
135     f.fuse_args.add('allow_other')
136
137 f.main()