global queue_name
[users/jgh/exim.git] / src / src / queue.c
index c234ffe26fee7f620baadef53733ae966c65e573..c971790927475b39f17e2e647c5fbd33a8fed721 100644 (file)
@@ -1,10 +1,8 @@
-/* $Cambridge: exim/src/src/queue.c,v 1.8 2005/06/27 14:29:43 ph10 Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2005 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Functions that operate on the input queue. */
@@ -144,7 +142,8 @@ else i = subdiroffset;
 
 /* Set up prototype for the directory name. */
 
-sprintf(CS buffer, "%s/input", spool_directory);
+snprintf(CS buffer, sizeof(buffer), "%s/input/%s", spool_directory, queue_name);
+buffer[sizeof(buffer) - 3] = 0;
 subptr = Ustrlen(buffer);
 buffer[subptr+2] = 0;               /* terminator for lengthened name */
 
@@ -163,8 +162,8 @@ for (; i <= *subcount; i++)
     buffer[subptr+1] = subdirchar;
     }
 
-  dd = opendir(CS buffer);
-  if (dd == NULL) continue;
+  if (!(dd = opendir(CS buffer)))
+    continue;
 
   /* Now scan the directory. */
 
@@ -267,7 +266,8 @@ for (; i <= *subcount; i++)
     if (!split_spool_directory && count <= 2)
       {
       rmdir(CS buffer);
-      sprintf(CS big_buffer, "%s/msglog/%c", spool_directory, subdirchar);
+      sprintf(CS big_buffer, "%s/msglog/%s/%c",
+               spool_directory, queue_name, subdirchar);
       rmdir(CS big_buffer);
       }
     if (subdiroffset > 0) break;    /* Single sub-directory */
