Ejemplo n.º 1
0
 def readlink(self, path):
     """
      readlink(const char* path, char* buf, size_t size)
     If path is a symbolic link, fill buf with its target, up to size.
     See readlink(2) for how to handle a too-small buffer and for error
     codes.  Not required if you don't support symbolic links.
     NOTE: Symbolic-link support requires only readlink and symlink.  FUSE
     itself will take care of tracking symbolic links in paths, so your
     path-evaluation code doesn't need to worry about it.
     """
     self.logger.debug('[FuseFSCore.readlink] path: %s. Context: %s', path,
                       self.GetContext())
     srctree = self.returntree(path, self.root, True)
     if isobject(srctree):
         dirtree = srctree._readlink(path)
         self.logger.debug('[FuseFSCore.readlink] readlink %s', srctree)
         # dirtree._readlink(path))
         # return None
     else:
         dirtree = srctree
     self.logger.debug('[FuseFSCore.readlink] FoundTree: %s', dirtree)
     if len(dirtree) > 1:
         return dirtree[1]
     else:
         return None
Ejemplo n.º 2
0
    def readdir(self, path, fhandle=None):
        """
         readdir(const char* path, void* buf, fuse_fill_dir_t filler, off_t
                 offset, struct fuse_file_info* fi)
        Return one or more directory entries (struct dirent) to the caller.
        This is one of the most complex FUSE functions.  It is related to, but
        not identical to, the readdir(2) and getdents(2) system calls, and the
        readdir(3) library function.  Because of its complexity, it is
        described separately below.  Required for essentially any filesystem,
        since it's what makes ls and a whole bunch of other things work.
        """
        self.logger.debug('[FuseFSCore.readdir] Path %s:%s. Context: %s', path,
                          fhandle, self.GetContext())
        srctree = self.returntree(path, self.root, False)
        self.logger.debug('[FuseFSCore.readdir] Found data %s for path %s',
                          srctree, path)
        if isobject(srctree):
            dirtree = srctree._readdir(path)
            self.logger.debug(
                '[FuseFSCore.readdir] Object %s return dirtree %s', srctree,
                dirtree)
        else:
            dirtree = srctree

        self.logger.debug('[FuseFSCore.readdir] SrcTree: %s, DirTree: %s:%s',
                          srctree, type(dirtree), dirtree)

        dirents = ['.', '..']
        dirents.extend(dirtree.keys())
        for entry in dirents:
            if entry == '__dirstat__':
                continue
            yield fuse.Direntry(entry)
Ejemplo n.º 3
0
    def read(self, path, length, offset):
        """
         read(const char* path, char *buf, size_t size, off_t offset, struct
        fuse_file_info* fi)
        Read sizebytes from the given file into the buffer buf, beginning
        offset bytes into the file.  See read(2) for full details.  Returns
        the number of bytes transferred, or 0 if offset was at or beyond the
        end of the file.  Required for any sensible filesystem.
        """
        self.logger.debug('[FuseFSCore.read] read file %s:%s:%s. Context: %s',
                          path, length, offset, self.GetContext())
        srctree = self.returntree(path, self.root, True)
        self.logger.debug('[FuseFSCore.read] dirtree data %s for path %s',
                          srctree, path)
        if isobject(srctree):
            if hasattr(srctree, '_read'):
                self.logger.debug(
                    '[FuseFSCore.read] srctree %s has attr _read', srctree)
                dirtree = srctree._read(path)
            else:
                dirtree = srctree._getattr(path)
            self.logger.debug('[FuseFSCore.read] get path %s', dirtree)
        else:
            dirtree = srctree
#        dirtree=self.returntree(path,self.root,True)
        self.logger.debug('[FuseFSCore.read] FoundTree: %s', dirtree)
        if callable(dirtree):
            retval = dirtree()[1]
            return retval[offset:length]
        elif len(dirtree) > 1:
            if callable(dirtree[1]):
                return dirtree[1](path)[offset:length]
            else:
                return dirtree[1][offset:length]
        else:
            return None
