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:
Родитель
b0a4c992e7
Коммит
ea43bb013b
8
CHANGES
8
CHANGES
|
@ -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:
|
||||||
|
|
||||||
|
|
22
docs/curl.1
22
docs/curl.1
|
@ -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
|
||||||
|
|
27
lib/ssh.c
27
lib/ssh.c
|
@ -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
|
||||||
|
|
|
@ -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>
|
Загрузка…
Ссылка в новой задаче