diff --git a/README b/README index 7260c078..71766ce0 100644 --- a/README +++ b/README @@ -15,6 +15,8 @@ Version 0.2 LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE Calls to channel_read() will check both the standard data stream and the extended data stream(s) for the first available packet + Changed libssh2_session_disconnect_ex() to return an error code when alloc fails + Added libssh2_channel_flush_ex() and basic macros: ..._flush() ..._flush_stderr() flush_ex accepts either the streamid (0 for standard data, 1 for stderr) or one of the two following constants: LIBSSH2_CHANNEL_FLUSH_ALL Flush all streams diff --git a/include/libssh2.h b/include/libssh2.h index eff0d82b..797f7464 100644 --- a/include/libssh2.h +++ b/include/libssh2.h @@ -43,7 +43,7 @@ #include #define LIBSSH2_VERSION "0.1" -#define LIBSSH2_APINO 200412161442 +#define LIBSSH2_APINO 200412161500 /* Part of every banner, user specified or not */ #define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION @@ -221,7 +221,7 @@ LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session); LIBSSH2_API void *libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callback); LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket); -LIBSSH2_API void libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, char *description, char *lang); +LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, char *description, char *lang); #define libssh2_session_disconnect(session, description) libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, (description), "") LIBSSH2_API void libssh2_session_free(LIBSSH2_SESSION *session); diff --git a/src/session.c b/src/session.c index 80315ff6..bfaa2fe7 100644 --- a/src/session.c +++ b/src/session.c @@ -402,9 +402,9 @@ LIBSSH2_API void libssh2_session_free(LIBSSH2_SESSION *session) /* {{{ libssh2_session_disconnect_ex */ -LIBSSH2_API void libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, char *description, char *lang) +LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, char *description, char *lang) { - unsigned char *data; + unsigned char *s, *data; unsigned long data_len, descr_len = 0, lang_len = 0; if (description) { @@ -415,29 +415,32 @@ LIBSSH2_API void libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int rea } data_len = descr_len + lang_len + 13; /* packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */ - data = LIBSSH2_ALLOC(session, data_len); - if (data) { - unsigned char *s = data; - - *(s++) = SSH_MSG_DISCONNECT; - libssh2_htonu32(s, reason); s += 4; - - libssh2_htonu32(s, descr_len); s += 4; - if (description) { - memcpy(s, description, descr_len); - s += descr_len; - } - - libssh2_htonu32(s, lang_len); s += 4; - if (lang) { - memcpy(s, lang, lang_len); - s += lang_len; - } - - libssh2_packet_write(session, data, data_len); - - LIBSSH2_FREE(session, data); + s = data = LIBSSH2_ALLOC(session, data_len); + if (!data) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for disconnect packet", 0); + return -1; } + + *(s++) = SSH_MSG_DISCONNECT; + libssh2_htonu32(s, reason); s += 4; + + libssh2_htonu32(s, descr_len); s += 4; + if (description) { + memcpy(s, description, descr_len); + s += descr_len; + } + + libssh2_htonu32(s, lang_len); s += 4; + if (lang) { + memcpy(s, lang, lang_len); + s += lang_len; + } + + libssh2_packet_write(session, data, data_len); + + LIBSSH2_FREE(session, data); + + return 0; } /* }}} */