mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-11 18:50:28 +09:00
Improve channel_write().
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@689 7dcaeef0-15fb-0310-b436-a5af3365683c
This commit is contained in:
@@ -847,62 +847,72 @@ error:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief blocking write on channel
|
/**
|
||||||
* \param channel channel
|
* @brief Blocking write on channel.
|
||||||
* \param data pointer to data to write
|
*
|
||||||
* \param len length of data
|
* @param channel The channel to write to.
|
||||||
* \return number of bytes written on success\n
|
*
|
||||||
* SSH_ERROR on error
|
* @param data A pointer to the data to write.
|
||||||
* \see channel_read()
|
*
|
||||||
|
* @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) {
|
int channel_write(CHANNEL *channel, const void *data, u32 len) {
|
||||||
SSH_SESSION *session=channel->session;
|
SSH_SESSION *session = channel->session;
|
||||||
|
int origlen = len;
|
||||||
int effectivelen;
|
int effectivelen;
|
||||||
int origlen=len;
|
|
||||||
enter_function();
|
enter_function();
|
||||||
if(channel->local_eof){
|
|
||||||
ssh_set_error(session,SSH_REQUEST_DENIED,"Can't write to channel %d:%d"
|
if (channel->local_eof) {
|
||||||
" after EOF was sent",channel->local_channel,channel->remote_channel);
|
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();
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(!channel->open || channel->delayed_close){
|
|
||||||
ssh_set_error(session,SSH_REQUEST_DENIED,"Remote channel is closed");
|
if (channel->open == 0 || channel->delayed_close != 0) {
|
||||||
|
ssh_set_error(session, SSH_REQUEST_DENIED, "Remote channel is closed");
|
||||||
leave_function();
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SSH1
|
#ifdef HAVE_SSH1
|
||||||
if(channel->version==1){
|
if (channel->version == 1) {
|
||||||
int err = channel_write1(channel,data,len);
|
int rc = channel_write1(channel, data, len);
|
||||||
leave_function();
|
leave_function();
|
||||||
return err;
|
return rc;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
while(len >0){
|
|
||||||
if(channel->remote_window<len){
|
while (len > 0) {
|
||||||
|
if (channel->remote_window < len) {
|
||||||
ssh_log(session, SSH_LOG_PROTOCOL,
|
ssh_log(session, SSH_LOG_PROTOCOL,
|
||||||
"Remote window is %d bytes. going to write %d bytes",
|
"Remote window is %d bytes. going to write %d bytes",
|
||||||
channel->remote_window,len);
|
channel->remote_window,
|
||||||
|
len);
|
||||||
ssh_log(session, SSH_LOG_PROTOCOL,
|
ssh_log(session, SSH_LOG_PROTOCOL,
|
||||||
"Waiting for a growing window message...");
|
"Waiting for a growing window message...");
|
||||||
// wonder what happens when the channel window is zero
|
/* What happens when the channel window is zero? */
|
||||||
while(channel->remote_window==0){
|
while(channel->remote_window == 0) {
|
||||||
// parse every incoming packet
|
/* parse every incoming packet */
|
||||||
packet_wait(channel->session,0,0);
|
packet_wait(channel->session, 0, 0);
|
||||||
}
|
}
|
||||||
effectivelen=len>channel->remote_window?channel->remote_window:len;
|
effectivelen = len > channel->remote_window ? channel->remote_window : len;
|
||||||
} else
|
} else {
|
||||||
effectivelen=len;
|
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_u8(session->out_buffer, SSH2_MSG_CHANNEL_DATA) < 0 ||
|
||||||
}
|
buffer_add_u32(session->out_buffer,
|
||||||
if (buffer_add_u32(session->out_buffer,htonl(effectivelen)) < 0) {
|
htonl(channel->remote_channel)) < 0 ||
|
||||||
goto error;
|
buffer_add_u32(session->out_buffer, htonl(effectivelen)) < 0 ||
|
||||||
}
|
buffer_add_data(session->out_buffer, data, effectivelen) < 0) {
|
||||||
if (buffer_add_data(session->out_buffer,data,effectivelen) < 0) {
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -910,12 +920,15 @@ int channel_write(CHANNEL *channel, const void *data, u32 len) {
|
|||||||
leave_function();
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_log(session, SSH_LOG_RARE,
|
ssh_log(session, SSH_LOG_RARE,
|
||||||
"channel_write wrote %d bytes", effectivelen);
|
"channel_write wrote %d bytes", effectivelen);
|
||||||
channel->remote_window-=effectivelen;
|
|
||||||
|
channel->remote_window -= effectivelen;
|
||||||
len -= effectivelen;
|
len -= effectivelen;
|
||||||
data+=effectivelen;
|
data += effectivelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
return origlen;
|
return origlen;
|
||||||
error:
|
error:
|
||||||
|
|||||||
Reference in New Issue
Block a user