X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=blobdiff_plain;f=src%2Fsrc%2Flookups%2Flsearch.c;h=50c25e31e86f113bc6fac15bf138d08a1fd1a5e0;hp=56b12783e7b1d33153a4338ec0c4b107f7a9b2a0;hb=9f4001740f061f29c65835c6f7efcab50c27db13;hpb=0756eb3cb50d73a77b486e47528f7cb1bffdb299 diff --git a/src/src/lookups/lsearch.c b/src/src/lookups/lsearch.c index 56b12783e..50c25e31e 100644 --- a/src/src/lookups/lsearch.c +++ b/src/src/lookups/lsearch.c @@ -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 */