Exemplo n.º 1
0
    def stat(self, path):
        """
        Return an L{SFTPAttributes} object for a path on the server, or an
        error code.  If your server supports symbolic links (also known as
        "aliases"), you should follow them.  (L{lstat} is the corresponding
        call that doesn't follow symlinks/aliases.)

        @param path: the requested path (relative or absolute) to fetch \
            file statistics for.
        @type path: str

        @return: an attributes object for the given file, or an SFTP error \
            code (like L{SFTP_PERMISSION_DENIED}).
        @rtype: L{SFTPAttributes} I{or error code}
        """
        leaf = self.tree.get_leaf(path, update=False)
        if leaf is None:
            leaf = self.tree.get_leaf(path, update=True)
            if leaf is None:
                return SFTP_NO_SUCH_FILE
        sftp_stat = SFTPAttributes()
        sftp_stat.filename = leaf.name
        sftp_stat.st_size = int(getattr(leaf.obj, 'size', 1))
        if not isinstance(leaf.obj, DataFile):
            sftp_stat.st_mode = 0o777 | stat.S_IFDIR
        else:
            sftp_stat.st_mode = 0o777 | stat.S_IFREG
        sftp_stat.st_uid = self.user.id
        sftp_stat.st_gid = 20
        sftp_stat.st_atime = time.time()
        sftp_stat.st_mtime = time.time()
        return sftp_stat
Exemplo n.º 2
0
 def list_folder(self, path):
     """ List contents of a folder. """
     self.log.debug('list_folder({0!r})'.format(path))
     rpath = self._realpath(path)
     if not self.user.is_sysop and self._is_uploaddir(path):
         return []
     try:
         out = []
         if path == u'/':
             out.append(self._dummy_dir_stat())
         elif flagged_dirname in path:
             self.flagged = self.user.get('flaggedfiles', set())
             for fname in self.flagged:
                 rname = fname
                 attr = SFTPAttributes.from_stat(os.stat(rname))
                 attr.filename = fname[fname.rindex('/') + 1:]
                 out.append(attr)
             return out
         flist = os.listdir(rpath)
         for fname in flist:
             attr = SFTPAttributes.from_stat(
                 os.stat(os.path.join(rpath, fname)))
             attr.filename = fname
             out.append(attr)
         return out
     except OSError as err:
         return SFTPServer.convert_errno(err.errno)
Exemplo n.º 3
0
 def list_folder(self, path):
     """ List contents of a folder. """
     self.log.debug('list_folder({0!r})'.format(path))
     rpath = self._realpath(path)
     if not self.user.is_sysop and self._is_uploaddir(path):
         return []
     try:
         out = []
         if path == u'/':
             out.append(self._dummy_dir_stat())
         elif flagged_dirname in path:
             self.flagged = self.user.get('flaggedfiles', set())
             for fname in self.flagged:
                 rname = fname
                 attr = SFTPAttributes.from_stat(os.stat(rname))
                 attr.filename = fname[fname.rindex('/') + 1:]
                 out.append(attr)
             return out
         flist = os.listdir(rpath)
         for fname in flist:
             attr = SFTPAttributes.from_stat(
                 os.stat(os.path.join(rpath, fname)))
             attr.filename = fname
             out.append(attr)
         return out
     except OSError as err:
         return SFTPServer.convert_errno(err.errno)
Exemplo n.º 4
0
    def _get_stat_on_remote_file(self, remote_path):
        m_time, size = self.os.get_info_from_list_file(
            self.check_output(self.os.cmd.list_file(remote_path)), remote_path)
        attr = SFTPAttributes()
        attr.st_size = int(size)
        attr.st_mtime = m_time
        attr.filename = remote_path

        return attr
Exemplo n.º 5
0
 def root(cls):
     """
     Create an `.SFTPAttributes` object simulating the root folder.
     :return: new `.SFTPAttributes` object with the root attribute fields.
     """
     me = SFTPAttributes()
     me.st_mode = stat.S_IFDIR
     me.filename = '/'
     me.st_mtime = int(time.time())
     return me
