214 spelling fixes
[exim.git] / src / src / receive.c
index 6a8ce884152a90924766e1ad2cb566f7760376f8..73713aa97f020f8c06ad39fed79be6004694ce17 100644 (file)
@@ -124,6 +124,7 @@ receive_statvfs(BOOL isspool, int *inodeptr)
 {
 #ifdef HAVE_STATFS
 struct STATVFS statbuf;
+struct stat dummy;
 uschar *path;
 uschar *name;
 uschar buffer[1024];
@@ -180,12 +181,18 @@ else
 memset(&statbuf, 0, sizeof(statbuf));
 
 if (STATVFS(CS path, &statbuf) != 0)
-  {
-  log_write(0, LOG_MAIN|LOG_PANIC, "cannot accept message: failed to stat "
-    "%s directory %s: %s", name, spool_directory, strerror(errno));
-  smtp_closedown(US"spool or log directory problem");
-  exim_exit(EXIT_FAILURE);
-  }
+  if (stat(CS path, &dummy) == -1 && errno == ENOENT)
+    {                          /* Can happen on first run after installation */
+    *inodeptr = -1;
+    return -1;
+    }
+  else
+    {
+    log_write(0, LOG_MAIN|LOG_PANIC, "cannot accept message: failed to stat "
+      "%s directory %s: %s", name, path, strerror(errno));
+    smtp_closedown(US"spool or log directory problem");
+    exim_exit(EXIT_FAILURE);
+    }
 
 *inodeptr = (statbuf.F_FILES > 0)? statbuf.F_FAVAIL : -1;
 
@@ -193,9 +200,9 @@ if (STATVFS(CS path, &statbuf) != 0)
 
 return (int)(((double)statbuf.F_BAVAIL * (double)statbuf.F_FRSIZE)/1024.0);
 
+#else
 /* Unable to find partition sizes in this environment. */
 
-#else
 *inodeptr = -1;
 return -1;
 #endif
@@ -986,6 +993,7 @@ handle_lost_connection(uschar *s)
 {
 log_write(L_lost_incoming_connection | L_smtp_connection, LOG_MAIN,
   "%s lost while reading message data%s", smtp_get_connection_info(), s);
+smtp_notquit_exit(US"connection-lost", NULL, NULL);
 return US"421 Lost incoming connection";
 }
 
@@ -1615,8 +1623,10 @@ message_linecount = body_linecount = body_zerocount =
   max_received_linelength = 0;
 
 #ifndef DISABLE_DKIM
-/* Call into DKIM to set up the context. */
-if (smtp_input && !smtp_batched_input && !dkim_disable_verify) dkim_exim_verify_init();
+/* Call into DKIM to set up the context.  In CHUNKING mode
+we clear the dot-stuffing flag */
+if (smtp_input && !smtp_batched_input && !dkim_disable_verify)
+  dkim_exim_verify_init(chunking_state <= CHUNKING_OFFERED);
 #endif
 
 #ifdef EXPERIMENTAL_DMARC
@@ -3728,7 +3738,7 @@ if (bmi_run == 1)
   }
 #endif
 
-/* Update the timstamp in our Received: header to account for any time taken by
+/* Update the timestamp in our Received: header to account for any time taken by
 an ACL or by local_scan(). The new time is the time that all reception
 processing is complete. */
 
@@ -3813,7 +3823,7 @@ string as required. Since we commonly want to add two items at a time, use a
 macro to simplify the coding. We log the arrival of a new message while the
 file is still locked, just in case the machine is *really* fast, and delivers
 it first! Include any message id that is in the message - since the syntax of a
-message id is actually an addr-spec, we can use the parse routine to canonicize
+message id is actually an addr-spec, we can use the parse routine to canonicalize
 it. */
 
 size = 256;
