tidying
authorJeremy Harris <jgh146exb@wizmail.org>
Mon, 28 Oct 2024 18:41:57 +0000 (18:41 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Fri, 1 Nov 2024 18:40:40 +0000 (18:40 +0000)
src/src/daemon.c
src/src/expand.c
src/src/functions.h
src/src/match.c

index 20e6bc05d40e13fe766526a007fbd5bf8b6b510c..4272dae7a54bd89f6031e757985127c8246ca9ab 100644 (file)
@@ -1875,14 +1875,12 @@ write to stderr. */
 
 if (f.daemon_listen && !f.inetd_wait_mode)
   {
 
 if (f.daemon_listen && !f.inetd_wait_mode)
   {
-  int *default_smtp_port;
-  int sep;
+  int * default_smtp_port;
   int pct = 0;
   int pct = 0;
-  uschar *s;
+  uschar * s;
   const uschar * list;
   const uschar * list;
-  uschar *local_iface_source = US"local_interfaces";
-  ip_address_item *ipa;
-  ip_address_item **pipa;
+  uschar * local_iface_source = US"local_interfaces";
+  ip_address_item * ipa, ** pipa;
 
   /* If -oX was used, disable the writing of a pid file unless -oP was
   explicitly used to force it. Then scan the string given to -oX. Any items
 
   /* If -oX was used, disable the writing of a pid file unless -oP was
   explicitly used to force it. Then scan the string given to -oX. Any items
@@ -1891,23 +1889,20 @@ if (f.daemon_listen && !f.inetd_wait_mode)
 
   if (override_local_interfaces)
     {
 
   if (override_local_interfaces)
     {
-    gstring * new_smtp_port = NULL;
-    gstring * new_local_interfaces = NULL;
+    gstring * new_smtp_port = NULL, * new_local_interfaces = NULL;
 
     if (!override_pid_file_path) write_pid = FALSE;
 
     list = override_local_interfaces;
 
     if (!override_pid_file_path) write_pid = FALSE;
 
     list = override_local_interfaces;
-    sep = 0;
-    while ((s = string_nextinlist(&list, &sep, NULL, 0)))
+    for (int sep = 0; s = string_nextinlist(&list, &sep, NULL, 0); )
       {
       uschar joinstr[4];
       gstring ** gp = Ustrpbrk(s, ".:") ? &new_local_interfaces : &new_smtp_port;
       {
       uschar joinstr[4];
       gstring ** gp = Ustrpbrk(s, ".:") ? &new_local_interfaces : &new_smtp_port;
-
       if (!*gp)
         {
         joinstr[0] = sep;
         joinstr[1] = ' ';
       if (!*gp)
         {
         joinstr[0] = sep;
         joinstr[1] = ' ';
-        *gp = string_catn(*gp, US"<", 1);
+        *gp = string_catn(NULL, US"<", 1);
         }
 
       *gp = string_catn(*gp, joinstr, 2);
         }
 
       *gp = string_catn(*gp, joinstr, 2);
@@ -1935,39 +1930,34 @@ if (f.daemon_listen && !f.inetd_wait_mode)
   build a translated list in a vector. */
 
   list = daemon_smtp_port;
   build a translated list in a vector. */
 
   list = daemon_smtp_port;
-  sep = 0;
-  while ((s = string_nextinlist(&list, &sep, NULL, 0)))
+  for (int sep = 0; s = string_nextinlist(&list, &sep, NULL, 0); )
     pct++;
   default_smtp_port = store_get((pct+1) * sizeof(int), GET_UNTAINTED);
   list = daemon_smtp_port;
     pct++;
   default_smtp_port = store_get((pct+1) * sizeof(int), GET_UNTAINTED);
   list = daemon_smtp_port;
-  sep = 0;
-  for (pct = 0;
-       (s = string_nextinlist(&list, &sep, NULL, 0));
-       pct++)
-    {
+  pct= 0;
+  for (int sep = 0; s = string_nextinlist(&list, &sep, NULL, 0); pct++)
     if (isdigit(*s))
       {
     if (isdigit(*s))
       {
-      uschar *end;
+      uschar * end;
       default_smtp_port[pct] = Ustrtol(s, &end, 0);
       if (end != s + Ustrlen(s))
         log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "invalid SMTP port: %s", s);
       }
     else
       {
       default_smtp_port[pct] = Ustrtol(s, &end, 0);
       if (end != s + Ustrlen(s))
         log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "invalid SMTP port: %s", s);
       }
     else
       {
-      struct servent *smtp_service = getservbyname(CS s, "tcp");
+      struct servent * smtp_service = getservbyname(CS s, "tcp");
       if (!smtp_service)
         log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "TCP port \"%s\" not found", s);
       default_smtp_port[pct] = ntohs(smtp_service->s_port);
       }
       if (!smtp_service)
         log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "TCP port \"%s\" not found", s);
       default_smtp_port[pct] = ntohs(smtp_service->s_port);
       }
