This commit was manufactured by cvs2svn to create tag 'FreeBSD-release/1.1'.
[unix-history] / usr.sbin / sendmail / src / collect.c
index 4398b85..b434d49 100644 (file)
@@ -33,7 +33,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)collect.c  8.1 (Berkeley) 6/7/93";
+static char sccsid[] = "@(#)collect.c  8.9 (Berkeley) 1/31/94";
 #endif /* not lint */
 
 # include <errno.h>
 #endif /* not lint */
 
 # include <errno.h>
@@ -72,6 +72,7 @@ collect(smtpmode, requeueflag, e)
        bool ignrdot = smtpmode ? FALSE : IgnrDot;
        char buf[MAXLINE], buf2[MAXLINE];
        register char *workbuf, *freebuf;
        bool ignrdot = smtpmode ? FALSE : IgnrDot;
        char buf[MAXLINE], buf2[MAXLINE];
        register char *workbuf, *freebuf;
+       bool inputerr = FALSE;
        extern char *hvalue();
        extern bool isheader(), flusheol();
 
        extern char *hvalue();
        extern bool isheader(), flusheol();
 
@@ -79,7 +80,8 @@ collect(smtpmode, requeueflag, e)
        **  Create the temp file name and create the file.
        */
 
        **  Create the temp file name and create the file.
        */
 
-       e->e_df = newstr(queuename(e, 'd'));
+       e->e_df = queuename(e, 'd');
+       e->e_df = newstr(e->e_df);
        if ((tf = dfopen(e->e_df, O_WRONLY|O_CREAT, FileMode)) == NULL)
        {
                syserr("Cannot create %s", e->e_df);
        if ((tf = dfopen(e->e_df, O_WRONLY|O_CREAT, FileMode)) == NULL)
        {
                syserr("Cannot create %s", e->e_df);
@@ -158,7 +160,10 @@ collect(smtpmode, requeueflag, e)
                        if (sfgets(freebuf, MAXLINE, InChannel,
                                        TimeOuts.to_datablock,
                                        "message header read") == NULL)
                        if (sfgets(freebuf, MAXLINE, InChannel,
                                        TimeOuts.to_datablock,
                                        "message header read") == NULL)
-                               goto readerr;
+                       {
+                               freebuf[0] = '\0';
+                               break;
+                       }
 
                        /* is this a continuation line? */
                        if (*freebuf != ' ' && *freebuf != '\t')
 
                        /* is this a continuation line? */
                        if (*freebuf != ' ' && *freebuf != '\t')
@@ -244,7 +249,7 @@ collect(smtpmode, requeueflag, e)
        **  Collect the body of the message.
        */
 
        **  Collect the body of the message.
        */
 
-       do
+       for (;;)
        {
                register char *bp = buf;
 
        {
                register char *bp = buf;
 
@@ -255,7 +260,8 @@ collect(smtpmode, requeueflag, e)
                        break;
 
                /* check for transparent dot */
                        break;
 
                /* check for transparent dot */
-               if (OpMode == MD_SMTP && bp[0] == '.' && bp[1] == '.')
+               if ((OpMode == MD_SMTP || OpMode == MD_DAEMON) &&
+                   bp[0] == '.' && bp[1] == '.')
                        bp++;
 
                /*
                        bp++;
 
                /*
@@ -268,39 +274,64 @@ collect(smtpmode, requeueflag, e)
                fputs("\n", tf);
                if (ferror(tf))
                        tferror(tf, e);
                fputs("\n", tf);
                if (ferror(tf))
                        tferror(tf, e);
-       } while (sfgets(buf, MAXLINE, InChannel, TimeOuts.to_datablock,
-                       "message body read") != NULL);
+               if (sfgets(buf, MAXLINE, InChannel, TimeOuts.to_datablock,
+                               "message body read") == NULL)
+                       goto readerr;
+       }
 
 
+       if (feof(InChannel) || ferror(InChannel))
+       {
 readerr:
 readerr:
+               if (tTd(30, 1))
+                       printf("collect: read error\n");
+               inputerr = TRUE;
+       }
+
        if (fflush(tf) != 0)
                tferror(tf, e);
        if (fflush(tf) != 0)
                tferror(tf, e);
-       (void) fsync(fileno(tf));
-       (void) fclose(tf);
+       if (fsync(fileno(tf)) < 0 || fclose(tf) < 0)
+       {
+               syserr("cannot sync message data to disk (%s)", e->e_df);
+               finis();
+       }
 
        /* An EOF when running SMTP is an error */
 
        /* An EOF when running SMTP is an error */
-       if ((feof(InChannel) || ferror(InChannel)) && OpMode == MD_SMTP)
+       if (inputerr && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
        {
                char *host;
        {
                char *host;
+               char *problem;
 
                host = RealHostName;
                if (host == NULL)
                        host = "localhost";
 
 
                host = RealHostName;
                if (host == NULL)
                        host = "localhost";
 
+               if (feof(InChannel))
+                       problem = "unexpected close";
+               else if (ferror(InChannel))
+                       problem = "I/O error";
+               else
+                       problem = "read timeout";
 # ifdef LOG
                if (LogLevel > 0 && feof(InChannel))
                        syslog(LOG_NOTICE,
 # ifdef LOG
                if (LogLevel > 0 && feof(InChannel))
                        syslog(LOG_NOTICE,
-                           "collect: unexpected close on connection from %s, sender=%s: %m\n",
-                           host, e->e_from.q_paddr);
+                           "collect: %s on connection from %s, sender=%s: %m\n",
+                           problem, host, e->e_from.q_paddr);
 # endif
 # endif
-               (feof(InChannel) ? usrerr : syserr)
-                       ("451 collect: unexpected close on connection from %s, from=%s",
-                               host, e->e_from.q_paddr);
+               if (feof(InChannel))
+                       usrerr("451 collect: %s on connection from %s, from=%s",
+                               problem, host, e->e_from.q_paddr);
+               else
+                       syserr("451 collect: %s on connection from %s, from=%s",
+                               problem, host, e->e_from.q_paddr);
 
                /* don't return an error indication */
                e->e_to = NULL;
                e->e_flags &= ~EF_FATALERRS;
 
                /* don't return an error indication */
                e->e_to = NULL;
                e->e_flags &= ~EF_FATALERRS;
+               e->e_flags |= EF_CLRQUEUE;
 
                /* and don't try to deliver the partial message either */
 
                /* and don't try to deliver the partial message either */
+               if (InChild)
+                       ExitStat = EX_QUIT;
                finis();
        }
 
                finis();
        }
 
@@ -311,6 +342,10 @@ readerr:
 
        eatheader(e, !requeueflag);
 
 
        eatheader(e, !requeueflag);
 
+       /* collect statistics */
+       if (OpMode != MD_VERIFY)
+               markstats(e, (ADDRESS *) NULL);
+
        /*
        **  Add an Apparently-To: line if we have no recipient lines.
        */
        /*
        **  Add an Apparently-To: line if we have no recipient lines.
        */