aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2001-12-14 08:37:11 +0000
committerEric S. Raymond <esr@thyrsus.com>2001-12-14 08:37:11 +0000
commit2a8d12fedded17916377e0de82afed0c8e54c759 (patch)
tree7b58ed977d8acea739846c7a7007b29c0c950ffc
parentac0dc02d3b255066da65eff3b1e8b8ca4629b0e0 (diff)
downloadfetchmail-2a8d12fedded17916377e0de82afed0c8e54c759.tar.gz
fetchmail-2a8d12fedded17916377e0de82afed0c8e54c759.tar.bz2
fetchmail-2a8d12fedded17916377e0de82afed0c8e54c759.zip
Revised dup-killer code.
svn path=/trunk/; revision=3561
-rw-r--r--NEWS2
-rw-r--r--fetchmail.h1
-rw-r--r--transact.c91
3 files changed, 56 insertions, 38 deletions
diff --git a/NEWS b/NEWS
index 5b5f010e..71d4baeb 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,8 @@
* Documented known IDLE bug in the todo.html file.
* Sunil Shetye's fix for a timeout/reconnect bug.
* LMTP fix from Toshiro HIKITA <toshi@sodan.org>.
+* The duplicate-killer doesn't try to operate if we can get an actual
+ recipient address from the trace headers.
fetchmail-5.9.5 (Thu Nov 8 14:14:35 EST 2001), 21162 lines:
diff --git a/fetchmail.h b/fetchmail.h
index 46344627..4ed413e8 100644
--- a/fetchmail.h
+++ b/fetchmail.h
@@ -308,6 +308,7 @@ struct query
struct idlist *skipped; /* messages skipped on the mail server */
struct idlist *oldsaved, *newsaved;
char *lastid; /* last Message-ID seen on this connection */
+ char *thisid; /* Message-ID of current message */
/* internal use -- per-message state */
int mimemsg; /* bitmask indicating MIME body-type */
diff --git a/transact.c b/transact.c
index 4ad9e799..c6387e3c 100644
--- a/transact.c
+++ b/transact.c
@@ -377,6 +377,11 @@ int readheaders(int sock,
if (msgblk.headers)
free(msgblk.headers);
+ /* initially, no message ID */
+ if (ctl->thisid)
+ free(ctl->thisid);
+ ctl->thisid = NULL;
+
msgblk.headers = received_for = delivered_to = NULL;
from_offs = reply_to_offs = resent_from_offs = app_from_offs =
sender_offs = resent_sender_offs = env_offs = -1;
@@ -514,44 +519,9 @@ int readheaders(int sock,
/* we see an ordinary (non-header, non-message-delimiter line */
has_nuls = (linelen != strlen(line));
- /*
- * When mail delivered to a multidrop mailbox on the server is
- * addressed to multiple people on the client machine, there
- * will be one copy left in the box for each recipient. Thus,
- * if the mail is addressed to N people, each recipient will
- * get N copies. This is bad when N > 1.
- *
- * Foil this by suppressing all but one copy of a message with
- * a given Message-ID. The accept_count test ensures that
- * multiple pieces of email with the same Message-ID, each
- * with a *single* addressee (the N == 1 case), won't be
- * suppressed.
- *
- * Note: This implementation only catches runs of successive
- * messages with the same ID, but that should be good
- * enough. A more general implementation would have to store
- * ever-growing lists of seen message-IDs; in a long-running
- * daemon this would turn into a memory leak even if the
- * implementation were perfect.
- *
- * Don't mess with this code casually. It would be way too easy
- * to break it in a way that blackholed mail. Better to pass
- * the occasional duplicate than to do that...
- */
+ /* save the message's ID, we may use it for killing duplicates later */
if (MULTIDROP(ctl) && !strncasecmp(line, "Message-ID:", 11))
- {
- if (ctl->lastid && !strcasecmp(ctl->lastid, line))
- {
- if (accept_count > 1)
- return(PS_REFUSED);
- }
- else
- {
- if (ctl->lastid)
- free(ctl->lastid);
- ctl->lastid = xstrdup(line);
- }
- }
+ ctl->thisid = xstrdup(line);
/*
* The University of Washington IMAP server (the reference
@@ -811,7 +781,52 @@ int readheaders(int sock,
}
}
- process_headers:
+ process_headers:
+ /*
+ * When mail delivered to a multidrop mailbox on the server is
+ * addressed to multiple people on the client machine, there will
+ * be one copy left in the box for each recipient. This is not a
+ * problem if we have the actual recipient address to dispatch on
+ * (e.g. because we've mined it out of sendmail trace headers, or
+ * a qmail Delivered-To line, or a declared sender envelope line).
+ *
+ * But if we're mining addressees out of the To/Cc/Bcc fields, and
+ * if the mail is addressed to N people, each recipient will
+ * get N copies. This is bad when N > 1.
+ *
+ * Foil this by suppressing all but one copy of a message with
+ * a given Message-ID. The accept_count test ensures that
+ * multiple pieces of email with the same Message-ID, each
+ * with a *single* addressee (the N == 1 case), won't be
+ * suppressed.
+ *
+ * Note: This implementation only catches runs of successive
+ * messages with the same ID, but that should be good
+ * enough. A more general implementation would have to store
+ * ever-growing lists of seen message-IDs; in a long-running
+ * daemon this would turn into a memory leak even if the
+ * implementation were perfect.
+ *
+ * Don't mess with this code casually. It would be way too easy
+ * to break it in a way that blackholed mail. Better to pass
+ * the occasional duplicate than to do that...
+ */
+ if (!received_for && env_offs == -1 && !delivered_to)
+ {
+ if (ctl->lastid && ctl->thisid && !strcasecmp(ctl->lastid, ctl->thisid))
+ {
+ if (accept_count > 1)
+ return(PS_REFUSED);
+ }
+ else
+ {
+ if (ctl->lastid)
+ free(ctl->lastid);
+ ctl->lastid = ctl->thisid;
+ ctl->thisid = NULL;
+ }
+ }
+
/*
* We want to detect this early in case there are so few headers that the
* dispatch logic barfs.