summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/ftp.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl/src/ftp.c')
-rw-r--r--libs/libcurl/src/ftp.c422
1 files changed, 129 insertions, 293 deletions
diff --git a/libs/libcurl/src/ftp.c b/libs/libcurl/src/ftp.c
index dd90f54090..20991676f1 100644
--- a/libs/libcurl/src/ftp.c
+++ b/libs/libcurl/src/ftp.c
@@ -302,10 +302,10 @@ static void close_secondarysocket(struct Curl_easy *data)
* requests on files respond with headers passed to the client/stdout that
* looked like HTTP ones.
*
- * This approach is not very elegant, it causes confusion and is error-prone.
- * It is subject for removal at the next (or at least a future) soname bump.
- * Until then you can test the effects of the removal by undefining the
- * following define named CURL_FTP_HTTPSTYLE_HEAD.
+ * This approach is not elegant, it causes confusion and is error-prone. It is
+ * subject for removal at the next (or at least a future) soname bump. Until
+ * then you can test the effects of the removal by undefining the following
+ * define named CURL_FTP_HTTPSTYLE_HEAD.
*/
#define CURL_FTP_HTTPSTYLE_HEAD 1
@@ -419,138 +419,19 @@ static const struct Curl_cwtype ftp_cw_lc = {
#endif /* CURL_PREFER_LF_LINEENDS */
/***********************************************************************
*
- * AcceptServerConnect()
- *
- * After connection request is received from the server this function is
- * called to accept the connection and close the listening socket
- *
- */
-static CURLcode AcceptServerConnect(struct Curl_easy *data)
-{
- struct connectdata *conn = data->conn;
- curl_socket_t sock = conn->sock[SECONDARYSOCKET];
- curl_socket_t s = CURL_SOCKET_BAD;
-#ifdef USE_IPV6
- struct Curl_sockaddr_storage add;
-#else
- struct sockaddr_in add;
-#endif
- curl_socklen_t size = (curl_socklen_t) sizeof(add);
- CURLcode result;
-
- if(0 == getsockname(sock, (struct sockaddr *) &add, &size)) {
- size = sizeof(add);
-
- s = accept(sock, (struct sockaddr *) &add, &size);
- }
-
- if(CURL_SOCKET_BAD == s) {
- failf(data, "Error accept()ing server connect");
- return CURLE_FTP_PORT_FAILED;
- }
- infof(data, "Connection accepted from server");
- /* when this happens within the DO state it is important that we mark us as
- not needing DO_MORE anymore */
- conn->bits.do_more = FALSE;
-
- (void)curlx_nonblock(s, TRUE); /* enable non-blocking */
- /* Replace any filter on SECONDARY with one listening on this socket */
- result = Curl_conn_tcp_accepted_set(data, conn, SECONDARYSOCKET, &s);
- if(result) {
- sclose(s);
- return result;
- }
-
- if(data->set.fsockopt) {
- int error = 0;
-
- /* activate callback for setting socket options */
- Curl_set_in_callback(data, true);
- error = data->set.fsockopt(data->set.sockopt_client,
- s,
- CURLSOCKTYPE_ACCEPT);
- Curl_set_in_callback(data, false);
-
- if(error) {
- close_secondarysocket(data);
- return CURLE_ABORTED_BY_CALLBACK;
- }
- }
-
- return CURLE_OK;
-
-}
-
-/*
- * ftp_timeleft_accept() returns the amount of milliseconds left allowed for
- * waiting server to connect. If the value is negative, the timeout time has
- * already elapsed.
- *
- * The start time is stored in progress.t_acceptdata - as set with
- * Curl_pgrsTime(..., TIMER_STARTACCEPT);
- *
- */
-static timediff_t ftp_timeleft_accept(struct Curl_easy *data)
-{
- timediff_t timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
- timediff_t other;
- struct curltime now;
-
- if(data->set.accepttimeout > 0)
- timeout_ms = data->set.accepttimeout;
-
- now = Curl_now();
-
- /* check if the generic timeout possibly is set shorter */
- other = Curl_timeleft(data, &now, FALSE);
- if(other && (other < timeout_ms))
- /* note that this also works fine for when other happens to be negative
- due to it already having elapsed */
- timeout_ms = other;
- else {
- /* subtract elapsed time */
- timeout_ms -= Curl_timediff(now, data->progress.t_acceptdata);
- if(!timeout_ms)
- /* avoid returning 0 as that means no timeout! */
- return -1;
- }
-
- return timeout_ms;
-}
-
-
-/***********************************************************************
- *
- * ReceivedServerConnect()
- *
- * After allowing server to connect to us from data port, this function
- * checks both data connection for connection establishment and ctrl
- * connection for a negative response regarding a failure in connecting
+ * ftp_check_ctrl_on_data_wait()
*
*/
-static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received)
+static CURLcode ftp_check_ctrl_on_data_wait(struct Curl_easy *data)
{
struct connectdata *conn = data->conn;
curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET];
- curl_socket_t data_sock = conn->sock[SECONDARYSOCKET];
struct ftp_conn *ftpc = &conn->proto.ftpc;
struct pingpong *pp = &ftpc->pp;
- int socketstate = 0;
- timediff_t timeout_ms;
ssize_t nread;
int ftpcode;
bool response = FALSE;
- *received = FALSE;
-
- timeout_ms = ftp_timeleft_accept(data);
- infof(data, "Checking for server connect");
- if(timeout_ms < 0) {
- /* if a timeout was already reached, bail out */
- failf(data, "Accept timeout occurred while waiting server connect");
- return CURLE_FTP_ACCEPT_TIMEOUT;
- }
-
/* First check whether there is a cached response from server */
if(Curl_dyn_len(&pp->recvbuf) && (*Curl_dyn_ptr(&pp->recvbuf) > '3')) {
/* Data connection could not be established, let's return */
@@ -562,26 +443,22 @@ static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received)
if(pp->overflow)
/* there is pending control data still in the buffer to read */
response = TRUE;
- else
- socketstate = Curl_socket_check(ctrl_sock, data_sock, CURL_SOCKET_BAD, 0);
-
- /* see if the connection request is already here */
- switch(socketstate) {
- case -1: /* error */
- /* let's die here */
- failf(data, "Error while waiting for server connect");
- return CURLE_FTP_ACCEPT_FAILED;
- case 0: /* Server connect is not received yet */
- break; /* loop */
- default:
- if(socketstate & CURL_CSELECT_IN2) {
- infof(data, "Ready to accept data connection from server");
- *received = TRUE;
+ else {
+ int socketstate = Curl_socket_check(ctrl_sock, CURL_SOCKET_BAD,
+ CURL_SOCKET_BAD, 0);
+ /* see if the connection request is already here */
+ switch(socketstate) {
+ case -1: /* error */
+ /* let's die here */
+ failf(data, "Error while waiting for server connect");
+ return CURLE_FTP_ACCEPT_FAILED;
+ default:
+ if(socketstate & CURL_CSELECT_IN)
+ response = TRUE;
+ break;
}
- else if(socketstate & CURL_CSELECT_IN)
- response = TRUE;
- break;
}
+
if(response) {
infof(data, "Ctrl conn has data while waiting for data conn");
if(pp->overflow > 3) {
@@ -600,7 +477,6 @@ static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received)
noticed. Leave the 226 in there and use this as a trigger to read
the data socket. */
infof(data, "Got 226 before data activity");
- *received = TRUE;
return CURLE_OK;
}
}
@@ -619,7 +495,6 @@ static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received)
return CURLE_OK;
}
-
/***********************************************************************
*
* InitiateTransfer()
@@ -635,12 +510,6 @@ static CURLcode InitiateTransfer(struct Curl_easy *data)
bool connected;
CURL_TRC_FTP(data, "InitiateTransfer()");
- if(conn->bits.ftp_use_data_ssl && data->set.ftp_use_port &&
- !Curl_conn_is_ssl(conn, SECONDARYSOCKET)) {
- result = Curl_ssl_cfilter_add(data, conn, SECONDARYSOCKET);
- if(result)
- return result;
- }
result = Curl_conn_connect(data, SECONDARYSOCKET, TRUE, &connected);
if(result || !connected)
return result;
@@ -653,12 +522,14 @@ static CURLcode InitiateTransfer(struct Curl_easy *data)
/* set the SO_SNDBUF for the secondary socket for those who need it */
Curl_sndbuf_init(conn->sock[SECONDARYSOCKET]);
- Curl_xfer_setup2(data, CURL_XFER_SEND, -1, TRUE);
+ /* FTP upload, shutdown DATA, ignore shutdown errors, as we rely
+ * on the server response on the CONTROL connection. */
+ Curl_xfer_setup2(data, CURL_XFER_SEND, -1, TRUE, TRUE);
}
else {
- /* FTP download: */
+ /* FTP download, shutdown, do not ignore errors */
Curl_xfer_setup2(data, CURL_XFER_RECV,
- conn->proto.ftpc.retr_size_saved, TRUE);
+ conn->proto.ftpc.retr_size_saved, TRUE, FALSE);
}
conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
@@ -667,60 +538,6 @@ static CURLcode InitiateTransfer(struct Curl_easy *data)
return CURLE_OK;
}
-/***********************************************************************
- *
- * AllowServerConnect()
- *
- * When we have issue the PORT command, we have told the server to connect to
- * us. This function checks whether data connection is established if so it is
- * accepted.
- *
- */
-static CURLcode AllowServerConnect(struct Curl_easy *data, bool *connected)
-{
- timediff_t timeout_ms;
- CURLcode result = CURLE_OK;
-
- *connected = FALSE;
- infof(data, "Preparing for accepting server on data port");
-
- /* Save the time we start accepting server connect */
- Curl_pgrsTime(data, TIMER_STARTACCEPT);
-
- timeout_ms = ftp_timeleft_accept(data);
- if(timeout_ms < 0) {
- /* if a timeout was already reached, bail out */
- failf(data, "Accept timeout occurred while waiting server connect");
- result = CURLE_FTP_ACCEPT_TIMEOUT;
- goto out;
- }
-
- /* see if the connection request is already here */
- result = ReceivedServerConnect(data, connected);
- if(result)
- goto out;
-
- if(*connected) {
- result = AcceptServerConnect(data);
- if(result)
- goto out;
-
- result = InitiateTransfer(data);
- if(result)
- goto out;
- }
- else {
- /* Add timeout to multi handle and break out of the loop */
- Curl_expire(data, data->set.accepttimeout ?
- data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT,
- EXPIRE_FTP_ACCEPT);
- }
-
-out:
- CURL_TRC_FTP(data, "AllowServerConnect() -> %d", result);
- return result;
-}
-
static bool ftp_endofresp(struct Curl_easy *data, struct connectdata *conn,
char *line, size_t len, int *code)
{
@@ -864,8 +681,8 @@ CURLcode Curl_GetFTPResponse(struct Curl_easy *data,
*/
}
else if(!Curl_conn_data_pending(data, FIRSTSOCKET)) {
- curl_socket_t wsock = Curl_pp_needs_flush(data, pp)?
- sockfd : CURL_SOCKET_BAD;
+ curl_socket_t wsock = Curl_pp_needs_flush(data, pp) ?
+ sockfd : CURL_SOCKET_BAD;
int ev = Curl_socket_check(sockfd, CURL_SOCKET_BAD, wsock, interval_ms);
if(ev < 0) {
failf(data, "FTP response aborted due to select/poll error: %d",
@@ -914,7 +731,7 @@ static CURLcode ftp_state_user(struct Curl_easy *data,
{
CURLcode result = Curl_pp_sendf(data,
&conn->proto.ftpc.pp, "USER %s",
- conn->user?conn->user:"");
+ conn->user ? conn->user : "");
if(!result) {
struct ftp_conn *ftpc = &conn->proto.ftpc;
ftpc->ftp_trying_alternative = FALSE;
@@ -1138,7 +955,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
/* attempt to get the address of the given interface name */
switch(Curl_if2ip(conn->remote_addr->family,
#ifdef USE_IPV6
- Curl_ipv6_scope(&conn->remote_addr->sa_addr),
+ Curl_ipv6_scope(&conn->remote_addr->curl_sa_addr),
conn->scope_id,
#endif
ipstr, hbuf, sizeof(hbuf))) {
@@ -1304,12 +1121,6 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
conn->bits.ftp_use_eprt = TRUE;
#endif
- /* Replace any filter on SECONDARY with one listening on this socket */
- result = Curl_conn_tcp_listen_set(data, conn, SECONDARYSOCKET, &portsock);
- if(result)
- goto out;
- portsock = CURL_SOCKET_BAD; /* now held in filter */
-
for(; fcmd != DONE; fcmd++) {
if(!conn->bits.ftp_use_eprt && (EPRT == fcmd))
@@ -1343,7 +1154,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
*/
result = Curl_pp_sendf(data, &ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd],
- sa->sa_family == AF_INET?1:2,
+ sa->sa_family == AF_INET ? 1 : 2,
myhost, port);
if(result) {
failf(data, "Failure sending EPRT command: %s",
@@ -1368,7 +1179,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
source++;
}
*dest = 0;
- msnprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff));
+ msnprintf(dest, 20, ",%d,%d", (int)(port >> 8), (int)(port & 0xff));
result = Curl_pp_sendf(data, &ftpc->pp, "%s %s", mode[fcmd], target);
if(result) {
@@ -1382,9 +1193,13 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
/* store which command was sent */
ftpc->count1 = fcmd;
-
ftp_state(data, FTP_PORT);
+ /* Replace any filter on SECONDARY with one listening on this socket */
+ result = Curl_conn_tcp_listen_set(data, conn, SECONDARYSOCKET, &portsock);
+ if(!result)
+ portsock = CURL_SOCKET_BAD; /* now held in filter */
+
out:
/* If we looked up a dns_entry, now is the time to safely release it */
if(dns_entry)
@@ -1392,6 +1207,18 @@ out:
if(result) {
ftp_state(data, FTP_STOP);
}
+ else {
+ /* successfully setup the list socket filter. Do we need more? */
+ if(conn->bits.ftp_use_data_ssl && data->set.ftp_use_port &&
+ !Curl_conn_is_ssl(conn, SECONDARYSOCKET)) {
+ result = Curl_ssl_cfilter_add(data, conn, SECONDARYSOCKET);
+ }
+ data->conn->bits.do_more = FALSE;
+ Curl_pgrsTime(data, TIMER_STARTACCEPT);
+ Curl_expire(data, data->set.accepttimeout ?
+ data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT,
+ EXPIRE_FTP_ACCEPT);
+ }
if(portsock != CURL_SOCKET_BAD)
Curl_socket_close(data, conn, portsock);
return result;
@@ -1426,7 +1253,7 @@ static CURLcode ftp_state_use_pasv(struct Curl_easy *data,
conn->bits.ftp_use_epsv = TRUE;
#endif
- modeoff = conn->bits.ftp_use_epsv?0:1;
+ modeoff = conn->bits.ftp_use_epsv ? 0 : 1;
result = Curl_pp_sendf(data, &ftpc->pp, "%s", mode[modeoff]);
if(!result) {
@@ -1469,9 +1296,9 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data)
struct ftp_conn *ftpc = &conn->proto.ftpc;
if(!conn->proto.ftpc.file)
result = Curl_pp_sendf(data, &ftpc->pp, "PRET %s",
- data->set.str[STRING_CUSTOMREQUEST]?
- data->set.str[STRING_CUSTOMREQUEST]:
- (data->state.list_only?"NLST":"LIST"));
+ data->set.str[STRING_CUSTOMREQUEST] ?
+ data->set.str[STRING_CUSTOMREQUEST] :
+ (data->state.list_only ? "NLST" : "LIST"));
else if(data->state.upload)
result = Curl_pp_sendf(data, &ftpc->pp, "PRET STOR %s",
conn->proto.ftpc.file);
@@ -1576,11 +1403,11 @@ 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->state.list_only?"NLST":"LIST"),
- lstArg? " ": "",
- lstArg? lstArg: "");
+ data->set.str[STRING_CUSTOMREQUEST] ?
+ data->set.str[STRING_CUSTOMREQUEST] :
+ (data->state.list_only ? "NLST" : "LIST"),
+ lstArg ? " " : "",
+ lstArg ? lstArg : "");
free(lstArg);
if(!cmd)
@@ -1702,10 +1529,10 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
/* Let's read off the proper amount of bytes from the input. */
if(data->set.seek_func) {
- Curl_set_in_callback(data, true);
+ Curl_set_in_callback(data, TRUE);
seekerr = data->set.seek_func(data->set.seek_client,
data->state.resume_from, SEEK_SET);
- Curl_set_in_callback(data, false);
+ Curl_set_in_callback(data, FALSE);
}
if(seekerr != CURL_SEEKFUNC_OK) {
@@ -1736,7 +1563,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
} while(passed < data->state.resume_from);
}
/* now, decrease the size of the read */
- if(data->state.infilesize>0) {
+ if(data->state.infilesize > 0) {
data->state.infilesize -= data->state.resume_from;
if(data->state.infilesize <= 0) {
@@ -1756,7 +1583,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
/* we have passed, proceed as normal */
} /* resume_from */
- result = Curl_pp_sendf(data, &ftpc->pp, append?"APPE %s":"STOR %s",
+ result = Curl_pp_sendf(data, &ftpc->pp, append ? "APPE %s" : "STOR %s",
ftpc->file);
if(!result)
ftp_state(data, FTP_STOR);
@@ -1804,7 +1631,7 @@ static CURLcode ftp_state_quote(struct Curl_easy *data,
int i = 0;
/* Skip count1 items in the linked list */
- while((i< ftpc->count1) && item) {
+ while((i < ftpc->count1) && item) {
item = item->next;
i++;
}
@@ -2038,7 +1865,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
if(!ftpc->newhost)
return CURLE_OUT_OF_MEMORY;
- ftpc->newport = (unsigned short)(((ip[4]<<8) + ip[5]) & 0xffff);
+ ftpc->newport = (unsigned short)(((ip[4] << 8) + ip[5]) & 0xffff);
}
else if(ftpc->count1 == 0) {
/* EPSV failed, move on to PASV */
@@ -2101,7 +1928,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
}
result = Curl_conn_setup(data, conn, SECONDARYSOCKET, addr,
- conn->bits.ftp_use_data_ssl?
+ conn->bits.ftp_use_data_ssl ?
CURL_CF_SSL_ENABLE : CURL_CF_SSL_DISABLE);
if(result) {
@@ -2215,10 +2042,10 @@ static CURLcode client_write_header(struct Curl_easy *data,
* headers from CONNECT should not automatically be part of the
* output. */
CURLcode result;
- int save = data->set.include_header;
+ bool save = data->set.include_header;
data->set.include_header = TRUE;
result = Curl_client_write(data, CLIENTWRITE_HEADER, buf, blen);
- data->set.include_header = save? TRUE:FALSE;
+ data->set.include_header = save;
return result;
}
@@ -2267,15 +2094,16 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
return result;
/* format: "Tue, 15 Nov 1994 12:45:26" */
- headerbuflen = msnprintf(headerbuf, sizeof(headerbuf),
- "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
- Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
- tm->tm_mday,
- Curl_month[tm->tm_mon],
- tm->tm_year + 1900,
- tm->tm_hour,
- tm->tm_min,
- tm->tm_sec);
+ headerbuflen =
+ msnprintf(headerbuf, sizeof(headerbuf),
+ "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
+ Curl_wkday[tm->tm_wday ? tm->tm_wday-1 : 6],
+ tm->tm_mday,
+ Curl_month[tm->tm_mon],
+ tm->tm_year + 1900,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec);
result = client_write_header(data, headerbuf, headerbuflen);
if(result)
return result;
@@ -2387,7 +2215,7 @@ static CURLcode ftp_state_retr(struct Curl_easy *data,
else {
/* We got a file size report, so we check that there actually is a
part of the file left to get, or else we go home. */
- if(data->state.resume_from< 0) {
+ if(data->state.resume_from < 0) {
/* We are supposed to download the last abs(from) bytes */
if(filesize < -data->state.resume_from) {
failf(data, "Offset (%" FMT_OFF_T
@@ -2562,21 +2390,21 @@ static CURLcode ftp_state_stor_resp(struct Curl_easy *data,
/* PORT means we are now awaiting the server to connect to us. */
if(data->set.ftp_use_port) {
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
bool connected;
ftp_state(data, FTP_STOP); /* no longer in STOR state */
- result = AllowServerConnect(data, &connected);
+ result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected);
if(result)
return result;
if(!connected) {
- struct ftp_conn *ftpc = &conn->proto.ftpc;
infof(data, "Data conn was not available immediately");
ftpc->wait_data_conn = TRUE;
+ return ftp_check_ctrl_on_data_wait(data);
}
-
- return CURLE_OK;
+ ftpc->wait_data_conn = FALSE;
}
return InitiateTransfer(data);
}
@@ -2626,10 +2454,10 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
!data->set.ignorecl &&
(ftp->downloadsize < 1)) {
/*
- * It seems directory listings either do not show the size or very
- * often uses size 0 anyway. ASCII transfers may very well turn out
- * that the transferred amount of data is not the same as this line
- * tells, why using this number in those cases only confuses us.
+ * It seems directory listings either do not show the size or often uses
+ * size 0 anyway. ASCII transfers may cause that the transferred amount
+ * of data is not the same as this line tells, why using this number in
+ * those cases only confuses us.
*
* Example D above makes this parsing a little tricky */
char *bytes;
@@ -2676,21 +2504,22 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
conn->proto.ftpc.retr_size_saved = size;
if(data->set.ftp_use_port) {
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
bool connected;
- result = AllowServerConnect(data, &connected);
+ result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected);
if(result)
return result;
if(!connected) {
- struct ftp_conn *ftpc = &conn->proto.ftpc;
infof(data, "Data conn was not available immediately");
ftp_state(data, FTP_STOP);
ftpc->wait_data_conn = TRUE;
+ return ftp_check_ctrl_on_data_wait(data);
}
+ ftpc->wait_data_conn = FALSE;
}
- else
- return InitiateTransfer(data);
+ return InitiateTransfer(data);
}
else {
if((instate == FTP_LIST) && (ftpcode == 450)) {
@@ -2700,8 +2529,8 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
}
else {
failf(data, "RETR response: %03d", ftpcode);
- return instate == FTP_RETR && ftpcode == 550?
- CURLE_REMOTE_FILE_NOT_FOUND:
+ return instate == FTP_RETR && ftpcode == 550 ?
+ CURLE_REMOTE_FILE_NOT_FOUND :
CURLE_FTP_COULDNT_RETR_FILE;
}
}
@@ -2753,7 +2582,7 @@ static CURLcode ftp_state_user_resp(struct Curl_easy *data,
/* 331 Password required for ...
(the server requires to send the user's password too) */
result = Curl_pp_sendf(data, &ftpc->pp, "PASS %s",
- conn->passwd?conn->passwd:"");
+ conn->passwd ? conn->passwd : "");
if(!result)
ftp_state(data, FTP_PASS);
}
@@ -2964,7 +2793,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
if(ftpcode/100 == 2)
/* We have enabled SSL for the data connection! */
conn->bits.ftp_use_data_ssl =
- (data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE;
+ (data->set.use_ssl != CURLUSESSL_CONTROL);
/* FTP servers typically responds with 500 if they decide to reject
our 'P' request */
else if(data->set.use_ssl > CURLUSESSL_CONTROL)
@@ -3281,7 +3110,7 @@ static CURLcode ftp_multi_statemach(struct Curl_easy *data,
/* Check for the state outside of the Curl_socket_check() return code checks
since at times we are in fact already in this state when this function
gets called. */
- *done = (ftpc->state == FTP_STOP) ? TRUE : FALSE;
+ *done = (ftpc->state == FTP_STOP);
return result;
}
@@ -3403,9 +3232,9 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
if(data->state.wildcardmatch) {
if(data->set.chunk_end && ftpc->file) {
- Curl_set_in_callback(data, true);
+ Curl_set_in_callback(data, TRUE);
data->set.chunk_end(data->set.wildcardptr);
- Curl_set_in_callback(data, false);
+ Curl_set_in_callback(data, FALSE);
}
ftpc->known_filesize = -1;
}
@@ -3432,7 +3261,8 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
if(data->set.ftp_filemethod == FTPFILE_NOCWD)
pathLen = 0; /* relative path => working directory is FTP home */
else
- pathLen -= ftpc->file?strlen(ftpc->file):0; /* file is url-decoded */
+ /* file is url-decoded */
+ pathLen -= ftpc->file ? strlen(ftpc->file) : 0;
rawPath[pathLen] = '\0';
ftpc->prevpath = rawPath;
@@ -3550,7 +3380,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
}
else if(!ftpc->dont_check &&
!data->req.bytecount &&
- (data->req.size>0)) {
+ (data->req.size > 0)) {
failf(data, "No data was received");
result = CURLE_FTP_COULDNT_RETR_FILE;
}
@@ -3634,7 +3464,7 @@ CURLcode ftp_sendquote(struct Curl_easy *data,
static int ftp_need_type(struct connectdata *conn,
bool ascii_wanted)
{
- return conn->proto.ftpc.transfertype != (ascii_wanted?'A':'I');
+ return conn->proto.ftpc.transfertype != (ascii_wanted ? 'A' : 'I');
}
/***********************************************************************
@@ -3651,7 +3481,7 @@ static CURLcode ftp_nb_type(struct Curl_easy *data,
{
struct ftp_conn *ftpc = &conn->proto.ftpc;
CURLcode result;
- char want = (char)(ascii?'A':'I');
+ char want = (char)(ascii ? 'A' : 'I');
if(ftpc->transfertype == want) {
ftp_state(data, newstate);
@@ -3714,20 +3544,25 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
* complete */
struct FTP *ftp = NULL;
- /* if the second connection is not done yet, wait for it to have
- * connected to the remote host. When using proxy tunneling, this
- * means the tunnel needs to have been establish. However, we
- * can not expect the remote host to talk to us in any way yet.
- * So, when using ftps: the SSL handshake will not start until we
- * tell the remote server that we are there. */
+ /* if the second connection has been set up, try to connect it fully
+ * to the remote host. This may not complete at this time, for several
+ * reasons:
+ * - we do EPTR and the server will not connect to our listen socket
+ * until we send more FTP commands
+ * - an SSL filter is in place and the server will not start the TLS
+ * handshake until we send more FTP commands
+ */
if(conn->cfilter[SECONDARYSOCKET]) {
+ bool is_eptr = Curl_conn_is_tcp_listen(data, SECONDARYSOCKET);
result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected);
- if(result || !Curl_conn_is_ip_connected(data, SECONDARYSOCKET)) {
- if(result && (ftpc->count1 == 0)) {
+ if(result || (!connected && !is_eptr &&
+ !Curl_conn_is_ip_connected(data, SECONDARYSOCKET))) {
+ if(result && !is_eptr && (ftpc->count1 == 0)) {
*completep = -1; /* go back to DOING please */
/* this is a EPSV connect failing, try PASV instead */
return ftp_epsv_disable(data, conn);
}
+ *completep = (int)complete;
return result;
}
}
@@ -3760,16 +3595,14 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
if(ftpc->wait_data_conn) {
bool serv_conned;
- result = ReceivedServerConnect(data, &serv_conned);
+ result = Curl_conn_connect(data, SECONDARYSOCKET, TRUE, &serv_conned);
if(result)
return result; /* Failed to accept data connection */
if(serv_conned) {
/* It looks data connection is established */
- result = AcceptServerConnect(data);
ftpc->wait_data_conn = FALSE;
- if(!result)
- result = InitiateTransfer(data);
+ result = InitiateTransfer(data);
if(result)
return result;
@@ -3777,6 +3610,11 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
*completep = 1; /* this state is now complete when the server has
connected back to us */
}
+ else {
+ result = ftp_check_ctrl_on_data_wait(data);
+ if(result)
+ return result;
+ }
}
else if(data->state.upload) {
result = ftp_nb_type(data, conn, data->state.prefer_ascii,
@@ -3912,8 +3750,7 @@ static CURLcode init_wc_data(struct Curl_easy *data)
last_slash++;
if(last_slash[0] == '\0') {
wildcard->state = CURLWC_CLEAN;
- result = ftp_parse_url_path(data);
- return result;
+ return ftp_parse_url_path(data);
}
wildcard->pattern = strdup(last_slash);
if(!wildcard->pattern)
@@ -3929,8 +3766,7 @@ static CURLcode init_wc_data(struct Curl_easy *data)
}
else { /* only list */
wildcard->state = CURLWC_CLEAN;
- result = ftp_parse_url_path(data);
- return result;
+ return ftp_parse_url_path(data);
}
}
@@ -4050,11 +3886,11 @@ static CURLcode wc_statemach(struct Curl_easy *data)
infof(data, "Wildcard - START of \"%s\"", finfo->filename);
if(data->set.chunk_bgn) {
long userresponse;
- Curl_set_in_callback(data, true);
+ Curl_set_in_callback(data, TRUE);
userresponse = data->set.chunk_bgn(
finfo, data->set.wildcardptr,
(int)Curl_llist_count(&wildcard->filelist));
- Curl_set_in_callback(data, false);
+ Curl_set_in_callback(data, FALSE);
switch(userresponse) {
case CURL_CHUNK_BGN_FUNC_SKIP:
infof(data, "Wildcard - \"%s\" skipped by user",
@@ -4093,9 +3929,9 @@ static CURLcode wc_statemach(struct Curl_easy *data)
case CURLWC_SKIP: {
if(data->set.chunk_end) {
- Curl_set_in_callback(data, true);
+ Curl_set_in_callback(data, TRUE);
data->set.chunk_end(data->set.wildcardptr);
- Curl_set_in_callback(data, false);
+ Curl_set_in_callback(data, FALSE);
}
Curl_node_remove(Curl_llist_head(&wildcard->filelist));
wildcard->state = (Curl_llist_count(&wildcard->filelist) == 0) ?
@@ -4406,7 +4242,7 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data)
if(data->set.ftp_filemethod == FTPFILE_NOCWD)
n = 0; /* CWD to entry for relative paths */
else
- n -= ftpc->file?strlen(ftpc->file):0;
+ n -= ftpc->file ? strlen(ftpc->file) : 0;
if((strlen(oldPath) == n) && !strncmp(rawPath, oldPath, n)) {
infof(data, "Request has same path as previous transfer");