
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 <dgaudet-list-qmail@arctic.org>
To: Julie Baumler <a4jb@psulib.cc.pdx.edu>
Cc: qmail list <djb-qmail@koobera.math.uic.edu>
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;

