Re: [exim-dev] Patch for ACL add_header: delete/replace

Top Page
Delete this message
Reply to this message
Author: Dave Evans
Date:  
To: exim-dev
Subject: Re: [exim-dev] Patch for ACL add_header: delete/replace
On Sun, Nov 26, 2006 at 10:24:08AM +0000, Dave Evans wrote:
> Hi,
>
> Please be gentle. This is my first exim-dev posting IIRC, and certainly my
> first patch :-)


Correction: *this* is my first patch :-)

--
Dave Evans
Power Internet

PGP key: http://powernet.co.uk/~davide/pgpkey
diff -ru exim-snapshot/src/acl.c exim-snapshot.new/src/acl.c
--- exim-snapshot/src/acl.c    2006-11-25 03:15:47.000000000 +0000
+++ exim-snapshot.new/src/acl.c    2006-11-25 22:04:36.000000000 +0000
@@ -960,6 +960,16 @@
       newtype = htype_add_bot;
       p += 8;
       }
+    else if (strncmpic(p, US":delete:", 8) == 0)
+      {
+      newtype = htype_add_del;
+      p += 8;
+      }
+    else if (strncmpic(p, US":replace:", 9) == 0)
+      {
+      newtype = htype_add_rep;
+      p += 9;
+      }
     while (*p == ' ' || *p == '\t') p++;
     }


diff -ru exim-snapshot/src/macros.h exim-snapshot.new/src/macros.h
--- exim-snapshot/src/macros.h    2006-11-25 03:15:46.000000000 +0000
+++ exim-snapshot.new/src/macros.h    2006-11-25 23:41:02.000000000 +0000
@@ -569,6 +569,8 @@
 #define htype_add_rec       'r'
 #define htype_add_bot       'z'
 #define htype_add_rfc       'f'
+#define htype_add_del       'l'
+#define htype_add_rep       'u'


 /* Types of item in options lists. These are the bottom 8 bits of the "type"
 field, which is an int. The opt_void value is used for entries in tables that
diff -ru exim-snapshot/src/receive.c exim-snapshot.new/src/receive.c
--- exim-snapshot/src/receive.c    2006-11-25 03:15:47.000000000 +0000
+++ exim-snapshot.new/src/receive.c    2006-11-26 09:52:44.000000000 +0000
@@ -896,8 +896,10 @@
 static void
 add_acl_headers(uschar *acl_name)
 {
-header_line *h, *next;
+header_line *h, *next, *rep;
 header_line *last_received = NULL;
+int occ;
+uschar *tagend, *value, oldtagend;


 if (acl_added_headers == NULL) return;
 DEBUG(D_receive|D_acl) debug_printf(">>Headers added by %s ACL:\n", acl_name);
@@ -944,7 +946,47 @@
     DEBUG(D_receive|D_acl) debug_printf("  (before any non-Received: or Resent-*: header)");
     break;


-    default:
+    case htype_add_del:
+    /* Delete one or all headers which match this tag */
+    for (tagend = h->text; *tagend && *tagend != ':' && *tagend != ' ' && *tagend != '\t'; ++tagend) 1;
+    for (value = tagend; *value == ' ' || *tagend == '\t'; ++value) 1;
+    ++value;
+    oldtagend = *tagend; *tagend = '\0';
+    occ = (*value ? atoi(value) : 0);
+    header_remove(occ, h->text);
+    *tagend = oldtagend;
+    /* Add to the top as a deleted header */
+    h->type = htype_old;
+    h->next = header_list;
+    header_list = h;
+    DEBUG(D_receive|D_acl) debug_printf("  (deleted)");
+    break;
+
+    case htype_add_rep:
+    /* Replace the first matching header.  If none match, add to the end */
+    for (tagend = h->text; *tagend && *tagend != ':' && *tagend != ' ' && *tagend != '\t'; ++tagend) 1;
+    oldtagend = *tagend; *tagend = '\0';
+    for (rep = header_list; rep != NULL; rep = rep->next)
+      {
+      if (header_testname(rep, h->text, tagend - h->text, TRUE))
+        {
+        h->next = rep->next;
+        rep->next = h;
+        rep->type = htype_old;
+        DEBUG(D_receive|D_acl) debug_printf("  (replaced)");
+        break;
+        }
+      }
+    *tagend = oldtagend;
+    /* If we didn't replace one, append it */
+    if (!rep)
+      {
+      h->next = NULL;
+      header_last->next = h;
+      }
+    break;
+
+    default: /* htype_add_bot */
     h->next = NULL;
     header_last->next = h;
     break;
@@ -958,8 +1000,12 @@
   for existence tests when messages are received. So discard any lower case
   flag values. */


-  h->type = header_checkname(h, FALSE);
-  if (h->type >= 'a') h->type = htype_other;
+  /* The new header may already have been marked as deleted */
+  if (h->type != htype_old)
+    {
+    h->type = header_checkname(h, FALSE);
+    if (h->type >= 'a') h->type = htype_other;
+    }


DEBUG(D_receive|D_acl) debug_printf(" %s", header_last->text);
}