X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=blobdiff_plain;f=src%2Fsrc%2Fsearch.c;h=15db52aa6aba0ca1716c52e3af09d6fb14787f43;hp=1b8115b5049e5629528c8fd3e44e6527e8067651;hb=52ba4661114d0a96c15f5f43bcb97ce89061f1b6;hpb=c988f1f4faa9f679f79beddf3c14676c5dcb8e28 diff --git a/src/src/search.c b/src/src/search.c index 1b8115b50..15db52aa6 100644 --- a/src/src/search.c +++ b/src/src/search.c @@ -1,10 +1,8 @@ -/* $Cambridge: exim/src/src/search.c,v 1.2 2005/01/04 10:00:42 ph10 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. */ /* A set of functions to search databases in various formats. An open @@ -71,7 +69,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 +79,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 +182,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 +235,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 +268,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 +333,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 +386,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 +395,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 +478,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 +509,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 +620,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;