root/trunk/source/pyhesiodfs/pyHesiodFS.py

Revision 157, 5.2 kB (checked in by broder, 16 years ago)

Use syslog instead of stdout in pyhesiodfs

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