Added support for quote commands before a transfer using SFTP and test

case 614.
Allow SFTP quote commands chmod, chown, chgrp to set a value of 0.
This commit is contained in:
Dan Fandrich 2007-05-15 00:28:50 +00:00
parent b0a4c992e7
commit ea43bb013b
7 changed files with 102 additions and 33 deletions

View File

@ -8,6 +8,14 @@
Dan F (14 May 2007)
- Added SFTP directory listing test case 613.
- Added support for quote commands before a transfer using SFTP and test
case 614.
- Changed the post-quote commands to occur after the transferred file is
closed.
- Allow SFTP quote commands chmod, chown, chgrp to set a value of 0.
Dan F (9 May 2007)
- Kristian Gunstone fixed a problem where overwriting an uploaded file with
sftp didn't truncate it first, which would corrupt the file if the new

View File

@ -16,6 +16,7 @@ This release includes the following changes:
o uses less memory in non-pipelined use cases
o CURLOPT_HTTP200ALIASES matched transfers assume HTTP 1.0 compliance
o more than one test harness can run at the same time without conflict
o SFTP now supports quote commands before a transfer
This release includes the following bugfixes:
@ -41,6 +42,7 @@ This release includes the following bugfixes:
o connection cache growth in multi handles
o better handling of out of memory conditions
o overwriting an uploaded file with sftp now truncates it first
o SFTP quote commands chmod, chown, chgrp can now set a value of 0
This release includes the following known bugs:

View File

@ -897,17 +897,17 @@ file will not be read and used. See the \fI-K/--config\fP for details on the
default config file search path.
.IP "-Q/--quote <command>"
(FTP/SFTP) Send an arbitrary command to the remote FTP or SFTP server. Quote
commands are
sent BEFORE the transfer is taking place (just after the initial PWD command
to be exact). To make commands take place after a successful transfer, prefix
them with a dash '-' (only the latter is supported with SFTP). To make
commands get sent after libcurl has changed working directory, just
before the transfer command(s), prefix the command with '+'. You may
specify any amount of commands. If the server returns failure for one
of the commands, the entire operation will be aborted. You must send
syntactically correct FTP commands as RFC959 defines to FTP servers, or
one of the following commands (with appropriate arguments) to SFTP servers:
chgrp, chmod, chown, ln, mkdir, rename, rm, rmdir, symlink.
commands are sent BEFORE the transfer is taking place (just after the
initial PWD command in an FTP transfer, to be exact). To make commands
take place after a successful transfer, prefix them with a dash '-'.
To make commands get sent after libcurl has changed working directory,
just before the transfer command(s), prefix the command with '+' (this
is only supported for FTP). You may specify any number of commands. If
the server returns failure for one of the commands, the entire operation
will be aborted. You must send syntactically correct FTP commands as
RFC959 defines to FTP servers, or one of the following commands (with
appropriate arguments) to SFTP servers: chgrp, chmod, chown, ln, mkdir,
rename, rm, rmdir, symlink.
This option can be used multiple times.
.IP "--random-file <file>"

View File

@ -839,19 +839,20 @@ address. Default FTP operations are passive, and thus won't use PORT.
You disable PORT again and go back to using the passive version by setting
this option to NULL.
.IP CURLOPT_QUOTE
Pass a pointer to a linked list of FTP commands to pass to the server prior to
your ftp request. This will be done before any other FTP commands are issued
(even before the CWD command). The linked list should be a fully valid list of
'struct curl_slist' structs properly filled in. Use \fIcurl_slist_append(3)\fP
to append strings (commands) to the list, and clear the entire list afterwards
with \fIcurl_slist_free_all(3)\fP. Disable this operation again by setting a
NULL to this option.
Pass a pointer to a linked list of FTP or SFTP commands to pass to
the server prior to your ftp request. This will be done before any
other commands are issued (even before the CWD command for FTP). The
linked list should be a fully valid list of 'struct curl_slist' structs
properly filled in with text strings. Use \fIcurl_slist_append(3)\fP
to append strings (commands) to the list, and clear the entire list
afterwards with \fIcurl_slist_free_all(3)\fP. Disable this operation
again by setting a NULL to this option.
.IP CURLOPT_POSTQUOTE
Pass a pointer to a linked list of FTP commands to pass to the server after
your ftp transfer request. The linked list should be a fully valid list of
struct curl_slist structs properly filled in as described for
\fICURLOPT_QUOTE\fP. Disable this operation again by setting a NULL to this
option.
Pass a pointer to a linked list of FTP or SFTP commands to pass to the
server after your ftp transfer request. The linked list should be a
fully valid list of struct curl_slist structs properly filled in as
described for \fICURLOPT_QUOTE\fP. Disable this operation again by
setting a NULL to this option.
.IP CURLOPT_PREQUOTE
Pass a pointer to a linked list of FTP commands to pass to the server after
the transfer type is set. The linked list should be a fully valid list of

