#!/usr/bin/python import fuse from fuse import Fuse from time import time import stat # for file properties import os # for filesystem modes (O_RDONLY, etc) import errno # for error number codes (ENOENT, etc) # - note: these must be returned as negatives fuse.fuse_python_api = (0, 2) machines = ['moo17', 'remus'] realpath = "/home/machines/" uid = 1000 def dirFromList(list): """ Return a properly formatted list of items suitable to a directory listing. ['a', 'b', 'c'] => [('a', 0), ('b', 0), ('c', 0)] """ return [(x, 0) for x in list] def getDepth(path): """ Return the depth of a given path, zero-based from root ('/') """ if path == '/': return 0 else: return path.count('/') def getParts(path): """ Return the slash-separated parts of a given path as a list """ if path == '/': return ['/'] else: return path[1:].split('/') class MyStat: def __init__(self): self.st_mode = 0 self.st_ino = 0 self.st_dev = 0 self.st_nlink = 0 self.st_uid = uid self.st_gid = 0 self.st_size = 0 self.st_atime = 0 self.st_mtime = 0 self.st_ctime = 0 def toTuple(self): return (self.st_mode, self.st_ino, self.st_dev, self.st_nlink, self.st_uid, self.st_gid, self.st_size, self.st_atime, self.st_mtime, self.st_ctime) class ConsoleFS(Fuse): """ """ def __init__(self, *args, **kw): Fuse.__init__(self, *args, **kw) print 'Init complete.' def mirrorPath(self, path): return realpath + "/".join(getParts(path)[1:]) def getattr(self, path): """ - st_mode (protection bits) - st_ino (inode number) - st_dev (device) - st_nlink (number of hard links) - st_uid (user ID of owner) - st_gid (group ID of owner) - st_size (size of file, in bytes) - st_atime (time of most recent access) - st_mtime (time of most recent content modification) - st_ctime (platform dependent; time of most recent metadata change on Unix, or the time of creation on Windows). """ print "*** getattr: " + path depth = getDepth(path) parts = getParts(path) st = MyStat() if path == '/': st.st_mode = stat.S_IFDIR | 0755 st.st_nlink = 2 elif depth == 1: if parts[-1] in machines: st.st_mode = stat.S_IFDIR | 0755 st.st_nlink = 2 else: return -errno.ENOENT elif depth == 2 and parts[-1] == '.k5login': st.st_mode = stat.S_IFREG | 0444 st.st_nlink = 1 st.st_size = 17 else: st = os.lstat(self.mirrorPath(path)) return st.toTuple() def readdir(self, path, offset): print '*** readdir', path, offset if path == '/': for r in ['.', '..']+machines: yield fuse.Direntry(r) elif getDepth(path) == 1: for r in set(os.listdir(self.mirrorPath(path)) + ['.k5login']): yield fuse.Direntry(r) else: for r in os.listdir(self.mirrorPath(path)): yield fuse.Direntry(r) def read ( self, path, length, offset ): print '*** read', path, length, offset if getDepth(path) < 2: return -errno.ENOENT elif getParts(path)[1:] == ['.k5login']: pass else: fname = self.mirrorPath(path) if not os.path.isfile(fname): return -errno.ENOENT else: f = open(fname) f.seek(offset) return f.read(length) if __name__ == '__main__': usage=""" ConsoleFS [mount_path] """ server = ConsoleFS() server.flags = 0 server.main()