-    }
   default_smtp_port[pct] = 0;
 
   /* Check the list of TLS-on-connect ports and do name lookups if needed */
 
   list = tls_in.on_connect_ports;
   default_smtp_port[pct] = 0;
 
   /* Check the list of TLS-on-connect ports and do name lookups if needed */
 
   list = tls_in.on_connect_ports;
-  sep = 0;
   /* the list isn't expanded so cannot be tainted.  If it ever is we will trap here */
   /* the list isn't expanded so cannot be tainted.  If it ever is we will trap here */
-  while ((s = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
+  for (int sep = 0;
+      s = string_nextinlist(&list, &sep, big_buffer, big_buffer_size); )
     if (!isdigit(*s))
       {
       gstring * g = NULL;
     if (!isdigit(*s))
       {
       gstring * g = NULL;
index ebfd4d44a72836235018c1a6f4e6ed52dc102c3d..fd5884306400c1851d2ae9cd769749cef393d192 100644 (file)
@@ -5173,8 +5173,7 @@ while (*s)
       restore_expand_strings(save_expand_nmax, save_expand_nstring,
         save_expand_nlength);
 
       restore_expand_strings(save_expand_nmax, save_expand_nstring,
         save_expand_nlength);
 
-      if (flags & ESI_SKIPPING) continue;
-      break;
+      if (flags & ESI_SKIPPING) continue; else break;
       }
 
     /* If Perl support is configured, handle calling embedded perl subroutines,
       }
 
     /* If Perl support is configured, handle calling embedded perl subroutines,
@@ -5474,7 +5473,7 @@ while (*s)
       FILE * f;
       uschar * sub_arg[2];
 
       FILE * f;
       uschar * sub_arg[2];
 
-      if ((expand_forbid & RDO_READFILE) != 0)
+      if (expand_forbid & RDO_READFILE)
         {
         expand_string_message = US"file insertions are not permitted";
         goto EXPAND_FAILED;
         {
         expand_string_message = US"file insertions are not permitted";
         goto EXPAND_FAILED;
@@ -5627,8 +5626,7 @@ while (*s)
        expand_string_message = US"missing '}' closing readsocket";
        goto EXPAND_FAILED_CURLY;
        }
        expand_string_message = US"missing '}' closing readsocket";
        goto EXPAND_FAILED_CURLY;
        }
-      if (flags & ESI_SKIPPING) continue;
-      break;
+      if (flags & ESI_SKIPPING) continue; else break;
 
       /* Come here on failure to create socket, connect socket, write to the
       socket, or timeout on reading. If another substring follows, expand and
 
       /* Come here on failure to create socket, connect socket, write to the
       socket, or timeout on reading. If another substring follows, expand and
@@ -5798,8 +5796,7 @@ while (*s)
         case 2: goto EXPAND_FAILED_CURLY;    /* returned value is 0 */
         }
 
         case 2: goto EXPAND_FAILED_CURLY;    /* returned value is 0 */
         }
 
-      if (flags & ESI_SKIPPING) continue;
-      break;
+      if (flags & ESI_SKIPPING) continue; else break;
       }
 
     /* Handle character translation for "tr" */
       }
 
     /* Handle character translation for "tr" */
@@ -6353,8 +6350,7 @@ while (*s)
       restore_expand_strings(save_expand_nmax, save_expand_nstring,
         save_expand_nlength);
 
       restore_expand_strings(save_expand_nmax, save_expand_nstring,
         save_expand_nlength);
 
-      if (flags & ESI_SKIPPING) continue;
-      break;
+      if (flags & ESI_SKIPPING) continue; else break;
       }
 
     /* return the Nth item from a list */
       }
 
     /* return the Nth item from a list */
