From 7a153310f77ac9f4aa65cbb99635b8ab244e915b Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Wed, 8 Dec 2004 18:14:46 +0000 Subject: [PATCH] Change extended data ignore to allow merging extended data into the primary stream --- include/libssh2.h | 18 ++++++++++++++++-- include/libssh2_priv.h | 2 +- src/channel.c | 21 +++++++++++++++------ src/packet.c | 2 +- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/include/libssh2.h b/include/libssh2.h index 7c23185..d2e5840 100644 --- a/include/libssh2.h +++ b/include/libssh2.h @@ -43,6 +43,7 @@ #include #define LIBSSH2_VERSION "0.1" +#define LIBSSH2_APINO 200412080954 /* Part of every banner, user specified or not */ #define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION @@ -176,6 +177,13 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, #define LIBSSH2_CHANNEL_WINDOW_DEFAULT 65536 #define LIBSSH2_CHANNEL_PACKET_DEFAULT 16384 +/* Extended Data Handling */ +#define LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL 0 +#define LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE 1 +#define LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE 2 + +#define SSH_EXTENDED_DATA_STDERR 1 + LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, char *channel_type, int channel_type_len, int window_size, int packet_size, char *message, int message_len); #define libssh2_channel_open_session(session) libssh2_channel_open_ex((session), "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0) LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, char *host, int port, char *shost, int sport); @@ -192,7 +200,6 @@ LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, char * #define libssh2_channel_exec(channel, command) libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, (command), strlen(command)) #define libssh2_channel_subsystem(channel, subsystem) libssh2_channel_process_startup((channel), "subsystem", sizeof("subsystem") - 1, (subsystem), strlen(subsystem)) -#define SSH_EXTENDED_DATA_STDERR 1 LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen); #define libssh2_channel_read(channel, buf, buflen) libssh2_channel_read_ex((channel), 0, (buf), (buflen)) #define libssh2_channel_read_stderr(channel, buf, buflen) libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen)) @@ -202,7 +209,14 @@ LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id #define libssh2_channel_write_stderr(channel, buf, buflen) libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen)) LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking); -LIBSSH2_API void libssh2_channel_ignore_extended_data(LIBSSH2_CHANNEL *channel, int ignore); +LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode); +/* libssh2_channel_ignore_extended_data() is defined below for BC with version 0.1 + * Future uses should use libssh2_channel_handle_extended_data() directly + * if LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE is passed, extended data will be read (FIFO) from the standard data channel + */ +/* DEPRECATED */ +#define libssh2_channel_ignore_extended_data(channel, ignore) libssh2_channel_handle_extended_data((channel), (ignore) ? LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL ) + LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel); LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL *channel); diff --git a/include/libssh2_priv.h b/include/libssh2_priv.h index ef5b42d..91cdb6a 100644 --- a/include/libssh2_priv.h +++ b/include/libssh2_priv.h @@ -98,7 +98,7 @@ typedef struct _libssh2_channel_data { unsigned long window_size_initial, window_size, packet_size; /* Set to 1 when CHANNEL_CLOSE / CHANNEL_EOF sent/received */ - char close, eof, ignore_extended_data; + char close, eof, extended_data_ignore_mode; } libssh2_channel_data; struct _LIBSSH2_CHANNEL { diff --git a/src/channel.c b/src/channel.c index 3f14647..d9caee3 100644 --- a/src/channel.c +++ b/src/channel.c @@ -434,14 +434,18 @@ LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int bloc } /* }}} */ -/* {{{ libssh2_channel_ignore_extended_data - * Ignore (or stop ignoring) extended data +/* {{{ libssh2_channel_handle_extended_data + * How should extended data look to the calling app? + * Keep it in separate channels[_read() _read_stdder()]? (NORMAL) + * Merge the extended data to the standard data? [everything via _read()]? (MERGE) + * +Ignore it entirely [toss out packets as they come in]? (IGNORE) */ -LIBSSH2_API void libssh2_channel_ignore_extended_data(LIBSSH2_CHANNEL *channel, int ignore) +LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode) { - channel->remote.ignore_extended_data = ignore; + channel->remote.extended_data_ignore_mode = ignore_mode; - if (ignore) { + if (ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) { /* Flush queued extended data */ LIBSSH2_PACKET *packet = channel->session->packets.head; unsigned long refund_bytes = 0; @@ -502,8 +506,13 @@ LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, /* In case packet gets destroyed during this iteration */ LIBSSH2_PACKET *next = packet->next; + /* Either we asked for a specific extended data stream (and data was available), + * or the standard stream (and data was available), + * or the standard stream with extended_data_merge enabled and data was available + */ if ((stream_id && (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (channel->local.id == libssh2_ntohu32(packet->data + 1))) || - (!stream_id && (packet->data[0] == SSH_MSG_CHANNEL_DATA) && (channel->local.id == libssh2_ntohu32(packet->data + 1)))) { + (!stream_id && (packet->data[0] == SSH_MSG_CHANNEL_DATA) && (channel->local.id == libssh2_ntohu32(packet->data + 1))) || + (!stream_id && (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (channel->local.id == libssh2_ntohu32(packet->data + 1)) && (channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) { int want = buflen - bytes_read; int unlink_packet = 0; diff --git a/src/packet.c b/src/packet.c index 4190d3c..7db5ada 100644 --- a/src/packet.c +++ b/src/packet.c @@ -153,7 +153,7 @@ static int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, siz LIBSSH2_FREE(session, data); return 0; } - if (channel->remote.ignore_extended_data && (data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) { + if ((channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) && (data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) { /* Pretend we didn't receive this */ LIBSSH2_FREE(session, data);