Lookups: per-searchtype options framework
[exim.git] / src / src / lookups / dsearch.c
CommitLineData
0756eb3c
PH
1/*************************************************
2* Exim - an Internet mail transport agent *
3*************************************************/
4
3386088d 5/* Copyright (c) University of Cambridge 1995 - 2015 */
0756eb3c
PH
6/* See the file NOTICE for conditions of use and distribution. */
7
8/* The idea for this code came from Matthew Byng-Maddick, but his original has
0f2cbd1b
MH
9been heavily reworked a lot for Exim 4 (and it now uses stat() (more precisely:
10lstat()) rather than a directory scan). */
0756eb3c
PH
11
12
13#include "../exim.h"
14#include "lf_functions.h"
0756eb3c
PH
15
16
17
18/*************************************************
19* Open entry point *
20*************************************************/
21
22/* See local README for interface description. We open the directory to test
23whether it exists and whether it is searchable. However, we don't need to keep
0f2cbd1b 24it open, because the "search" can be done by a call to lstat() rather than
0756eb3c
PH
25actually scanning through the list of files. */
26
e6d225ae 27static void *
d447dbd1 28dsearch_open(const uschar * dirname, uschar ** errmsg)
0756eb3c 29{
54a2a2a9 30DIR * dp = exim_opendir(dirname);
36b600bb 31if (!dp)
0756eb3c
PH
32 {
33 int save_errno = errno;
34 *errmsg = string_open_failed(errno, "%s for directory search", dirname);
35 errno = save_errno;
36 return NULL;
37 }
38closedir(dp);
39return (void *)(-1);
40}
41
42
43/*************************************************
44* Check entry point *
45*************************************************/
46
47/* The handle will always be (void *)(-1), but don't try casting it to an
48integer as this gives warnings on 64-bit systems. */
49
36b600bb 50static BOOL
d447dbd1
JH
51dsearch_check(void * handle, const uschar * filename, int modemask,
52 uid_t * owners, gid_t * owngroups, uschar ** errmsg)
0756eb3c
PH
53{
54handle = handle;
129a5d13
JH
55if (*filename == '/')
56 return lf_check_file(-1, filename, S_IFDIR, modemask, owners, owngroups,
57 "dsearch", errmsg) == 0;
58*errmsg = string_sprintf("dirname '%s' for dsearch is not absolute", filename);
59return FALSE;
0756eb3c
PH
60}
61
62
63/*************************************************
64* Find entry point *
65*************************************************/
66
0f2cbd1b 67/* See local README for interface description. We use lstat() instead of
0756eb3c
PH
68scanning the directory, as it is hopefully faster to let the OS do the scanning
69for us. */
70
13e70f55 71static int
d447dbd1 72dsearch_find(void * handle, const uschar * dirname, const uschar * keystring,
67a57a5a
JH
73 int length, uschar ** result, uschar ** errmsg, uint * do_cache,
74 const uschar * opts)
0756eb3c
PH
75{
76struct stat statbuf;
77int save_errno;
13e70f55 78uschar * filename;
0756eb3c
PH
79
80handle = handle; /* Keep picky compilers happy */
81length = length;
82do_cache = do_cache;
83
84if (Ustrchr(keystring, '/') != 0)
85 {
86 *errmsg = string_sprintf("key for dsearch lookup contains a slash: %s",
87 keystring);
88 return DEFER;
89 }
90
13e70f55 91filename = string_sprintf("%s/%s", dirname, keystring);
0f2cbd1b 92if (Ulstat(filename, &statbuf) >= 0)
0756eb3c 93 {
36b600bb
JH
94 /* Since the filename exists in the filesystem, we can return a
95 non-tainted result. */
96 *result = string_copy_taint(keystring, FALSE);
0756eb3c
PH
97 return OK;
98 }
99
100if (errno == ENOENT) return FAIL;
101
102save_errno = errno;
0f2cbd1b 103*errmsg = string_sprintf("%s: lstat failed", filename);
0756eb3c
PH
104errno = save_errno;
105return DEFER;
106}
107
108
109/*************************************************
110* Close entry point *
111*************************************************/
112
113/* See local README for interface description */
114
115void
e6d225ae 116static dsearch_close(void *handle)
0756eb3c
PH
117{
118handle = handle; /* Avoid compiler warning */
119}
120
6545de78
PP
121
122/*************************************************
123* Version reporting entry point *
124*************************************************/
125
126/* See local README for interface description. */
127
128#include "../version.h"
129
130void
131dsearch_version_report(FILE *f)
132{
133#ifdef DYNLOOKUP
134fprintf(f, "Library version: dsearch: Exim version %s\n", EXIM_VERSION_STR);
135#endif
136}
137
138
e6d225ae
DW
139static lookup_info _lookup_info = {
140 US"dsearch", /* lookup name */
141 lookup_absfile, /* uses absolute file name */
142 dsearch_open, /* open function */
143 dsearch_check, /* check function */
144 dsearch_find, /* find function */
145 dsearch_close, /* close function */
146 NULL, /* no tidy function */
6545de78
PP
147 NULL, /* no quoting function */
148 dsearch_version_report /* version reporting */
e6d225ae
DW
149};
150
151#ifdef DYNLOOKUP
152#define dsearch_lookup_module_info _lookup_module_info
153#endif
154
155static lookup_info *_lookup_list[] = { &_lookup_info };
156lookup_module_info dsearch_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
157
0756eb3c 158/* End of lookups/dsearch.c */