Ejemplo n.º 1
0
 def _close(self, async_=False):
     # We allow double-close without signaling an error, because real
     # Python file objects do.  However, we must protect against actually
     # sending multiple CMD_CLOSE packets, because after we close our
     # handle, the same handle may be re-allocated by the server, and we
     # may end up mysteriously closing some random other file.  (This is
     # especially important because we unconditionally call close() from
     # __del__.)
     if self._closed:
         return
     self.sftp._log(DEBUG, 'close({})'.format(u(hexlify(self.handle))))
     if self.pipelined:
         self.sftp._finish_responses(self)
     BufferedFile.close(self)
     try:
         if async_:
             # GC'd file handle could be called from an arbitrary thread
             # -- don't wait for a response
             self.sftp._async_request(type(None), CMD_CLOSE, self.handle)
         else:
             self.sftp._request(CMD_CLOSE, self.handle)
     except EOFError:
         # may have outlived the Transport connection
         pass
     except (IOError, socket.error):
         # may have outlived the Transport connection
         pass
Ejemplo n.º 2
0
    def get_base64(self):
        """
        Return a base64 string containing the public part of this key.  Nothing
        secret is revealed.  This format is compatible with that used to store
        public key files or recognized host keys.

        :return: a base64 `string <str>` containing the public part of the key.
        """
        return u(encodebytes(self.asbytes())).replace('\n', '')
Ejemplo n.º 3
0
    def getcwd(self):
        """
        Return the "current working directory" for this SFTP session, as
        emulated by Paramiko.  If no directory has been set with `chdir`,
        this method will return ``None``.

        .. versionadded:: 1.4
        """
        # TODO: make class initialize with self._cwd set to self.normalize('.')
        return self._cwd and u(self._cwd)
Ejemplo n.º 4
0
    def open(self, filename, mode='r', bufsize=-1):
        """
        Open a file on the remote server.  The arguments are the same as for
        Python's built-in `python:file` (aka `python:open`).  A file-like
        object is returned, which closely mimics the behavior of a normal
        Python file object, including the ability to be used as a context
        manager.

        The mode indicates how the file is to be opened: ``'r'`` for reading,
        ``'w'`` for writing (truncating an existing file), ``'a'`` for
        appending, ``'r+'`` for reading/writing, ``'w+'`` for reading/writing
        (truncating an existing file), ``'a+'`` for reading/appending.  The
        Python ``'b'`` flag is ignored, since SSH treats all files as binary.
        The ``'U'`` flag is supported in a compatible way.

        Since 1.5.2, an ``'x'`` flag indicates that the operation should only
        succeed if the file was created and did not previously exist.  This has
        no direct mapping to Python's file flags, but is commonly known as the
        ``O_EXCL`` flag in posix.

        The file will be buffered in standard Python style by default, but
        can be altered with the ``bufsize`` parameter.  ``0`` turns off
        buffering, ``1`` uses line buffering, and any number greater than 1
        (``>1``) uses that specific buffer size.

        :param str filename: name of the file to open
        :param str mode: mode (Python-style) to open in
        :param int bufsize: desired buffering (-1 = default buffer size)
        :return: an `.SFTPFile` object representing the open file

        :raises: ``IOError`` -- if the file could not be opened.
        """
        filename = self._adjust_cwd(filename)
        self._log(DEBUG, 'open({!r}, {!r})'.format(filename, mode))
        imode = 0
        if ('r' in mode) or ('+' in mode):
            imode |= SFTP_FLAG_READ
        if ('w' in mode) or ('+' in mode) or ('a' in mode):
            imode |= SFTP_FLAG_WRITE
        if 'w' in mode:
            imode |= SFTP_FLAG_CREATE | SFTP_FLAG_TRUNC
        if 'a' in mode:
            imode |= SFTP_FLAG_CREATE | SFTP_FLAG_APPEND
        if 'x' in mode:
            imode |= SFTP_FLAG_CREATE | SFTP_FLAG_EXCL
        attrblock = SFTPAttributes()
        t, msg = self._request(CMD_OPEN, filename, imode, attrblock)
        if t != CMD_HANDLE:
            raise SFTPError('Expected handle')
        handle = msg.get_binary()
        self._log(
            DEBUG,
            'open({!r}, {!r}) -> {}'.format(filename, mode, u(hexlify(handle)))
        )
        return SFTPFile(self, handle, mode, bufsize)
