1
1

First, only try to send max packet size *4 to channel write, as trying to send

much larger packages only cause internal problems and much larger allocations.

Also fix sftp_write() when _libssh2_channel_write() returns that a packet was
only partially sent as that is not an error.

Fixed a few error messages to more accurately point out the problem
Этот коммит содержится в:
Daniel Stenberg 2009-05-20 14:31:46 +02:00
родитель b95fe985af
Коммит b755f3eb10

Просмотреть файл

@ -1105,7 +1105,7 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
/* TODO: a partial write is not a critical error when in /* TODO: a partial write is not a critical error when in
non-blocking mode! */ non-blocking mode! */
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send FXP_READ command", 0); "_libssh2_channel_write() failed", 0);
sftp->read_packet = NULL; sftp->read_packet = NULL;
sftp->read_state = libssh2_NB_state_idle; sftp->read_state = libssh2_NB_state_idle;
return -1; return -1;
@ -1305,7 +1305,7 @@ static int sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
} }
else if (packet_len != retcode) { else if (packet_len != retcode) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send FXP_READ command", 0); "_libssh2_channel_write() failed", 0);
LIBSSH2_FREE(session, sftp->readdir_packet); LIBSSH2_FREE(session, sftp->readdir_packet);
sftp->readdir_packet = NULL; sftp->readdir_packet = NULL;
sftp->readdir_state = libssh2_NB_state_idle; sftp->readdir_state = libssh2_NB_state_idle;
@ -1409,10 +1409,12 @@ libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *hnd, char *buffer,
return rc; return rc;
} }
/* sftp_write /*
* Write data to a file handle * sftp_write
*
* Write data to an SFTP handle
*/ */
static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE * handle, const char *buffer, static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
size_t count) size_t count)
{ {
LIBSSH2_SFTP *sftp = handle->sftp; LIBSSH2_SFTP *sftp = handle->sftp;
@ -1421,20 +1423,28 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE * handle, const char *buffer,
unsigned long data_len, retcode; unsigned long data_len, retcode;
/* 25 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) + /* 25 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) +
offset(8) + count(4) */ offset(8) + count(4) */
ssize_t packet_len = handle->handle_len + count + 25; ssize_t packet_len;
unsigned char *s, *data; unsigned char *s, *data;
int rc; int rc;
/* There's no point in us accepting a VERY large packet here since we
cannot send it anyway. We just accept 4 times the big size to fill up
the queue somewhat. */
if(count > (MAX_SSH_PACKET_LEN*4))
count = MAX_SSH_PACKET_LEN*4;
packet_len = handle->handle_len + count + 25;
if (sftp->write_state == libssh2_NB_state_idle) { if (sftp->write_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Writing %lu bytes", _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Writing %lu bytes",
(unsigned long) count); (unsigned long) count);
s = sftp->write_packet = LIBSSH2_ALLOC(session, packet_len); s = sftp->write_packet = LIBSSH2_ALLOC(session, packet_len);
if (!sftp->write_packet) { if (!sftp->write_packet) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for FXP_WRITE packet", 0); "Unable to allocate memory for FXP_WRITE", 0);
return -1; return -1;
} }
_libssh2_htonu32(s, packet_len - 4); _libssh2_htonu32(s, packet_len - 4);
s += 4; s += 4;
*(s++) = SSH_FXP_WRITE; *(s++) = SSH_FXP_WRITE;
@ -1456,19 +1466,23 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE * handle, const char *buffer,
} }
if (sftp->write_state == libssh2_NB_state_created) { if (sftp->write_state == libssh2_NB_state_created) {
rc = _libssh2_channel_write(channel, 0, (char *) sftp->write_packet, rc = _libssh2_channel_write(channel, 0, (char *)sftp->write_packet,
packet_len); packet_len);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
if (packet_len != rc) { else if(rc < 0) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, /* an actual error */
"Unable to send FXP_READ command", 0); return rc;
LIBSSH2_FREE(session, sftp->write_packet); }
sftp->write_packet = NULL; else if(0 == rc) {
sftp->write_state = libssh2_NB_state_idle; /* an actual error */
fprintf(stderr, "WEIRDNESS\n");
return -1; return -1;
} }
else if (packet_len != rc) {
return rc;
}
LIBSSH2_FREE(session, sftp->write_packet); LIBSSH2_FREE(session, sftp->write_packet);
sftp->write_packet = NULL; sftp->write_packet = NULL;
sftp->write_state = libssh2_NB_state_sent; sftp->write_state = libssh2_NB_state_sent;
@ -2084,7 +2098,7 @@ static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path,
} }
if (packet_len != rc) { if (packet_len != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send FXP_READ command", 0); "_libssh2_channel_write() failed", 0);
LIBSSH2_FREE(session, packet); LIBSSH2_FREE(session, packet);
sftp->mkdir_state = libssh2_NB_state_idle; sftp->mkdir_state = libssh2_NB_state_idle;
return -1; return -1;