C99 initialisers
[exim.git] / src / src / lookups / lsearch.c
index 56b12783e7b1d33153a4338ec0c4b107f7a9b2a0..50c25e31e86f113bc6fac15bf138d08a1fd1a5e0 100644 (file)
@@ -1,15 +1,12 @@
-/* $Cambridge: exim/src/src/lookups/lsearch.c,v 1.1 2004/10/07 13:10:01 ph10 Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2004 */
+/* Copyright (c) University of Cambridge 1995 - 2018 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 #include "../exim.h"
 #include "lf_functions.h"
-#include "lsearch.h"
 
 /* Codes for the different kinds of lsearch that are supported */
 
@@ -28,8 +25,8 @@ enum {
 
 /* See local README for interface description */
 
-void *
-lsearch_open(uschar *filename, uschar **errmsg)
+static void *
+lsearch_open(const uschar * filename, uschar ** errmsg)
 {
 FILE *f = Ufopen(filename, "rb");
 if (f == NULL)
@@ -48,8 +45,8 @@ return f;
 *             Check entry point                  *
 *************************************************/
 
-BOOL
-lsearch_check(void *handle, uschar *filename, int modemask, uid_t *owners,
+static BOOL
+lsearch_check(void *handle, const uschar *filename, int modemask, uid_t *owners,
   gid_t *owngroups, uschar **errmsg)
 {
 return lf_check_file(fileno((FILE *)handle), filename, S_IFREG, modemask,
@@ -74,14 +71,15 @@ fit into the fixed sized buffer. Most of the time this will never be exercised,
 but people do occasionally do weird things. */
 
 static int
-internal_lsearch_find(void *handle, uschar *filename, uschar *keystring,
-  int length, uschar **result, uschar **errmsg, int type)
+internal_lsearch_find(void * handle, const uschar * filename,
+  const uschar * keystring, int length, uschar ** result, uschar ** errmsg,
+ int type)
 {
 FILE *f = (FILE *)handle;
 BOOL last_was_eol = TRUE;
 BOOL this_is_eol = TRUE;
 int old_pool = store_pool;
-void *reset_point = NULL;
+rmark reset_point = NULL;
 uschar buffer[4096];
 
 /* Wildcard searches may use up some store, because of expansions. We don't
@@ -93,7 +91,7 @@ safely stored in the search pool again. */
 if(type == LSEARCH_WILD || type == LSEARCH_NWILD)
   {
   store_pool = POOL_MAIN;
-  reset_point = store_get(0);
+  reset_point = store_mark();
   }
 
 filename = filename;  /* Keep picky compilers happy */
@@ -104,10 +102,10 @@ for (last_was_eol = TRUE;
      Ufgets(buffer, sizeof(buffer), f) != NULL;
      last_was_eol = this_is_eol)
   {
-  int ptr, size;
   int p = Ustrlen(buffer);
   int linekeylength;
-  uschar *yield;
+  BOOL this_is_comment;
+  gstring * yield;
   uschar *s = buffer;
 
   /* Check whether this the final segment of a line. If it follows an
@@ -148,7 +146,7 @@ for (last_was_eol = TRUE;
     uschar *t = s++;
     while (*s != 0 && *s != '\"')
       {
-      if (*s == '\\') *t++ = string_interpret_escape(&s);
+      if (*s == '\\') *t++ = string_interpret_escape(CUSS &s);
         else *t++ = *s;
       s++;
       }
@@ -183,7 +181,7 @@ for (last_was_eol = TRUE;
       {
       int rc;
       int save = buffer[linekeylength];
-      uschar *list = buffer;
+      const uschar *list = buffer;
       buffer[linekeylength] = 0;
       rc = match_isinlist(keystring,
         &list,
@@ -197,7 +195,16 @@ for (last_was_eol = TRUE;
       if (rc == FAIL) continue;
       if (rc == DEFER) return DEFER;
       }
-    break;      /* Key matched */
+
+    /* The key has matched. If the search involved a regular expression, it
+    might have caused numerical variables to be set. However, their values will
+    be in the wrong storage pool for external use. Copying them to the standard
+    pool is not feasible because of the caching of lookup results - a repeated
+    lookup will not match the regular expression again. Therefore, we flatten
+    all numeric variables at this point. */
+
+    expand_nmax = -1;
+    break;
 
     /* Compare an ip address against a list of network/ip addresses. We have to
     allow for the "*" case specially. */
@@ -213,7 +220,7 @@ for (last_was_eol = TRUE;
       int maskoffset;
       int save = buffer[linekeylength];
       buffer[linekeylength] = 0;
-      if (!string_is_ip_address(buffer, &maskoffset) ||
+      if (string_is_ip_address(buffer, &maskoffset) == 0 ||
           !host_is_in_net(keystring, buffer, maskoffset)) continue;
       buffer[linekeylength] = save;
       }
@@ -233,9 +240,9 @@ for (last_was_eol = TRUE;
 
   /* Reset dynamic store, if we need to, and revert to the search pool */
 
-  if (reset_point != NULL)
+  if (reset_point)
     {
-    store_reset(reset_point);
+    reset_point = store_reset(reset_point);
     store_pool = old_pool;
     }
 
@@ -246,11 +253,10 @@ for (last_was_eol = TRUE;
 
   Initialize, and copy the first segment of data. */
 
-  size = 100;
-  ptr = 0;
-  yield = store_get(size);
+  this_is_comment = FALSE;
+  yield = string_get(100);
   if (*s != 0)
-    yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+    yield = string_cat(yield, s);
 
   /* Now handle continuations */
 
@@ -276,26 +282,27 @@ for (last_was_eol = TRUE;
 
     if (last_was_eol)
       {
-      if (buffer[0] == 0 || buffer[0] == '#') continue;
+      this_is_comment = (this_is_comment || (buffer[0] == 0 || buffer[0] == '#'));
+      if (this_is_comment) continue;
       if (!isspace((uschar)buffer[0])) break;
       while (isspace((uschar)*s)) s++;
       *(--s) = ' ';
       }
+    if (this_is_comment) continue;
 
     /* Join a physical or logical line continuation onto the result string. */
 
-    yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+    yield = string_cat(yield, s);
     }
 
-  yield[ptr] = 0;
-  store_reset(yield + ptr + 1);
-  *result = yield;
+  gstring_release_unused(yield);
+  *result = string_from_gstring(yield);
   return OK;
   }
 
 /* Reset dynamic store, if we need to */
 
-if (reset_point != NULL)
+if (reset_point)
   {
   store_reset(reset_point);
   store_pool = old_pool;
@@ -311,9 +318,10 @@ return FAIL;
 
 /* See local README for interface description */
 
-int
-lsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
-  uschar **result, uschar **errmsg, BOOL *do_cache)
+static int
+lsearch_find(void * handle, const uschar * filename, const uschar * keystring,
+  int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+  const uschar * opts)
 {
 do_cache = do_cache;  /* Keep picky compilers happy */
 return internal_lsearch_find(handle, filename, keystring, length, result,
@@ -328,9 +336,10 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
 
 /* See local README for interface description */
 
-int
-wildlsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
-  uschar **result, uschar **errmsg, BOOL *do_cache)
+static int
+wildlsearch_find(void * handle, const uschar * filename, const uschar * keystring,
+  int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+  const uschar * opts)
 {
 do_cache = do_cache;  /* Keep picky compilers happy */
 return internal_lsearch_find(handle, filename, keystring, length, result,
@@ -345,9 +354,10 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
 
 /* See local README for interface description */
 
-int
-nwildlsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
-  uschar **result, uschar **errmsg, BOOL *do_cache)
+static int
+nwildlsearch_find(void * handle, const uschar * filename, const uschar * keystring,
+  int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+  const uschar * opts)
 {
 do_cache = do_cache;  /* Keep picky compilers happy */
 return internal_lsearch_find(handle, filename, keystring, length, result,
@@ -363,24 +373,22 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
 
 /* See local README for interface description */
 
-int
-iplsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
-  uschar **result, uschar **errmsg, BOOL *do_cache)
+static int
+iplsearch_find(void * handle, uschar const * filename, const uschar * keystring,
+  int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+  const uschar * opts)
 {
 do_cache = do_cache;  /* Keep picky compilers happy */
+
 if ((length == 1 && keystring[0] == '*') ||
-    string_is_ip_address(keystring, NULL))
-  {
+    string_is_ip_address(keystring, NULL) != 0)
   return internal_lsearch_find(handle, filename, keystring, length, result,
     errmsg, LSEARCH_IP);
-  }
-else
-  {
-  *errmsg = string_sprintf("\"%s\" is not a valid iplsearch key (an IP "
-    "address, with optional CIDR mask, is wanted): "
-    "in a host list, use net-iplsearch as the search type", keystring);
-  return DEFER;
-  }
+
+*errmsg = string_sprintf("\"%s\" is not a valid iplsearch key (an IP "
+"address, with optional CIDR mask, is wanted): "
+"in a host list, use net-iplsearch as the search type", keystring);
+return DEFER;
 }
 
 
@@ -392,10 +400,87 @@ else
 
 /* See local README for interface description */
 
-void
+static void
 lsearch_close(void *handle)
 {
-fclose((FILE *)handle);
+(void)fclose((FILE *)handle);
 }
 
+
+
+/*************************************************
+*         Version reporting entry point          *
+*************************************************/
+
+/* See local README for interface description. */
+
+#include "../version.h"
+
+void
+lsearch_version_report(FILE *f)
+{
+#ifdef DYNLOOKUP
+fprintf(f, "Library version: lsearch: Exim version %s\n", EXIM_VERSION_STR);
+#endif
+}
+
+
+static lookup_info iplsearch_lookup_info = {
+  .name = US"iplsearch",               /* lookup name */
+  .type = lookup_absfile,              /* uses absolute file name */
+  .open = lsearch_open,                        /* open function */
+  .check = lsearch_check,              /* check function */
+  .find = iplsearch_find,              /* find function */
+  .close = lsearch_close,              /* close function */
+  .tidy = NULL,                                /* no tidy function */
+  .quote = NULL,                       /* no quoting function */
+  .version_report = NULL                           /* no version reporting (redundant) */
+};
+
+static lookup_info lsearch_lookup_info = {
+  .name = US"lsearch",                 /* lookup name */
+  .type = lookup_absfile,              /* uses absolute file name */
+  .open = lsearch_open,                        /* open function */
+  .check = lsearch_check,              /* check function */
+  .find = lsearch_find,                        /* find function */
+  .close = lsearch_close,              /* close function */
+  .tidy = NULL,                                /* no tidy function */
+  .quote = NULL,                       /* no quoting function */
+  .version_report = lsearch_version_report         /* version reporting */
+};
+
+static lookup_info nwildlsearch_lookup_info = {
+  .name = US"nwildlsearch",            /* lookup name */
+  .type = lookup_absfile,              /* uses absolute file name */
+  .open = lsearch_open,                        /* open function */
+  .check = lsearch_check,              /* check function */
+  .find = nwildlsearch_find,           /* find function */
+  .close = lsearch_close,              /* close function */
+  .tidy = NULL,                                /* no tidy function */
+  .quote = NULL,                       /* no quoting function */
+  .version_report = NULL                           /* no version reporting (redundant) */
+};
+
+static lookup_info wildlsearch_lookup_info = {
+  .name = US"wildlsearch",             /* lookup name */
+  .type = lookup_absfile,              /* uses absolute file name */
+  .open = lsearch_open,                        /* open function */
+  .check = lsearch_check,              /* check function */
+  .find = wildlsearch_find,            /* find function */
+  .close = lsearch_close,              /* close function */
+  .tidy = NULL,                                /* no tidy function */
+  .quote = NULL,                       /* no quoting function */
+  .version_report = NULL                           /* no version reporting (redundant) */
+};
+
+#ifdef DYNLOOKUP
+#define lsearch_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &iplsearch_lookup_info,
+                                       &lsearch_lookup_info,
+                                       &nwildlsearch_lookup_info,
+                                       &wildlsearch_lookup_info };
+lookup_module_info lsearch_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 4 };
+
 /* End of lookups/lsearch.c */