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
Родитель b0a4c992e7
Коммит ea43bb013b
7 изменённых файлов: 102 добавлений и 33 удалений

Просмотреть файл

@ -8,6 +8,14 @@
Dan F (14 May 2007) Dan F (14 May 2007)
- Added SFTP directory listing test case 613. - 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) Dan F (9 May 2007)
- Kristian Gunstone fixed a problem where overwriting an uploaded file with - 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 sftp didn't truncate it first, which would corrupt the file if the new

Просмотреть файл

@ -16,6 +16,7 @@ This release includes the following changes:
o uses less memory in non-pipelined use cases o uses less memory in non-pipelined use cases
o CURLOPT_HTTP200ALIASES matched transfers assume HTTP 1.0 compliance 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 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: This release includes the following bugfixes:
@ -41,6 +42,7 @@ This release includes the following bugfixes:
o connection cache growth in multi handles o connection cache growth in multi handles
o better handling of out of memory conditions o better handling of out of memory conditions
o overwriting an uploaded file with sftp now truncates it first 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: This release includes the following known bugs:

Просмотреть файл

@ -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. default config file search path.
.IP "-Q/--quote <command>" .IP "-Q/--quote <command>"
(FTP/SFTP) Send an arbitrary command to the remote FTP or SFTP server. Quote (FTP/SFTP) Send an arbitrary command to the remote FTP or SFTP server. Quote
commands are commands are sent BEFORE the transfer is taking place (just after the
sent BEFORE the transfer is taking place (just after the initial PWD command initial PWD command in an FTP transfer, to be exact). To make commands
to be exact). To make commands take place after a successful transfer, prefix take place after a successful transfer, prefix them with a dash '-'.
them with a dash '-' (only the latter is supported with SFTP). To make To make commands get sent after libcurl has changed working directory,
commands get sent after libcurl has changed working directory, just just before the transfer command(s), prefix the command with '+' (this
before the transfer command(s), prefix the command with '+'. You may is only supported for FTP). You may specify any number of commands. If
specify any amount of commands. If the server returns failure for one the server returns failure for one of the commands, the entire operation
of the commands, the entire operation will be aborted. You must send will be aborted. You must send syntactically correct FTP commands as
syntactically correct FTP commands as RFC959 defines to FTP servers, or RFC959 defines to FTP servers, or one of the following commands (with
one of the following commands (with appropriate arguments) to SFTP servers: appropriate arguments) to SFTP servers: chgrp, chmod, chown, ln, mkdir,
chgrp, chmod, chown, ln, mkdir, rename, rm, rmdir, symlink. rename, rm, rmdir, symlink.
This option can be used multiple times. This option can be used multiple times.
.IP "--random-file <file>" .IP "--random-file <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 You disable PORT again and go back to using the passive version by setting
this option to NULL. this option to NULL.
.IP CURLOPT_QUOTE .IP CURLOPT_QUOTE
Pass a pointer to a linked list of FTP commands to pass to the server prior to Pass a pointer to a linked list of FTP or SFTP commands to pass to
your ftp request. This will be done before any other FTP commands are issued the server prior to your ftp request. This will be done before any
(even before the CWD command). The linked list should be a fully valid list of other commands are issued (even before the CWD command for FTP). The
'struct curl_slist' structs properly filled in. Use \fIcurl_slist_append(3)\fP linked list should be a fully valid list of 'struct curl_slist' structs
to append strings (commands) to the list, and clear the entire list afterwards properly filled in with text strings. Use \fIcurl_slist_append(3)\fP
with \fIcurl_slist_free_all(3)\fP. Disable this operation again by setting a to append strings (commands) to the list, and clear the entire list
NULL to this option. afterwards with \fIcurl_slist_free_all(3)\fP. Disable this operation
again by setting a NULL to this option.
.IP CURLOPT_POSTQUOTE .IP CURLOPT_POSTQUOTE
Pass a pointer to a linked list of FTP commands to pass to the server after Pass a pointer to a linked list of FTP or SFTP commands to pass to the
your ftp transfer request. The linked list should be a fully valid list of server after your ftp transfer request. The linked list should be a
struct curl_slist structs properly filled in as described for fully valid list of struct curl_slist structs properly filled in as
\fICURLOPT_QUOTE\fP. Disable this operation again by setting a NULL to this described for \fICURLOPT_QUOTE\fP. Disable this operation again by
option. setting a NULL to this option.
.IP CURLOPT_PREQUOTE .IP CURLOPT_PREQUOTE
Pass a pointer to a linked list of FTP commands to pass to the server after 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 the transfer type is set. The linked list should be a fully valid list of

Просмотреть файл

@ -714,6 +714,14 @@ CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
*done = TRUE; /* unconditionally */ *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) { if (data->set.upload) {
/* /*
* NOTE!!! libssh2 requires that the destination path is a full path * 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); Curl_safefree(sftp->homedir);
sftp->homedir = NULL; 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 (sftp->sftp_handle) {
if (libssh2_sftp_close(sftp->sftp_handle) < 0) { if (libssh2_sftp_close(sftp->sftp_handle) < 0) {
infof(conn->data, "Failed to close libssh2 file\n"); 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 (sftp->sftp_session) {
if (libssh2_sftp_shutdown(sftp->sftp_session) < 0) { if (libssh2_sftp_shutdown(sftp->sftp_session) < 0) {
infof(conn->data, "Failed to stop libssh2 sftp subsystem\n"); 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; const char *cp = *cpp, *end;
char quot; char quot;
u_int i, j; u_int i, j;
const char *WHITESPACE = " \t\r\n"; static const char * const WHITESPACE = " \t\r\n";
cp += strspn(cp, WHITESPACE); cp += strspn(cp, WHITESPACE);
if (!*cp) { if (!*cp) {
@ -1239,7 +1248,7 @@ static CURLcode sftp_sendquote(struct connectdata *conn,
/* Now set the new attributes... */ /* Now set the new attributes... */
if (curl_strnequal(item->data, "chgrp", 5)) { if (curl_strnequal(item->data, "chgrp", 5)) {
attrs.gid = strtol(path1, NULL, 10); attrs.gid = strtol(path1, NULL, 10);
if (attrs.gid == 0) { if (attrs.gid == 0 && !ISDIGIT(path1[0])) {
free(path1); free(path1);
free(path2); free(path2);
failf(data, "Syntax error: chgrp gid not a number"); 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)) { else if (curl_strnequal(item->data, "chmod", 5)) {
attrs.permissions = strtol(path1, NULL, 8);/* permissions are octal */ attrs.permissions = strtol(path1, NULL, 8);/* permissions are octal */
if (attrs.permissions == 0) { if (attrs.permissions == 0 && !ISDIGIT(path1[0])) {
free(path1); free(path1);
free(path2); free(path2);
failf(data, "Syntax error: chmod permissions not a number"); 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)) { else if (curl_strnequal(item->data, "chown", 5)) {
attrs.uid = strtol(path1, NULL, 10); attrs.uid = strtol(path1, NULL, 10);
if (attrs.uid == 0) { if (attrs.uid == 0 && !ISDIGIT(path1[0])) {
free(path1); free(path1);
free(path2); free(path2);
failf(data, "Syntax error: chown uid not a number"); failf(data, "Syntax error: chown uid not a number");

Просмотреть файл

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

49
tests/data/test614 Normal 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>