root/trunk/source/pyhesiodfs/pyHesiodFS.py

Revision 142, 4.2 kB (checked in by broder, 16 years ago)

Upstream pyHesiodFS patch to not use Mac-only options on a non-Mac

Line 
1 #!/usr/bin/python2.5
2
3 #    pyHesiodFS:
4 #    Copyright (C) 2007  Quentin Smith <quentin@mit.edu>
5 #    "Hello World" pyFUSE example:
6 #    Copyright (C) 2006  Andrew Straw  <strawman@astraw.com>
7 #
8 #    This program can be distributed under the terms of the GNU LGPL.
9 #    See the file COPYING.
10 #
11
12 import sys, os, stat, errno
13 import fuse
14 from fuse import Fuse
15
16 import hesiod
17
18 if not hasattr(fuse, '__version__'):
19     raise RuntimeError, \
20         "your fuse-py doesn't know of fuse.__version__, probably it's too old."
21
22 fuse.fuse_python_api = (0, 2)
23
24 hello_path = '/README.txt'
25 hello_str = """This is the pyhesiodfs FUSE autmounter. To access a Hesiod filsys, just access
26 %(mountpoint)s/name.
27
28 If you're using the Finder, try pressing Cmd+Shift+G and then entering
29 %(mountpoint)s/name"""
30
31 class MyStat(fuse.Stat):
32     def __init__(self):
33         self.st_mode = 0
34         self.st_ino = 0
35         self.st_dev = 0
36         self.st_nlink = 0
37         self.st_uid = 0
38         self.st_gid = 0
39         self.st_size = 0
40         self.st_atime = 0
41         self.st_mtime = 0
42         self.st_ctime = 0
43
44 class PyHesiodFS(Fuse):
45
46     def __init__(self, *args, **kwargs):
47         Fuse.__init__(self, *args, **kwargs)
48         self.fuse_args.add("allow_other", True)
49         self.fuse_args.add("fsname", "pyHesiodFS")
50         if sys.platform == 'darwin':
51             self.fuse_args.add("noappledouble", True)
52             self.fuse_args.add("noapplexattr", True)
53             self.fuse_args.add("volname", "MIT")
54         self.mounts = {}
55    
56     def getattr(self, path):
57         st = MyStat()
58         if path == '/':
59             st.st_mode = stat.S_IFDIR | 0755
60             st.st_nlink = 2
61         elif path == hello_path:
62             st.st_mode = stat.S_IFREG | 0444
63             st.st_nlink = 1
64             st.st_size = len(hello_str)
65         elif '/' not in path[1:]:
66             if self.findLocker(path[1:]):
67                 st.st_mode = stat.S_IFLNK | 0777
68                 st.st_nlink = 1
69                 st.st_size = len(self.findLocker(path[1:]))
70             else:
71                 return -errno.ENOENT
72         else:
73             return -errno.ENOENT
74         return st
75
76     def getCachedLockers(self):
77         return self.mounts.keys()
78
79     def findLocker(self, name):
80         """Lookup a locker in hesiod and return its path"""
81         if name in self.mounts:
82             return self.mounts[name]
83         else:
84             filsys = hesiod.FilsysLookup(name)
85             # FIXME check if the first locker is valid
86             if len(filsys.getFilsys()) >= 1:
87                 pointers = filsys.getFilsys()
88                 pointer = pointers[0]
89                 if pointer['type'] != 'AFS' and pointer['type'] != 'LOC':
90                     print >>sys.stderr, "Unknown locker type "+pointer.type+" for locker "+name+" ("+repr(pointer)+" )"
91                     return None
92                 else:
93                     self.mounts[name] = pointer['location']
94                     print >>sys.stderr, "Mounting "+name+" on "+pointer['location']
95                     return pointer['location']
96             else:
97                 print >>sys.stderr, "Couldn't find filsys for "+name
98                 return None
99
100     def readdir(self, path, offset):
101         for r in  ['.', '..', hello_path[1:]]+self.getCachedLockers():
102             yield fuse.Direntry(r)
103            
104     def readlink(self, path):
105         return self.findLocker(path[1:])
106
107     def open(self, path, flags):
108         if path != hello_path:
109             return -errno.ENOENT
110         accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
111         if (flags & accmode) != os.O_RDONLY:
112             return -errno.EACCES
113
114     def read(self, path, size, offset):
115         if path != hello_path:
116             return -errno.ENOENT
117         slen = len(hello_str)
118         if offset < slen:
119             if offset + size > slen:
120                 size = slen - offset
121             buf = hello_str[offset:offset+size]
122         else:
123             buf = ''
124         return buf
125
126 def main():
127     global hello_str
128     usage="""
129 pyHesiodFS
130
131 """ + Fuse.fusage
132     server = PyHesiodFS(version="%prog " + fuse.__version__,
133                      usage=usage,
134                      dash_s_do='setsingle')
135
136     server.parse(errex=1)
137     hello_str = hello_str % {'mountpoint': server.parse(errex=1).mountpoint}
138     server.main()
139
140 if __name__ == '__main__':
141     main()
Note: See TracBrowser for help on using the browser.