ACL: merge the tables used for codition/modifier decode
[exim.git] / src / src / smtp_in.c
index 3144b39ad79d7ba688df0f85cd1d21d2bdcf4983..3b631ea100647c07e8bba5355abcb96d3977de24 100644 (file)
@@ -352,6 +352,15 @@ if (smtp_inptr >= smtp_inend)
 return *smtp_inptr++;
 }
 
+void
+smtp_get_cache(void)
+{
+#ifndef DISABLE_DKIM
+int n = smtp_inend - smtp_inptr;
+if (n > 0)
+  dkim_exim_verify_feed(smtp_inptr, n);
+#endif
+}
 
 
 /* Get a byte from the smtp input, in CHUNKING mode.  Handle ack of the
@@ -386,10 +395,14 @@ for(;;)
 
   /* If not the last, ack the received chunk.  The last response is delayed
   until after the data ACL decides on it */
-  /*XXX find that "last response" and append the chunk size */
 
   if (chunking_state == CHUNKING_LAST)
+    {
+#ifndef DISABLE_DKIM
+    dkim_exim_verify_feed(NULL, 0);    /* notify EOD */
+#endif
     return EOD;
+    }
 
   chunking_state = CHUNKING_OFFERED;
   smtp_printf("250 %u byte chunk received\r\n", chunking_datasize);
@@ -463,6 +476,20 @@ next_cmd:
   }
 }
 
+static void
+bdat_flush_data(void)
+{
+while (chunking_data_left-- > 0)
+  if (lwr_receive_getc() < 0)
+    break;
+
+receive_getc = lwr_receive_getc;
+receive_ungetc = lwr_receive_ungetc;
+
+if (chunking_state != CHUNKING_LAST)
+  chunking_state = CHUNKING_OFFERED;
+}
+
 
 
 
@@ -2022,10 +2049,10 @@ acl_var_c = NULL;
 
 /* Allow for trailing 0 in the command and data buffers. */
 
-smtp_cmd_buffer = (uschar *)malloc(2*smtp_cmd_buffer_size + 2);
-if (smtp_cmd_buffer == NULL)
+if (!(smtp_cmd_buffer = US malloc(2*smtp_cmd_buffer_size + 2)))
   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
     "malloc() failed for SMTP command buffer");
+
 smtp_cmd_buffer[0] = 0;
 smtp_data_buffer = smtp_cmd_buffer + smtp_cmd_buffer_size + 1;
 
@@ -2034,7 +2061,7 @@ command line by a trusted caller. */
 
 if (smtp_batched_input)
   {
-  if (received_protocol == NULL) received_protocol = US"local-bsmtp";
+  if (!received_protocol) received_protocol = US"local-bsmtp";
   }
 
 /* For non-batched SMTP input, the protocol setting is forced here. It will be
@@ -2047,10 +2074,11 @@ else
 /* Set up the buffer for inputting using direct read() calls, and arrange to
 call the local functions instead of the standard C ones. */
 
-smtp_inbuffer = (uschar *)malloc(in_buffer_size);
-if (smtp_inbuffer == NULL)
+if (!(smtp_inbuffer = (uschar *)malloc(in_buffer_size)))
   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "malloc() failed for SMTP input buffer");
+
 receive_getc = smtp_getc;
+receive_get_cache = smtp_get_cache;
 receive_ungetc = smtp_ungetc;
 receive_feof = smtp_feof;
 receive_ferror = smtp_ferror;
@@ -2933,8 +2961,9 @@ if (lognl != NULL) *lognl = 0;
 always a 5xx one - see comments at the start of this function. If the original
 rc was FAIL_DROP we drop the connection and yield 2. */
 
-if (rc == FAIL) smtp_respond(smtp_code, codelen, TRUE, (user_msg == NULL)?
-  US"Administrative prohibition" : user_msg);
+if (rc == FAIL)
+  smtp_respond(smtp_code, codelen, TRUE,
+    user_msg ? user_msg : US"Administrative prohibition");
 
 /* Send temporary failure response to the command. Don't give any details,
 unless acl_temp_details is set. This is TRUE for a callout defer, a "defer"
@@ -2945,21 +2974,19 @@ interactions between temp_details and return_error_details. One day it should
 be re-implemented in a tidier fashion. */
 
 else
-  {
-  if (acl_temp_details && user_msg != NULL)
+  if (acl_temp_details && user_msg)
     {
-    if (smtp_return_error_details &&
-        sender_verified_failed != NULL &&
-        sender_verified_failed->message != NULL)
-      {
+    if (  smtp_return_error_details
+       && sender_verified_failed
+       && sender_verified_failed->message
+       )
       smtp_respond(smtp_code, codelen, FALSE, sender_verified_failed->message);
-      }
+
     smtp_respond(smtp_code, codelen, TRUE, user_msg);
     }
   else
     smtp_respond(smtp_code, codelen, TRUE,
       US"Temporary local problem - please try later");
-  }
 
 /* Log the incident to the logs that are specified by log_reject_target
 (default main, reject). This can be empty to suppress logging of rejections. If
@@ -3043,12 +3070,11 @@ smtp_exit_function_called = TRUE;
 
 /* Call the not-QUIT ACL, if there is one, unless no reason is given. */
 
-if (acl_smtp_notquit != NULL && reason != NULL)
+if (acl_smtp_notquit && reason)
   {
   smtp_notquit_reason = reason;
-  rc = acl_check(ACL_WHERE_NOTQUIT, NULL, acl_smtp_notquit, &user_msg,
-    &log_msg);
-  if (rc == ERROR)
+  if ((rc = acl_check(ACL_WHERE_NOTQUIT, NULL, acl_smtp_notquit, &user_msg,
+                     &log_msg)) == ERROR)
     log_write(0, LOG_MAIN|LOG_PANIC, "ACL for not-QUIT returned ERROR: %s",
       log_msg);
   }
@@ -3058,9 +3084,11 @@ responses are all internal, they should always fit in the buffer, but code a
 warning, just in case. Note that string_vformat() still leaves a complete
 string, even if it is incomplete. */
 
-if (code != NULL && defaultrespond != NULL)
+if (code && defaultrespond)
   {
-  if (user_msg == NULL)
+  if (user_msg)
+    smtp_respond(code, 3, TRUE, user_msg);
+  else
     {
     uschar buffer[128];
     va_list ap;
@@ -3070,8 +3098,6 @@ if (code != NULL && defaultrespond != NULL)
     smtp_printf("%s %s\r\n", code, buffer);
     va_end(ap);
     }
-  else
-    smtp_respond(code, 3, TRUE, user_msg);
   mac_smtp_fflush();
   }
 }
@@ -4762,6 +4788,9 @@ while (done <= 0)
          smtp_connection_had[smtp_ch_index-1] == SCH_DATA
          ? US"valid RCPT command must precede DATA"
          : US"valid RCPT command must precede BDAT");
+
+      if (chunking_state > CHUNKING_OFFERED)
+       bdat_flush_data();
       break;
       }