@@ -6453,8 +6449,7 @@ while (*s)
       restore_expand_strings(save_expand_nmax, save_expand_nstring,
         save_expand_nlength);
 
       restore_expand_strings(save_expand_nmax, save_expand_nstring,
         save_expand_nlength);
 
-      if (flags & ESI_SKIPPING) continue;
-      break;
+      if (flags & ESI_SKIPPING) continue; else break;
       }
 
     case EITEM_LISTQUOTE:
       }
 
     case EITEM_LISTQUOTE:
@@ -6553,8 +6548,7 @@ while (*s)
 
       restore_expand_strings(save_expand_nmax, save_expand_nstring,
         save_expand_nlength);
 
       restore_expand_strings(save_expand_nmax, save_expand_nstring,
         save_expand_nlength);
-      if (flags & ESI_SKIPPING) continue;
-      break;
+      if (flags & ESI_SKIPPING) continue; else break;
       }
 #endif /*DISABLE_TLS*/
 
       }
 #endif /*DISABLE_TLS*/
 
@@ -6766,8 +6760,7 @@ while (*s)
       /* Restore preserved $item */
 
       iterate_item = save_iterate_item;
       /* Restore preserved $item */
 
       iterate_item = save_iterate_item;
-      if (flags & ESI_SKIPPING) continue;
-      break;
+      if (flags & ESI_SKIPPING) continue; else break;
       }
 
     case EITEM_SORT:
       }
 
     case EITEM_SORT:
@@ -7068,8 +7061,7 @@ while (*s)
         case 1: goto EXPAND_FAILED;          /* when all is well, the */
         case 2: goto EXPAND_FAILED_CURLY;    /* returned value is 0 */
         }
         case 1: goto EXPAND_FAILED;          /* when all is well, the */
         case 2: goto EXPAND_FAILED_CURLY;    /* returned value is 0 */
         }
-      if (flags & ESI_SKIPPING) continue;
-      break;
+      if (flags & ESI_SKIPPING) continue; else break;
       }
 
 #ifdef SUPPORT_SRS
       }
 
 #ifdef SUPPORT_SRS
index f04fe1f1bf776458ae06084d895da6b914be7e4b..ace6d4018778cc381032342c56e31b278a216402 100644 (file)
@@ -1074,7 +1074,9 @@ g->s = s;
 static inline gstring *
 gstring_append(gstring * dest, gstring * item)
 {
 static inline gstring *
 gstring_append(gstring * dest, gstring * item)
 {
-return item ? string_catn(dest, item->s, item->ptr) : dest;
+return item
+  ? dest ? string_catn(dest, item->s, item->ptr) : item
+  : dest;
 }
 
 
 }
 
 
index dc88485a4d8f696e6a07440e2b59eb4f28ddb2cc..60d9cad1f98c016de6cf54617508f92b18dd3698 100644 (file)
@@ -489,6 +489,9 @@ else
     }
   }
 
     }
   }
 