Ejemplo n.º 4
0
    def getattr(self, path, fhandle=None):
        """
         getattr(const char* path, struct stat* stbuf)
        Return file attributes.  The "stat" structure is described in detail
        in the stat(2) manual page.  For the given pathname, this should fill
        in the elements of the "stat" structure.  If a field is meaningless or
        semi-meaningless (e.g., st_ino) then it should be set to 0 or given a
        "reasonable" value.  This call is pretty much required for a usable
        filesystem.
        =====================================================================
        getattr procedure must return stat object for
        requested path or -errno.ENOENT if path is not found
        """
        self.logger.debug('[FuseFSCore.getattr] path %s fh %s. Context: %s',
                          path, fhandle, self.GetContext())
        #
        # returntree procedure make a recurse search over root object tree
        # returntree can return many types of object
        # object(class) - proceed path with found object(class)
        # callable(function) - proceed path with found callable(function)
        # int - error or status
        # list - static record from root tree
        # dict - static directory record from root tree
        #
        srctree = self.returntree(path, self.root, False)
        self.logger.debug('[FuseFSCore.getattr] Found data %s for path %s',
                          srctree, path)
        if isobject(srctree):
            dirtree = srctree._getattr(path)
            self.logger.debug(
                '[FuseFSCore.getattr] Object %s return dirtree %s', srctree,
                dirtree)
        else:
            dirtree = srctree

        attrstat = {}

        if callable(dirtree):
            #
            # dirtree can be a function
            # function must return a list with structure
            # [ {} , '' ]
            # part with index 0 - stat info for object
            # part with index 1 - object data(for object size calculation)
            #
            attrstat.update(stat_info['def'])
            attrstat.update(dirtree()[0])
            attrstat.update({
                'st_size': len(dirtree()[1]),
                'st_mtime': int('%d' % time())
            })
            self.logger.debug('[FuseFSCore.getattr] dirtree callable %s' %
                              attrstat)
        elif isinstance(dirtree, int):
            #
            # if dirtree type is negative int - error occured or
            # object not found in root tree
            #
            if dirtree < 0:
                return dirtree
            else:
                attrstat.update(stat_info['def'])
        elif isinstance(dirtree, list):
            #
            # if dirtree type is list, use structure
            # [ {} , '' ]
            # part with index 0 - stat info for object
            # part with index 1 - object data(for object size calculation)
            #
            attrstat.update(dirtree[0])
            ###########
            if callable(dirtree[1]):
                #
                # if dirtree part with index 1 is callable
                # request length of data from this callable
                #
                attrstat.update({'st_size': len(dirtree[1](path))})
            elif attrstat['st_size'] == 0:
                attrstat.update({'st_size': len(dirtree[1])})
            ###########
            self.logger.debug('[FuseFSCore.getattr] List %s:%s' %
                              (type(attrstat), attrstat))
        elif isinstance(dirtree, dict):
            #
            # if dirtree type is dict, object is directory
            # and key '__dirstat__' used for object stat,
            # other keys in dirtree object used as count of
            # linked items to this directory objects
            # __dirstat__ key has a structure
            # [ {} , '' ]
            # part with index 0 - stat info for directory object
            # part with index 1 - None or ''
            #
            if '__dirstat__' in dirtree:
                attrstat.update(dirtree['__dirstat__'][0])
                if attrstat['st_nlink'] == 1:
                    attrstat.update({'st_nlink': len(dirtree)})
            else:
                attrstat.update(stat_info['def'])
                attrstat.update(stat_info['file'])

        elif dirtree is None:
            #
            # if dirtree is None - object not found in root tree
            #
            return -errno.ENOENT
        else:
            #
            # any other types for dirtree return stat as file
            #
            attrstat.update(stat_info['def'])
            attrstat.update(stat_info['file'])

        self.logger.debug(
            '[FuseFSCore.getattr] Attrstat Result for object %s is %s:%s',
            path, type(attrstat), attrstat)
        fusest = fuse.Stat()
        for key in attrstat:
            setattr(fusest, key, attrstat[key])
        return fusest
Ejemplo n.º 5
0
    def recursepath(self, path, tree, withdata):
        """
        recursive search a path in existing tree
        """
        # print 'Path %s length %s tree %s'%(path,len(path),tree)
        # !logger.debug('[recursepath] Path %s length %s WithData:
        # %s'%(path,len(path),withdata))
        if path[0] not in tree:
            # print 'Path not found'
            return None
        else:
            # print 'Tree %s'%tree
            if not isobject(tree[path[0]]):
                if len(path) == 1:
                    if isobject(tree[path[0]]):
                        logger.debug(
                            '[FuseFSCore.recursepath] object found %s',
                            tree[path[0]])
                        return tree[path[0]]
                    elif callable(tree[path[0]]):
                        logger.debug(
                            '[FuseFSCore.recursepath] callable dir %s',
                            dir(tree[path[0]]))
                        # return { '1234' : { '12345' : [stat_info['def'],None] } }
                        logger.debug(
                            '[FuseFSCore.recursepath] Callable \
                        Path found %s at %s:%s', path, tree[path[0]], withdata)
                        dictpath = dict(
                            (x, {}) for x in tree[path[0]](withdata))
                        logger.debug(
                            '[FuseFSCore.recursepath] --------- Callable \
                            Path result %s', len(dictpath))
                        return dictpath
                    else:
                        return tree[path[0]]
                else:
                    for part in path:
                        # print '\n[recursepath] Path part %s'%part
                        # print '\n[recursepath] Path %s length
                        # %s:%s'%(path,len(path),withdata)

                        if callable(tree[part]):
                            # print '[recursepath] callable %s at path
                            # %s'%(tree[part],path)
                            data = tree[part](withdata, path[1:])
                            # print '[recursepath] Plain callable data for
                            # path %s tree %s'%(path,data)
                            return data
                        else:
                            # print 'recurse %s tree %s'%(part,tree[part])
                            # pathkey = '/'.join(path)
                            # if pathkey in cache:
                            # data = cache[pathkey]
                            # print '\n%s\n[recursepath] Cached data tree
                            # for path %s is %s'%('='*30,path,data)
                            # else:
                            # cache.expire()
                            data = self.recursepath(path[1:], tree[part],
                                                    withdata)
                            # cache.set(pathkey, data, expire=15)
                            # print '\n%s\n[recursepath] Plain ordinal data
                            # tree for path %s is %s'%('='*30,path,data)
                            return data
            else:
                return tree[path[0]]