removed libssh2_error()'s forth argument

libssh2_error() no longer allocates a string and only accepts a const
error string. I also made a lot of functions use the construct of
return libssh2_error(...) instead of having one call to
libssh2_error() and then a separate return call. In several of those
cases I then also changed the former -1 return code to a more
detailed one - something that I think will not change behaviors
anywhere but it's worth keeping an eye open for any such.
This commit is contained in:
Daniel Stenberg
2010-03-03 23:04:05 +01:00
parent d377c3065a
commit d4a768af4e
15 changed files with 693 additions and 980 deletions

211
src/scp.c
View File

@@ -44,7 +44,7 @@
/* Max. length of a quoted string after libssh2_shell_quotearg() processing */
#define libssh2_shell_quotedsize(s) (3 * strlen(s) + 2)
#define libssh2_shell_quotedsize(s) (3 * strlen(s) + 2)
/*
This function quotes a string in a way suitable to be used with a
@@ -59,32 +59,32 @@
The following special cases are handled:
o If the string contains an apostrophy itself, the apostrophy
character is written in quotation marks, e.g. "'".
The shell cannot handle the syntax 'doesn\'t', so we close the
current argument word, add the apostrophe in quotation marks "",
and open a new argument word instead (_ indicate the input
string characters):
_____ _ _
'doesn' "'" 't'
character is written in quotation marks, e.g. "'".
The shell cannot handle the syntax 'doesn\'t', so we close the
current argument word, add the apostrophe in quotation marks "",
and open a new argument word instead (_ indicate the input
string characters):
_____ _ _
'doesn' "'" 't'
Sequences of apostrophes are combined in one pair of quotation marks:
a'''b
becomes
_ ___ _
'a'"'''"'b'
Sequences of apostrophes are combined in one pair of quotation marks:
a'''b
becomes
_ ___ _
'a'"'''"'b'
o If the string contains an exclamation mark (!), the C-Shell
interprets it as an event number. Using \! (not within quotation
marks or single quotation marks) is a mechanism understood by
both Bourne Shell and C-Shell.
o If the string contains an exclamation mark (!), the C-Shell
interprets it as an event number. Using \! (not within quotation
marks or single quotation marks) is a mechanism understood by
both Bourne Shell and C-Shell.
If a quotation was already started, the argument word is closed
first:
a!b
If a quotation was already started, the argument word is closed
first:
a!b
become
_ _ _
'a'\!'b'
become
_ _ _
'a'\!'b'
The result buffer must be large enough for the expanded result. A
bad case regarding expansion is alternating characters and
@@ -96,7 +96,7 @@
This is the worst case.
Maximum length of the result:
1 + 6 * (length(input) + 1) / 2) + 1
1 + 6 * (length(input) + 1) / 2) + 1
=> 3 * length(input) + 2
@@ -130,8 +130,8 @@ libssh2_shell_quotearg(const char *path, unsigned char *buf,
/*
* Processing States:
* UQSTRING: unquoted string: ... -- used for quoting exclamation
* marks. This is the initial state
* UQSTRING: unquoted string: ... -- used for quoting exclamation
* marks. This is the initial state
* SQSTRING: single-qouted-string: '... -- any character may follow
* QSTRING: quoted string: "... -- only apostrophes may follow
*/
@@ -142,23 +142,23 @@ libssh2_shell_quotearg(const char *path, unsigned char *buf,
dst = buf;
while (*src && dst < endp - 1) {
switch (*src) {
/*
* Special handling for apostrophe.
* An apostrophe is always written in quotation marks, e.g.
* ' -> "'".
*/
switch (*src) {
/*
* Special handling for apostrophe.
* An apostrophe is always written in quotation marks, e.g.
* ' -> "'".
*/
case '\'':
switch (state) {
case UQSTRING: /* Unquoted string */
case UQSTRING: /* Unquoted string */
if (dst+1 >= endp)
return 0;
*dst++ = '"';
break;
case QSTRING: /* Continue quoted string */
case QSTRING: /* Continue quoted string */
break;
case SQSTRING: /* Close single quoted string */
case SQSTRING: /* Close single quoted string */
if (dst+2 >= endp)
return 0;
*dst++ = '\'';
@@ -187,10 +187,10 @@ libssh2_shell_quotearg(const char *path, unsigned char *buf,
case QSTRING:
if (dst+2 >= endp)
return 0;
*dst++ = '"'; /* Closing quotation mark */
*dst++ = '"'; /* Closing quotation mark */
*dst++ = '\\';
break;
case SQSTRING: /* Close single quoted string */
case SQSTRING: /* Close single quoted string */
if (dst+2 >= endp)
return 0;
*dst++ = '\'';
@@ -202,9 +202,9 @@ libssh2_shell_quotearg(const char *path, unsigned char *buf,
state = UQSTRING;
break;
/*
* Ordinary character: prefer single-quoted string
*/
/*
* Ordinary character: prefer single-quoted string
*/
default:
switch (state) {
@@ -216,17 +216,17 @@ libssh2_shell_quotearg(const char *path, unsigned char *buf,
case QSTRING:
if (dst+2 >= endp)
return 0;
*dst++ = '"'; /* Closing quotation mark */
*dst++ = '"'; /* Closing quotation mark */
*dst++ = '\'';
break;
case SQSTRING: /* Continue single quoted string */
case SQSTRING: /* Continue single quoted string */
break;
default:
break;
}
state = SQSTRING; /* Start single-quoted string */
state = SQSTRING; /* Start single-quoted string */
break;
}
}
if (dst+1 >= endp)
return 0;
@@ -234,7 +234,7 @@ libssh2_shell_quotearg(const char *path, unsigned char *buf,
}
switch (state) {
case UQSTRING:
case UQSTRING:
break;
case QSTRING: /* Close quoted string */
if (dst+1 >= endp)
@@ -286,8 +286,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
if (!session->scpRecv_command) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a command buffer for SCP session",
0);
"Unable to allocate a command buffer for "
"SCP session");
return NULL;
}
@@ -324,7 +324,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
}
else {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel", 0);
"Would block starting up channel");
}
return NULL;
}
@@ -340,7 +340,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
session->scpRecv_command_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting SCP startup", 0);
"Would block requesting SCP startup");
return NULL;
} else if (rc) {
LIBSSH2_FREE(session, session->scpRecv_command);
@@ -362,7 +362,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
(char *) session->scpRecv_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending initial wakeup", 0);
"Would block sending initial wakeup");
return NULL;
} else if (rc != 1) {
goto scp_recv_error;
@@ -387,12 +387,12 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
session->scpRecv_response_len, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for SCP response", 0);
"Would block waiting for SCP response");
return NULL;
} else if (rc <= 0) {
/* Timeout, give up */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Timed out waiting for SCP response", 0);
"Timed out waiting for SCP response");
goto scp_recv_error;
}
session->scpRecv_response_len++;
@@ -403,8 +403,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
* we are successful it will be replaced
*/
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid data in SCP response, missing Time data",
0);
"Invalid data in SCP response, missing Time data");
session->scpRecv_err_len =
_libssh2_channel_packet_data_len(session->
@@ -427,16 +426,18 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
* 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;
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unknown error while getting error string",
0);
goto scp_recv_error;
"Unknown error" );
}
else
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"SCP protocol error");
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
session->scpRecv_err_msg, 1);
/* TODO: for debugging purposes, the
session->scpRecv_err_msg should be displayed here
when available */
LIBSSH2_FREE(session, session->scpRecv_err_msg);
session->scpRecv_err_msg = NULL;
goto scp_recv_error;
}
@@ -458,7 +459,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid data in SCP response", 0);
"Invalid data in SCP response");
goto scp_recv_error;
}
@@ -470,8 +471,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
LIBSSH2_SCP_RESPONSE_BUFLEN) {
/* You had your chance */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unterminated response from SCP server",
0);
"Unterminated response from SCP server");
goto scp_recv_error;
}
/* Way too short to be an SCP response, or not done yet,
@@ -494,8 +494,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
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);
"Invalid response from SCP server, "
"too short" );
goto scp_recv_error;
}
@@ -505,8 +505,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
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);
"Invalid response from SCP server, "
"malformed mtime");
goto scp_recv_error;
}
@@ -516,16 +516,14 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
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);
"Invalid response from SCP server, invalid mtime");
goto scp_recv_error;
}
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);
"Invalid response from SCP server, malformed mtime.usec");
goto scp_recv_error;
}
@@ -535,8 +533,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
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);
"Invalid response from SCP server, too short or malformed");
goto scp_recv_error;
}
@@ -546,8 +543,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
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);
"Invalid response from SCP server, invalid atime");
goto scp_recv_error;
}
@@ -563,7 +559,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
scpRecv_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting to send SCP ACK", 0);
"Would block waiting to send SCP ACK");
return NULL;
} else if (rc != 1) {
goto scp_recv_error;
@@ -600,19 +596,19 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
session->scpRecv_response_len, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for SCP response", 0);
"Would block waiting for SCP response");
return NULL;
} else if (rc <= 0) {
/* Timeout, give up */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Timed out waiting for SCP response", 0);
"Timed out waiting for SCP response");
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);
"Invalid response from SCP server");
goto scp_recv_error;
}
@@ -630,7 +626,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
scpRecv_response[session->scpRecv_response_len - 1] >
126))) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid data in SCP response", 0);
"Invalid data in SCP response");
goto scp_recv_error;
}
@@ -642,8 +638,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
LIBSSH2_SCP_RESPONSE_BUFLEN) {
/* You had your chance */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unterminated response from SCP server",
0);
"Unterminated response from SCP server");
goto scp_recv_error;
}
/* Way too short to be an SCP response, or not done yet,
@@ -667,8 +662,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
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);
"Invalid response from SCP server, too short");
goto scp_recv_error;
}
@@ -678,8 +672,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
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);
"Invalid response from SCP server, malformed mode");
goto scp_recv_error;
}
@@ -689,8 +682,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
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);
"Invalid response from SCP server, invalid mode");
goto scp_recv_error;
}
@@ -698,8 +690,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
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",
0);
"Invalid response from SCP server, too short or malformed");
goto scp_recv_error;
}
@@ -709,8 +700,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
session->scpRecv_size = scpsize_strtol(p, &e, 10);
if ((e && *e) || errno) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid size",
0);
"Invalid response from SCP server, invalid size");
goto scp_recv_error;
}
@@ -726,7 +716,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
scpRecv_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending SCP ACK", 0);
"Would block sending SCP ACK");
return NULL;
} else if (rc != 1) {
goto scp_recv_error;
@@ -800,8 +790,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
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);
"Unable to allocate a command buffer for scp session");
return NULL;
}
@@ -838,7 +827,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
}
else {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel", 0);
"Would block starting up channel");
}
return NULL;
}
@@ -854,7 +843,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
session->scpSend_command_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting SCP startup", 0);
"Would block requesting SCP startup");
return NULL;
}
else if (rc) {
@@ -863,7 +852,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
LIBSSH2_FREE(session, session->scpSend_command);
session->scpSend_command = NULL;
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unknown error while getting error string", 0);
"Unknown error while getting error string");
goto scp_send_error;
}
LIBSSH2_FREE(session, session->scpSend_command);
@@ -878,11 +867,11 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
(char *) session->scpSend_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response from remote", 0);
"Would block waiting for response from remote");
return NULL;
} else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote", 0);
"Invalid ACK response from remote");
goto scp_send_error;
}
@@ -907,11 +896,11 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
session->scpSend_response_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending time data for SCP file", 0);
"Would block sending time data for SCP file");
return NULL;
} else if (rc != (int)session->scpSend_response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send time data for SCP file", 0);
"Unable to send time data for SCP file");
goto scp_send_error;
}
@@ -924,11 +913,11 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
(char *) session->scpSend_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response", 0);
"Would block waiting for response");
return NULL;
} else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote", 0);
"Invalid ACK response from remote");
goto scp_send_error;
}
@@ -965,11 +954,11 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
session->scpSend_response_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block send core file data for SCP file", 0);
"Would block send core file data for SCP file");
return NULL;
} else if (rc != (int)session->scpSend_response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send core file data for SCP file", 0);
"Unable to send core file data for SCP file");
goto scp_send_error;
}
@@ -982,11 +971,11 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
(char *) session->scpSend_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response", 0);
"Would block waiting for response");
return NULL;
} else if (rc <= 0) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote", 0);
"Invalid ACK response from remote");
goto scp_send_error;
} else if (session->scpSend_response[0] != 0) {
/*
@@ -994,7 +983,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
* we are successful it will be replaced
*/
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote", 0);
"Invalid ACK response from remote");
session->scpSend_err_len =
_libssh2_channel_packet_data_len(session->scpSend_channel, 0);
@@ -1020,7 +1009,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
}
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
session->scpSend_err_msg, 1);
"failed waiting for ACK");
session->scpSend_err_msg = NULL;
goto scp_send_error;
}