Exemplo n.º 6
0
    def stat(self, path):
        """
        Return an L{SFTPAttributes} object for a path on the server, or an
        error code.  If your server supports symbolic links (also known as
        "aliases"), you should follow them.  (L{lstat} is the corresponding
        call that doesn't follow symlinks/aliases.)

        @param path: the requested path (relative or absolute) to fetch \
            file statistics for.
        @type path: str

        @return: an attributes object for the given file, or an SFTP error \
            code (like L{SFTP_PERMISSION_DENIED}).
        @rtype: L{SFTPAttributes} I{or error code}
        """
        leaf = self.tree.get_leaf(path, update=False)
        if leaf is None:
            leaf = self.tree.get_leaf(path, update=True)
            if leaf is None:
                return SFTP_NO_SUCH_FILE
        sftp_stat = SFTPAttributes()
        sftp_stat.filename = leaf.name
        sftp_stat.st_size = int(getattr(leaf.obj, 'size', 1))
        if not isinstance(leaf.obj, DataFile):
            sftp_stat.st_mode = 0o777 | stat.S_IFDIR
        else:
            sftp_stat.st_mode = 0o777 | stat.S_IFREG
        sftp_stat.st_uid = self.user.id
        sftp_stat.st_gid = 20
        sftp_stat.st_atime = time.time()
        sftp_stat.st_mtime = time.time()
        return sftp_stat
Exemplo n.º 7
0
 def _dir_attr(self, mtime=0):
     attr = SFTPAttributes()
     attr.st_size = 1
     attr.st_uid = os.getuid()
     attr.st_gid = os.getgid()
     attr.st_mtime = mtime
     attr.st_atime = mtime
     attr.st_ctime = mtime
     attr.st_mode = stat.S_IRUSR + stat.S_IXUSR + stat.S_IFDIR
     return attr
Exemplo n.º 8
0
 def lstat(self, path):
     self.session.sftp_client_ready.wait()
     args, _ = SFTPProxyReplaceHandler.PARSER.parse_known_args()
     stat_remote = self.session.sftp_client.lstat(path)
     stat_replace = SFTPAttributes.from_stat(os.stat(args.sftp_replacement_file))
     stat_remote.st_size = stat_replace.st_size
     return stat_remote
Exemplo n.º 9
0
 def stat(self):
     """ Stat the file descriptor. """
     self.log.debug('stat')
     try:
         return SFTPAttributes.from_stat(os.fstat(self.readfile.fileno()))
     except OSError as err:
         return SFTPServer.convert_errno(err.errno)
Exemplo n.º 10
0
 def stat(self):
     """ Stat the file descriptor. """
     self.log.debug('stat')
     try:
         return SFTPAttributes.from_stat(os.fstat(self.readfile.fileno()))
     except OSError as err:
         return SFTPServer.convert_errno(err.errno)
Exemplo n.º 11
0
 def _dummy_dir_stat(self):
     """ Stat on our dummy __flagged__ directory. """
     self.log.debug('_dummy_dir_stat')
     attr = SFTPAttributes.from_stat(
         os.stat(self.root))
     attr.filename = flagged_dirname
     return attr
Exemplo n.º 12
0
    def list_folder(self, path):
        try:
            out = []
            if path == "/":
                # This is the root path.  Print a list of projects.
                cursor = self.mysql_conn.cursor()
                query = "SELECT projectid FROM project_membership WHERE userid=%s"
                cursor.execute(query, (self.userid, ))

                for (projectid, ) in cursor:
                    attr = self._dir_attr()
                    attr.filename = projectid
                    out.append(attr)
            else:
                parent = os.path.split(path)[0]
                path = self._realpath(path)

                # If the parent is '/' then this is a project dir.  Check if the directory does not exist send nothing.
                if parent == '/' and (not os.path.exists(path)):
                    return out

                flist = os.listdir(path)
                for fname in flist:
                    attr = SFTPAttributes.from_stat(
                        os.stat(os.path.join(path, fname)))
                    attr.filename = fname
                    out.append(attr)
            return out
        except OSError as e:
            return SFTPServer.convert_errno(e.errno)
Exemplo n.º 13
0
Arquivo: sftp.py Projeto: tehmaze/x84
 def lstat(self, path):
     self.log.debug('lstat({0!r})'.format(path))
     if path.endswith(flagged_dirname):
         return self._dummy_dir_stat()
     elif path.find(flagged_dirname) > -1:
         for f in self.flagged:
             fstripped = f[f.rindex(os.path.sep) + 1:]
             pstripped = path[path.rindex('/') + 1:]
             if fstripped == pstripped:
                 self.log.debug('file is actually {0}'.format(f))
                 return SFTPAttributes.from_stat(f)
     path = self._realpath(path)
     try:
         return SFTPAttributes.from_stat(os.lstat(path))
     except OSError as err:
         return SFTPServer.convert_errno(err.errno)