View File

@ -714,6 +714,14 @@ CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
*done = TRUE; /* unconditionally */
/* Send any quote commands */
if(conn->data->set.quote) {
infof(conn->data, "Sending quote commands\n");
res = sftp_sendquote(conn, conn->data->set.quote);
if (res != CURLE_OK)
return res;
}
if (data->set.upload) {
/*
* NOTE!!! libssh2 requires that the destination path is a full path
@ -980,17 +988,18 @@ CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode status,
Curl_safefree(sftp->homedir);
sftp->homedir = NULL;
/* Before we shut down, see if there are any post-quote commands to send: */
if(!status && !premature && conn->data->set.postquote) {
rc = sftp_sendquote(conn, conn->data->set.postquote);
}
if (sftp->sftp_handle) {
if (libssh2_sftp_close(sftp->sftp_handle) < 0) {
infof(conn->data, "Failed to close libssh2 file\n");
}
}
/* Before we shut down, see if there are any post-quote commands to send: */
if(!status && !premature && conn->data->set.postquote) {
infof(conn->data, "Sending postquote commands\n");
rc = sftp_sendquote(conn, conn->data->set.postquote);
}
if (sftp->sftp_session) {
if (libssh2_sftp_shutdown(sftp->sftp_session) < 0) {
infof(conn->data, "Failed to stop libssh2 sftp subsystem\n");
@ -1060,7 +1069,7 @@ get_pathname(const char **cpp, char **path)
const char *cp = *cpp, *end;
char quot;
u_int i, j;
const char *WHITESPACE = " \t\r\n";
static const char * const WHITESPACE = " \t\r\n";
cp += strspn(cp, WHITESPACE);
if (!*cp) {
@ -1239,7 +1248,7 @@ static CURLcode sftp_sendquote(struct connectdata *conn,
/* Now set the new attributes... */
if (curl_strnequal(item->data, "chgrp", 5)) {
attrs.gid = strtol(path1, NULL, 10);
if (attrs.gid == 0) {
if (attrs.gid == 0 && !ISDIGIT(path1[0])) {
free(path1);
free(path2);
failf(data, "Syntax error: chgrp gid not a number");
@ -1248,7 +1257,7 @@ static CURLcode sftp_sendquote(struct connectdata *conn,
}
else if (curl_strnequal(item->data, "chmod", 5)) {
attrs.permissions = strtol(path1, NULL, 8);/* permissions are octal */
if (attrs.permissions == 0) {
if (attrs.permissions == 0 && !ISDIGIT(path1[0])) {
free(path1);
free(path2);
failf(data, "Syntax error: chmod permissions not a number");
@ -1257,7 +1266,7 @@ static CURLcode sftp_sendquote(struct connectdata *conn,
}
else if (curl_strnequal(item->data, "chown", 5)) {
attrs.uid = strtol(path1, NULL, 10);
if (attrs.uid == 0) {
if (attrs.uid == 0 && !ISDIGIT(path1[0])) {
free(path1);
free(path2);
failf(data, "Syntax error: chown uid not a number");

View File

@ -41,4 +41,4 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
test603 test401 test402 test290 test291 test292 test293 test403 test404 \
test405 test604 test605 test606 test607 test608 test609 test294 test295 \
test296 test297 test298 test610 test611 test612 test406 test407 test408 \
test409 test613
test409 test613 test614

49
tests/data/test614 Normal file
View File

@ -0,0 +1,49 @@
<testcase>
<info>
<keywords>
SFTP
pre-quote
directory
</keywords>
</info>
#
# Server-side
<reply>
<datacheck>
d????????? N U U N ??? N NN:NN .
d????????? N U U N ??? N NN:NN ..
d????????? N U U N ??? N NN:NN asubdir
-r-?r-?r-? 1 U U 37 Jan 1 2000 plainfile.txt
-r-?r-?r-? 1 U U 47 Dec 31 2000 rofile.txt
</datacheck>
</reply>
#
# Client-side
<client>
<server>
sftp
</server>
<precheck>
perl %SRCDIR/libtest/test613.pl prepare %PWD/log/test614.dir
</precheck>
<name>
SFTP pre-quote chmod
</name>
<command>
--key curl_client_key --pubkey curl_client_key.pub -u %USER: -Q "chmod 444 %PWD/log/test614.dir/plainfile.txt" sftp://%HOSTIP:%SSHPORT%PWD/log/test614.dir/
</command>
<postcheck>
perl %SRCDIR/libtest/test613.pl postprocess %PWD/log/test614.dir %PWD/log/curl614.out
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<valgrind>
disable
</valgrind>
</verify>
</testcase>