-/* $Cambridge: exim/src/src/lookups/lsearch.c,v 1.3 2005/01/11 15:51:03 ph10 Exp $ */
-
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2005 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* 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 */
/* See local README for interface description */
-void *
+static void *
lsearch_open(uschar *filename, uschar **errmsg)
{
FILE *f = Ufopen(filename, "rb");
* Check entry point *
*************************************************/
-BOOL
+static BOOL
lsearch_check(void *handle, uschar *filename, int modemask, uid_t *owners,
gid_t *owngroups, uschar **errmsg)
{
but people do occasionally do weird things. */
static int
-internal_lsearch_find(void *handle, uschar *filename, uschar *keystring,
+internal_lsearch_find(void *handle, uschar *filename, const uschar *keystring,
int length, uschar **result, uschar **errmsg, int type)
{
FILE *f = (FILE *)handle;
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
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++;
}
{
int rc;
int save = buffer[linekeylength];
- uschar *list = buffer;
+ const uschar *list = buffer;
buffer[linekeylength] = 0;
rc = match_isinlist(keystring,
&list,
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. */
/* Reset dynamic store, if we need to, and revert to the search pool */
- if (reset_point != NULL)
+ if (reset_point)
{
store_reset(reset_point);
store_pool = old_pool;
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 */
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;
+ store_reset(yield->s + yield->ptr + 1);
+ *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;
/* 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, uschar *filename, const uschar *keystring, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
do_cache = do_cache; /* Keep picky compilers happy */
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, uschar *filename, const uschar *keystring, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
do_cache = do_cache; /* Keep picky compilers happy */
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, uschar *filename, const uschar *keystring, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
do_cache = do_cache; /* Keep picky compilers happy */
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 *filename, const uschar *keystring, int length,
+ uschar **result, uschar **errmsg, uint *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);
/* 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 */