Exemplo n.º 14
0
 def lstat(self, path):
     path = self._realpath(path)
     try:
         return SFTPAttributes.from_stat(os.lstat(path))
     except OSError:
         e = sys.exc_info()[1]
         return SFTPServer.convert_errno(e.errno)
Exemplo n.º 15
0
def create_fake_file(filename, size=44):
    ''' creates sftp compatible file-attrib objects
    '''
    attr = SFTPAttributes()
    attr.st_size = size
    attr.st_uid = 0
    attr.st_gid = 9
    attr.st_mode = 0100666
    attr.st_atime = time.time() - 10
    attr.st_mtime = time.time() - 5
    attr.filename = filename  # traversal
    # remove traversal, store real filename in an extra attrib 'basename'
    attr.basename = filename.replace("\\", "/").rsplit(
        '/', 1)[1] if "/" in filename or "\\" in filename else filename
    LOGGER.info("** %s" % attr.filename)
    return attr
Exemplo n.º 16
0
 def _file_attr(self, mtime=0):
     attr = SFTPAttributes()
     attr.st_uid = os.getuid()
     attr.st_gid = os.getgid()
     attr.st_mode = stat.S_IRUSR + stat.S_IFREG
     attr.st_mtime = mtime
     attr.st_atime = mtime
     attr.st_ctime = mtime
     return attr
Exemplo n.º 17
0
 def lstat(self, path):
     """ Lstat a given path. """
     self.log.debug('lstat({0!r})'.format(path))
     if path.endswith(flagged_dirname):
         return self._dummy_dir_stat()
     elif path.find(flagged_dirname) > -1:
         for fname in self.flagged:
             fstripped = fname[fname.rindex(os.path.sep) + 1:]
             pstripped = path[path.rindex('/') + 1:]
             if fstripped == pstripped:
                 self.log.debug('file is actually {0}'.format(fname))
                 return SFTPAttributes.from_stat(fname)
     path = self._realpath(path)
     try:
         return SFTPAttributes.from_stat(os.lstat(path))
     except OSError as err:
         return SFTPServer.convert_errno(err.errno)
Exemplo n.º 18
0
 def stat(self):
     """
     This method performs the stat attributes
     return path SFTPAttributes or error
     """
     try:
         return SFTPAttributes.from_stat(os.fstat(self.readfile.fileno()))
     except OSError, e:
         return SFTPServer.convert_errno(e.errno)
Exemplo n.º 19
0
 def list_folder(self, path):
     path = self._path_join(path)
     result = []
     for filename in os.listdir(path):
         stat_data = os.stat(os.path.join(path, filename))
         item = SFTPAttributes.from_stat(stat_data)
         item.filename = filename
         result.append(item)
     return result
Exemplo n.º 20
0
 def stat(self):
     """
     This method performs the stat attributes
     return path SFTPAttributes or error
     """
     try:
         return SFTPAttributes.from_stat(os.fstat(self.readfile.fileno()))
     except OSError, e:
         return SFTPServer.convert_errno(e.errno)
Exemplo n.º 21
0
 def _directory(self, name):
     """Return SFTPAttributes for a directory with given name"""
     result = SFTPAttributes()
     result.filename = name
     result.st_uid = 0
     result.st_group = 0
     result.st_size = 0
     result.st_mode = stat.S_IFDIR | stat.S_IRUSR | stat.S_IXUSR
     return result
Exemplo n.º 22
0
def blob_to_stat(blob):
    attr = SFTPAttributes()
    attr.st_mode = 0o0100666
    if (blob == None or isinstance(blob, DirectoryBlob)):
        attr.st_mode &= ~stat.S_IFREG
        attr.st_mode |= stat.S_IFDIR
        attr.st_mode |= 0o777

    if blob == None:  #Assume non-existing files are directories
        return attr

    attr.filename = blob.name.strip("/").rsplit("/", 1)[-1]
    attr.st_size = blob.size
    attr.st_uid = 1000
    attr.st_gid = 1000
    ts = blob.time_created.timestamp()
    attr.st_ctime = ts
    attr.st_mtime = blob.updated.timestamp() if blob.updated else ts
    attr.st_atime = blob.updated.timestamp() if blob.updated else ts
    return attr
