/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Functions for handling string expansion. */
#include "exim.h"
+#ifdef MACRO_PREDEF
+# include "macro_predef.h"
+#endif
+
typedef unsigned esi_flags;
#define ESI_NOFLAGS 0
#define ESI_BRACE_ENDS BIT(0) /* expansion should stop at } */
#define ESI_HONOR_DOLLAR BIT(1) /* $ is meaningfull */
#define ESI_SKIPPING BIT(2) /* value will not be needed */
+#ifdef STAND_ALONE
+# ifndef SUPPORT_CRYPTEQ
+# define SUPPORT_CRYPTEQ
+# endif
+#else
+
/* Recursively called function */
static uschar *expand_string_internal(const uschar *, esi_flags, const uschar **, BOOL *, BOOL *);
static int_eximarith_t expanded_string_integer(const uschar *, BOOL);
-#ifdef STAND_ALONE
-# ifndef SUPPORT_CRYPTEQ
-# define SUPPORT_CRYPTEQ
-# endif
-#endif
+#endif /*!STAND_ALONE*/
#ifdef LOOKUP_LDAP
# include "lookups/ldap.h"
{ "sender_fullhost", vtype_stringptr, &sender_fullhost },
{ "sender_helo_dnssec", vtype_bool, &sender_helo_dnssec },
{ "sender_helo_name", vtype_stringptr, &sender_helo_name },
+ { "sender_helo_verified",vtype_string_func, (void *) &sender_helo_verified_boolstr },
{ "sender_host_address", vtype_stringptr, &sender_host_address },
{ "sender_host_authenticated",vtype_stringptr, &sender_host_authenticated },
{ "sender_host_dnssec", vtype_bool, &sender_host_dnssec },
{ "warnmsg_recipients", vtype_stringptr, &warnmsg_recipients }
};
-static int var_table_size = nelem(var_table);
+#ifdef MACRO_PREDEF
+
+/* dummies */
+uschar * fn_arc_domains(void) {return NULL;}
+uschar * fn_hdrs_added(void) {return NULL;}
+uschar * fn_queue_size(void) {return NULL;}
+uschar * fn_recipients(void) {return NULL;}
+uschar * sender_helo_verified_boolstr(void) {return NULL;}
+uschar * smtp_cmd_hist(void) {return NULL;}
+
+
+
+static void
+expansion_items(void)
+{
+uschar buf[64];
+for (int i = 0; i < nelem(item_table); i++)
+ {
+ spf(buf, sizeof(buf), CUS"_EXP_ITEM_%T", item_table[i]);
+ builtin_macro_create(buf);
+ }
+}
+static void
+expansion_operators(void)
+{
+uschar buf[64];
+for (int i = 0; i < nelem(op_table_underscore); i++)
+ {
+ spf(buf, sizeof(buf), CUS"_EXP_OP_%T", op_table_underscore[i]);
+ builtin_macro_create(buf);
+ }
+for (int i = 0; i < nelem(op_table_main); i++)
+ {
+ spf(buf, sizeof(buf), CUS"_EXP_OP_%T", op_table_main[i]);
+ builtin_macro_create(buf);
+ }
+}
+static void
+expansion_conditions(void)
+{
+uschar buf[64];
+for (int i = 0; i < nelem(cond_table); i++)
+ {
+ spf(buf, sizeof(buf), CUS"_EXP_COND_%T", cond_table[i]);
+ builtin_macro_create(buf);
+ }
+}
+static void
+expansion_variables(void)
+{
+uschar buf[64];
+for (int i = 0; i < nelem(var_table); i++)
+ {
+ spf(buf, sizeof(buf), CUS"_EXP_VAR_%T", var_table[i].name);
+ builtin_macro_create(buf);
+ }
+}
+
+void
+expansions(void)
+{
+expansion_items();
+expansion_operators();
+expansion_conditions();
+expansion_variables();
+}
+
+#else /*!MACRO_PREDEF*/
+
static uschar var_buffer[256];
static BOOL malformed_header;
find_var_ent(uschar * name)
{
int first = 0;
-int last = var_table_size;
+int last = nelem(var_table);
while (last > first)
{
reset in the middle of the buffer will make it inaccessible. */
len = Ustrlen(value);
+ DEBUG(D_expand) debug_expansion_interim(US"value", value, len, !!(flags & ESI_SKIPPING));
if (!yield && newsize != 0)
{
yield = g;
continue;
}
- if (isdigit(*s))
+ if (isdigit(*s)) /* A $<n> variable */
{
int n;
s = read_cnumber(&n, s);
if (n >= 0 && n <= expand_nmax)
+ {
+ DEBUG(D_expand) debug_expansion_interim(US"value", expand_nstring[n], expand_nlength[n], !!(flags & ESI_SKIPPING));
yield = string_catn(yield, expand_nstring[n], expand_nlength[n]);
+ }
continue;
}
goto EXPAND_FAILED;
}
if (n >= 0 && n <= expand_nmax)
+ {
+ DEBUG(D_expand) debug_expansion_interim(US"value", expand_nstring[n], expand_nlength[n], !!(flags & ESI_SKIPPING));
yield = string_catn(yield, expand_nstring[n], expand_nlength[n]);
+ }
continue;
}
switch(read_subs(sub_arg, nelem(sub_arg), 1, &s, flags, TRUE, name, &resetok, NULL))
{
+ case -1: continue; /* If skipping, we don't actually do anything */
case 1: goto EXPAND_FAILED_CURLY;
case 2:
case 3: goto EXPAND_FAILED;
}
- /*XXX no skipping-optimisation? */
yield = string_append(yield, 3,
US"Authentication-Results: ", sub_arg[0], US"; none");
case 2:
case 3: goto EXPAND_FAILED;
}
- /*XXX no skipping-optimisation? */
if (!sub_arg[1]) /* One argument */
{
switch(read_subs(sub_arg, 2, 1, &s, flags, TRUE, name, &resetok, NULL))
{
+ case -1: continue; /* If skipping, we don't actually do anything */
case 1: goto EXPAND_FAILED_CURLY;
case 2:
case 3: goto EXPAND_FAILED;
}
- /* If skipping, we don't actually do anything */
-
- if (flags & ESI_SKIPPING) continue;
-
/* Open the file and read it */
if (!(f = Ufopen(sub_arg[0], "rb")))
const uschar * arg, ** argv;
BOOL late_expand = TRUE;
- if ((expand_forbid & RDO_RUN) != 0)
+ if (expand_forbid & RDO_RUN)
{
expand_string_message = US"running a command is not permitted";
goto EXPAND_FAILED;
s++;
if (late_expand) /* this is the default case */
- { /*{*/
- int n = Ustrcspn(s, "}");
+ {
+ int n;
+ const uschar * t;
+ /* Locate the end of the args */
+ (void) expand_string_internal(s,
+ ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | ESI_SKIPPING, &t, NULL, NULL);
+ n = t - s;
arg = flags & ESI_SKIPPING ? NULL : string_copyn(s, n);
s += n;
}
else
{
+ DEBUG(D_expand)
+ debug_printf_indent("args string for ${run} expand before split\n");
if (!(arg = expand_string_internal(s,
ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, &s, &resetok, NULL)))
goto EXPAND_FAILED;
save_expand_strings(save_expand_nstring, save_expand_nlength);
/* Read the field & list arguments */
+ /*XXX Could we use read_subs here (and get better efficiency for skipping)? */
for (int i = 0; i < 2; i++)
{
/* Deal specially with operators that might take a certificate variable
as we do not want to do the usual expansion. For most, expand the string.*/
+
switch(c)
{
#ifndef DISABLE_TLS
to the main loop top. */
{
- int start = yield->ptr;
+ unsigned expansion_start = gstring_length(yield);
switch(c)
{
case EOP_BASE32:
DEBUG(D_expand)
{
- const uschar * s = yield->s + start;
- int i = yield->ptr - start;
+ const uschar * s = yield->s + expansion_start;
+ int i = gstring_length(yield) - expansion_start;
BOOL tainted = is_tainted(s);
DEBUG(D_noutf8)
#endif
/* check known-name variables */
-for (var_entry * v = var_table; v < var_table + var_table_size; v++)
+for (var_entry * v = var_table; v < var_table + nelem(var_table); v++)
if (v->type == vtype_stringptr)
assert_variable_notin(US v->name, *(USS v->value), &e);
return 0;
}
-#endif
+#endif /*STAND_ALONE*/
+#endif /*!MACRO_PREDEF*/
/* vi: aw ai sw=2
*/
/* End of expand.c */