Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
sftp_handle.py197 linesDownload Raw Back to paramiko
1# Copyright (C) 2003-2007  Robey Pointer <robeypointer@gmail.com>2#3# This file is part of paramiko.4#5# Paramiko is free software; you can redistribute it and/or modify it under the6# terms of the GNU Lesser General Public License as published by the Free7# Software Foundation; either version 2.1 of the License, or (at your option)8# any later version.9#10# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY11# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR12# A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more13# details.14#15# You should have received a copy of the GNU Lesser General Public License16# along with Paramiko; if not, write to the Free Software Foundation, Inc.,17# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.18 19"""20Abstraction of an SFTP file handle (for server mode).21"""22 23import os24from paramiko.sftp import SFTP_OP_UNSUPPORTED, SFTP_OK25from paramiko.util import ClosingContextManager26 27 28class SFTPHandle(ClosingContextManager):29    """30    Abstract object representing a handle to an open file (or folder) in an31    SFTP server implementation.  Each handle has a string representation used32    by the client to refer to the underlying file.33 34    Server implementations can (and should) subclass SFTPHandle to implement35    features of a file handle, like `stat` or `chattr`.36 37    Instances of this class may be used as context managers.38    """39 40    def __init__(self, flags=0):41        """42        Create a new file handle representing a local file being served over43        SFTP.  If ``flags`` is passed in, it's used to determine if the file44        is open in append mode.45 46        :param int flags: optional flags as passed to47            `.SFTPServerInterface.open`48        """49        self.__flags = flags50        self.__name = None51        # only for handles to folders:52        self.__files = {}53        self.__tell = None54 55    def close(self):56        """57        When a client closes a file, this method is called on the handle.58        Normally you would use this method to close the underlying OS level59        file object(s).60 61        The default implementation checks for attributes on ``self`` named62        ``readfile`` and/or ``writefile``, and if either or both are present,63        their ``close()`` methods are called.  This means that if you are64        using the default implementations of `read` and `write`, this65        method's default implementation should be fine also.66        """67        readfile = getattr(self, "readfile", None)68        if readfile is not None:69            readfile.close()70        writefile = getattr(self, "writefile", None)71        if writefile is not None:72            writefile.close()73 74    def read(self, offset, length):75        """76        Read up to ``length`` bytes from this file, starting at position77        ``offset``.  The offset may be a Python long, since SFTP allows it78        to be 64 bits.79 80        If the end of the file has been reached, this method may return an81        empty string to signify EOF, or it may also return ``SFTP_EOF``.82 83        The default implementation checks for an attribute on ``self`` named84        ``readfile``, and if present, performs the read operation on the Python85        file-like object found there.  (This is meant as a time saver for the86        common case where you are wrapping a Python file object.)87 88        :param offset: position in the file to start reading from.89        :param int length: number of bytes to attempt to read.90        :return: the `bytes` read, or an error code `int`.91        """92        readfile = getattr(self, "readfile", None)93        if readfile is None:94            return SFTP_OP_UNSUPPORTED95        try:96            if self.__tell is None:97                self.__tell = readfile.tell()98            if offset != self.__tell:99                readfile.seek(offset)100                self.__tell = offset101            data = readfile.read(length)102        except IOError as e:103            self.__tell = None104            return SFTPServer.convert_errno(e.errno)105        self.__tell += len(data)106        return data107 108    def write(self, offset, data):109        """110        Write ``data`` into this file at position ``offset``.  Extending the111        file past its original end is expected.  Unlike Python's normal112        ``write()`` methods, this method cannot do a partial write: it must113        write all of ``data`` or else return an error.114 115        The default implementation checks for an attribute on ``self`` named116        ``writefile``, and if present, performs the write operation on the117        Python file-like object found there.  The attribute is named118        differently from ``readfile`` to make it easy to implement read-only119        (or write-only) files, but if both attributes are present, they should120        refer to the same file.121 122        :param offset: position in the file to start reading from.123        :param bytes data: data to write into the file.124        :return: an SFTP error code like ``SFTP_OK``.125        """126        writefile = getattr(self, "writefile", None)127        if writefile is None:128            return SFTP_OP_UNSUPPORTED129        try:130            # in append mode, don't care about seeking131            if (self.__flags & os.O_APPEND) == 0:132                if self.__tell is None:133                    self.__tell = writefile.tell()134                if offset != self.__tell:135                    writefile.seek(offset)136                    self.__tell = offset137            writefile.write(data)138            writefile.flush()139        except IOError as e:140            self.__tell = None141            return SFTPServer.convert_errno(e.errno)142        if self.__tell is not None:143            self.__tell += len(data)144        return SFTP_OK145 146    def stat(self):147        """148        Return an `.SFTPAttributes` object referring to this open file, or an149        error code.  This is equivalent to `.SFTPServerInterface.stat`, except150        it's called on an open file instead of a path.151 152        :return:153            an attributes object for the given file, or an SFTP error code154            (like ``SFTP_PERMISSION_DENIED``).155        :rtype: `.SFTPAttributes` or error code156        """157        return SFTP_OP_UNSUPPORTED158 159    def chattr(self, attr):160        """161        Change the attributes of this file.  The ``attr`` object will contain162        only those fields provided by the client in its request, so you should163        check for the presence of fields before using them.164 165        :param .SFTPAttributes attr: the attributes to change on this file.166        :return: an `int` error code like ``SFTP_OK``.167        """168        return SFTP_OP_UNSUPPORTED169 170    # ...internals...171 172    def _set_files(self, files):173        """174        Used by the SFTP server code to cache a directory listing.  (In175        the SFTP protocol, listing a directory is a multi-stage process176        requiring a temporary handle.)177        """178        self.__files = files179 180    def _get_next_files(self):181        """182        Used by the SFTP server code to retrieve a cached directory183        listing.184        """185        fnlist = self.__files[:16]186        self.__files = self.__files[16:]187        return fnlist188 189    def _get_name(self):190        return self.__name191 192    def _set_name(self, name):193        self.__name = name194 195 196from paramiko.sftp_server import SFTPServer197 
codekingpro/portable-devtools · Team Ai