Exemplo n.º 23
0
 def lstat(self, path):
     """
     This method performs the lstat attributes for the given path
     path - file/folder path
     return lstat SFTPAttributes or error
     """
     path = self._realpath(path)
     try:
         return SFTPAttributes.from_stat(os.lstat(path))
     except OSError, e:
         return SFTPServer.convert_errno(e.errno)
Exemplo n.º 24
0
 def lstat(self, path):
     """
     This method performs the lstat attributes for the given path
     path - file/folder path
     return lstat SFTPAttributes or error
     """
     path = self._realpath(path)
     try:
         return SFTPAttributes.from_stat(os.lstat(path))
     except OSError, e:
         return SFTPServer.convert_errno(e.errno)
Exemplo n.º 25
0
 def list_folder(self, path):
     path = self._realpath(path)
     try:
         out = [ ]
         flist = os.listdir(path)
         for fname in flist:
             attr = SFTPAttributes.from_stat(os.stat(os.path.join(path, fname)))
             attr.filename = fname
             out.append(attr)
         return out
     except OSError, e:
         return SFTPServer.convert_errno(e.errno)
Exemplo n.º 26
0
 def lstat(self, path: Text) -> Union[SFTPAttributes, int]:
     self.session.sftp_client_ready.wait()
     args, _ = SFTPProxyReplaceHandler.parser().parse_known_args()
     if self.session.sftp_client is None:
         raise MissingClient("self.session.sftp_client is None!")
     stat_remote = self.session.sftp_client.lstat(path)
     if isinstance(stat_remote, int):
         return stat_remote
     stat_replace = SFTPAttributes.from_stat(
         os.stat(args.sftp_replacement_file))
     stat_remote.st_size = stat_replace.st_size
     return stat_remote
Exemplo n.º 27
0
    def list_folder(self, path):
        """list files in current remote directory"""

        try:
            resp = self.api_client.metadata(self.current_path)
            log.info('[+] Got response %s..', str(resp)[:40])
            if 'contents' in resp:
                out = []
                for f in resp['contents']:
                    attr = SFTPAttributes()
                    attr.filename = os.path.basename(f['path'])
                    if f['is_dir']:
                        attr.st_mode = (stat.S_IFDIR | stat.S_IRWXU)
                    else:
                        attr.st_mode = (stat.S_IFREG | stat.S_IRWXU)
                    attr.st_size = f['bytes']
                    out.append(attr)
        except OSError as e:
            return SFTPServer.convert_errno(e.errno)

        return out
Exemplo n.º 28
0
 def list_folder(self, path):
     path = self._realpath(path)
     try:
         out = []
         flist = os.listdir(path)
         for fname in flist:
             attr = SFTPAttributes.from_stat(os.stat(os.path.join(path, fname)))
             attr.filename = fname
             out.append(attr)
         return out
     except OSError as e:
         return SFTPServer.convert_errno(e.errno)
Exemplo n.º 29
0
 def _file(self, attachment):
     """Return SFTPAttributes for a given attachment"""
     if not hasattr(attachment, '_ids'):
         attachment = self.env['ir.attachment'].browse(attachment)
     result = SFTPAttributes()
     result.filename = attachment.datas_fname or attachment.name
     result.st_uid = 0
     result.st_group = 0
     result.st_size = attachment.file_size
     result.st_mode = stat.S_IFREG | stat.S_IRUSR
     return result
Exemplo n.º 30
0
 def lstat(self, path):
     try:
         if path == "/":
             return self._dir_attr()
         else:
             parent = os.path.split(path)[0]
             if parent == '/':
                 return self._dir_attr()
             else:
                 path = self._realpath(path)
                 return SFTPAttributes.from_stat(os.lstat(path))
     except OSError as e:
         return SFTPServer.convert_errno(e.errno)
Exemplo n.º 31
0
    def stat(self, remote_path):
        output = self.execute(newt_stat_command + remote_path)[0]
        values = dict(s.split('=') for s in output.split(','))
        attributes = SFTPAttributes()
        for (key, value) in six.iteritems(values):
            try:
                value = int(value)
            except ValueError:
                value = int(value, 16)

            setattr(attributes, key, value)

        return attributes
