root/trunk/pyHesiodFS/pyHesiodFS.py

Revision 38, 4.0 kB (checked in by broder, 16 years ago)

Adding pyHesiodFS to trunk. I fixed the bug with the 1-tuple, but made no other modifications

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