def rmdir(self, path): if self.path.isdir(path): code = self._sftp.rmdir(self.path.abspath(path)) while code == ecd.LIBSSH2_ERROR_EAGAIN: utils.wait_socket(self.client.socket, self.client.session) code = self._sftp.rmdir(self.path.abspath(path)) else: raise Exception('PathFiletypeError')
def test_handle_open_nonblocking(self): self._auth() sftp = self.session.sftp_init() self.session.set_blocking(False) try: fh = sftp.open('fakey fake fake', 0, 0) while fh == LIBSSH2_ERROR_EAGAIN: wait_socket(self.sock, self.session) fh = sftp.open('fakey fake fake', 0, 0) except SFTPProtocolError: pass else: raise Exception("Should have raised SFTPProtocolError")
def test_readdir_nonblocking(self): self.assertEqual(self._auth(), 0) sftp = self.session.sftp_init() with sftp.opendir('.') as fh: self.session.set_blocking(False) dir_data = [] for size, buf, attrs in fh.readdir(): if size == LIBSSH2_ERROR_EAGAIN: wait_socket(self.sock, self.session) continue dir_data.append(buf) self.assertTrue(len(dir_data) > 0) self.assertTrue(b'..' in dir_data)
def open(self, file, mode='r'): """ this method opens the file on remote system (if possible) and returns a corresponding file object. sftp only handle binary mode so 't' and 'b' cannot be used as mode. Args: file(str): path-like object (representing a file system path) giving the pathname mode(str): mode while opening a file. If not provided, it defaults to 'r'. 'r': open a file for reading. (default) 'w': open a file for writing. creates a new file if it does not exist or truncates the file if it exists. 'x': open a file for exclusive creation. If the file already exists, the operation fails 'a': open for appending at the end of the file without truncating it, creates a new file if it does not exist. '+': open a file for updating (reading and writing) Returns: """ f_flags = 0 rw_flag = 0 for code in mode: if code == 'r': rw_flag = flags.LIBSSH2_FXF_READ elif code == 'w': rw_flag = flags.LIBSSH2_FXF_WRITE f_flags = f_flags | flags.LIBSSH2_FXF_CREAT | flags.LIBSSH2_FXF_TRUNC elif code == 'x': rw_flag = flags.LIBSSH2_FXF_WRITE f_flags = f_flags | flags.LIBSSH2_FXF_EXCL | flags.LIBSSH2_FXF_CREAT elif code == 'a': rw_flag = flags.LIBSSH2_FXF_WRITE f_flags = f_flags | flags.LIBSSH2_FXF_APPEND | flags.LIBSSH2_FXF_CREAT elif code == '+': if flags.LIBSSH2_FXF_READ == rw_flag: f_flags = f_flags | flags.LIBSSH2_FXF_WRITE elif flags.LIBSSH2_FXF_WRITE == rw_flag: f_flags = f_flags | flags.LIBSSH2_FXF_READ else: f_flags = f_flags | flags.LIBSSH2_FXF_READ | flags.LIBSSH2_FXF_WRITE else: pass f_flags = f_flags + rw_flag umask = self.umask() f_mode = self.__convert_umask_to_flags(umask) fh = self._sftp.open(file, flags=f_flags, mode=f_mode) while fh is None: utils.wait_socket(self._client.socket, self._client.session) fh = self._sftp.open(file, flags=f_flags, mode=f_mode) return fh # TODO: File handler not compatible with other python modules
def test_non_blocking(self): self.assertEqual(self._auth(), 0) self.session.set_blocking(False) self.assertFalse(self.session.get_blocking()) sftp = self.session.sftp_init() while sftp == LIBSSH2_ERROR_EAGAIN: wait_socket(self.sock, self.session) sftp = self.session.sftp_init() self.assertIsNotNone(sftp) self.assertIsInstance(sftp, SFTP) chan = self.session.open_session() while chan == LIBSSH2_ERROR_EAGAIN: wait_socket(self.sock, self.session) chan = self.session.open_session() self.assertIsInstance(chan, Channel)
def mkdir(self, path, mode=None): dirname = os.path.dirname(path) if len(dirname) == 0: path = self.path.join(self.getcwd(), path) if mode is None: mode = self.__convert_umask_to_flags(self._umask, isdir=True) elif isinstance(mode, int): if len(str(mode)) == 3: mode = int(str(mode), 8) else: raise Exception('ModeValueError') else: raise Exception('ModeTypeError') code = self._sftp.mkdir(path, mode) while code == ecd.LIBSSH2_ERROR_EAGAIN: utils.wait_socket(self.client.socket, self.client.session) self._sftp.mkdir(path, mode)
def main(): args = parser.parse_args() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((args.host, args.port)) s = Session() s.handshake(sock) s.agent_auth(args.user) sftp = s.sftp_init() now = datetime.now() print("Starting read for remote dir %s" % (args.dir, )) with sftp.opendir(args.dir) as fh: # Can set blocking to false at any point, as long as the # libssh2 operations support running in non-blocking mode. s.set_blocking(False) for size, buf, attrs in fh.readdir(): if size == LIBSSH2_ERROR_EAGAIN: print("Would block on readdir, waiting on socket..") wait_socket(sock, s) continue print(buf) print("Finished read dir in %s" % (datetime.now() - now, ))
def exec_command(self, cmd, simple=False): chan = self.session.open_session() if self.__non_block is True: while chan == ecd.LIBSSH2_ERROR_EAGAIN: utils.wait_socket(self.socket, self.session) chan = self.session.open_session() while chan.execute(cmd) == ecd.LIBSSH2_ERROR_EAGAIN: utils.wait_socket(self.socket, self.session) else: chan.execute(cmd) rc1, stdout = chan.read_ex() if self.__non_block is True: while rc1 == ecd.LIBSSH2_ERROR_EAGAIN: rc1, stdout = chan.read_ex() if simple: chan.close() return stdout.decode('ascii') else: rc2, stderr = chan.read_stderr() chan.close() return BytesIO(stdout), BytesIO(stderr)
def listdir(self, path=None, get_attr=False): if path is None: path = '.' dh = self._sftp.opendir(path) while dh == ecd.LIBSSH2_ERROR_EAGAIN: utils.wait_socket(self.client.socket, self.client.session) dh = self._sftp.opendir(path) output = [] for size, buf, attr in dh.readdir(): if size == ecd.LIBSSH2_ERROR_EAGAIN: utils.wait_socket(self.client.socket, self.client.session) continue if get_attr: if buf.decode('ascii') not in ['.', '..']: output.append((buf.decode('ascii'), attr)) else: if buf.decode('ascii') not in ['.', '..']: output.append(buf.decode('ascii')) return output
def set_client(self, client): self._client = client if client.connected: self._sftp = client.open_sftp() while self._sftp is None: utils.wait_socket(client.socket, client.session) self._sftp = client.open_sftp() if self._homedir == None: while self._sftp == ecd.LIBSSH2_ERROR_EAGAIN: utils.wait_socket(client.socket, client.session) self._sftp = client.open_sftp() self._homedir = self._sftp.realpath('.') while self._homedir == ecd.LIBSSH2_ERROR_EAGAIN: utils.wait_socket(client.socket, client.session) self._homedir = self._sftp.realpath('.') self._path = Path(self) self._check_sep() else: pass
def wait_complete(sock, session, channel): data = '' while not is_complete(data): wait_socket(sock, session) data = get_data(channel)