aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Andree <matthias.andree@gmx.de>2006-03-01 16:47:49 +0000
committerMatthias Andree <matthias.andree@gmx.de>2006-03-01 16:47:49 +0000
commit9da8090cf973fccd969377bb587810331671caac (patch)
treeb73b7490f85f7a2449afc085c0a6d8b740d883a8
parentcfec6074565fbe4e59ce144595240f2baa54e90f (diff)
downloadfetchmail-9da8090cf973fccd969377bb587810331671caac.tar.gz
fetchmail-9da8090cf973fccd969377bb587810331671caac.tar.bz2
fetchmail-9da8090cf973fccd969377bb587810331671caac.zip
Handle other clients concurrently accessing IMAP mailboxes better.
Fetchmail quits the poll if the EXPUNGE count does not match expectations, and servers not updating RECENT counts after EXPUNGE are handled in a better way. (Patch by Sunil Shetye.) svn path=/branches/BRANCH_6-3/; revision=4700
-rw-r--r--NEWS4
-rw-r--r--imap.c44
2 files changed, 37 insertions, 11 deletions
diff --git a/NEWS b/NEWS
index 1d426ae6..8389e4fc 100644
--- a/NEWS
+++ b/NEWS
@@ -36,6 +36,10 @@ fetchmail 6.3.3 (not yet released):
Fixes Debian Bug#354661, reported by Keith Hellman.
* The manual page now suggests -- before the addresses in the sendmail MDA
example.
+* Handle other clients concurrently accessing IMAP mailboxes better.
+ Fetchmail quits the poll if the EXPUNGE count does not match expectations, and
+ servers not updating RECENT counts after EXPUNGE are handled in a better way.
+ (Patch by Sunil Shetye.)
fetchmail 6.3.2 (released 2006-01-22):
diff --git a/imap.c b/imap.c
index 68e87eb8..cc534c01 100644
--- a/imap.c
+++ b/imap.c
@@ -43,7 +43,7 @@ static int expunged = 0;
static unsigned int *unseen_messages;
/* for "IMAP> EXPUNGE" */
-static int recentcount_ok = 0;
+static int actual_deletions = 0;
/* for "IMAP> IDLE" */
static int saved_timeout = 0;
@@ -114,7 +114,6 @@ static int imap_ok(int sock, char *argbuf)
}
else if (strstr(buf, " RECENT"))
{
- recentcount_ok = 1;
recentcount = atoi(buf+2);
}
else if (strstr(buf, " EXPUNGE"))
@@ -122,9 +121,18 @@ static int imap_ok(int sock, char *argbuf)
/* the response "* 10 EXPUNGE" means that the currently
* tenth (i.e. only one) message has been deleted */
if (atoi(buf+2) > 0)
- count--;
- if (count < 0)
- count = 0;
+ {
+ if (count > 0)
+ count--;
+ /* Some servers do not report RECENT after an EXPUNGE.
+ * For such servers, assume that the mail being
+ * expunged is a recent one. For other servers, we
+ * should get an updated RECENT report later and this
+ * assumption will have no effect. */
+ if (recentcount > 0)
+ recentcount--;
+ actual_deletions++;
+ }
}
else if (strstr(buf, " PREAUTH"))
{
@@ -577,15 +585,26 @@ static int internal_expunge(int sock)
{
int ok;
- recentcount_ok = 0;
+ actual_deletions = 0;
if ((ok = gen_transact(sock, "EXPUNGE")))
return(ok);
- /* some servers do not report RECENT after an EXPUNGE. in this case,
- * the previous value of recentcount is just ignored. */
- if (!recentcount_ok)
- recentcount = 0;
+ /* if there is a mismatch between the number of mails which should
+ * have been expunged and the number of mails actually expunged,
+ * another email client may be deleting mails. Quit here,
+ * otherwise fetchmail gets out-of-sync with the imap server,
+ * reports the wrong size to the SMTP server on MAIL FROM: and
+ * triggers a "message ... was not the expected length" error on
+ * every subsequent mail */
+ if (deletions > 0 && deletions != actual_deletions)
+ {
+ report(stderr,
+ GT_("mail expunge mismatch (%d actual != %d expected)\n"),
+ actual_deletions, deletions);
+ deletions = 0;
+ return(PS_ERROR);
+ }
expunged += deletions;
deletions = 0;
@@ -1131,7 +1150,10 @@ static int imap_delete(int sock, struct query *ctl, int number)
* the next session.
*/
if (NUM_NONZERO(expunge_period) && (deletions % expunge_period) == 0)
- internal_expunge(sock);
+ {
+ if ((ok = internal_expunge(sock)))
+ return(ok);
+ }
return(PS_SUCCESS);
}