aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--driver.c14
-rw-r--r--pop3.c27
3 files changed, 37 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index d2e5e244..2c88a751 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,9 @@
Release Notes:
------------------------------------------------------------------------------
+fetchmail-4.4.2 ():
+* Use TOP for POP3 retrieval to avoid marking messages seen. Duh!
+
fetchmail-4.4.1 (Tue Mar 24 00:01:20 EST 1998):
* We now properly shroud IMAP passwords containing ", \, and SP.
* Checked for Y2K safety. No 2-digit dates anywhere, so we're safe.
diff --git a/driver.c b/driver.c
index 6963ea80..5257819a 100644
--- a/driver.c
+++ b/driver.c
@@ -2029,11 +2029,13 @@ const struct method *proto; /* protocol method table */
flag force_retrieval;
/*
- * What forces this code is that in POP3 and
- * IMAP2BIS you can't fetch a message without
- * having it marked `seen'. In IMAP4, on the
- * other hand, you can (peek_capable is set to
- * convey this).
+ * What forces this code is that in POP2 and
+ * IMAP2bis you can't fetch a message without
+ * having it marked `seen'. In POP3 and IMAP4, on the
+ * other hand, you can (peek_capable is set by
+ * each driver module to convey this; it's not a
+ * method constant because of the difference between
+ * IMAP2bis and IMAP4).
*
* The result of being unable to peek is that if there's
* any kind of transient error (DNS lookup failure, or
@@ -2477,7 +2479,7 @@ int size; /* length of buffer */
if (buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0';
if (buf[strlen(buf)-1] == '\r')
- buf[strlen(buf)-1] = '\r';
+ buf[strlen(buf)-1] = '\0';
if (outlevel == O_VERBOSE)
error(0, 0, "%s< %s", protocol->name, buf);
phase = oldphase;
diff --git a/pop3.c b/pop3.c
index 75fa0082..ffcb6469 100644
--- a/pop3.c
+++ b/pop3.c
@@ -234,6 +234,9 @@ int pop3_getauth(int sock, struct query *ctl, char *greeting)
*/
sleep(3); /* to be _really_ safe, probably need sleep(5)! */
+ /* we're peek-capable because the TOP command exists */
+ peek_capable = TRUE;
+
/* we're approved */
return(PS_SUCCESS);
}
@@ -519,7 +522,29 @@ static int pop3_fetch(int sock, struct query *ctl, int number, int *lenp)
/* phase = PHASE_FETCH */
- gen_send(sock, "RETR %d", number);
+ /*
+ * Though the POP RFCs don't document this fact, on every POP3 server
+ * I know of messages are marked "seen" only at the time the OK
+ * response to a RETR is issued.
+ *
+ * This means we can use TOP to fetch the message without setting its
+ * seen flag. This is good! It means that if the protocol exchange
+ * craps out during the message, it will still be marked `unseen' on
+ * the server.
+ *
+ * The line count passed is the maximum value of a twos-complement
+ * signed integer (we take advantage of the fact that, according
+ * to all the POP RFCs, "if the number of lines requested by the
+ * POP3 client is greater than than the number of lines in the
+ * body, then the POP3 server sends the entire message.").
+ *
+ * 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. */
+ if (ctl->keep)
+ gen_send(sock, "RETR %d", number);
+ else
+ gen_send(sock, "TOP %d 2147483647", number);
if ((ok = pop3_ok(sock, buf)) != 0)
return(ok);