+/* If expansion had no effect on the list text, the list-test result can
+be cached */
+
 if (textonly_re) switch (type)
   {
   case MCL_STRING:
 if (textonly_re) switch (type)
   {
   case MCL_STRING:
@@ -601,203 +604,10 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
   else
     yield = OK;
 
   else
     yield = OK;
 
-  /* If the item does not begin with '/', it might be a + item for a named
-  list. Otherwise, it is just a single list entry that has to be matched.
-  We recognize '+' only when supplied with a tree of named lists. */
-
-  if (*ss != '/')
-    {
-    if (*ss == '+' && anchorptr)
-      {
-      int bits = 0, offset = 0, shift = 0;
-      unsigned int * use_cache_bits = original_cache_bits;
-      uschar * cached = US"";
-      namedlist_block * nb;
-      tree_node * t;
-
-      HDEBUG(D_lists)
-       { debug_printf_indent(" start sublist %s\n", ss+1); expand_level += 2; }
-
-      if (!(t = tree_search(*anchorptr, ss+1)))
-       {
-        log_write(0, LOG_MAIN|LOG_PANIC, "unknown named%s list \"%s\"",
-          type == MCL_DOMAIN ?    " domain" :
-          type == MCL_HOST ?      " host" :
-          type == MCL_ADDRESS ?   " address" :
-          type == MCL_LOCALPART ? " local part" : "",
-          ss);
-       goto DEFER_RETURN;
-       }
-      nb = t->data.ptr;
-
-      /* If the list number is negative, it means that this list is not
-      cacheable because it contains expansion items. */
-
-      if (nb->number < 0) use_cache_bits = NULL;
-
-      /* If we have got a cache pointer, get the bits. This is not an "else"
-      because the pointer may be NULL from the start if caching is not
-      required. */
-
-      if (use_cache_bits)
-        {
-        offset = (nb->number)/16;
-        shift = ((nb->number)%16)*2;
-        bits = use_cache_bits[offset] & (3 << shift);
-        }
-
-      /* Not previously tested or no cache - run the full test */
-
-      if (bits == 0)
-        {
-        int res = match_check_list(&(nb->string), 0, anchorptr, &use_cache_bits,
-                func, arg, type, name, valueptr);
-       HDEBUG(D_lists)
-         { expand_level -= 2; debug_printf_indent(" end sublist %s\n", ss+1); }
-
-        switch (res)
-          {
-          case OK:   bits = 1; break;
-          case FAIL: bits = 3; break;
-          case DEFER: goto DEFER_RETURN;
-          }
-
-        /* If this list was uncacheable, or a sublist turned out to be
-        uncacheable, the value of use_cache_bits will now be NULL, even if it
-        wasn't before. Ensure that this is passed up to the next level.
-        Otherwise, remember the result of the search in the cache. */
-
-        if (!use_cache_bits)
-          *cache_ptr = NULL;
-        else
-          {
-          use_cache_bits[offset] |= bits << shift;
-
-          if (valueptr)
-            {
-            int old_pool = store_pool;
-            namedlist_cacheblock *p;
-
-            /* Cached data for hosts persists over more than one message,
-            so we use the permanent store pool */
-
-            store_pool = POOL_PERM;
-            p = store_get(sizeof(namedlist_cacheblock), GET_UNTAINTED);
-            p->key = string_copy(get_check_key(arg, type));
-
-
-            p->data = *valueptr ? string_copy(*valueptr) : NULL;
-            store_pool = old_pool;
-
-            p->next = nb->cache_data;
-            nb->cache_data = p;
-            if (*valueptr)
-              HDEBUG(D_lists) debug_printf_indent("data from lookup saved for "
-                "cache for %s: key '%s' value '%s'\n", ss, p->key, *valueptr);
-            }
-          }
-        }
-
-       /* Previously cached; to find a lookup value, search a chain of values
-       and compare keys. Typically, there is only one such, but it is possible
-       for different keys to have matched the same named list. */
-
-      else
-        {
-        HDEBUG(D_lists)
-         {
-         expand_level -= 2;
-         debug_printf_indent("cached %s match for %s\n",
-           (bits & (-bits)) == bits ? "yes" : "no", ss);
-         }
-
-        cached = US" - cached";
-        if (valueptr)
-          {
-          const uschar *key = get_check_key(arg, type);
-
-          for (namedlist_cacheblock * p = nb->cache_data; p; p = p->next)
-            if (Ustrcmp(key, p->key) == 0)
-              {
-              *valueptr = p->data;
-              break;
-              }
-          HDEBUG(D_lists) debug_printf_indent("cached lookup data = %s\n", *valueptr);
-          }
-        }
-
-      /* Result of test is indicated by value in bits. For each test, we
-      have 00 => untested, 01 => tested yes, 11 => tested no. */
-
-      if ((bits & (-bits)) == bits)    /* Only one of the two bits is set */
-        {
-        HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\"%s)\n", ot,
-          yield == OK ? "yes" : "no", sss, cached);
-       goto YIELD_RETURN;
-        }
-      }
-
-    /* Run the provided function to do the individual test. */
-
-    else
-      {
-      uschar * error = NULL;
-      switch ((func)(arg, ss, valueptr, &error))
-        {
-        case OK:
-         HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\")\n", ot,
-           yield == OK ? "yes" : "no", sss);
-         goto YIELD_RETURN;
-
-        case DEFER:
-         if (!error)
-           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);
-           break;
-           }
-         if (include_defer)
-           {
-           log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
-           return OK;
-           }
-         if (!search_error_message) search_error_message = error;
-         goto DEFER_RETURN;
-
-        /* 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);
-           }
-         else
-           {
-           HDEBUG(D_lists) debug_printf_indent("%s %s (%s)\n", ot,
-             include_unknown? "yes":"no", error);
-           if (!include_unknown)
-             {
-             if (LOGGING(unknown_in_list))
-               log_write(0, LOG_MAIN, "list matching forced to fail: %s", error);
-             return FAIL;
-             }
-           log_write(0, LOG_MAIN, "%s: accepted by +include_unknown", error);
-           return OK;
-           }
-        }
-      }
-    }
-
   /* If the item is a file name, we read the file and do a match attempt
   on each line in the file, including possibly more negation processing. */
 
   /* If the item is a file name, we read the file and do a match attempt
   on each line in the file, including possibly more negation processing. */
 
-  else
+  if (*ss == '/')
     {
     int file_yield = yield;       /* In case empty file */
     uschar * filename = ss;
     {
     int file_yield = yield;       /* In case empty file */
     uschar * filename = ss;
@@ -915,6 +725,197 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
     yield = file_yield;
     (void)fclose(f);
     }
     yield = file_yield;
     (void)fclose(f);
     }
+
+  /* If the item does not begin with '/', it might be a + item for a named
+  list. Otherwise, it is just a single list entry that has to be matched.
+  We recognize '+' only when supplied with a tree of named lists. */
+
+  else if (*ss == '+' && anchorptr)
+    {
+    int bits = 0, offset = 0, shift = 0;
+    unsigned int * use_cache_bits = original_cache_bits;
+    uschar * cached = US"";
+    namedlist_block * nb;
+    tree_node * t;
+
+    HDEBUG(D_lists)
+      { debug_printf_indent(" start sublist %s\n", ss+1); expand_level += 2; }
+
+    if (!(t = tree_search(*anchorptr, ss+1)))
+      {
+      log_write(0, LOG_MAIN|LOG_PANIC, "unknown named%s list \"%s\"",
+       type == MCL_DOMAIN ?    " domain" :
+       type == MCL_HOST ?      " host" :
+       type == MCL_ADDRESS ?   " address" :
+       type == MCL_LOCALPART ? " local part" : "",
+       ss);
+      goto DEFER_RETURN;
+      }
+    nb = t->data.ptr;
+
+    /* If the list number is negative, it means that this list is not
+    cacheable because it contains expansion items. */
+
+    if (nb->number < 0) use_cache_bits = NULL;
+
+    /* If we have got a cache pointer, get the bits. This is not an "else"
+    because the pointer may be NULL from the start if caching is not
+    required. */
+
+    if (use_cache_bits)
+      {
+      offset = (nb->number)/16;
+      shift = ((nb->number)%16)*2;
+      bits = use_cache_bits[offset] & (3 << shift);
+      }
+
+    /* Not previously tested or no cache - run the full test */
+
+    if (bits == 0)
+      {
+      int res = match_check_list(&(nb->string), 0, anchorptr, &use_cache_bits,
+             func, arg, type, name, valueptr);
+      HDEBUG(D_lists)
+       { expand_level -= 2; debug_printf_indent(" end sublist %s\n", ss+1); }
+
+      switch (res)
+       {
+       case OK:   bits = 1; break;
+       case FAIL: bits = 3; break;
+       case DEFER: goto DEFER_RETURN;
+       }
+
+      /* If this list was uncacheable, or a sublist turned out to be
+      uncacheable, the value of use_cache_bits will now be NULL, even if it
+      wasn't before. Ensure that this is passed up to the next level.
+      Otherwise, remember the result of the search in the cache. */
+
+      if (!use_cache_bits)
+       *cache_ptr = NULL;
+      else
+       {
+       use_cache_bits[offset] |= bits << shift;
+
+       if (valueptr)
+         {
+         int old_pool = store_pool;
+         namedlist_cacheblock *p;
+
+         /* Cached data for hosts persists over more than one message,
+         so we use the permanent store pool */
+
+         store_pool = POOL_PERM;
+         p = store_get(sizeof(namedlist_cacheblock), GET_UNTAINTED);
+         p->key = string_copy(get_check_key(arg, type));
+
+
+         p->data = *valueptr ? string_copy(*valueptr) : NULL;
+         store_pool = old_pool;
+
+         p->next = nb->cache_data;
+         nb->cache_data = p;
+         if (*valueptr)
+           HDEBUG(D_lists) debug_printf_indent("data from lookup saved for "
+             "cache for %s: key '%s' value '%s'\n", ss, p->key, *valueptr);
+         }
+       }
+      }
+
+     /* Previously cached; to find a lookup value, search a chain of values
+     and compare keys. Typically, there is only one such, but it is possible
+     for different keys to have matched the same named list. */
+
+    else
+      {
+      HDEBUG(D_lists)
+       {
+       expand_level -= 2;
+       debug_printf_indent("cached %s match for %s\n",
+         (bits & (-bits)) == bits ? "yes" : "no", ss);
+       }
+
+      cached = US" - cached";
+      if (valueptr)
+       {
+       const uschar *key = get_check_key(arg, type);
+
+       for (namedlist_cacheblock * p = nb->cache_data; p; p = p->next)
+         if (Ustrcmp(key, p->key) == 0)
+           {
+           *valueptr = p->data;
+           break;
+           }
+       HDEBUG(D_lists) debug_printf_indent("cached lookup data = %s\n", *valueptr);
+       }
+      }
+
+    /* Result of test is indicated by value in bits. For each test, we
+    have 00 => untested, 01 => tested yes, 11 => tested no. */
+
+    if ((bits & (-bits)) == bits)    /* Only one of the two bits is set */
+      {
+      HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\"%s)\n", ot,
+       yield == OK ? "yes" : "no", sss, cached);
+      goto YIELD_RETURN;
+      }
+    }
+
+  /* Run the provided function to do the individual test. */
+
+  else
+    {
+    uschar * error = NULL;
+    switch ((func)(arg, ss, valueptr, &error))
+      {
+      case OK:
+       HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\")\n", ot,
+         yield == OK ? "yes" : "no", sss);
+       goto YIELD_RETURN;
+
+      case DEFER:
+       if (!error)
+         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);
+         break;
+         }
+       if (include_defer)
+         {
+         log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
+         return OK;
+         }
+       if (!search_error_message) search_error_message = error;
+       goto DEFER_RETURN;
+
+      /* 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);
+         }
+       else
+         {
+         HDEBUG(D_lists) debug_printf_indent("%s %s (%s)\n", ot,
+           include_unknown? "yes":"no", error);
+         if (!include_unknown)
+           {
+           if (LOGGING(unknown_in_list))
+             log_write(0, LOG_MAIN, "list matching forced to fail: %s", error);
+           return FAIL;
+           }
+         log_write(0, LOG_MAIN, "%s: accepted by +include_unknown", error);
+         return OK;
+         }
+      }
+    }
+
   }    /* Loop for the next item on the top-level list */
 
 /* End of list reached: if the last item was negated yield OK, else FAIL. */
   }    /* Loop for the next item on the top-level list */
 
 /* End of list reached: if the last item was negated yield OK, else FAIL. */
@@ -1197,12 +1198,12 @@ if ((pdomain = Ustrrchr(pattern, '@')))
   automatically interpreted in match_check_string. We just need to arrange that
   the leading @ is included in the domain. */
 
   automatically interpreted in match_check_string. We just need to arrange that
   the leading @ is included in the domain. */
 
-  if (pdomain > pattern && pdomain[-1] == '@' &&
-       (pdomain[1] == 0 ||
-        Ustrcmp(pdomain+1, "[]") == 0 ||
-        Ustrcmp(pdomain+1, "mx_any") == 0 ||
-        Ustrcmp(pdomain+1, "mx_primary") == 0 ||
-        Ustrcmp(pdomain+1, "mx_secondary") == 0))
+  if (pdomain > pattern && pdomain[-1] == '@'
+     && (pdomain[1] == 0
+        || Ustrcmp(pdomain+1, "[]") == 0
+        || Ustrcmp(pdomain+1, "mx_any") == 0
+        || Ustrcmp(pdomain+1, "mx_primary") == 0
+        || Ustrcmp(pdomain+1, "mx_secondary") == 0))
     pdomain--;
 
   pllen = pdomain - pattern;
     pdomain--;
 
   pllen = pdomain - pattern;