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
 -------------------------------------------
 
 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.)
 
       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
 
 
 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
 --------------------
 
 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.
 
       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
 
 
 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    *
 
 /*************************************************
 *     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!) */
       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 */
     &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    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -271,7 +271,7 @@ if (is_system)
 else
   {
   yield = (filter_type == FILTER_SIEVE)?
 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);
   }
     :
     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    *
 
 /*************************************************
 *     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
 #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 **,
 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 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);
 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    *
 
 /*************************************************
 *     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
   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
   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,
 
 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;
   error_block **eblockp, int *filtertype)
 {
 uschar *data;
@@ -407,8 +410,8 @@ if (*filtertype != FILTER_FORWARD)
       *error = US"Sieve filtering not enabled";
       return FF_ERROR;
       }
       *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;
     }
 
   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()
                               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
   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,
 
 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];
   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,
      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
   }
 
 /* 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,
   /* 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. */
 
   /* 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    *
 
 /*************************************************
 *     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 */
       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 */
     &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    *
 
 /*************************************************
 *     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) },
       (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,
   { "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,        /* 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 */
   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,
   }
 
 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;
 
 
 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    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -25,6 +25,8 @@ typedef struct {
   uschar *include_directory;
   uschar *pipe_transport_name;
   uschar *reply_transport_name;
   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;
   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    *
 *************************************************/
 
 
 /*************************************************
 *     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. */
 /* 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;
   int vacation_ran;
 #endif
   uschar *vacation_directory;
+  const uschar *subaddress;
+  const uschar *useraddress;
   int require_copy;
   int require_iascii_numeric;
   };
   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_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
 #endif
-          break;
           }
 
         *end_addr = saveend;
           }
 
         *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_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
         }
       }
 #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_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;
 #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
   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
 
   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,
 
 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;
 {
 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
 #ifdef COMPILE_SYNTAX_CHECKER
 if (parse_start(&sieve,0,generated)==1)
 #else