summaryrefslogtreecommitdiffstats
path: root/imap/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'imap/command.c')
-rw-r--r--imap/command.c89
1 files changed, 75 insertions, 14 deletions
diff --git a/imap/command.c b/imap/command.c
index 2f90dc48..55ab7d06 100644
--- a/imap/command.c
+++ b/imap/command.c
@@ -32,12 +32,12 @@
#define IMAP_CMD_BUFSIZE 512
/* forward declarations */
-static void cmd_finish (IMAP_DATA* idata);
static void cmd_handle_fatal (IMAP_DATA* idata);
static int cmd_handle_untagged (IMAP_DATA* idata);
static void cmd_make_sequence (IMAP_DATA* idata);
static void cmd_parse_capabilities (IMAP_DATA* idata, char* s);
-static void cmd_parse_expunge (IMAP_DATA* idata, char* s);
+static void cmd_parse_expunge (IMAP_DATA* idata, const char* s);
+static void cmd_parse_fetch (IMAP_DATA* idata, char* s);
static void cmd_parse_myrights (IMAP_DATA* idata, char* s);
static char *Capabilities[] = {
@@ -148,7 +148,7 @@ int imap_cmd_step (IMAP_DATA* idata)
/* tagged completion code */
if (!mutt_strncmp (cmd->buf, cmd->seq, SEQLEN))
{
- cmd_finish (idata);
+ imap_cmd_finish (idata);
return imap_code (cmd->buf) ? IMAP_CMD_OK : IMAP_CMD_NO;
}
@@ -229,16 +229,16 @@ int imap_cmd_running (IMAP_DATA* idata)
return 0;
}
-/* cmd_finish: When the caller has finished reading command responses,
- * it must call this routine to perform cleanup (eg fetch new mail if
- * detected, do expunge). Called automatically by imap_cmd_step */
-static void cmd_finish (IMAP_DATA* idata)
+/* imap_cmd_finish: Attempts to perform cleanup (eg fetch new mail if
+ * detected, do expunge). Called automatically by imap_cmd_step, but
+ * may be called at any time. Called by imap_check_mailbox just before
+ * the index is refreshed, for instance. */
+void imap_cmd_finish (IMAP_DATA* idata)
{
if (!(idata->state == IMAP_SELECTED) || idata->ctx->closing)
return;
- if ((idata->reopen & IMAP_REOPEN_ALLOW) &&
- (idata->reopen & (IMAP_EXPUNGE_PENDING|IMAP_NEWMAIL_PENDING)))
+ if (idata->reopen & IMAP_REOPEN_ALLOW)
{
int count = idata->newMailCount;
@@ -247,16 +247,16 @@ static void cmd_finish (IMAP_DATA* idata)
&& count > idata->ctx->msgcount)
{
/* read new mail messages */
- dprint (2, (debugfile, "cmd_finish: Fetching new mail\n"));
+ dprint (2, (debugfile, "imap_cmd_finish: Fetching new mail\n"));
/* check_status: curs_main uses imap_check_mailbox to detect
* whether the index needs updating */
idata->check_status = IMAP_NEWMAIL_PENDING;
idata->reopen &= ~IMAP_NEWMAIL_PENDING;
count = imap_read_headers (idata, idata->ctx->msgcount, count-1)+1;
}
- else
+ else if (idata->reopen & IMAP_EXPUNGE_PENDING)
{
- dprint (2, (debugfile, "cmd_finish: Expunging mailbox\n"));
+ dprint (2, (debugfile, "imap_cmd_finish: Expunging mailbox\n"));
imap_expunge_mailbox (idata);
/* Detect whether we've gotten unexpected EXPUNGE messages */
if (idata->reopen & IMAP_EXPUNGE_PENDING &&
@@ -334,9 +334,11 @@ static int cmd_handle_untagged (IMAP_DATA* idata)
idata->newMailCount = count;
}
}
+ /* pn vs. s: need initial seqno */
else if (ascii_strncasecmp ("EXPUNGE", s, 7) == 0)
- /* pn vs. s: need initial seqno */
cmd_parse_expunge (idata, pn);
+ else if (ascii_strncasecmp ("FETCH", s, 5) == 0)
+ cmd_parse_fetch (idata, pn);
}
else if (ascii_strncasecmp ("CAPABILITY", s, 10) == 0)
cmd_parse_capabilities (idata, s);
@@ -407,7 +409,7 @@ static void cmd_parse_capabilities (IMAP_DATA* idata, char* s)
/* cmd_parse_expunge: mark headers with new sequence ID and mark idata to
* be reopened at our earliest convenience */
-static void cmd_parse_expunge (IMAP_DATA* idata, char* s)
+static void cmd_parse_expunge (IMAP_DATA* idata, const char* s)
{
int expno, cur;
HEADER* h;
@@ -433,6 +435,65 @@ static void cmd_parse_expunge (IMAP_DATA* idata, char* s)
idata->reopen |= IMAP_EXPUNGE_PENDING;
}
+/* cmd_parse_fetch: Load fetch response into IMAP_DATA. Currently only
+ * handles unanticipated FETCH responses, and only FLAGS data. We get
+ * these if another client has changed flags for a mailbox we've selected.
+ * Of course, a lot of code here duplicates code in message.c. */
+static void cmd_parse_fetch (IMAP_DATA* idata, char* s)
+{
+ int msgno, cur;
+ HEADER* h = NULL;
+
+ dprint (2, (debugfile, "Handling FETCH\n"));
+
+ msgno = atoi (s);
+
+ /* see cmd_parse_expunge */
+ for (cur = 0; cur < idata->ctx->msgcount; cur++)
+ {
+ h = idata->ctx->hdrs[cur];
+
+ if (h->active && h->index+1 == msgno)
+ {
+ dprint (2, (debugfile, "Message UID %d updated\n", HEADER_DATA(h)->uid));
+ break;
+ }
+
+ h = NULL;
+ }
+
+ if (!h)
+ {
+ dprint (1, (debugfile, "FETCH response ignored for this message\n"));
+ return;
+ }
+
+ /* skip FETCH */
+ s = imap_next_word (s);
+ s = imap_next_word (s);
+
+ if (*s != '(')
+ {
+ dprint (1, (debugfile, "Malformed FETCH response"));
+ return;
+ }
+ s++;
+
+ if (ascii_strncasecmp ("FLAGS", s, 5) != 0)
+ {
+ dprint (2, (debugfile, "Only handle FLAGS updates\n"));
+ return;
+ }
+
+ /* If server flags could conflict with mutt's flags, reopen the mailbox. */
+ if (h->changed)
+ idata->reopen |= IMAP_EXPUNGE_PENDING;
+ else {
+ imap_set_flags (idata, h, s);
+ idata->check_status = IMAP_FLAGS_PENDING;
+ }
+}
+
/* cmd_parse_myrights: set rights bits according to MYRIGHTS response */
static void cmd_parse_myrights (IMAP_DATA* idata, char* s)
{