Close notifier socket before re-exec of daemon. Bug 2539
[exim.git] / src / src / deliver.c
index 8c05934483a10d183cae2aedfc12bf7bded28e9a..5c5167b3a94f42b5e9139afd2a30be14284a1ec8 100644 (file)
@@ -220,7 +220,9 @@ if (!addr->next)
 
   deliver_localpart = addr->local_part;
   deliver_localpart_prefix = addr->prefix;
+  deliver_localpart_prefix_v = addr->prefix_v;
   deliver_localpart_suffix = addr->suffix;
+  deliver_localpart_suffix_v = addr->suffix_v;
 
   for (addr_orig = addr; addr_orig->parent; addr_orig = addr_orig->parent) ;
   deliver_domain_orig = addr_orig->domain;
@@ -260,7 +262,9 @@ if (!addr->next)
       else if (deliver_localpart[0] == '|') address_pipe = addr->local_part;
       deliver_localpart = addr->parent->local_part;
       deliver_localpart_prefix = addr->parent->prefix;
+      deliver_localpart_prefix_v = addr->parent->prefix_v;
       deliver_localpart_suffix = addr->parent->suffix;
+      deliver_localpart_suffix_v = addr->parent->suffix_v;
       }
     }
 
@@ -429,7 +433,7 @@ for (address_item * addr2 = addr->next; addr2; addr2 = addr2->next)
   addr2->transport_return = addr->transport_return;
   addr2->basic_errno =     addr->basic_errno;
   addr2->more_errno =      addr->more_errno;
-  addr2->delivery_usec =    addr->delivery_usec;
+  addr2->delivery_time =    addr->delivery_time;
   addr2->special_action =   addr->special_action;
   addr2->message =         addr->message;
   addr2->user_message =            addr->user_message;
@@ -1264,10 +1268,7 @@ if (LOGGING(queue_time))
     string_timesince(&received_time));
 
 if (LOGGING(deliver_time))
-  {
-  struct timeval diff = {.tv_sec = addr->more_errno, .tv_usec = addr->delivery_usec};
-  g = string_append(g, 2, US" DT=", string_timediff(&diff));
-  }
+  g = string_append(g, 2, US" DT=", string_timediff(&addr->delivery_time));
 
 /* string_cat() always leaves room for the terminator. Release the
 store we used to build the line after writing it. */
@@ -1335,6 +1336,9 @@ if (addr->host_used)
     }
   }
 
+if (LOGGING(deliver_time))
+  g = string_append(g, 2, US" DT=", string_timediff(&addr->delivery_time));
+
 if (addr->message)
   g = string_append(g, 2, US": ", addr->message);
 
@@ -1414,6 +1418,9 @@ if (addr->basic_errno > 0)
 if (addr->message)
   g = string_append(g, 2, US": ", addr->message);
 
+if (LOGGING(deliver_time))
+  g = string_append(g, 2, US" DT=", string_timediff(&addr->delivery_time));
+
 (void) string_from_gstring(g);
 
 /* Do the logging. For the message log, "routing failed" for those cases,
@@ -2402,14 +2409,14 @@ if ((pid = fork()) == 0)
     uschar *s;
     int ret;
 
-    if(  (ret = os_pipe_write(pfd[pipe_write], &addr2->transport_return, sizeof(int))) != sizeof(int)
-      || (ret = os_pipe_write(pfd[pipe_write], &transport_count, sizeof(transport_count))) != sizeof(transport_count)
-      || (ret = os_pipe_write(pfd[pipe_write], &addr2->flags, sizeof(addr2->flags))) != sizeof(addr2->flags)
-      || (ret = os_pipe_write(pfd[pipe_write], &addr2->basic_errno,    sizeof(int))) != sizeof(int)
-      || (ret = os_pipe_write(pfd[pipe_write], &addr2->more_errno,     sizeof(int))) != sizeof(int)
-      || (ret = os_pipe_write(pfd[pipe_write], &addr2->delivery_usec,  sizeof(int))) != sizeof(int)
-      || (ret = os_pipe_write(pfd[pipe_write], &addr2->special_action, sizeof(int))) != sizeof(int)
-      || (ret = os_pipe_write(pfd[pipe_write], &addr2->transport,
+    if(  (ret = write(pfd[pipe_write], &addr2->transport_return, sizeof(int))) != sizeof(int)
+      || (ret = write(pfd[pipe_write], &transport_count, sizeof(transport_count))) != sizeof(transport_count)
+      || (ret = write(pfd[pipe_write], &addr2->flags, sizeof(addr2->flags))) != sizeof(addr2->flags)
+      || (ret = write(pfd[pipe_write], &addr2->basic_errno,    sizeof(int))) != sizeof(int)
+      || (ret = write(pfd[pipe_write], &addr2->more_errno,     sizeof(int))) != sizeof(int)
+      || (ret = write(pfd[pipe_write], &addr2->delivery_time,  sizeof(struct timeval))) != sizeof(struct timeval)
+      || (ret = write(pfd[pipe_write], &addr2->special_action, sizeof(int))) != sizeof(int)
+      || (ret = write(pfd[pipe_write], &addr2->transport,
         sizeof(transport_instance *))) != sizeof(transport_instance *)
 
     /* For a file delivery, pass back the local part, in case the original
@@ -2417,8 +2424,8 @@ if ((pid = fork()) == 0)
     logging. */
 
       || (testflag(addr2, af_file)
-          && (  (ret = os_pipe_write(pfd[pipe_write], &local_part_length, sizeof(int))) != sizeof(int)
-             || (ret = os_pipe_write(pfd[pipe_write], addr2->local_part, local_part_length)) != local_part_length
+          && (  (ret = write(pfd[pipe_write], &local_part_length, sizeof(int))) != sizeof(int)
+             || (ret = write(pfd[pipe_write], addr2->local_part, local_part_length)) != local_part_length
             )
         )
       )
