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):
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;
}
else if (strstr(buf, " RECENT"))
{
- recentcount_ok = 1;
recentcount = atoi(buf+2);
}
else if (strstr(buf, " EXPUNGE"))
/* 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"))
{
{
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;
* 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);
}