* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) The Exim Maintainers 2020 - 2023 */
+/* Copyright (c) The Exim Maintainers 2020 - 2024 */
/* 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 */
uschar ** error)
{
const check_string_block * cb = arg;
-int search_type, partial, affixlen, starflags;
+int partial, affixlen, starflags;
+const lookup_info * li;
int expand_setup = cb->expand_setup;
const uschar * affix, * opts;
uschar *s;
{
int rc;
host_item h;
- BOOL prim = FALSE;
- BOOL secy = FALSE;
- BOOL removed = FALSE;
+ BOOL prim = FALSE, secy = FALSE, removed = FALSE;
const uschar *ss = pattern + 4;
const uschar *ignore_target_hosts = NULL;
- if (strncmpic(ss, US"any", 3) == 0) ss += 3;
+ if (strncmpic(ss, US"any", 3) == 0)
+ ss += 3;
else if (strncmpic(ss, US"primary", 7) == 0)
- {
- ss += 7;
- prim = TRUE;
- }
+ { ss += 7; prim = TRUE; }
else if (strncmpic(ss, US"secondary", 9) == 0)
- {
- ss += 9;
- secy = TRUE;
- }
- else goto NOT_AT_SPECIAL;
+ { ss += 9; secy = TRUE; }
+ else
+ goto NOT_AT_SPECIAL;
- if (strncmpic(ss, US"/ignore=", 8) == 0) ignore_target_hosts = ss + 8;
- else if (*ss) goto NOT_AT_SPECIAL;
+ if (strncmpic(ss, US"/ignore=", 8) == 0)
+ ignore_target_hosts = ss + 8;
+ else if (*ss)
+ goto NOT_AT_SPECIAL;
h.next = NULL;
h.name = s;
the part of the string preceding the semicolon. */
*semicolon = 0;
-search_type = search_findtype_partial(pattern, &partial, &affix, &affixlen,
+li = search_findtype_partial(pattern, &partial, &affix, &affixlen,
&starflags, &opts);
*semicolon = ';';
-if (search_type < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s",
- search_error_message);
+if (!li)
+ log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s", search_error_message);
/* Partial matching is not appropriate for certain lookups (e.g. when looking
up user@domain for sender rejection). There's a flag to disable it. */
/* Set the parameters for the three different kinds of lookup. */
-keyquery = search_args(search_type, s, semicolon+1, &filename, opts);
+keyquery = search_args(li, s, semicolon+1, &filename, opts);
/* Now do the actual lookup; throw away the data returned unless it was asked
for; partial matching is all handled inside search_find(). Note that there is
no search_close() because of the caching arrangements. */
-if (!(handle = search_open(filename, search_type, 0, NULL, NULL)))
+if (!(handle = search_open(filename, li, 0, NULL, NULL)))
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s", search_error_message);
result = search_find(handle, filename, keyquery, partial, affix, affixlen,
starflags, &expand_setup, opts);
BOOL include_unknown = FALSE, ignore_unknown = FALSE,
include_defer = FALSE, ignore_defer = FALSE;
const uschar * list;
-uschar * sss;
-uschar * ot = NULL;
+uschar * ot = NULL, * sss;
BOOL textonly_re;
/* Save time by not scanning for the option name when we don't need it. */
HDEBUG(D_any)
{
- uschar * listname = readconf_find_option(listptr);
+ const uschar * listname = readconf_find_option(listptr);
if (*listname) ot = string_sprintf("%s in %s?", name, listname);
}
-/* If the list is empty, the answer is no. Skip the debugging output for
-an unnamed list. */
+/* If the list is empty, the answer is no. */
if (!*listptr)
{
- HDEBUG(D_lists) if (ot) debug_printf_indent("%s no (option unset)\n", ot);
+ HDEBUG(D_lists)
+ if (ot) debug_printf_indent("%s no (option unset)\n", ot);
+ else debug_printf_indent("%s not in empty list (option unset? cannot trace name)\n", name);
return FAIL;
}
#define LIST_LIMIT_PR 2048
HDEBUG(D_any) if (!ot)
- {
+ { /* We failed to identify an option name, so give the list text */
int n, m;
gstring * g = string_fmt_append(NULL, "%s in \"%n%.*s%n\"",
name, &n, LIST_LIMIT_PR, list, &m);
{
uschar * ss = sss;
- HDEBUG(D_lists) debug_printf_indent("list element: %s\n", ss);
+ HDEBUG(D_lists) debug_printf_indent("list element: %W\n", ss);
/* Address lists may contain +caseful, to restore caseful matching of the
local part. We have to know the layout of the control block, unfortunately.
if (*ss == '!')
{
yield = FAIL;
- while (isspace((*(++ss))));
+ while (isspace(*++ss)) ;
}
else
yield = OK;
namedlist_block * nb;
tree_node * t;
- DEBUG(D_lists)
+ HDEBUG(D_lists)
{ debug_printf_indent(" start sublist %s\n", ss+1); expand_level += 2; }
if (!(t = tree_search(*anchorptr, ss+1)))
{
int res = match_check_list(&(nb->string), 0, anchorptr, &use_cache_bits,
func, arg, type, name, valueptr);
- DEBUG(D_lists)
+ HDEBUG(D_lists)
{ expand_level -= 2; debug_printf_indent(" end sublist %s\n", ss+1); }
switch (res)
p->next = nb->cache_data;
nb->cache_data = p;
if (*valueptr)
- DEBUG(D_lists) debug_printf_indent("data from lookup saved for "
+ HDEBUG(D_lists) debug_printf_indent("data from lookup saved for "
"cache for %s: key '%s' value '%s'\n", ss, p->key, *valueptr);
}
}
else
{
- DEBUG(D_lists)
+ HDEBUG(D_lists)
{
expand_level -= 2;
debug_printf_indent("cached %s match for %s\n",
*valueptr = p->data;
break;
}
- DEBUG(D_lists) debug_printf_indent("cached lookup data = %s\n", *valueptr);
+ HDEBUG(D_lists) debug_printf_indent("cached lookup data = %s\n", *valueptr);
}
}
{
case OK:
HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\")\n", ot,
- (yield == OK)? "yes" : "no", sss);
+ yield == OK ? "yes" : "no", sss);
goto YIELD_RETURN;
case DEFER:
error = string_sprintf("DNS lookup of \"%s\" deferred", ss);
if (ignore_defer)
{
- HDEBUG(D_lists) debug_printf_indent("%s: item ignored by +ignore_defer\n",
- error);
+ HDEBUG(D_lists)
+ debug_printf_indent("%s: item ignored by +ignore_defer\n", error);
break;
}
if (include_defer)
case ERROR:
if (ignore_unknown)
{
- HDEBUG(D_lists) debug_printf_indent("%s: item ignored by +ignore_unknown\n",
- error);
+ HDEBUG(D_lists) debug_printf_indent(
+ "%s: item ignored by +ignore_unknown\n", error);
}
else
{
if (!f)
{
- uschar * listname = readconf_find_option(listptr);
- if (listname[0] == 0)
+ const uschar * listname = readconf_find_option(listptr);
+ if (!*listname)
listname = string_sprintf("\"%s\"", *listptr);
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s",
string_open_failed("%s when checking %s", sss, listname));
while (Ufgets(filebuffer, sizeof(filebuffer), f) != NULL)
{
- uschar *error;
- uschar *sss = filebuffer;
+ uschar * error, * sss = filebuffer;
while ((ss = Ustrchr(sss, '#')) != NULL)
{
if ((type != MCL_ADDRESS && type != MCL_LOCALPART) ||
ss == filebuffer || isspace(ss[-1]))
{
- *ss = 0;
+ *ss = '\0';
break;
}
sss = ss + 1;
ss = filebuffer + Ustrlen(filebuffer); /* trailing space */
while (ss > filebuffer && isspace(ss[-1])) ss--;
- *ss = 0;
+ *ss = '\0';
ss = filebuffer;
- while (isspace(*ss)) ss++; /* leading space */
-
- if (!*ss) continue; /* ignore empty */
+ if (!Uskip_whitespace(&ss)) /* leading space */
+ continue; /* ignore empty */
file_yield = yield; /* positive yield */
sss = ss; /* for debugging */
if (*ss == '!') /* negation */
{
- file_yield = (file_yield == OK)? FAIL : OK;
- while (isspace((*(++ss))));
+ file_yield = file_yield == OK ? FAIL : OK;
+ while (isspace(*++ss)) ;
}
switch ((func)(arg, ss, valueptr, &error))
{
case OK:
(void)fclose(f);
- HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\" in %s)\n", ot,
- yield == OK ? "yes" : "no", sss, filename);
+ HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\" in %s)\n",
+ ot, yield == OK ? "yes" : "no", sss, filename);
/* The "pattern" being matched came from the file; we use a stack-local.
Copy it to allocated memory now we know it matched. */
error = string_sprintf("DNS lookup of %s deferred", ss);
if (ignore_defer)
{
- HDEBUG(D_lists) debug_printf_indent("%s: item ignored by +ignore_defer\n",
- error);
+ HDEBUG(D_lists)
+ debug_printf_indent("%s: item ignored by +ignore_defer\n", error);
break;
}
(void)fclose(f);
log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
goto OK_RETURN;
- case ERROR: /* host name lookup failed - this can only */
- if (ignore_unknown) /* be for an incoming host (not outgoing) */
+ /* The ERROR return occurs when checking hosts, when either a forward
+ or reverse lookup has failed. It can also occur in a match_ip list if a
+ non-IP address item is encountered. The error string gives details of
+ which it was. */
+
+ case ERROR:
+ if (ignore_unknown)
{
- HDEBUG(D_lists) debug_printf_indent("%s: item ignored by +ignore_unknown\n",
- error);
+ HDEBUG(D_lists) debug_printf_indent(
+ "%s: item ignored by +ignore_unknown\n", error);
}
else
- {
+ {
HDEBUG(D_lists) debug_printf_indent("%s %s (%s)\n", ot,
- include_unknown? "yes":"no", error);
+ include_unknown ? "yes":"no", error);
(void)fclose(f);
if (!include_unknown)
{
/* End of list reached: if the last item was negated yield OK, else FAIL. */
-HDEBUG(D_lists)
- HDEBUG(D_lists)
- {
- expand_level--;
- debug_printf_indent("%s %s (end of list)\n", ot, yield == OK ? "no":"yes");
- }
- return yield == OK ? FAIL : OK;
-
+HDEBUG(D_any)
+ {
+ HDEBUG(D_lists) expand_level--;
+ debug_printf_indent("%s %s (end of list)\n", ot, yield == OK ? "no":"yes");
+ }
+return yield == OK ? FAIL : OK;
+
/* Something deferred */
DEFER_RETURN:
- HDEBUG(D_lists)
+ HDEBUG(D_any)
{
- expand_level--;
+ HDEBUG(D_lists) expand_level--;
debug_printf_indent("%s list match deferred for %s\n", ot, sss);
}
return DEFER;
if (*ss == '!')
{
local_yield = FAIL;
- while (isspace((*(++ss))));
+ while (isspace(*++ss)) ;
}
else local_yield = OK;
}
/* End of match.c */
+/* vi: aw ai sw=2
+*/