Michael Haardt's patch for support for :user and :subaddress in Sieve
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Wed, 6 Apr 2005 14:40:23 +0000 (14:40 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Wed, 6 Apr 2005 14:40:23 +0000 (14:40 +0000)
filters by means of two new redirect router options.

doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/src/deliver.c
src/src/filtertest.c
src/src/functions.h
src/src/rda.c
src/src/routers/queryprogram.c
src/src/routers/redirect.c
src/src/routers/redirect.h
src/src/sieve.c

index 2d4044efcbc3a2570f2bbcf56402a2179e51c545..7ac876c15951580e139c5f2552cfa2fe0f23418f 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.115 2005/04/06 14:09:17 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.116 2005/04/06 14:40:23 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -176,6 +176,9 @@ PH/28 Modified OS/os.c-Linux with
       to make Exim compile on kfreebsd-gnu. (I'm totally confused about the
       nomenclature these days.)
 
+PH/29 Installed patch from the Sieve maintainer that adds the options
+      sieve_useraddress and sieve_subaddress to the redirect router.
+
 
 
 A note about Exim versions 4.44 and 4.50
index 4a27391886d819a975994576083dddba62c6e19e..16f494bb98c94d84e6060227931ff8cae24178c9 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.34 2005/04/06 14:03:53 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.35 2005/04/06 14:40:23 ph10 Exp $
 
 New Features in Exim
 --------------------
@@ -140,6 +140,12 @@ PH/07 $acl_verify_message is now set immediately after the failure of a
       Previously, $acl_verify_message was set only while expanding "message"
       and "log_message" when a very denied access.
 
+PH/08 The redirect router has two new options, sieve_useraddress and
+      sieve_subaddress. These are passed to a Sieve filter to specify the :user
+      and :subaddress parts of an address. Both options are unset by default.
+      However, when a Sieve filter is run, if sieve_useraddress is unset, the
+      entire original local part (including any prefix or suffix) is used for
+      :user. An unset subaddress is treated as an empty subaddress.
 
 
 Version 4.50
index cc9b8ee0fd3d4e01a268243a9bd6b4309bb2f39e..ac23a33aa3a41a02410bde87008ac118e9efb8dd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/deliver.c,v 1.10 2005/04/05 15:47:50 ph10 Exp $ */
+/* $Cambridge: exim/src/src/deliver.c,v 1.11 2005/04/06 14:40:24 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -4662,6 +4662,8 @@ else if (system_filter != NULL && process_recipients != RECIP_FAIL_TIMEOUT)
       RDO_REWRITE,
     NULL,                   /* No :include: restriction (not used in filter) */
     NULL,                   /* No sieve vacation directory (not sieve!) */
+    NULL,                   /* No sieve user address (not sieve!) */
+    NULL,                   /* No sieve subaddress (not sieve!) */
     &ugid,                  /* uid/gid data */
     &addr_new,              /* Where to hang generated addresses */
     &filter_message,        /* Where to put error message */
index c0a183d6aefbfbc85656da1ef680f8e941e75718..107e35e0b3976ace9746b1f829edd8b0d51ac8b1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/filtertest.c,v 1.4 2005/02/17 11:58:26 ph10 Exp $ */
+/* $Cambridge: exim/src/src/filtertest.c,v 1.5 2005/04/06 14:40:24 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -271,7 +271,7 @@ if (is_system)
 else
   {
   yield = (filter_type == FILTER_SIEVE)?
-    sieve_interpret(filebuf, RDO_REWRITE, NULL, &generated, &error)
+    sieve_interpret(filebuf, RDO_REWRITE, NULL, NULL, NULL, &generated, &error)
     :
     filter_interpret(filebuf, RDO_REWRITE, &generated, &error);
   }
index 1563a55c3bc673eb106c9bafb7b7b49191a18d1c..5fce129a750a9ada390b6dc1e3682797c794b48c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/functions.h,v 1.13 2005/04/04 10:33:49 ph10 Exp $ */
+/* $Cambridge: exim/src/src/functions.h,v 1.14 2005/04/06 14:40:24 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -184,8 +184,9 @@ extern int     random_number(int);
 #ifdef WITH_CONTENT_SCAN
 extern int     recv_line(int, uschar *, int);
 #endif
-extern int     rda_interpret(redirect_block *, int, uschar *, uschar *, ugid_block *,
-                 address_item **, uschar **, error_block **, int *, uschar *);
+extern int     rda_interpret(redirect_block *, int, uschar *, uschar *,
+                 uschar *, uschar *, ugid_block *, address_item **, uschar **,
+                 error_block **, int *, uschar *);
 extern int     rda_is_filter(const uschar *);
 extern BOOL    readconf_depends(driver_instance *, uschar *);
 extern void    readconf_driver_init(uschar *, driver_instance **,
@@ -247,8 +248,8 @@ extern void    set_process_info(char *, ...);
 extern void    sha1_end(sha1 *, const uschar *, int, uschar *);
 extern void    sha1_mid(sha1 *, const uschar *);
 extern void    sha1_start(sha1 *);
-extern int     sieve_interpret(uschar *, int, uschar *, address_item **,
-                 uschar **);
+extern int     sieve_interpret(uschar *, int, uschar *, uschar *, uschar *,
+                 address_item **, uschar **);
 extern void    sigalrm_handler(int);
 extern void    smtp_closedown(uschar *);
 extern int     smtp_connect(host_item *, int, int, uschar *, int, BOOL);
index cae283d8ceddcb403f0b04a30b20284d3fab870d..311f173945f951c69ed7a98d9449174be919a42e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/rda.c,v 1.4 2005/02/17 11:58:26 ph10 Exp $ */
+/* $Cambridge: exim/src/src/rda.c,v 1.5 2005/04/06 14:40:24 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -333,6 +333,8 @@ Arguments:
   options                   the options bits
   include_directory         restrain to this directory
   sieve_vacation_directory  passed to sieve_interpret
+  sieve_useraddress         passed to sieve_interpret
+  sieve_subaddress          passed to sieve_interpret
   generated                 where to hang generated addresses
   error                     for error messages
   eblockp                   for details of skipped syntax errors
@@ -348,7 +350,8 @@ Returns:                    a suitable return for rda_interpret()
 
 static int
 rda_extract(redirect_block *rdata, int options, uschar *include_directory,
-  uschar *sieve_vacation_directory, address_item **generated, uschar **error,
+  uschar *sieve_vacation_directory, uschar *sieve_useraddress,
+  uschar *sieve_subaddress, address_item **generated, uschar **error,
   error_block **eblockp, int *filtertype)
 {
 uschar *data;
@@ -407,8 +410,8 @@ if (*filtertype != FILTER_FORWARD)
       *error = US"Sieve filtering not enabled";
       return FF_ERROR;
       }
-    frc = sieve_interpret(data, options, sieve_vacation_directory, generated,
-      error);
+    frc = sieve_interpret(data, options, sieve_vacation_directory,
+      sieve_useraddress, sieve_subaddress, generated, error);
     }
 
   expand_forbid = old_expand_forbid;
@@ -515,6 +518,8 @@ Arguments:
                               plus ENOTDIR and EACCES handling bits
   include_directory         restrain :include: to this directory
   sieve_vacation_directory  directory passed to sieve_interpret()
+  sieve_useraddress         passed to sieve_interpret
+  sieve_subaddress          passed to sieve_interpret
   ugid                      uid/gid to run under - if NULL, no change
   generated                 where to hang generated addresses, initially NULL
   error                     pointer for error message
@@ -541,7 +546,8 @@ Returns:        values from extraction function, or FF_NONEXIST:
 
 int
 rda_interpret(redirect_block *rdata, int options, uschar *include_directory,
-  uschar *sieve_vacation_directory, ugid_block *ugid, address_item **generated,
+  uschar *sieve_vacation_directory, uschar *sieve_useraddress,
+  uschar *sieve_subaddress, ugid_block *ugid, address_item **generated,
   uschar **error, error_block **eblockp, int *filtertype, uschar *rname)
 {
 int fd, rc, pfd[2];
@@ -586,7 +592,8 @@ if (!ugid->uid_set ||                         /* Either there's no uid, or */
      Ustrstr(data, ":include:") == NULL))     /* and there's no :include: */
   {
   return rda_extract(rdata, options, include_directory,
-    sieve_vacation_directory, generated, error, eblockp, filtertype);
+    sieve_vacation_directory, sieve_useraddress, sieve_subaddress,
+    generated, error, eblockp, filtertype);
   }
 
 /* We need to run the processing code in a sub-process. However, if we can
@@ -631,7 +638,8 @@ if ((pid = fork()) == 0)
   /* Now do the business */
 
   yield = rda_extract(rdata, options, include_directory,
-    sieve_vacation_directory, generated, error, eblockp, filtertype);
+    sieve_vacation_directory, sieve_useraddress, sieve_subaddress, generated,
+    error, eblockp, filtertype);
 
   /* Pass back whether it was a filter, and the return code and any overall
   error text via the pipe. */
