def access(self, path, amode): if amode & os.W_OK: raise fuse.FuseOSError(EACCES) obj = self._getpath(path) if not obj.exist: raise fuse.FuseOSError(ENOENT) elif (obj.stat.st_mode & amode) != amode: raise fuse.FuseOSError(EACCES) return 0
def removexattr(self, path, name): fh = self.root.get_file(path) if fh.access(os.W_OK) == 0: attrs = fh.attrs.get('attrs', {}) try: del attrs[name] except KeyError: raise fuse.FuseOSError(ENODATA) else: raise fuse.FuseOSError(EACCES)
def read(self): try: req = SESSION.get(self.url, timeout=CONFIG['timeout']) except Exception: raise fuse.FuseOSError(EIO) try: req.raise_for_status() except requests.exceptions.HTTPError: self.stat.setmode(0o000, True) self.init = 2 self._readable = False if req.status_code == 403: raise fuse.FuseOSError(EACCES) elif req.status_code == 404: self.exist = False raise fuse.FuseOSError(ENOENT) else: raise fuse.FuseOSError(EIO) lm = req.headers.get('Last-Modified') if lm: self.stat.settime(time.mktime(parsedate(lm))) else: self.stat.settime(time.time()) try: cwd, listing = parse_dir(req.content) except Exception: logging.exception('failed to parse listing: ' + self.url) listing = [] content = ['.', '..'] objmap = {} for name, modified, size, description in listing: fpath = os.path.join(self.path, name) if name[-1] == '/': fileobj = Directory(self.baseurl, fpath) fpath = fpath.rstrip('/') else: fileobj = File(self.baseurl, fpath) if size is None: fileobj.get_stat() else: fileobj.stat.st_size = size if modified: fileobj.stat.settime(calendar.timegm(modified)) else: fileobj.stat.settime(self.stat.st_mtime) fileobj.init = fileobj.init or 1 content.append(name.rstrip('/')) objmap[fpath] = fileobj self.content = content self.stat.st_nlink = len(content) self.init = 2 self._readable = True return objmap
def rename(self, old, new): fh = self.root.get_file(old) if fh.access(os.W_OK) != 0: raise fuse.FuseOSError(EACCES) parent_old = self.root.get_parent(old) if parent_old.access(os.W_OK) != 0: raise fuse.FuseOSError(EACCES) parent_old.remove_child(fh) parent_new = self.root.get_parent(new) if parent_new.access(os.W_OK) != 0: raise fuse.FuseOSError(EACCES) fh.name = new.split("/")[-1] parent_new.add_child(fh)
def setxattr(self, path, name, value, options, position=0): fh = self.root.get_file(path) if fh.access(os.W_OK) == 0: attrs = fh.attrs.get('attrs', {}) attrs[name] = value else: raise fuse.FuseOSError(EACCES)
def truncate(self, path, length, fh=None): f = self.root.get_file(path) if f.access(os.W_OK) == 0: f.data = f.data[:length] f.attrs['st_size'] = length else: raise fuse.FuseOSError(EACCES)
def unlink(self, path): parent = self.root.get_parent(path) fh = self.root.get_file(path) if fh.access(os.W_OK) == 0 and parent.access(os.W_OK) == 0: parent.remove_child(fh) else: raise fuse.FuseOSError(EACCES)
def rename(self, old, new): if os.path.dirname(old) == os.path.dirname(new): if api.file_exists(new): self.unlink(new) api.api_file_rename(old, os.path.basename(new)) else: raise fusepy.FuseOSError(errno.ENOTSUP)
def getxattr(self, path, name, position=0): fh = self.root.get_file(path) attrs = fh.attrs.get('attrs', {}) try: return attrs[name] except KeyError: raise fuse.FuseOSError(ENODATA)
def rmdir(self, path): fh = self.root.get_file(path) parent = self.root.get_parent(path) if fh.access(os.W_OK) == 0 and parent.access(os.W_OK) == 0: parent.remove_child(fh) parent.attrs['st_nlink'] -= 1 else: raise fuse.FuseOSError(EACCES)
def symlink(self, target, source): name = target.split("/")[-1] lnk = utils.SLink(name,source) parent = self.root.get_parent(target) if parent.access(os.W_OK) == 0: parent.add_child(lnk) else: raise fuse.FuseOSError(EACCES)
def getfile(self, path): if (len(path) == 1 and path[0] == "") or len(path) == 0: return self else: try: return self.children[path[0]].getfile(path[1:]) except KeyError: raise fuse.FuseOSError(ENOENT)
def mkdir(self, path, mode): name = path.split("/")[-1] parent = self.root.get_parent(path) if parent.access(os.W_OK) == 0: nf = utils.Folder(name,mode) parent.add_child(nf) parent.attrs['st_nlink'] += 1 else: raise fuse.FuseOSError(EACCES)
def write(self, path, data, offset, fh): f = self.root.get_file(path) if f.access(os.W_OK) == 0: f.data = f.data[:offset] + data f.attrs['st_size'] = len(f.data) f.trigger(utils.Event.FILE_UPDATE) return len(data) else: raise fuse.FuseOSError(EACCES)
def utimens(self, path, times=None): now = time() atime, mtime = times if times else (now, now) fh = self.root.get_file(path) if fh.access(os.W_OK) == 0: fh.attrs['st_atime'] = atime fh.attrs['st_mtime'] = mtime else: raise fuse.FuseOSError(EACCES)
def create(self, path, mode): p = path.split("/") name = p[-1] parent = self.root.get_parent(path) if parent.access(os.W_OK) == 0: f = utils.File(name,mode) parent.add_child(f) self.fd += 1 parent.trigger(utils.Event.NEW_CHILD) else: raise fuse.FuseOSError(EACCES) return self.fd
def open(self, path, flags): file_type = api.file_exists(path) if file_type == 'folder': raise fusepy.FuseOSError(-errno.EACCES) new_fd = self.next_fd() for file_obj in self.files.values(): if file_obj.path == path: fo = self.files[new_fd] = file_obj file_obj.inc_ref() break else: fo = self.files[new_fd] = CachedFile(path) if not file_type: if flags & os.O_CREAT: fo.truncate(0) else: raise fusepy.FuseOSError(errno.ENOENT) else: if flags & os.O_TRUNC: fo.truncate(0) return new_fd
def getattr(self, path, fh=None): if not os.path.islink(path) or os.path.realpath(path).startswith( self.chroot): stat = os.stat(path) lstat = os.lstat(path) keys = ('st_atime', 'st_gid', 'st_mode', 'st_nlink', 'st_size', 'st_uid') lkeys = ('st_mtime', 'st_ctime') result = dict((key, getattr(stat, key)) for key in keys) lresult = dict((key, getattr(lstat, key)) for key in lkeys) return {**result, **lresult} else: raise fuse.FuseOSError(errno.EACCES)
def _retrieve(self): if not self.fd: if self.path is None: raise fusepy.FuseOSError(errno.EACCES) self.fd = tempfile.TemporaryFile(dir=api_cache_dir) try: f = api.get_file_reader(self.path) except cloudapi.NotFoundError: return while True: s = f.read(1024) if not s: break self.fd.write(s)
def read(self, size=None, offset=None): if not self.init or not self.stat.st_size: self.get_stat() if not self.exist: raise fuse.FuseOSError(ENOENT) elif not self.readable(): raise fuse.FuseOSError(EIO) if offset is None: offset = self.offset end = min(self.stat.st_size, offset + size - 1) brange = '%d-%d' % (offset, end) headers = {'range': 'bytes=' + brange} req = SESSION.get(self.url, headers=headers, stream=True, timeout=CONFIG['timeout']) if req.status_code == 206: self._seekable = True elif req.status_code == 416: # we may have a wrong size self.get_stat() raise fuse.FuseOSError(EIO) elif req.status_code == 200: self._seekable = False if offset != 0: raise fuse.FuseOSError(EIO) elif req.status_code == 403: self._readable = False raise fuse.FuseOSError(EACCES) elif req.status_code == 404: self.exist = False self._readable = False raise fuse.FuseOSError(ENOENT) else: self._readable = False raise fuse.FuseOSError(EIO) content = bytes() for chunk in req.iter_content(CONTENT_CHUNK_SIZE, False): content += chunk if len(content) > size: content = content[:size] break req.close() if self._seekable: self.offset = end return content
def getattr(self, path, fh=None): try: res = api.api_file(path) except cloudapi.NotFoundError: raise fusepy.FuseOSError(errno.ENOENT) st = {} if res['kind'] == 'file': st = dict( st_mode=stat.S_IFREG | 0666, st_nlink=1, st_size=res['size'], st_mtime=res['mtime'], st_ctime=res['mtime'], st_atime=res['mtime'], st_uid=1000) elif res['kind'] == 'folder': st = dict( st_mode=stat.S_IFDIR | 0777, st_nlink=2, st_uid=1000) return st
def getattr(self, path, fh=None): logging.debug('getattr: %s', path) obj = self._getpath(path) if not obj.exist: raise fuse.FuseOSError(ENOENT) return obj.stat
def readdir(self, path, fh): f = self.root.get_file(path) if f.access(os.R_OK) == 0: return f.read() else: raise fuse.FuseOSError(EACCES)
def readdir(self, path, fh): try: res = api.api_folder(path) except cloudapi.NotFoundError: raise fusepy.FuseOSError(errno.ENOENT) return ['.', '..'] + [rec['name'].encode('utf-8') for rec in res['list']]
def symlink(self, target, source): raise fusepy.FuseOSError(errno.ENOTSUP)
def access(self, path, mode): if not os.access(path, mode): raise fuse.FuseOSError(errno.EACCES)