wmbiff: EXAMINE before STATUS

Patch by Nye Liu <nyet@nyet.org> to fix Debian bug #830889 [1].

Dear Maintainer,

Outlook Office365 IMAP servers now expect a client to issue at least one
EXAMINE before STATUS, or UNSEEN is always zero:

"unsub" folder has two messages, one unseen.

Broken:

56:04.84 > CJFK1 LOGIN "nyet@xxx" "xxx"
56:21.99 < CJFK1 OK LOGIN completed.
56:21.99 > CJFK2 STATUS unsub (MESSAGES UNSEEN)
56:22.20 < * STATUS unsub (MESSAGES 2 UNSEEN 0)
56:22.20 < CJFK2 OK STATUS completed.

Works:

56:46.04 > BPEB1 LOGIN "nyet@xxx" "xxx"
56:51.43 < BPEB1 OK LOGIN completed.
56:51.43 > BPEB2 EXAMINE unsub
56:51.67 < * 2 EXISTS
56:51.67 < * 0 RECENT
56:51.67 < * FLAGS (\Seen \Answered \Flagged \Deleted \Draft $MDNSent)
56:51.67 < * OK [PERMANENTFLAGS ()] Permanent flags
56:51.67 < * OK [UNSEEN 2] Is the first unseen message
56:51.67 < * OK [UIDVALIDITY 164] UIDVALIDITY value
56:51.67 < * OK [UIDNEXT 16] The next unique identifier value
56:51.67 < BPEB2 OK [READ-ONLY] EXAMINE completed.
56:51.67 > BPEB3 STATUS unsub (MESSAGES UNSEEN)
56:51.89 < * STATUS unsub (MESSAGES 2 UNSEEN 1)
56:51.89 < BPEB3 OK STATUS completed.

Attached is a patch to always issue EXAMINE before a STATUS.

It doesn't seem like it has to be done before every STATUS, just at least once.
Is only a proof of concept. I don't presume to know the best way to handle
optimizing it.

[1] https://bugs.debian.org/830889
This commit is contained in:
Doug Torrance 2016-07-12 14:25:18 -04:00 committed by Carlos R. Mafra
parent b44abc7a58
commit 1d84a1d8e4

View file

@ -294,6 +294,7 @@ int imap_checkmail( /*@notnull@ */ Pop3 pc)
/* recover connection state from the cache */ /* recover connection state from the cache */
struct connection_state *scs = state_for_pcu(pc); struct connection_state *scs = state_for_pcu(pc);
char buf[BUF_SIZE]; char buf[BUF_SIZE];
char examine_expect[BUF_SIZE];
static int command_id; static int command_id;
/* if it's not in the cache, try to open */ /* if it's not in the cache, try to open */
@ -312,6 +313,14 @@ int imap_checkmail( /*@notnull@ */ Pop3 pc)
return -1; return -1;
} }
command_id++;
tlscomm_printf(scs, "a%03d EXAMINE %s\r\n", command_id, pc->path);
snprintf(examine_expect, BUF_SIZE, "a%03d OK", command_id);
if (tlscomm_expect(scs, examine_expect, buf, 127) == 0) {
tlscomm_close(unbind(scs));
return -1;
}
/* if we've got it by now, try the status query */ /* if we've got it by now, try the status query */
command_id++; command_id++;
tlscomm_printf(scs, "a%03d STATUS %s (MESSAGES UNSEEN)\r\n", tlscomm_printf(scs, "a%03d STATUS %s (MESSAGES UNSEEN)\r\n",