@@ -453,7 +453,8 @@ for (i  = (queue_run_in_order? -1 : 0);
       load_average = os_getloadavg();
       if (load_average > deliver_queue_load_max)
         {
-        log_write(0, LOG_MAIN, "abandon queue run (load %.2f, max %.2f)",
+        log_write(L_queue_run, LOG_MAIN, "Abandon queue run: %s (load %.2f, max %.2f)",
+          log_detail,
           (double)load_average/1000.0,
           (double)deliver_queue_load_max/1000.0);
         i = subcount;                 /* Don't process other directories */
@@ -477,8 +478,8 @@ for (i  = (queue_run_in_order? -1 : 0);
     /* Check that the message still exists */
 
     message_subdir[0] = f->dir_uschar;
-    sprintf(CS buffer, "%s/input/%s/%s", spool_directory, message_subdir,
-      f->text);
+    snprintf(CS buffer, sizeof(buffer), "%s/input/%s/%s/%s",
+      spool_directory, queue_name, message_subdir, f->text);
     if (Ustat(buffer, &statbuf) < 0) continue;
 
     /* There are some tests that require the reading of the header file. Ensure
@@ -651,7 +652,8 @@ for (i  = (queue_run_in_order? -1 : 0);
     the mere fact that read() unblocks is enough. */
 
     set_process_info("running queue: waiting for children of %d", pid);
-    (void)read(pfd[pipe_read], buffer, sizeof(buffer));
+    if (read(pfd[pipe_read], buffer, sizeof(buffer)) > 0)
+      log_write(0, LOG_MAIN|LOG_PANIC, "queue run: unexpected data on pipe");
     (void)close(pfd[pipe_read]);
     set_process_info("running queue");
 
@@ -842,8 +844,8 @@ for (; f != NULL; f = f->next)
     FILE *jread;
     struct stat statbuf;
 
-    sprintf(CS big_buffer, "%s/input/%s/%s", spool_directory, message_subdir,
-      f->text);
+    sprintf(CS big_buffer, "%s/input/%s/%s/%s",
+      spool_directory, queue_name, message_subdir, f->text);
     ptr = Ustrlen(big_buffer)-1;
     big_buffer[ptr] = 'D';
 
@@ -892,8 +894,8 @@ for (; f != NULL; f = f->next)
     if (save_errno == ERRNO_SPOOLFORMAT)
       {
       struct stat statbuf;
-      sprintf(CS big_buffer, "%s/input/%s/%s", spool_directory, message_subdir,
-        f->text);
+      sprintf(CS big_buffer, "%s/input/%s/%s/%s",
+        spool_directory, queue_name, message_subdir, f->text);
       if (Ustat(big_buffer, &statbuf) == 0)
         printf("*** spool format error: size=" OFF_T_FMT " ***",
           statbuf.st_size);
@@ -935,9 +937,9 @@ for (; f != NULL; f = f->next)
 *             Act on a specific message          *
 *************************************************/
 
-/* Actions that require a list of addresses make use of
-argv/argc/recipients_arg. Other actions do not. This function does its
-own authority checking.
+/* Actions that require a list of addresses make use of argv/argc/
+recipients_arg. Other actions do not. This function does its own
+authority checking.
 
 Arguments:
   id              id of the message to work on
@@ -1004,12 +1006,15 @@ if (action >= MSG_SHOW_BODY)
 
   for (i = 0; i < 2; i++)
     {
-    message_subdir[0] = (split_spool_directory == (i == 0))? id[5] : 0;
-    sprintf(CS spoolname, "%s/%s/%s/%s%s", spool_directory, subdirectory,
-      message_subdir, id, suffix);
-    fd = Uopen(spoolname, O_RDONLY, 0);
-    if (fd >= 0) break;
-    if (i == 0) continue;
+    message_subdir[0] = split_spool_directory == (i == 0) ? id[5] : 0;
+    snprintf(CS spoolname, sizeof(spoolname), "%s/%s/%s/%s/%s%s",
+             spool_directory, subdirectory, queue_name,
+             message_subdir, id, suffix);
+    if ((fd = Uopen(spoolname, O_RDONLY, 0)) >= 0)
+      break;
+    if (i == 0)
+      continue;
+
     printf("Failed to open %s file for %s%s: %s\n", subdirectory, id, suffix,
       strerror(errno));
     if (action == MSG_SHOW_LOG && !message_logs)
@@ -1019,7 +1024,7 @@ if (action >= MSG_SHOW_BODY)
     }
 
   while((rc = read(fd, big_buffer, big_buffer_size)) > 0)
-    (void)write(fileno(stdout), big_buffer, rc);
+    rc = write(fileno(stdout), big_buffer, rc);
 
   (void)close(fd);
   return TRUE;
@@ -1030,7 +1035,7 @@ other process is working on this message. If the file does not exist, continue
 only if the action is remove and the user is an admin user, to allow for
 tidying up broken states. */
 
-if (!spool_open_datafile(id))
+if ((deliver_datafile = spool_open_datafile(id)) < 0)
   {
   if (errno == ENOENT)
     {
@@ -1092,10 +1097,17 @@ username = (pw != NULL)?
 
 /* Take the necessary action. */
 
-printf("Message %s ", id);
+if (action != MSG_SHOW_COPY) printf("Message %s ", id);
 
 switch(action)
   {
+  case MSG_SHOW_COPY:
+  deliver_in_buffer = store_malloc(DELIVER_IN_BUFFER_SIZE);
+  deliver_out_buffer = store_malloc(DELIVER_OUT_BUFFER_SIZE);
+  transport_write_message(NULL, 1, 0, 0, NULL, NULL, NULL, NULL, NULL, 0);
+  break;
+
+
   case MSG_FREEZE:
   if (deliver_freeze)
     {
@@ -1155,7 +1167,8 @@ switch(action)
   message_subdir[0] = id[5];
   for (j = 0; j < 2; message_subdir[0] = 0, j++)
     {
-    sprintf(CS spoolname, "%s/msglog/%s/%s", spool_directory, message_subdir, id);
+    snprintf(CS spoolname, sizeof(spoolname), "%s/msglog/%s/%s/%s",
+      spool_directory, queue_name, message_subdir, id);
     if (Uunlink(spoolname) < 0)
       {
       if (errno != ENOENT)
@@ -1169,8 +1182,8 @@ switch(action)
 
     for (i = 0; i < 3; i++)
       {
-      sprintf(CS spoolname, "%s/input/%s/%s-%c", spool_directory, message_subdir,
-        id, "DHJ"[i]);
+      snprintf(CS spoolname, sizeof(spoolname), "%s/input/%s/%s/%s-%c",
+        spool_directory, queue_name, message_subdir, id, "DHJ"[i]);
       if (Uunlink(spoolname) < 0)
         {
         if (errno != ENOENT)
@@ -1267,6 +1280,9 @@ switch(action)
       {
       if (action == MSG_ADD_RECIPIENT)
         {
+#ifdef SUPPORT_I18N
+       if (string_is_utf8(recipient)) allow_utf8_domains = message_smtputf8 = TRUE;
+#endif
         receive_add_recipient(recipient, -1);
         log_write(0, LOG_MAIN, "recipient <%s> added by %s",
           recipient, username);
@@ -1290,6 +1306,9 @@ switch(action)
         }
       else  /* MSG_EDIT_SENDER */
         {
+#ifdef SUPPORT_I18N
+       if (string_is_utf8(recipient)) allow_utf8_domains = message_smtputf8 = TRUE;
+#endif
         sender_address = recipient;
         log_write(0, LOG_MAIN, "sender address changed to <%s> by %s",
           recipient, username);
@@ -1338,7 +1357,8 @@ queue_check_only(void)
 BOOL *set;
 int sep = 0;
 struct stat statbuf;
-uschar *s, *ss, *name;
+const uschar *s;
+uschar *ss, *name;
 uschar buffer[1024];
 
 if (queue_only_file == NULL) return;