From e0df43b9d35a2ccacfb61a60534fa2f51a6a9468 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 May 2026 18:39:12 +0200 Subject: [PATCH] protocol: introduce typedef for the do_more() function Instead of using magic values -1, 0 and -1 using enum. Closes #21509 --- lib/ftp.c | 27 +++++++++++++++------------ lib/multi.c | 18 +++++++++--------- lib/protocol.h | 14 ++++++++++++-- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/lib/ftp.c b/lib/ftp.c index 4f537db2b2..f06f8ef7ca 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -2281,10 +2281,10 @@ static CURLcode ftp_statemach(struct Curl_easy *data, * This function shall be called when the second FTP (data) connection is * connected. * - * 'complete' can return 0 for incomplete, 1 for done and -1 for go back + * 'more' can return DOMORE_INCOMPLETE, DOMORE_DONE or DOMORE_GOBACK * (which is for when PASV is being sent to retry a failed EPSV). */ -static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) +static CURLcode ftp_do_more(struct Curl_easy *data, domore *more) { struct connectdata *conn = data->conn; struct ftp_conn *ftpc = Curl_conn_meta_get(data->conn, CURL_META_FTP_CONN); @@ -2299,7 +2299,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) if(!ftpc || !ftp) return CURLE_FAILED_INIT; - *completep = 0; /* default to stay in the state */ + *more = DOMORE_INCOMPLETE; /* default to stay in the state */ /* 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 @@ -2317,7 +2317,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) 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 */ + *more = DOMORE_GOBACK; /* go back to DOING please */ /* this is a EPSV connect failing, try PASV instead */ return ftp_epsv_disable(data, ftpc, conn); } @@ -2330,7 +2330,8 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) They are only done to kickstart the do_more state */ result = ftp_statemach(data, ftpc, &complete); - *completep = (int)complete; + if(complete) + *more = DOMORE_DONE; /* if we got an error or if we do not wait for a data connection return immediately */ @@ -2340,7 +2341,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) /* if we reach the end of the FTP state machine here, *complete will be TRUE but so is ftpc->wait_data_conn, which says we need to wait for the data connection and therefore we are not actually complete */ - *completep = 0; + *more = DOMORE_INCOMPLETE; } if(ftp->transfer <= PPTRANSFER_INFO) { @@ -2362,8 +2363,8 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) if(result) return result; - *completep = 1; /* this state is now complete when the server has - connected back to us */ + *more = DOMORE_DONE; /* this state is now complete when the server has + connected back to us */ } else { result = ftp_check_ctrl_on_data_wait(data, ftpc); @@ -2382,7 +2383,8 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) * deemed necessary and directly sent `STORE name`. If this was * then complete, but we are still waiting on the data connection, * the transfer has not been initiated yet. */ - *completep = (int)(ftpc->wait_data_conn ? 0 : complete); + *more = (!ftpc->wait_data_conn && complete) ? + DOMORE_DONE : DOMORE_INCOMPLETE; } else { /* download */ @@ -2425,7 +2427,8 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) } result = ftp_statemach(data, ftpc, &complete); - *completep = (int)complete; + if(complete) + *more = DOMORE_DONE; } return result; } @@ -2435,7 +2438,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) if(!ftpc->wait_data_conn) { /* no waiting for the data connection so this is now complete */ - *completep = 1; + *more = DOMORE_DONE; CURL_TRC_FTP(data, "[%s] DO-MORE phase ends with %d", FTP_CSTATE(ftpc), (int)result); } @@ -2450,7 +2453,7 @@ static CURLcode ftp_dophase_done(struct Curl_easy *data, bool connected) { if(connected) { - int completed; + domore completed; CURLcode result = ftp_do_more(data, &completed); if(result) { diff --git a/lib/multi.c b/lib/multi.c index 5e5c3194de..be32740a70 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -1773,16 +1773,16 @@ static CURLcode multi_do(struct Curl_easy *data, bool *done) * stage DO state which (wrongly) was introduced to support FTP's second * connection. * - * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to - * DOING state there is more work to do! + * 'complete' can return DOMORE_INCOMPLETE, DOMORE_DONE or DOMORE_GOBACK + * (to DOING state when there is more work to do) */ -static CURLcode multi_do_more(struct Curl_easy *data, int *complete) +static CURLcode multi_do_more(struct Curl_easy *data, domore *complete) { CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; - *complete = 0; + *complete = DOMORE_INCOMPLETE; if(conn->scheme->run->do_more) result = conn->scheme->run->do_more(data, complete); @@ -2596,7 +2596,7 @@ static CURLMcode multistate_doing_more(struct Curl_easy *data, bool *stream_error, CURLcode *result) { - int control; + domore control; /* * When we are connected, DOING MORE and then go DID @@ -2605,10 +2605,10 @@ static CURLMcode multistate_doing_more(struct Curl_easy *data, *result = multi_do_more(data, &control); if(!(*result)) { - if(control) { - /* if positive, advance to DO_DONE - if negative, go back to DOING */ - multistate(data, control == 1 ? MSTATE_DID : MSTATE_DOING); + if(control != DOMORE_INCOMPLETE) { + /* if DONE, advance to DO_DONE + if GOBACK, go back to DOING */ + multistate(data, control == DOMORE_DONE ? MSTATE_DID : MSTATE_DOING); return CURLM_CALL_MULTI_PERFORM; } /* else diff --git a/lib/protocol.h b/lib/protocol.h index fc2c844db7..8ae2155ee6 100644 --- a/lib/protocol.h +++ b/lib/protocol.h @@ -105,6 +105,12 @@ typedef enum { FOLLOW_REDIR /* a full true redirect */ } followtype; +typedef enum { + DOMORE_GOBACK = -1, + DOMORE_INCOMPLETE = 0, + DOMORE_DONE = 1 +} domore; + /* * Specific protocol handler, an implementation of one or more URI schemes. */ @@ -120,9 +126,13 @@ struct Curl_protocol { /* If the curl_do() function is better made in two halves, this * curl_do_more() function will be called afterwards, if set. For example - * for doing the FTP stuff after the PASV/PORT command. + * for doing the FTP stuff after the PASV/PORT command. The second + * argument is an output parameter that MUST be set to one of the + * DOMORE_* values: DOMORE_INCOMPLETE if more do_more work remains, + * DOMORE_DONE when the second phase is complete, or DOMORE_GOBACK + * to return to the regular DO/DOING handling. */ - CURLcode (*do_more)(struct Curl_easy *, int *); + CURLcode (*do_more)(struct Curl_easy *, domore *); /* This function *MAY* be set to a protocol-dependent function that is run * after the connect() and everything is done, as a step in the connection.