logging
[exim.git] / src / src / receive.c
index 585cb902529fb8a600a67c0f0663f92509212a4a..c783cedfdebf3ad1ce14e1692e3fa621337770ab 100644 (file)
@@ -2,7 +2,7 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2015 */
+/* Copyright (c) University of Cambridge 1995 - 2016 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Code for receiving a message and setting up spool files. */
@@ -525,7 +525,7 @@ static void
 smtp_user_msg(uschar *code, uschar *user_msg)
 {
 int len = 3;
-smtp_message_code(&code, &len, &user_msg, NULL);
+smtp_message_code(&code, &len, &user_msg, NULL, TRUE);
 smtp_respond(code, len, TRUE, user_msg);
 }
 #endif
@@ -835,7 +835,15 @@ while ((ch = (receive_getc)()) != EOF)
       ch_state = 4;
       continue;
       }
-    ch_state = 1;                       /* The dot itself is removed */
+    /* The dot was removed at state 3. For a doubled dot, here, reinstate
+    it to cutthrough. The current ch, dot or not, is passed both to cutthrough
+    and to file below. */
+    if (ch == '.')
+      {
+      uschar c= ch;
+      (void) cutthrough_puts(&c, 1);
+      }
+    ch_state = 1;
     break;
 
     case 4:                             /* After [CR] LF . CR */
@@ -953,10 +961,12 @@ if (error_handling == ERRORS_SENDER)
   error_block eblock;
   eblock.next = NULL;
   eblock.text1 = text1;
+  eblock.text2 = US"";
   if (!moan_to_sender(errcode, &eblock, hptr, f, FALSE))
     error_rc = EXIT_FAILURE;
   }
-else fprintf(stderr, "exim: %s%s\n", text2, text1);  /* Sic */
+else
+  fprintf(stderr, "exim: %s%s\n", text2, text1);  /* Sic */
 (void)fclose(f);
 exim_exit(error_rc);
 }
@@ -1122,7 +1132,7 @@ if (sender_fullhost != NULL)
     {
     uschar *ss = string_sprintf(" I=[%s]:%d", interface_address,
       interface_port);
-    s = string_cat(s, sizeptr, ptrptr, ss, Ustrlen(ss));
+    s = string_cat(s, sizeptr, ptrptr, ss);
     }
   }
 if (sender_ident != NULL)
@@ -1279,10 +1289,12 @@ else if (rc != OK)
 #ifdef EXPERIMENTAL_DCC
   dcc_ok = 0;
 #endif
-  if (smtp_input && smtp_handle_acl_fail(ACL_WHERE_MIME, rc, user_msg, log_msg) != 0) {
-    *smtp_yield_ptr = FALSE;    /* No more messsages after dropped connection */
+  if (  smtp_input
+     && smtp_handle_acl_fail(ACL_WHERE_MIME, rc, user_msg, log_msg) != 0)
+    {
+    *smtp_yield_ptr = FALSE;    /* No more messages after dropped connection */
     *smtp_reply_ptr = US"";     /* Indicate reply already sent */
-  }
+    }
   message_id[0] = 0;            /* Indicate no message accepted */
   return FALSE;                 /* Cause skip to end of receive function */
   }
@@ -1306,7 +1318,7 @@ if (recipients_count == 1) received_for = recipients_list[0].address;
 received = expand_string(received_header_text);
 received_for = NULL;
 
