[exim-dev] Saving the variable part of local part suffixes

Top Page
Delete this message
Reply to this message
Author: Michael Haardt
Date:  
To: exim-dev
Subject: [exim-dev] Saving the variable part of local part suffixes
Hello,

last year, Philip and me spoke about how to obtain the part of
a local part suffix that is matched by "*". With the address
"address-subaddress@domain" and local_part_suffix = "-*" you get:

$local_part is address
$local_part_suffix is -subaddress
$local_part_subaddress is subaddress (no -)

Looks easy without an Exim patch, but if local_part_suffix is set to
use multiple strings or if different routers use multiple ones, there
is no easy way to know what to strip from $local_part_suffix to get the
subaddress, so the subaddress really needs to be held in the address_item.
The subaddress is required in order to implement the Sieve subaddress
extension, but it would also make some Exim configurations easier.
We did not hack the code, because there was some subtle problem, that
I unfortunately forgot by now.

The patch below is not tested and please do not commit it. I would
be glad if you could just have a look at it and tell me if there is
something obvious I forgot or screwed up. I just can't remember what
stopped us last year from an easy hack like this.

Michael
----------------------------------------------------------------------
--- src/structs.h.orig    2005-03-01 11:22:08.000000000 +0100
+++ src/structs.h    2005-03-08 16:57:15.000000000 +0100
@@ -248,6 +248,7 @@
   uschar *self;                   /* Text option for handling self reference */
   uschar *senders;                /* Specific senders */
   uschar *suffix;                 /* Address suffix */
+  uschar *subaddress;             /* Subaddress */
   uschar *translate_ip_address;   /* IP address translation fudgery */
   uschar *transport_name;         /* Transport name */


@@ -531,6 +532,7 @@
   uschar *local_part;             /* points to cc or lc version */
   uschar *prefix;                 /* stripped prefix of local part */
   uschar *suffix;                 /* stripped suffix of local part */
+  uschar *subaddress;                 /* stripped suffix of local part */
   uschar *domain;                 /* working domain (lower cased) */


   uschar *address_retry_key;      /* retry key including full address */
--- src/route.c.orig    2005-03-08 16:00:41.000000000 +0100
+++ src/route.c    2005-03-08 16:39:41.000000000 +0100
@@ -353,10 +353,11 @@
   suffixes      the list of suffixes


 Returns:        length of matching suffix or zero
+  subaddress    length of matched subaddress or zero
 */


 int
-route_check_suffix(uschar *local_part, uschar *suffixes)
+route_check_suffix(uschar *local_part, uschar *suffixes, int *subaddress)
 {
 int sep = 0;
 int alen = Ustrlen(local_part);
@@ -373,13 +374,21 @@
     uschar *p, *pend;
     pend = local_part + alen - (--slen) + 1;
     for (p = local_part; p < pend; p++)
-      if (strncmpic(suffix, p, slen) == 0) return alen - (p - local_part);
+      if (strncmpic(suffix, p, slen) == 0)
+        {
+        if (subaddress) *subaddress = alen - (p + slen - local_part);
+        return alen - (p - local_part);
+        }
     }
   else
     if (alen > slen && strncmpic(suffix, local_part + alen - slen, slen) == 0)
+      {
+      if (subaddress) *subaddress = 0;
       return slen;
+      }
   }


+if (subaddress) *subaddress = 0;
return 0;
}

