From 215db086e09665ee7af9b646ad6c4d6e281001ac Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 8 Jan 2021 17:58:15 +0100 Subject: lib: pass in 'struct Curl_easy *' to most functions ... in most cases instead of 'struct connectdata *' but in some cases in addition to. - We mostly operate on transfers and not connections. - We need the transfer handle to log, store data and more. Everything in libcurl is driven by a transfer (the CURL * in the public API). - This work clarifies and separates the transfers from the connections better. - We should avoid "conn->data". Since individual connections can be used by many transfers when multiplexing, making sure that conn->data points to the current and correct transfer at all times is difficult and has been notoriously error-prone over the years. The goal is to ultimately remove the conn->data pointer for this reason. Closes #6425 --- lib/imap.c | 443 +++++++++++++++++++++++++++++++------------------------------ 1 file changed, 228 insertions(+), 215 deletions(-) (limited to 'lib/imap.c') diff --git a/lib/imap.c b/lib/imap.c index 75ab77dca..04ee4ef55 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -88,25 +88,31 @@ #include "memdebug.h" /* Local API functions */ -static CURLcode imap_regular_transfer(struct connectdata *conn, bool *done); -static CURLcode imap_do(struct connectdata *conn, bool *done); -static CURLcode imap_done(struct connectdata *conn, CURLcode status, +static CURLcode imap_regular_transfer(struct Curl_easy *data, bool *done); +static CURLcode imap_do(struct Curl_easy *data, bool *done); +static CURLcode imap_done(struct Curl_easy *data, CURLcode status, bool premature); -static CURLcode imap_connect(struct connectdata *conn, bool *done); -static CURLcode imap_disconnect(struct connectdata *conn, bool dead); -static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done); -static int imap_getsock(struct connectdata *conn, curl_socket_t *socks); -static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done); -static CURLcode imap_setup_connection(struct connectdata *conn); +static CURLcode imap_connect(struct Curl_easy *data, bool *done); +static CURLcode imap_disconnect(struct Curl_easy *data, + struct connectdata *conn, bool dead); +static CURLcode imap_multi_statemach(struct Curl_easy *data, bool *done); +static int imap_getsock(struct Curl_easy *data, struct connectdata *conn, + curl_socket_t *socks); +static CURLcode imap_doing(struct Curl_easy *data, bool *dophase_done); +static CURLcode imap_setup_connection(struct Curl_easy *data, + struct connectdata *conn); static char *imap_atom(const char *str, bool escape_only); -static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...); +static CURLcode imap_sendf(struct Curl_easy *data, + struct connectdata *conn, const char *fmt, ...); static CURLcode imap_parse_url_options(struct connectdata *conn); -static CURLcode imap_parse_url_path(struct connectdata *conn); -static CURLcode imap_parse_custom_request(struct connectdata *conn); -static CURLcode imap_perform_authenticate(struct connectdata *conn, +static CURLcode imap_parse_url_path(struct Curl_easy *data); +static CURLcode imap_parse_custom_request(struct Curl_easy *data); +static CURLcode imap_perform_authenticate(struct Curl_easy *data, + struct connectdata *conn, const char *mech, const char *initresp); -static CURLcode imap_continue_authenticate(struct connectdata *conn, +static CURLcode imap_continue_authenticate(struct Curl_easy *data, + struct connectdata *conn, const char *resp); static void imap_get_message(char *buffer, char **outptr); @@ -243,10 +249,10 @@ static bool imap_matchresp(const char *line, size_t len, const char *cmd) * Checks whether the given string is a valid tagged, untagged or continuation * response which can be processed by the response handler. */ -static bool imap_endofresp(struct connectdata *conn, char *line, size_t len, - int *resp) +static bool imap_endofresp(struct Curl_easy *data, struct connectdata *conn, + char *line, size_t len, int *resp) { - struct IMAP *imap = conn->data->req.p.imap; + struct IMAP *imap = data->req.p.imap; struct imap_conn *imapc = &conn->proto.imapc; const char *id = imapc->resptag; size_t id_len = strlen(id); @@ -328,7 +334,7 @@ static bool imap_endofresp(struct connectdata *conn, char *line, size_t len, break; default: - failf(conn->data, "Unexpected continuation response"); + failf(data, "Unexpected continuation response"); *resp = -1; break; } @@ -381,9 +387,9 @@ static void imap_get_message(char *buffer, char **outptr) * * This is the ONLY way to change IMAP state! */ -static void state(struct connectdata *conn, imapstate newstate) +static void state(struct Curl_easy *data, imapstate newstate) { - struct imap_conn *imapc = &conn->proto.imapc; + struct imap_conn *imapc = &data->conn->proto.imapc; #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) /* for debug purposes */ static const char * const names[]={ @@ -406,7 +412,7 @@ static void state(struct connectdata *conn, imapstate newstate) }; if(imapc->state != newstate) - infof(conn->data, "IMAP %p state change from %s to %s\n", + infof(data, "IMAP %p state change from %s to %s\n", (void *)imapc, names[imapc->state], names[newstate]); #endif @@ -420,7 +426,8 @@ static void state(struct connectdata *conn, imapstate newstate) * Sends the CAPABILITY command in order to obtain a list of server side * supported capabilities. */ -static CURLcode imap_perform_capability(struct connectdata *conn) +static CURLcode imap_perform_capability(struct Curl_easy *data, + struct connectdata *conn) { CURLcode result = CURLE_OK; struct imap_conn *imapc = &conn->proto.imapc; @@ -429,10 +436,10 @@ static CURLcode imap_perform_capability(struct connectdata *conn) imapc->tls_supported = FALSE; /* Clear the TLS capability */ /* Send the CAPABILITY command */ - result = imap_sendf(conn, "CAPABILITY"); + result = imap_sendf(data, conn, "CAPABILITY"); if(!result) - state(conn, IMAP_CAPABILITY); + state(data, IMAP_CAPABILITY); return result; } @@ -443,13 +450,14 @@ static CURLcode imap_perform_capability(struct connectdata *conn) * * Sends the STARTTLS command to start the upgrade to TLS. */ -static CURLcode imap_perform_starttls(struct connectdata *conn) +static CURLcode imap_perform_starttls(struct Curl_easy *data, + struct connectdata *conn) { /* Send the STARTTLS command */ - CURLcode result = imap_sendf(conn, "STARTTLS"); + CURLcode result = imap_sendf(data, conn, "STARTTLS"); if(!result) - state(conn, IMAP_STARTTLS); + state(data, IMAP_STARTTLS); return result; } @@ -460,7 +468,8 @@ static CURLcode imap_perform_starttls(struct connectdata *conn) * * Performs the upgrade to TLS. */ -static CURLcode imap_perform_upgrade_tls(struct connectdata *conn) +static CURLcode imap_perform_upgrade_tls(struct Curl_easy *data, + struct connectdata *conn) { /* Start the SSL connection */ struct imap_conn *imapc = &conn->proto.imapc; @@ -469,11 +478,11 @@ static CURLcode imap_perform_upgrade_tls(struct connectdata *conn) if(!result) { if(imapc->state != IMAP_UPGRADETLS) - state(conn, IMAP_UPGRADETLS); + state(data, IMAP_UPGRADETLS); if(imapc->ssldone) { imap_to_imaps(conn); - result = imap_perform_capability(conn); + result = imap_perform_capability(data, conn); } } @@ -486,7 +495,8 @@ static CURLcode imap_perform_upgrade_tls(struct connectdata *conn) * * Sends a clear text LOGIN command to authenticate with. */ -static CURLcode imap_perform_login(struct connectdata *conn) +static CURLcode imap_perform_login(struct Curl_easy *data, + struct connectdata *conn) { CURLcode result = CURLE_OK; char *user; @@ -495,7 +505,7 @@ static CURLcode imap_perform_login(struct connectdata *conn) /* Check we have a username and password to authenticate with and end the connect phase if we don't */ if(!conn->bits.user_passwd) { - state(conn, IMAP_STOP); + state(data, IMAP_STOP); return result; } @@ -505,14 +515,14 @@ static CURLcode imap_perform_login(struct connectdata *conn) passwd = imap_atom(conn->passwd, false); /* Send the LOGIN command */ - result = imap_sendf(conn, "LOGIN %s %s", user ? user : "", + result = imap_sendf(data, conn, "LOGIN %s %s", user ? user : "", passwd ? passwd : ""); free(user); free(passwd); if(!result) - state(conn, IMAP_LOGIN); + state(data, IMAP_LOGIN); return result; } @@ -524,19 +534,21 @@ static CURLcode imap_perform_login(struct connectdata *conn) * Sends an AUTHENTICATE command allowing the client to login with the given * SASL authentication mechanism. */ -static CURLcode imap_perform_authenticate(struct connectdata *conn, +static CURLcode imap_perform_authenticate(struct Curl_easy *data, + struct connectdata *conn, const char *mech, const char *initresp) { CURLcode result = CURLE_OK; + (void)data; if(initresp) { /* Send the AUTHENTICATE command with the initial response */ - result = imap_sendf(conn, "AUTHENTICATE %s %s", mech, initresp); + result = imap_sendf(data, conn, "AUTHENTICATE %s %s", mech, initresp); } else { /* Send the AUTHENTICATE command */ - result = imap_sendf(conn, "AUTHENTICATE %s", mech); + result = imap_sendf(data, conn, "AUTHENTICATE %s", mech); } return result; @@ -548,12 +560,13 @@ static CURLcode imap_perform_authenticate(struct connectdata *conn, * * Sends SASL continuation data or cancellation. */ -static CURLcode imap_continue_authenticate(struct connectdata *conn, +static CURLcode imap_continue_authenticate(struct Curl_easy *data, + struct connectdata *conn, const char *resp) { struct imap_conn *imapc = &conn->proto.imapc; - return Curl_pp_sendf(&imapc->pp, "%s", resp); + return Curl_pp_sendf(data, &imapc->pp, "%s", resp); } /*********************************************************************** @@ -564,7 +577,8 @@ static CURLcode imap_continue_authenticate(struct connectdata *conn, * authentication mechanism, falling back to clear text should a common * mechanism not be available between the client and server. */ -static CURLcode imap_perform_authentication(struct connectdata *conn) +static CURLcode imap_perform_authentication(struct Curl_easy *data, + struct connectdata *conn) { CURLcode result = CURLE_OK; struct imap_conn *imapc = &conn->proto.imapc; @@ -574,7 +588,7 @@ static CURLcode imap_perform_authentication(struct connectdata *conn) with and end the connect phase if we don't */ if(imapc->preauth || !Curl_sasl_can_authenticate(&imapc->sasl, conn)) { - state(conn, IMAP_STOP); + state(data, IMAP_STOP); return result; } @@ -583,13 +597,13 @@ static CURLcode imap_perform_authentication(struct connectdata *conn) if(!result) { if(progress == SASL_INPROGRESS) - state(conn, IMAP_AUTHENTICATE); + state(data, IMAP_AUTHENTICATE); else if(!imapc->login_disabled && (imapc->preftype & IMAP_TYPE_CLEARTEXT)) /* Perform clear text authentication */ - result = imap_perform_login(conn); + result = imap_perform_login(data, conn); else { /* Other mechanisms not supported */ - infof(conn->data, "No known authentication mechanisms supported!\n"); + infof(data, "No known authentication mechanisms supported!\n"); result = CURLE_LOGIN_DENIED; } } @@ -603,15 +617,15 @@ static CURLcode imap_perform_authentication(struct connectdata *conn) * * Sends a LIST command or an alternative custom request. */ -static CURLcode imap_perform_list(struct connectdata *conn) +static CURLcode imap_perform_list(struct Curl_easy *data) { CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; + struct connectdata *conn = data->conn; struct IMAP *imap = data->req.p.imap; if(imap->custom) /* Send the custom request */ - result = imap_sendf(conn, "%s%s", imap->custom, + result = imap_sendf(data, conn, "%s%s", imap->custom, imap->custom_params ? imap->custom_params : ""); else { /* Make sure the mailbox is in the correct atom format if necessary */ @@ -621,13 +635,13 @@ static CURLcode imap_perform_list(struct connectdata *conn) return CURLE_OUT_OF_MEMORY; /* Send the LIST command */ - result = imap_sendf(conn, "LIST \"%s\" *", mailbox); + result = imap_sendf(data, conn, "LIST \"%s\" *", mailbox); free(mailbox); } if(!result) - state(conn, IMAP_LIST); + state(data, IMAP_LIST); return result; } @@ -638,10 +652,10 @@ static CURLcode imap_perform_list(struct connectdata *conn) * * Sends a SELECT command to ask the server to change the selected mailbox. */ -static CURLcode imap_perform_select(struct connectdata *conn) +static CURLcode imap_perform_select(struct Curl_easy *data) { CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; + struct connectdata *conn = data->conn; struct IMAP *imap = data->req.p.imap; struct imap_conn *imapc = &conn->proto.imapc; char *mailbox; @@ -652,7 +666,7 @@ static CURLcode imap_perform_select(struct connectdata *conn) /* Check we have a mailbox */ if(!imap->mailbox) { - failf(conn->data, "Cannot SELECT without a mailbox."); + failf(data, "Cannot SELECT without a mailbox."); return CURLE_URL_MALFORMAT; } @@ -662,12 +676,12 @@ static CURLcode imap_perform_select(struct connectdata *conn) return CURLE_OUT_OF_MEMORY; /* Send the SELECT command */ - result = imap_sendf(conn, "SELECT %s", mailbox); + result = imap_sendf(data, conn, "SELECT %s", mailbox); free(mailbox); if(!result) - state(conn, IMAP_SELECT); + state(data, IMAP_SELECT); return result; } @@ -678,43 +692,39 @@ static CURLcode imap_perform_select(struct connectdata *conn) * * Sends a FETCH command to initiate the download of a message. */ -static CURLcode imap_perform_fetch(struct connectdata *conn) +static CURLcode imap_perform_fetch(struct Curl_easy *data, + struct connectdata *conn) { CURLcode result = CURLE_OK; - struct IMAP *imap = conn->data->req.p.imap; + struct IMAP *imap = data->req.p.imap; /* Check we have a UID */ if(imap->uid) { /* Send the FETCH command */ if(imap->partial) - result = imap_sendf(conn, "UID FETCH %s BODY[%s]<%s>", - imap->uid, - imap->section ? imap->section : "", - imap->partial); + result = imap_sendf(data, conn, "UID FETCH %s BODY[%s]<%s>", + imap->uid, imap->section ? imap->section : "", + imap->partial); else - result = imap_sendf(conn, "UID FETCH %s BODY[%s]", - imap->uid, - imap->section ? imap->section : ""); + result = imap_sendf(data, conn, "UID FETCH %s BODY[%s]", + imap->uid, imap->section ? imap->section : ""); } else if(imap->mindex) { - /* Send the FETCH command */ if(imap->partial) - result = imap_sendf(conn, "FETCH %s BODY[%s]<%s>", - imap->mindex, - imap->section ? imap->section : "", - imap->partial); + result = imap_sendf(data, conn, "FETCH %s BODY[%s]<%s>", + imap->mindex, imap->section ? imap->section : "", + imap->partial); else - result = imap_sendf(conn, "FETCH %s BODY[%s]", - imap->mindex, - imap->section ? imap->section : ""); + result = imap_sendf(data, conn, "FETCH %s BODY[%s]", + imap->mindex, imap->section ? imap->section : ""); } else { - failf(conn->data, "Cannot FETCH without a UID."); - return CURLE_URL_MALFORMAT; + failf(data, "Cannot FETCH without a UID."); + return CURLE_URL_MALFORMAT; } if(!result) - state(conn, IMAP_FETCH); + state(data, IMAP_FETCH); return result; } @@ -725,10 +735,10 @@ static CURLcode imap_perform_fetch(struct connectdata *conn) * * Sends an APPEND command to initiate the upload of a message. */ -static CURLcode imap_perform_append(struct connectdata *conn) +static CURLcode imap_perform_append(struct Curl_easy *data) { CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; + struct connectdata *conn = data->conn; struct IMAP *imap = data->req.p.imap; char *mailbox; @@ -749,7 +759,7 @@ static CURLcode imap_perform_append(struct connectdata *conn) NULL, MIMESTRATEGY_MAIL); if(!result) - if(!Curl_checkheaders(conn, "Mime-Version")) + if(!Curl_checkheaders(data, "Mime-Version")) result = Curl_mime_add_header(&data->set.mimepost.curlheaders, "Mime-Version: 1.0"); @@ -779,13 +789,14 @@ static CURLcode imap_perform_append(struct connectdata *conn) return CURLE_OUT_OF_MEMORY; /* Send the APPEND command */ - result = imap_sendf(conn, "APPEND %s (\\Seen) {%" CURL_FORMAT_CURL_OFF_T "}", + result = imap_sendf(data, conn, + "APPEND %s (\\Seen) {%" CURL_FORMAT_CURL_OFF_T "}", mailbox, data->state.infilesize); free(mailbox); if(!result) - state(conn, IMAP_APPEND); + state(data, IMAP_APPEND); return result; } @@ -796,22 +807,23 @@ static CURLcode imap_perform_append(struct connectdata *conn) * * Sends a SEARCH command. */ -static CURLcode imap_perform_search(struct connectdata *conn) +static CURLcode imap_perform_search(struct Curl_easy *data, + struct connectdata *conn) { CURLcode result = CURLE_OK; - struct IMAP *imap = conn->data->req.p.imap; + struct IMAP *imap = data->req.p.imap; /* Check we have a query string */ if(!imap->query) { - failf(conn->data, "Cannot SEARCH without a query string."); + failf(data, "Cannot SEARCH without a query string."); return CURLE_URL_MALFORMAT; } /* Send the SEARCH command */ - result = imap_sendf(conn, "SEARCH %s", imap->query); + result = imap_sendf(data, conn, "SEARCH %s", imap->query); if(!result) - state(conn, IMAP_SEARCH); + state(data, IMAP_SEARCH); return result; } @@ -822,23 +834,24 @@ static CURLcode imap_perform_search(struct connectdata *conn) * * Performs the logout action prior to sclose() being called. */ -static CURLcode imap_perform_logout(struct connectdata *conn) +static CURLcode imap_perform_logout(struct Curl_easy *data, + struct connectdata *conn) { /* Send the LOGOUT command */ - CURLcode result = imap_sendf(conn, "LOGOUT"); + CURLcode result = imap_sendf(data, conn, "LOGOUT"); if(!result) - state(conn, IMAP_LOGOUT); + state(data, IMAP_LOGOUT); return result; } /* For the initial server greeting */ -static CURLcode imap_state_servergreet_resp(struct connectdata *conn, +static CURLcode imap_state_servergreet_resp(struct Curl_easy *data, int imapcode, imapstate instate) { - struct Curl_easy *data = conn->data; + struct connectdata *conn = data->conn; (void)instate; /* no use for this yet */ if(imapcode == IMAP_RESP_PREAUTH) { @@ -852,16 +865,16 @@ static CURLcode imap_state_servergreet_resp(struct connectdata *conn, return CURLE_WEIRD_SERVER_REPLY; } - return imap_perform_capability(conn); + return imap_perform_capability(data, conn); } /* For CAPABILITY responses */ -static CURLcode imap_state_capability_resp(struct connectdata *conn, +static CURLcode imap_state_capability_resp(struct Curl_easy *data, int imapcode, imapstate instate) { CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; + struct connectdata *conn = data->conn; struct imap_conn *imapc = &conn->proto.imapc; const char *line = data->state.buffer; @@ -924,31 +937,31 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn, /* We don't have a SSL/TLS connection yet, but SSL is requested */ if(imapc->tls_supported) /* Switch to TLS connection now */ - result = imap_perform_starttls(conn); + result = imap_perform_starttls(data, conn); else if(data->set.use_ssl == CURLUSESSL_TRY) /* Fallback and carry on with authentication */ - result = imap_perform_authentication(conn); + result = imap_perform_authentication(data, conn); else { failf(data, "STARTTLS not supported."); result = CURLE_USE_SSL_FAILED; } } else - result = imap_perform_authentication(conn); + result = imap_perform_authentication(data, conn); } else - result = imap_perform_authentication(conn); + result = imap_perform_authentication(data, conn); return result; } /* For STARTTLS responses */ -static CURLcode imap_state_starttls_resp(struct connectdata *conn, +static CURLcode imap_state_starttls_resp(struct Curl_easy *data, int imapcode, imapstate instate) { CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; + struct connectdata *conn = data->conn; (void)instate; /* no use for this yet */ @@ -958,21 +971,21 @@ static CURLcode imap_state_starttls_resp(struct connectdata *conn, result = CURLE_USE_SSL_FAILED; } else - result = imap_perform_authentication(conn); + result = imap_perform_authentication(data, conn); } else - result = imap_perform_upgrade_tls(conn); + result = imap_perform_upgrade_tls(data, conn); return result; } /* For SASL authentication responses */ -static CURLcode imap_state_auth_resp(struct connectdata *conn, +static CURLcode imap_state_auth_resp(struct Curl_easy *data, + struct connectdata *conn, int imapcode, imapstate instate) { CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; struct imap_conn *imapc = &conn->proto.imapc; saslprogress progress; @@ -982,12 +995,12 @@ static CURLcode imap_state_auth_resp(struct connectdata *conn, if(!result) switch(progress) { case SASL_DONE: - state(conn, IMAP_STOP); /* Authenticated */ + state(data, IMAP_STOP); /* Authenticated */ break; case SASL_IDLE: /* No mechanism left after cancellation */ if((!imapc->login_disabled) && (imapc->preftype & IMAP_TYPE_CLEARTEXT)) /* Perform clear text authentication */ - result = imap_perform_login(conn); + result = imap_perform_login(data, conn); else { failf(data, "Authentication cancelled"); result = CURLE_LOGIN_DENIED; @@ -1001,13 +1014,11 @@ static CURLcode imap_state_auth_resp(struct connectdata *conn, } /* For LOGIN responses */ -static CURLcode imap_state_login_resp(struct connectdata *conn, +static CURLcode imap_state_login_resp(struct Curl_easy *data, int imapcode, imapstate instate) { CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; - (void)instate; /* no use for this yet */ if(imapcode != IMAP_RESP_OK) { @@ -1016,18 +1027,18 @@ static CURLcode imap_state_login_resp(struct connectdata *conn, } else /* End of connect phase */ - state(conn, IMAP_STOP); + state(data, IMAP_STOP); return result; } /* For LIST and SEARCH responses */ -static CURLcode imap_state_listsearch_resp(struct connectdata *conn, +static CURLcode imap_state_listsearch_resp(struct Curl_easy *data, int imapcode, imapstate instate) { CURLcode result = CURLE_OK; - char *line = conn->data->state.buffer; + char *line = data->state.buffer; size_t len = strlen(line); (void)instate; /* No use for this yet */ @@ -1035,25 +1046,25 @@ static CURLcode imap_state_listsearch_resp(struct connectdata *conn, if(imapcode == '*') { /* Temporarily add the LF character back and send as body to the client */ line[len] = '\n'; - result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1); + result = Curl_client_write(data, CLIENTWRITE_BODY, line, len + 1); line[len] = '\0'; } else if(imapcode != IMAP_RESP_OK) result = CURLE_QUOTE_ERROR; else /* End of DO phase */ - state(conn, IMAP_STOP); + state(data, IMAP_STOP); return result; } /* For SELECT responses */ -static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode, +static CURLcode imap_state_select_resp(struct Curl_easy *data, int imapcode, imapstate instate) { CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; - struct IMAP *imap = conn->data->req.p.imap; + struct connectdata *conn = data->conn; + struct IMAP *imap = data->req.p.imap; struct imap_conn *imapc = &conn->proto.imapc; const char *line = data->state.buffer; @@ -1071,7 +1082,7 @@ static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode, /* Check if the UIDVALIDITY has been specified and matches */ if(imap->uidvalidity && imapc->mailbox_uidvalidity && !strcasecompare(imap->uidvalidity, imapc->mailbox_uidvalidity)) { - failf(conn->data, "Mailbox UIDVALIDITY has changed"); + failf(data, "Mailbox UIDVALIDITY has changed"); result = CURLE_REMOTE_FILE_NOT_FOUND; } else { @@ -1079,11 +1090,11 @@ static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode, imapc->mailbox = strdup(imap->mailbox); if(imap->custom) - result = imap_perform_list(conn); + result = imap_perform_list(data); else if(imap->query) - result = imap_perform_search(conn); + result = imap_perform_search(data, conn); else - result = imap_perform_fetch(conn); + result = imap_perform_fetch(data, conn); } } else { @@ -1095,11 +1106,11 @@ static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode, } /* For the (first line of the) FETCH responses */ -static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode, +static CURLcode imap_state_fetch_resp(struct Curl_easy *data, + struct connectdata *conn, int imapcode, imapstate instate) { CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; struct imap_conn *imapc = &conn->proto.imapc; struct pingpong *pp = &imapc->pp; const char *ptr = data->state.buffer; @@ -1110,7 +1121,7 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode, if(imapcode != '*') { Curl_pgrsSetDownloadSize(data, -1); - state(conn, IMAP_STOP); + state(data, IMAP_STOP); return CURLE_REMOTE_FILE_NOT_FOUND; } @@ -1145,10 +1156,10 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode, if(!chunk) { /* no size, we're done with the data */ - state(conn, IMAP_STOP); + state(data, IMAP_STOP); return CURLE_OK; } - result = Curl_client_write(conn, CLIENTWRITE_BODY, pp->cache, chunk); + result = Curl_client_write(data, CLIENTWRITE_BODY, pp->cache, chunk); if(result) return result; @@ -1186,18 +1197,18 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode, } else { /* We don't know how to parse this line */ - failf(pp->conn->data, "Failed to parse FETCH response."); + failf(data, "Failed to parse FETCH response."); result = CURLE_WEIRD_SERVER_REPLY; } /* End of DO phase */ - state(conn, IMAP_STOP); + state(data, IMAP_STOP); return result; } /* For final FETCH responses performed after the download */ -static CURLcode imap_state_fetch_final_resp(struct connectdata *conn, +static CURLcode imap_state_fetch_final_resp(struct Curl_easy *data, int imapcode, imapstate instate) { @@ -1209,18 +1220,16 @@ static CURLcode imap_state_fetch_final_resp(struct connectdata *conn, result = CURLE_WEIRD_SERVER_REPLY; else /* End of DONE phase */ - state(conn, IMAP_STOP); + state(data, IMAP_STOP); return result; } /* For APPEND responses */ -static CURLcode imap_state_append_resp(struct connectdata *conn, int imapcode, +static CURLcode imap_state_append_resp(struct Curl_easy *data, int imapcode, imapstate instate) { CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; - (void)instate; /* No use for this yet */ if(imapcode != '+') { @@ -1234,14 +1243,14 @@ static CURLcode imap_state_append_resp(struct connectdata *conn, int imapcode, Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); /* End of DO phase */ - state(conn, IMAP_STOP); + state(data, IMAP_STOP); } return result; } /* For final APPEND responses performed after the upload */ -static CURLcode imap_state_append_final_resp(struct connectdata *conn, +static CURLcode imap_state_append_final_resp(struct Curl_easy *data, int imapcode, imapstate instate) { @@ -1253,12 +1262,13 @@ static CURLcode imap_state_append_final_resp(struct connectdata *conn, result = CURLE_UPLOAD_FAILED; else /* End of DONE phase */ - state(conn, IMAP_STOP); + state(data, IMAP_STOP); return result; } -static CURLcode imap_statemach_act(struct connectdata *conn) +static CURLcode imap_statemachine(struct Curl_easy *data, + struct connectdata *conn) { CURLcode result = CURLE_OK; curl_socket_t sock = conn->sock[FIRSTSOCKET]; @@ -1266,10 +1276,11 @@ static CURLcode imap_statemach_act(struct connectdata *conn) struct imap_conn *imapc = &conn->proto.imapc; struct pingpong *pp = &imapc->pp; size_t nread = 0; + (void)data; /* Busy upgrading the connection; right now all I/O is SSL/TLS, not IMAP */ if(imapc->state == IMAP_UPGRADETLS) - return imap_perform_upgrade_tls(conn); + return imap_perform_upgrade_tls(data, conn); /* Flush any data that needs to be sent */ if(pp->sendleft) @@ -1277,7 +1288,7 @@ static CURLcode imap_statemach_act(struct connectdata *conn) do { /* Read the response from the server */ - result = Curl_pp_readresp(sock, pp, &imapcode, &nread); + result = Curl_pp_readresp(data, sock, pp, &imapcode, &nread); if(result) return result; @@ -1291,55 +1302,55 @@ static CURLcode imap_statemach_act(struct connectdata *conn) /* We have now received a full IMAP server response */ switch(imapc->state) { case IMAP_SERVERGREET: - result = imap_state_servergreet_resp(conn, imapcode, imapc->state); + result = imap_state_servergreet_resp(data, imapcode, imapc->state); break; case IMAP_CAPABILITY: - result = imap_state_capability_resp(conn, imapcode, imapc->state); + result = imap_state_capability_resp(data, imapcode, imapc->state); break; case IMAP_STARTTLS: - result = imap_state_starttls_resp(conn, imapcode, imapc->state); + result = imap_state_starttls_resp(data, imapcode, imapc->state); break; case IMAP_AUTHENTICATE: - result = imap_state_auth_resp(conn, imapcode, imapc->state); + result = imap_state_auth_resp(data, conn, imapcode, imapc->state); break; case IMAP_LOGIN: - result = imap_state_login_resp(conn, imapcode, imapc->state); + result = imap_state_login_resp(data, imapcode, imapc->state); break; case IMAP_LIST: case IMAP_SEARCH: - result = imap_state_listsearch_resp(conn, imapcode, imapc->state); + result = imap_state_listsearch_resp(data, imapcode, imapc->state); break; case IMAP_SELECT: - result = imap_state_select_resp(conn, imapcode, imapc->state); + result = imap_state_select_resp(data, imapcode, imapc->state); break; case IMAP_FETCH: - result = imap_state_fetch_resp(conn, imapcode, imapc->state); + result = imap_state_fetch_resp(data, conn, imapcode, imapc->state); break; case IMAP_FETCH_FINAL: - result = imap_state_fetch_final_resp(conn, imapcode, imapc->state); + result = imap_state_fetch_final_resp(data, imapcode, imapc->state); break; case IMAP_APPEND: - result = imap_state_append_resp(conn, imapcode, imapc->state); + result = imap_state_append_resp(data, imapcode, imapc->state); break; case IMAP_APPEND_FINAL: - result = imap_state_append_final_resp(conn, imapcode, imapc->state); + result = imap_state_append_final_resp(data, imapcode, imapc->state); break; case IMAP_LOGOUT: /* fallthrough, just stop! */ default: /* internal error */ - state(conn, IMAP_STOP); + state(data, IMAP_STOP); break; } } while(!result && imapc->state != IMAP_STOP && Curl_pp_moredata(pp)); @@ -1348,9 +1359,10 @@ static CURLcode imap_statemach_act(struct connectdata *conn) } /* Called repeatedly until done from multi.c */ -static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done) +static CURLcode imap_multi_statemach(struct Curl_easy *data, bool *done) { CURLcode result = CURLE_OK; + struct connectdata *conn = data->conn; struct imap_conn *imapc = &conn->proto.imapc; if((conn->handler->flags & PROTOPT_SSL) && !imapc->ssldone) { @@ -1359,30 +1371,30 @@ static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done) return result; } - result = Curl_pp_statemach(&imapc->pp, FALSE, FALSE); + result = Curl_pp_statemach(data, &imapc->pp, FALSE, FALSE); *done = (imapc->state == IMAP_STOP) ? TRUE : FALSE; return result; } -static CURLcode imap_block_statemach(struct connectdata *conn, +static CURLcode imap_block_statemach(struct Curl_easy *data, + struct connectdata *conn, bool disconnecting) { CURLcode result = CURLE_OK; struct imap_conn *imapc = &conn->proto.imapc; while(imapc->state != IMAP_STOP && !result) - result = Curl_pp_statemach(&imapc->pp, TRUE, disconnecting); + result = Curl_pp_statemach(data, &imapc->pp, TRUE, disconnecting); return result; } /* Allocate and initialize the struct IMAP for the current Curl_easy if required */ -static CURLcode imap_init(struct connectdata *conn) +static CURLcode imap_init(struct Curl_easy *data) { CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; struct IMAP *imap; imap = data->req.p.imap = calloc(sizeof(struct IMAP), 1); @@ -1393,8 +1405,11 @@ static CURLcode imap_init(struct connectdata *conn) } /* For the IMAP "protocol connect" and "doing" phases only */ -static int imap_getsock(struct connectdata *conn, curl_socket_t *socks) +static int imap_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks) { + (void)data; return Curl_pp_getsock(&conn->proto.imapc.pp, socks); } @@ -1408,9 +1423,10 @@ static int imap_getsock(struct connectdata *conn, curl_socket_t *socks) * The variable 'done' points to will be TRUE if the protocol-layer connect * phase is done when this function returns, or FALSE if not. */ -static CURLcode imap_connect(struct connectdata *conn, bool *done) +static CURLcode imap_connect(struct Curl_easy *data, bool *done) { CURLcode result = CURLE_OK; + struct connectdata *conn = data->conn; struct imap_conn *imapc = &conn->proto.imapc; struct pingpong *pp = &imapc->pp; @@ -1419,11 +1435,7 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done) /* We always support persistent connections in IMAP */ connkeep(conn, "IMAP default"); - /* Set the default response time-out */ - pp->response_time = RESP_TIMEOUT; - pp->statemach_act = imap_statemach_act; - pp->endofresp = imap_endofresp; - pp->conn = conn; + PINGPONG_SETUP(pp, imap_statemachine, imap_endofresp); /* Set the default preferred authentication type and mechanism */ imapc->preftype = IMAP_TYPE_ANY; @@ -1432,7 +1444,7 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done) Curl_dyn_init(&imapc->dyn, DYN_IMAP_CMD); /* Initialise the pingpong layer */ Curl_pp_setup(pp); - Curl_pp_init(pp); + Curl_pp_init(data, pp); /* Parse the URL options */ result = imap_parse_url_options(conn); @@ -1440,12 +1452,12 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done) return result; /* Start off waiting for the server greeting response */ - state(conn, IMAP_SERVERGREET); + state(data, IMAP_SERVERGREET); /* Start off with an response id of '*' */ strcpy(imapc->resptag, "*"); - result = imap_multi_statemach(conn, done); + result = imap_multi_statemach(data, done); return result; } @@ -1459,11 +1471,11 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done) * * Input argument is already checked for validity. */ -static CURLcode imap_done(struct connectdata *conn, CURLcode status, +static CURLcode imap_done(struct Curl_easy *data, CURLcode status, bool premature) { CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; + struct connectdata *conn = data->conn; struct IMAP *imap = data->req.p.imap; (void)premature; @@ -1481,17 +1493,17 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status, /* Handle responses after FETCH or APPEND transfer has finished */ if(!data->set.upload && data->set.mimepost.kind == MIMEKIND_NONE) - state(conn, IMAP_FETCH_FINAL); + state(data, IMAP_FETCH_FINAL); else { /* End the APPEND command first by sending an empty line */ - result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", ""); + result = Curl_pp_sendf(data, &conn->proto.imapc.pp, "%s", ""); if(!result) - state(conn, IMAP_APPEND_FINAL); + state(data, IMAP_APPEND_FINAL); } /* Run the state-machine */ if(!result) - result = imap_block_statemach(conn, FALSE); + result = imap_block_statemach(data, conn, FALSE); } /* Cleanup our per-request based variables */ @@ -1518,19 +1530,19 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status, * This is the actual DO function for IMAP. Fetch or append a message, or do * other things according to the options previously setup. */ -static CURLcode imap_perform(struct connectdata *conn, bool *connected, +static CURLcode imap_perform(struct Curl_easy *data, bool *connected, bool *dophase_done) { /* This is IMAP and no proxy */ CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; + struct connectdata *conn = data->conn; struct IMAP *imap = data->req.p.imap; struct imap_conn *imapc = &conn->proto.imapc; bool selected = FALSE; - DEBUGF(infof(conn->data, "DO phase starts\n")); + DEBUGF(infof(data, "DO phase starts\n")); - if(conn->data->set.opt_no_body) { + if(data->set.opt_no_body) { /* Requested no body means no transfer */ imap->transfer = FTPTRANSFER_INFO; } @@ -1546,36 +1558,36 @@ static CURLcode imap_perform(struct connectdata *conn, bool *connected, selected = TRUE; /* Start the first command in the DO phase */ - if(conn->data->set.upload || data->set.mimepost.kind != MIMEKIND_NONE) + if(data->set.upload || data->set.mimepost.kind != MIMEKIND_NONE) /* APPEND can be executed directly */ - result = imap_perform_append(conn); + result = imap_perform_append(data); else if(imap->custom && (selected || !imap->mailbox)) /* Custom command using the same mailbox or no mailbox */ - result = imap_perform_list(conn); + result = imap_perform_list(data); else if(!imap->custom && selected && (imap->uid || imap->mindex)) /* FETCH from the same mailbox */ - result = imap_perform_fetch(conn); + result = imap_perform_fetch(data, conn); else if(!imap->custom && selected && imap->query) /* SEARCH the current mailbox */ - result = imap_perform_search(conn); + result = imap_perform_search(data, conn); else if(imap->mailbox && !selected && (imap->custom || imap->uid || imap->mindex || imap->query)) /* SELECT the mailbox */ - result = imap_perform_select(conn); + result = imap_perform_select(data); else /* LIST */ - result = imap_perform_list(conn); + result = imap_perform_list(data); if(result) return result; /* Run the state-machine */ - result = imap_multi_statemach(conn, dophase_done); + result = imap_multi_statemach(data, dophase_done); *connected = conn->bits.tcpconnect[FIRSTSOCKET]; if(*dophase_done) - DEBUGF(infof(conn->data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete\n")); return result; } @@ -1589,23 +1601,22 @@ static CURLcode imap_perform(struct connectdata *conn, bool *connected, * * The input argument is already checked for validity. */ -static CURLcode imap_do(struct connectdata *conn, bool *done) +static CURLcode imap_do(struct Curl_easy *data, bool *done) { CURLcode result = CURLE_OK; - *done = FALSE; /* default to false */ /* Parse the URL path */ - result = imap_parse_url_path(conn); + result = imap_parse_url_path(data); if(result) return result; /* Parse the custom request */ - result = imap_parse_custom_request(conn); + result = imap_parse_custom_request(data); if(result) return result; - result = imap_regular_transfer(conn, done); + result = imap_regular_transfer(data, done); return result; } @@ -1617,9 +1628,11 @@ static CURLcode imap_do(struct connectdata *conn, bool *done) * Disconnect from an IMAP server. Cleanup protocol-specific per-connection * resources. BLOCKING. */ -static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection) +static CURLcode imap_disconnect(struct Curl_easy *data, + struct connectdata *conn, bool dead_connection) { struct imap_conn *imapc = &conn->proto.imapc; + (void)data; /* We cannot send quit unconditionally. If this connection is stale or bad in any way, sending quit and waiting around here will make the @@ -1627,9 +1640,10 @@ static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection) /* The IMAP session may or may not have been allocated/setup at this point! */ - if(!dead_connection && imapc->pp.conn && imapc->pp.conn->bits.protoconnstart) - if(!imap_perform_logout(conn)) - (void)imap_block_statemach(conn, TRUE); /* ignore errors on LOGOUT */ + if(!dead_connection && conn->bits.protoconnstart) { + if(!imap_perform_logout(data, conn)) + (void)imap_block_statemach(data, conn, TRUE); /* ignore errors */ + } /* Disconnect from the server */ Curl_pp_disconnect(&imapc->pp); @@ -1646,30 +1660,30 @@ static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection) } /* Call this when the DO phase has completed */ -static CURLcode imap_dophase_done(struct connectdata *conn, bool connected) +static CURLcode imap_dophase_done(struct Curl_easy *data, bool connected) { - struct IMAP *imap = conn->data->req.p.imap; + struct IMAP *imap = data->req.p.imap; (void)connected; if(imap->transfer != FTPTRANSFER_BODY) /* no data to transfer */ - Curl_setup_transfer(conn->data, -1, -1, FALSE, -1); + Curl_setup_transfer(data, -1, -1, FALSE, -1); return CURLE_OK; } /* Called from multi.c while DOing */ -static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done) +static CURLcode imap_doing(struct Curl_easy *data, bool *dophase_done) { - CURLcode result = imap_multi_statemach(conn, dophase_done); + CURLcode result = imap_multi_statemach(data, dophase_done); if(result) - DEBUGF(infof(conn->data, "DO phase failed\n")); + DEBUGF(infof(data, "DO phase failed\n")); else if(*dophase_done) { - result = imap_dophase_done(conn, FALSE /* not connected */); + result = imap_dophase_done(data, FALSE /* not connected */); - DEBUGF(infof(conn->data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete\n")); } return result; @@ -1684,12 +1698,11 @@ static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done) * Performs all commands done before a regular transfer between a local and a * remote host. */ -static CURLcode imap_regular_transfer(struct connectdata *conn, +static CURLcode imap_regular_transfer(struct Curl_easy *data, bool *dophase_done) { CURLcode result = CURLE_OK; bool connected = FALSE; - struct Curl_easy *data = conn->data; /* Make sure size is unknown at this point */ data->req.size = -1; @@ -1701,19 +1714,20 @@ static CURLcode imap_regular_transfer(struct connectdata *conn, Curl_pgrsSetDownloadSize(data, -1); /* Carry out the perform */ - result = imap_perform(conn, &connected, dophase_done); + result = imap_perform(data, &connected, dophase_done); /* Perform post DO phase operations if necessary */ if(!result && *dophase_done) - result = imap_dophase_done(conn, connected); + result = imap_dophase_done(data, connected); return result; } -static CURLcode imap_setup_connection(struct connectdata *conn) +static CURLcode imap_setup_connection(struct Curl_easy *data, + struct connectdata *conn) { /* Initialise the IMAP layer */ - CURLcode result = imap_init(conn); + CURLcode result = imap_init(data); if(result) return result; @@ -1731,7 +1745,8 @@ static CURLcode imap_setup_connection(struct connectdata *conn) * * Designed to never block. */ -static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...) +static CURLcode imap_sendf(struct Curl_easy *data, + struct connectdata *conn, const char *fmt, ...) { CURLcode result = CURLE_OK; struct imap_conn *imapc = &conn->proto.imapc; @@ -1751,7 +1766,7 @@ static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...) if(!result) { va_list ap; va_start(ap, fmt); - result = Curl_pp_vsendf(&imapc->pp, Curl_dyn_ptr(&imapc->dyn), ap); + result = Curl_pp_vsendf(data, &imapc->pp, Curl_dyn_ptr(&imapc->dyn), ap); va_end(ap); } return result; @@ -1940,11 +1955,10 @@ static CURLcode imap_parse_url_options(struct connectdata *conn) * Parse the URL path into separate path components. * */ -static CURLcode imap_parse_url_path(struct connectdata *conn) +static CURLcode imap_parse_url_path(struct Curl_easy *data) { /* The imap struct is already initialised in imap_connect() */ CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; struct IMAP *imap = data->req.p.imap; const char *begin = &data->state.up.path[1]; /* skip leading slash */ const char *ptr = begin; @@ -2000,7 +2014,7 @@ static CURLcode imap_parse_url_path(struct connectdata *conn) return result; } - DEBUGF(infof(conn->data, "IMAP URL parameter '%s' = '%s'\n", name, value)); + DEBUGF(infof(data, "IMAP URL parameter '%s' = '%s'\n", name, value)); /* Process the known hierarchical parameters (UIDVALIDITY, UID, SECTION and PARTIAL) stripping of the trailing slash character if it is present. @@ -2073,10 +2087,9 @@ static CURLcode imap_parse_url_path(struct connectdata *conn) * * Parse the custom request. */ -static CURLcode imap_parse_custom_request(struct connectdata *conn) +static CURLcode imap_parse_custom_request(struct Curl_easy *data) { CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; struct IMAP *imap = data->req.p.imap; const char *custom = data->set.str[STRING_CUSTOMREQUEST]; -- cgit v1.2.1