mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
pop3: Get message listing if no mailbox in URL
If you pass a URL to pop3 that does not contain a message ID as part of the URL, it will currently ask for 'INBOX' which just causes the pop3 server to return an error. The change makes libcurl treat en empty message ID as a request for LIST (list of pop3 message IDs). User's code could then parse this and download individual messages as desired.
This commit is contained in:
parent
302507d5dc
commit
69ccc9f861
75
lib/pop3.c
75
lib/pop3.c
@ -232,6 +232,7 @@ static void state(struct connectdata *conn,
|
||||
"USER",
|
||||
"PASS",
|
||||
"STARTTLS",
|
||||
"LIST",
|
||||
"RETR",
|
||||
"QUIT",
|
||||
/* LAST */
|
||||
@ -382,7 +383,49 @@ static CURLcode pop3_state_retr_resp(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* start the DO phase */
|
||||
|
||||
/* for the list response */
|
||||
static CURLcode pop3_state_list_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 */
|
||||
result=Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE,
|
||||
pop3->bytecountp,
|
||||
-1, NULL); /* no upload here */
|
||||
|
||||
if(pp->cache) {
|
||||
/* cache holds the email ID listing */
|
||||
|
||||
/* we may get the EOB already here! */
|
||||
result = Curl_pop3_write(conn, pp->cache, pp->cache_size);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* cache is drained */
|
||||
free(pp->cache);
|
||||
pp->cache = NULL;
|
||||
pp->cache_size = 0;
|
||||
}
|
||||
|
||||
state(conn, POP3_STOP);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* start the DO phase for RETR */
|
||||
static CURLcode pop3_retr(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -396,6 +439,20 @@ static CURLcode pop3_retr(struct connectdata *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* start the DO phase for LIST */
|
||||
static CURLcode pop3_list(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
|
||||
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "LIST %s", pop3c->mailbox);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
state(conn, POP3_LIST);
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode pop3_statemach_act(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result;
|
||||
@ -451,6 +508,10 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
|
||||
result = pop3_state_retr_resp(conn, pop3code, pop3c->state);
|
||||
break;
|
||||
|
||||
case POP3_LIST:
|
||||
result = pop3_state_list_resp(conn, pop3code, pop3c->state);
|
||||
break;
|
||||
|
||||
case POP3_QUIT:
|
||||
/* fallthrough, just stop! */
|
||||
default:
|
||||
@ -655,6 +716,7 @@ 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"));
|
||||
|
||||
@ -667,7 +729,13 @@ CURLcode pop3_perform(struct connectdata *conn,
|
||||
*dophase_done = FALSE; /* not done yet */
|
||||
|
||||
/* start the first command in the DO phase */
|
||||
result = pop3_retr(conn);
|
||||
/* 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))
|
||||
result = pop3_retr(conn);
|
||||
else
|
||||
result = pop3_list(conn);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -785,9 +853,6 @@ static CURLcode pop3_parse_url_path(struct connectdata *conn)
|
||||
const char *path = data->state.path;
|
||||
int len;
|
||||
|
||||
if(!*path)
|
||||
path = "INBOX";
|
||||
|
||||
/* url decode the path and use this mailbox */
|
||||
pop3c->mailbox = curl_easy_unescape(data, path, 0, &len);
|
||||
|
||||
|
@ -32,6 +32,7 @@ typedef enum {
|
||||
POP3_USER,
|
||||
POP3_PASS,
|
||||
POP3_STARTTLS,
|
||||
POP3_LIST,
|
||||
POP3_RETR,
|
||||
POP3_QUIT,
|
||||
POP3_LAST /* never used */
|
||||
|
Loading…
Reference in New Issue
Block a user