aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/pop3.c75
-rw-r--r--lib/pop3.h1
2 files changed, 71 insertions, 5 deletions
diff --git a/lib/pop3.c b/lib/pop3.c
index 320f75644..ff929b09c 100644
--- a/lib/pop3.c
+++ b/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);
diff --git a/lib/pop3.h b/lib/pop3.h
index 3076287fd..20a226985 100644
--- a/lib/pop3.h
+++ b/lib/pop3.h
@@ -32,6 +32,7 @@ typedef enum {
POP3_USER,
POP3_PASS,
POP3_STARTTLS,
+ POP3_LIST,
POP3_RETR,
POP3_QUIT,
POP3_LAST /* never used */