index 309695b887e00086504b6170b5f88bb9b7c1a433..5d7a51fdf9dca14c1150a621f5ebc6ef926beb8f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/routers/queryprogram.c,v 1.2 2005/01/04 10:00:44 ph10 Exp $ */
+/* $Cambridge: exim/src/src/routers/queryprogram.c,v 1.3 2005/04/06 14:40:24 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -356,6 +356,8 @@ if (strcmpic(rword, US"REDIRECT") == 0)
       RDO_REWRITE,               /* rewrite generated addresses */
     NULL,                        /* :include: directory not relevant */
     NULL,                        /* sieve vacation directory not relevant */
+    NULL,                        /* sieve useraddress not relevant */
+    NULL,                        /* sieve subaddress not relevant */
     &ugid,                       /* uid/gid (but not set) */
     &generated,                  /* where to hang the results */
     &(addr->message),            /* where to put messages */
index c0c76322cc9581d60c8a760b22e5e68fb93f63c9..0153a4d499e704c2f041484408e97effa4b64d97 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/routers/redirect.c,v 1.8 2005/03/22 15:02:34 ph10 Exp $ */
+/* $Cambridge: exim/src/src/routers/redirect.c,v 1.9 2005/04/06 14:40:24 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -97,6 +97,10 @@ optionlist redirect_router_options[] = {
       (void *)offsetof(redirect_router_options_block, reply_transport_name) },
   { "rewrite",            opt_bit | (RDON_REWRITE << 16),
       (void *)offsetof(redirect_router_options_block, bit_options) },
+  { "sieve_subaddress", opt_stringptr,
+      (void *)offsetof(redirect_router_options_block, sieve_subaddress) },
+  { "sieve_useraddress", opt_stringptr,
+      (void *)offsetof(redirect_router_options_block, sieve_useraddress) },
   { "sieve_vacation_directory", opt_stringptr,
       (void *)offsetof(redirect_router_options_block, sieve_vacation_directory) },
   { "skip_syntax_errors", opt_bool,
@@ -138,6 +142,8 @@ redirect_router_options_block redirect_router_option_defaults = {
   NULL,        /* include_directory */
   NULL,        /* pipe_transport_name */
   NULL,        /* reply_transport_name */
