]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - contrib/fuse/impl_b/pyfuse/memoryfs.py
add Protovis.js-based download-status timeline visualization
[tahoe-lafs/tahoe-lafs.git] / contrib / fuse / impl_b / pyfuse / memoryfs.py
1 from kernel import *
2 from handler import Handler
3 import stat, time, os, weakref, errno
4 from cStringIO import StringIO
5
6
7 class MemoryFS(object):
8     INFINITE = 86400.0
9
10
11     class Dir(object):
12         type = TYPE_DIR
13         def __init__(self, attr):
14             self.attr = attr
15             self.contents = {}    # { 'filename': Dir()/File()/SymLink() }
16
17     class File(object):
18         type = TYPE_REG
19         def __init__(self, attr):
20             self.attr = attr
21             self.data = StringIO()
22
23     class SymLink(object):
24         type = TYPE_LNK
25         def __init__(self, attr, target):
26             self.attr = attr
27             self.target = target
28
29
30     def __init__(self, root=None):
31         self.uid = os.getuid()
32         self.gid = os.getgid()
33         self.umask = os.umask(0); os.umask(self.umask)
34         self.root = root or self.Dir(self.newattr(stat.S_IFDIR))
35         self.root.id = FUSE_ROOT_ID
36         self.nodes = weakref.WeakValueDictionary()
37         self.nodes[FUSE_ROOT_ID] = self.root
38         self.nextid = FUSE_ROOT_ID + 1
39
40     def newattr(self, s, ino=None, mode=0666):
41         now = time.time()
42         attr = fuse_attr(size  = 0,
43                          mode  = s | (mode & ~self.umask),
44                          nlink = 1,  # even on dirs! this confuses 'find' in
45                                      # a good way :-)
46                          atime = now,
47                          mtime = now,
48                          ctime = now,
49                          uid   = self.uid,
50                          gid   = self.gid)
51         if ino is None:
52             ino = id(attr)
53         if ino < 0:
54             ino = ~ino
55         attr.ino = ino
56         return attr
57
58     def getnode(self, id):
59         return self.nodes[id]
60
61     def modified(self, node):
62         node.attr.mtime = node.attr.atime = time.time()
63         if isinstance(node, self.File):
64             node.data.seek(0, 2)
65             node.attr.size = node.data.tell()
66
67     def getattr(self, node):
68         return node.attr, self.INFINITE
69
70     def setattr(self, node, mode, uid, gid, size, atime, mtime):
71         if mode is not None:
72             node.attr.mode = (node.attr.mode & ~0777) | (mode & 0777)
73         if uid is not None:
74             node.attr.uid = uid
75         if gid is not None:
76             node.attr.gid = gid
77         if size is not None:
78             assert isinstance(node, self.File)
79             node.data.seek(0, 2)
80             oldsize = node.data.tell()
81             if size < oldsize:
82                 node.data.seek(size)
83                 node.data.truncate()
84                 self.modified(node)
85             elif size > oldsize:
86                 node.data.write('\x00' * (size - oldsize))
87                 self.modified(node)
88         if atime is not None:
89             node.attr.atime = atime
90         if mtime is not None:
91             node.attr.mtime = mtime
92
93     def listdir(self, node):
94         assert isinstance(node, self.Dir)
95         for name, subobj in node.contents.items():
96             yield name, subobj.type
97
98     def lookup(self, dirnode, filename):
99         try:
100             return dirnode.contents[filename].id, self.INFINITE
101         except KeyError:
102             raise IOError(errno.ENOENT, filename)
103
104     def open(self, filenode, flags):
105         return filenode.data
106
107     def newnodeid(self, newnode):
108         id = self.nextid
109         self.nextid += 1
110         newnode.id = id
111         self.nodes[id] = newnode
112         return id
113
114     def mknod(self, dirnode, filename, mode):
115         node = self.File(self.newattr(stat.S_IFREG, mode=mode))
116         dirnode.contents[filename] = node
117         return self.newnodeid(node), self.INFINITE
118
119     def mkdir(self, dirnode, subdirname, mode):
120         node = self.Dir(self.newattr(stat.S_IFDIR, mode=mode))
121         dirnode.contents[subdirname] = node
122         return self.newnodeid(node), self.INFINITE
123
124     def symlink(self, dirnode, linkname, target):
125         node = self.SymLink(self.newattr(stat.S_IFLNK), target)
126         dirnode.contents[linkname] = node
127         return self.newnodeid(node), self.INFINITE
128
129     def unlink(self, dirnode, filename):
130         del dirnode.contents[filename]
131
132     rmdir = unlink
133
134     def readlink(self, symlinknode):
135         return symlinknode.target
136
137     def rename(self, olddirnode, oldname, newdirnode, newname):
138         node = olddirnode.contents[oldname]
139         newdirnode.contents[newname] = node
140         del olddirnode.contents[oldname]
141
142     def getxattrs(self, node):
143         try:
144             return node.xattrs
145         except AttributeError:
146             node.xattrs = {}
147             return node.xattrs
148
149
150 if __name__ == '__main__':
151     import sys
152     mountpoint = sys.argv[1]
153     memoryfs = MemoryFS()
154     handler = Handler(mountpoint, memoryfs)
155     handler.loop_forever()