diff -r 000000000000 -r c9bf2537109a ait/os/bin/mirrorfuse/mirrorfuse.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ait/os/bin/mirrorfuse/mirrorfuse.py Tue Nov 12 11:31:34 2013 +0100 @@ -0,0 +1,270 @@ +#!/bin/env python +# -*- coding: utf-8 -*- + +# ------------------------------------------------------------ +# mirrorfuse +# +# create a mirror filesystem folder as a new filesystem to mount +# +# This is directly based on xmp.py of the +# dev-python/fuse-python example +# +# Autor: Oliver Maurhart, +# +# Copyright (C) 2013 AIT Austrian Institute of Technology +# AIT Austrian Institute of Technology GmbH +# Donau-City-Strasse 1 | 1220 Vienna | Austria +# http://www.ait.ac.at +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation version 2. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# ------------------------------------------------------------ + + +# ------------------------------------------------------------ +# imports + +import errno +import fcntl +import fuse +import os +import sys + +from fuse import Fuse + +# ------------------------------------------------------------ +# const + + +__version__ = "0.1" + + +# ------------------------------------------------------------ +# code + + +class MirrorFuse(Fuse): + + """This is the Mirror FUSE in python. + + This is to represnt a file hierarchy elsewhere (and intercept each file system call) + """ + + def __init__(self, *args, **kw): + fuse.fuse_python_api = (0, 2) + super(MirrorFuse, self).__init__(*args, **kw) + self.root = '/' + self.os_server_url = '' + + def getattr(self, path): + return os.lstat("." + path) + + + # + # links are not allowed for a mirrored FS + # + def readlink(self, path): + eturn -errno.EACCES + + + def readdir(self, path, offset): + for e in os.listdir("." + path): + yield fuse.Direntry(e) + + + def unlink(self, path): + sys.stdout.write("===\nInsert Hook here! Deleting file %s\n===\n" % path) + os.unlink("." + path) + + + def rmdir(self, path): + sys.stdout.write("===\nInsert Hook here! Deleting folder %s\n===\n" % path) + os.rmdir("." + path) + + + # + # links are not allowed for a mirrored FS + # + def symlink(self, path, path1): + eturn -errno.EACCES + + + def rename(self, path, path1): + sys.stdout.write("===\nInsert Hook here! Moving file %s --> %s\n===\n" % path % path1) + os.rename("." + path, "." + path1) + + + # + # links are not allowed for a mirrored FS + # + def link(self, path, path1): + return -errno.EACCES + + + # + # changing access mode is not allowed in mirrored FS + # + def chmod(self, path, mode): + return -errno.EACCES + + + # + # changing ownership is not allowed in mirrored FS + # + def chown(self, path, user, group): + return -errno.EACCES + + + def truncate(self, path, len): + f = open("." + path, "a") + f.truncate(len) + f.close() + + + def mknod(self, path, mode, dev): + sys.stdout.write("===\nInsert Hook here! Creating file %s\n===\n" % path) + os.mknod("." + path, mode, dev) + + + def mkdir(self, path, mode): + sys.stdout.write("===\nInsert Hook here! Creating folder %s\n===\n" % path) + os.mkdir("." + path, mode) + + + def utime(self, path, times): + os.utime("." + path, times) + + + def access(self, path, mode): + if not os.access("." + path, mode): + return -errno.EACCES + + + def statfs(self): + return os.statvfs(".") + + + def fsinit(self): + os.chdir(self.root) + + + def main(self, *a, **kw): + self.file_class = MirrorFuseFile + return Fuse.main(self, *a, **kw) + + +class MirrorFuseFile(object): + + """This is a single "File" in the Mirror FUSE""" + + def __init__(self, path, flags, *mode): + sys.stdout.write("===\nInsert Hook here! Opening file %s\n===\n" % path) + self.file = os.fdopen(os.open("." + path, flags, *mode), flag2mode(flags)) + self.fd = self.file.fileno() + + + def read(self, length, offset): + self.file.seek(offset) + return self.file.read(length) + + + def write(self, buf, offset): + self.file.seek(offset) + self.file.write(buf) + return len(buf) + + + def release(self, flags): + self.file.close() + + + def _fflush(self): + if 'w' in self.file.mode or 'a' in self.file.mode: + self.file.flush() + + def fsync(self, isfsyncfile): + self._fflush() + if isfsyncfile and hasattr(os, 'fdatasync'): + os.fdatasync(self.fd) + else: + os.fsync(self.fd) + + + def flush(self): + self._fflush() + os.close(os.dup(self.fd)) + + + def fgetattr(self): + return os.fstat(self.fd) + + + def ftruncate(self, len): + self.file.truncate(len) + + + def lock(self, cmd, owner, **kw): + op = {fcntl.F_UNLCK : fcntl.LOCK_UN, fcntl.F_RDLCK : fcntl.LOCK_SH, fcntl.F_WRLCK : fcntl.LOCK_EX}[kw['l_type']] + if cmd == fcntl.F_GETLK: + return -EOPNOTSUPP + elif cmd == fcntl.F_SETLK: + if op != fcntl.LOCK_UN: + op |= fcntl.LOCK_NB + elif cmd == fcntl.F_SETLKW: + pass + else: + return -errno.EINVAL + + fcntl.lockf(self.fd, op, kw['l_start'], kw['l_len']) + + +def flag2mode(flags): + + """Turn os flags into mode chars""" + + md = {os.O_RDONLY: 'r', os.O_WRONLY: 'w', os.O_RDWR: 'w+'} + m = md[flags & (os.O_RDONLY | os.O_WRONLY | os.O_RDWR)] + if flags | os.O_APPEND: + m = m.replace('w', 'a', 1) + return m + + +def main(): + + usage = """ +mirror the a file tree from some point on. + +""" + Fuse.fusage + + # launch the Fuse server + server = MirrorFuse(version = "%prog " + __version__, usage = usage, dash_s_do = 'setsingle') + server.parser.add_option(mountopt = "root", metavar = "PATH", default='/', help="mirror filesystem from under PATH [default: %default]") + server.parser.add_option(mountopt = "os_server_url", metavar = "URL", default='http://localhost:8080', help="URL to OpenSecurity Server [default: %default]") + server.parse(values=server, errex=1) + + try: + if server.fuse_args.mount_expected(): + os.chdir(server.root) + except OSError: + print >> sys.stderr, "can't enter root of underlying filesystem" + sys.exit(1) + + server.main() + + +# start +if __name__ == "__main__": + main() + +