diff --git a/README b/README index 7ac578b..343a1b0 100644 --- a/README +++ b/README @@ -6,6 +6,12 @@ Version 0.3 Fixed libssh2_channel_read_ex(). Packet loop initialized BEFORE transport polled for new packets (should have been after). + Fixed blocking issues in scp_send()/scp_recv(). + + Fixed degree of indirection in macerror callback. + + Added channel close callback. + Version 0.2 ----------- diff --git a/include/libssh2.h b/include/libssh2.h index 154b037..7a834de 100644 --- a/include/libssh2.h +++ b/include/libssh2.h @@ -137,6 +137,8 @@ #define LIBSSH2_PASSWD_CHANGEREQ_FUNC(name) void name(LIBSSH2_SESSION *session, char **newpw, int *newpw_len, void **abstract) #define LIBSSH2_MACERROR_FUNC(name) int name(LIBSSH2_SESSION *session, const char *packet, int packet_len, void **abstract) +#define LIBSSH2_CHANNEL_CLOSE_FUNC(name) int name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, void **abstract) + /* libssh2_session_callback_set() constants */ #define LIBSSH2_CALLBACK_IGNORE 0 #define LIBSSH2_CALLBACK_DEBUG 1 diff --git a/include/libssh2_priv.h b/include/libssh2_priv.h index 0c5b753..136bf52 100644 --- a/include/libssh2_priv.h +++ b/include/libssh2_priv.h @@ -55,7 +55,9 @@ #define LIBSSH2_DISCONNECT(session, reason, message, message_len, language, language_len) \ session->ssh_msg_disconnect((session), (reason), (message), (message_len), (language), (language_len), &(session)->abstract) -#define LIBSSH2_MACERROR(session, data, datalen) session->macerror((session), (data), (datalen), (session)->abstract) +#define LIBSSH2_MACERROR(session, data, datalen) session->macerror((session), (data), (datalen), &(session)->abstract) + +#define LIBSSH2_CHANNEL_CLOSE(session, channel) channel->close_cb((session), (channel), &(session)->abstract) typedef struct _LIBSSH2_KEX_METHOD LIBSSH2_KEX_METHOD; typedef struct _LIBSSH2_HOSTKEY_METHOD LIBSSH2_HOSTKEY_METHOD; @@ -112,6 +114,8 @@ struct _LIBSSH2_CHANNEL { LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *next, *prev; + + LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb)); }; struct _LIBSSH2_CHANNEL_BRIGADE { diff --git a/src/channel.c b/src/channel.c index 3bebe18..1fdf143 100644 --- a/src/channel.c +++ b/src/channel.c @@ -734,6 +734,10 @@ LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel) return 0; } + if (channel->close_cb) { + LIBSSH2_CHANNEL_CLOSE(session, channel); + } + packet[0] = SSH_MSG_CHANNEL_CLOSE; libssh2_htonu32(packet + 1, channel->remote.id); if (libssh2_packet_write(session, packet, 5)) { diff --git a/src/scp.c b/src/scp.c index 07d4ec5..55e233d 100644 --- a/src/scp.c +++ b/src/scp.c @@ -76,6 +76,8 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, char *pa LIBSSH2_FREE(session, command); return NULL; } + /* Use blocking I/O for negotiation phase */ + libssh2_channel_set_blocking(channel, 1); /* Request SCP for the desired file */ if (libssh2_channel_process_startup(channel, "exec", sizeof("exec") - 1, command, command_len)) { @@ -307,7 +309,8 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, char *pa sb->st_size = size; sb->st_mode = mode; } - /* Let the data BEGIN! */ + /* Revert to non-blocking and let the data BEGIN! */ + libssh2_channel_set_blocking(channel, 0); return channel; } @@ -347,6 +350,8 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, char LIBSSH2_FREE(session, command); return NULL; } + /* Use blocking I/O for negotiation phase */ + libssh2_channel_set_blocking(channel, 1); /* Request SCP for the desired file */ if (libssh2_channel_process_startup(channel, "exec", sizeof("exec") - 1, command, command_len)) { @@ -400,7 +405,8 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, char return NULL; } - /* Ready to send file */ + /* Ready to start, switch to non-blocking and let calling app send file */ + libssh2_channel_set_blocking(channel, 0); return channel; }