Ejemplo n.º 5
0
 def readline(self, timeout):
     """
     Read a line from the socket.  We assume no data is pending after the
     line, so it's okay to attempt large reads.
     """
     buf = self.__remainder
     while linefeed_byte not in buf:
         buf += self._read_timeout(timeout)
     n = buf.index(linefeed_byte)
     self.__remainder = buf[n + 1:]
     buf = buf[:n]
     if (len(buf) > 0) and (buf[-1] == cr_byte_value):
         buf = buf[:-1]
     return u(buf)
Ejemplo n.º 6
0
 def __enter__(self):
     p_SA = (ctypes.byref(self.security_attributes)
             if self.security_attributes else None)
     INVALID_HANDLE_VALUE = -1
     PAGE_READWRITE = 0x4
     FILE_MAP_WRITE = 0x2
     filemap = ctypes.windll.kernel32.CreateFileMappingW(
         INVALID_HANDLE_VALUE, p_SA, PAGE_READWRITE, 0, self.length,
         u(self.name))
     handle_nonzero_success(filemap)
     if filemap == INVALID_HANDLE_VALUE:
         raise Exception("Failed to create file mapping")
     self.filemap = filemap
     self.view = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0)
     return self
Ejemplo n.º 7
0
    def readline(self, size=None):
        """
        Read one entire line from the file.  A trailing newline character is
        kept in the string (but may be absent when a file ends with an
        incomplete line).  If the size argument is present and non-negative, it
        is a maximum byte count (including the trailing newline) and an
        incomplete line may be returned.  An empty string is returned only when
        EOF is encountered immediately.

        .. note::
            Unlike stdio's ``fgets``, the returned string contains null
            characters (``'\\0'``) if they occurred in the input.

        :param int size: maximum length of returned string.
        :returns:
            next line of the file, or an empty string if the end of the
            file has been reached.

            If the file was opened in binary (``'b'``) mode: bytes are returned
            Else: the encoding of the file is assumed to be UTF-8 and character
            strings (`str`) are returned
        """
        # it's almost silly how complex this function is.
        if self._closed:
            raise IOError('File is closed')
        if not (self._flags & self.FLAG_READ):
            raise IOError('File not open for reading')
        line = self._rbuffer
        truncated = False
        while True:
            if (self._at_trailing_cr
                    and self._flags & self.FLAG_UNIVERSAL_NEWLINE
                    and len(line) > 0):
                # edge case: the newline may be '\r\n' and we may have read
                # only the first '\r' last time.
                if line[0] == linefeed_byte_value:
                    line = line[1:]
                    self._record_newline(crlf)
                else:
                    self._record_newline(cr_byte)
                self._at_trailing_cr = False
            # check size before looking for a linefeed, in case we already have
            # enough.
            if (size is not None) and (size >= 0):
                if len(line) >= size:
                    # truncate line
                    self._rbuffer = line[size:]
                    line = line[:size]
                    truncated = True
                    break
                n = size - len(line)
            else:
                n = self._bufsize
            if (linefeed_byte in line
                    or (self._flags & self.FLAG_UNIVERSAL_NEWLINE
                        and cr_byte in line)):
                break
            try:
                new_data = self._read(n)
            except EOFError:
                new_data = None
            if (new_data is None) or (len(new_data) == 0):
                self._rbuffer = bytes()
                self._pos += len(line)
                return line if self._flags & self.FLAG_BINARY else u(line)
            line += new_data
            self._realpos += len(new_data)
        # find the newline
        pos = line.find(linefeed_byte)
        if self._flags & self.FLAG_UNIVERSAL_NEWLINE:
            rpos = line.find(cr_byte)
            if (rpos >= 0) and (rpos < pos or pos < 0):
                pos = rpos
        if pos == -1:
            # we couldn't find a newline in the truncated string, return it
            self._pos += len(line)
            return line if self._flags & self.FLAG_BINARY else u(line)
        xpos = pos + 1
        if (line[pos] == cr_byte_value and xpos < len(line)
                and line[xpos] == linefeed_byte_value):
            xpos += 1
        # if the string was truncated, _rbuffer needs to have the string after
        # the newline character plus the truncated part of the line we stored
        # earlier in _rbuffer
        if truncated:
            self._rbuffer = line[xpos:] + self._rbuffer
        else:
            self._rbuffer = line[xpos:]

        lf = line[pos:xpos]
        line = line[:pos] + linefeed_byte
        if (len(self._rbuffer) == 0) and (lf == cr_byte):
            # we could read the line up to a '\r' and there could still be a
            # '\n' following that we read next time.  note that and eat it.
            self._at_trailing_cr = True
        else:
            self._record_newline(lf)
        self._pos += len(line)
        return line if self._flags & self.FLAG_BINARY else u(line)
Ejemplo n.º 8
0
 def get_text(self):
     """
     Fetch a Unicode string from the stream.
     """
     return u(self.get_string())