@@ -1593,11 +1602,13 @@

   if (r->suffix != NULL)
     {
-    int slen = route_check_suffix(addr->local_part, r->suffix);
+    int salen,slen = route_check_suffix(addr->local_part, r->suffix, &salen);
     if (slen > 0)
       {
-      int lplen = Ustrlen(addr->local_part) - slen;
+      int olplen = Ustrlen(addr->local_part);
+      int lplen = olplen - slen;
       addr->suffix = addr->local_part + lplen;
+      addr->subaddress = addr->local_part + olplen - salen;
       addr->local_part = string_copyn(addr->local_part, lplen);
       DEBUG(D_route) debug_printf("stripped suffix %s\n", addr->suffix);
       }
--- src/receive.c.orig    2005-03-08 16:32:25.000000000 +0100
+++ src/receive.c    2005-03-08 16:35:00.000000000 +0100
@@ -2292,7 +2292,7 @@


     if (at != NULL) *at = 0;
     from_address += route_check_prefix(from_address, local_from_prefix);
-    slen = route_check_suffix(from_address, local_from_suffix);
+    slen = route_check_suffix(from_address, local_from_suffix, (int*)0);
     if (slen > 0)
       {
       memmove(from_address+slen, from_address, Ustrlen(from_address)-slen);
--- src/functions.h.orig    2005-03-08 16:29:39.000000000 +0100
+++ src/functions.h    2005-03-08 16:29:51.000000000 +0100
@@ -221,7 +221,7 @@
 extern int     route_address(address_item *, address_item **, address_item **,
                  address_item **, address_item **, int);
 extern int     route_check_prefix(uschar *, uschar *);
-extern int     route_check_suffix(uschar *, uschar *);
+extern int     route_check_suffix(uschar *, uschar *, int *);
 extern BOOL    route_findgroup(uschar *, gid_t *);
 extern BOOL    route_finduser(uschar *, struct passwd **, uid_t *);
 extern BOOL    route_find_expanded_group(uschar *, uschar *, uschar *, gid_t *,
--- src/globals.h.orig    2005-03-08 16:50:45.000000000 +0100
+++ src/globals.h    2005-03-08 16:50:39.000000000 +0100
@@ -241,6 +241,7 @@
 extern uschar *deliver_localpart_parent; /* The parent local part for delivery */
 extern uschar *deliver_localpart_prefix; /* The stripped prefix, if any */
 extern uschar *deliver_localpart_suffix; /* The stripped suffix, if any */
+extern uschar *deliver_localpart_subaddress; /* The stripped subaddress, if any */
 extern BOOL    deliver_force_thaw;     /* TRUE to force thaw in queue run */
 extern BOOL    deliver_manual_thaw;    /* TRUE if manually thawed */
 extern uschar *deliver_out_buffer;     /* Buffer for copying file */
--- src/globals.c.orig    2005-03-01 11:22:08.000000000 +0100
+++ src/globals.c    2005-03-08 16:49:14.000000000 +0100
@@ -142,6 +142,7 @@
   &deliver_localpart_parent,
   &deliver_localpart_prefix,
   &deliver_localpart_suffix,
+  &deliver_localpart_subaddress,
   (uschar **)(&deliver_recipients),
   &deliver_host,
   &deliver_home,
@@ -244,6 +245,7 @@
   NULL,                 /* local_part */
   NULL,                 /* prefix */
   NULL,                 /* suffix */
+  NULL,                 /* subaddress */
   NULL,                 /* domain */
   NULL,                 /* address_retry_key */
   NULL,                 /* domain_retry_key */
@@ -447,6 +454,7 @@
 uschar *deliver_localpart_parent = NULL;
 uschar *deliver_localpart_prefix = NULL;
 uschar *deliver_localpart_suffix = NULL;
+uschar *deliver_localpart_subaddress = NULL;
 BOOL    deliver_force_thaw     = FALSE;
 BOOL    deliver_manual_thaw    = FALSE;
 uschar *deliver_out_buffer     = NULL;
@@ -872,6 +880,7 @@
     US"freeze",                /* self */
     NULL,                      /* senders */
     NULL,                      /* suffix */
+    NULL,                      /* subaddress */
     NULL,                      /* translate_ip_address */
     NULL,                      /* transport_name */


--- src/macros.h.orig    2005-03-08 16:52:58.000000000 +0100
+++ src/macros.h    2005-03-08 16:53:07.000000000 +0100
@@ -101,7 +101,7 @@
 verifying. This has to be explicit because it is referenced in more than one
 source module. */


-#define ADDRESS_EXPANSIONS_COUNT 18
+#define ADDRESS_EXPANSIONS_COUNT 19

 /* The maximum permitted number of command-line (-D) macro definitions. We
 need a limit only to make it easier to generate argument vectors for re-exec
--- src/expand.c.orig    2005-03-08 17:02:13.000000000 +0100
+++ src/expand.c    2005-03-08 17:02:41.000000000 +0100
@@ -364,6 +364,7 @@
   { "local_part_data",     vtype_stringptr,   &deliver_localpart_data },
   { "local_part_prefix",   vtype_stringptr,   &deliver_localpart_prefix },
   { "local_part_suffix",   vtype_stringptr,   &deliver_localpart_suffix },
+  { "local_part_subaddress",   vtype_stringptr,   &deliver_localpart_subaddress },
   { "local_scan_data",     vtype_stringptr,   &local_scan_data },
   { "local_user_gid",      vtype_gid,         &local_user_gid },
   { "local_user_uid",      vtype_uid,         &local_user_uid },