Add "continue" modifier.
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Wed, 14 Feb 2007 15:33:40 +0000 (15:33 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Wed, 14 Feb 2007 15:33:40 +0000 (15:33 +0000)
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/src/acl.c
test/confs/0023
test/stderr/0023

index 61b6ac275d257bb0598f9144777720843692d6c0..1d894c33982cc6370e161e61e5778e43f36e9f19 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.479 2007/02/14 14:59:01 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.480 2007/02/14 15:33:40 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -106,6 +106,9 @@ PH/25 Applied Magnus Holmgren's patch for ${addresses, ${map, ${filter, and
 
 SC/02 Applied Daniel Tiefnig's patch to improve the '($parent) =' pattern match.
 
+PH/26 Added a "continue" ACL modifier that does nothing, for the benefit of its
+      expansion side effects.
+
 
 Exim version 4.66
 -----------------
index b70fa5e68bc50f321ecc1fab11fb1d7f758def15..677ab21aa9fc39c0be37e7ad8817e101ce0a03f1 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.141 2007/02/14 14:59:01 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.142 2007/02/14 15:33:40 ph10 Exp $
 
 New Features in Exim
 --------------------
@@ -292,7 +292,7 @@ Version 4.67
     option; with -I they don't. In both cases it is possible to change the case
     sensitivity within the pattern using (?i) or (?-i).
 
-14. A number of new features have been added to string expansions to make it
+16. A number of new features have been added to string expansions to make it
     easier to process lists of items, typically addresses. These are as
     follows:
 
@@ -365,6 +365,16 @@ Version 4.67
     At the end of a ${reduce expansion, the values of $item and $value is
     restored to what they were before.
 
+17. There's a new ACL modifier called "continue". It does nothing of itself,
+    and processing of the ACL always continues with the next condition or
+    modifier. It is provided so that the side effects of expanding its argument
+    can be used. Typically this would be for updating a database. It is really
+    just a syntactic tidiness, because the following two lines have the same
+    effect:
+
+      continue  = <some expansion>
+      condition = ${if eq{0}{<some expansion>}{true}{true}}
+
 
 Version 4.66
 ------------
index 78b30addc04c8c060747eec9dbca8bb2daa27163..afbb93e5c8ad6750a1fd8bd4f315ab68386fe3f0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.73 2007/02/07 11:24:56 ph10 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.74 2007/02/14 15:33:40 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -53,6 +53,7 @@ enum { ACLC_ACL,
        ACLC_BMI_OPTIN,
 #endif
        ACLC_CONDITION,
+       ACLC_CONTINUE,
        ACLC_CONTROL,
 #ifdef WITH_CONTENT_SCAN
        ACLC_DECODE,
@@ -101,10 +102,10 @@ enum { ACLC_ACL,
 #endif
        ACLC_VERIFY };
 
-/* ACL conditions/modifiers: "delay", "control", "endpass", "message",
-"log_message", "log_reject_target", "logwrite", and "set" are modifiers that
-look like conditions but always return TRUE. They are used for their side
-effects. */
+/* ACL conditions/modifiers: "delay", "control", "continue", "endpass",
+"message", "log_message", "log_reject_target", "logwrite", and "set" are
+modifiers that look like conditions but always return TRUE. They are used for
+their side effects. */
 
 static uschar *conditions[] = {
   US"acl",
@@ -114,6 +115,7 @@ static uschar *conditions[] = {
   US"bmi_optin",
 #endif
   US"condition",
+  US"continue",
   US"control",
 #ifdef WITH_CONTENT_SCAN
   US"decode",
@@ -237,6 +239,7 @@ static uschar cond_expand_at_top[] = {
   TRUE,    /* bmi_optin */
 #endif
   TRUE,    /* condition */
+  TRUE,    /* continue */
   TRUE,    /* control */
 #ifdef WITH_CONTENT_SCAN
   TRUE,    /* decode */
@@ -296,6 +299,7 @@ static uschar cond_modifiers[] = {
   TRUE,    /* bmi_optin */
 #endif
   FALSE,   /* condition */
+  TRUE,    /* continue */
   TRUE,    /* control */
 #ifdef WITH_CONTENT_SCAN
   FALSE,   /* decode */
@@ -345,9 +349,9 @@ static uschar cond_modifiers[] = {
   FALSE    /* verify */
 };
 
-/* Bit map vector of which conditions are not allowed at certain times. For
-each condition, there's a bitmap of dis-allowed times. For some, it is easier
-to specify the negation of a small number of allowed times. */
+/* Bit map vector of which conditions and modifiers are not allowed at certain
+times. For each condition, there's a bitmap of dis-allowed times. For some, it
+is easier to specify the negation of a small number of allowed times. */
 
 static unsigned int cond_forbids[] = {
   0,                                               /* acl */
@@ -375,6 +379,8 @@ static unsigned int cond_forbids[] = {
 
   0,                                               /* condition */
 
+  0,                                               /* continue */
+
   /* Certain types of control are always allowed, so we let it through
   always and check in the control processing itself. */
 
@@ -2554,6 +2560,9 @@ for (; cb != NULL; cb = cb->next)
       *log_msgptr = string_sprintf("invalid \"condition\" value \"%s\"", arg);
     break;
 
+    case ACLC_CONTINUE:    /* Always succeeds */
+    break;
+
     case ACLC_CONTROL:
     control_type = decode_control(arg, &p, where, log_msgptr);
 
index ac6d8f7e27ba958cff28cdf867dc9550afbd0607..17c88ff6a79f6b18b42f467eaab09afc4c192a0e 100644 (file)
@@ -51,6 +51,7 @@ acl_1_2_3:
 
   deny    message = domain explicitly denied
           log_message = DOMAIN EXPLICITLY DENIED
+          continue = this value is not used
           domains = deny.test.ex
 
   accept  domains = +local_domains
index d54ccab128af055bb32e727ea8d261f484262fdb..a0b6e2aed161f68d634b3d9efa3f348da8a8b151 100644 (file)
@@ -16,6 +16,7 @@
 >>> test.ex in "!wontpass"? yes (end of list)
 >>> require: condition test succeeded
 >>> processing "deny"
+>>> check continue = this value is not used
 >>> check domains = deny.test.ex
 >>> test.ex in "deny.test.ex"? no (end of list)
 >>> deny: condition test failed
@@ -36,6 +37,7 @@
 >>> z in "!wontpass"? yes (end of list)
 >>> require: condition test succeeded
 >>> processing "deny"
+>>> check continue = this value is not used
 >>> check domains = deny.test.ex
 >>> z in "deny.test.ex"? no (end of list)
 >>> deny: condition test failed
@@ -65,6 +67,7 @@ LOG: H=[1.2.3.4] F=<x@y> rejected RCPT <z@z>
 >>> test.ex in "!wontpass"? yes (end of list)
 >>> require: condition test succeeded
 >>> processing "deny"
+>>> check continue = this value is not used
 >>> check domains = deny.test.ex
 >>> test.ex in "deny.test.ex"? no (end of list)
 >>> deny: condition test failed
@@ -85,6 +88,7 @@ LOG: H=[1.2.3.4] F=<x@y> rejected RCPT <z@z>
 >>> test.ex in "!wontpass"? yes (end of list)
 >>> require: condition test succeeded
 >>> processing "deny"
+>>> check continue = this value is not used
 >>> check domains = deny.test.ex
 >>> test.ex in "deny.test.ex"? no (end of list)
 >>> deny: condition test failed
@@ -105,6 +109,7 @@ LOG: H=[1.2.3.4] F=<x@y> rejected RCPT <z@z>
 >>> relay.test.ex in "!wontpass"? yes (end of list)
 >>> require: condition test succeeded
 >>> processing "deny"
+>>> check continue = this value is not used
 >>> check domains = deny.test.ex
 >>> relay.test.ex in "deny.test.ex"? no (end of list)
 >>> deny: condition test failed
@@ -125,6 +130,7 @@ LOG: H=[1.2.3.4] F=<x@y> rejected RCPT <z@z>
 >>> deny.test.ex in "!wontpass"? yes (end of list)
 >>> require: condition test succeeded
 >>> processing "deny"
+>>> check continue = this value is not used
 >>> check domains = deny.test.ex
 >>> deny.test.ex in "deny.test.ex"? yes (matched "deny.test.ex")
 >>> deny: condition test succeeded
@@ -139,6 +145,7 @@ LOG: H=[1.2.3.4] F=<x@y> rejected RCPT <x@deny.test.ex>: DOMAIN EXPLICITLY DENIE
 >>> refuse.test.ex in "!wontpass"? yes (end of list)
 >>> require: condition test succeeded
 >>> processing "deny"
+>>> check continue = this value is not used
 >>> check domains = deny.test.ex
 >>> refuse.test.ex in "deny.test.ex"? no (end of list)
 >>> deny: condition test failed