From: Eric S. Raymond Date: Thu, 26 Mar 1998 19:43:14 +0000 (-0000) Subject: Use TOP instead of RETR for POP3 retrieval. X-Git-Url: http://pileus.org/git/?a=commitdiff_plain;h=cacba6b362fb7907d1bb2d529e95504b27a00d25;p=~andy%2Ffetchmail Use TOP instead of RETR for POP3 retrieval. svn path=/trunk/; revision=1727 --- 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);