Update version number and copyright year.
[exim.git] / src / src / lookups / dsearch.c
CommitLineData
184e8823 1/* $Cambridge: exim/src/src/lookups/dsearch.c,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */
0756eb3c
PH
2
3/*************************************************
4* Exim - an Internet mail transport agent *
5*************************************************/
6
184e8823 7/* Copyright (c) University of Cambridge 1995 - 2007 */
0756eb3c
PH
8/* See the file NOTICE for conditions of use and distribution. */
9
10/* The idea for this code came from Matthew Byng-Maddick, but his original has
11been heavily reworked a lot for Exim 4 (and it now uses stat() rather than a
12directory scan). */
13
14
15#include "../exim.h"
16#include "lf_functions.h"
17#include "dsearch.h"
18
19
20
21/*************************************************
22* Open entry point *
23*************************************************/
24
25/* See local README for interface description. We open the directory to test
26whether it exists and whether it is searchable. However, we don't need to keep
27it open, because the "search" can be done by a call to stat() rather than
28actually scanning through the list of files. */
29
30void *
31dsearch_open(uschar *dirname, uschar **errmsg)
32{
33DIR *dp = opendir(CS dirname);
34if (dp == NULL)
35 {
36 int save_errno = errno;
37 *errmsg = string_open_failed(errno, "%s for directory search", dirname);
38 errno = save_errno;
39 return NULL;
40 }
41closedir(dp);
42return (void *)(-1);
43}
44
45
46/*************************************************
47* Check entry point *
48*************************************************/
49
50/* The handle will always be (void *)(-1), but don't try casting it to an
51integer as this gives warnings on 64-bit systems. */
52
53BOOL
54dsearch_check(void *handle, uschar *filename, int modemask, uid_t *owners,
55 gid_t *owngroups, uschar **errmsg)
56{
57handle = handle;
58return lf_check_file(-1, filename, S_IFDIR, modemask, owners, owngroups,
59 "dsearch", errmsg) == 0;
60}
61
62
63/*************************************************
64* Find entry point *
65*************************************************/
66
67/* See local README for interface description. We use stat() instead of
68scanning the directory, as it is hopefully faster to let the OS do the scanning
69for us. */
70
71int
72dsearch_find(void *handle, uschar *dirname, uschar *keystring, int length,
73 uschar **result, uschar **errmsg, BOOL *do_cache)
74{
75struct stat statbuf;
76int save_errno;
77uschar filename[PATH_MAX];
78
79handle = handle; /* Keep picky compilers happy */
80length = length;
81do_cache = do_cache;
82
83if (Ustrchr(keystring, '/') != 0)
84 {
85 *errmsg = string_sprintf("key for dsearch lookup contains a slash: %s",
86 keystring);
87 return DEFER;
88 }
89
90if (!string_format(filename, sizeof(filename), "%s/%s", dirname, keystring))
91 {
92 *errmsg = US"path name too long";
93 return DEFER;
94 }
95
96if (Ustat(filename, &statbuf) >= 0)
97 {
98 *result = string_copy(keystring);
99 return OK;
100 }
101
102if (errno == ENOENT) return FAIL;
103
104save_errno = errno;
105*errmsg = string_sprintf("%s: stat failed", filename);
106errno = save_errno;
107return DEFER;
108}
109
110
111/*************************************************
112* Close entry point *
113*************************************************/
114
115/* See local README for interface description */
116
117void
118dsearch_close(void *handle)
119{
120handle = handle; /* Avoid compiler warning */
121}
122
123/* End of lookups/dsearch.c */