US"h",
US"hash",
US"hex2b64",
+ US"hexquote",
US"l",
US"lc",
US"length",
EOP_H,
EOP_HASH,
EOP_HEX2B64,
+ EOP_HEXQUOTE,
EOP_L,
EOP_LC,
EOP_LENGTH,
{ "address_data", vtype_stringptr, &deliver_address_data },
{ "address_file", vtype_stringptr, &address_file },
{ "address_pipe", vtype_stringptr, &address_pipe },
+ { "authenticated_fail_id",vtype_stringptr, &authenticated_fail_id },
{ "authenticated_id", vtype_stringptr, &authenticated_id },
{ "authenticated_sender",vtype_stringptr, &authenticated_sender },
{ "authentication_failed",vtype_int, &authentication_failed },
{ "dkim_signers", vtype_stringptr, &dkim_signers },
{ "dkim_verify_reason", vtype_dkim, (void *)DKIM_VERIFY_REASON },
{ "dkim_verify_status", vtype_dkim, (void *)DKIM_VERIFY_STATUS},
+#endif
+#ifdef EXPERIMENTAL_DMARC
+ { "dmarc_ar_header", vtype_stringptr, &dmarc_ar_header },
+ { "dmarc_status", vtype_stringptr, &dmarc_status },
+ { "dmarc_status_text", vtype_stringptr, &dmarc_status_text },
+ { "dmarc_used_domain", vtype_stringptr, &dmarc_used_domain },
#endif
{ "dnslist_domain", vtype_stringptr, &dnslist_domain },
{ "dnslist_matched", vtype_stringptr, &dnslist_matched },
{ "reply_address", vtype_reply, NULL },
{ "return_path", vtype_stringptr, &return_path },
{ "return_size_limit", vtype_int, &bounce_return_size_limit },
+ { "router_name", vtype_stringptr, &router_name },
{ "runrc", vtype_int, &runrc },
{ "self_hostname", vtype_stringptr, &self_hostname },
{ "sender_address", vtype_stringptr, &sender_address },
{ "tod_logfile", vtype_todlf, NULL },
{ "tod_zone", vtype_todzone, NULL },
{ "tod_zulu", vtype_todzulu, NULL },
+#ifdef EXPERIMENTAL_TPDA
+ { "tpda_defer_errno", vtype_int, &tpda_defer_errno },
+ { "tpda_defer_errstr", vtype_stringptr, &tpda_defer_errstr },
+ { "tpda_delivery_confirmation", vtype_stringptr, &tpda_delivery_confirmation },
+ { "tpda_delivery_domain", vtype_stringptr, &tpda_delivery_domain },
+ { "tpda_delivery_fqdn", vtype_stringptr, &tpda_delivery_fqdn },
+ { "tpda_delivery_ip", vtype_stringptr, &tpda_delivery_ip },
+ { "tpda_delivery_local_part",vtype_stringptr,&tpda_delivery_local_part },
+ { "tpda_delivery_port", vtype_int, &tpda_delivery_port },
+#endif
+ { "transport_name", vtype_stringptr, &transport_name },
{ "value", vtype_stringptr, &lookup_value },
{ "version_number", vtype_stringptr, &version_string },
{ "warn_message_delay", vtype_stringptr, &warnmsg_delay },
DEBUG(D_expand)
debug_printf("expanding: acl: %s arg: %s%s\n",
sub[0],
- acl_narg>0 ? sub[1] : US"<none>",
- acl_narg>1 ? " +more" : "");
+ acl_narg>0 ? acl_arg[0] : US"<none>",
+ acl_narg>1 ? " +more" : "");
-ret = acl_eval(acl_where, NULL, sub[0], user_msgp, &tmp);
+ret = acl_eval(acl_where, sub[0], user_msgp, &tmp);
for (i = 0; i < nsub; i++)
acl_arg[i] = sub[i+1]; /* restore old args */
* can just let the other invalid results occur otherwise, as they have
* until now. For this one case, we can coerce.
*/
- if (y == -1 && x == LLONG_MIN && op != '*')
+ if (y == -1 && x == EXIM_ARITH_MIN && op != '*')
{
DEBUG(D_expand)
debug_printf("Integer exception dodging: " PR_EXIM_ARITH "%c-1 coerced to " PR_EXIM_ARITH "\n",
- LLONG_MIN, op, LLONG_MAX);
- x = LLONG_MAX;
+ EXIM_ARITH_MIN, op, EXIM_ARITH_MAX);
+ x = EXIM_ARITH_MAX;
continue;
}
if (op == '*')
continue;
}
+ /*{*/
/* Anything other than $ is just copied verbatim, unless we are
looking for a terminating } character. */
+ /*{*/
if (ket_ends && *s == '}') break;
if (*s != '$' || !honour_dollar)
names can contain any printing characters except space and colon.
For those that don't like typing this much, "$h_" is a synonym for
"$header_". A non-existent header yields a NULL value; nothing is
- inserted. */
+ inserted. */ /*}*/
if (isalpha((*(++s))))
{
continue;
}
- /* Otherwise, if there's no '{' after $ it's an error. */
+ /* Otherwise, if there's no '{' after $ it's an error. */ /*}*/
- if (*s != '{')
+ if (*s != '{') /*}*/
{
- expand_string_message = US"$ not followed by letter, digit, or {";
+ expand_string_message = US"$ not followed by letter, digit, or {"; /*}*/
goto EXPAND_FAILED;
}
if (isdigit((*(++s))))
{
int n;
- s = read_number(&n, s);
+ s = read_number(&n, s); /*{*/
if (*s++ != '}')
- {
+ { /*{*/
expand_string_message = US"} expected after number";
goto EXPAND_FAILED;
}
if (!isalpha(*s))
{
- expand_string_message = US"letter or digit expected after ${";
+ expand_string_message = US"letter or digit expected after ${"; /*}*/
goto EXPAND_FAILED;
}
Otherwise set the key NULL pro-tem. */
while (isspace(*s)) s++;
- if (*s == '{')
+ if (*s == '{') /*}*/
{
key = expand_string_internal(s+1, TRUE, &s, skipping, TRUE);
- if (key == NULL) goto EXPAND_FAILED;
+ if (key == NULL) goto EXPAND_FAILED; /*{*/
if (*s++ != '}') goto EXPAND_FAILED_CURLY;
while (isspace(*s)) s++;
}
/* The type is a string that may contain special characters of various
kinds. Allow everything except space or { to appear; the actual content
- is checked by search_findtype_partial. */
+ is checked by search_findtype_partial. */ /*}*/
- while (*s != 0 && *s != '{' && !isspace(*s))
+ while (*s != 0 && *s != '{' && !isspace(*s)) /*}*/
{
if (nameptr < sizeof(name) - 1) name[nameptr++] = *s;
s++;
case EITEM_PERL:
#ifndef EXIM_PERL
- expand_string_message = US"\"${perl\" encountered, but this facility "
+ expand_string_message = US"\"${perl\" encountered, but this facility " /*}*/
"is not included in this binary";
goto EXPAND_FAILED;
uschar *sub[3];
/* "length" takes only 2 arguments whereas the others take 2 or 3.
- Ensure that sub[2] is set in the ${length case. */
+ Ensure that sub[2] is set in the ${length } case. */
sub[2] = NULL;
switch(read_subs(sub, (item_type == EITEM_LENGTH)? 2:3, 2, &s, skipping,
while (isspace(*s)) s++;
if (*s++ != '}')
- {
+ { /*{*/
expand_string_message = string_sprintf("missing } at end of condition "
"or expression inside \"%s\"", name);
goto EXPAND_FAILED;
}
- while (isspace(*s)) s++;
+ while (isspace(*s)) s++; /*{*/
if (*s++ != '}')
- {
+ { /*{*/
expand_string_message = string_sprintf("missing } at end of \"%s\"",
name);
goto EXPAND_FAILED;
}
- /* If ${dlfunc support is configured, handle calling dynamically-loaded
+ /* If ${dlfunc } support is configured, handle calling dynamically-loaded
functions, unless locked out at this time. Syntax is ${dlfunc{file}{func}}
or ${dlfunc{file}{func}{arg}} or ${dlfunc{file}{func}{arg1}{arg2}} or up to
a maximum of EXPAND_DLFUNC_MAX_ARGS arguments (defined below). */
case EITEM_DLFUNC:
#ifndef EXPAND_DLFUNC
- expand_string_message = US"\"${dlfunc\" encountered, but this facility "
+ expand_string_message = US"\"${dlfunc\" encountered, but this facility " /*}*/
"is not included in this binary";
goto EXPAND_FAILED;
}
}
#endif /* EXPAND_DLFUNC */
- }
+ } /* EITEM_* switch */
/* Control reaches here if the name is not recognized as one of the more
complicated expansion items. Check for the "operator" syntax (name terminated
continue;
}
+ /* Convert octets outside 0x21..0x7E to \xXX form */
+
+ case EOP_HEXQUOTE:
+ {
+ uschar *t = sub - 1;
+ while (*(++t) != 0)
+ {
+ if (*t < 0x21 || 0x7E < *t)
+ yield = string_cat(yield, &size, &ptr,
+ string_sprintf("\\x%02x", *t), 4);
+ else
+ yield = string_cat(yield, &size, &ptr, t, 1);
+ }
+ continue;
+ }
+
/* count the number of list elements */
case EOP_LISTCOUNT:
store instead of copying. Many expansion strings contain just one reference,
so this is a useful optimization, especially for humungous headers
($message_headers). */
-
+ /*{*/
if (*s++ == '}')
{
int len;
default:
break;
case 'k':
- if (value > LLONG_MAX/1024 || value < LLONG_MIN/1024) errno = ERANGE;
+ if (value > EXIM_ARITH_MAX/1024 || value < EXIM_ARITH_MIN/1024) errno = ERANGE;
else value *= 1024;
endptr++;
break;
case 'm':
- if (value > LLONG_MAX/(1024*1024) || value < LLONG_MIN/(1024*1024)) errno = ERANGE;
+ if (value > EXIM_ARITH_MAX/(1024*1024) || value < EXIM_ARITH_MIN/(1024*1024)) errno = ERANGE;
else value *= 1024*1024;
endptr++;
break;
case 'g':
- if (value > LLONG_MAX/(1024*1024*1024) || value < LLONG_MIN/(1024*1024*1024)) errno = ERANGE;
+ if (value > EXIM_ARITH_MAX/(1024*1024*1024) || value < EXIM_ARITH_MIN/(1024*1024*1024)) errno = ERANGE;
else value *= 1024*1024*1024;
endptr++;
break;
else
{
while (isspace(*endptr)) endptr++;
- if (*endptr == 0) return (int)value;
+ if (*endptr == 0) return value;
}
}
#ifdef LOOKUP_PGSQL
pgsql_servers = argv[i];
#endif
+ #ifdef EXPERIMENTAL_REDIS
+ redis_servers = argv[i];
+ #endif
}
#ifdef EXIM_PERL
else opt_perl_startup = argv[i];