root/trunk/source/pyhesiodfs/pyHesiodFS.py

Revision 144, 4.8 kB (checked in by broder, 16 years ago)

Use PyHesiod instead of Python DNS based wrapper

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 new_fuse = hasattr(fuse, '__version__')
19
20 fuse.fuse_python_api = (0, 2)
21
22 hello_path = '/README.txt'
23 hello_str = """This is the pyhesiodfs FUSE autmounter. To access a Hesiod filsys, just access
24 %(mountpoint)s/name.
25
26 If you're using the Finder, try pressing Cmd+Shift+G and then entering
27 %(mountpoint)s/name"""
28
29 if not hasattr(fuse, 'Stat'):
30     fuse.Stat = object
31
32 class MyStat(fuse.Stat):
33     def __init__(self):
34         self.st_mode = 0
35         self.st_ino = 0
36         self.st_dev = 0
37         self.st_nlink = 0
38         self.st_uid = 0
39         self.st_gid = 0
40         self.st_size = 0
41         self.st_atime = 0
42         self.st_mtime = 0
43         self.st_ctime = 0
44
45     def toTuple(self):
46         return (self.st_mode, self.st_ino, self.st_dev, self.st_nlink,
47                 self.st_uid, self.st_gid, self.st_size, self.st_atime,
48                 self.st_mtime, self.st_ctime)
49
50 class PyHesiodFS(Fuse):
51
52     def __init__(self, *args, **kwargs):
53         Fuse.__init__(self, *args, **kwargs)
54         try:
55             self.fuse_args.add("allow_other", True)
56         except AttributeError:
57             self.allow_other = 1
58
59         if sys.platform == 'darwin':
60             self.fuse_args.add("noappledouble", True)
61             self.fuse_args.add("noapplexattr", True)
62             self.fuse_args.add("volname", "MIT")
63             self.fuse_args.add("fsname", "pyHesiodFS")
64         self.mounts = {}
65    
66     def getattr(self, path):
67         st = MyStat()
68         if path == '/':
69             st.st_mode = stat.S_IFDIR | 0755
70             st.st_nlink = 2
71         elif path == hello_path:
72             st.st_mode = stat.S_IFREG | 0444
73             st.st_nlink = 1
74             st.st_size = len(hello_str)
75         elif '/' not in path[1:]:
76             if self.findLocker(path[1:]):
77                 st.st_mode = stat.S_IFLNK | 0777
78                 st.st_nlink = 1
79                 st.st_size = len(self.findLocker(path[1:]))
80             else:
81                 return -errno.ENOENT
82         else:
83             return -errno.ENOENT
84         if new_fuse:
85             return st
86         else:
87             return st.toTuple()
88
89     def getCachedLockers(self):
90         return self.mounts.keys()
91
92     def findLocker(self, name):
93         """Lookup a locker in hesiod and return its path"""
94         if name in self.mounts:
95             return self.mounts[name]
96         else:
97             filsys = hesiod.FilsysLookup(name)
98             # FIXME check if the first locker is valid
99             if len(filsys.filsys) >= 1:
100                 pointers = filsys.filsys
101                 pointer = pointers[0]
102                 if pointer['type'] != 'AFS' and pointer['type'] != 'LOC':
103                     print >>sys.stderr, "Unknown locker type "+pointer.type+" for locker "+name+" ("+repr(pointer)+" )"
104                     return None
105                 else:
106                     self.mounts[name] = pointer['location']
107                     print >>sys.stderr, "Mounting "+name+" on "+pointer['location']
108                     return pointer['location']
109             else:
110                 print >>sys.stderr, "Couldn't find filsys for "+name
111                 return None
112
113     def getdir(self, path):
114         return [(i, 0) for i in (['.', '..', hello_path[1:]] + self.getCachedLockers())]
115
116     def readdir(self, path, offset):
117         for (r, zero) in self.getdir(path):
118             yield fuse.Direntry(r)
119            
120     def readlink(self, path):
121         return self.findLocker(path[1:])
122
123     def open(self, path, flags):
124         if path != hello_path:
125             return -errno.ENOENT
126         accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
127         if (flags & accmode) != os.O_RDONLY:
128             return -errno.EACCES
129
130     def read(self, path, size, offset):
131         if path != hello_path:
132             return -errno.ENOENT
133         slen = len(hello_str)
134         if offset < slen:
135             if offset + size > slen:
136                 size = slen - offset
137             buf = hello_str[offset:offset+size]
138         else:
139             buf = ''
140         return buf
141
142 def main():
143     global hello_str
144     try:
145         usage = Fuse.fusage
146         server = PyHesiodFS(version="%prog " + fuse.__version__,
147                             usage=usage,
148                             dash_s_do='setsingle')
149         server.parse(errex=1)
150     except AttributeError:
151         usage="""
152 pyHesiodFS [mountpath] [options]
153
154 """
155         if sys.argv[1] == '-f':
156             sys.argv.pop(1)
157         server = PyHesiodFS()
158
159     hello_str = hello_str % {'mountpoint': server.parse(errex=1).mountpoint}
160     server.main()
161
162 if __name__ == '__main__':
163     main()
Note: See TracBrowser for help on using the browser.