-if (received == NULL)
+if (!received)
   {
   if(spool_name[0] != 0)
     Uunlink(spool_name);           /* Lose the data file */
@@ -2459,7 +2471,7 @@ it will fit. */
 to be the least significant base-62 digit of the time of arrival. Otherwise
 ensure that it is an empty string. */
 
-message_subdir[0] = split_spool_directory? message_id[5] : 0;
+message_subdir[0] = split_spool_directory ? message_id[5] : 0;
 
 /* Now that we have the message-id, if there is no message-id: header, generate
 one, but only for local (without suppress_local_fixups) or submission mode
@@ -2851,16 +2863,17 @@ to access it both via a file descriptor and a stream. Try to make the
 directory if it isn't there. Note re use of sprintf: spool_directory
 is checked on input to be < 200 characters long. */
 
-sprintf(CS spool_name, "%s/input/%s/%s-D", spool_directory, message_subdir,
-  message_id);
-data_fd = Uopen(spool_name, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE);
-if (data_fd < 0)
+snprintf(CS spool_name, sizeof(spool_name), "%s/input/%s/%s/%s-D",
+  spool_directory, queue_name, message_subdir, message_id);
+DEBUG(D_receive) debug_printf("Data file name: %s\n", spool_name);
+
+if ((data_fd = Uopen(spool_name, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE)) < 0)
   {
   if (errno == ENOENT)
     {
-    uschar temp[16];
-    sprintf(CS temp, "input/%s", message_subdir);
-    if (message_subdir[0] == 0) temp[5] = 0;
+    uschar * temp = string_sprintf("input%s%s%s%s",
+           *queue_name ? "/" : "", queue_name,
+           *message_subdir ? "/" : "", message_subdir);
     (void)directory_make(spool_directory, temp, INPUT_DIRECTORY_MODE, TRUE);
     data_fd = Uopen(spool_name, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE);
     }
@@ -3263,7 +3276,7 @@ else
             {
             Uunlink(spool_name);
             if (smtp_handle_acl_fail(ACL_WHERE_DKIM, rc, user_msg, log_msg) != 0)
-              smtp_yield = FALSE;    /* No more messsages after dropped connection */
+              smtp_yield = FALSE;    /* No more messages after dropped connection */
             smtp_reply = US"";       /* Indicate reply already sent */
             message_id[0] = 0;       /* Indicate no message accepted */
             goto TIDYUP;             /* Skip to end of function */
@@ -3381,7 +3394,7 @@ else
        dcc_ok = 0;
 #endif
         if (smtp_handle_acl_fail(ACL_WHERE_DATA, rc, user_msg, log_msg) != 0)
-          smtp_yield = FALSE;    /* No more messsages after dropped connection */
+          smtp_yield = FALSE;    /* No more messages after dropped connection */
         smtp_reply = US"";       /* Indicate reply already sent */
         message_id[0] = 0;       /* Indicate no message accepted */
         goto TIDYUP;             /* Skip to end of function */
@@ -3637,11 +3650,11 @@ signal(SIGINT, SIG_IGN);
 deliver_firsttime = TRUE;
 
 #ifdef EXPERIMENTAL_BRIGHTMAIL
-if (bmi_run == 1) {
-  /* rewind data file */
+if (bmi_run == 1)
+  /* rewind data file */
   lseek(data_fd, (long int)SPOOL_DATA_START_OFFSET, SEEK_SET);
   bmi_verdicts = bmi_process_message(header_list, data_fd);
-};
+  }
 #endif
 
 /* Update the timstamp in our Received: header to account for any time taken by
@@ -3679,7 +3692,6 @@ if (host_checking || blackholed_by != NULL)
 /* Write the -H file */
 
 else
-  {
   if ((msg_size = spool_write_header(message_id, SW_RECEIVING, &errmsg)) < 0)
     {
     log_write(0, LOG_MAIN, "Message abandoned: %s", errmsg);
@@ -3699,7 +3711,6 @@ else
       /* Does not return */
       }
     }
-  }
 
 
 /* The message has now been successfully received. */
@@ -3793,6 +3804,9 @@ if (LOGGING(8bitmime))
   s = string_append(s, &size, &sptr, 2, US" M8S=", big_buffer);
   }
 
+if (*queue_name)
+  s = string_append(s, &size, &sptr, 2, US" Q=", queue_name);
+
 /* If an addr-spec in a message-id contains a quoted string, it can contain
 any characters except " \ and CR and so in particular it can contain NL!
 Therefore, make sure we use a printing-characters only version for the log.
@@ -3847,15 +3861,16 @@ if (message_logs && blackholed_by == NULL)
   {
   int fd;
 
-  sprintf(CS spool_name, "%s/msglog/%s/%s", spool_directory, message_subdir,
-    message_id);
-  fd = Uopen(spool_name, O_WRONLY|O_APPEND|O_CREAT, SPOOL_MODE);
-
-  if (fd < 0 && errno == ENOENT)
+  snprintf(CS spool_name, sizeof(spool_name), "%s/msglog/%s/%s/%s",
+    spool_directory, queue_name, message_subdir, message_id);
+  
+  if (  (fd = Uopen(spool_name, O_WRONLY|O_APPEND|O_CREAT, SPOOL_MODE)) < 0
+     && errno == ENOENT
+     )
     {
-    uschar temp[16];
-    sprintf(CS temp, "msglog/%s", message_subdir);
-    if (message_subdir[0] == 0) temp[6] = 0;
+    uschar * temp = string_sprintf("msglog%s%s%s%s",
+                       *queue_name ? "/" : "", queue_name,
+                       *message_subdir ? "/" : "", message_subdir);
     (void)directory_make(spool_directory, temp, MSGLOG_DIRECTORY_MODE, TRUE);
     fd = Uopen(spool_name, O_WRONLY|O_APPEND|O_CREAT, SPOOL_MODE);
     }
@@ -3934,23 +3949,23 @@ if (smtp_input && sender_host_address != NULL && !sender_host_notsocket &&
       /* Re-use the log line workspace */
 
       sptr = 0;
