diff options
author | Andreas Schneider <mail@cynapses.org> | 2009-05-04 06:30:12 +0000 |
---|---|---|
committer | Andreas Schneider <mail@cynapses.org> | 2009-05-04 06:30:12 +0000 |
commit | 9345ba70308ffb0431079f8491e0e85f97ebb168 (patch) | |
tree | f42dd2c771af35503e9328bda84c45c6f0338b90 | |
parent | 17c146391c51f5dc2670d72489d72f9ae364f106 (diff) | |
download | libssh-9345ba70308ffb0431079f8491e0e85f97ebb168.tar.gz libssh-9345ba70308ffb0431079f8491e0e85f97ebb168.tar.xz libssh-9345ba70308ffb0431079f8491e0e85f97ebb168.zip |
Improve channel_write().
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@689 7dcaeef0-15fb-0310-b436-a5af3365683c
-rw-r--r-- | libssh/channels.c | 149 |
1 files changed, 81 insertions, 68 deletions
diff --git a/libssh/channels.c b/libssh/channels.c index 72219e55..400a2461 100644 --- a/libssh/channels.c +++ b/libssh/channels.c @@ -847,82 +847,95 @@ error: return rc; } -/** \brief blocking write on channel - * \param channel channel - * \param data pointer to data to write - * \param len length of data - * \return number of bytes written on success\n - * SSH_ERROR on error - * \see channel_read() +/** + * @brief Blocking write on channel. + * + * @param channel The channel to write to. + * + * @param data A pointer to the data to write. + * + * @param len The length of the buffer to write to. + * + * @return The number of bytes written, SSH_ERROR on error. + * + * @see channel_read() */ int channel_write(CHANNEL *channel, const void *data, u32 len) { - SSH_SESSION *session=channel->session; - int effectivelen; - int origlen=len; - enter_function(); - if(channel->local_eof){ - ssh_set_error(session,SSH_REQUEST_DENIED,"Can't write to channel %d:%d" - " after EOF was sent",channel->local_channel,channel->remote_channel); - leave_function(); - return -1; - } - if(!channel->open || channel->delayed_close){ - ssh_set_error(session,SSH_REQUEST_DENIED,"Remote channel is closed"); - leave_function(); - return -1; - } + SSH_SESSION *session = channel->session; + int origlen = len; + int effectivelen; + + enter_function(); + + if (channel->local_eof) { + ssh_set_error(session, SSH_REQUEST_DENIED, + "Can't write to channel %d:%d after EOF was sent", + channel->local_channel, + channel->remote_channel); + leave_function(); + return -1; + } + + if (channel->open == 0 || channel->delayed_close != 0) { + ssh_set_error(session, SSH_REQUEST_DENIED, "Remote channel is closed"); + leave_function(); + return -1; + } + #ifdef HAVE_SSH1 - if(channel->version==1){ - int err = channel_write1(channel,data,len); - leave_function(); - return err; - } + if (channel->version == 1) { + int rc = channel_write1(channel, data, len); + leave_function(); + return rc; + } #endif - while(len >0){ - if(channel->remote_window<len){ - ssh_log(session, SSH_LOG_PROTOCOL, - "Remote window is %d bytes. going to write %d bytes", - channel->remote_window,len); - ssh_log(session, SSH_LOG_PROTOCOL, - "Waiting for a growing window message..."); - // wonder what happens when the channel window is zero - while(channel->remote_window==0){ - // parse every incoming packet - packet_wait(channel->session,0,0); - } - effectivelen=len>channel->remote_window?channel->remote_window:len; - } else - effectivelen=len; - if (buffer_add_u8(session->out_buffer,SSH2_MSG_CHANNEL_DATA) < 0) { - goto error; - } - if (buffer_add_u32(session->out_buffer,htonl(channel->remote_channel)) < 0) { - goto error; - } - if (buffer_add_u32(session->out_buffer,htonl(effectivelen)) < 0) { - goto error; - } - if (buffer_add_data(session->out_buffer,data,effectivelen) < 0) { - goto error; - } - if (packet_send(session) != SSH_OK) { - leave_function(); - return SSH_ERROR; - } - ssh_log(session, SSH_LOG_RARE, - "channel_write wrote %d bytes", effectivelen); - channel->remote_window-=effectivelen; - len -= effectivelen; - data+=effectivelen; + while (len > 0) { + if (channel->remote_window < len) { + ssh_log(session, SSH_LOG_PROTOCOL, + "Remote window is %d bytes. going to write %d bytes", + channel->remote_window, + len); + ssh_log(session, SSH_LOG_PROTOCOL, + "Waiting for a growing window message..."); + /* What happens when the channel window is zero? */ + while(channel->remote_window == 0) { + /* parse every incoming packet */ + packet_wait(channel->session, 0, 0); + } + effectivelen = len > channel->remote_window ? channel->remote_window : len; + } else { + effectivelen = len; } - leave_function(); - return origlen; + + if (buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_DATA) < 0 || + buffer_add_u32(session->out_buffer, + htonl(channel->remote_channel)) < 0 || + buffer_add_u32(session->out_buffer, htonl(effectivelen)) < 0 || + buffer_add_data(session->out_buffer, data, effectivelen) < 0) { + goto error; + } + + if (packet_send(session) != SSH_OK) { + leave_function(); + return SSH_ERROR; + } + + ssh_log(session, SSH_LOG_RARE, + "channel_write wrote %d bytes", effectivelen); + + channel->remote_window -= effectivelen; + len -= effectivelen; + data += effectivelen; + } + + leave_function(); + return origlen; error: - buffer_free(session->out_buffer); + buffer_free(session->out_buffer); - leave_function(); - return SSH_ERROR; + leave_function(); + return SSH_ERROR; } /** \brief returns if the channel is open or not |