typedef uschar * stringptr_fn_t(void);
static uschar * fn_recipients(void);
+static uschar * fn_recipients_list(void);
static uschar * fn_queue_size(void);
/* This table must be kept in alphabetical order. */
{ "recipient_verify_failure",vtype_stringptr,&recipient_verify_failure },
{ "recipients", vtype_string_func, (void *) &fn_recipients },
{ "recipients_count", vtype_int, &recipients_count },
+ { "recipients_list", vtype_string_func, (void *) &fn_recipients_list },
{ "regex_cachesize", vtype_int, ®ex_cachesize },/* undocumented; devel observability */
#ifdef WITH_CONTENT_SCAN
{ "regex_match_string", vtype_stringptr, ®ex_match_string },
uschar * fn_hdrs_added(void) {return NULL;}
uschar * fn_queue_size(void) {return NULL;}
uschar * fn_recipients(void) {return NULL;}
+uschar * fn_recipients_list(void) {return NULL;}
uschar * sender_helo_verified_boolstr(void) {return NULL;}
uschar * smtp_cmd_hist(void) {return NULL;}
*************************************************/
/* A recipients list is available only during system message filtering,
during ACL processing after DATA, and while expanding pipe commands
-generated from a system filter, but not elsewhere. */
+generated from a system filter, but not elsewhere. Note that this does
+not check for comman in the elements, and uses comma-space as seperator -
+so cannot be used as an exim list as-is. */
static uschar *
fn_recipients(void)
s = recipients_list[i].address;
g = string_append2_listele_n(g, US", ", s, Ustrlen(s));
}
+gstring_release_unused(g);
+return string_from_gstring(g);
+}
+
+/* Similar, but as a properly-quoted exim list */
+
+
+static uschar *
+fn_recipients_list(void)
+{
+gstring * g = NULL;
+
+if (!f.enable_dollar_recipients) return NULL;
+
+for (int i = 0; i < recipients_count; i++)
+ g = string_append_listele(g, ':', recipients_list[i].address);
+gstring_release_unused(g);
return string_from_gstring(g);
}
case vtype_string_func:
{
stringptr_fn_t * fn = (stringptr_fn_t *) val;
- uschar* s = fn();
+ uschar * s = fn();
return s ? s : US"";
}
{
FILE * f;
const uschar * arg, ** argv;
- BOOL late_expand = TRUE;
+ unsigned late_expand = TSUC_EXPAND_ARGS | TSUC_ALLOW_TAINTED_ARGS | TSUC_ALLOW_RECIPIENTS;
if (expand_forbid & RDO_RUN)
{
while (*s == ',')
if (Ustrncmp(++s, "preexpand", 9) == 0)
- { late_expand = FALSE; s += 9; }
+ { late_expand = 0; s += 9; }
else
{
const uschar * t = s;
late_expand, /* expand args if not already done */
0, /* not relevant when... */
NULL, /* no transporting address */
- late_expand, /* allow tainted args, when expand-after-split */
US"${run} expansion", /* for error messages */
&expand_string_message)) /* where to put error message */
goto EXPAND_FAILED;
case 3: goto EXPAND_FAILED;
}
- yield = string_cat(yield, sub[0]);
- o2m = Ustrlen(sub[2]) - 1;
-
- if (o2m >= 0) for (; oldptr < yield->ptr; oldptr++)
+ if ( (yield = string_cat(yield, sub[0]))
+ && (o2m = Ustrlen(sub[2]) - 1) >= 0)
+ for (; oldptr < yield->ptr; oldptr++)
{
uschar * m = Ustrrchr(sub[1], yield->s[oldptr]);
if (m)
{
int o = m - sub[1];
- yield->s[oldptr] = sub[2][(o < o2m)? o : o2m];
+ yield->s[oldptr] = sub[2][o < o2m ? o : o2m];
}
}
case EOP_BASE64D:
{
uschar * s;
- int len = b64decode(sub, &s);
+ int len = b64decode(sub, &s, sub);
if (len < 0)
{
expand_string_message = string_sprintf("string \"%s\" is not "