X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fexpand.c;h=89e0ac7794f54526f74e3fe87534a6757a91dafa;hb=790fbb71d92b47c6637892f3feedc0f99000f01e;hp=2092701630b254008d68dfdef81dd869ebd6f131;hpb=ed0512a1a151a4108d7fe309055219c2da3b2bbc;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/expand.c b/src/src/expand.c index 209270163..89e0ac779 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2014 */ +/* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -94,10 +94,6 @@ bcrypt ({CRYPT}$2a$). -#ifndef nelements -# define nelements(arr) (sizeof(arr) / sizeof(*arr)) -#endif - /************************************************* * Local statics and tables * *************************************************/ @@ -109,6 +105,7 @@ static uschar *item_table[] = { US"acl", US"certextract", US"dlfunc", + US"env", US"extract", US"filter", US"hash", @@ -138,6 +135,7 @@ enum { EITEM_ACL, EITEM_CERTEXTRACT, EITEM_DLFUNC, + EITEM_ENV, EITEM_EXTRACT, EITEM_FILTER, EITEM_HASH, @@ -237,7 +235,7 @@ static uschar *op_table_main[] = { US"utf8clean" }; enum { - EOP_ADDRESS = sizeof(op_table_underscore)/sizeof(uschar *), + EOP_ADDRESS = nelem(op_table_underscore), EOP_ADDRESSES, EOP_BASE62, EOP_BASE62D, @@ -648,6 +646,7 @@ static var_entry var_table[] = { { "sender_address_local_part", vtype_localpart, &sender_address }, { "sender_data", vtype_stringptr, &sender_data }, { "sender_fullhost", vtype_stringptr, &sender_fullhost }, + { "sender_helo_dnssec", vtype_bool, &sender_helo_dnssec }, { "sender_helo_name", vtype_stringptr, &sender_helo_name }, { "sender_host_address", vtype_stringptr, &sender_host_address }, { "sender_host_authenticated",vtype_stringptr, &sender_host_authenticated }, @@ -761,7 +760,7 @@ static var_entry var_table[] = { { "warnmsg_recipients", vtype_stringptr, &warnmsg_recipients } }; -static int var_table_size = sizeof(var_table)/sizeof(var_entry); +static int var_table_size = nelem(var_table); static uschar var_buffer[256]; static BOOL malformed_header; @@ -1286,7 +1285,7 @@ if (*field >= '0' && *field <= '9') return tls_cert_ext_by_oid(*(void **)vp->value, field, 0); for(cp = certfields; - cp < certfields + nelements(certfields); + cp < certfields + nelem(certfields); cp++) if (Ustrncmp(cp->name, field, cp->namelen) == 0) { @@ -1456,7 +1455,7 @@ unsigned long int total = 0; /* no overflow */ while (*s != 0) { - if (i == 0) i = sizeof(prime)/sizeof(int) - 1; + if (i == 0) i = nelem(prime) - 1; total += prime[i--] * (unsigned int)(*s++); } @@ -2054,7 +2053,7 @@ int ret; uschar * dummy_logmsg; extern int acl_where; -if(--nsub > sizeof(acl_arg)/sizeof(*acl_arg)) nsub = sizeof(acl_arg)/sizeof(*acl_arg); +if(--nsub > nelem(acl_arg)) nsub = nelem(acl_arg); for (i = 0; i < nsub && sub[i+1]; i++) { uschar * tmp = acl_arg[i]; @@ -2156,7 +2155,7 @@ if (name[0] == 0) /* Find which condition we are dealing with, and switch on it */ -cond_type = chop_match(name, cond_table, sizeof(cond_table)/sizeof(uschar *)); +cond_type = chop_match(name, cond_table, nelem(cond_table)); switch(cond_type) { /* def: tests for a non-empty variable, or for the existence of a header. If @@ -2345,7 +2344,7 @@ switch(cond_type) while (isspace(*s)) s++; if (*s++ != '{') goto COND_FAILED_CURLY_START; /*}*/ - switch(read_subs(sub, sizeof(sub)/sizeof(*sub), 1, + switch(read_subs(sub, nelem(sub), 1, &s, yield == NULL, TRUE, US"acl", resetok)) { case 1: expand_string_message = US"too few arguments or bracketing " @@ -2355,7 +2354,7 @@ switch(cond_type) } *resetok = FALSE; - if (yield != NULL) switch(eval_acl(sub, sizeof(sub)/sizeof(*sub), &user_msg)) + if (yield != NULL) switch(eval_acl(sub, nelem(sub), &user_msg)) { case OK: cond = TRUE; @@ -2387,29 +2386,32 @@ switch(cond_type) in their own set of braces. */ case ECOND_SASLAUTHD: - #ifndef CYRUS_SASLAUTHD_SOCKET - goto COND_FAILED_NOT_COMPILED; - #else - while (isspace(*s)) s++; - if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */ - switch(read_subs(sub, 4, 2, &s, yield == NULL, TRUE, US"saslauthd", resetok)) - { - case 1: expand_string_message = US"too few arguments or bracketing " - "error for saslauthd"; - case 2: - case 3: return NULL; - } - if (sub[2] == NULL) sub[3] = NULL; /* realm if no service */ - if (yield != NULL) +#ifndef CYRUS_SASLAUTHD_SOCKET + goto COND_FAILED_NOT_COMPILED; +#else { - int rc; - rc = auth_call_saslauthd(sub[0], sub[1], sub[2], sub[3], - &expand_string_message); - if (rc == ERROR || rc == DEFER) return NULL; - *yield = (rc == OK) == testfor; + uschar *sub[4]; + while (isspace(*s)) s++; + if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */ + switch(read_subs(sub, nelem(sub), 2, &s, yield == NULL, TRUE, US"saslauthd", + resetok)) + { + case 1: expand_string_message = US"too few arguments or bracketing " + "error for saslauthd"; + case 2: + case 3: return NULL; + } + if (sub[2] == NULL) sub[3] = NULL; /* realm if no service */ + if (yield != NULL) + { + int rc = auth_call_saslauthd(sub[0], sub[1], sub[2], sub[3], + &expand_string_message); + if (rc == ERROR || rc == DEFER) return NULL; + *yield = (rc == OK) == testfor; + } + return s; } - return s; - #endif /* CYRUS_SASLAUTHD_SOCKET */ +#endif /* CYRUS_SASLAUTHD_SOCKET */ /* symbolic operators for numeric and string comparison, and a number of @@ -3982,7 +3984,7 @@ while (*s != 0) OK. */ s = read_name(name, sizeof(name), s, US"_-"); - item_type = chop_match(name, item_table, sizeof(item_table)/sizeof(uschar *)); + item_type = chop_match(name, item_table, nelem(item_table)); switch(item_type) { @@ -4001,7 +4003,8 @@ while (*s != 0) uschar *sub[10]; /* name + arg1-arg9 (which must match number of acl_arg[]) */ uschar *user_msg; - switch(read_subs(sub, 10, 1, &s, skipping, TRUE, US"acl", &resetok)) + switch(read_subs(sub, nelem(sub), 1, &s, skipping, TRUE, US"acl", + &resetok)) { case 1: goto EXPAND_FAILED_CURLY; case 2: @@ -4010,7 +4013,7 @@ while (*s != 0) if (skipping) continue; resetok = FALSE; - switch(eval_acl(sub, sizeof(sub)/sizeof(*sub), &user_msg)) + switch(eval_acl(sub, nelem(sub), &user_msg)) { case OK: case FAIL: @@ -4082,7 +4085,8 @@ while (*s != 0) uschar *sub_arg[3]; uschar *encoded; - switch(read_subs(sub_arg, 3, 1, &s, skipping, TRUE, name, &resetok)) + switch(read_subs(sub_arg, nelem(sub_arg), 1, &s, skipping, TRUE, name, + &resetok)) { case 1: goto EXPAND_FAILED_CURLY; case 2: @@ -4091,13 +4095,10 @@ while (*s != 0) if (sub_arg[1] == NULL) /* One argument */ { - sub_arg[1] = "/"; /* default separator */ + sub_arg[1] = US"/"; /* default separator */ sub_arg[2] = NULL; } - else if (sub_arg[2] == NULL) /* Two arguments */ - sub_arg[2] = NULL; - - if (Ustrlen(sub_arg[1]) != 1) + else if (Ustrlen(sub_arg[1]) != 1) { expand_string_message = string_sprintf( @@ -5204,7 +5205,7 @@ while (*s != 0) { int ovector[3*(EXPAND_MAXN+1)]; int n = pcre_exec(re, NULL, CS subject, slen, moffset + moffsetextra, - PCRE_EOPT | emptyopt, ovector, sizeof(ovector)/sizeof(int)); + PCRE_EOPT | emptyopt, ovector, nelem(ovector)); int nn; uschar *insert; @@ -5861,12 +5862,12 @@ while (*s != 0) #define EXPAND_DLFUNC_MAX_ARGS 8 case EITEM_DLFUNC: - #ifndef EXPAND_DLFUNC - expand_string_message = US"\"${dlfunc\" encountered, but this facility " /*}*/ - "is not included in this binary"; - goto EXPAND_FAILED; +#ifndef EXPAND_DLFUNC + expand_string_message = US"\"${dlfunc\" encountered, but this facility " /*}*/ + "is not included in this binary"; + goto EXPAND_FAILED; - #else /* EXPAND_DLFUNC */ +#else /* EXPAND_DLFUNC */ { tree_node *t; exim_dlfunc_t *func; @@ -5952,7 +5953,39 @@ while (*s != 0) goto EXPAND_FAILED; } } - #endif /* EXPAND_DLFUNC */ +#endif /* EXPAND_DLFUNC */ + + case EITEM_ENV: /* ${env {name} {val_if_found} {val_if_unfound}} */ + { + uschar * key; + uschar *save_lookup_value = lookup_value; + + while (isspace(*s)) s++; + if (*s != '{') /*}*/ + goto EXPAND_FAILED; + + key = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok); + if (!key) goto EXPAND_FAILED; /*{*/ + if (*s++ != '}') goto EXPAND_FAILED_CURLY; + + lookup_value = US getenv(CS key); + + switch(process_yesno( + skipping, /* were previously skipping */ + lookup_value != NULL, /* success/failure indicator */ + save_lookup_value, /* value to reset for string2 */ + &s, /* input pointer */ + &yield, /* output pointer */ + &size, /* output size */ + &ptr, /* output current point */ + US"env", /* condition type */ + &resetok)) + { + case 1: goto EXPAND_FAILED; /* when all is well, the */ + case 2: goto EXPAND_FAILED_CURLY; /* returned value is 0 */ + } + continue; + } } /* EITEM_* switch */ /* Control reaches here if the name is not recognized as one of the more @@ -5973,13 +6006,12 @@ while (*s != 0) the arguments and then scan the main table. */ if ((c = chop_match(name, op_table_underscore, - sizeof(op_table_underscore)/sizeof(uschar *))) < 0) + nelem(op_table_underscore))) < 0) { arg = Ustrchr(name, '_'); if (arg != NULL) *arg = 0; - c = chop_match(name, op_table_main, - sizeof(op_table_main)/sizeof(uschar *)); - if (c >= 0) c += sizeof(op_table_underscore)/sizeof(uschar *); + c = chop_match(name, op_table_main, nelem(op_table_main)); + if (c >= 0) c += nelem(op_table_underscore); if (arg != NULL) *arg++ = '_'; /* Put back for error messages */ } @@ -7360,7 +7392,7 @@ regex_match_and_setup(const pcre *re, uschar *subject, int options, int setup) { int ovector[3*(EXPAND_MAXN+1)]; int n = pcre_exec(re, NULL, subject, Ustrlen(subject), 0, PCRE_EOPT|options, - ovector, sizeof(ovector)/sizeof(int)); + ovector, nelem(ovector)); BOOL yield = n >= 0; if (n == 0) n = EXPAND_MAXN + 1; if (yield)