Hello,
it seems that some libssh2 SCP functions do not correctly handle
whitespace in file names. When trying to copy a file named "with blanks"
using libssh2_scp_recv() I get an error message.
The reason is that libssh2 builds a "scp" command line that will be
run on the remote side, but does not take care to quote the file
name. It runs the equivalent of the following "ssh" command:
scp -f with blanks
instead of (note the quotation marks):
scp -f 'with blanks'
The code causing problems is in libssh2_scp_recv():
memcpy(session->scpRecv_command, "scp -f ", sizeof("scp -f ") - 1);
memcpy(session->scpRecv_command + sizeof("scp -f ") - 1, path,
path_len);
(Similar code is in libssh2_scp_send()).
Variable "path" should get correct quoting.
I attached the function shell_quotearg() that could be used for quoting
the path name.
Greetings
Heiner
/*
shell_quotearg - quote arguments for the shell in single quotation marks
Heiner Steven <[EMAIL PROTECTED]>, Public Domain
usage:
unsigned len;
char *path, quotedpath[PATH_LEN];
len = shell_quotearg(path, quotedpath, sizeof(quotedpath));
if (len == 0) {
fprintf(stderr, "ERROR: path buffer too small (%d bytes)\n",
sizeof(quotedpath));
}
printf("path=<%s>, quotedpath=<%s>\n", path, quotedpath);
Basically we quote an argument in apostrophes, e.g.
one two
becomes
'one two'
If the string contains an apostrophe itself, we have a special case
because the shell cannot handle it (the shell syntax 'doesn\'t' will
not work). Instead we close the current argument word, add a quoted
apostrophe, and open a new argument word:
_____ _ _
'doesn' \' 't'
The result buffer must be large enough for the expanded result. The
worst case regarding expansion are alternating characters and
apostrophes:
a'b'c'd' (length 8) get converted to
'a'\''b'\''c'\''d'\' (length 20)
Maximum size of the result:
2 + 5 * length(result) / 2 + 1
Explanation:
o leading + trailing apostrophy
o one pair of character and apostrophy (two characters) get
represented as five characters: a' -> a'\''
o String terminator
A result buffer roughly three times the size of the input buffer
should be safe.
Return value:
Length of the resulting string (not counting the terminating '\0'),
or 0 in case of errors, e.g. result buffer too small
*/
#include <assert.h>
unsigned shell_quotearg(const char *arg, char *buf, size_t bufsize)
{
const char *src;
char *dst, *endp;
bool_t instring;
assert(arg);
assert (buf && bufsize >= 3); /* Smallest result: "''" */
endp = &buf[bufsize];
src = arg;
dst = buf;
instring = false; /* Are we within a ' string? */
while (*src && dst < endp - 1) {
if (*src != '\'') {
if (!instring) {
if (dst+2 >= endp) return 0;
*dst++ = '\'';
instring = true;
}
*dst++ = *src++;
continue;
}
if (instring) {
if (dst+3 >= endp) return 0;
*dst++ = '\'';
*dst++ = '\\';
*dst++ = '\'';
instring = false;
} else {
if (dst+2 >= endp) return 0;
*dst++ = '\\';
*dst++ = '\'';
}
src++;
}
if (instring) {
if (dst+1 >= endp) return 0;
*dst++ = '\'';
}
*dst = '\0';
return dst - buf;
}
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
libssh2-devel mailing list
libssh2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libssh2-devel