Fix support of $spam_ variables at delivery time. Bug 1647
[users/jgh/exim.git] / src / src / spool_mbox.c
index 69b0995ad190e13ba44601f5ef0bfe64d1cbb89d..8d04f8e17ea5f77030255c320a4c88de7c1ee1ab 100644 (file)
@@ -1,10 +1,8 @@
-/* $Cambridge: exim/src/src/spool_mbox.c,v 1.12 2006/09/12 10:35:56 ph10 Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003-???? */
+/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003 - 2015 */
 /* License: GPL */
 
 /* Code for setting up a MBOX style spool file inside a /scan/<msgid>
@@ -25,9 +23,12 @@ extern int spam_ok;
 int spool_mbox_ok = 0;
 uschar spooled_message_id[17];
 
-/* returns a pointer to the FILE, and puts the size in bytes into mbox_file_size */
+/* returns a pointer to the FILE, and puts the size in bytes into mbox_file_size
+ * normally, source_file_override is NULL */
 
-FILE *spool_mbox(unsigned long *mbox_file_size) {
+FILE *
+spool_mbox(unsigned long *mbox_file_size, const uschar *source_file_override)
+{
   uschar message_subdir[2];
   uschar buffer[16384];
   uschar *temp_string;
@@ -57,7 +58,7 @@ FILE *spool_mbox(unsigned long *mbox_file_size) {
     mbox_file = modefopen(mbox_path, "wb", SPOOL_MODE);
     if (mbox_file == NULL) {
       log_write(0, LOG_MAIN|LOG_PANIC, "%s", string_open_failed(errno,
-        "scan file %s", mbox_file));
+        "scan file %s", mbox_path));
       goto OUT;
     };
 
@@ -69,7 +70,7 @@ FILE *spool_mbox(unsigned long *mbox_file_size) {
     temp_string = expand_string(
       US"From ${if def:return_path{$return_path}{MAILER-DAEMON}} ${tod_bsdinbox}\n"
       "${if def:sender_address{X-Envelope-From: <${sender_address}>\n}}"
-      "${if def:received_for{X-Envelope-To: <${received_for}>\n}}");
+      "${if def:recipients{X-Envelope-To: ${recipients}\n}}");
 
     if (temp_string != NULL) {
       i = fwrite(temp_string, Ustrlen(temp_string), 1, mbox_file);
@@ -97,16 +98,24 @@ FILE *spool_mbox(unsigned long *mbox_file_size) {
     };
 
     /* End headers */
-    (void)fwrite("\n", 1, 1, mbox_file);
+    if (fwrite("\n", 1, 1, mbox_file) != 1) {
+      log_write(0, LOG_MAIN|LOG_PANIC, "Error/short write while writing \
+        message headers to %s", mbox_path);
+      goto OUT;
+    }
 
     /* copy body file */
-    message_subdir[1] = '\0';
-    for (i = 0; i < 2; i++) {
-      message_subdir[0] = (split_spool_directory == (i == 0))? message_id[5] : 0;
-      temp_string = string_sprintf("%s/input/%s/%s-D", spool_directory,
-        message_subdir, message_id);
-      data_file = Ufopen(temp_string, "rb");
-      if (data_file != NULL) break;
+    if (source_file_override == NULL) {
+      message_subdir[1] = '\0';
+      for (i = 0; i < 2; i++) {
+        message_subdir[0] = (split_spool_directory == (i == 0))? message_id[5] : 0;
+        temp_string = string_sprintf("%s/input/%s/%s-D", spool_directory,
+          message_subdir, message_id);
+        data_file = Ufopen(temp_string, "rb");
+        if (data_file != NULL) break;
+      };
+    } else {
+      data_file = Ufopen(source_file_override, "rb");
     };
 
     if (data_file == NULL) {
@@ -125,7 +134,8 @@ FILE *spool_mbox(unsigned long *mbox_file_size) {
      * explicitly, because the one in the file is parted of the locked area.
      */
 
-    (void)fseek(data_file, SPOOL_DATA_START_OFFSET, SEEK_SET);
+    if (!source_file_override)
+      (void)fseek(data_file, SPOOL_DATA_START_OFFSET, SEEK_SET);
 
     do {
       j = fread(buffer, 1, sizeof(buffer), data_file);
@@ -140,6 +150,9 @@ FILE *spool_mbox(unsigned long *mbox_file_size) {
       };
     } while (j > 0);
 
+    (void)fclose(mbox_file);
+    mbox_file = NULL;
+
     Ustrcpy(spooled_message_id, message_id);
     spool_mbox_ok = 1;
   };
@@ -148,7 +161,7 @@ FILE *spool_mbox(unsigned long *mbox_file_size) {
   if (Ustat(mbox_path, &statbuf) != 0 ||
       (yield = Ufopen(mbox_path,"rb")) == NULL) {
     log_write(0, LOG_MAIN|LOG_PANIC, "%s", string_open_failed(errno,
-      "scan file %s", mbox_file));
+      "scan file %s", mbox_path));
     goto OUT;
   };
 
@@ -185,6 +198,12 @@ void unspool_mbox(void) {
     mbox_path = string_sprintf("%s/scan/%s", spool_directory, spooled_message_id);
 
     tempdir = opendir(CS mbox_path);
+    if (!tempdir) {
+      debug_printf("Unable to opendir(%s): %s\n", mbox_path, strerror(errno));
+      /* Just in case we still can: */
+      rmdir(CS mbox_path);
+      return;
+    }
     /* loop thru dir & delete entries */
     while((entry = readdir(tempdir)) != NULL) {
       uschar *name = US entry->d_name;