diff -Naur fetchmail-6.2.2.orig/driver.c fetchmail-6.2.2/driver.c --- fetchmail-6.2.2.orig/driver.c 2003-06-02 18:38:48.000000000 +0530 +++ fetchmail-6.2.2/driver.c 2003-06-03 16:22:46.000000000 +0530 @@ -471,6 +471,7 @@ else { flag wholesize = !ctl->server.base_protocol->fetch_body; + flag separatefetchbody = (ctl->server.base_protocol->fetch_body) ? TRUE : FALSE; /* request a message */ err = (ctl->server.base_protocol->fetch_headers)(mailserver_socket,ctl,num, &len); @@ -512,45 +513,23 @@ * output sink. */ err = readheaders(mailserver_socket, len, msgsizes[num-1], - ctl, num); + ctl, num, + /* pass the suppress_readbody flag only if the underlying + * protocol does not fetch the body separately */ + separatefetchbody ? 0 : &suppress_readbody); if (err == PS_RETAINED) - { suppress_forward = suppress_delete = retained = TRUE; - /* do not read the body only if the underlying protocol - * allows the body to be fetched separately */ - if (ctl->server.base_protocol->fetch_body) - suppress_readbody = TRUE; - } else if (err == PS_TRANSIENT) - { suppress_delete = suppress_forward = TRUE; - if (ctl->server.base_protocol->fetch_body) - suppress_readbody = TRUE; - } else if (err == PS_REFUSED) - { suppress_forward = TRUE; - if (ctl->server.base_protocol->fetch_body) - suppress_readbody = TRUE; - } else if (err == PS_TRUNCATED) - { - if (ctl->server.base_protocol->fetch_body) - suppress_readbody = TRUE; - len = 0; /* suppress body processing */ - } + suppress_readbody = TRUE; else if (err) return(err); - /* - * If we're using IMAP4 or something else that - * can fetch headers separately from bodies, - * it's time to request the body now. This - * fetch may be skipped if we got an anti-spam - * or other PS_REFUSED error response during - * readheaders. - */ - if (ctl->server.base_protocol->fetch_body && !suppress_readbody) + /* tell server we got it OK and resynchronize */ + if (separatefetchbody && ctl->server.base_protocol->trail) { if (outlevel >= O_VERBOSE && !isafile(1)) { @@ -560,9 +539,27 @@ if ((err = (ctl->server.base_protocol->trail)(mailserver_socket, ctl, num))) return(err); - len = 0; - if (!suppress_forward) + } + + /* do not read the body which is not being forwarded only if + * the underlying protocol allows the body to be fetched + * separately */ + if (separatefetchbody && suppress_forward) + suppress_readbody = TRUE; + + /* + * If we're using IMAP4 or something else that + * can fetch headers separately from bodies, + * it's time to request the body now. This + * fetch may be skipped if we got an anti-spam + * or other PS_REFUSED error response during + * readheaders. + */ + if (!suppress_readbody) + { + if (separatefetchbody) { + len = -1; if ((err=(ctl->server.base_protocol->fetch_body)(mailserver_socket,ctl,num,&len))) return(err); /* @@ -578,22 +575,12 @@ report_complete(stdout, GT_(" (%d body octets) "), len); } - } - /* process the body now */ - if (len > 0) - { - if (suppress_readbody) - { - err = PS_SUCCESS; - } - else - { - err = readbody(mailserver_socket, - ctl, - !suppress_forward, - len); - } + /* process the body now */ + err = readbody(mailserver_socket, + ctl, + !suppress_forward, + len); if (err == PS_TRANSIENT) suppress_delete = suppress_forward = TRUE; else if (err) diff -Naur fetchmail-6.2.2.orig/fetchmail.h fetchmail-6.2.2/fetchmail.h --- fetchmail-6.2.2.orig/fetchmail.h 2003-03-01 07:13:11.000000000 +0530 +++ fetchmail-6.2.2/fetchmail.h 2003-06-03 16:19:43.000000000 +0530 @@ -437,7 +437,8 @@ long fetchlen, long reallen, struct query *ctl, - int num); + int num, + flag *suppress_readbody); int readbody(int sock, struct query *ctl, flag forward, int len); #if defined(HAVE_STDARG_H) void gen_send(int sock, const char *, ... ) diff -Naur fetchmail-6.2.2.orig/transact.c fetchmail-6.2.2/transact.c --- fetchmail-6.2.2.orig/transact.c 2003-06-02 18:38:48.000000000 +0530 +++ fetchmail-6.2.2/transact.c 2003-06-03 16:19:55.000000000 +0530 @@ -352,13 +352,15 @@ long fetchlen, long reallen, struct query *ctl, - int num) + int num, + flag *suppress_readbody) /* read message headers and ship to SMTP or MDA */ /* sock: to which the server is connected */ /* fetchlen: length of message according to fetch response */ /* reallen: length of message according to getsizes */ /* ctl: query control record */ /* num: index of message */ +/* suppress_readbody: whether call to readbody() should be supressed */ { struct addrblk { @@ -379,12 +381,12 @@ int n, linelen, oldlen, ch, remaining, skipcount; struct idlist *idp; flag no_local_matches = FALSE; - flag headers_ok, has_nuls; + flag has_nuls; int olderrs, good_addresses, bad_addresses; - int retain_mail = 0; + int retain_mail = 0, refuse_mail = 0; sizeticker = 0; - has_nuls = headers_ok = FALSE; + has_nuls = FALSE; msgblk.return_path[0] = '\0'; olderrs = ctl->errcount; @@ -487,7 +489,6 @@ /* check for end of headers */ if (end_of_header(line)) { - headers_ok = TRUE; has_nuls = (linelen != strlen(line)); free(line); goto process_headers; @@ -500,7 +501,11 @@ */ if (protocol->delimited && line[0] == '.' && EMPTYLINE(line+1)) { - headers_ok = FALSE; + if (outlevel > O_SILENT) + report(stdout, + GT_("message delimiter found while scanning headers\n")); + if (suppress_readbody) + *suppress_readbody = TRUE; has_nuls = (linelen != strlen(line)); free(line); goto process_headers; @@ -510,20 +515,16 @@ * At least one brain-dead website (netmind.com) is known to * send out robotmail that's missing the RFC822 delimiter blank * line before the body! Without this check fetchmail segfaults. - * With it, we treat such messages as though they had the missing - * blank line. + * With it, we treat such messages as spam and refuse them. */ - if (!isspace(line[0]) && !strchr(line, ':')) + if (!refuse_mail && !isspace(line[0]) && !strchr(line, ':')) { - /* the headers_ok flag cannot be set to FALSE here as the - * delimiter has not occurred yet. */ if (outlevel > O_SILENT) report(stdout, GT_("incorrect header line found while scanning headers\n")); if (outlevel >= O_VERBOSE) report (stdout, GT_("line: %s"), line); - retain_mail = 1; - goto process_headers; + refuse_mail = 1; } /* check for RFC822 continuations */ @@ -548,6 +549,13 @@ } } + /* skip processing if we are going to retain or refuse this mail */ + if (retain_mail || refuse_mail) + { + free(line); + continue; + } + /* we see an ordinary (non-header, non-message-delimiter line */ has_nuls = (linelen != strlen(line)); @@ -825,6 +833,8 @@ msgblk.headers = NULL; return(PS_RETAINED); } + if (refuse_mail) + return(PS_REFUSED); /* * When mail delivered to a multidrop mailbox on the server is * addressed to multiple people on the client machine, there will @@ -1249,14 +1259,6 @@ *cp++ = '\0'; stuffline(ctl, buf); - if (!headers_ok) - { - if (outlevel > O_SILENT) - report(stdout, - GT_("message delimiter found while scanning headers\n")); - return(PS_TRUNCATED); - } - return(PS_SUCCESS); }