diff -x '*Debug*' -x '*vc6*' -x '*ftpget*' -Naur curl-7.20.0-20091227/docs/curl.1 curl-pret/docs/curl.1 --- curl-7.20.0-20091227/docs/curl.1 2009-12-11 04:00:04.000000000 +0100 +++ curl-pret/docs/curl.1 2009-12-28 11:48:23.132034800 +0100 @@ -461,6 +461,11 @@ connection. (Added in 7.14.2) This option has no effect if PORT, EPRT or EPSV is used instead of PASV. +.IP "--ftp-pret" +(FTP) Tell curl to send a PRET command before PASV (and EPSV). Certain +FTP servers, mainly drftpd, require this non-standard command for +directory listings as well as up and downloads in PASV mode. +(Added in 7.20.x) .IP "--ftp-ssl" (FTP) Try to use SSL/TLS for the FTP connection. Reverts to a non-secure connection if the server doesn't support SSL/TLS. See also diff -x '*Debug*' -x '*vc6*' -x '*ftpget*' -Naur curl-7.20.0-20091227/docs/libcurl/curl_easy_setopt.3 curl-pret/docs/libcurl/curl_easy_setopt.3 --- curl-7.20.0-20091227/docs/libcurl/curl_easy_setopt.3 2009-11-24 04:00:08.000000000 +0100 +++ curl-pret/docs/libcurl/curl_easy_setopt.3 2009-12-27 23:20:47.199298800 +0100 @@ -1147,6 +1147,12 @@ pass zero to this option, it will not try using EPSV, only plain PASV. If the server is an IPv6 host, this option will have no effect as of 7.12.3. +.IP CURLOPT_FTP_USE_PRET +Pass a long. If the value is 1, it tells curl to send a PRET command +before PASV (and EPSV). Certain FTP servers, mainly drftpd, require this +non-standard command for directory listings as well as up and downloads in +PASV mode. Has no effect when using the active FTP transfers mode. +(Added in 7.20.x) .IP CURLOPT_FTP_CREATE_MISSING_DIRS Pass a long. If the value is 1, curl will attempt to create any remote directory that it fails to CWD into. CWD is the command that changes working diff -x '*Debug*' -x '*vc6*' -x '*ftpget*' -Naur curl-7.20.0-20091227/docs/libcurl/libcurl-errors.3 curl-pret/docs/libcurl/libcurl-errors.3 --- curl-7.20.0-20091227/docs/libcurl/libcurl-errors.3 2008-12-29 04:00:50.000000000 +0100 +++ curl-pret/docs/libcurl/libcurl-errors.3 2009-12-28 11:50:11.971260100 +0100 @@ -70,6 +70,10 @@ .IP "CURLE_FTP_WEIRD_227_FORMAT (14)" FTP servers return a 227-line as a response to a PASV command. If libcurl fails to parse that line, this return code is passed back. +.IP "CURLE_FTP_PRET_FAILED (84)" +The FTP server does not understand the PRET command at all or does not +support the given argument. Be careful when using \fICURLOPT_CUSTOMREQUEST\fP, +a custom LIST command will be sent with PRET CMD before PASV as well. .IP "CURLE_FTP_CANT_GET_HOST (15)" An internal failure to lookup the host used for the new connection. .IP "CURLE_FTP_COULDNT_SET_TYPE (17)" diff -x '*Debug*' -x '*vc6*' -x '*ftpget*' -Naur curl-7.20.0-20091227/include/curl/curl.h curl-pret/include/curl/curl.h --- curl-7.20.0-20091227/include/curl/curl.h 2009-12-27 04:00:04.000000000 +0100 +++ curl-pret/include/curl/curl.h 2009-12-28 11:49:05.510458800 +0100 @@ -413,6 +413,7 @@ wrong format (Added in 7.19.0) */ CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in 7.19.0) */ + CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ CURL_LAST /* never use! */ } CURLcode; @@ -1291,6 +1292,9 @@ /* set the SMTP mail receiver(s) */ CINIT(MAIL_RCPT, OBJECTPOINT, 187), + /* FTP: send PRET before PASV */ + CINIT(FTP_USE_PRET, LONG, 188), + CURLOPT_LASTENTRY /* the last unused */ } CURLoption; diff -x '*Debug*' -x '*vc6*' -x '*ftpget*' -Naur curl-7.20.0-20091227/lib/ftp.c curl-pret/lib/ftp.c --- curl-7.20.0-20091227/lib/ftp.c 2009-12-15 04:00:04.000000000 +0100 +++ curl-pret/lib/ftp.c 2009-12-28 11:47:36.908391000 +0100 @@ -565,6 +565,7 @@ "REST", "RETR_REST", "PORT", + "PRET", "PASV", "LIST", "RETR", @@ -1090,7 +1091,25 @@ } else { /* We have chosen (this is default) to use the PASV (or similar) command */ - result = ftp_state_use_pasv(conn); + if(data->set.ftp_use_pret) { + /* The user has requested that we send a PRET command + to prepare the server for the upcoming PASV */ + if(!conn->proto.ftpc.file) { + PPSENDF(&conn->proto.ftpc.pp, "PRET %s", data->set.str[STRING_CUSTOMREQUEST]? + data->set.str[STRING_CUSTOMREQUEST]: + (data->set.ftp_list_only?"NLST":"LIST")); + } + else if(data->set.upload) { + PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file); + } + else { + PPSENDF(&conn->proto.ftpc.pp, "PRET RETR %s", conn->proto.ftpc.file); + } + state(conn, FTP_PRET); + } + else { + result = ftp_state_use_pasv(conn); + } } return result; } @@ -2710,6 +2729,15 @@ result = ftp_state_rest_resp(conn, ftpcode, ftpc->state); break; + case FTP_PRET: + if(ftpcode != 200) { + /* there only is this one standard OK return code. */ + failf(data, "PRET command not accepted: %03d", ftpcode); + return CURLE_FTP_PRET_FAILED; + } + result = ftp_state_use_pasv(conn); + break; + case FTP_PASV: result = ftp_state_pasv_resp(conn, ftpcode); break; diff -x '*Debug*' -x '*vc6*' -x '*ftpget*' -Naur curl-7.20.0-20091227/lib/ftp.h curl-pret/lib/ftp.h --- curl-7.20.0-20091227/lib/ftp.h 2009-12-13 04:00:04.000000000 +0100 +++ curl-pret/lib/ftp.h 2009-12-27 23:13:04.598839600 +0100 @@ -79,6 +79,7 @@ FTP_REST, /* when used to check if the server supports it in head-like */ FTP_RETR_REST, /* when asking for "resume" in for RETR */ FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */ + FTP_PRET, /* generic state for PRET RETR, PRET STOR and PRET LIST/NLST */ FTP_PASV, /* generic state for PASV and EPSV, check count1 */ FTP_LIST, /* generic state for LIST, NLST or a custom list command */ FTP_RETR, diff -x '*Debug*' -x '*vc6*' -x '*ftpget*' -Naur curl-7.20.0-20091227/lib/strerror.c curl-pret/lib/strerror.c --- curl-7.20.0-20091227/lib/strerror.c 2009-07-23 04:00:02.000000000 +0200 +++ curl-pret/lib/strerror.c 2009-12-27 16:08:20.251218300 +0100 @@ -81,6 +81,9 @@ case CURLE_REMOTE_ACCESS_DENIED: return "Access denied to remote resource"; + case CURLE_FTP_PRET_FAILED: + return "FTP: The server did not accept the PRET command."; + case CURLE_FTP_WEIRD_PASS_REPLY: return "FTP: unknown PASS reply"; diff -x '*Debug*' -x '*vc6*' -x '*ftpget*' -Naur curl-7.20.0-20091227/lib/url.c curl-pret/lib/url.c --- curl-7.20.0-20091227/lib/url.c 2009-12-18 04:00:04.000000000 +0100 +++ curl-pret/lib/url.c 2009-12-27 23:12:21.216358300 +0100 @@ -701,6 +701,7 @@ set->httpreq = HTTPREQ_GET; /* Default HTTP request */ set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ + set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */ set->ftp_filemethod = FTPFILE_MULTICWD; set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ @@ -1563,6 +1564,10 @@ data->set.ftp_use_epsv = (bool)(0 != va_arg(param, long)); break; + case CURLOPT_FTP_USE_PRET: + data->set.ftp_use_pret = (bool)(0 != va_arg(param, long)); + break; + case CURLOPT_FTP_SSL_CCC: data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long); break; diff -x '*Debug*' -x '*vc6*' -x '*ftpget*' -Naur curl-7.20.0-20091227/lib/urldata.h curl-pret/lib/urldata.h --- curl-7.20.0-20091227/lib/urldata.h 2009-12-18 04:00:04.000000000 +0100 +++ curl-pret/lib/urldata.h 2009-12-27 23:11:57.877023300 +0100 @@ -1309,6 +1309,7 @@ bool reuse_fresh; /* do not re-use an existing connection */ bool ftp_use_epsv; /* if EPSV is to be attempted or not */ bool ftp_use_eprt; /* if EPRT is to be attempted or not */ + bool ftp_use_pret; /* if PRET is to be used before PASV or not */ curl_usessl ftp_ssl; /* if AUTH TLS is to be attempted etc, for FTP or IMAP or POP3 or others! */ diff -x '*Debug*' -x '*vc6*' -x '*ftpget*' -Naur curl-7.20.0-20091227/src/main.c curl-pret/src/main.c --- curl-7.20.0-20091227/src/main.c 2009-12-13 04:00:04.000000000 +0100 +++ curl-pret/src/main.c 2009-12-27 23:08:54.028507800 +0100 @@ -477,6 +477,7 @@ bool resume_from_current; bool disable_epsv; bool disable_eprt; + bool ftp_pret; curl_off_t resume_from; char *postfields; curl_off_t postfieldsize; @@ -794,6 +795,7 @@ " --ftp-pasv Use PASV/EPSV instead of PORT (F)", " -P/--ftp-port
Use PORT with address instead of PASV (F)", " --ftp-skip-pasv-ip Skip the IP address for PASV (F)\n" + " --ftp-pret Send PRET before PASV (for drftpd) (F)", " --ftp-ssl Try SSL/TLS for ftp transfer (F)", " --ftp-ssl-ccc Send CCC after authenticating (F)", " --ftp-ssl-ccc-mode [active/passive] Set CCC mode (F)", @@ -1746,6 +1748,7 @@ {"$9", "tftp-blksize", TRUE}, {"$A", "mail-from", TRUE}, {"$B", "mail-rcpt", TRUE}, + {"$C", "ftp-pret", FALSE}, {"0", "http1.0", FALSE}, {"1", "tlsv1", FALSE}, {"2", "sslv2", FALSE}, @@ -2281,6 +2284,9 @@ case 'B': /* --mail-rcpt */ GetStr(&config->mail_rcpt, nextarg); break; + case 'C': /* --ftp-pret */ + config->ftp_pret = toggle; + break; } break; case '#': /* --progress-bar */ @@ -5028,6 +5034,10 @@ if(config->mail_rcpt) my_setopt_str(curl, CURLOPT_MAIL_RCPT, config->mail_rcpt); + /* curl 7.20.x */ + if(config->ftp_pret) + my_setopt(curl, CURLOPT_FTP_USE_PRET, TRUE); + retry_numretries = config->req_retry; retrystart = cutil_tvnow();