Version reporting & module ABI change.
[exim.git] / src / src / lookups / lsearch.c
index f91ddf89cb1b0b2582e53cb6a7cf292a98dd7beb..b96f70980edbc3c85d61074ffd1c776403d880e3 100644 (file)
@@ -1,15 +1,14 @@
-/* $Cambridge: exim/src/src/lookups/lsearch.c,v 1.3 2005/01/11 15:51:03 ph10 Exp $ */
+/* $Cambridge: exim/src/src/lookups/lsearch.c,v 1.11 2009/11/16 19:50:38 nm4 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2005 */
+/* Copyright (c) University of Cambridge 1995 - 2009 */
 /* 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,7 +27,7 @@ enum {
 
 /* See local README for interface description */
 
-void *
+static void *
 lsearch_open(uschar *filename, uschar **errmsg)
 {
 FILE *f = Ufopen(filename, "rb");
@@ -48,7 +47,7 @@ return f;
 *             Check entry point                  *
 *************************************************/
 
-BOOL
+static BOOL
 lsearch_check(void *handle, uschar *filename, int modemask, uid_t *owners,
   gid_t *owngroups, uschar **errmsg)
 {
@@ -107,6 +106,7 @@ for (last_was_eol = TRUE;
   int ptr, size;
   int p = Ustrlen(buffer);
   int linekeylength;
+  BOOL this_is_comment;
   uschar *yield;
   uschar *s = buffer;
 
@@ -197,7 +197,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. */
@@ -246,6 +255,7 @@ for (last_was_eol = TRUE;
 
   Initialize, and copy the first segment of data. */
 
+  this_is_comment = FALSE;
   size = 100;
   ptr = 0;
   yield = store_get(size);
@@ -276,11 +286,13 @@ 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. */
 
@@ -311,7 +323,7 @@ return FAIL;
 
 /* See local README for interface description */
 
-int
+static int
 lsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -328,7 +340,7 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
 
 /* See local README for interface description */
 
-int
+static int
 wildlsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -345,7 +357,7 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
 
 /* See local README for interface description */
 
-int
+static int
 nwildlsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -363,13 +375,13 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
 
 /* See local README for interface description */
 
-int
+static int
 iplsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
 do_cache = do_cache;  /* Keep picky compilers happy */
 if ((length == 1 && keystring[0] == '*') ||
-    string_is_ip_address(keystring, NULL) > 0)
+    string_is_ip_address(keystring, NULL) != 0)
   {
   return internal_lsearch_find(handle, filename, keystring, length, result,
     errmsg, LSEARCH_IP);
@@ -392,10 +404,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 = {
+  US"iplsearch",                 /* lookup name */
+  lookup_absfile,                /* uses absolute file name */
+  lsearch_open,                  /* open function */
+  lsearch_check,                 /* check function */
+  iplsearch_find,                /* find function */
+  lsearch_close,                 /* close function */
+  NULL,                          /* no tidy function */
+  NULL,                          /* no quoting function */
+  NULL                           /* no version reporting (redundant) */
+};
+
+static lookup_info lsearch_lookup_info = {
+  US"lsearch",                   /* lookup name */
+  lookup_absfile,                /* uses absolute file name */
+  lsearch_open,                  /* open function */
+  lsearch_check,                 /* check function */
+  lsearch_find,                  /* find function */
+  lsearch_close,                 /* close function */
+  NULL,                          /* no tidy function */
+  NULL,                          /* no quoting function */
+  lsearch_version_report         /* version reporting */
+};
+
+static lookup_info nwildlsearch_lookup_info = {
+  US"nwildlsearch",              /* lookup name */
+  lookup_absfile,                /* uses absolute file name */
+  lsearch_open,                  /* open function */
+  lsearch_check,                 /* check function */
+  nwildlsearch_find,             /* find function */
+  lsearch_close,                 /* close function */
+  NULL,                          /* no tidy function */
+  NULL,                          /* no quoting function */
+  NULL                           /* no version reporting (redundant) */
+};
+
+static lookup_info wildlsearch_lookup_info = {
+  US"wildlsearch",               /* lookup name */
+  lookup_absfile,                /* uses absolute file name */
+  lsearch_open,                  /* open function */
+  lsearch_check,                 /* check function */
+  wildlsearch_find,              /* find function */
+  lsearch_close,                 /* close function */
+  NULL,                          /* no tidy function */
+  NULL,                          /* no quoting function */
+  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 */