+  NULL,        /* sieve_subaddress */
+  NULL,        /* sieve_useraddress */
   NULL,        /* sieve_vacation_directory */
   NULL,        /* syntax_errors_text */
   NULL,        /* syntax_errors_to */
@@ -613,9 +619,10 @@ else
   }
 
 frc = rda_interpret(&redirect, options, ob->include_directory,
-  ob->sieve_vacation_directory, &ugid, &generated, &(addr->message),
-  ob->skip_syntax_errors? &eblock : NULL, &filtertype,
-  string_sprintf("%s router (recipient is %s)", rblock->name, addr->address));
+  ob->sieve_vacation_directory, ob->sieve_useraddress, ob->sieve_subaddress,
+  &ugid, &generated, &(addr->message), ob->skip_syntax_errors? &eblock : NULL,
+  &filtertype, string_sprintf("%s router (recipient is %s)", rblock->name,
+  addr->address));
 
 qualify_domain_recipient = save_qualify_domain_recipient;
 
index 9fd54ee54f82d20c47a8cebe203df3c2b17a4fb3..bda2224a8628508b4c2fc9e7c7c2fd7b0303bda0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/routers/redirect.h,v 1.3 2005/01/04 10:00:44 ph10 Exp $ */
+/* $Cambridge: exim/src/src/routers/redirect.h,v 1.4 2005/04/06 14:40:24 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -25,6 +25,8 @@ typedef struct {
   uschar *include_directory;
   uschar *pipe_transport_name;
   uschar *reply_transport_name;
+  uschar *sieve_subaddress;
+  uschar *sieve_useraddress;
   uschar *sieve_vacation_directory;
   uschar *syntax_errors_text;
   uschar *syntax_errors_to;
index abe0d37f323631fd4b9ddb995c8270fd5eb5750e..cc3ad14a2d9920092b2b87223f722d5c73069973 100644 (file)
@@ -1,10 +1,10 @@
-/* $Cambridge: exim/src/src/sieve.c,v 1.8 2005/03/01 10:21:44 ph10 Exp $ */
+/* $Cambridge: exim/src/src/sieve.c,v 1.9 2005/04/06 14:40:24 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) Michael Haardt 2003,2004 */
+/* Copyright (c) Michael Haardt 2003-2005 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* This code was contributed by Michael Haardt. */
@@ -61,6 +61,8 @@ struct Sieve
   int vacation_ran;
 #endif
   uschar *vacation_directory;
