diff --git a/examples/scp_upload.py b/examples/scp_upload.py index e640449..0a6f425 100755 --- a/examples/scp_upload.py +++ b/examples/scp_upload.py @@ -38,18 +38,18 @@ def _prepare_sock(self): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((self.hostname, self.port)) self.sock.setblocking(1) - except Exception, e: - print "SockError: Can't connect socket to %s:%d" % (self.hostname, self.port) - print e + except Exception as e: + print("SockError: Can't connect socket to %s:%d" % (self.hostname, self.port)) + print(e) try: self.session = libssh2.Session() self.session.set_banner() self.session.startup(self.sock) self.session.userauth_password(self.username, self.password) - except Exception, e: - print "SSHError: Can't startup session" - print e + except Exception as e: + print("SSHError: Can't startup session") + print(e) def send(self, remote_path, mode=0644): datas="" @@ -71,7 +71,7 @@ def __del__(self): if __name__ == '__main__' : if len(sys.argv) == 1: - print usage + print(usage) sys.exit(1) myscp = MySCPClient( hostname=sys.argv[1], diff --git a/examples/sftp_listdir.py b/examples/sftp_listdir.py index 88a26df..f91dbab 100755 --- a/examples/sftp_listdir.py +++ b/examples/sftp_listdir.py @@ -38,18 +38,18 @@ def _prepare_sock(self): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((self.hostname, self.port)) self.sock.setblocking(1) - except Exception, e: - print "SockError: Can't connect socket to %s:%d" % (self.hostname, self.port) - print e + except Exception as e: + print("SockError: Can't connect socket to %s:%d" % (self.hostname, self.port)) + print(e) try: self.session = libssh2.Session() self.session.set_banner() self.session.startup(self.sock) self.session.userauth_password(self.username, self.password) - except Exception, e: - print "SSHError: Can't startup session" - print e + except Exception as e: + print("SSHError: Can't startup session") + print(e) # use low level layer because we don't yet provide High layer for sftp self.sftp = self.session._session.sftp_init() @@ -60,10 +60,10 @@ def listdir(self, remote_path='/tmp'): while True: data = self.sftp.readdir(handle) if not data: break - print data + print(data) for file, attribute in self.sftp.listdir(handle): - print file, attribute + print(file, attribute) self.sftp.close(handle) @@ -73,7 +73,7 @@ def __del__(self): if __name__ == '__main__' : if len(sys.argv) == 1: - print usage + print(usage) sys.exit(1) mysftp = MySFTPClient( hostname=sys.argv[1], diff --git a/examples/ssh.py b/examples/ssh.py index 0b03709..9ce17c0 100755 --- a/examples/ssh.py +++ b/examples/ssh.py @@ -42,9 +42,9 @@ def _prepare_sock(self): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((self.hostname, self.port)) self.sock.setblocking(1) - except Exception, e: - print "SockError: Can't connect socket to %s:%d" % (self.hostname, self.port) - print e + except Exception as e: + print("SockError: Can't connect socket to %s:%d" % (self.hostname, self.port)) + print(e) try: self.session = libssh2.Session() @@ -58,9 +58,9 @@ def _prepare_sock(self): sys.stdout.write("Authentication that can continue %s\r\n" % auth_list) self.session.userauth_password(self.username, self.password) - except Exception, e: - print "SSHError: Can't startup session" - print e + except Exception as e: + print("SSHError: Can't startup session") + print(e) def run(self): @@ -91,8 +91,8 @@ def run(self): data = sys.stdin.read(1).replace('\n','\r\n') channel.write(data) - except Exception,e: - print e + except Exception as e: + print(e) finally: channel.close() @@ -103,7 +103,7 @@ def __del__(self): if __name__ == '__main__' : if len(sys.argv) == 1: - print usage + print(usage) sys.exit(1) # save terminal settings diff --git a/examples/ssh_exec.py b/examples/ssh_exec.py index a3b70a1..f605671 100755 --- a/examples/ssh_exec.py +++ b/examples/ssh_exec.py @@ -47,9 +47,9 @@ def __init__(self, hostname, username, password, port=22): my_print(self.session.last_error()) self.session.userauth_password(self.username,self.password) my_print(self.session.last_error()) - except Exception, e: - print str(e) - raise Exception, self.session.last_error() + except Exception as e: + print(str(e)) + raise Exception(self.session.last_error()) self.channel = self.session.open_session() my_print(self.session.last_error()) @@ -62,7 +62,7 @@ def execute(self, command="uname -a"): data = self.channel.read(buffer) if data == '' or data is None: break my_print(type(data)) - print data.strip() + print(data.strip().decode('utf-8')) self.channel.close() @@ -73,11 +73,11 @@ def __del__(self): if __name__ == '__main__': try: if len(sys.argv) == 1: - print usage + print(usage) sys.exit(1) src = SSHRemoteClient(sys.argv[1], sys.argv[2], sys.argv[3]) src.execute(sys.argv[4]) - except Exception, e: - print str(e) - except KeyboardInterrupt, e: + except Exception as e: + print(str(e)) + except KeyboardInterrupt as e: sys.exit(1) diff --git a/examples/ssh_exec2.py b/examples/ssh_exec2.py index 0bf40ea..ca22b82 100755 --- a/examples/ssh_exec2.py +++ b/examples/ssh_exec2.py @@ -43,8 +43,8 @@ def _wait_select(self): # return if not blocked return - readfds = [self.sock] if (blockdir & 01) else [] - writefds = [self.sock] if (blockdir & 02) else [] + readfds = [self.sock] if (blockdir & 0x1) else [] + writefds = [self.sock] if (blockdir & 0x2) else [] select(readfds, writefds, []) return @@ -108,7 +108,7 @@ def execute(self, cmd): data1 = self.chan.read_ex() while data1[0] > 0: my_print('Received data') - print data1[1] + print(data1[1].encode('utf-8')) data1 = self.chan.read_ex() @@ -126,14 +126,14 @@ def __del__(self): if __name__ == '__main__': try: if len(sys.argv) == 1: - print usage + print(usage) sys.exit(1) src = SSHRemoteClientNonBlocking(sys.argv[1], sys.argv[2], sys.argv[3]) src.startup() src.auth() src.open_channel() src.execute(sys.argv[4]) - except Exception, e: - print str(e) - except KeyboardInterrupt, e: + except Exception as e: + print(str(e)) + except KeyboardInterrupt as e: sys.exit(1) diff --git a/examples/ssh_publickey.py b/examples/ssh_publickey.py index 561acde..10f29ce 100755 --- a/examples/ssh_publickey.py +++ b/examples/ssh_publickey.py @@ -48,9 +48,9 @@ def _prepare_sock(self): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((self.hostname, self.port)) self.sock.setblocking(1) - except Exception, e: - print "SockError: Can't connect socket to %s:%d" % (self.hostname, self.port) - print e + except Exception as e: + print("SockError: Can't connect socket to %s:%d" % (self.hostname, self.port)) + print(e) try: self.session = libssh2.Session() @@ -62,9 +62,9 @@ def _prepare_sock(self): # authentication self.session.userauth_publickey_fromfile(self.username, self.public_key, self.private_key, self.password) - except Exception, e: - print "SSHError: Can't startup session" - raise e + except Exception as e: + print("SSHError: Can't startup session") + raise(e) def run(self): @@ -99,7 +99,7 @@ def run(self): # Print a newline (in case user was sitting at prompt) print('') except Exception as e: - print e + print(e) finally: channel.close() @@ -117,7 +117,7 @@ def argv_or(position, default): return default if len(sys.argv) == 1: - print usage + print(usage) sys.exit(1) # save terminal settings @@ -132,7 +132,7 @@ def argv_or(position, default): myssh.run() finally: - print '' + print('') # restore terminal settings atexit.register( termios.tcsetattr, diff --git a/examples/ssh_x11.py b/examples/ssh_x11.py index eb69f11..668b5e9 100755 --- a/examples/ssh_x11.py +++ b/examples/ssh_x11.py @@ -66,7 +66,7 @@ def trace(session): if __name__ == '__main__': if len(sys.argv) == 1: - print usage + print(usage) sys.exit(1) DEBUG=False @@ -86,10 +86,10 @@ def trace(session): try: sock.connect((hostname, port)) sock.setblocking(0) - except Exception, e: - print "Can't connect socket to (%s:%d): %s" % ( + except Exception as e: + print("Can't connect socket to (%s:%d): %s" % ( hostname, port, e - ) + )) sys.exit(1) # start session @@ -99,8 +99,8 @@ def trace(session): # trace session on stderr if DEBUG=True trace(session) session.startup(sock) - except SessionException, e: - print "Can't startup session: %s" % e + except SessionException as e: + print("Can't startup session: %s" % e) sys.exit(1) # register X11 callback @@ -111,10 +111,10 @@ def trace(session): try: session.userauth_password(username, password) - except SessionException, e: - print "Failed to authenticate user with %s %s" % ( + except SessionException as e: + print("Failed to authenticate user with %s %s" % ( username, password - ) + )) sys.exit(1) try: @@ -179,8 +179,8 @@ def trace(session): if channel.eof(): break - except ChannelException, e: - print "Channel exception: %s" % e + except ChannelException as e: + print("Channel exception: %s" % e) finally: channel.close() diff --git a/libssh2/__init__.py b/libssh2/__init__.py index cdcd82e..9a8460f 100644 --- a/libssh2/__init__.py +++ b/libssh2/__init__.py @@ -19,11 +19,11 @@ # __doc__ = """Python binding for libssh2 library""" -from version import * +from libssh2.version import * -from channel import ChannelException, Channel -from session import SessionException, Session -from sftp import SftpException, Sftp +from libssh2.channel import ChannelException, Channel +from libssh2.session import SessionException, Session +from libssh2.sftp import SftpException, Sftp __all__ = [ 'Channel', diff --git a/libssh2/session.py b/libssh2/session.py index 93d958e..abb6c6d 100644 --- a/libssh2/session.py +++ b/libssh2/session.py @@ -23,7 +23,7 @@ import _libssh2 -from channel import Channel +from libssh2.channel import Channel class SessionException(Exception): """ @@ -141,6 +141,26 @@ def set_trace(self, bitmask): """ self._session.set_trace(bitmask) + def keepalive_config(self, wantReply, interval): + """ + Set how often to send keepalives. + + @param wantReply: Whether to request the server sends responses to keepalives + @type wantReply: bool + @param interval: How often to send keepalives (0 to disable) + @type interval: int + @param bitmask: bitmask on libssh2.LIBSSH2_TRACE_* constant + """ + self._session.keepalive_config(wantReply, interval) + + def keepalive_send(self): + """ + Sends keepalive, if due. Call this to send keepalives from non-blocking code. + + @return: seconds until next keepalive + @rtype: int + """ + return self._session.keepalive_send() def scp_recv(self, remote_path): """ diff --git a/setup.py b/setup.py old mode 100755 new mode 100644 diff --git a/src/channel.c b/src/channel.c index 6365054..01588e1 100644 --- a/src/channel.c +++ b/src/channel.c @@ -43,7 +43,7 @@ PYLIBSSH2_Channel_close(PYLIBSSH2_CHANNEL *self, PyObject *args) Py_BEGIN_ALLOW_THREADS rc = libssh2_channel_close(self->channel); - if (rc != LIBSSH2_ERROR_EAGAIN) + if (rc && rc != LIBSSH2_ERROR_EAGAIN) rc = libssh2_channel_wait_closed(self->channel); Py_END_ALLOW_THREADS @@ -324,19 +324,19 @@ PYLIBSSH2_Channel_read(PYLIBSSH2_CHANNEL *self, PyObject *args) if (!PyArg_ParseTuple(args, "i|i:read", &buffer_size)) return NULL; - buffer = PyString_FromStringAndSize(NULL, buffer_size); + buffer = PyBytes_FromStringAndSize(NULL, buffer_size); if (buffer == NULL) { return NULL; } if (libssh2_channel_eof(self->channel) != 1) { Py_BEGIN_ALLOW_THREADS - rc = libssh2_channel_read(self->channel, PyString_AsString(buffer), + rc = libssh2_channel_read(self->channel, PyBytes_AsString(buffer), buffer_size); Py_END_ALLOW_THREADS if (rc > 0) { - if (rc != buffer_size && _PyString_Resize(&buffer, rc) < 0) + if (rc != buffer_size && _PyBytes_Resize(&buffer, rc) < 0) return NULL; return buffer; } @@ -379,19 +379,19 @@ PYLIBSSH2_Channel_read_stderr(PYLIBSSH2_CHANNEL *self, PyObject *args) if (!PyArg_ParseTuple(args, "i|i:read_stderr", &buffer_size)) return NULL; - buffer = PyString_FromStringAndSize(NULL, buffer_size); + buffer = PyBytes_FromStringAndSize(NULL, buffer_size); if (buffer == NULL) { return NULL; } if (libssh2_channel_eof(self->channel) != 1) { Py_BEGIN_ALLOW_THREADS - rc = libssh2_channel_read_stderr(self->channel, PyString_AsString(buffer), + rc = libssh2_channel_read_stderr(self->channel, PyBytes_AsString(buffer), buffer_size); Py_END_ALLOW_THREADS if (rc > 0) { - if (rc != buffer_size && _PyString_Resize(&buffer, rc) < 0) + if (rc != buffer_size && _PyBytes_Resize(&buffer, rc) < 0) return NULL; return buffer; } @@ -435,18 +435,18 @@ PYLIBSSH2_Channel_read_ex(PYLIBSSH2_CHANNEL *self, PyObject *args) if (!PyArg_ParseTuple(args, "i|i:read_ex", &buffer_size, &stream_id)) return NULL; - buffer = PyString_FromStringAndSize(NULL, buffer_size); + buffer = PyBytes_FromStringAndSize(NULL, buffer_size); if (buffer == NULL) { return NULL; } - cbuf = PyString_AsString(buffer); + cbuf = PyBytes_AsString(buffer); Py_BEGIN_ALLOW_THREADS rc = libssh2_channel_read_ex(self->channel, stream_id, cbuf, buffer_size); Py_END_ALLOW_THREADS if (rc > 0) { - if (rc != buffer_size && _PyString_Resize(&buffer, rc) < 0) + if (rc != buffer_size && _PyBytes_Resize(&buffer, rc) < 0) return NULL; } /** @@ -800,27 +800,17 @@ PYLIBSSH2_Channel_dealloc(PYLIBSSH2_CHANNEL *self) } /* }}} */ -/* {{{ PYLIBSSH2_Channel_getattr - */ -static PyObject * -PYLIBSSH2_Channel_getattr(PYLIBSSH2_CHANNEL *self, char *name) -{ - return Py_FindMethod(PYLIBSSH2_Channel_methods, (PyObject *)self, name); -} -/* }}} */ - /* {{{ PYLIBSSH2_Channel_Type * see /usr/include/python2.5/object.h line 261 */ PyTypeObject PYLIBSSH2_Channel_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "Channel", /* tp_name */ + PyVarObject_HEAD_INIT(NULL, 0) + PYLIBSSH2_MODULE_NAME ".Channel", /* tp_name */ sizeof(PYLIBSSH2_CHANNEL), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PYLIBSSH2_Channel_dealloc, /* tp_dealloc */ 0, /* tp_print */ - (getattrfunc)PYLIBSSH2_Channel_getattr, /* tp_getattr */ + 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ @@ -835,6 +825,13 @@ PyTypeObject PYLIBSSH2_Channel_Type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Channel objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PYLIBSSH2_Channel_methods, /* tp_methods */ }; /* }}} */ @@ -843,10 +840,15 @@ PyTypeObject PYLIBSSH2_Channel_Type = { int init_libssh2_Channel(PyObject *dict) { - PYLIBSSH2_Channel_Type.ob_type = &PyType_Type; - Py_XINCREF(&PYLIBSSH2_Channel_Type); + int rc; + + Py_TYPE(&PYLIBSSH2_Channel_Type) = &PyType_Type; + rc = PyType_Ready(&PYLIBSSH2_Channel_Type); + if (rc < 0) + return rc; + Py_INCREF(&PYLIBSSH2_Channel_Type); PyDict_SetItemString(dict, "ChannelType", (PyObject *)&PYLIBSSH2_Channel_Type); - return 1; + return rc; } /* }}} */ diff --git a/src/listener.c b/src/listener.c index 5a15894..424d75e 100644 --- a/src/listener.c +++ b/src/listener.c @@ -119,28 +119,18 @@ PYLIBSSH2_Listener_dealloc(PYLIBSSH2_LISTENER *self) } /* }}} */ -/* {{{ PYLIBSSH2_Listener_getattr - */ -static PyObject * -PYLIBSSH2_Listener_getattr(PYLIBSSH2_LISTENER *self, char *name) -{ - return Py_FindMethod(PYLIBSSH2_Listener_methods, (PyObject *) self, name); -} -/* }}} */ - /* {{{ PYLIBSSH2_Listener_Type * * see /usr/include/python2.5/object.h line 261 */ PyTypeObject PYLIBSSH2_Listener_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "Listener", /* tp_name */ + PyVarObject_HEAD_INIT(NULL, 0) + PYLIBSSH2_MODULE_NAME ".Listener", /* tp_name */ sizeof(PYLIBSSH2_LISTENER), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PYLIBSSH2_Listener_dealloc, /* tp_dealloc */ 0, /* tp_print */ - (getattrfunc)PYLIBSSH2_Listener_getattr, /* tp_getattr */ + 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ @@ -155,6 +145,13 @@ PyTypeObject PYLIBSSH2_Listener_Type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Listener objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PYLIBSSH2_Listener_methods, /* tp_methods */ }; /* }}} */ @@ -163,10 +160,16 @@ PyTypeObject PYLIBSSH2_Listener_Type = { int init_libssh2_Listener(PyObject *dict) { - PYLIBSSH2_Listener_Type.ob_type = &PyType_Type; - Py_XINCREF(&PYLIBSSH2_Listener_Type); + int rc; + + Py_TYPE(&PYLIBSSH2_Listener_Type) = &PyType_Type; + rc = PyType_Ready(&PYLIBSSH2_Listener_Type); + if (rc < 0) + return rc; + + Py_INCREF(&PYLIBSSH2_Listener_Type); PyDict_SetItemString(dict, "ListenerType", (PyObject *)&PYLIBSSH2_Listener_Type); - return 1; + return rc; } /* }}} */ diff --git a/src/py3.h b/src/py3.h new file mode 100644 index 0000000..8adfac0 --- /dev/null +++ b/src/py3.h @@ -0,0 +1,55 @@ +/* + Python3 definition file to consistently map the code to Python 2.6 or + Python 3. + + PyInt and PyLong were merged into PyLong in Python 3, so all PyInt functions + are mapped to PyLong. + + PyString, on the other hand, was split into PyBytes and PyUnicode. We map + both back onto PyString, so use PyBytes or PyUnicode where appropriate. The + only exception to this is _imagingft.c, where PyUnicode is left alone. +*/ + +#if PY_VERSION_HEX >= 0x03000000 +#define PY_ARG_BYTES_LENGTH "y#" + +/* Map PyInt -> PyLong */ +#define PyInt_AsLong PyLong_AsLong +#define PyInt_Check PyLong_Check +#define PyInt_FromLong PyLong_FromLong +#define PyInt_AS_LONG PyLong_AS_LONG +#define PyInt_FromSsize_t PyLong_FromSsize_t + +#else /* PY_VERSION_HEX < 0x03000000 */ +#define PY_ARG_BYTES_LENGTH "s#" + +#if !defined(KEEP_PY_UNICODE) +/* Map PyUnicode -> PyString */ +#undef PyUnicode_AsString +#undef PyUnicode_AS_STRING +#undef PyUnicode_Check +#undef PyUnicode_FromStringAndSize +#undef PyUnicode_FromString +#undef PyUnicode_FromFormat +#undef PyUnicode_DecodeFSDefault + +#define PyUnicode_AsString PyString_AsString +#define PyUnicode_AS_STRING PyString_AS_STRING +#define PyUnicode_Check PyString_Check +#define PyUnicode_FromStringAndSize PyString_FromStringAndSize +#define PyUnicode_FromString PyString_FromString +#define PyUnicode_FromFormat PyString_FromFormat +#define PyUnicode_DecodeFSDefault PyString_FromString +#endif + +/* Map PyBytes -> PyString */ +#define PyBytesObject PyStringObject +#define PyBytes_AsString PyString_AsString +#define PyBytes_AS_STRING PyString_AS_STRING +#define PyBytes_Check PyString_Check +#define PyBytes_AsStringAndSize PyString_AsStringAndSize +#define PyBytes_FromStringAndSize PyString_FromStringAndSize +#define PyBytes_FromString PyString_FromString +#define _PyBytes_Resize _PyString_Resize + +#endif /* PY_VERSION_HEX < 0x03000000 */ diff --git a/src/pylibssh2.c b/src/pylibssh2.c index 7043bb0..a7fb30f 100644 --- a/src/pylibssh2.c +++ b/src/pylibssh2.c @@ -156,12 +156,34 @@ static PyMethodDef PYLIBSSH2_methods[] = { /* {{{ init_libssh2 */ PyMODINIT_FUNC +#if PY_MAJOR_VERSION >= 3 +PyInit__libssh2(void) +#else init_libssh2(void) +#endif { static void *PYLIBSSH2_API[PYLIBSSH2_API_pointers]; PyObject *c_api_object; PyObject *module, *dict; +#if PY_MAJOR_VERSION >= 3 + static struct PyModuleDef libssh2_moduledef = { + PyModuleDef_HEAD_INIT, + PYLIBSSH2_MODULE_NAME, /* m_name */ + PYLIBSSH2_doc, /* m_doc */ + -1, /* m_size */ + PYLIBSSH2_methods, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ + }; + + module = PyModule_Create(&libssh2_moduledef); + if (module == NULL) { + return NULL; + } +#else module = Py_InitModule3( PYLIBSSH2_MODULE_NAME, PYLIBSSH2_methods, @@ -170,13 +192,18 @@ init_libssh2(void) if (module == NULL) { return; } +#endif PYLIBSSH2_API[PYLIBSSH2_Session_New_NUM] = (void *) PYLIBSSH2_Session_New; PYLIBSSH2_API[PYLIBSSH2_Channel_New_NUM] = (void *) PYLIBSSH2_Channel_New; PYLIBSSH2_API[PYLIBSSH2_Sftp_New_NUM] = (void *) PYLIBSSH2_Sftp_New; PYLIBSSH2_API[PYLIBSSH2_Sftphandle_New_NUM] = (void *) PYLIBSSH2_Sftphandle_New; +#if PY_MAJOR_VERSION >= 3 + c_api_object = PyCapsule_New((void *)PYLIBSSH2_API, NULL, NULL); +#else c_api_object = PyCObject_FromVoidPtr((void *)PYLIBSSH2_API, NULL); +#endif if (c_api_object != NULL) { PyModule_AddObject(module, "_C_API", c_api_object); } @@ -218,20 +245,23 @@ init_libssh2(void) PyModule_AddStringConstant(module, "LIBSSH2_VERSION", LIBSSH2_VERSION); dict = PyModule_GetDict(module); - if (!init_libssh2_Session(dict)) { + if (init_libssh2_Session(dict) < 0) { goto error; } - if (!init_libssh2_Channel(dict)) { + if (init_libssh2_Channel(dict) < 0) { goto error; } - if (!init_libssh2_Sftp(dict)) { + if (init_libssh2_Sftp(dict) < 0) { goto error; } - if (!init_libssh2_Sftphandle(dict)) { + if (init_libssh2_Sftphandle(dict) < 0) { goto error; } error: ; +#if PY_MAJOR_VERSION >= 3 + return module; +#endif } /* }}} */ diff --git a/src/pylibssh2.h b/src/pylibssh2.h index f65e7de..389bdc4 100644 --- a/src/pylibssh2.h +++ b/src/pylibssh2.h @@ -27,6 +27,7 @@ #include #include +#include "py3.h" #include "channel.h" #include "listener.h" #include "sftp.h" diff --git a/src/session.c b/src/session.c index a4c7941..946ff3c 100644 --- a/src/session.c +++ b/src/session.c @@ -260,7 +260,7 @@ PYLIBSSH2_Session_userauth_list(PYLIBSSH2_SESSION *self, PyObject *args) return NULL; } - return PyString_FromString(auth_list); + return PyBytes_FromString(auth_list); } /* }}} */ @@ -296,7 +296,7 @@ PYLIBSSH2_Session_hostkey_hash(PYLIBSSH2_SESSION *self, PyObject *args) return Py_None; } - return PyString_FromString(hash); + return PyBytes_FromString(hash); } /* }}} */ @@ -517,16 +517,16 @@ PYLIBSSH2_Session_session_methods(PYLIBSSH2_SESSION *self, PyObject *args) /* create a python dictionnary to store cryptographic algorithms */ methods = PyDict_New(); - PyDict_SetItemString(methods, "KEX", PyString_FromString(kex)); - PyDict_SetItemString(methods, "HOSTKEY", PyString_FromString(hostkey)); - PyDict_SetItemString(methods, "CRYPT_CS", PyString_FromString(crypt_cs)); - PyDict_SetItemString(methods, "CRYPT_SC", PyString_FromString(crypt_sc)); - PyDict_SetItemString(methods, "MAC_CS", PyString_FromString(mac_cs)); - PyDict_SetItemString(methods, "MAC_SC", PyString_FromString(mac_sc)); - PyDict_SetItemString(methods, "COMP_CS", PyString_FromString(comp_cs)); - PyDict_SetItemString(methods, "COMP_SC", PyString_FromString(comp_sc)); - PyDict_SetItemString(methods, "LANG_CS", PyString_FromString(lang_cs)); - PyDict_SetItemString(methods, "LANG_SC", PyString_FromString(lang_sc)); + PyDict_SetItemString(methods, "KEX", PyBytes_FromString(kex)); + PyDict_SetItemString(methods, "HOSTKEY", PyBytes_FromString(hostkey)); + PyDict_SetItemString(methods, "CRYPT_CS", PyBytes_FromString(crypt_cs)); + PyDict_SetItemString(methods, "CRYPT_SC", PyBytes_FromString(crypt_sc)); + PyDict_SetItemString(methods, "MAC_CS", PyBytes_FromString(mac_cs)); + PyDict_SetItemString(methods, "MAC_SC", PyBytes_FromString(mac_sc)); + PyDict_SetItemString(methods, "COMP_CS", PyBytes_FromString(comp_cs)); + PyDict_SetItemString(methods, "COMP_SC", PyBytes_FromString(comp_sc)); + PyDict_SetItemString(methods, "LANG_CS", PyBytes_FromString(lang_cs)); + PyDict_SetItemString(methods, "LANG_SC", PyBytes_FromString(lang_sc)); return methods; } @@ -558,7 +558,7 @@ PYLIBSSH2_Session_session_method_pref(PYLIBSSH2_SESSION *self, PyObject *args) return NULL; } - return PyInt_FromLong(libssh2_session_method_pref(self->session, method, pref)==0?1:0); + return PyLong_FromLong(libssh2_session_method_pref(self->session, method, pref)==0?1:0); } /* }}} */ @@ -882,8 +882,8 @@ stub_callback_func(LIBSSH2_SESSION *session, /* Performing Python callback with C API */ result = PyEval_CallObject(py_callback_func, arglist); - if (result && PyInt_Check(result)) { - rc = PyInt_AsLong(result); + if (result && PyLong_Check(result)) { + rc = PyLong_AsLong(result); } /* Restore previous thread state and release acquired resources */ @@ -957,6 +957,62 @@ PYLIBSSH2_Session_set_trace(PYLIBSSH2_SESSION *self, PyObject *args) } /* }}} */ +/* PYLIBSSH2_Session_keepalive_config + */ +static char PYLIBSSH2_Session_keepalive_config_doc[] = "\n\ +keepalive_config(want_reply, interval)\n\ +\n\ +Configures how often keepalives are sent.\n\ +\n\ +@param want_reply: keepalives request response from server\n\ +@type want_reply: bool\n\ +@param interval: time between keepalives (0 to disable)\n\ +@type interval: int\n\ +\n\ +@return\n\ +@rtype "; + +static PyObject * +PYLIBSSH2_Session_keepalive_config(PYLIBSSH2_SESSION *self, PyObject *args) +{ + int rc=0; + int want_reply, interval; + + if (!PyArg_ParseTuple(args, "ii:keepalive_config", &want_reply, &interval)) { + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + libssh2_keepalive_config(self->session, want_reply, interval); + Py_END_ALLOW_THREADS + + return Py_BuildValue("i", rc); +} +/* }}} */ + +/* PYLIBSSH2_Session_keepalive_send + */ +static char PYLIBSSH2_Session_keepalive_send_doc[] = "\n\ +keepalive_send()\n\ +\n\ +Send keepalives if due when using non-blocking I/O.\n\ +\n\ +@return seconds until next keepalive\n\ +@rtype int"; + +static PyObject * +PYLIBSSH2_Session_keepalive_send(PYLIBSSH2_SESSION *self, PyObject *args) +{ + int rc=0; + + Py_BEGIN_ALLOW_THREADS + libssh2_keepalive_send(self->session, &rc); + Py_END_ALLOW_THREADS + + return Py_BuildValue("i", rc); +} +/* }}} */ + /* void kbd_callback(const char *name, int name_len, const char *instruction, @@ -1059,6 +1115,8 @@ static PyMethodDef PYLIBSSH2_Session_methods[] = ADD_METHOD(last_error), ADD_METHOD(callback_set), ADD_METHOD(set_trace), + ADD_METHOD(keepalive_config), + ADD_METHOD(keepalive_send), ADD_METHOD(userauth_keyboardinteractive), ADD_METHOD(userauth_agent), { NULL, NULL } @@ -1112,28 +1170,18 @@ PYLIBSSH2_Session_dealloc(PYLIBSSH2_SESSION *self) } /* }}} */ -/* {{{ PYLIBSSH2_Session_getattr - */ -static PyObject * -PYLIBSSH2_Session_getattr(PYLIBSSH2_SESSION *self, char *name) -{ - return Py_FindMethod(PYLIBSSH2_Session_methods, (PyObject *)self, name); -} -/* }}} */ - /* {{{ PYLIBSSH2_Session_Type * * see /usr/include/python2.5/object.h line 261 */ PyTypeObject PYLIBSSH2_Session_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "Session", /* tp_name */ + PyVarObject_HEAD_INIT(NULL, 0) + PYLIBSSH2_MODULE_NAME ".Session", /* tp_name */ sizeof(PYLIBSSH2_SESSION), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PYLIBSSH2_Session_dealloc, /* tp_dealloc */ 0, /* tp_print */ - (getattrfunc)PYLIBSSH2_Session_getattr, /* tp_getattr */ + 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ @@ -1148,6 +1196,13 @@ PyTypeObject PYLIBSSH2_Session_Type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Sesssion objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PYLIBSSH2_Session_methods, /* tp_methods */ }; /* }}} */ @@ -1156,9 +1211,14 @@ PyTypeObject PYLIBSSH2_Session_Type = { int init_libssh2_Session(PyObject *dict) { - PYLIBSSH2_Session_Type.ob_type = &PyType_Type; - Py_XINCREF(&PYLIBSSH2_Session_Type); + int rc; + Py_TYPE(&PYLIBSSH2_Session_Type) = &PyType_Type; + rc = PyType_Ready(&PYLIBSSH2_Session_Type); + if (rc < 0) + return rc; + + Py_INCREF(&PYLIBSSH2_Session_Type); PyDict_SetItemString(dict, "SessionType", (PyObject *)&PYLIBSSH2_Session_Type); - - return 1; + + return rc; } diff --git a/src/sftp.c b/src/sftp.c index 706808a..65a3fcf 100644 --- a/src/sftp.c +++ b/src/sftp.c @@ -137,14 +137,14 @@ PYLIBSSH2_Sftp_readdir(PYLIBSSH2_SFTP *self, PyObject *args) return NULL; } - buffer = PyString_FromStringAndSize(NULL, longentry_maxlen); + buffer = PyBytes_FromStringAndSize(NULL, longentry_maxlen); if (buffer == NULL) { Py_INCREF(Py_None); return Py_None; } Py_BEGIN_ALLOW_THREADS - buffer_maxlen = libssh2_sftp_readdir(handle->sftphandle, PyString_AsString(buffer), + buffer_maxlen = libssh2_sftp_readdir(handle->sftphandle, PyBytes_AsString(buffer), longentry_maxlen, &attrs); Py_END_ALLOW_THREADS @@ -158,7 +158,7 @@ PYLIBSSH2_Sftp_readdir(PYLIBSSH2_SFTP *self, PyObject *args) } if (buffer_maxlen != longentry_maxlen && - _PyString_Resize(&buffer, buffer_maxlen) < 0) { + _PyBytes_Resize(&buffer, buffer_maxlen) < 0) { Py_INCREF(Py_None); return Py_None; } @@ -197,7 +197,7 @@ PYLIBSSH2_Sftp_listdir(PYLIBSSH2_SFTP *self, PyObject *args) all = PyList_New(0); while (1) { - buffer = PyString_FromStringAndSize(NULL, longentry_maxlen); + buffer = PyBytes_FromStringAndSize(NULL, longentry_maxlen); if (buffer == NULL) { Py_INCREF(Py_None); return Py_None; @@ -205,7 +205,7 @@ PYLIBSSH2_Sftp_listdir(PYLIBSSH2_SFTP *self, PyObject *args) Py_BEGIN_ALLOW_THREADS buffer_maxlen = libssh2_sftp_readdir(handle->sftphandle, - PyString_AsString(buffer), longentry_maxlen, &attrs); + PyBytes_AsString(buffer), longentry_maxlen, &attrs); Py_END_ALLOW_THREADS if (buffer_maxlen == 0) { @@ -216,7 +216,7 @@ PYLIBSSH2_Sftp_listdir(PYLIBSSH2_SFTP *self, PyObject *args) } if ( buffer_maxlen != longentry_maxlen && - _PyString_Resize(&buffer, buffer_maxlen) < 0) { + _PyBytes_Resize(&buffer, buffer_maxlen) < 0) { Py_INCREF(Py_None); return Py_None; } @@ -314,19 +314,19 @@ PYLIBSSH2_Sftp_read(PYLIBSSH2_SFTP *self, PyObject *args) return NULL; } - buffer = PyString_FromStringAndSize(NULL, buffer_maxlen); + buffer = PyBytes_FromStringAndSize(NULL, buffer_maxlen); if (buffer == NULL) { Py_INCREF(Py_None); return Py_None; } Py_BEGIN_ALLOW_THREADS - rc = libssh2_sftp_read(handle->sftphandle, PyString_AsString(buffer), + rc = libssh2_sftp_read(handle->sftphandle, PyBytes_AsString(buffer), buffer_maxlen); Py_END_ALLOW_THREADS if (rc > 0) { - if ( rc != buffer_maxlen && _PyString_Resize(&buffer, rc) < 0) { + if ( rc != buffer_maxlen && _PyBytes_Resize(&buffer, rc) < 0) { Py_INCREF(Py_None); return Py_None; } @@ -393,7 +393,7 @@ PYLIBSSH2_Sftp_tell(PYLIBSSH2_SFTP *self, PyObject *args) return NULL; } - return PyInt_FromLong(libssh2_sftp_tell(handle->sftphandle)); + return PyLong_FromLong(libssh2_sftp_tell(handle->sftphandle)); } /* }}} */ @@ -420,7 +420,7 @@ PYLIBSSH2_Sftp_seek(PYLIBSSH2_SFTP *self, PyObject *args) libssh2_sftp_seek(handle->sftphandle, offset); Py_END_ALLOW_THREADS - return PyInt_FromLong(1); + return PyLong_FromLong(1); } /* }}} */ @@ -555,7 +555,7 @@ PYLIBSSH2_Sftp_realpath(PYLIBSSH2_SFTP *self, PyObject *args) return NULL; } - target = PyString_FromStringAndSize(NULL, target_len); + target = PyBytes_FromStringAndSize(NULL, target_len); if (target == NULL) { Py_INCREF(Py_None); return Py_None; @@ -563,11 +563,11 @@ PYLIBSSH2_Sftp_realpath(PYLIBSSH2_SFTP *self, PyObject *args) Py_BEGIN_ALLOW_THREADS rc = libssh2_sftp_symlink_ex(self->sftp, path, path_len, - PyString_AsString(target), target_len, type); + PyBytes_AsString(target), target_len, type); Py_END_ALLOW_THREADS if (rc > 0) { - if (rc != target_len && _PyString_Resize(&target, rc) < 0) { + if (rc != target_len && _PyBytes_Resize(&target, rc) < 0) { Py_INCREF(Py_None); return Py_None; } @@ -779,11 +779,13 @@ PYLIBSSH2_Sftp_dealloc(PYLIBSSH2_SFTP *self) /* {{{ PYLIBSSH2_Sftp_getattr */ +#if 0 static PyObject * PYLIBSSH2_Sftp_getattr(PYLIBSSH2_SFTP *self, char *name) { return Py_FindMethod(PYLIBSSH2_Sftp_methods, (PyObject *)self, name); } +#endif /* }}} */ /* {{{ PYLIBSSH2_Sftp_Type @@ -791,14 +793,13 @@ PYLIBSSH2_Sftp_getattr(PYLIBSSH2_SFTP *self, char *name) * see /usr/include/python2.5/object.h line 261 */ PyTypeObject PYLIBSSH2_Sftp_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "Sftp", /* tp_name */ + PyVarObject_HEAD_INIT(NULL, 0) + PYLIBSSH2_MODULE_NAME ".Sftp", /* tp_name */ sizeof(PYLIBSSH2_SFTP), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PYLIBSSH2_Sftp_dealloc, /* tp_dealloc */ 0, /* tp_print */ - (getattrfunc)PYLIBSSH2_Sftp_getattr, /* tp_getattr */ + 0, /* (getattrfunc)PYLIBSSH2_Sftp_getattr, tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ @@ -813,6 +814,13 @@ PyTypeObject PYLIBSSH2_Sftp_Type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Sftp objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PYLIBSSH2_Sftp_methods, /* tp_methods */ }; /* }}} */ @@ -821,10 +829,18 @@ PyTypeObject PYLIBSSH2_Sftp_Type = { int init_libssh2_Sftp(PyObject *dict) { - PYLIBSSH2_Sftp_Type.ob_type = &PyType_Type; - Py_XINCREF(&PYLIBSSH2_Sftp_Type); + int rc; + + Py_TYPE(&PYLIBSSH2_Sftp_Type) = &PyType_Type; + + rc = PyType_Ready(&PYLIBSSH2_Sftp_Type); + if (rc < 0) + return rc; + + Py_INCREF(&PYLIBSSH2_Channel_Type); + PyDict_SetItemString(dict, "SFTPType", (PyObject *) &PYLIBSSH2_Sftp_Type); - return 1; + return rc; } /* }}} */ diff --git a/src/sftphandle.c b/src/sftphandle.c index 193cbb7..493ee90 100644 --- a/src/sftphandle.c +++ b/src/sftphandle.c @@ -57,24 +57,17 @@ PYLIBSSH2_Sftphandle_dealloc(PYLIBSSH2_SFTPHANDLE *self) PyObject_Del(self); } -static PyObject * -PYLIBSSH2_Sftphandle_getattr(PYLIBSSH2_SFTPHANDLE *self, char *name) -{ - return Py_FindMethod(PYLIBSSH2_Sftphandle_methods, (PyObject *)self, name); -} - /* * see /usr/include/python2.5/object.c line 261 */ PyTypeObject PYLIBSSH2_Sftphandle_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ + PyVarObject_HEAD_INIT(NULL, 0) "Sftphandle", /* tp_name */ sizeof(PYLIBSSH2_SFTPHANDLE), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PYLIBSSH2_Sftphandle_dealloc, /* tp_dealloc */ 0, /* tp_print */ - (getattrfunc)PYLIBSSH2_Sftphandle_getattr, /* tp_getattr */ + 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ @@ -89,14 +82,27 @@ PyTypeObject PYLIBSSH2_Sftphandle_Type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Sftphandle objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PYLIBSSH2_Sftphandle_methods, /* tp_methods */ }; int init_libssh2_Sftphandle(PyObject *dict) { - PYLIBSSH2_Sftphandle_Type.ob_type = &PyType_Type; - Py_XINCREF(&PYLIBSSH2_Sftphandle_Type); + int rc; + + Py_TYPE(&PYLIBSSH2_Sftphandle_Type) = &PyType_Type; + rc = PyType_Ready(&PYLIBSSH2_Sftphandle_Type); + if (rc < 0) + return rc; + + Py_INCREF(&PYLIBSSH2_Sftphandle_Type); PyDict_SetItemString(dict, "SftphandleType", (PyObject *)&PYLIBSSH2_Sftphandle_Type); - return 1; + return rc; }