diff options
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | driver.c | 14 | ||||
-rw-r--r-- | pop3.c | 27 |
3 files changed, 37 insertions, 7 deletions
@@ -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. @@ -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; @@ -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); |