ftp: add 'list_only' to the transfer state struct

and rename it from 'ftp_list_only' since it is also used for SSH and
POP3. The state is updated internally for 'type=D' FTP URLs.

Added test case 1570 to verify.

Closes #6578
This commit is contained in:
Daniel Stenberg 2021-02-08 16:40:34 +01:00
parent 115c9e27f5
commit 528f71c2ec
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
10 changed files with 87 additions and 12 deletions

View File

@ -1378,7 +1378,7 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data)
result = Curl_pp_sendf(data, &ftpc->pp, "PRET %s",
data->set.str[STRING_CUSTOMREQUEST]?
data->set.str[STRING_CUSTOMREQUEST]:
(data->set.ftp_list_only?"NLST":"LIST"));
(data->state.list_only?"NLST":"LIST"));
else if(data->set.upload)
result = Curl_pp_sendf(data, &ftpc->pp, "PRET STOR %s",
conn->proto.ftpc.file);
@ -1485,7 +1485,7 @@ static CURLcode ftp_state_list(struct Curl_easy *data)
cmd = aprintf("%s%s%s",
data->set.str[STRING_CUSTOMREQUEST]?
data->set.str[STRING_CUSTOMREQUEST]:
(data->set.ftp_list_only?"NLST":"LIST"),
(data->state.list_only?"NLST":"LIST"),
lstArg? " ": "",
lstArg? lstArg: "");
free(lstArg);
@ -3648,7 +3648,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
if(result)
;
else if(data->set.ftp_list_only || !ftpc->file) {
else if(data->state.list_only || !ftpc->file) {
/* The specified path ends with a slash, and therefore we think this
is a directory that is requested, use LIST. But before that we
need to set ASCII transfer mode. */
@ -4356,7 +4356,7 @@ static CURLcode ftp_setup_connection(struct Curl_easy *data,
break;
case 'D': /* directory mode */
data->set.ftp_list_only = TRUE;
data->state.list_only = TRUE;
break;
case 'I': /* binary mode */

View File

@ -571,7 +571,7 @@ static CURLcode pop3_perform_command(struct Curl_easy *data)
const char *command = NULL;
/* Calculate the default command */
if(pop3->id[0] == '\0' || data->set.ftp_list_only) {
if(pop3->id[0] == '\0' || data->set.list_only) {
command = "LIST";
if(pop3->id[0] != '\0')

View File

@ -1157,7 +1157,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
* An option that changes the command to one that asks for a list only, no
* file info details. Used for FTP, POP3 and SFTP.
*/
data->set.ftp_list_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
data->set.list_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
case CURLOPT_APPEND:

View File

@ -1416,6 +1416,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
}
data->state.prefer_ascii = data->set.prefer_ascii;
data->state.list_only = data->set.list_only;
data->state.httpreq = data->set.method;
data->change.url = data->set.str[STRING_SET_URL];

View File

@ -1467,7 +1467,8 @@ struct UrlState {
BIT(stream_depends_e); /* set or don't set the Exclusive bit */
BIT(previouslypending); /* this transfer WAS in the multi->pending queue */
BIT(cookie_engine);
BIT(prefer_ascii); /* ASCII rather than binary */
BIT(prefer_ascii); /* ASCII rather than binary */
BIT(list_only); /* list directory contents */
};
@ -1807,7 +1808,7 @@ struct UserDefined {
BIT(tunnel_thru_httpproxy); /* use CONNECT through a HTTP proxy */
BIT(prefer_ascii); /* ASCII rather than binary */
BIT(remote_append); /* append, not overwrite, on upload */
BIT(ftp_list_only); /* switch FTP command for listing directories */
BIT(list_only); /* list directory */
#ifndef CURL_DISABLE_FTP
BIT(ftp_use_port); /* use the FTP PORT command */
BIT(ftp_use_epsv); /* if EPSV is to be attempted or not */

View File

@ -1413,7 +1413,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
sshc->readdir_longentry = sshc->readdir_attrs->longname;
sshc->readdir_len = strlen(sshc->readdir_filename);
if(data->set.ftp_list_only) {
if(data->set.list_only) {
char *tmpLine;
tmpLine = aprintf("%s\n", sshc->readdir_filename);

View File

@ -2143,7 +2143,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
readdir_len = (size_t) rc;
sshp->readdir_filename[readdir_len] = '\0';
if(data->set.ftp_list_only) {
if(data->set.list_only) {
result = Curl_client_write(data, CLIENTWRITE_BODY,
sshp->readdir_filename,
readdir_len);

View File

@ -859,7 +859,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block)
result = CURLE_OK;
while(name) {
char *line = aprintf("%s\n",
data->set.ftp_list_only ?
data->set.list_only ?
name->fName : name->lName);
if(line == NULL) {
state(data, SSH_SFTP_CLOSE);

View File

@ -187,7 +187,7 @@ test1540 \
\
test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \
test1558 test1559 test1560 test1561 test1562 test1563 test1564 test1565 \
test1566 test1567 test1568 test1569 \
test1566 test1567 test1568 test1569 test1570 \
\
test1590 test1591 test1592 test1593 test1594 test1595 test1596 \
\

73
tests/data/test1570 Normal file
View File

@ -0,0 +1,73 @@
<testcase>
<info>
<keywords>
FTP
PASV
RETR
</keywords>
</info>
# Server-side
<reply>
<data nocheck="yes">
data
to
see
that FTP
works
so does it?
</data>
<servercmd>
REPLY EPSV 500 no such command
</servercmd>
</reply>
# Client-side
<client>
<server>
ftp
</server>
<name>
FTP first type=D then regular URL
</name>
<tool>
lib1569
</tool>
<command>
"ftp://%HOSTIP:%FTPPORT/1570;type=D" ftp://%HOSTIP:%FTPPORT/1570
</command>
</client>
# Verify data after the test has been "shot"
<verify>
<protocol>
USER anonymous
PASS ftp@example.com
PWD
EPSV
PASV
TYPE A
NLST
PASV
TYPE I
SIZE 1570
RETR 1570
QUIT
</protocol>
</verify>
<stdout>
data
to
see
that FTP
works
so does it?
data
to
see
that FTP
works
so does it?
</stdout>
</testcase>