Beispiel #1
0
 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
Beispiel #2
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
Beispiel #4
0
 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)
Beispiel #5
0
 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)
Beispiel #6
0
 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)
Beispiel #7
0
 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)
Beispiel #8
0
 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)
Beispiel #9
0
 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)
Beispiel #10
0
 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)
Beispiel #11
0
 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)
Beispiel #12
0
 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)
Beispiel #13
0
 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)
Beispiel #14
0
 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)
Beispiel #15
0
 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)
Beispiel #16
0
 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
Beispiel #17
0
 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
Beispiel #18
0
 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)
Beispiel #19
0
 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)
Beispiel #20
0
 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
Beispiel #21
0
 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
Beispiel #22
0
 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
Beispiel #23
0
 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)
Beispiel #24
0
 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']]
Beispiel #25
0
 def symlink(self, target, source):
     raise fusepy.FuseOSError(errno.ENOTSUP)
Beispiel #26
0
 def access(self, path, mode):
     if not os.access(path, mode):
         raise fuse.FuseOSError(errno.EACCES)