bool: condition support. fixes: #167
authorNigel Metheringham <nigel@exim.org>
Wed, 14 Oct 2009 14:48:40 +0000 (14:48 +0000)
committerNigel Metheringham <nigel@exim.org>
Wed, 14 Oct 2009 14:48:40 +0000 (14:48 +0000)
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
src/src/acl.c
src/src/expand.c

index 7add7e6041da3f201a088eccedd8516323a71040..201aefc5dd3fbcd1e5d7a6c4fc1da6c963aa2223 100644 (file)
@@ -1,4 +1,4 @@
-. $Cambridge: exim/doc/doc-docbook/spec.xfpt,v 1.54 2009/10/13 08:46:06 tom Exp $
+. $Cambridge: exim/doc/doc-docbook/spec.xfpt,v 1.55 2009/10/14 14:48:40 nm4 Exp $
 .
 . /////////////////////////////////////////////////////////////////////////////
 . This is the primary source of the Exim Manual. It is an xfpt document that is
@@ -9732,6 +9732,22 @@ lower case), signifying multiplication by 1024 or 1024*1024, respectively.
 As a special case, the numerical value of an empty string is taken as
 zero.
 
+.vitem &*bool&~{*&<&'string'&>&*}*&
+.cindex "expansion" "boolean parsing"
+.cindex "&%bool%& expansion condition"
+This condition turns a string holding a true or false representation into
+a boolean state.  It parses &"true"&, &"false"&, &"yes"& and &"no"&
+(case-insensitively); also positive integer numbers map to true if non-zero,
+false if zero.  Leading whitespace is ignored.
+All other string values will result in expansion failure.
+
+When combined with ACL variables, this expansion condition will let you
+make decisions in one place and act on those decisions in another place.
+For example,
+.code
+${if bool{$acl_m_privileged_sender} ...
+.endd
+
 .vitem &*crypteq&~{*&<&'string1'&>&*}{*&<&'string2'&>&*}*&
 .cindex "expansion" "encrypted comparison"
 .cindex "encrypted strings, comparing"
index 944cc6717b84a36f0c54149c7662fedc600961a8..e7db600034468fc6bf4af20caa7324ab06f0e9d5 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.568 2009/10/14 13:52:48 nm4 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.569 2009/10/14 14:48:41 nm4 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -105,7 +105,11 @@ NM/17 Changed NOTICE file to remove references to embedded PCRE.
 
 NM/18 Bugzilla 894: Fix issue with very long lines including comments in lsearch
 
-NM/18 Bugzilla 745: TLS version reporting
+NM/19 Bugzilla 745: TLS version reporting
+      Patch provided by Phil Pennock
+
+NM/20 Bugzilla 167: bool: condition support
+      Patch provided by Phil Pennock
 
 
 Exim version 4.69
index a3e79b13d2177976c384addd8e9d58b2667c67c4..04b7fe5f59bd59b1f730908744e4446f0791ea4f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.83 2009/06/10 07:34:04 tom Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.84 2009/10/14 14:48:41 nm4 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -2540,6 +2540,9 @@ for (; cb != NULL; cb = cb->next)
     #endif
 
     case ACLC_CONDITION:
+    /* The true/false parsing here should be kept in sync with that used in
+    expand.c when dealing with ECOND_BOOL so that we don't have too many
+    different definitions of what can be a boolean. */
     if (Ustrspn(arg, "0123456789") == Ustrlen(arg))     /* Digits, or empty */
       rc = (Uatoi(arg) == 0)? FAIL : OK;
     else
index 943ec76ecf46e36ba65d7035c05b99ffdb8b7727..b52901c32878b30b53166801069cdcafedabe30e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/expand.c,v 1.100 2009/08/31 21:14:50 tom Exp $ */
+/* $Cambridge: exim/src/src/expand.c,v 1.101 2009/10/14 14:48:41 nm4 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -242,6 +242,7 @@ static uschar *cond_table[] = {
   US">",
   US">=",
   US"and",
+  US"bool",
   US"crypteq",
   US"def",
   US"eq",
@@ -283,6 +284,7 @@ enum {
   ECOND_NUM_G,
   ECOND_NUM_GE,
   ECOND_AND,
+  ECOND_BOOL,
   ECOND_CRYPTEQ,
   ECOND_DEF,
   ECOND_STR_EQ,
@@ -2408,6 +2410,53 @@ switch(cond_type)
     }
 
 
+  /* The bool{} expansion condition maps a string to boolean.
+  The values supported should match those supported by the ACL condition
+  (acl.c, ACLC_CONDITION) so that we keep to a minimum the different ideas
+  of true/false.  Note that Router "condition" rules have a different
+  interpretation, where general data can be used and only a few values
+  map to FALSE.
+  Note that readconf.c boolean matching, for boolean configuration options,
+  only matches true/yes/false/no. */
+  case ECOND_BOOL:
+    {
+    uschar *sub_arg[1];
+    uschar *t;
+    size_t len;
+    BOOL boolvalue = FALSE;
+    while (isspace(*s)) s++;
+    if (*s != '{') goto COND_FAILED_CURLY_START;
+    switch(read_subs(sub_arg, 1, 1, &s, yield == NULL, FALSE, US"bool"))
+      {
+      case 1: expand_string_message = US"too few arguments or bracketing "
+        "error for bool";
+      /*FALLTHROUGH*/
+      case 2:
+      case 3: return NULL;
+      }
+    t = sub_arg[0];
+    while (isspace(*t)) t++;
+    len = Ustrlen(t);
+    DEBUG(D_expand)
+      debug_printf("considering bool: %s\n", len ? t : US"<empty>");
+    if (len == 0)
+      boolvalue = FALSE;
+    else if (Ustrspn(t, "0123456789") == len)
+      boolvalue = (Uatoi(t) == 0) ? FALSE : TRUE;
+    else if (strcmpic(t, US"true") == 0 || strcmpic(t, US"yes") == 0)
+      boolvalue = TRUE;
+    else if (strcmpic(t, US"false") == 0 || strcmpic(t, US"no") == 0)
+      boolvalue = FALSE;
+    else
+      {
+      expand_string_message = string_sprintf("unrecognised boolean "
+       "value \"%s\"", t);
+      return NULL;
+      }
+    if (yield != NULL) *yield = (boolvalue != 0);
+    return s;
+    }
+
   /* Unknown condition */
 
   default: