constification
[exim.git] / src / src / moan.c
index 31d033c1adcf66ed51c9ad65307212fea66804a5..c2e38d4f76e60ebb2ced6eaf9381592749b13ca0 100644 (file)
@@ -2,8 +2,10 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
+/* Copyright (c) The Exim Maintainers 2020 - 2023 */
 /* Copyright (c) University of Cambridge 1995 - 2018 */
 /* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
 
 /* Functions for sending messages to sender or to mailmaster. */
 
@@ -63,7 +65,7 @@ if (!message_id)
     if (h->type == htype_id)
       {
       message_id = Ustrchr(h->text, ':') + 1;
-      while (isspace(*message_id)) message_id++;
+      Uskip_whitespace(&message_id);
       }
 
 for (h = header_list; h; h = h->next)
@@ -78,28 +80,48 @@ if (!h)
 /* We limit the total length of references.  Although there is no fixed
 limit, some systems do not like headers growing beyond recognition.
 Keep the first message ID for the thread root and the last few for
-the position inside the thread, up to a maximum of 12 altogether. */
+the position inside the thread, up to a maximum of 12 altogether.
+Also apply the max line length limit from RFC 2822 2.1.1
+
+XXX preferably we would get any limit from the outbound transport,
+passed in here for a limit value.
+*/
 
 if (h || message_id)
   {
-  fprintf(fp, "References:");
+  unsigned use = fprintf(fp, "References:");
+  if (message_id) use += Ustrlen(message_id) + 1;
   if (h)
     {
-    uschar * s, * id, * error;
+    const uschar * s;
+    uschar * id, * error;
     uschar * referenced_ids[12];
     int reference_count = 0;
 
     s = Ustrchr(h->text, ':') + 1;
     f.parse_allow_group = FALSE;
     while (*s && (s = parse_message_id(s, &id, &error)))
-      if (reference_count == nelem(referenced_ids))
-        {
-        memmove(referenced_ids + 1, referenced_ids + 2,
-           sizeof(referenced_ids) - 2*sizeof(uschar *));
-        referenced_ids[reference_count - 1] = id;
-        }
+      {
+      unsigned this = Ustrlen(id);
+      if (  reference_count == nelem(referenced_ids)
+        || use + this + reference_count > 998
+         )
+       {
+       if (reference_count > 1)
+         {
+         /* drop position 1 and shuffle down */
+         use -= Ustrlen(referenced_ids + 1);
+         memmove(referenced_ids + 1, referenced_ids + 2,
+            sizeof(referenced_ids) - 2*sizeof(*referenced_ids));
+
+         /* append new one */
+         referenced_ids[reference_count - 1] = id;
+         }
+       }
       else
        referenced_ids[reference_count++] = id;
+      use += this;
+      }
 
     for (int i = 0; i < reference_count; ++i)
       fprintf(fp, " %s", referenced_ids[i]);
@@ -136,8 +158,8 @@ Returns:         TRUE if message successfully sent
 */
 
 BOOL
-moan_send_message(uschar *recipient, int ident, error_block *eblock,
-  header_line *headers, FILE *message_file, uschar *firstline)
+moan_send_message(const uschar * recipient, int ident, error_block * eblock,
+  header_line * headers, FILE * message_file, uschar * firstline)
 {
 int written = 0;
 int fd;
@@ -160,15 +182,16 @@ if (  ident == ERRMESS_DMARC_FORENSIC
    && (s2 = expand_string(string_sprintf("${address:%s}", s)))
    && *s2
    )
-  pid = child_open_exim2(&fd, s2, bounce_sender_authentication);
+  pid = child_open_exim2(&fd, s2, bounce_sender_authentication,
+               US"moan_send_message");
 else
   {
   s = NULL;
-  pid = child_open_exim(&fd);
+  pid = child_open_exim(&fd, US"moan_send_message");
   }
 
 #else
-pid = child_open_exim(&fd);
+pid = child_open_exim(&fd, US"moan_send_message");
 #endif
 
 if (pid < 0)
@@ -383,7 +406,7 @@ if (bounce_return_message)
   if (bounce_return_body && message_file)
     {
     BOOL enddot = f.dot_ends && message_file == stdin;
-    uschar * buf = store_get(bounce_return_linesize_limit+2, TRUE);
+    uschar * buf = store_get(bounce_return_linesize_limit+2, GET_TAINTED);
 
     if (firstline) fprintf(fp, "%s", CS firstline);
 
@@ -584,7 +607,7 @@ moan_tell_someone(uschar *who, address_item *addr,
 FILE *f;
 va_list ap;
 int fd;
-int pid = child_open_exim(&fd);
+int pid = child_open_exim(&fd, US"moan_tell_someone");
 
 if (pid < 0)
   {
@@ -608,7 +631,7 @@ if (addr)
   fprintf(f, "\nThe following address(es) have yet to be delivered:\n");
   for (; addr; addr = addr->next)
     {
-    uschar * parent = addr->parent ? addr->parent->address : NULL;
+    const uschar * parent = addr->parent ? addr->parent->address : NULL;
     fprintf(f, "  %s", addr->address);
     if (parent) fprintf(f, " <%s>", parent);
     if (addr->basic_errno > 0) fprintf(f, ": %s", strerror(addr->basic_errno));
@@ -691,7 +714,7 @@ fprintf(stderr, "%d previous message%s successfully processed.\n",
 
 fprintf(stderr, "The rest of the batch was abandoned.\n");
 
-exim_exit(yield, US"batch");
+exim_exit(yield);
 }
 
 
@@ -711,28 +734,28 @@ Returns:    additional recipient list or NULL
 */
 
 uschar *
-moan_check_errorcopy(uschar *recipient)
+moan_check_errorcopy(const uschar * recipient)
 {
-uschar *item, *localpart, *domain;
-const uschar *listptr = errors_copy;
+uschar * item;
+const uschar * localpart, * domain;
+const uschar * listptr = errors_copy;
 uschar *yield = NULL;
-uschar buffer[256];
 int sep = 0;
 int llen;
 
-if (errors_copy == NULL) return NULL;
+if (!errors_copy) return NULL;
 
 /* Set up pointer to the local part and domain, and compute the
 length of the local part. */
 
 localpart = recipient;
 domain = Ustrrchr(recipient, '@');
-if (domain == NULL) return NULL;  /* should not occur, but avoid crash */
+if (!domain) return NULL;      /* should not occur, but avoid crash */
 llen = domain++ - recipient;
 
 /* Scan through the configured items */
 
-while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer))))
+while ((item = string_nextinlist(&listptr, &sep, NULL, 0)))
   {
   const uschar *newaddress = item;
   const uschar *pattern = string_dequote(&newaddress);
@@ -820,7 +843,7 @@ if (!(s = expand_string(syntax_errors_to)))
 /* If we can't create a process to send the message, just forget about
 it. */
 
-pid = child_open_exim(&fd);
+pid = child_open_exim(&fd, US"moan_skipped_syntax_errors");
 
 if (pid < 0)
   {