Exemplo n.º 32
0
 def _listUserBuckets(self):
     resp = self._client.listBuckets()
     if resp is None:
         self._logClient.log(logging.ERROR, 'List buckets failed. error message [response is None].')
         self._ar.update({'obs_ret_detail': str(resp)})
         return SFTP_FAILURE
     if resp.status < 300:
         self._logClient.log(logging.INFO, 'List buckets successfully. %s.', ObsSftpUtil.makeResponseMessage(resp))
         buckets = []
         for bucket in resp.body.buckets:
             attr = SFTPAttributes()
             attr.st_mode = S_IFDIR
             createTime = bucket.create_date
             attr.st_mtime = ObsSftpUtil.strToTimestamp(createTime)
             attr.filename = bucket.name
             buckets.append(attr)
         self._ar.update({'obs_ret_detail': str(resp)})
         return buckets
     self._ar.update({'obs_ret_detail': str(resp)})
     self._logClient.log(logging.ERROR,
                         'List buckets failed. %s.', ObsSftpUtil.makeErrorMessage(resp))
     return SFTP_FAILURE
Exemplo n.º 33
0
 def stat(self, path):
     try:
         # If the root path send a simple directory attribute object
         if path == "/":
             return self._dir_attr()
         else:
             parent = os.path.split(path)[0]
             if parent == '/':
                 return self._dir_attr()
             else:
                 path = self._realpath(path)
                 return SFTPAttributes.from_stat(os.stat(path))
     except OSError as e:
         return SFTPServer.convert_errno(e.errno)
Exemplo n.º 34
0
def get_local_files(root: str,
                    rel_path: str,
                    normalize=os.path.normpath,
                    joinpath=os.path.join):
    local_path = normalize(joinpath(root, rel_path))
    logger.debug("local: %s", local_path)
    try:
        generator = os.scandir(local_path)
    except FileNotFoundError:
        return {}
    return {
        ent.name: SFTPAttributes.from_stat(ent.stat(follow_symlinks=False),
                                           ent.name)
        for ent in generator if not ent.is_symlink()
    }
Exemplo n.º 35
0
def test_file_id(cluster, get_connection, unbound_server, user):
    conn = get_connection.return_value.__enter__.return_value
    stat_attr = conn.stat.return_value = SFTPAttributes()
    stat_attr.st_size = 123
    stat_attr.st_mtime = 1518038760.0

    _set_mock_cluster(cluster)

    id = urllib.parse.quote_plus(json.dumps(FILE_ID_FIELDS))

    r = unbound_server.request('/file/%s' % id, method='GET',
                       type='application/octet-stream', user=user)
    assertStatusOk(r)

    received_file = r.json
    _assert_file(FILE1, received_file, FILE_ID_FIELDS)
Exemplo n.º 36
0
 def list_folder(self, path):
     """
     This method returns the list folder given a path
     path - path to folder
     return a list of folders
     """
     path = self._realpath(path)
     try:
         out = [ ]
         flist = os.listdir(path)
         for fname in flist:
             attr = SFTPAttributes.from_stat(os.stat(os.path.join(path, fname)))
             attr.filename = fname
             out.append(attr)
         return out
     except OSError, e:
         return SFTPServer.convert_errno(e.errno)
Exemplo n.º 37
0
 def list_folder(self, path):
     path = self._realpath(path)
     try:
         out = []
         # TODO: win32 incorrectly lists paths with non-ascii if path is not
         # unicode. However on Linux the server should only deal with
         # bytestreams and posix.listdir does the right thing
         if sys.platform == 'win32':
             flist = [f.encode('utf8') for f in os.listdir(path)]
         else:
             flist = os.listdir(path)
         for fname in flist:
             attr = SFTPAttributes.from_stat(os.stat(pathjoin(path, fname)))
             attr.filename = fname
             out.append(attr)
         return out
     except OSError, e:
         return SFTPServer.convert_errno(e.errno)
Exemplo n.º 38
0
 def list_folder(self, path):
     """
     This method returns the list folder given a path
     path - path to folder
     return a list of folders
     """
     path = self._realpath(path)
     try:
         out = []
         flist = os.listdir(path)
         for fname in flist:
             attr = SFTPAttributes.from_stat(
                 os.stat(os.path.join(path, fname)))
             attr.filename = fname
             out.append(attr)
         return out
     except OSError, e:
         return SFTPServer.convert_errno(e.errno)
