From dgaudet-list-qmail@arctic.org Fri Jan 17 17:50:19 1997 Date: Fri, 17 Jan 1997 17:38:33 -0800 (PST) From: Dean Gaudet To: Julie Baumler Cc: qmail list Subject: [PATCH] qmail and \r\n (was Re: host unable to deliver to host using qmail (summary)) On Thu, 16 Jan 1997, Julie Baumler wrote: > > The admin on the machine in question added "E=\r\n" this morning and low > and behold, suddenly they can send us mail. > > >From a quick look at the source code, it appears that the remote machine > is notified of the problem, but sendmail in its infinite wisdom apparently > doesn't capture the error message. (SIGH) I don't know what the sendmail config had wrong with it, but I know that systems I've set up bounce the error just fine. Check also in the mail logs. qmail by default violates the "be liberal in what you accept" rule when receiving mail via smtp. It enforces strict \r\n behaviour... which is exactly what the standard dictates. But I'm not interested in my mailer telling other admins to fix their setup, because I know they won't. (The straynewline() function tells people that if they're under Solaris they need E=\r\n in their Mether mailer.) There is also bug in sendmail pre 8.8 that in some instances will emit \rx\n for some printable x. The case where it occured to me, the message had been generated by a lame PC mail program. In any event, this causes qmail to indefinitely defer the incoming message. So instead I looked at the sendmail-8.8.4 code and tried to duplicate its behaviour w.r.t. seeing \n when it wasn't expecting it. That is what this patch implements. Go ahead, shoot me. Dean *** qmail-smtpd.c.dist Thu Jan 9 00:17:06 1997 --- qmail-smtpd.c Thu Jan 9 00:44:49 1997 *************** *** 140,156 **** switch(state) { case 0: ! if (ch == '\n') straynewline(); if (ch == '\r') { state = 4; continue; } break; case 1: /* \r\n */ - if (ch == '\n') straynewline(); if (ch == '.') { state = 2; continue; } if (ch == '\r') { state = 4; continue; } ! state = 0; break; case 2: /* \r\n + . */ ! if (ch == '\n') straynewline(); if (ch == '\r') { state = 3; continue; } state = 0; break; --- 140,155 ---- switch(state) { case 0: ! if (ch == '\n') { state = 1; break; } if (ch == '\r') { state = 4; continue; } break; case 1: /* \r\n */ if (ch == '.') { state = 2; continue; } if (ch == '\r') { state = 4; continue; } ! if (ch != '\n') state = 0; break; case 2: /* \r\n + . */ ! if (ch == '\n') return; /* this is what sendmail-8.8.4 does -djg */ if (ch == '\r') { state = 3; continue; } state = 0; break;