re-indented the source code with this script:

indent \
--braces-on-if-line \
--braces-after-struct-decl-line \
--space-after-cast \
--line-length 79 \
--comment-line-length 79 \
--cuddle-else \
--no-tabs \
--tab-size 8 \
--indent-level 4 \
--no-space-after-for \
--space-after-if \
--space-after-while \
--no-space-after-function-call-names \
*.[ch]
This commit is contained in:
Daniel Stenberg
2007-08-06 20:48:04 +00:00
parent 4c3dd3ea9f
commit 210459db4b
20 changed files with 6378 additions and 4497 deletions

537
src/scp.c
View File

@@ -46,7 +46,8 @@
* otherwise the blocking error code would erase the true
* cause of the error.
*/
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb)
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
{
int path_len = strlen(path);
int rc;
@@ -56,63 +57,78 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
session->scpRecv_size = 0;
session->scpRecv_mtime = 0;
session->scpRecv_atime = 0;
session->scpRecv_command_len = path_len + sizeof("scp -f ");
if (sb) {
session->scpRecv_command_len++;
}
session->scpRecv_command = LIBSSH2_ALLOC(session, session->scpRecv_command_len);
session->scpRecv_command =
LIBSSH2_ALLOC(session, session->scpRecv_command_len);
if (!session->scpRecv_command) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for SCP session", 0);
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a command buffer for SCP session",
0);
return NULL;
}
if (sb) {
memcpy(session->scpRecv_command, "scp -pf ", sizeof("scp -pf ") - 1);
memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path, path_len);
memcpy(session->scpRecv_command, "scp -pf ",
sizeof("scp -pf ") - 1);
memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path,
path_len);
} else {
memcpy(session->scpRecv_command, "scp -f ", sizeof("scp -f ") - 1);
memcpy(session->scpRecv_command + sizeof("scp -f ") - 1, path, path_len);
memcpy(session->scpRecv_command + sizeof("scp -f ") - 1, path,
path_len);
}
session->scpRecv_command[session->scpRecv_command_len - 1] = '\0';
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP receive");
_libssh2_debug(session, LIBSSH2_DBG_SCP,
"Opening channel for SCP receive");
session->scpRecv_state = libssh2_NB_state_created;
}
if (session->scpRecv_state == libssh2_NB_state_created) {
/* Allocate a channel */
do {
session->scpRecv_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT,
NULL, 0);
session->scpRecv_channel =
libssh2_channel_open_ex(session, "session",
sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
0);
if (!session->scpRecv_channel) {
if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
if (libssh2_session_last_errno(session) !=
LIBSSH2_ERROR_EAGAIN) {
LIBSSH2_FREE(session, session->scpRecv_command);
session->scpRecv_command = NULL;
session->scpRecv_state = libssh2_NB_state_idle;
return NULL;
}
else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0);
} else if (libssh2_session_last_errno(session) ==
LIBSSH2_ERROR_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel", 0);
return NULL;
}
}
} while (!session->scpRecv_channel);
session->scpRecv_state = libssh2_NB_state_sent;
}
if (session->scpRecv_state == libssh2_NB_state_sent) {
/* Request SCP for the desired file */
rc = libssh2_channel_process_startup(session->scpRecv_channel, "exec", sizeof("exec") - 1, (char *)session->scpRecv_command, session->scpRecv_command_len);
rc = libssh2_channel_process_startup(session->scpRecv_channel, "exec",
sizeof("exec") - 1,
(char *) session->scpRecv_command,
session->scpRecv_command_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting SCP startup", 0);
return NULL;
}
else if (rc) {
} else if (rc) {
LIBSSH2_FREE(session, session->scpRecv_command);
session->scpRecv_command = NULL;
goto scp_recv_error;
@@ -123,40 +139,47 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup");
/* SCP ACK */
session->scpRecv_response[0] = '\0';
session->scpRecv_state = libssh2_NB_state_sent1;
}
if (session->scpRecv_state == libssh2_NB_state_sent1) {
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1);
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
(char *) session->scpRecv_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending initial wakeup", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending initial wakeup", 0);
return NULL;
}
else if (rc != 1) {
} else if (rc != 1) {
goto scp_recv_error;
}
/* Parse SCP response */
session->scpRecv_response_len = 0;
session->scpRecv_state = libssh2_NB_state_sent2;
}
if ((session->scpRecv_state == libssh2_NB_state_sent2) || (session->scpRecv_state == libssh2_NB_state_sent3)) {
while (sb && (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN)) {
if ((session->scpRecv_state == libssh2_NB_state_sent2)
|| (session->scpRecv_state == libssh2_NB_state_sent3)) {
while (sb
&& (session->scpRecv_response_len <
LIBSSH2_SCP_RESPONSE_BUFLEN)) {
unsigned char *s, *p;
if (session->scpRecv_state == libssh2_NB_state_sent2) {
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
(char *)session->scpRecv_response + session->scpRecv_response_len, 1);
(char *) session->
scpRecv_response +
session->scpRecv_response_len, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for SCP response", 0);
return NULL;
}
else if (rc <= 0) {
} else if (rc <= 0) {
/* Timeout, give up */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Timed out waiting for SCP response", 0);
goto scp_recv_error;
}
session->scpRecv_response_len++;
@@ -166,17 +189,25 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
* 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);
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);
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);
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);
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
@@ -184,29 +215,49 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
*/
LIBSSH2_FREE(session, session->scpRecv_err_msg);
session->scpRecv_err_msg = NULL;
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unknown error while getting error string", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unknown error while getting error string",
0);
goto scp_recv_error;
}
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, session->scpRecv_err_msg, 1);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
session->scpRecv_err_msg, 1);
session->scpRecv_err_msg = NULL;
goto scp_recv_error;
}
if ((session->scpRecv_response_len > 1) &&
((session->scpRecv_response[session->scpRecv_response_len-1] < '0') ||
(session->scpRecv_response[session->scpRecv_response_len-1] > '9')) &&
(session->scpRecv_response[session->scpRecv_response_len-1] != ' ') &&
(session->scpRecv_response[session->scpRecv_response_len-1] != '\r') &&
(session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0);
((session->
scpRecv_response[session->scpRecv_response_len - 1] <
'0')
|| (session->
scpRecv_response[session->scpRecv_response_len - 1] >
'9'))
&& (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
' ')
&& (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\r')
&& (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid data in SCP response", 0);
goto scp_recv_error;
}
if ((session->scpRecv_response_len < 9) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) {
if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) {
if ((session->scpRecv_response_len < 9)
|| (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')) {
if (session->scpRecv_response_len ==
LIBSSH2_SCP_RESPONSE_BUFLEN) {
/* You had your chance */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unterminated response from SCP server",
0);
goto scp_recv_error;
}
/* Way too short to be an SCP response, or not done yet, short circuit */
@@ -214,125 +265,168 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
}
/* We're guaranteed not to go under response_len == 0 by the logic above */
while ((session->scpRecv_response[session->scpRecv_response_len-1] == '\r') || (session->scpRecv_response[session->scpRecv_response_len-1] == '\n')) session->scpRecv_response_len--;
session->scpRecv_response[session->scpRecv_response_len] = '\0';
while ((session->
scpRecv_response[session->scpRecv_response_len - 1] ==
'\r')
|| (session->
scpRecv_response[session->scpRecv_response_len -
1] == '\n'))
session->scpRecv_response_len--;
session->scpRecv_response[session->scpRecv_response_len] =
'\0';
if (session->scpRecv_response_len < 8) {
/* EOL came too soon */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short",
0);
goto scp_recv_error;
}
s = session->scpRecv_response + 1;
p = (unsigned char *)strchr((char *)s, ' ');
p = (unsigned char *) strchr((char *) s, ' ');
if (!p || ((p - s) <= 0)) {
/* No spaces or space in the wrong spot */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, malformed mtime",
0);
goto scp_recv_error;
}
*(p++) = '\0';
/* Make sure we don't get fooled by leftover values */
errno = 0;
session->scpRecv_mtime = strtol((char *)s, NULL, 10);
session->scpRecv_mtime = strtol((char *) s, NULL, 10);
if (errno) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mtime", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid mtime",
0);
goto scp_recv_error;
}
s = (unsigned char *)strchr((char *)p, ' ');
s = (unsigned char *) strchr((char *) p, ' ');
if (!s || ((s - p) <= 0)) {
/* No spaces or space in the wrong spot */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime.usec", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, malformed mtime.usec",
0);
goto scp_recv_error;
}
/* Ignore mtime.usec */
s++;
p = (unsigned char *)strchr((char *)s, ' ');
p = (unsigned char *) strchr((char *) s, ' ');
if (!p || ((p - s) <= 0)) {
/* No spaces or space in the wrong spot */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short or malformed",
0);
goto scp_recv_error;
}
*(p++) = '\0';
/* Make sure we don't get fooled by leftover values */
errno = 0;
session->scpRecv_atime = strtol((char *)s, NULL, 10);
session->scpRecv_atime = strtol((char *) s, NULL, 10);
if (errno) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid atime", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid atime",
0);
goto scp_recv_error;
}
/* SCP ACK */
session->scpRecv_response[0] = '\0';
session->scpRecv_state = libssh2_NB_state_sent3;
}
if (session->scpRecv_state == libssh2_NB_state_sent3) {
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1);
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
(char *) session->
scpRecv_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting to send SCP ACK", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting to send SCP ACK", 0);
return NULL;
}
else if (rc != 1) {
} else if (rc != 1) {
goto scp_recv_error;
}
_libssh2_debug(session, LIBSSH2_DBG_SCP, "mtime = %ld, atime = %ld", session->scpRecv_mtime, session->scpRecv_atime);
_libssh2_debug(session, LIBSSH2_DBG_SCP,
"mtime = %ld, atime = %ld",
session->scpRecv_mtime, session->scpRecv_atime);
/* We *should* check that atime.usec is valid, but why let that stop use? */
break;
}
}
session->scpRecv_state = libssh2_NB_state_sent4;
}
if (session->scpRecv_state == libssh2_NB_state_sent4) {
session->scpRecv_response_len = 0;
session->scpRecv_state = libssh2_NB_state_sent5;
}
if ((session->scpRecv_state == libssh2_NB_state_sent5) || (session->scpRecv_state == libssh2_NB_state_sent6)) {
if ((session->scpRecv_state == libssh2_NB_state_sent5)
|| (session->scpRecv_state == libssh2_NB_state_sent6)) {
while (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) {
char *s, *p, *e = NULL;
if (session->scpRecv_state == libssh2_NB_state_sent5) {
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
(char *)session->scpRecv_response + session->scpRecv_response_len, 1);
(char *) session->
scpRecv_response +
session->scpRecv_response_len, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for SCP response", 0);
return NULL;
}
else if (rc <= 0) {
} else if (rc <= 0) {
/* Timeout, give up */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Timed out waiting for SCP response", 0);
goto scp_recv_error;
}
session->scpRecv_response_len++;
if (session->scpRecv_response[0] != 'C') {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server", 0);
goto scp_recv_error;
}
if ((session->scpRecv_response_len > 1) &&
(session->scpRecv_response[session->scpRecv_response_len-1] != '\r') &&
(session->scpRecv_response[session->scpRecv_response_len-1] != '\n') &&
((session->scpRecv_response[session->scpRecv_response_len-1] < 32) ||
(session->scpRecv_response[session->scpRecv_response_len-1] > 126))) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0);
(session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\r')
&& (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')
&&
((session->
scpRecv_response[session->scpRecv_response_len - 1] < 32)
|| (session->
scpRecv_response[session->scpRecv_response_len - 1] >
126))) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid data in SCP response", 0);
goto scp_recv_error;
}
if ((session->scpRecv_response_len < 7) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) {
if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) {
if ((session->scpRecv_response_len < 7)
|| (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')) {
if (session->scpRecv_response_len ==
LIBSSH2_SCP_RESPONSE_BUFLEN) {
/* You had your chance */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unterminated response from SCP server",
0);
goto scp_recv_error;
}
/* Way too short to be an SCP response, or not done yet, short circuit */
@@ -340,24 +434,33 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
}
/* We're guaranteed not to go under response_len == 0 by the logic above */
while ((session->scpRecv_response[session->scpRecv_response_len-1] == '\r') ||
(session->scpRecv_response[session->scpRecv_response_len-1] == '\n')) {
while ((session->
scpRecv_response[session->scpRecv_response_len - 1] ==
'\r')
|| (session->
scpRecv_response[session->scpRecv_response_len -
1] == '\n')) {
session->scpRecv_response_len--;
}
session->scpRecv_response[session->scpRecv_response_len] = '\0';
session->scpRecv_response[session->scpRecv_response_len] =
'\0';
if (session->scpRecv_response_len < 6) {
/* EOL came too soon */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short",
0);
goto scp_recv_error;
}
s = (char *)session->scpRecv_response + 1;
s = (char *) session->scpRecv_response + 1;
p = strchr(s, ' ');
if (!p || ((p - s) <= 0)) {
/* No spaces or space in the wrong spot */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mode", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, malformed mode",
0);
goto scp_recv_error;
}
@@ -366,14 +469,17 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
errno = 0;
session->scpRecv_mode = strtol(s, &e, 8);
if ((e && *e) || errno) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mode", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid mode",
0);
goto scp_recv_error;
}
s = strchr(p, ' ');
if (!s || ((s - p) <= 0)) {
/* No spaces or space in the wrong spot */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed",
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short or malformed",
0);
goto scp_recv_error;
}
@@ -383,32 +489,38 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
errno = 0;
session->scpRecv_size = strtol(p, &e, 10);
if ((e && *e) || errno) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid size", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid size",
0);
goto scp_recv_error;
}
/* SCP ACK */
session->scpRecv_response[0] = '\0';
session->scpRecv_state = libssh2_NB_state_sent6;
}
if (session->scpRecv_state == libssh2_NB_state_sent6) {
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1);
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
(char *) session->
scpRecv_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending SCP ACK", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending SCP ACK", 0);
return NULL;
}
else if (rc != 1) {
} else if (rc != 1) {
goto scp_recv_error;
}
_libssh2_debug(session, LIBSSH2_DBG_SCP, "mode = 0%lo size = %ld", session->scpRecv_mode, session->scpRecv_size);
_libssh2_debug(session, LIBSSH2_DBG_SCP,
"mode = 0%lo size = %ld", session->scpRecv_mode,
session->scpRecv_size);
/* We *should* check that basename is valid, but why let that stop us? */
break;
}
}
session->scpRecv_state = libssh2_NB_state_sent7;
}
@@ -423,13 +535,14 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
session->scpRecv_state = libssh2_NB_state_idle;
return session->scpRecv_channel;
scp_recv_error:
scp_recv_error:
while (libssh2_channel_free(session->scpRecv_channel) == PACKET_EAGAIN);
session->scpRecv_channel = NULL;
session->scpRecv_state = libssh2_NB_state_idle;
return NULL;
}
/* }}} */
/* {{{ libssh2_scp_send_ex
@@ -440,7 +553,8 @@ scp_recv_error:
* cause of the error.
*/
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime)
libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
size_t size, long mtime, long atime)
{
int path_len = strlen(path);
unsigned const char *base;
@@ -448,124 +562,147 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
if (session->scpSend_state == libssh2_NB_state_idle) {
session->scpSend_command_len = path_len + sizeof("scp -t ");
if (mtime || atime) {
session->scpSend_command_len++;
}
session->scpSend_command = LIBSSH2_ALLOC(session, session->scpSend_command_len);
session->scpSend_command =
LIBSSH2_ALLOC(session, session->scpSend_command_len);
if (!session->scpSend_command) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for scp session", 0);
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a command buffer for scp session",
0);
return NULL;
}
if (mtime || atime) {
memcpy(session->scpSend_command, "scp -pt ", sizeof("scp -pt ") - 1);
memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path, path_len);
memcpy(session->scpSend_command, "scp -pt ",
sizeof("scp -pt ") - 1);
memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path,
path_len);
} else {
memcpy(session->scpSend_command, "scp -t ", sizeof("scp -t ") - 1);
memcpy(session->scpSend_command + sizeof("scp -t ") - 1, path, path_len);
memcpy(session->scpSend_command + sizeof("scp -t ") - 1, path,
path_len);
}
session->scpSend_command[session->scpSend_command_len - 1] = '\0';
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP send");
_libssh2_debug(session, LIBSSH2_DBG_SCP,
"Opening channel for SCP send");
/* Allocate a channel */
session->scpSend_state = libssh2_NB_state_created;
}
if (session->scpSend_state == libssh2_NB_state_created) {
session->scpSend_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0);
session->scpSend_channel =
libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0);
if (!session->scpSend_channel) {
if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
/* previous call set libssh2_session_last_error(), pass it through */
LIBSSH2_FREE(session, session->scpSend_command);
session->scpSend_command = NULL;
session->scpSend_state = libssh2_NB_state_idle;
return NULL;
}
else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0);
} else if (libssh2_session_last_errno(session) ==
LIBSSH2_ERROR_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel", 0);
return NULL;
}
}
session->scpSend_state = libssh2_NB_state_sent;
}
if (session->scpSend_state == libssh2_NB_state_sent) {
/* Request SCP for the desired file */
rc = libssh2_channel_process_startup(session->scpSend_channel, "exec", sizeof("exec") - 1,
(char *)session->scpSend_command, session->scpSend_command_len);
rc = libssh2_channel_process_startup(session->scpSend_channel, "exec",
sizeof("exec") - 1,
(char *) session->scpSend_command,
session->scpSend_command_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting SCP startup", 0);
return NULL;
}
else if (rc) {
} else if (rc) {
/* previous call set libssh2_session_last_error(), pass it through */
LIBSSH2_FREE(session, session->scpSend_command);
session->scpSend_command = NULL;
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unknown error while getting error string", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unknown error while getting error string", 0);
goto scp_send_error;
}
LIBSSH2_FREE(session, session->scpSend_command);
session->scpSend_command = NULL;
session->scpSend_state = libssh2_NB_state_sent1;
}
if (session->scpSend_state == libssh2_NB_state_sent1) {
/* Wait for ACK */
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1);
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response from remote", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response from remote", 0);
return NULL;
}
else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
} else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote", 0);
goto scp_send_error;
}
if (mtime || atime) {
/* Send mtime and atime to be used for file */
session->scpSend_response_len = snprintf((char *)session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN,
"T%ld 0 %ld 0\n", mtime, atime);
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", session->scpSend_response);
session->scpSend_response_len =
snprintf((char *) session->scpSend_response,
LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", mtime,
atime);
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s",
session->scpSend_response);
}
session->scpSend_state = libssh2_NB_state_sent2;
}
/* Send mtime and atime to be used for file */
if (mtime || atime) {
if (session->scpSend_state == libssh2_NB_state_sent2) {
rc = libssh2_channel_write_ex(session->scpSend_channel, 0, (char *)session->scpSend_response,
rc = libssh2_channel_write_ex(session->scpSend_channel, 0,
(char *) session->scpSend_response,
session->scpSend_response_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending time data for SCP file", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending time data for SCP file", 0);
return NULL;
}
else if (rc != session->scpSend_response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send time data for SCP file", 0);
} else if (rc != session->scpSend_response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send time data for SCP file", 0);
goto scp_send_error;
}
session->scpSend_state = libssh2_NB_state_sent3;
}
if (session->scpSend_state == libssh2_NB_state_sent3) {
/* Wait for ACK */
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1);
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
(char *) session->scpSend_response,
1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response", 0);
return NULL;
}
else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
} else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote", 0);
goto scp_send_error;
}
session->scpSend_state = libssh2_NB_state_sent4;
}
} else {
@@ -576,62 +713,73 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
if (session->scpSend_state == libssh2_NB_state_sent4) {
/* Send mode, size, and basename */
base = (unsigned char *)strrchr(path, '/');
base = (unsigned char *) strrchr(path, '/');
if (base) {
base++;
} else {
base = (unsigned char *)path;
base = (unsigned char *) path;
}
session->scpSend_response_len = snprintf((char *)session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN,
"C0%o %lu %s\n", mode, (unsigned long)size, base);
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", session->scpSend_response);
session->scpSend_response_len =
snprintf((char *) session->scpSend_response,
LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %lu %s\n", mode,
(unsigned long) size, base);
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s",
session->scpSend_response);
session->scpSend_state = libssh2_NB_state_sent5;
}
if (session->scpSend_state == libssh2_NB_state_sent5) {
rc = libssh2_channel_write_ex(session->scpSend_channel, 0, (char *)session->scpSend_response,
rc = libssh2_channel_write_ex(session->scpSend_channel, 0,
(char *) session->scpSend_response,
session->scpSend_response_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block send core file data for SCP file", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block send core file data for SCP file", 0);
return NULL;
}
else if (rc != session->scpSend_response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send core file data for SCP file", 0);
} else if (rc != session->scpSend_response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send core file data for SCP file", 0);
goto scp_send_error;
}
session->scpSend_state = libssh2_NB_state_sent6;
}
if (session->scpSend_state == libssh2_NB_state_sent6) {
/* Wait for ACK */
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1);
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response", 0);
return NULL;
}
else if (rc <= 0) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
} else if (rc <= 0) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote", 0);
goto scp_send_error;
}
else if (session->scpSend_response[0] != 0) {
} else if (session->scpSend_response[0] != 0) {
/*
* Set this as the default error for here, if
* we are successful it will be replaced
*/
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
session->scpSend_err_len = libssh2_channel_packet_data_len(session->scpSend_channel, 0);
session->scpSend_err_msg = LIBSSH2_ALLOC(session, session->scpSend_err_len+1);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote", 0);
session->scpSend_err_len =
libssh2_channel_packet_data_len(session->scpSend_channel, 0);
session->scpSend_err_msg =
LIBSSH2_ALLOC(session, session->scpSend_err_len + 1);
if (!session->scpSend_err_msg) {
goto scp_send_error;
}
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 */
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 <= 0) {
/*
* Since we have alread started reading this packet, it is
@@ -641,22 +789,23 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
session->scpSend_err_msg = NULL;
goto scp_send_error;
}
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, session->scpSend_err_msg, 1);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
session->scpSend_err_msg, 1);
session->scpSend_err_msg = NULL;
goto scp_send_error;
}
}
session->scpSend_state = libssh2_NB_state_idle;
return session->scpSend_channel;
scp_send_error:
scp_send_error:
while (libssh2_channel_free(session->scpSend_channel) == PACKET_EAGAIN);
session->scpSend_channel = NULL;
session->scpSend_state = libssh2_NB_state_idle;
return NULL;
}
/* }}} */
/* }}} */