Copyright updates:
[exim.git] / src / src / header.c
index dd82b2b699f5a99d65052b86511c9ba1ccd77359..cf7a81296f74c2c05a3266cfea5f131567f5393c 100644 (file)
@@ -3,6 +3,7 @@
 *************************************************/
 
 /* Copyright (c) University of Cambridge 1995 - 2016 */
+/* Copyright (c) The Exim Maintainers 2020 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 
@@ -86,34 +87,36 @@ Arguments:
   format    sprintf format
   ap        va_list value for format arguments
 
-Returns:    nothing
+Returns:    pointer to header struct (last one, if multiple added)
 */
 
-static void
+static header_line *
 header_add_backend(BOOL after, uschar *name, BOOL topnot, int type,
   const char *format, va_list ap)
 {
-header_line *h, *new;
+header_line *h, *new = NULL;
 header_line **hptr;
 
 uschar *p, *q;
-uschar buffer[HEADER_ADD_BUFFER_SIZE];
-gstring gs = { .size = HEADER_ADD_BUFFER_SIZE, .ptr = 0, .s = buffer };
+uschar * buf = store_get(HEADER_ADD_BUFFER_SIZE, FALSE);
+gstring gs = { .size = HEADER_ADD_BUFFER_SIZE, .ptr = 0, .s = buf };
 
-if (!header_last) return;
+if (!header_last) return NULL;
 
-if (!string_vformat(&gs, FALSE, format, ap))
+if (!string_vformat(&gs, SVFMT_REBUFFER, format, ap))
   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "string too long in header_add: "
     "%.100s ...", string_from_gstring(&gs));
+
+if (gs.s != buf) store_release_above(buf);
+gstring_release_unused(&gs);
 string_from_gstring(&gs);
 
 /* Find where to insert this header */
 
 if (!name)
-  {
   if (after)
     {
-    hptr = &(header_last->next);
+    hptr = &header_last->next;
     h = NULL;
     }
   else
@@ -128,7 +131,6 @@ if (!name)
       hptr = &header_list->next;
     h = *hptr;
     }
-  }
 
 else
   {
@@ -159,7 +161,7 @@ else
     for (;;)
       {
       if (!h->next || !header_testname(h, name, len, FALSE)) break;
-      hptr = &(h->next);
+      hptr = &h->next;
       h = h->next;
       }
   }
@@ -168,7 +170,7 @@ else
 point, we have hptr pointing to the link field that will point to the new
 header, and h containing the following header, or NULL. */
 
-for (p = q = buffer; *p != 0; )
+for (p = q = gs.s; *p; p = q)
   {
   for (;;)
     {
@@ -177,18 +179,18 @@ for (p = q = buffer; *p != 0; )
     if (*(++q) != ' ' && *q != '\t') break;
     }
 
-  new = store_get(sizeof(header_line));
+  new = store_get(sizeof(header_line), FALSE);
   new->text = string_copyn(p, q - p);
   new->slen = q - p;
   new->type = type;
   new->next = h;
 
   *hptr = new;
-  hptr = &(new->next);
+  hptr = &new->next;
 
   if (!h) header_last = new;
-  p = q;
   }
+return new;
 }
 
 
@@ -206,20 +208,32 @@ Arguments:
   format    sprintf format
   ...       format arguments
 
-Returns:    nothing
+Returns:    pointer to header struct added
 */
 
-void
-header_add_at_position(BOOL after, uschar *name, BOOL topnot, int type,
+header_line *
+header_add_at_position_internal(BOOL after, uschar *name, BOOL topnot, int type,
   const char *format, ...)
 {
+header_line * h;
 va_list ap;
 va_start(ap, format);
-header_add_backend(after, name, topnot, type, format, ap);
+h = header_add_backend(after, name, topnot, type, format, ap);
 va_end(ap);
+return h;
 }
 
 
+/* Documented external i/f for local_scan */
+void
+header_add_at_position(BOOL after, uschar *name, BOOL topnot, int type,
+  const char *format, ...)
+{
+va_list ap;
+va_start(ap, format);
+(void) header_add_backend(after, name, topnot, type, format, ap);
+va_end(ap);
+}
 
 /*************************************************
 *            Add new header on end of chain      *
@@ -240,7 +254,7 @@ header_add(int type, const char *format, ...)
 {
 va_list ap;
 va_start(ap, format);
-header_add_backend(TRUE, NULL, FALSE, type, format, ap);
+(void) header_add_backend(TRUE, NULL, FALSE, type, format, ap);
 va_end(ap);
 }
 
@@ -308,9 +322,8 @@ while (bot < top)
 
   if (c == 0)
     {
-    uschar *s = text + mid->len;
-    while (isspace(*s)) s++;
-    if (*s == ':')
+    uschar * s = text + mid->len;
+    if (Uskip_whitespace(&s) == ':')
       return (!is_resent || mid->allow_resent)? mid->htype : htype_other;
     c = 1;
     }
@@ -399,14 +412,13 @@ for (header_line * h = header_list; !yield && h; h = h->next)
       /* If there is some kind of syntax error, just give up on this header
       line. */
 
-      if (next == NULL) break;
+      if (!next) break;
 
       /* Otherwise, test for the pattern; a non-regex must be an exact match */
 
-      yield = (re == NULL)?
-        (strcmpic(next, pattern) == 0)
-        :
-        (pcre_exec(re, NULL, CS next, Ustrlen(next), 0, PCRE_EOPT, NULL, 0)
+      yield = !re
+        ? (strcmpic(next, pattern) == 0)
+        : (pcre_exec(re, NULL, CS next, Ustrlen(next), 0, PCRE_EOPT, NULL, 0)
           >= 0);
       }
     }