source: trunk/debathena/debathena/pyhesiodfs/pyHesiodFS.py @ 23245

Revision 23245, 5.2 KB checked in by broder, 16 years ago (diff)
In pyhesiodfs, use the syslog instead of printing to stderr
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
12import sys, os, stat, errno
13from syslog import *
14import fuse
15from fuse import Fuse
16
17import hesiod
18
19new_fuse = hasattr(fuse, '__version__')
20
21fuse.fuse_python_api = (0, 2)
22
23hello_path = '/README.txt'
24hello_str = """This is the pyhesiodfs FUSE autmounter. To access a Hesiod filsys, just access
25%(mountpoint)s/name.
26
27If you're using the Finder, try pressing Cmd+Shift+G and then entering
28%(mountpoint)s/name"""
29
30if not hasattr(fuse, 'Stat'):
31    fuse.Stat = object
32
33class 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
51class 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
152def 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="""
162pyHesiodFS [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
172if __name__ == '__main__':
173    main()
Note: See TracBrowser for help on using the repository browser.