aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/imap.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/lib/imap.c b/lib/imap.c
index 4ee6fff71..aae474c6b 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -397,6 +397,11 @@ static bool imap_endofresp(struct connectdata *conn, char *line, size_t len,
return FALSE;
break;
+ case IMAP_LIST:
+ if(!imap_matchresp(line, len, "LIST"))
+ return FALSE;
+ break;
+
case IMAP_SELECT:
/* SELECT is special in that its untagged responses does not have a
common prefix so accept anything! */
@@ -681,6 +686,30 @@ static CURLcode imap_authenticate(struct connectdata *conn)
}
/* Start the DO phase */
+static CURLcode imap_list(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct IMAP *imap = data->state.proto.imap;
+ struct imap_conn *imapc = &conn->proto.imapc;
+ char *mailbox;
+
+ /* Make sure the mailbox is in the correct atom format */
+ mailbox = imap_atom(imap->mailbox ? imap->mailbox : "");
+ if(!mailbox)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Send the LIST command */
+ result = imap_sendf(conn, "LIST \"%s\" *", mailbox);
+
+ Curl_safefree(mailbox);
+
+ if(!result)
+ state(conn, IMAP_LIST);
+
+ return result;
+}
+
static CURLcode imap_select(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
@@ -1278,6 +1307,38 @@ static CURLcode imap_state_login_resp(struct connectdata *conn,
return result;
}
+/* For LIST responses */
+static CURLcode imap_state_list_resp(struct connectdata *conn, int imapcode,
+ imapstate instate)
+{
+ CURLcode result = CURLE_OK;
+ char *line = conn->data->state.buffer;
+ size_t len = strlen(line);
+
+ (void)instate; /* No use for this yet */
+
+ if(imapcode == '*') {
+ /* The client which asked for this custom command should know best
+ how to cope with the result, just send it as body.
+ Add back the LF character temporarily while saving. */
+ line[len] = '\n';
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1);
+ line[len] = '\0';
+ }
+ else {
+ /* Final response. Stop and return the final status. */
+ if(imapcode != 'O')
+ result = CURLE_QUOTE_ERROR; /* TODO: Fix error code */
+ else
+ result = CURLE_OK;
+
+ /* End of DO phase */
+ state(conn, IMAP_STOP);
+ }
+
+ return result;
+}
+
/* For SELECT responses */
static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode,
imapstate instate)
@@ -1605,6 +1666,10 @@ static CURLcode imap_statemach_act(struct connectdata *conn)
result = imap_state_login_resp(conn, imapcode, imapc->state);
break;
+ case IMAP_LIST:
+ result = imap_state_list_resp(conn, imapcode, imapc->state);
+ break;
+
case IMAP_SELECT:
result = imap_state_select_resp(conn, imapcode, imapc->state);
break;