Update version number to 4.53.
[exim.git] / src / src / search.c
CommitLineData
c988f1f4 1/* $Cambridge: exim/src/src/search.c,v 1.2 2005/01/04 10:00:42 ph10 Exp $ */
059ec3d9
PH
2
3/*************************************************
4* Exim - an Internet mail transport agent *
5*************************************************/
6
c988f1f4 7/* Copyright (c) University of Cambridge 1995 - 2005 */
059ec3d9
PH
8/* See the file NOTICE for conditions of use and distribution. */
9
10/* A set of functions to search databases in various formats. An open
11database is represented by a void * value which is returned from a lookup-
12specific "open" function. These are now all held in individual modules in the
13lookups subdirectory and the functions here form a generic interface.
14
15Caching is used to improve performance. Open files are cached until a tidyup
16function is called, and for each file the result of the last lookup is cached.
17However, if too many files are opened, some of those that are not in use have
18to be closed. Those open items that use real files are kept on a LRU chain to
19help with this.
20
21All the data is held in permanent store so as to be independent of the stacking
22pool that is reset from time to time. In fact, we use malloc'd store so that it
23can be freed when the caches are tidied up. It isn't actually clear whether
24this is a benefit or not, to be honest. */
25
26#include "exim.h"
27
28
29/* Tree in which to cache open files until tidyup called. */
30
31static tree_node *search_tree = NULL;
32
33/* Two-way chain of open databases that use real files. This is maintained in
34recently-used order for the purposes of closing the least recently used when
35too many files are open. */
36
37static tree_node *open_top = NULL;
38static tree_node *open_bot = NULL;
39
40/* Count of open databases that use real files */
41
42static int open_filecount = 0;
43
44/* Allow us to reset store used for lookups and lookup caching */
45
46static void *search_reset_point = NULL;
47
48
49
50/*************************************************
51* Validate a plain lookup type name *
52*************************************************/
53
54/* Only those names that are recognized and whose code is included in the
55binary give an OK response. Use a binary chop search now that the list has got
56so long.
57
58Arguments:
59 name lookup type name - not necessarily zero terminated (e.g. dbm*)
60 len length of the name
61
62Returns: +ve => valid lookup name; value is offset in lookup_list
63 -ve => invalid name; message in search_error_message.
64*/
65
66int
67search_findtype(uschar *name, int len)
68{
69int bot = 0;
70int top = lookup_list_count;
71while (top > bot)
72 {
73 int mid = (top + bot)/2;
74 int c = Ustrncmp(name, lookup_list[mid].name, len);
75
76 /* If c == 0 we have matched the incoming name with the start of the search
77 type name. However, some search types are substrings of others (e.g. nis and
78 nisplus) so we need to check that the lengths are the same. The length of the
79 type name cannot be shorter (else c would not be 0); if it is not equal it
80 must be longer, and in that case, the incoming name comes before the name we
81 are testing. By leaving c == 0 when the lengths are different, and doing a
82 > 0 test below, this all falls out correctly. */
83
84 if (c == 0 && Ustrlen(lookup_list[mid].name) == len)
85 {
86 if (lookup_list[mid].find != NULL) return mid;
87 search_error_message = string_sprintf("lookup type \"%.*s\" is not "
88 "available (not in the binary - check buildtime LOOKUP configuration)",
89 len, name);
90 return -1;
91 }
92
93 if (c > 0) bot = mid + 1; else top = mid;
94 }
95
96search_error_message = string_sprintf("unknown lookup type \"%.*s\"",len,name);
97return -1;
98}
99
100
101
102/*************************************************
103* Validate a full lookup type name *
104*************************************************/
105
106/* This function recognizes the "partial-" prefix and also terminating * and *@
107suffixes.
108
109Arguments:
110 name the full lookup type name
111 ptypeptr where to put the partial type
112 after subtraction of 1024 or 2048:
113 negative => no partial matching
114 non-negative => minimum number of non-wild components
115 ptypeaff where to put a pointer to the affix
116 the affix is within name if supplied therein
117 otherwise it's a literal string
118 afflen the length of the affix
119 starflags where to put the SEARCH_STAR and SEARCH_STARAT flags
120
121Returns: +ve => valid lookup name; value is offset in lookup_list
122 -ve => invalid name; message in search_error_message.
123*/
124
125int
126search_findtype_partial(uschar *name, int *ptypeptr, uschar **ptypeaff,
127 int *afflen, int *starflags)
128{
129int len, stype;
130int pv = -1;
131uschar *ss = name;
132
133*starflags = 0;
134*ptypeaff = NULL;
135
136/* Check for a partial matching type. It must start with "partial", optionally
137followed by a sequence of digits. If this is followed by "-", the affix is the
138default "*." string. Otherwise we expect an affix in parentheses. Affixes are a
139limited number of characters, not including parens. */
140
141if (Ustrncmp(name, "partial", 7) == 0)
142 {
143 ss += 7;
144 if (isdigit (*ss))
145 {
146 pv = 0;
147 while (isdigit(*ss)) pv = pv*10 + *ss++ - '0';
148 }
149 else pv = 2; /* Default number of wild components */
150
151 if (*ss == '(')
152 {
153 *ptypeaff = ++ss;
154 while (ispunct(*ss) && *ss != ')') ss++;
155 if (*ss != ')') goto BAD_TYPE;
156 *afflen = ss++ - *ptypeaff;
157 }
158 else if (*ss++ == '-')
159 {
160 *ptypeaff = US "*.";
161 *afflen = 2;
162 }
163 else
164 {
165 BAD_TYPE:
166 search_error_message = string_sprintf("format error in lookup type \"%s\"",
167 name);
168 return -1;
169 }
170 }
171
172/* Now we are left with a lookup name, possibly followed by * or *@. */
173
174len = Ustrlen(ss);
175if (len >= 2 && Ustrncmp(ss + len - 2, "*@", 2) == 0)
176 {
177 *starflags |= SEARCH_STARAT;
178 len -= 2;
179 }
180else if (len >= 1 && ss[len-1] == '*')
181 {
182 *starflags |= SEARCH_STAR;
183 len--;
184 }
185
186/* Check for the individual search type. Only those that are actually in the
187binary are valid. For query-style types, "partial" is an error. */
188
189stype = search_findtype(ss, len);
190if (pv >= 0 && mac_islookup(stype, lookup_querystyle))
191 {
192 search_error_message = string_sprintf("\"partial\" is not permitted "
193 "for lookup type \"%s\"", ss);
194 return -1;
195 }
196
197/* All is well; pass back the partial type and return the lookup type. */
198
199*ptypeptr = pv;
200return stype;
201}
202
203
204
205/*************************************************
206* Release cached resources *
207*************************************************/
208
209/* When search_open is called it caches the "file" that it opens in
210search_tree. The name of the tree node is a concatenation of the search type
211with the file name. For query-style lookups, the file name is empty. Real files
212are normally closed only when this tidyup routine is called, typically at the
213end of sections of code where a number of lookups might occur. However, if too
214many files are open simultaneously, some get closed beforehand. They can't be
215removed from the tree. There is also a general tidyup function which is called
216for the lookup driver, if it exists.
217
218First, there is an internal, recursive subroutine.
219
220Argument: a pointer to a search_openfile tree node
221Returns: nothing
222*/
223
224static void
225tidyup_subtree(tree_node *t)
226{
227search_cache *c = (search_cache *)(t->data.ptr);
228if (t->left != NULL) tidyup_subtree(t->left);
229if (t->right != NULL) tidyup_subtree(t->right);
230if (c != NULL &&
231 c->handle != NULL &&
232 lookup_list[c->search_type].close != NULL)
233 lookup_list[c->search_type].close(c->handle);
234}
235
236
237/* The external entry point
238
239Argument: none
240Returns: nothing
241*/
242
243void
244search_tidyup(void)
245{
246int i;
247int old_pool = store_pool;
248
249DEBUG(D_lookup) debug_printf("search_tidyup called\n");
250
251/* Close individually each cached open file. */
252
253store_pool = POOL_SEARCH;
254if (search_tree != NULL)
255 {
256 tidyup_subtree(search_tree);
257 search_tree = NULL;
258 }
259open_top = open_bot = NULL;
260open_filecount = 0;
261
262/* Call the general tidyup entry for any drivers that have one. */
263
264for (i = 0; i < lookup_list_count; i++)
265 if (lookup_list[i].tidy != NULL) (lookup_list[i].tidy)();
266
267if (search_reset_point != NULL) store_reset(search_reset_point);
268search_reset_point = NULL;
269store_pool = old_pool;
270}
271
272
273
274
275/*************************************************
276* Open search database *
277*************************************************/
278
279/* A mode, and lists of owners and groups, are passed over for checking in
280the cases where the database is one or more files. Return NULL, with a message
281pointed to by message, in cases of error.
282
283For search types that use a file or files, check up on the mode after
284opening. It is tempting to do a stat before opening the file, and use it as
285an existence check. However, doing that opens a small security loophole in
286that the status could be changed before the file is opened. Can't quite see
287what problems this might lead to, but you can't be too careful where security
288is concerned. Fstat() on an open file can normally be expected to succeed,
289but there are some NFS states where it does not.
290
291There are two styles of query: (1) in the "single-key+file" style, a single
292key string and a file name are given, for example, for linear searches, DBM
293files, or for NIS. (2) In the "query" style, no "filename" is given; instead
294just a single query string is passed. This applies to multiple-key lookup
295types such as NIS+.
296
297Before opening, scan the tree of cached files to see if this file is already
298open for the correct search type. If so, return the saved handle. If not, put
299the handle in the tree for possible subsequent use. See search_tidyup above for
300closing all the cached files.
301
302A count of open databases which use real files is maintained, and if this
303gets too large, we have to close a cached file. Its entry remains in the tree,
304but is marked closed.
305
306Arguments:
307 filename the name of the file for single-key+file style lookups,
308 NULL for query-style lookups
309 search_type the type of search required
310 modemask if a real single file is used, this specifies mode bits that
311 must not be set; otherwise it is ignored
312 owners if a real single file is used, this specifies the possible
313 owners of the file; otherwise it is ignored
314 owngroups if a real single file is used, this specifies the possible
315 group owners of the file; otherwise it is ignored
316
317Returns: an identifying handle for the open database;
318 this is the pointer to the tree block in the
319 cache of open files; return NULL on open failure, with
320 a message in search_error_message
321*/
322
323void *
324search_open(uschar *filename, int search_type, int modemask, uid_t *owners,
325 gid_t *owngroups)
326{
327void *handle;
328tree_node *t;
329search_cache *c;
330lookup_info *lk = lookup_list + search_type;
331uschar keybuffer[256];
332int old_pool = store_pool;
333
334/* Change to the search store pool and remember our reset point */
335
336store_pool = POOL_SEARCH;
337if (search_reset_point == NULL) search_reset_point = store_get(0);
338
339DEBUG(D_lookup) debug_printf("search_open: %s \"%s\"\n", lk->name,
340 (filename == NULL)? US"NULL" : filename);
341
342/* See if we already have this open for this type of search, and if so,
343pass back the tree block as the handle. The key for the tree node is the search
344type plus '0' concatenated with the file name. There may be entries in the tree
345with closed files if a lot of files have been opened. */
346
347sprintf(CS keybuffer, "%c%.254s", search_type + '0',
348 (filename == NULL)? US"" : filename);
349
350if ((t = tree_search(search_tree, keybuffer)) != NULL)
351 {
352 c = (search_cache *)(t->data.ptr);
353 if (c->handle != NULL)
354 {
355 DEBUG(D_lookup) debug_printf(" cached open\n");
356 store_pool = old_pool;
357 return t;
358 }
359 DEBUG(D_lookup) debug_printf(" cached closed\n");
360 }
361
362/* Otherwise, we need to open the file or database - each search type has its
363own code, which is now split off into separately compiled modules. Before doing
364this, if the search type is one that uses real files, check on the number that
365we are holding open in the cache. If the limit is reached, close the least
366recently used one. */
367
368if (lk->type == lookup_absfile && open_filecount >= lookup_open_max)
369 {
370 if (open_bot == NULL)
371 log_write(0, LOG_MAIN|LOG_PANIC, "too many lookups open, but can't find "
372 "one to close");
373 else
374 {
375 search_cache *c = (search_cache *)(open_bot->data.ptr);
376 DEBUG(D_lookup) debug_printf("Too many lookup files open\n closing %s\n",
377 open_bot->name);
378 open_bot = c->up;
379 if (open_bot != NULL)
380 ((search_cache *)(open_bot->data.ptr))->down = NULL;
381 else
382 open_top = NULL;
383 ((lookup_list + c->search_type)->close)(c->handle);
384 c->handle = NULL;
385 open_filecount--;
386 }
387 }
388
389/* If opening is successful, call the file-checking function if there is one,
390and if all is still well, enter the open database into the tree. */
391
392handle = lk->open(filename, &search_error_message);
393if (handle == NULL)
394 {
395 store_pool = old_pool;
396 return NULL;
397 }
398
399if (lk->check != NULL &&
400 !lk->check(handle, filename, modemask, owners, owngroups,
401 &search_error_message))
402 {
403 lk->close(handle);
404 store_pool = old_pool;
405 return NULL;
406 }
407
408/* If this is a search type that uses real files, keep count. */
409
410if (lk->type == lookup_absfile) open_filecount++;
411
412/* If we found a previously opened entry in the tree, re-use it; otherwise
413insert a new entry. On re-use, leave any cached lookup data and the lookup
414count alone. */
415
416if (t == NULL)
417 {
418 t = store_get(sizeof(tree_node) + Ustrlen(keybuffer));
419 t->data.ptr = c = store_get(sizeof(search_cache));
420 c->item_cache = NULL;
421 Ustrcpy(t->name, keybuffer);
422 tree_insertnode(&search_tree, t);
423 }
424else c = t->data.ptr;
425
426c->handle = handle;
427c->search_type = search_type;
428c->up = c->down = NULL;
429
430store_pool = old_pool;
431return t;
432}
433
434
435
436
437
438/*************************************************
439* Internal function: Find one item in database *
440*************************************************/
441
442/* The answer is always put into dynamic store. The last lookup for each handle
443is cached.
444
445Arguments:
446 handle the handle from search_open; points to tree node
447 filename the filename that was handed to search_open, or
448 NULL for query-style searches
449 keystring the keystring for single-key+file lookups, or
450 the querystring for query-style lookups
451
452Returns: a pointer to a dynamic string containing the answer,
453 or NULL if the query failed or was deferred; in the
454 latter case, search_find_defer is set TRUE; after an unusual
455 failure, there may be a message in search_error_message.
456*/
457
458static uschar *
459internal_search_find(void *handle, uschar *filename, uschar *keystring)
460{
461tree_node *t = (tree_node *)handle;
462search_cache *c = (search_cache *)(t->data.ptr);
463uschar *data = NULL;
464int search_type = t->name[0] - '0';
465int old_pool = store_pool;
466
467/* Lookups that return DEFER may not always set an error message. So that
468the callers don't have to test for NULL, set an empty string. */
469
470search_error_message = US"";
471search_find_defer = FALSE;
472
473DEBUG(D_lookup) debug_printf("internal_search_find: file=\"%s\"\n "
474 "type=%s key=\"%s\"\n", filename,
475 lookup_list[search_type].name, keystring);
476
477/* Insurance. If the keystring is empty, just fail. */
478
479if (keystring[0] == 0) return NULL;
480
481/* Use the special store pool for search data */
482
483store_pool = POOL_SEARCH;
484
485/* Look up the data for the key, unless it is already in the cache for this
486file. No need to check c->item_cache for NULL, tree_search will do so. */
487
488if ((t = tree_search(c->item_cache, keystring)) == NULL)
489 {
490 BOOL do_cache = TRUE;
491 int keylength = Ustrlen(keystring);
492
493 DEBUG(D_lookup)
494 {
495 if (filename != NULL)
496 debug_printf("file lookup required for %s\n in %s\n",
497 keystring, filename);
498 else
499 debug_printf("database lookup required for %s\n", keystring);
500 }
501
502 /* Call the code for the different kinds of search. DEFER is handled
503 like FAIL, except that search_find_defer is set so the caller can
504 distinguish if necessary. */
505
506 if (lookup_list[search_type].find(c->handle, filename, keystring, keylength,
507 &data, &search_error_message, &do_cache) == DEFER)
508 {
509 search_find_defer = TRUE;
510 }
511
512 /* A record that has been found is now in data, which is either NULL
513 or points to a bit of dynamic store. Cache the result of the lookup if
514 caching is permitted. Lookups can disable caching, when they did something
515 that changes their data. The mysql and pgsql lookups do this when an
516 UPDATE/INSERT query was executed. */
517
518 else if (do_cache)
519 {
520 int len = keylength + 1;
521 t = store_get(sizeof(tree_node) + len);
522 memcpy(t->name, keystring, len);
523 t->data.ptr = data;
524 tree_insertnode(&c->item_cache, t);
525 }
526
527 /* If caching was disabled, empty the cache tree. We just set the cache
528 pointer to NULL here, because we cannot release the store at this stage. */
529
530 else
531 {
532 DEBUG(D_lookup) debug_printf("lookup forced cache cleanup\n");
533 c->item_cache = NULL;
534 }
535 }
536
537/* Data was in the cache already; set the pointer from the tree node */
538
539else
540 {
541 data = US t->data.ptr;
542 DEBUG(D_lookup) debug_printf("cached data used for lookup of %s%s%s\n",
543 keystring,
544 (filename == NULL)? US"" : US"\n in ",
545 (filename == NULL)? US"" : filename);
546 }
547
548/* Debug: output the answer */
549
550DEBUG(D_lookup)
551 {
552 if (data == NULL)
553 {
554 if (search_find_defer) debug_printf("lookup deferred: %s\n",
555 search_error_message);
556 else debug_printf("lookup failed\n");
557 }
558 else debug_printf("lookup yielded: %s\n", data);
559 }
560
561/* Return it in new dynamic store in the regular pool */
562
563store_pool = old_pool;
564return (data == NULL)? NULL : string_copy(data);
565}
566
567
568
569
570/*************************************************
571* Find one item in database, possibly wildcarded *
572*************************************************/
573
574/* This function calls the internal function above; once only if there
575is no partial matching, but repeatedly when partial matching is requested.
576
577Arguments:
578 handle the handle from search_open
579 filename the filename that was handed to search_open, or
580 NULL for query-style searches
581 keystring the keystring for single-key+file lookups, or
582 the querystring for query-style lookups
583 partial -1 means no partial matching;
584 otherwise it's the minimum number of components;
585 affix the affix string for partial matching
586 affixlen the length of the affix string
587 starflags SEARCH_STAR and SEARCH_STARAT flags
588 expand_setup pointer to offset for setting up expansion strings;
589 don't do any if < 0
590
591Returns: a pointer to a dynamic string containing the answer,
592 or NULL if the query failed or was deferred; in the
593 latter case, search_find_defer is set TRUE
594*/
595
596uschar *
597search_find(void *handle, uschar *filename, uschar *keystring, int partial,
598 uschar *affix, int affixlen, int starflags, int *expand_setup)
599{
600tree_node *t = (tree_node *)handle;
601BOOL set_null_wild = FALSE;
602uschar *yield;
603
604DEBUG(D_lookup)
605 {
606 if (partial < 0) affixlen = 99; /* So that "NULL" prints */
607 debug_printf("search_find: file=\"%s\"\n key=\"%s\" "
608 "partial=%d affix=%.*s starflags=%x\n",
609 (filename == NULL)? US"NULL" : filename,
610 keystring, partial, affixlen, affix, starflags);
611 }
612
613/* Arrange to put this database at the top of the LRU chain if it is a type
614that opens real files. */
615
616if (open_top != (tree_node *)handle &&
617 lookup_list[t->name[0]-'0'].type == lookup_absfile)
618 {
619 search_cache *c = (search_cache *)(t->data.ptr);
620 tree_node *up = c->up;
621 tree_node *down = c->down;
622
623 /* Cut it out of the list. A newly opened file will a NULL up pointer.
624 Otherwise there will be a non-NULL up pointer, since we checked above that
625 this block isn't already at the top of the list. */
626
627 if (up != NULL)
628 {
629 ((search_cache *)(up->data.ptr))->down = down;
630 if (down != NULL)
631 ((search_cache *)(down->data.ptr))->up = up;
632 else open_bot = up;
633 }
634
635 /* Now put it at the head of the list. */
636
637 c->up = NULL;
638 c->down = open_top;
639 if (open_top == NULL) open_bot = t; else
640 ((search_cache *)(open_top->data.ptr))->up = t;
641 open_top = t;
642 }
643
644DEBUG(D_lookup)
645 {
646 tree_node *t = open_top;
647 debug_printf("LRU list:\n");
648 while (t != NULL)
649 {
650 search_cache *c = (search_cache *)(t->data.ptr);
651 debug_printf(" %s\n", t->name);
652 if (t == open_bot) debug_printf(" End\n");
653 t = c->down;
654 }
655 }
656
657/* First of all, try to match the key string verbatim. If matched a complete
658entry but could have been partial, flag to set up variables. */
659
660yield = internal_search_find(handle, filename, keystring);
661if (search_find_defer) return NULL;
662if (yield != NULL) { if (partial >= 0) set_null_wild = TRUE; }
663
664/* Not matched a complete entry; handle partial lookups, but only if the full
665search didn't defer. Don't use string_sprintf() to construct the initial key,
666just in case the original key is too long for the string_sprintf() buffer (it
667*has* happened!). The case of a zero-length affix has to be treated specially.
668*/
669
670else if (partial >= 0)
671 {
672 int len = Ustrlen(keystring);
673 uschar *keystring2;
674
675 /* Try with the affix on the front, except for a zero-length affix */
676
677 if (affixlen == 0) keystring2 = keystring; else
678 {
679 keystring2 = store_get(len + affixlen + 1);
680 Ustrncpy(keystring2, affix, affixlen);
681 Ustrcpy(keystring2 + affixlen, keystring);
682 DEBUG(D_lookup) debug_printf("trying partial match %s\n", keystring2);
683 yield = internal_search_find(handle, filename, keystring2);
684 if (search_find_defer) return NULL;
685 }
686
687 /* The key in its entirety did not match a wild entry; try chopping off
688 leading components. */
689
690 if (yield == NULL)
691 {
692 int dotcount = 0;
693 uschar *keystring3 = keystring2 + affixlen;
694 uschar *s = keystring3;
695 while (*s != 0) if (*s++ == '.') dotcount++;
696
697 while (dotcount-- >= partial)
698 {
699 while (*keystring3 != 0 && *keystring3 != '.') keystring3++;
700
701 /* If we get right to the end of the string (which will be the last time
702 through this loop), we've failed if the affix is null. Otherwise do one
703 last lookup for the affix itself, but if it is longer than 1 character,
704 remove the last character if it is ".". */
705
706 if (*keystring3 == 0)
707 {
708 if (affixlen < 1) break;
709 if (affixlen > 1 && affix[affixlen-1] == '.') affixlen--;
710 Ustrncpy(keystring2, affix, affixlen);
711 keystring2[affixlen] = 0;
712 keystring3 = keystring2;
713 }
714 else
715 {
716 keystring3 -= affixlen - 1;
717 if (affixlen > 0) Ustrncpy(keystring3, affix, affixlen);
718 }
719
720 DEBUG(D_lookup) debug_printf("trying partial match %s\n", keystring3);
721 yield = internal_search_find(handle, filename, keystring3);
722 if (search_find_defer) return NULL;
723 if (yield != NULL)
724 {
725 /* First variable is the wild part; second is the fixed part. Take care
726 to get it right when keystring3 is just "*". */
727
728 if (expand_setup != NULL && *expand_setup >= 0)
729 {
730 int fixedlength = Ustrlen(keystring3) - affixlen;
731 int wildlength = Ustrlen(keystring) - fixedlength - 1;
732 *expand_setup += 1;
733 expand_nstring[*expand_setup] = keystring;
734 expand_nlength[*expand_setup] = wildlength;
735 *expand_setup += 1;
736 expand_nstring[*expand_setup] = keystring + wildlength + 1;
737 expand_nlength[*expand_setup] = (fixedlength < 0)? 0 : fixedlength;
738 }
739 break;
740 }
741 keystring3 += affixlen;
742 }
743 }
744
745 else set_null_wild = TRUE; /* Matched a wild entry without any wild part */
746 }
747
748/* If nothing has been matched, but the option to look for "*@" is set, try
749replacing everthing to the left of @ by *. After a match, the wild part
750is set to the string to the left of the @. */
751
752if (yield == NULL && (starflags & SEARCH_STARAT) != 0)
753 {
754 uschar *atat = Ustrrchr(keystring, '@');
755 if (atat != NULL && atat > keystring)
756 {
757 int savechar;
758 savechar = *(--atat);
759 *atat = '*';
760
761 DEBUG(D_lookup) debug_printf("trying default match %s\n", atat);
762 yield = internal_search_find(handle, filename, atat);
763 *atat = savechar;
764 if (search_find_defer) return NULL;
765
766 if (yield != NULL && expand_setup != NULL && *expand_setup >= 0)
767 {
768 *expand_setup += 1;
769 expand_nstring[*expand_setup] = keystring;
770 expand_nlength[*expand_setup] = atat - keystring + 1;
771 *expand_setup += 1;
772 expand_nstring[*expand_setup] = keystring;
773 expand_nlength[*expand_setup] = 0;
774 }
775 }
776 }
777
778/* If we still haven't matched anything, and the option to look for "*" is set,
779try that. If we do match, the first variable (the wild part) is the whole key,
780and the second is empty. */
781
782if (yield == NULL && (starflags & (SEARCH_STAR|SEARCH_STARAT)) != 0)
783 {
784 DEBUG(D_lookup) debug_printf("trying to match *\n");
785 yield = internal_search_find(handle, filename, US"*");
786 if (yield != NULL && expand_setup != NULL && *expand_setup >= 0)
787 {
788 *expand_setup += 1;
789 expand_nstring[*expand_setup] = keystring;
790 expand_nlength[*expand_setup] = Ustrlen(keystring);
791 *expand_setup += 1;
792 expand_nstring[*expand_setup] = keystring;
793 expand_nlength[*expand_setup] = 0;
794 }
795 }
796
797/* If this was a potentially partial lookup, and we matched either a
798complete non-wild domain entry, or we matched a wild-carded entry without
799chopping off any of the domain components, set up the expansion variables
800(if required) so that the first one is empty, and the second one is the
801fixed part of the domain. The set_null_wild flag is set only when yield is not
802NULL. */
803
804if (set_null_wild && expand_setup != NULL && *expand_setup >= 0)
805 {
806 *expand_setup += 1;
807 expand_nstring[*expand_setup] = keystring;
808 expand_nlength[*expand_setup] = 0;
809 *expand_setup += 1;
810 expand_nstring[*expand_setup] = keystring;
811 expand_nlength[*expand_setup] = Ustrlen(keystring);
812 }
813
814return yield;
815}
816
817/* End of search.c */