-      s = string_cat(s, &size, &sptr, msg, Ustrlen(msg));
+      s = string_cat(s, &size, &sptr, msg);
       s = add_host_info_for_log(s, &size, &sptr);
       s[sptr] = 0;
       log_write(0, LOG_MAIN, "%s", s);
 
       /* Delete the files for this aborted message. */
 
-      sprintf(CS spool_name, "%s/input/%s/%s-D", spool_directory,
-        message_subdir, message_id);
+      snprintf(CS spool_name, sizeof(spool_name), "%s/input/%s/%s/%s-D",
+       spool_directory, queue_name, message_subdir, message_id);
       Uunlink(spool_name);
 
-      sprintf(CS spool_name, "%s/input/%s/%s-H", spool_directory,
-        message_subdir, message_id);
+      snprintf(CS spool_name, sizeof(spool_name), "%s/input/%s/%s/%s-H",
+       spool_directory, queue_name, message_subdir, message_id);
       Uunlink(spool_name);
 
-      sprintf(CS spool_name, "%s/msglog/%s/%s", spool_directory,
-        message_subdir, message_id);
+      snprintf(CS spool_name, sizeof(spool_name), "%s/msglog/%s/%s/%s",
+       spool_directory, queue_name, message_subdir, message_id);
       Uunlink(spool_name);
 
       goto TIDYUP;
@@ -3975,7 +3990,7 @@ for this message. */
 */
 if(cutthrough.fd >= 0)
   {
-  uschar * msg= cutthrough_finaldot(); /* Ask the target system to accept the messsage */
+  uschar * msg= cutthrough_finaldot(); /* Ask the target system to accept the message */
                                        /* Logging was done in finaldot() */
   switch(msg[0])
     {
@@ -4078,7 +4093,7 @@ if (smtp_input)
         {
         uschar *code = US"250";
         int len = 3;
-        smtp_message_code(&code, &len, &user_msg, NULL);
+        smtp_message_code(&code, &len, &user_msg, NULL, TRUE);
         smtp_respond(code, len, TRUE, user_msg);
         }
 
@@ -4106,14 +4121,14 @@ if (smtp_input)
       {
       case ACCEPTED: log_write(0, LOG_MAIN, "Completed");/* Delivery was done */
       case PERM_REJ: {                                 /* Delete spool files */
-             sprintf(CS spool_name, "%s/input/%s/%s-D", spool_directory,
-               message_subdir, message_id);
+             snprintf(CS spool_name, sizeof(spool_name), "%s/input/%s/%s/%s-D",
+               spool_directory, queue_name, message_subdir, message_id);
              Uunlink(spool_name);
-             sprintf(CS spool_name, "%s/input/%s/%s-H", spool_directory,
-               message_subdir, message_id);
+             snprintf(CS spool_name, sizeof(spool_name), "%s/input/%s/%s/%s-H",
+               spool_directory, queue_name, message_subdir, message_id);
              Uunlink(spool_name);
-             sprintf(CS spool_name, "%s/msglog/%s/%s", spool_directory,
-               message_subdir, message_id);
+             snprintf(CS spool_name, sizeof(spool_name), "%s/msglog/%s/%s/%s",
+               spool_directory, queue_name, message_subdir, message_id);
              Uunlink(spool_name);
              }
       case TMP_REJ: message_id[0] = 0;   /* Prevent a delivery from starting */