X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/059ec3d9952740285fb1ebf47961b8aca2eb1b4a..d639d9e15a21db966b98b74f7dc76f8c218b1931:/src/src/search.c diff --git a/src/src/search.c b/src/src/search.c index 3dfd80e32..528dc722d 100644 --- a/src/src/search.c +++ b/src/src/search.c @@ -1,10 +1,10 @@ -/* $Cambridge: exim/src/src/search.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */ +/* $Cambridge: exim/src/src/search.c,v 1.7 2009/11/16 19:50:37 nm4 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2004 */ +/* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ /* A set of functions to search databases in various formats. An open @@ -71,7 +71,7 @@ int top = lookup_list_count; while (top > bot) { int mid = (top + bot)/2; - int c = Ustrncmp(name, lookup_list[mid].name, len); + int c = Ustrncmp(name, lookup_list[mid]->name, len); /* If c == 0 we have matched the incoming name with the start of the search type name. However, some search types are substrings of others (e.g. nis and @@ -81,9 +81,9 @@ while (top > bot) are testing. By leaving c == 0 when the lengths are different, and doing a > 0 test below, this all falls out correctly. */ - if (c == 0 && Ustrlen(lookup_list[mid].name) == len) + if (c == 0 && Ustrlen(lookup_list[mid]->name) == len) { - if (lookup_list[mid].find != NULL) return mid; + if (lookup_list[mid]->find != NULL) return mid; search_error_message = string_sprintf("lookup type \"%.*s\" is not " "available (not in the binary - check buildtime LOOKUP configuration)", len, name); @@ -184,18 +184,26 @@ else if (len >= 1 && ss[len-1] == '*') } /* Check for the individual search type. Only those that are actually in the -binary are valid. For query-style types, "partial" is an error. */ +binary are valid. For query-style types, "partial" and default types are +erroneous. */ stype = search_findtype(ss, len); -if (pv >= 0 && mac_islookup(stype, lookup_querystyle)) +if (stype >= 0 && mac_islookup(stype, lookup_querystyle)) { - search_error_message = string_sprintf("\"partial\" is not permitted " - "for lookup type \"%s\"", ss); - return -1; + if (pv >= 0) + { + search_error_message = string_sprintf("\"partial\" is not permitted " + "for lookup type \"%s\"", ss); + return -1; + } + if ((*starflags & (SEARCH_STAR|SEARCH_STARAT)) != 0) + { + search_error_message = string_sprintf("defaults using \"*\" or \"*@\" are " + "not permitted for lookup type \"%s\"", ss); + return -1; + } } -/* All is well; pass back the partial type and return the lookup type. */ - *ptypeptr = pv; return stype; } @@ -229,8 +237,8 @@ if (t->left != NULL) tidyup_subtree(t->left); if (t->right != NULL) tidyup_subtree(t->right); if (c != NULL && c->handle != NULL && - lookup_list[c->search_type].close != NULL) - lookup_list[c->search_type].close(c->handle); + lookup_list[c->search_type]->close != NULL) + lookup_list[c->search_type]->close(c->handle); } @@ -262,7 +270,7 @@ open_filecount = 0; /* Call the general tidyup entry for any drivers that have one. */ for (i = 0; i < lookup_list_count; i++) - if (lookup_list[i].tidy != NULL) (lookup_list[i].tidy)(); + if (lookup_list[i]->tidy != NULL) (lookup_list[i]->tidy)(); if (search_reset_point != NULL) store_reset(search_reset_point); search_reset_point = NULL; @@ -327,7 +335,7 @@ search_open(uschar *filename, int search_type, int modemask, uid_t *owners, void *handle; tree_node *t; search_cache *c; -lookup_info *lk = lookup_list + search_type; +lookup_info *lk = lookup_list[search_type]; uschar keybuffer[256]; int old_pool = store_pool; @@ -380,7 +388,7 @@ if (lk->type == lookup_absfile && open_filecount >= lookup_open_max) ((search_cache *)(open_bot->data.ptr))->down = NULL; else open_top = NULL; - ((lookup_list + c->search_type)->close)(c->handle); + ((lookup_list[c->search_type])->close)(c->handle); c->handle = NULL; open_filecount--; } @@ -389,7 +397,7 @@ if (lk->type == lookup_absfile && open_filecount >= lookup_open_max) /* If opening is successful, call the file-checking function if there is one, and if all is still well, enter the open database into the tree. */ -handle = lk->open(filename, &search_error_message); +handle = (lk->open)(filename, &search_error_message); if (handle == NULL) { store_pool = old_pool; @@ -472,7 +480,7 @@ search_find_defer = FALSE; DEBUG(D_lookup) debug_printf("internal_search_find: file=\"%s\"\n " "type=%s key=\"%s\"\n", filename, - lookup_list[search_type].name, keystring); + lookup_list[search_type]->name, keystring); /* Insurance. If the keystring is empty, just fail. */ @@ -503,7 +511,7 @@ if ((t = tree_search(c->item_cache, keystring)) == NULL) like FAIL, except that search_find_defer is set so the caller can distinguish if necessary. */ - if (lookup_list[search_type].find(c->handle, filename, keystring, keylength, + if (lookup_list[search_type]->find(c->handle, filename, keystring, keylength, &data, &search_error_message, &do_cache) == DEFER) { search_find_defer = TRUE; @@ -614,7 +622,7 @@ DEBUG(D_lookup) that opens real files. */ if (open_top != (tree_node *)handle && - lookup_list[t->name[0]-'0'].type == lookup_absfile) + lookup_list[t->name[0]-'0']->type == lookup_absfile) { search_cache *c = (search_cache *)(t->data.ptr); tree_node *up = c->up;