debug tidying
[exim.git] / src / src / log.c
index 3fdcbbee9962b97ba45397313eed124c01e60b2a..2dd85c4842a19d94d49ba1ba8db038bfb9fdaa2b 100644 (file)
@@ -112,6 +112,7 @@ static const uschar * exim_errstrings[] = {
   US"Local-only delivery",
   US"Domain in queue_domains",
   US"Transport concurrency limit",
+  US"Event requests alternate response",
 };
 
 
@@ -142,7 +143,7 @@ Returns:         nothing
 static void
 write_syslog(int priority, const uschar *s)
 {
-int len, pass;
+int len;
 int linecount = 0;
 
 if (!syslog_pid && LOGGING(pid))
@@ -171,12 +172,10 @@ if (!syslog_open && !f.running_in_test_harness)
 /* First do a scan through the message in order to determine how many lines
 it is going to end up as. Then rescan to output it. */
 
-for (pass = 0; pass < 2; pass++)
+for (int pass = 0; pass < 2; pass++)
   {
-  int i;
-  int tlen;
   const uschar * ss = s;
-  for (i = 1, tlen = len; tlen > 0; i++)
+  for (int i = 1, tlen = len; tlen > 0; i++)
     {
     int plen = tlen;
     uschar *nlptr = Ustrchr(ss, '\n');
@@ -314,7 +313,7 @@ Returns:       a file descriptor, or < 0 on failure (errno set)
 int
 log_create_as_exim(uschar *name)
 {
-pid_t pid = fork();
+pid_t pid = exim_fork(US"logfile-create");
 int status = 1;
 int fd = -1;
 
@@ -511,7 +510,7 @@ non-setuid binary with log_arguments set, called in certain ways.) Rather than
 just bombing out, force the log to stderr and carry on if stderr is available.
 */
 
-if (euid != root_uid && euid != exim_uid && log_stderr != NULL)
+if (euid != root_uid && euid != exim_uid && log_stderr)
   {
   *fd = fileno(log_stderr);
   return;
@@ -520,7 +519,9 @@ if (euid != root_uid && euid != exim_uid && log_stderr != NULL)
 /* Otherwise this is a disaster. This call is deliberately ONLY to the panic
 log. If possible, save a copy of the original line that was being logged. If we
 are recursing (can't open the panic log either), the pointer will already be
-set. */
+set.  Also, when we had to use a subprocess for the create we didn't retrieve
+errno from it, so get the error from the open attempt above (which is often
+meaningful enough, so leave it). */
 
 if (!panic_save_buffer)
   if ((panic_save_buffer = US malloc(LOG_BUFFER_SIZE)))
@@ -736,7 +737,6 @@ Returns:    nothing
 void
 log_write(unsigned int selector, int flags, const char *format, ...)
 {
-uschar * ptr;
 int paniclogfd;
 ssize_t written_len;
 gstring gs = { .size = LOG_BUFFER_SIZE-1, .ptr = 0, .s = log_buffer };
@@ -867,9 +867,13 @@ DEBUG(D_any|D_v)
 
   if (flags & LOG_CONFIG) g = log_config_info(g, flags);
 
+  /* We want to be able to log tainted info, but log_buffer is directly
+  malloc'd.  So use deliberately taint-nonchecking routines to build into
+  it, trusting that we will never expand the results. */
+
   va_start(ap, format);
   i = g->ptr;
-  if (!string_vformat(g, FALSE, format, ap))
+  if (!string_vformat(g, SVFMT_TAINT_NOCHK, format, ap))
     {
     g->ptr = i;
     g = string_cat(g, US"**** log string overflowed log buffer ****");
@@ -923,7 +927,12 @@ if (flags & LOG_CONFIG)
 va_start(ap, format);
   {
   int i = g->ptr;
-  if (!string_vformat(g, FALSE, format, ap))
+
+  /* We want to be able to log tainted info, but log_buffer is directly
+  malloc'd.  So use deliberately taint-nonchecking routines to build into
+  it, trusting that we will never expand the results. */
+
+  if (!string_vformat(g, SVFMT_TAINT_NOCHK, format, ap))
     {
     g->ptr = i;
     g = string_cat(g, US"**** log string overflowed log buffer ****\n");
@@ -936,7 +945,7 @@ this way because it kind of fits with LOG_RECIPIENTS. */
 
 if (   flags & LOG_SENDER
    && g->ptr < LOG_BUFFER_SIZE - 10 - Ustrlen(raw_sender))
-  g = string_fmt_append(g, " from <%s>", raw_sender);
+  g = string_fmt_append_f(g, SVFMT_TAINT_NOCHK, " from <%s>", raw_sender);
 
 /* Add list of recipients to the message if required; the raw list,
 before rewriting, was saved in raw_recipients. There may be none, if an ACL
@@ -947,12 +956,12 @@ if (  flags & LOG_RECIPIENTS
    && raw_recipients_count > 0)
   {
   int i;
-  g = string_fmt_append(g, " for");
+  g = string_fmt_append_f(g, SVFMT_TAINT_NOCHK, " for", NULL);
   for (i = 0; i < raw_recipients_count; i++)
     {
     uschar * s = raw_recipients[i];
     if (LOG_BUFFER_SIZE - g->ptr < Ustrlen(s) + 3) break;
-    g = string_fmt_append(g, " %s", s);
+    g = string_fmt_append_f(g, SVFMT_TAINT_NOCHK, " %s", s);
     }
   }
 
@@ -1046,55 +1055,48 @@ headers. */
 
 if (flags & LOG_REJECT)
   {
-  header_line *h;
-
   if (header_list && LOGGING(rejected_header))
     {
-    uschar * p = g->s + g->ptr;
+    gstring * g2;
     int i;
 
     if (recipients_count > 0)
       {
       /* List the sender */
 
-      string_format(p, LOG_BUFFER_SIZE - g->ptr,
-        "Envelope-from: <%s>\n", sender_address);
-      while (*p) p++;
-      g->ptr = p - g->s;
+      g2 = string_fmt_append_f(g, SVFMT_TAINT_NOCHK,
+                       "Envelope-from: <%s>\n", sender_address);
+      if (g2) g = g2;
 
       /* List up to 5 recipients */
 
-      string_format(p, LOG_BUFFER_SIZE - g->ptr,
-        "Envelope-to: <%s>\n", recipients_list[0].address);
-      while (*p) p++;
-      g->ptr = p - g->s;
+      g2 = string_fmt_append_f(g, SVFMT_TAINT_NOCHK,
+                       "Envelope-to: <%s>\n", recipients_list[0].address);
+      if (g2) g = g2;
 
       for (i = 1; i < recipients_count && i < 5; i++)
         {
-        string_format(p, LOG_BUFFER_SIZE - g->ptr, "    <%s>\n",
-          recipients_list[i].address);
-       while (*p) p++;
-       g->ptr = p - g->s;
+        g2 = string_fmt_append_f(g, SVFMT_TAINT_NOCHK,
+                       "    <%s>\n", recipients_list[i].address);
+       if (g2) g = g2;
         }
 
       if (i < recipients_count)
         {
-        string_format(p, LOG_BUFFER_SIZE - g->ptr,
-          "    ...\n");
-       while (*p) p++;
-       g->ptr = p - g->s;
+        g2 = string_fmt_append_f(g, SVFMT_TAINT_NOCHK, "    ...\n", NULL);
+       if (g2) g = g2;
         }
       }
 
     /* A header with a NULL text is an unfilled in Received: header */
 
-    for (h = header_list; h; h = h->next) if (h->text)
+    for (header_line * h = header_list; h; h = h->next) if (h->text)
       {
-      BOOL fitted = string_format(p, LOG_BUFFER_SIZE - g->ptr,
-        "%c %s", h->type, h->text);
-      while (*p) p++;
-      g->ptr = p - g->s;
-      if (!fitted)         /* Buffer is full; truncate */
+      g2 = string_fmt_append_f(g, SVFMT_TAINT_NOCHK,
+                       "%c %s", h->type, h->text);
+      if (g2)
+       g = g2;
+      else             /* Buffer is full; truncate */
         {
         g->ptr -= 100;        /* For message and separator */
         if (g->s[g->ptr-1] == '\n') g->ptr--;