* 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);
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
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);
}
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 */
/* 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) {
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);
* 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 */
}
result = ftp_statemach(data, ftpc, &complete);
- *completep = (int)complete;
+ if(complete)
+ *more = DOMORE_DONE;
}
return result;
}
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);
}
bool connected)
{
if(connected) {
- int completed;
+ domore completed;
CURLcode result = ftp_do_more(data, &completed);
if(result) {
* 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);
bool *stream_error,
CURLcode *result)
{
- int control;
+ domore control;
/*
* When we are connected, DOING MORE and then go DID
*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
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.
*/
/* 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.