*************************************************/
/* Copyright (c) University of Cambridge 1995 - 2018 */
+/* Copyright (c) The Exim Maintainers 2020 - 2021 */
/* See the file NOTICE for conditions of use and distribution. */
/* Miscellaneous other declarations */
static uschar **error_pointer;
-static uschar *log_filename;
+static const uschar *log_filename;
static int filter_options;
static int line_number;
static int expect_endif;
test_condition(condition_block *c, BOOL toplevel)
{
BOOL yield = FALSE;
-const pcre *re;
uschar *exp[2], *p, *pp;
-const uschar *regcomp_error = NULL;
-int regcomp_error_offset;
int val[2];
int i;
parse_extract_address(pp, &error, &start, &end, &domain, FALSE);
*p = saveend;
- if (filter_thisaddress != NULL)
+ if (filter_thisaddress)
{
if ((filter_test != FTEST_NONE && debug_selector != 0) ||
(debug_selector & D_filter) != 0)
case cond_matches:
case cond_MATCHES:
- if ((filter_test != FTEST_NONE && debug_selector != 0) ||
- (debug_selector & D_filter) != 0)
{
- debug_printf_indent("Match expanded arguments:\n");
- debug_printf_indent(" Subject = %s\n", exp[0]);
- debug_printf_indent(" Pattern = %s\n", exp[1]);
- }
+ const pcre2_code *re;
+ int err;
+ PCRE2_SIZE offset;
- re = pcre_compile(CS exp[1],
- PCRE_COPT | ((c->type == cond_matches)? PCRE_CASELESS : 0),
- (const char **)®comp_error, ®comp_error_offset, NULL);
+ if ((filter_test != FTEST_NONE && debug_selector != 0) ||
+ (debug_selector & D_filter) != 0)
+ {
+ debug_printf_indent("Match expanded arguments:\n");
+ debug_printf_indent(" Subject = %s\n", exp[0]);
+ debug_printf_indent(" Pattern = %s\n", exp[1]);
+ }
- if (re == NULL)
- {
- *error_pointer = string_sprintf("error while compiling "
- "regular expression \"%s\": %s at offset %d",
- exp[1], regcomp_error, regcomp_error_offset);
- return FALSE;
- }
+ if (!(re = pcre2_compile((PCRE2_SPTR)exp[1], PCRE2_ZERO_TERMINATED,
+ PCRE_COPT | (c->type == cond_matches ? PCRE2_CASELESS : 0),
+ &err, &offset, pcre_cmp_ctx)))
+ {
+ uschar errbuf[128];
+ pcre2_get_error_message(err, errbuf, sizeof(errbuf));
+ *error_pointer = string_sprintf("error while compiling "
+ "regular expression \"%s\": %s at offset %ld",
+ exp[1], errbuf, (long)offset);
+ return FALSE;
+ }
- yield = regex_match_and_setup(re, exp[0], PCRE_EOPT, -1);
- break;
+ yield = regex_match_and_setup(re, exp[0], PCRE_EOPT, -1);
+ break;
+ }
/* For above and below, convert the strings to numbers */
static int
interpret_commands(filter_cmd *commands, address_item **generated)
{
-uschar *s;
+const uschar *s;
int mode;
address_item *addr;
BOOL condition_value;
{
int ff_ret;
uschar *fmsg, *ff_name;
- uschar *expargs[MAILARGS_STRING_COUNT];
+ const uschar *expargs[MAILARGS_STRING_COUNT];
int i, n[2];
case add_command:
for (i = 0; i < 2; i++)
{
- uschar *ss = expargs[i];
+ const uschar *ss = expargs[i];
uschar *end;
if (i == 1 && (*ss++ != 'n' || ss[1] != 0))
uschar *error;
uschar *ss = parse_extract_address(s, &error, &start, &end, &domain,
FALSE);
- if (ss != NULL)
- expargs[i] = ((filter_options & RDO_REWRITE) != 0)?
- rewrite_address(ss, TRUE, FALSE, global_rewrite_rules,
- rewrite_existflags) :
- rewrite_address_qualify(ss, TRUE);
+ if (ss)
+ expargs[i] = filter_options & RDO_REWRITE
+ ? rewrite_address(ss, TRUE, FALSE, global_rewrite_rules,
+ rewrite_existflags)
+ : rewrite_address_qualify(ss, TRUE);
else
{
*error_pointer = string_sprintf("malformed address \"%s\" in "
af_ignore_error flag if necessary, and the errors address, which can be
set in a system filter and to the local address in user filters. */
- addr = deliver_make_addr(expargs[0], TRUE); /* TRUE => copy s */
- addr->prop.errors_address = (s == NULL)?
- s : string_copy(s); /* Default is NULL */
+ addr = deliver_make_addr(US expargs[0], TRUE); /* TRUE => copy s, so deconst ok */
+ addr->prop.errors_address = !s ? NULL : string_copy(s); /* Default is NULL */
if (commands->noerror) addr->prop.ignore_error = TRUE;
addr->next = *generated;
*generated = addr;
af_pfr and af_file flags, the af_ignore_error flag if necessary, and the
mode value. */
- addr = deliver_make_addr(s, TRUE); /* TRUE => copy s */
+ addr = deliver_make_addr(US s, TRUE); /* TRUE => copy s, so deconst ok */
setflag(addr, af_pfr);
setflag(addr, af_file);
if (commands->noerror) addr->prop.ignore_error = TRUE;
each command argument is expanded in the transport after the command
has been split up into separate arguments. */
- addr = deliver_make_addr(s, TRUE); /* TRUE => copy s */
+ addr = deliver_make_addr(US s, TRUE); /* TRUE => copy s, so deconst ok */
setflag(addr, af_pfr);
setflag(addr, af_expand_pipe);
if (commands->noerror) addr->prop.ignore_error = TRUE;
(long int)geteuid());
if (log_fd < 0)
{
- if (log_filename == NULL)
+ if (!log_filename)
{
*error_pointer = US"attempt to obey \"logwrite\" command "
"without a previous \"logfile\"";
log_fd = Uopen(log_filename, O_CREAT|O_APPEND|O_WRONLY, log_mode);
if (log_fd < 0)
{
- *error_pointer = string_open_failed(errno, "filter log file \"%s\"",
+ *error_pointer = string_open_failed("filter log file \"%s\"",
log_filename);
return FF_ERROR;
}
}
}
else
- {
- DEBUG(D_filter) debug_printf_indent("skipping logwrite (verifying or testing)\n");
- }
+ DEBUG(D_filter)
+ debug_printf_indent("skipping logwrite (verifying or testing)\n");
break;
/* Header addition and removal is available only in the system filter. The
s = expargs[0];
if (filter_test != FTEST_NONE)
- printf("Headers %s \"%s\"\n", (subtype == TRUE)? "add" :
- (subtype == FALSE)? "remove" : "charset", string_printing(s));
+ printf("Headers %s \"%s\"\n",
+ subtype == TRUE ? "add"
+ : subtype == FALSE ? "remove"
+ : "charset",
+ string_printing(s));
if (subtype == TRUE)
{
while (isspace(*s)) s++;
- if (s[0] != 0)
+ if (*s)
{
- header_add(htype_other, "%s%s", s, (s[Ustrlen(s)-1] == '\n')?
- "" : "\n");
+ header_add(htype_other, "%s%s", s,
+ s[Ustrlen(s)-1] == '\n' ? "" : "\n");
header_last->type = header_checkname(header_last, FALSE);
if (header_last->type >= 'a') header_last->type = htype_other;
}
else if (subtype == FALSE)
{
int sep = 0;
- uschar *ss;
- const uschar *list = s;
- uschar buffer[128];
- while ((ss = string_nextinlist(&list, &sep, buffer, sizeof(buffer)))
- != NULL)
+ const uschar * list = s;
+
+ for (uschar * ss; ss = string_nextinlist(&list, &sep, NULL, 0); )
header_remove(0, ss);
}
ff_name = US"freeze";
ff_ret = FF_FREEZE;
- DEFERFREEZEFAIL:
- fmsg = expargs[0];
- if (Ustrlen(fmsg) > 1024) Ustrcpy(fmsg + 1000, US" ... (truncated)");
- fmsg = US string_printing(fmsg);
- *error_pointer = fmsg;
+ DEFERFREEZEFAIL:
+ *error_pointer = fmsg = US string_printing(Ustrlen(expargs[0]) > 1024
+ ? string_sprintf("%.1000s ... (truncated)", expargs[0])
+ : string_copy(expargs[0]));
if (filter_test != FTEST_NONE)
{
indent();
printf("%c%s text \"%s\"\n", toupper(ff_name[0]), ff_name+1, fmsg);
}
- else DEBUG(D_filter) debug_printf_indent("Filter: %s \"%s\"\n", ff_name, fmsg);
+ else
+ DEBUG(D_filter) debug_printf_indent("Filter: %s \"%s\"\n", ff_name, fmsg);
return ff_ret;
case finish_command:
printf("%sinish\n", (commands->seen)? "Seen f" : "F");
}
else
- {
DEBUG(D_filter) debug_printf_indent("Filter: %sfinish\n",
- (commands->seen)? " Seen " : "");
- }
+ commands->seen ? " Seen " : "");
finish_obeyed = TRUE;
- return filter_delivered? FF_DELIVERED : FF_NOTDELIVERED;
+ return filter_delivered ? FF_DELIVERED : FF_NOTDELIVERED;
case if_command:
{
uschar *save_address = filter_thisaddress;
int ok = FF_DELIVERED;
condition_value = test_condition(commands->args[0].c, TRUE);
- if (*error_pointer != NULL) ok = FF_ERROR; else
+ if (*error_pointer)
+ ok = FF_ERROR;
+ else
{
output_indent += 2;
ok = interpret_commands(commands->args[condition_value? 1:2].f,
output_indent -= 2;
}
filter_thisaddress = save_address;
- if (finish_obeyed || (ok != FF_DELIVERED && ok != FF_NOTDELIVERED))
+ if (finish_obeyed || ok != FF_DELIVERED && ok != FF_NOTDELIVERED)
return ok;
}
break;
case mail_command:
case vacation_command:
- if (return_path == NULL || return_path[0] == 0)
+ if (!return_path || !*return_path)
{
if (filter_test != FTEST_NONE)
printf("%s command ignored because return_path is empty\n",
for (i = 0; i < MAILARGS_STRING_COUNT; i++)
{
- uschar *p;
- uschar *s = expargs[i];
+ const uschar *p;
+ const uschar *s = expargs[i];
- if (s == NULL) continue;
+ if (!s) continue;
if (i != mailarg_index_text) for (p = s; *p != 0; p++)
{
else
{
- uschar *pp;
+ const uschar *pp;
for (pp = p + 1;; pp++)
{
c = *pp;
if (c == ':' && pp != p + 1) break;
- if (c == 0 || c == ':' || isspace(*pp))
+ if (!c || c == ':' || isspace(c))
{
*error_pointer = string_sprintf("\\n not followed by space or "
"valid header name in \"%.1024s\" in %s command",
/* The string is OK */
- commands->args[i].u = s;
+ commands->args[i].u = s; /*XXX loses track of const */
}
/* Proceed with mail or vacation command */
commands->noerror ? " (noerror)" : "");
for (i = 1; i < MAILARGS_STRING_COUNT; i++)
{
- uschar *arg = commands->args[i].u;
+ const uschar *arg = commands->args[i].u;
if (arg)
{
int len = Ustrlen(mailargs[i]);
BOOL
filter_personal(string_item *aliases, BOOL scan_cc)
{
-uschar *self, *self_from, *self_to;
-uschar *psself = NULL, *psself_from = NULL, *psself_to = NULL;
+const uschar *self, *self_from, *self_to;
+uschar *psself = NULL;
+const uschar *psself_from = NULL, *psself_to = NULL;
rmark reset_point = store_mark();
BOOL yield;
header_line *h;
for (h = header_list; h; h = h->next)
{
- uschar *s;
if (h->type == htype_old) continue;
if (strncmpic(h->text, US"List-", 5) == 0)
{
- s = h->text + 5;
+ uschar * s = h->text + 5;
if (strncmpic(s, US"Id:", 3) == 0 ||
strncmpic(s, US"Help:", 5) == 0 ||
strncmpic(s, US"Subscribe:", 10) == 0 ||
else if (strncmpic(h->text, US"Auto-submitted:", 15) == 0)
{
- s = h->text + 15;
- while (isspace(*s)) s++;
+ uschar * s = h->text + 15;
+ Uskip_whitespace(&s);
if (strncmpic(s, US"no", 2) != 0) return FALSE;
s += 2;
- while (isspace(*s)) s++;
- if (*s != 0) return FALSE;
+ Uskip_whitespace(&s);
+ if (*s) return FALSE;
}
}
global_rewrite_rules);
-if (self_from == NULL) self_from = self;
-if (self_to == NULL) self_to = self;
+if (!self_from) self_from = self;
+if (self_to) self_to = self;
/* If there's a prefix or suffix set, we must include the prefixed/
suffixed version of the local part in the tests. */
-if (deliver_localpart_prefix != NULL || deliver_localpart_suffix != NULL)
+if (deliver_localpart_prefix || deliver_localpart_suffix)
{
psself = string_sprintf("%s%s%s@%s",
- (deliver_localpart_prefix == NULL)? US"" : deliver_localpart_prefix,
+ deliver_localpart_prefix ? deliver_localpart_prefix : US"",
deliver_localpart,
- (deliver_localpart_suffix == NULL)? US"" : deliver_localpart_suffix,
+ deliver_localpart_suffix ? deliver_localpart_suffix : US"",
deliver_domain);
psself_from = rewrite_one(psself, rewrite_from, NULL, FALSE, US"",
global_rewrite_rules);
int i;
int yield = FF_ERROR;
uschar *ptr = filter;
-uschar *save_headers_charset = headers_charset;
+const uschar *save_headers_charset = headers_charset;
filter_cmd *commands = NULL;
filter_cmd **lastcmdptr = &commands;