Const-ification
[exim.git] / src / src / match.c
index 01b52ed0e0c77bb49e2d179a5166a34095a55078..97c4ea045b7f533681dacf7443be9b6f9c676575 100644 (file)
@@ -1,10 +1,8 @@
-/* $Cambridge: exim/src/src/match.c,v 1.17 2007/01/08 10:50:18 ph10 Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2007 */
+/* Copyright (c) University of Cambridge 1995 - 2009 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Functions for matching strings */
@@ -17,8 +15,8 @@
 strings, domains, and local parts. */
 
 typedef struct check_string_block {
-  uschar *origsubject;               /* caseful; keep these two first, in */
-  uschar *subject;                   /* step with the block below */
+  const uschar *origsubject;           /* caseful; keep these two first, in */
+  const uschar *subject;               /* step with the block below */
   int    expand_setup;
   BOOL   use_partial;
   BOOL   caseless;
@@ -96,7 +94,7 @@ Returns:       OK    if matched
 static int
 check_string(void *arg, uschar *pattern, uschar **valueptr, uschar **error)
 {
-check_string_block *cb = (check_string_block *)arg;
+const check_string_block *cb = arg;
 int search_type, partial, affixlen, starflags;
 int expand_setup = cb->expand_setup;
 uschar *affix;
@@ -113,7 +111,7 @@ if (valueptr != NULL) *valueptr = NULL;  /* For non-lookup matches */
 it works if the pattern uses (?-i) to turn off case-independence, overriding
 "caseless". */
 
-s = (pattern[0] == '^')? cb->origsubject : cb->subject;
+s = string_copy(pattern[0] == '^' ? cb->origsubject : cb->subject);
 
 /* If required to set up $0, initialize the data but don't turn on by setting
 expand_nmax until the match is assured. */
@@ -133,7 +131,7 @@ if (pattern[0] == '^')
   {
   const pcre *re = regex_must_compile(pattern, cb->caseless, FALSE);
   return ((expand_setup < 0)?
-           pcre_exec(re, NULL, CS s, Ustrlen(s), 0, PCRE_EOPT, NULL, 0) >= 0
+           pcre_exec(re, NULL, CCS s, Ustrlen(s), 0, PCRE_EOPT, NULL, 0) >= 0
            :
            regex_match_and_setup(re, s, 0, expand_setup)
          )?
@@ -223,6 +221,8 @@ if (cb->at_is_special && pattern[0] == '@')
       NULL,                /* service name not relevant */
       NULL,                /* srv_fail_domains not relevant */
       NULL,                /* mx_fail_domains not relevant */
+      NULL,                /* no dnssec request XXX ? */
+      NULL,                /* no dnssec require XXX ? */
       NULL,                /* no feedback FQDN */
       &removed);           /* feedback if local removed */
 
@@ -366,7 +366,7 @@ Arguments:
   type         MCL_STRING, MCL_DOMAIN, MCL_HOST, MCL_ADDRESS, or MCL_LOCALPART
 */
 
-static uschar *
+static const uschar *
 get_check_key(void *arg, int type)
 {
 switch(type)
@@ -438,12 +438,14 @@ Returns:       OK    if matched a non-negated item
 int
 match_check_list(uschar **listptr, int sep, tree_node **anchorptr,
   unsigned int **cache_ptr, int (*func)(void *,uschar *,uschar **,uschar **),
-  void *arg, int type, uschar *name, uschar **valueptr)
+  void *arg, int type, const uschar *name, uschar **valueptr)
 {
 int yield = OK;
 unsigned int *original_cache_bits = *cache_ptr;
 BOOL include_unknown = FALSE;
 BOOL ignore_unknown = FALSE;
+BOOL include_defer = FALSE;
+BOOL ignore_defer = FALSE;
 uschar *list;
 uschar *sss;
 uschar *ot = NULL;
@@ -487,7 +489,7 @@ else
   if (type == MCL_DOMAIN && deliver_domain == NULL)
     {
     check_string_block *cb = (check_string_block *)arg;
-    deliver_domain = cb->subject;
+    deliver_domain = string_copy(cb->subject);
     list = expand_string(*listptr);
     deliver_domain = NULL;
     }
@@ -553,10 +555,11 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
       }
     }
 
-  /* If the host item is "+include_unknown", remember it in case there's a
-  subsequent failed reverse lookup. */
+  /* If the host item is "+include_unknown" or "+ignore_unknown", remember it
+  in case there's a subsequent failed reverse lookup. There is similar
+  processing for "defer". */
 
-  else if (type == MCL_HOST)
+  else if (type == MCL_HOST && *ss == '+')
     {
     if (Ustrcmp(ss, "+include_unknown") == 0)
       {
@@ -570,6 +573,18 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
       include_unknown = FALSE;
       continue;
       }
+    if (Ustrcmp(ss, "+include_defer") == 0)
+      {
+      include_defer = TRUE;
+      ignore_defer = FALSE;
+      continue;
+      }
+    if (Ustrcmp(ss, "+ignore_defer") == 0)
+      {
+      ignore_defer = TRUE;
+      include_defer = FALSE;
+      continue;
+      }
     }
 
   /* Starting with ! specifies a negative item. It is theoretically possible
@@ -686,7 +701,7 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
         cached = US" - cached";
         if (valueptr != NULL)
           {
-          uschar *key = get_check_key(arg, type);
+          const uschar *key = get_check_key(arg, type);
           namedlist_cacheblock *p;
           for (p = nb->cache_data; p != NULL; p = p->next)
             {
@@ -715,7 +730,7 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
 
     else
       {
-      uschar *error;
+      uschar *error = NULL;
       switch ((func)(arg, ss, valueptr, &error))
         {
         case OK:
@@ -724,6 +739,19 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
         return yield;
 
         case DEFER:
+        if (error == NULL)
+          error = string_sprintf("DNS lookup of %s deferred", ss);
+        if (ignore_defer)
+          {
+          HDEBUG(D_lists) debug_printf("%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;
+          }
         goto DEFER_RETURN;
 
         /* The ERROR return occurs when checking hosts, when either a forward
@@ -823,7 +851,20 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
         return file_yield;
 
         case DEFER:
+        if (error == NULL)
+          error = string_sprintf("DNS lookup of %s deferred", ss);
+        if (ignore_defer)
+          {
+          HDEBUG(D_lists) debug_printf("%s: item ignored by +ignore_defer\n",
+            error);
+          break;
+          }
         (void)fclose(f);
+        if (include_defer)
+          {
+          log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
+          return OK;
+          }
         goto DEFER_RETURN;
 
         case ERROR:          /* host name lookup failed - this can only */
@@ -911,7 +952,8 @@ Returns:         OK    if matched a non-negated item
 */
 
 int
-match_isinlist(uschar *s, uschar **listptr, int sep, tree_node **anchorptr,
+match_isinlist(const uschar *s, uschar **listptr, int sep,
+   tree_node **anchorptr,
   unsigned int *cache_bits, int type, BOOL caseless, uschar **valueptr)
 {
 unsigned int *local_cache_bits = cache_bits;
@@ -971,7 +1013,7 @@ uschar *s, *pdomain, *sdomain;
 
 error = error;  /* Keep clever compilers from complaining */
 
-DEBUG(D_lists) debug_printf("address match: subject=%s pattern=%s\n",
+DEBUG(D_lists) debug_printf("address match test: subject=%s pattern=%s\n",
   subject, pattern);
 
 /* Find the subject's domain */