source: trunk/debathena/debathena/debathena-pyhesiodfs/pyHesiodFS.py @ 23080

Revision 23080, 4.2 KB checked in by broder, 17 years ago (diff)
Add debathena-pyhesiodfs package to replace insecure debathena-afuse-automounter
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
13import fuse
14from fuse import Fuse
15
16import hesiod
17
18if not hasattr(fuse, '__version__'):
19    raise RuntimeError, \
20        "your fuse-py doesn't know of fuse.__version__, probably it's too old."
21
22fuse.fuse_python_api = (0, 2)
23
24hello_path = '/README.txt'
25hello_str = """This is the pyhesiodfs FUSE autmounter. To access a Hesiod filsys, just access
26%(mountpoint)s/name.
27
28If you're using the Finder, try pressing Cmd+Shift+G and then entering
29%(mountpoint)s/name"""
30
31class 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
44class 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
125def main():
126    global hello_str
127    usage="""
128pyHesiodFS
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
139if __name__ == '__main__':
140    main()
Note: See TracBrowser for help on using the repository browser.