From 15e1227ed4cbf3364c70f4aa8fb4141879777a6d Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Mon, 2 Apr 2012 23:24:00 +0100 Subject: [PATCH] pop3: Reworked the command sending and handling Reworked the command sending from two specific LIST and RETR command functions into a single command based function as well as the two associated response handlers into a generic command handler. --- lib/pop3.c | 119 +++++++++++++---------------------------------------- lib/pop3.h | 3 +- 2 files changed, 29 insertions(+), 93 deletions(-) diff --git a/lib/pop3.c b/lib/pop3.c index 44db3a474d..91b544a0a2 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -236,8 +236,7 @@ static void state(struct connectdata *conn, "USER", "PASS", "STARTTLS", - "LIST", - "RETR", + "COMMAND", "QUIT", /* LAST */ }; @@ -393,10 +392,10 @@ static CURLcode pop3_state_pass_resp(struct connectdata *conn, return result; } -/* for the list response */ -static CURLcode pop3_state_list_resp(struct connectdata *conn, - int pop3code, - pop3state instate) +/* for the command response */ +static CURLcode pop3_state_command_resp(struct connectdata *conn, + int pop3code, + pop3state instate) { CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; @@ -421,50 +420,6 @@ static CURLcode pop3_state_list_resp(struct connectdata *conn, the strip counter here so that these bytes won't be delivered. */ pop3c->strip = 2; - /* POP3 download */ - Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, pop3->bytecountp, - -1, NULL); /* no upload here */ - - if(pp->cache) { - /* The header "cache" contains a bunch of data that is actually list data - so send it as such */ - - if(!data->set.opt_no_body) { - result = Curl_pop3_write(conn, pp->cache, pp->cache_size); - if(result) - return result; - } - - /* Free the cache */ - Curl_safefree(pp->cache); - - /* Reset the cache size */ - pp->cache_size = 0; - } - - state(conn, POP3_STOP); - - return result; -} - -/* for the retr response */ -static CURLcode pop3_state_retr_resp(struct connectdata *conn, - int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct FTP *pop3 = data->state.proto.pop3; - struct pop3_conn *pop3c = &conn->proto.pop3c; - struct pingpong *pp = &pop3c->pp; - - (void)instate; /* no use for this yet */ - - if('O' != pop3code) { - state(conn, POP3_STOP); - return CURLE_RECV_ERROR; - } - /* POP3 download */ Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, pop3->bytecountp, -1, NULL); /* no upload here */ @@ -492,47 +447,40 @@ static CURLcode pop3_state_retr_resp(struct connectdata *conn, return result; } -/* start the DO phase for LIST */ -static CURLcode pop3_list(struct connectdata *conn) +/* start the DO phase for the command */ +static CURLcode pop3_command(struct connectdata *conn) { CURLcode result = CURLE_OK; struct pop3_conn *pop3c = &conn->proto.pop3c; + const char *command = NULL; - if(pop3c->mailbox[0] != '\0') { - /* Message specific LIST means no transfer */ - struct FTP *pop3 = conn->data->state.proto.pop3; - pop3->transfer = FTPTRANSFER_INFO; + /* Calculate the default command */ + if(pop3c->mailbox[0] == '\0' || conn->data->set.ftp_list_only) { + command = "LIST"; + if(pop3c->mailbox[0] != '\0') { + /* Message specific LIST so skip the BODY transfer */ + struct FTP *pop3 = conn->data->state.proto.pop3; + pop3->transfer = FTPTRANSFER_INFO; + } + } + else + command = "RETR"; + + /* Send the command */ + if(pop3c->mailbox[0] != '\0') result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s %s", (pop3c->custom && pop3c->custom[0] != '\0' ? - pop3c->custom : "LIST"), pop3c->mailbox); - } + pop3c->custom : command), pop3c->mailbox); else result = Curl_pp_sendf(&conn->proto.pop3c.pp, (pop3c->custom && pop3c->custom[0] != '\0' ? - pop3c->custom : "LIST")); + pop3c->custom : command)); if(result) return result; - state(conn, POP3_LIST); - - return result; -} - -/* start the DO phase for RETR */ -static CURLcode pop3_retr(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct pop3_conn *pop3c = &conn->proto.pop3c; - - result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s %s", - (pop3c->custom && pop3c->custom[0] != '\0' ? - pop3c->custom : "RETR"), pop3c->mailbox); - if(result) - return result; - - state(conn, POP3_RETR); + state(conn, POP3_COMMAND); return result; } @@ -573,12 +521,8 @@ static CURLcode pop3_statemach_act(struct connectdata *conn) result = pop3_state_starttls_resp(conn, pop3code, pop3c->state); break; - case POP3_LIST: - result = pop3_state_list_resp(conn, pop3code, pop3c->state); - break; - - case POP3_RETR: - result = pop3_state_retr_resp(conn, pop3code, pop3c->state); + case POP3_COMMAND: + result = pop3_state_command_resp(conn, pop3code, pop3c->state); break; case POP3_QUIT: @@ -762,7 +706,6 @@ CURLcode pop3_perform(struct connectdata *conn, { /* this is POP3 and no proxy */ CURLcode result = CURLE_OK; - struct pop3_conn *pop3c = &conn->proto.pop3c; DEBUGF(infof(conn->data, "DO phase starts\n")); @@ -775,13 +718,7 @@ CURLcode pop3_perform(struct connectdata *conn, *dophase_done = FALSE; /* not done yet */ /* start the first command in the DO phase */ - /* If mailbox is empty, then assume user wants listing for mail IDs, - * otherwise, attempt to retrieve the mail-id stored in mailbox - */ - if(strlen(pop3c->mailbox) && !conn->data->set.ftp_list_only) - result = pop3_retr(conn); - else - result = pop3_list(conn); + result = pop3_command(conn); if(result) return result; diff --git a/lib/pop3.h b/lib/pop3.h index 3071a6eb8a..e30c3b3b2a 100644 --- a/lib/pop3.h +++ b/lib/pop3.h @@ -32,8 +32,7 @@ typedef enum { POP3_USER, POP3_PASS, POP3_STARTTLS, - POP3_LIST, - POP3_RETR, + POP3_COMMAND, POP3_QUIT, POP3_LAST /* never used */ } pop3state;