@@ -2430,8 +2437,8 @@ if ((pid = fork()) == 0)
     for (i = 0, s = addr2->message; i < 2; i++, s = addr2->user_message)
       {
       int message_length = s ? Ustrlen(s) + 1 : 0;
-      if(  (ret = os_pipe_write(pfd[pipe_write], &message_length, sizeof(int))) != sizeof(int)
-        || message_length > 0  && (ret = os_pipe_write(pfd[pipe_write], s, message_length)) != message_length
+      if(  (ret = write(pfd[pipe_write], &message_length, sizeof(int))) != sizeof(int)
+        || message_length > 0  && (ret = write(pfd[pipe_write], s, message_length)) != message_length
        )
         log_write(0, LOG_MAIN|LOG_PANIC, "Failed writing transport results to pipe: %s",
          ret == -1 ? strerror(errno) : "short write");
@@ -2464,26 +2471,26 @@ will remain. Afterwards, close the reading end. */
 
 for (addr2 = addr; addr2; addr2 = addr2->next)
   {
-  if ((len = os_pipe_read(pfd[pipe_read], &status, sizeof(int))) > 0)
+  if ((len = read(pfd[pipe_read], &status, sizeof(int))) > 0)
     {
     int i;
     uschar **sptr;
 
     addr2->transport_return = status;
-    len = os_pipe_read(pfd[pipe_read], &transport_count,
+    len = read(pfd[pipe_read], &transport_count,
       sizeof(transport_count));
-    len = os_pipe_read(pfd[pipe_read], &addr2->flags, sizeof(addr2->flags));
-    len = os_pipe_read(pfd[pipe_read], &addr2->basic_errno,    sizeof(int));
-    len = os_pipe_read(pfd[pipe_read], &addr2->more_errno,     sizeof(int));
-    len = os_pipe_read(pfd[pipe_read], &addr2->delivery_usec,  sizeof(int));
-    len = os_pipe_read(pfd[pipe_read], &addr2->special_action, sizeof(int));
-    len = os_pipe_read(pfd[pipe_read], &addr2->transport,
+    len = read(pfd[pipe_read], &addr2->flags, sizeof(addr2->flags));
+    len = read(pfd[pipe_read], &addr2->basic_errno,    sizeof(int));
+    len = read(pfd[pipe_read], &addr2->more_errno,     sizeof(int));
+    len = read(pfd[pipe_read], &addr2->delivery_time,  sizeof(struct timeval));
+    len = read(pfd[pipe_read], &addr2->special_action, sizeof(int));
+    len = read(pfd[pipe_read], &addr2->transport,
       sizeof(transport_instance *));
 
     if (testflag(addr2, af_file))
       {
       int llen;
-      if (  os_pipe_read(pfd[pipe_read], &llen, sizeof(int)) != sizeof(int)
+      if (  read(pfd[pipe_read], &llen, sizeof(int)) != sizeof(int)
         || llen > 64*4 /* limit from rfc 5821, times I18N factor */
          )
        {
@@ -2493,7 +2500,7 @@ for (addr2 = addr; addr2; addr2 = addr2->next)
        }
       /* sanity-checked llen so disable the Coverity error */
       /* coverity[tainted_data] */
-      if (os_pipe_read(pfd[pipe_read], big_buffer, llen) != llen)
+      if (read(pfd[pipe_read], big_buffer, llen) != llen)
        {
        log_write(0, LOG_MAIN|LOG_PANIC, "bad local_part read"
          " from delivery subprocess");
@@ -2506,10 +2513,10 @@ for (addr2 = addr; addr2; addr2 = addr2->next)
     for (i = 0, sptr = &addr2->message; i < 2; i++, sptr = &addr2->user_message)
       {
       int message_length;
-      len = os_pipe_read(pfd[pipe_read], &message_length, sizeof(int));
+      len = read(pfd[pipe_read], &message_length, sizeof(int));
       if (message_length > 0)
         {
-        len = os_pipe_read(pfd[pipe_read], big_buffer, message_length);
+        len = read(pfd[pipe_read], big_buffer, message_length);
        big_buffer[big_buffer_size-1] = '\0';           /* guard byte */
         if (len > 0) *sptr = string_copy(big_buffer);
         }
@@ -3129,11 +3136,7 @@ while (addr_local)
 
     /* Done with this address */
 
-    if (result == OK)
-      {
-      addr2->more_errno = deliver_time.tv_sec;
-      addr2->delivery_usec = deliver_time.tv_usec;
-      }
+    addr2->delivery_time = deliver_time;
     post_process_one(addr2, result, logflags, EXIM_DTYPE_TRANSPORT, logchar);
 
     /* If a pipe delivery generated text to be sent back, the result may be
@@ -3607,8 +3610,8 @@ while (!done)
          ptr += sizeof(addr->basic_errno);
          memcpy(&addr->more_errno, ptr, sizeof(addr->more_errno));
          ptr += sizeof(addr->more_errno);
-         memcpy(&addr->delivery_usec, ptr, sizeof(addr->delivery_usec));
-         ptr += sizeof(addr->delivery_usec);
+         memcpy(&addr->delivery_time, ptr, sizeof(addr->delivery_time));
+         ptr += sizeof(addr->delivery_time);
          memcpy(&addr->flags, ptr, sizeof(addr->flags));
          ptr += sizeof(addr->flags);
          addr->message = *ptr ? string_copy(ptr) : NULL;
@@ -4147,7 +4150,7 @@ if (PIPE_HEADER_SIZE != snprintf(CS pipe_header, PIPE_HEADER_SIZE+1, "%c%c%05ld"
 DEBUG(D_deliver) debug_printf("header write id:%c,subid:%c,size:%ld,final:%s\n",
                                  id, subid, (long)size, pipe_header);
 
-if ((ret = os_pipe_writev(fd, iov, 2)) != total_len)
+if ((ret = writev(fd, iov, 2)) != total_len)
   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
     "Failed writing transport result to pipe (%ld of %ld bytes): %s",
     (long)ret, (long)total_len, ret == -1 ? strerror(errno) : "short write");
@@ -4643,6 +4646,7 @@ all pipes, so I do not see a reason to use non-blocking IO here
 
   search_tidyup();
 
+  DEBUG(D_deliver) debug_printf("forking transport process\n");
   if ((pid = fork()) == 0)
     {
     int fd = pfd[pipe_write];
@@ -4924,8 +4928,8 @@ all pipes, so I do not see a reason to use non-blocking IO here
       ptr += sizeof(addr->basic_errno);
       memcpy(ptr, &addr->more_errno, sizeof(addr->more_errno));
       ptr += sizeof(addr->more_errno);
-      memcpy(ptr, &addr->delivery_usec, sizeof(addr->delivery_usec));
-      ptr += sizeof(addr->delivery_usec);
+      memcpy(ptr, &addr->delivery_time, sizeof(addr->delivery_time));
+      ptr += sizeof(addr->delivery_time);
       memcpy(ptr, &addr->flags, sizeof(addr->flags));
       ptr += sizeof(addr->flags);
 
@@ -4973,6 +4977,7 @@ all pipes, so I do not see a reason to use non-blocking IO here
     (void)close(fd);
     exit(EXIT_SUCCESS);
     }
+  DEBUG(D_deliver) debug_printf("forked transport process (%d)\n", pid);
 
   /* Back in the mainline: close the unwanted half of the pipe. */