From 0ce9abe687c08503facdd9f4f94dfa27ada83da9 Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Tue, 6 Feb 2007 10:00:24 +0000 Subject: Add forany/forall (Marcus Holmgren's patch, basically). --- src/ACKNOWLEDGMENTS | 5 ++-- src/src/expand.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/src/globals.c | 3 ++- src/src/globals.h | 3 ++- 4 files changed, 75 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ACKNOWLEDGMENTS b/src/ACKNOWLEDGMENTS index 1a39046c3..d9238db38 100644 --- a/src/ACKNOWLEDGMENTS +++ b/src/ACKNOWLEDGMENTS @@ -1,4 +1,4 @@ -$Cambridge: exim/src/ACKNOWLEDGMENTS,v 1.71 2007/01/31 16:52:12 ph10 Exp $ +$Cambridge: exim/src/ACKNOWLEDGMENTS,v 1.72 2007/02/06 10:00:24 ph10 Exp $ EXIM ACKNOWLEDGEMENTS @@ -20,7 +20,7 @@ relatively small patches. Philip Hazel Lists created: 20 November 2002 -Last updated: 31 January 2007 +Last updated: 06 February 2007 THE OLD LIST @@ -168,6 +168,7 @@ Magnus Holmgren Patch for filter_prepend_home Patch for "h" flag in Domain Keys Patch for $sending_ip_address/$sending_port Patch for ${rfc2047d: + ... and several more Lots of other maintenance support Kjetil Torgrim Homme Patch for require_files problem on NFS file systems Tom Hughes Suggested patch for $n bug in pipe command from filter diff --git a/src/src/expand.c b/src/src/expand.c index b2674dd42..1409437d4 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/expand.c,v 1.79 2007/01/31 11:30:08 ph10 Exp $ */ +/* $Cambridge: exim/src/src/expand.c,v 1.80 2007/02/06 10:00:24 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -240,6 +240,8 @@ static uschar *cond_table[] = { US"eqi", US"exists", US"first_delivery", + US"forall", + US"forany", US"ge", US"gei", US"gt", @@ -279,6 +281,8 @@ enum { ECOND_STR_EQI, ECOND_EXISTS, ECOND_FIRST_DELIVERY, + ECOND_FORALL, + ECOND_FORANY, ECOND_STR_GE, ECOND_STR_GEI, ECOND_STR_GT, @@ -420,6 +424,7 @@ static var_entry var_table[] = { { "inode", vtype_ino, &deliver_inode }, { "interface_address", vtype_stringptr, &interface_address }, { "interface_port", vtype_int, &interface_port }, + { "item", vtype_stringptr, &iterate_item }, #ifdef LOOKUP_LDAP { "ldap_dn", vtype_stringptr, &eldap_dn }, #endif @@ -2349,6 +2354,68 @@ switch(cond_type) return ++s; + /* forall/forany: iterates a condition with different values */ + + case ECOND_FORALL: + case ECOND_FORANY: + { + int sep = 0; + uschar *iterate_item_save = iterate_item; + + while (isspace(*s)) s++; + if (*s++ != '{') goto COND_FAILED_CURLY_START; + + sub[0] = expand_string_internal(s, TRUE, &s, (yield == NULL)); + if (sub[0] == NULL) return NULL; + if (*s++ != '}') goto COND_FAILED_CURLY_END; + + while (isspace(*s)) s++; + if (*s++ != '{') goto COND_FAILED_CURLY_START; + + sub[1] = s; + + /* Call eval_condition once, with result discarded (as if scanning a + "false" part). This allows us to find the end of the condition, because if + the list it empty, we won't actually evaluate the condition for real. */ + + s = eval_condition(sub[1], NULL); + if (s == NULL) + { + expand_string_message = string_sprintf("%s inside \"%s\" condition", + expand_string_message, name); + return NULL; + } + while (isspace(*s)) s++; + + if (*s++ != '}') + { + expand_string_message = string_sprintf("missing } at end of condition " + "inside \"%s\"", name); + return NULL; + } + + if (yield != NULL) *yield = !testfor; + while ((iterate_item = string_nextinlist(&sub[0], &sep, NULL, 0)) != NULL) + { + DEBUG(D_expand) debug_printf("%s: $item = \"%s\"\n", name, iterate_item); + if (eval_condition(sub[1], &tempcond) == NULL) + { + expand_string_message = string_sprintf("%s inside \"%s\" condition", + expand_string_message, name); + return NULL; + } + DEBUG(D_expand) debug_printf("%s: condition evaluated to %s\n", name, + tempcond? "true":"false"); + + if (yield != NULL) *yield = (tempcond == testfor); + if (tempcond == (cond_type == ECOND_FORANY)) break; + } + + iterate_item = iterate_item_save; + return s; + } + + /* Unknown condition */ default: diff --git a/src/src/globals.c b/src/src/globals.c index b3bbd7faf..4d790ee9e 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.c,v 1.68 2007/02/05 12:35:46 ph10 Exp $ */ +/* $Cambridge: exim/src/src/globals.c,v 1.69 2007/02/06 10:00:24 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -630,6 +630,7 @@ uschar *ignore_fromline_hosts = NULL; uschar *interface_address = NULL; int interface_port = -1; BOOL is_inetd = FALSE; +uschar *iterate_item = NULL; int journal_fd = -1; diff --git a/src/src/globals.h b/src/src/globals.h index 570e4c87b..77662b376 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.h,v 1.48 2007/02/05 12:35:46 ph10 Exp $ */ +/* $Cambridge: exim/src/src/globals.h,v 1.49 2007/02/06 10:00:24 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -385,6 +385,7 @@ extern int ignore_bounce_errors_after; /* Keep them for this time. */ extern BOOL ignore_fromline_local; /* Local SMTP ignore fromline */ extern uschar *ignore_fromline_hosts; /* Hosts permitted to send "From " */ extern BOOL is_inetd; /* True for inetd calls */ +extern uschar *iterate_item; /* Item from iterate list */ extern int journal_fd; /* Fd for journal file */ -- cgit v1.2.3