+  const uschar *subaddress;
+  const uschar *useraddress;
   int require_copy;
   int require_iascii_numeric;
   };
@@ -1711,10 +1713,8 @@ if (parse_identifier(filter,CUS "address"))
           case ADDRPART_LOCALPART: part=extracted_addr; part[domain-1]='\0'; break;
           case ADDRPART_DOMAIN: part=extracted_addr+domain; break;
 #ifdef SUBADDRESS
-          case ADDRPART_DETAIL:
-          part=NULL;
+          case ADDRPART_DETAIL: part=NULL; break;
 #endif
-          break;
           }
 
         *end_addr = saveend;
@@ -2019,9 +2019,7 @@ else if (parse_identifier(filter,CUS "envelope"))
         case ADDRPART_LOCALPART: envelopeExpr=CUS "${local_part:$sender_address}"; break;
         case ADDRPART_DOMAIN: envelopeExpr=CUS "${domain:$sender_address}"; break;
 #ifdef SUBADDRESS
-        case ADDRPART_DETAIL:
-        envelopeExpr=CUS 0;
-        break;
+        case ADDRPART_DETAIL: envelopeExpr=CUS 0; break;
 #endif
         }
       }
@@ -2031,8 +2029,8 @@ else if (parse_identifier(filter,CUS "envelope"))
         {
         case ADDRPART_ALL: envelopeExpr=CUS "$local_part_prefix$local_part$local_part_suffix@$domain"; break;
 #ifdef SUBADDRESS
-        case ADDRPART_USER: envelopeExpr=CUS "$local_part_prefix$local_part"; break;
-        case ADDRPART_DETAIL: envelopeExpr=CUS "$local_part_suffix"; break;
+        case ADDRPART_USER: envelopeExpr=filter->useraddress; break;
+        case ADDRPART_DETAIL: envelopeExpr=filter->subaddress; break;
 #endif
         case ADDRPART_LOCALPART: envelopeExpr=CUS "$local_part_prefix$local_part$local_part_suffix"; break;
         case ADDRPART_DOMAIN: envelopeExpr=CUS "$domain"; break;
@@ -2724,6 +2722,8 @@ Arguments:
   options     controls whether various special things are allowed, and requests
               special actions (not currently used)
   sieve_vacation_directory  where to store vacation "once" files
+  useraddress string expression for :user part of address
+  subaddress  string expression for :subaddress part of address
   generated   where to hang newly-generated addresses
   error       where to pass back an error text
 
@@ -2737,7 +2737,7 @@ Returns:      FF_DELIVERED     success, a significant action was taken
 
 int
 sieve_interpret(uschar *filter, int options, uschar *vacation_directory,
-  address_item **generated, uschar **error)
+  uschar *useraddress, uschar *subaddress, address_item **generated, uschar **error)
 {
 struct Sieve sieve;
 int r;
@@ -2763,6 +2763,9 @@ else
     }
   }
 
+sieve.useraddress = useraddress == NULL ? CUS "$local_part_prefix$local_part$local_part_suffix" : useraddress;
+sieve.subaddress = subaddress;
+
 #ifdef COMPILE_SYNTAX_CHECKER
 if (parse_start(&sieve,0,generated)==1)
 #else