* Since the packet as already had data read from it, it can't retrun

PACKET_EAGAIN while reading the rest of it.
* Get the error message in libssh2_scp_recv() in the same manner as it
  was gotten in libssh2_scp_send_ex()
This commit is contained in:
James Housley
2007-07-05 15:31:19 +00:00
parent b53db3d3a9
commit 6ac790a477
3 changed files with 37 additions and 19 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: scp_nonblock.c,v 1.5 2007/06/08 13:33:08 jehousley Exp $ * $Id: scp_nonblock.c,v 1.6 2007/07/05 15:31:19 jehousley Exp $
* *
* Sample showing how to do SCP transfers in a non-blocking manner. * Sample showing how to do SCP transfers in a non-blocking manner.
*/ */
@@ -146,7 +146,10 @@ int main(int argc, char *argv[])
channel = libssh2_scp_recv(session, scppath, &fileinfo); channel = libssh2_scp_recv(session, scppath, &fileinfo);
if ((!channel) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { if ((!channel) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
fprintf(stderr, "Unable to open a session\n"); char *err_msg;
libssh2_session_last_error(session, &err_msg, NULL, 0);
fprintf(stderr, "%s\n", err_msg);
goto shutdown; goto shutdown;
} }
} while (!channel); } while (!channel);

View File

@@ -790,6 +790,8 @@ struct _LIBSSH2_SESSION {
long scpRecv_size; long scpRecv_size;
long scpRecv_mtime; long scpRecv_mtime;
long scpRecv_atime; long scpRecv_atime;
char *scpRecv_err_msg;
long scpRecv_err_len;
LIBSSH2_CHANNEL *scpRecv_channel; LIBSSH2_CHANNEL *scpRecv_channel;
/* State variables used in libssh2_scp_send_ex() */ /* State variables used in libssh2_scp_send_ex() */

View File

@@ -162,7 +162,32 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
session->scpRecv_response_len++; session->scpRecv_response_len++;
if (session->scpRecv_response[0] != 'T') { if (session->scpRecv_response[0] != 'T') {
/*
* Set this as the default error for here, if
* we are successful it will be replaced
*/
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response, missing Time data", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response, missing Time data", 0);
session->scpRecv_err_len = libssh2_channel_packet_data_len(session->scpRecv_channel, 0);
session->scpRecv_err_msg = LIBSSH2_ALLOC(session, session->scpRecv_err_len+1);
if (!session->scpRecv_err_msg) {
goto scp_recv_error;
}
memset(session->scpRecv_err_msg, 0, session->scpRecv_err_len+1);
/* Read the remote error message */
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0, session->scpRecv_err_msg, session->scpRecv_err_len);
if (rc <= 0) {
/*
* Since we have alread started reading this packet, it is
* already in the systems so it can't return PACKET_EAGAIN
*/
LIBSSH2_FREE(session, session->scpRecv_err_msg);
session->scpRecv_err_msg = NULL;
goto scp_recv_error;
}
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, session->scpRecv_err_msg, 1);
goto scp_recv_error; goto scp_recv_error;
} }
@@ -419,15 +444,6 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
unsigned const char *base; unsigned const char *base;
int rc; int rc;
/*
* =============================== NOTE ===============================
* I know this is very ugly and not a really good use of "goto", but
* this case statement would be even uglier to do it any other way
*/
if (session->scpSend_state == libssh2_NB_state_jump1) {
goto scp_read_ex_point1;
}
if (session->scpSend_state == libssh2_NB_state_idle) { if (session->scpSend_state == libssh2_NB_state_idle) {
session->scpSend_command_len = path_len + sizeof("scp -t "); session->scpSend_command_len = path_len + sizeof("scp -t ");
@@ -598,8 +614,6 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
goto scp_send_error; goto scp_send_error;
} }
else if (session->scpSend_response[0] != 0) { else if (session->scpSend_response[0] != 0) {
session->scpSend_state = libssh2_NB_state_jump1;
/* /*
* Set this as the default error for here, if * Set this as the default error for here, if
* we are successful it will be replaced * we are successful it will be replaced
@@ -614,13 +628,12 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
memset(session->scpSend_err_msg, 0, session->scpSend_err_len+1); memset(session->scpSend_err_msg, 0, session->scpSend_err_len+1);
/* Read the remote error message */ /* Read the remote error message */
scp_read_ex_point1:
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, session->scpSend_err_msg, session->scpSend_err_len); rc = libssh2_channel_read_ex(session->scpSend_channel, 0, session->scpSend_err_msg, session->scpSend_err_len);
if (rc == PACKET_EAGAIN) { if (rc <= 0) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0); /*
return NULL; * Since we have alread started reading this packet, it is
} * already in the systems so it can't return PACKET_EAGAIN
else if (rc <= 0) { */
LIBSSH2_FREE(session, session->scpSend_err_msg); LIBSSH2_FREE(session, session->scpSend_err_msg);
session->scpSend_err_msg = NULL; session->scpSend_err_msg = NULL;
goto scp_send_error; goto scp_send_error;