IMAP bug?
I'm not an IMAP expert, but I had a problem opening a mail folder via
IMAP and looked into it. I think this problem was caused by a system
administrator deleting some messages that has viruses in them. This
seems to have caused Cyrus to respond with a FETCH syntax that mutt
isn't prepared to handle -- mutt fails to open the folder and then also
seems to get wedged. The short illustration below of an interaction
with the imap server will hopefully illustrate this problem. Messages
3274 and 3275 exhibit the problem; message 3276 seems okay.
To fix this problem, as it was preventing me from opening the folder in
mutt (which unfortunately was necessary to recover lost mail), I applied
the attached patch. I don't want to vouch too much for this patch, but
it was sufficient to let me open my mail folder.
Interaction with IMAP server illustrating problem:
* OK kitche1.zk3.dec.com Cyrus IMAP4 v1.6.19 server ready
a0000 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ NAMESPACE UIDPLUS
X-NON-HIERARCHICAL-RENAME NO_ATOMIC_RENAME AUTH=PLAIN UNSELECT
a0000 OK Completed
a0001 LOGIN "bobbell" "qwer56re"
a0001 OK User logged in
a0002 SELECT "INBOX.Backup"
* FLAGS (\Answered \Flagged \Draft \Deleted \Seen)
* OK [PERMANENTFLAGS (\Answered \Flagged \Draft \Deleted \Seen \*)]
* 72777 EXISTS
* 7 RECENT
* OK [UNSEEN 31012]
* OK [UIDVALIDITY 1037659487]
* OK [UIDNEXT 72780]
a0002 OK [READ-WRITE] Completed
a0003 FETCH 3274 (UID FLAGS INTERNALDATE RFC822.SIZE BODY.PEEK[HEADER.FIELDS
(DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES CONTENT-TYPE IN-REPLY-TO
REPLY-TO LINES X-LABEL)])
* OK Message 3274 no longer exists
* 3274 FETCH (FLAGS (\Seen) UID 3276 INTERNALDATE " 4-May-2000 07:43:02 -0400"
RFC822.SIZE 15262 BODY[HEADER.FIELDS (DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES CONTENT-TYPE
IN-REPLY-TO REPLY-TO LINES X-LABEL)] "")
a0003 OK Completed
a0004 FETCH 3275 (UID FLAGS INTERNALDATE RFC822.SIZE BODY.PEEK[HEADER.FIELDS
(DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES CONTENT-TYPE IN-REPLY-TO
REPLY-TO LINES X-LABEL)])
* OK Message 3275 no longer exists
* 3275 FETCH (FLAGS (\Seen) UID 3277 INTERNALDATE " 4-May-2000 07:55:30 -0400"
RFC822.SIZE 15264 BODY[HEADER.FIELDS (DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES CONTENT-TYPE
IN-REPLY-TO REPLY-TO LINES X-LABEL)] "")
a0004 OK Completed
a0005 FETCH 3276 (UID FLAGS INTERNALDATE RFC822.SIZE BODY.PEEK[HEADER.FIELDS
(DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES CONTENT-TYPE IN-REPLY-TO
REPLY-TO LINES X-LABEL)])
* 3276 FETCH (FLAGS (\Seen) UID 3278 INTERNALDATE " 4-May-2000 09:34:23 -0400"
RFC822.SIZE 1715 BODY[HEADER.FIELDS (DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES
CONTENT-TYPE IN-REPLY-TO REPLY-TO LINES X-LABEL)] {270}
From: "Chris Walker" <cwalker@xxxxxxxxxxx>
To: <usg_zk@xxxxxxxxxxx>
Subject: ! PC Virus Alert ! VBS.LoveLetter.A
Date: Thu, 4 May 2000 09:31:40 -0400
Message-ID: <JFEAJBIHLMALDNHBADCLIEHECCAA.cwalker@xxxxxxxxxxx>
Content-Type: text/plain;
charset="iso-8859-1"
)
a0005 OK Completed
a0006 LOGOUT
* BYE LOGOUT received
a0006 OK Completed
Connection closed by foreign host.
--
Bob Bell <bbell@xxxxxxxxxxxxxxxxxxxxx>
diff -rup mutt-1.5.5.1/imap/message.c /tmp/mutt-patched/imap/message.c
--- mutt-1.5.5.1/imap/message.c 2003-11-05 04:41:36.000000000 -0500
+++ /tmp/mutt-patched/imap/message.c 2004-01-20 12:59:09.000000000 -0500
@@ -768,11 +768,13 @@ static int msg_fetch_header (CONTEXT* ct
* (eg Domino puts FLAGS here). Nothing wrong with that, either.
* This all has to go - we should accept literals and nonliterals
* interchangeably at any time. */
- if (imap_cmd_step (idata) != IMAP_CMD_CONTINUE)
- return -2;
-
- if (msg_parse_fetch (h, idata->cmd.buf) == -1)
- return rc;
+ if (bytes)
+ {
+ if (imap_cmd_step (idata) != IMAP_CMD_CONTINUE)
+ return rc;
+ if (msg_parse_fetch (h, idata->cmd.buf) == -1)
+ return rc;
+ }
rc = 0; /* success */
diff -rup mutt-1.5.5.1/imap/util.c /tmp/mutt-patched/imap/util.c
--- mutt-1.5.5.1/imap/util.c 2003-11-05 04:41:36.000000000 -0500
+++ /tmp/mutt-patched/imap/util.c 2004-01-20 13:01:26.000000000 -0500
@@ -307,7 +307,17 @@ int imap_get_literal_count(const char *b
char *pn;
if (!(pc = strchr (buf, '{')))
- return (-1);
+ {
+ if ((pc = strrchr (buf, '"')) && pc > (char *)buf && pc[-1] == '"')
+ {
+ *bytes = 0;
+ return (0);
+ }
+ else
+ {
+ return (-1);
+ }
+ }
pc++;
pn = pc;
while (isdigit ((unsigned char) *pc))