[prev in list] [next in list] [prev in thread] [next in thread]
List: fetchmail-friends
Subject: [fetchmail] [PATCH] Re: how to avoid "missed" mail
From: Sunil Shetye <shetye () bombay ! retortsoft ! com>
Date: 2002-12-23 14:19:03
[Download RAW message or body]
Quoting from Matthias Andree's mail on Fri, Dec 20, 2002 at 05:22:35PM +0100:
> > Quoting from Matthias Andree's mail on Thu, Dec 19, 2002 at 06:55:38PM +0100:
> >> Then there's a driver bug. fetchmail must not mark a mail it could not
> >> deliver "read". However, I only tested against POP3, so I may have
> >> missed that one at that time.
> >
> > I am not sure if this is correct for POP3. It works correctly only for
> > POP3+UIDL (client side tracking).
>
> UIDL is the only sane way for a reliable retrieval. Eric should make
> that the default in the next version (it should have become the default
> in 6.0.0 already).
Ok.
In that case, the IMAP code indeed has a bug. Here is a patch which
fixes that by adding a mark_seen() function to the driver and always
using BODY.PEEK for imap.
This patch also moves around the POP3/UID code from driver.c to pop3.c
just to keep things consistent.
I have tested this patch by using a script which returns 1 as an mda
for both IMAP and POP3.
--
Sunil Shetye.
["fetchmail-6.2.0-markseen.patch" (text/plain)]
diff -Naur fetchmail-6.2.0.orig/driver.c fetchmail-6.2.0/driver.c
--- fetchmail-6.2.0.orig/driver.c Thu Dec 19 03:38:47 2002
+++ fetchmail-6.2.0/driver.c Sat Dec 21 15:02:14 2002
@@ -658,25 +658,6 @@
* now.
*/
- /*
- * Tell the UID code we've seen this.
- * Matthias Andree: only register the UID if we could actually
- * forward this mail. If we omit this !suppress_delete check,
- * fetchmail will never retry mail that the local listener
- * refused temporarily.
- */
- if (ctl->newsaved && !suppress_delete)
- {
- struct idlist *sdp;
-
- for (sdp = ctl->newsaved; sdp; sdp = sdp->next)
- if ((sdp->val.status.num == num) && (msgcodes[num-1] >= 0))
- {
- sdp->val.status.mark = UID_SEEN;
- save_str(&ctl->oldsaved, sdp->id,UID_SEEN);
- }
- }
-
/* maybe we delete this message now? */
if (retained)
{
@@ -694,11 +675,10 @@
err = (ctl->server.base_protocol->delete)(mailserver_socket, ctl, num);
if (err != 0)
return(err);
-#ifdef POP3_ENABLE
- delete_str(&ctl->newsaved, num);
-#endif /* POP3_ENABLE */
}
- else if ( (outlevel >= O_VERBOSE) ||
+ else
+ {
+ if ( (outlevel >= O_VERBOSE) ||
/* To avoid flooding the syslog when using --keep,
* report "Skipped message" only when:
* 1) --verbose is on, or
@@ -709,6 +689,17 @@
(outlevel > O_SILENT && (!run.use_syslog || msgcodes[num-1] != MSGLEN_OLD))
)
report_complete(stdout, GT_(" not flushed\n"));
+
+ /* maybe we mark this message as seen now? */
+ if (ctl->server.base_protocol->mark_seen
+ && !suppress_delete
+ && (msgcodes[num-1] >= 0 && ctl->keep))
+ {
+ err = (ctl->server.base_protocol->mark_seen)(mailserver_socket, ctl, num);
+ if (err != 0)
+ return(err);
+ }
+ }
/* perhaps this as many as we're ready to handle */
if (maxfetch && maxfetch <= *fetches && *fetches < count)
diff -Naur fetchmail-6.2.0.orig/etrn.c fetchmail-6.2.0/etrn.c
--- fetchmail-6.2.0.orig/etrn.c Mon Mar 11 01:04:50 2002
+++ fetchmail-6.2.0/etrn.c Sat Dec 21 15:02:14 2002
@@ -140,6 +140,7 @@
NULL, /* no way to fetch body */
NULL, /* no message trailer */
NULL, /* how to delete a message */
+ NULL, /* how to mark a message as seen */
etrn_logout, /* log out, we're done */
FALSE, /* no, we can't re-poll */
};
diff -Naur fetchmail-6.2.0.orig/fetchmail.h fetchmail-6.2.0/fetchmail.h
--- fetchmail-6.2.0.orig/fetchmail.h Fri Dec 13 10:39:06 2002
+++ fetchmail-6.2.0/fetchmail.h Sat Dec 21 15:02:14 2002
@@ -191,6 +191,8 @@
/* eat trailer of a message */
int (*delete)(int, struct query *, int);
/* delete method */
+ int (*mark_seen)(int, struct query *, int);
+ /* mark as seen method */
int (*logout_cmd)(int, struct query *);
/* logout command */
flag retry; /* can getrange poll for new messages? */
diff -Naur fetchmail-6.2.0.orig/imap.c fetchmail-6.2.0/imap.c
--- fetchmail-6.2.0.orig/imap.c Thu Nov 28 15:59:24 2002
+++ fetchmail-6.2.0/imap.c Sat Dec 21 15:02:14 2002
@@ -876,11 +876,6 @@
* craps out during the message, it will still be marked `unseen' on
* the server.
*
- * However...*don't* do this if we're using keep to suppress deletion!
- * In that case, marking the seen flag is the only way to prevent the
- * message from being re-fetched on subsequent runs (and according
- * to RFC2060 p.43 this fetch should set Seen as a side effect).
- *
* According to RFC2060, and Mark Crispin the IMAP maintainer,
* FETCH %d BODY[TEXT] and RFC822.TEXT are "functionally
* equivalent". However, we know of at least one server that
@@ -898,17 +893,11 @@
switch (imap_version)
{
case IMAP4rev1: /* RFC 2060 */
- if (!ctl->keep)
- gen_send(sock, "FETCH %d BODY.PEEK[TEXT]", number);
- else
- gen_send(sock, "FETCH %d BODY[TEXT]", number);
+ gen_send(sock, "FETCH %d BODY.PEEK[TEXT]", number);
break;
case IMAP4: /* RFC 1730 */
- if (!ctl->keep)
- gen_send(sock, "FETCH %d RFC822.TEXT.PEEK", number);
- else
- gen_send(sock, "FETCH %d RFC822.TEXT", number);
+ gen_send(sock, "FETCH %d RFC822.TEXT.PEEK", number);
break;
default: /* RFC 1176 */
@@ -958,26 +947,6 @@
/* UW IMAP returns "OK FETCH", Cyrus returns "OK Completed" */
if (strstr(buf, "OK"))
break;
-
-#ifdef __UNUSED__
- /*
- * Any IMAP server that fails to set Seen on a BODY[TEXT]
- * fetch violates RFC2060 p.43 (top). This becomes an issue
- * when keep is on, because seen messages aren't deleted and
- * get refetched on each poll. As a workaround, if keep is on
- * we can set the Seen flag explicitly.
- *
- * This code isn't used yet because we don't know of any IMAP
- * servers broken in this way.
- */
- if (ctl->keep)
- if ((ok = gen_transact(sock,
- imap_version == IMAP4
- ? "STORE %d +FLAGS.SILENT (\\Seen)"
- : "STORE %d +FLAGS (\\Seen)",
- number)))
- return(ok);
-#endif /* __UNUSED__ */
}
return(PS_SUCCESS);
@@ -1022,6 +991,16 @@
return(PS_SUCCESS);
}
+static int imap_mark_seen(int sock, struct query *ctl, int number)
+/* mark the given message as seen */
+{
+ return(gen_transact(sock,
+ imap_version == IMAP4
+ ? "STORE %d +FLAGS.SILENT (\\Seen)"
+ : "STORE %d +FLAGS (\\Seen)",
+ number));
+}
+
static int imap_logout(int sock, struct query *ctl)
/* send logout command */
{
@@ -1059,6 +1038,7 @@
imap_fetch_body, /* request given message body */
imap_trail, /* eat message trailer */
imap_delete, /* delete the message */
+ imap_mark_seen, /* how to mark a message as seen */
imap_logout, /* expunge and exit */
TRUE, /* yes, we can re-poll */
};
diff -Naur fetchmail-6.2.0.orig/odmr.c fetchmail-6.2.0/odmr.c
--- fetchmail-6.2.0.orig/odmr.c Fri Oct 18 17:09:00 2002
+++ fetchmail-6.2.0/odmr.c Sat Dec 21 15:02:14 2002
@@ -229,6 +229,7 @@
NULL, /* no way to fetch body */
NULL, /* no message trailer */
NULL, /* how to delete a message */
+ NULL, /* how to mark a message as seen */
odmr_logout, /* log out, we're done */
FALSE, /* no, we can't re-poll */
};
diff -Naur fetchmail-6.2.0.orig/pop2.c fetchmail-6.2.0/pop2.c
--- fetchmail-6.2.0.orig/pop2.c Thu Mar 22 11:15:35 2001
+++ fetchmail-6.2.0/pop2.c Sat Dec 21 15:02:14 2002
@@ -146,6 +146,7 @@
NULL, /* no way to fetch body alone */
pop2_trail, /* eat message trailer */
NULL, /* no POP2 delete method */
+ NULL, /* how to mark a message as seen */
pop2_logout, /* log out, we're done */
FALSE, /* no, we can't re-poll */
};
diff -Naur fetchmail-6.2.0.orig/pop3.c fetchmail-6.2.0/pop3.c
--- fetchmail-6.2.0.orig/pop3.c Thu Nov 28 15:59:26 2002
+++ fetchmail-6.2.0/pop3.c Sat Dec 21 15:08:52 2002
@@ -792,11 +792,40 @@
return(PS_SUCCESS);
}
+static void mark_uid_seen(struct query *ctl, int number)
+/* Tell the UID code we've seen this. */
+{
+ if (ctl->newsaved)
+ {
+ struct idlist *sdp;
+
+ for (sdp = ctl->newsaved; sdp; sdp = sdp->next)
+ if (sdp->val.status.num == number)
+ {
+ sdp->val.status.mark = UID_SEEN;
+ save_str(&ctl->oldsaved, sdp->id,UID_SEEN);
+ }
+ }
+}
+
static int pop3_delete(int sock, struct query *ctl, int number)
/* delete a given message */
{
+ int ok;
+ mark_uid_seen(ctl, number);
/* actually, mark for deletion -- doesn't happen until QUIT time */
- return(gen_transact(sock, "DELE %d", number));
+ ok = gen_transact(sock, "DELE %d", number);
+ if (ok != PS_SUCCESS)
+ return(ok);
+ delete_str(&ctl->newsaved, number);
+ return(PS_SUCCESS);
+}
+
+static int pop3_mark_seen(int sock, struct query *ctl, int number)
+/* mark a given message as seen */
+{
+ mark_uid_seen(ctl, number);
+ return(PS_SUCCESS);
}
static int pop3_logout(int sock, struct query *ctl)
@@ -856,6 +885,7 @@
NULL, /* no way to fetch body alone */
NULL, /* no message trailer */
pop3_delete, /* how to delete a message */
+ pop3_mark_seen, /* how to mark a message as seen */
pop3_logout, /* log out, we're done */
FALSE, /* no, we can't re-poll */
};
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic