root/trunk/pyHesiodFS/pyHesiodFS.py

Revision 41, 4.2 kB (checked in by broder, 17 years ago)

Patch from me. Fixes the README file and volname

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("noappledouble", True)
50         self.fuse_args.add("noapplexattr", True)
51         self.fuse_args.add("fsname", "pyHesiodFS")
52         self.fuse_args.add("volname", "MIT")
53         self.mounts = {}
54    
55     def getattr(self, path):
56         st = MyStat()
57         if path == '/':
58             st.st_mode = stat.S_IFDIR | 0755
59             st.st_nlink = 2
60         elif path == hello_path:
61             st.st_mode = stat.S_IFREG | 0444
62             st.st_nlink = 1
63             st.st_size = len(hello_str)
64         elif '/' not in path[1:]:
65             if self.findLocker(path[1:]):
66                 st.st_mode = stat.S_IFLNK | 0777
67                 st.st_nlink = 1
68                 st.st_size = len(self.findLocker(path[1:]))
69             else:
70                 return -errno.ENOENT
71         else:
72             return -errno.ENOENT
73         return st
74
75     def getCachedLockers(self):
76         return self.mounts.keys()
77
78     def findLocker(self, name):
79         """Lookup a locker in hesiod and return its path"""
80         if name in self.mounts:
81             return self.mounts[name]
82         else:
83             filsys = hesiod.FilsysLookup(name)
84             # FIXME check if the first locker is valid
85             if len(filsys.getFilsys()) >= 1:
86                 pointers = filsys.getFilsys()
87                 pointer = pointers[0]
88                 if pointer['type'] != 'AFS' and pointer['type'] != 'LOC':
89                     print >>sys.stderr, "Unknown locker type "+pointer.type+" for locker "+name+" ("+repr(pointer)+" )"
90                     return None
91                 else:
92                     self.mounts[name] = pointer['location']
93                     print >>sys.stderr, "Mounting "+name+" on "+pointer['location']
94                     return pointer['location']
95             else:
96                 print >>sys.stderr, "Couldn't find filsys for "+name
97                 return None
98
99     def readdir(self, path, offset):
100         for r in  ['.', '..', hello_path[1:]]+self.getCachedLockers():
101             yield fuse.Direntry(r)
102            
103     def readlink(self, path):
104         return self.findLocker(path[1:])
105
106     def open(self, path, flags):
107         if path != hello_path:
108             return -errno.ENOENT
109         accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
110         if (flags & accmode) != os.O_RDONLY:
111             return -errno.EACCES
112
113     def read(self, path, size, offset):
114         if path != hello_path:
115             return -errno.ENOENT
116         slen = len(hello_str)
117         if offset < slen:
118             if offset + size > slen:
119                 size = slen - offset
120             buf = hello_str[offset:offset+size]
121         else:
122             buf = ''
123         return buf
124
125 def main():
126     global hello_str
127     usage="""
128 pyHesiodFS
129
130 """ + Fuse.fusage
131     server = PyHesiodFS(version="%prog " + fuse.__version__,
132                      usage=usage,
133                      dash_s_do='setsingle')
134
135     server.parse(errex=1)
136     hello_str = hello_str % {'mountpoint': server.parse(errex=1).mountpoint}
137     server.main()
138
139 if __name__ == '__main__':
140     main()
Note: See TracBrowser for help on using the browser.