@@ -4017,14 +4027,14 @@ if (smtp_input && sender_host_address != NULL && !sender_host_notsocket &&
     int c = (receive_getc)();
     if (c != EOF) (receive_ungetc)(c); else
       {
-      uschar *msg = US"SMTP connection lost after final dot";
+      smtp_notquit_exit(US"connection-lost", NULL, NULL);
       smtp_reply = US"";    /* No attempt to send a response */
       smtp_yield = FALSE;   /* Nothing more on this connection */
 
       /* Re-use the log line workspace */
 
       sptr = 0;
-      s = string_cat(s, &size, &sptr, msg);
+      s = string_cat(s, &size, &sptr, US"SMTP connection lost after final dot");
       s = add_host_info_for_log(s, &size, &sptr);
       s[sptr] = 0;
       log_write(0, LOG_MAIN, "%s", s);
@@ -4048,8 +4058,9 @@ for this message. */
 
    Send dot onward.  If accepted, wipe the spooled files, log as delivered and accept
    the sender's dot (below).
-   If rejected: copy response to sender, wipe the spooled files, log approriately.
-   If temp-reject: accept to sender, keep the spooled files.
+   If rejected: copy response to sender, wipe the spooled files, log appropriately.
+   If temp-reject: normally accept to sender, keep the spooled file - unless defer=pass
+   in which case pass temp-reject back to initiator and dump the files.
 
    Having the normal spool files lets us do data-filtering, and store/forward on temp-reject.
 
@@ -4065,13 +4076,17 @@ if(cutthrough.fd >= 0)
       cutthrough_done = ACCEPTED;
       break;                                   /* message_id needed for SMTP accept below */
 
+    case '4':  /* Temp-reject. Keep spoolfiles and accept, unless defer-pass mode.
+               ... for which, pass back the exact error */
+      if (cutthrough.defer_pass) smtp_reply = string_copy_malloc(msg);
+      /*FALLTRHOUGH*/
+
     default:   /* Unknown response, or error.  Treat as temp-reject.         */
-    case '4':  /* Temp-reject. Keep spoolfiles and accept. */
       cutthrough_done = TMP_REJ;               /* Avoid the usual immediate delivery attempt */
       break;                                   /* message_id needed for SMTP accept below */
 
     case '5':  /* Perm-reject.  Do the same to the source.  Dump any spoolfiles */
-      smtp_reply= msg;         /* Pass on the exact error */
+      smtp_reply = string_copy_malloc(msg);            /* Pass on the exact error */
       cutthrough_done = PERM_REJ;
       break;
     }
@@ -4185,27 +4200,37 @@ if (smtp_input)
     /* smtp_reply is set non-empty */
 
     else if (smtp_reply[0] != 0)
-      {
       if (fake_response != OK && (smtp_reply[0] == '2'))
         smtp_respond((fake_response == DEFER)? US"450" : US"550", 3, TRUE,
           fake_response_text);
       else
         smtp_printf("%.1024s\r\n", smtp_reply);
-      }
 
     switch (cutthrough_done)
       {
-      case ACCEPTED: log_write(0, LOG_MAIN, "Completed");/* Delivery was done */
+      case ACCEPTED:
+       log_write(0, LOG_MAIN, "Completed");/* Delivery was done */
       case PERM_REJ:
-             {                                          /* Delete spool files */
-             Uunlink(spool_fname(US"input", message_subdir, message_id, US"-D"));
-             Uunlink(spool_fname(US"input", message_subdir, message_id, US"-H"));
-             Uunlink(spool_fname(US"msglog", message_subdir, message_id, US""));
-             }
-      case TMP_REJ: message_id[0] = 0;   /* Prevent a delivery from starting */
-      default:break;
+                                                        /* Delete spool files */
+       Uunlink(spool_fname(US"input", message_subdir, message_id, US"-D"));
+       Uunlink(spool_fname(US"input", message_subdir, message_id, US"-H"));
+       Uunlink(spool_fname(US"msglog", message_subdir, message_id, US""));
+       message_id[0] = 0;        /* Prevent a delivery from starting */
+       break;
+
+      case TMP_REJ:
+       if (cutthrough.defer_pass)
+         {
+         Uunlink(spool_fname(US"input", message_subdir, message_id, US"-D"));
+         Uunlink(spool_fname(US"input", message_subdir, message_id, US"-H"));
+         Uunlink(spool_fname(US"msglog", message_subdir, message_id, US""));
+         }
+       message_id[0] = 0;        /* Prevent a delivery from starting */
+      default:
+       break;
       }
     cutthrough.delivery = FALSE;
+    cutthrough.defer_pass = FALSE;
     }
 
   /* For batched SMTP, generate an error message on failure, and do