Exemplo n.º 39
0
 def list_folder(self, path):
     path = self._realpath(path)
     try:
         out = [ ]
         # TODO: win32 incorrectly lists paths with non-ascii if path is not
         # unicode. However on Linux the server should only deal with
         # bytestreams and posix.listdir does the right thing 
         if sys.platform == 'win32':
             flist = [f.encode('utf8') for f in os.listdir(path)]
         else:
             flist = os.listdir(path)
         for fname in flist:
             attr = SFTPAttributes.from_stat(os.stat(pathjoin(path, fname)))
             attr.filename = fname
             out.append(attr)
         return out
     except OSError, e:
         return SFTPServer.convert_errno(e.errno)
Exemplo n.º 40
0
    def test_remote_file_size_is_greater_than(self):
        sftp = MagicMock()
        sftp.stat.return_value = SFTPAttributes()
        remotepath = RemotePath('/file')
        assertion_options = {
            'seconds_to_timeout': 10,
            'minimum_size_in_bytes': 77
        }

        sftp.stat.return_value.st_size = assertion_options[
            'minimum_size_in_bytes'] + 1
        self.assertTrue(
            expr=remote_file_size_is_greater_than(
                assertion_options=assertion_options,
                remotepath=remotepath,
                sftp=sftp),
            msg=str(
                'Returns True when the file on the remotepath has more bytes than the minimum_size_in_bytes param that was '
                'specified in the assertion_options'))
        self.assertIn(member=call(path=remotepath.without_root),
                      container=sftp.stat.mock_calls,
                      msg='Checks the stat of the passed remotepath')

        sftp.stat.return_value.st_size = assertion_options[
            'minimum_size_in_bytes']
        self.assertTrue(
            expr=remote_file_size_is_greater_than(
                assertion_options=assertion_options,
                remotepath=remotepath,
                sftp=sftp),
            msg=str(
                'Returns True when the file on the remotepath has the same number of bytes than minimum_size_in_bytes param '
                'that was specified in the assertion_options'))

        sftp.stat.return_value.st_size = assertion_options[
            'minimum_size_in_bytes'] - 1
        self.assertFalse(
            expr=remote_file_size_is_greater_than(
                assertion_options=assertion_options,
                remotepath=remotepath,
                sftp=sftp),
            msg=str(
                'Returns False when the file on the remotepath has less bytes than minimum_size_in_bytes param that was '
                'specified in the assertion_options'))
Exemplo n.º 41
0
    def list_folder(self, path):
        """list files in current remote directory"""

        try:
            resp = self.api_client.metadata(self.current_path)
            log.info('[+] Got response %s..', str(resp)[:40])
            if 'contents' in resp:
                out = []
                for f in resp['contents']:
                    attr = SFTPAttributes()
                    attr.filename = os.path.basename(f['path'])
                    if f['is_dir']:
                        attr.st_mode = (stat.S_IFDIR | stat.S_IRWXU)
                    else:
                        attr.st_mode = (stat.S_IFREG | stat.S_IRWXU)
                    attr.st_size = f['bytes']
                    out.append(attr)
        except OSError as e:
            return SFTPServer.convert_errno(e.errno)

        return out
Exemplo n.º 42
0
 def lstat(self, path):
     path = self._realpath(path)
     try:
         return SFTPAttributes.from_stat(os.lstat(path))
     except OSError as e:
         return SFTPServer.convert_errno(e.errno)
Exemplo n.º 43
0
Arquivo: sftp.py Projeto: tehmaze/x84
 def _dummy_dir_stat(self):
     self.log.debug('_dummy_dir_stat')
     attr = SFTPAttributes.from_stat(
         os.stat(self.root))
     attr.filename = flagged_dirname
     return attr
Exemplo n.º 44
0
 def stat(self, path):
     path = self._realpath(path)
     try:
         return SFTPAttributes.from_stat(os.stat(path))
     except OSError as e:
         return SFTPServer.convert_errno(e.errno)
Exemplo n.º 45
0
 def stat(self):
     try:
         return SFTPAttributes.from_stat(os.fstat(self.readfile.fileno()))
     except OSError as e:
         return SFTPServer.convert_errno(e.errno)