Module loading working on FreeBSD (and unbreak).
[exim.git] / src / src / lookups / dbmdb.c
CommitLineData
0a49a7a4 1/* $Cambridge: exim/src/src/lookups/dbmdb.c,v 1.6 2009/11/16 19:50:38 nm4 Exp $ */
0756eb3c
PH
2
3/*************************************************
4* Exim - an Internet mail transport agent *
5*************************************************/
6
0a49a7a4 7/* Copyright (c) University of Cambridge 1995 - 2009 */
0756eb3c
PH
8/* See the file NOTICE for conditions of use and distribution. */
9
10#include "../exim.h"
11#include "lf_functions.h"
0756eb3c
PH
12
13
14/*************************************************
15* Open entry point *
16*************************************************/
17
18/* See local README for interface description */
19
e6d225ae 20static void *
0756eb3c
PH
21dbmdb_open(uschar *filename, uschar **errmsg)
22{
23EXIM_DB *yield;
24EXIM_DBOPEN(filename, O_RDONLY, 0, &yield);
25if (yield == NULL)
26 {
27 int save_errno = errno;
28 *errmsg = string_open_failed(errno, "%s as a %s file", filename, EXIM_DBTYPE);
29 errno = save_errno;
30 }
31return yield;
32}
33
34
35
36/*************************************************
37* Check entry point *
38*************************************************/
39
40/* This needs to know more about the underlying files than is good for it!
41We need to know what the real file names are in order to check the owners and
42modes. If USE_DB is set, we know it is Berkeley DB, which uses an unmodified
43file name. If USE_TDB or USE_GDBM is set, we know it is tdb or gdbm, which do
44the same. Otherwise, for safety, we have to check for x.db or x.dir and x.pag.
45*/
46
e6d225ae 47static BOOL
0756eb3c
PH
48dbmdb_check(void *handle, uschar *filename, int modemask, uid_t *owners,
49 gid_t *owngroups, uschar **errmsg)
50{
51int rc;
52handle = handle; /* Keep picky compilers happy */
53
54#if defined(USE_DB) || defined(USE_TDB) || defined(USE_GDBM)
55rc = lf_check_file(-1, filename, S_IFREG, modemask, owners, owngroups,
56 "dbm", errmsg);
57#else
58 {
59 uschar filebuffer[256];
f1e894f3 60 (void)sprintf(CS filebuffer, "%.250s.db", filename);
0756eb3c
PH
61 rc = lf_check_file(-1, filebuffer, S_IFREG, modemask, owners, owngroups,
62 "dbm", errmsg);
63 if (rc < 0) /* stat() failed */
64 {
f1e894f3 65 (void)sprintf(CS filebuffer, "%.250s.dir", filename);
0756eb3c
PH
66 rc = lf_check_file(-1, filebuffer, S_IFREG, modemask, owners, owngroups,
67 "dbm", errmsg);
68 if (rc == 0) /* x.dir was OK */
69 {
f1e894f3 70 (void)sprintf(CS filebuffer, "%.250s.pag", filename);
0756eb3c
PH
71 rc = lf_check_file(-1, filebuffer, S_IFREG, modemask, owners, owngroups,
72 "dbm", errmsg);
73 }
74 }
75 }
76#endif
77
78return rc == 0;
79}
80
81
82
83/*************************************************
84* Find entry point *
85*************************************************/
86
87/* See local README for interface description. This function adds 1 to
88the keylength in order to include the terminating zero. */
89
e6d225ae 90static int
0756eb3c
PH
91dbmdb_find(void *handle, uschar *filename, uschar *keystring, int length,
92 uschar **result, uschar **errmsg, BOOL *do_cache)
93{
94EXIM_DB *d = (EXIM_DB *)handle;
95EXIM_DATUM key, data;
96
97filename = filename; /* Keep picky compilers happy */
98errmsg = errmsg;
99do_cache = do_cache;
100
101EXIM_DATUM_INIT(key); /* Some DBM libraries require datums to */
102EXIM_DATUM_INIT(data); /* be cleared before use. */
103EXIM_DATUM_DATA(key) = CS keystring;
104EXIM_DATUM_SIZE(key) = length + 1;
105
106if (EXIM_DBGET(d, key, data))
107 {
108 *result = string_copyn(US EXIM_DATUM_DATA(data), EXIM_DATUM_SIZE(data));
109 EXIM_DATUM_FREE(data); /* Some DBM libraries need a free() call */
110 return OK;
111 }
112return FAIL;
113}
114
115
116
117/*************************************************
118* Find entry point - no zero on key *
119*************************************************/
120
121/* See local README for interface description */
122
123int
e6d225ae 124static dbmnz_find(void *handle, uschar *filename, uschar *keystring, int length,
0756eb3c
PH
125 uschar **result, uschar **errmsg, BOOL *do_cache)
126{
127return dbmdb_find(handle, filename, keystring, length-1, result, errmsg,
128 do_cache);
129}
130
131
132
133/*************************************************
134* Close entry point *
135*************************************************/
136
137/* See local README for interface description */
138
139void
e6d225ae 140static dbmdb_close(void *handle)
0756eb3c
PH
141{
142EXIM_DBCLOSE((EXIM_DB *)handle);
143}
144
e6d225ae
DW
145lookup_info dbm_lookup_info = {
146 US"dbm", /* lookup name */
147 lookup_absfile, /* uses absolute file name */
148 dbmdb_open, /* open function */
149 dbmdb_check, /* check function */
150 dbmdb_find, /* find function */
151 dbmdb_close, /* close function */
152 NULL, /* no tidy function */
153 NULL /* no quoting function */
154};
155
156lookup_info dbmz_lookup_info = {
157 US"dbmnz", /* lookup name */
158 lookup_absfile, /* uses absolute file name */
159 dbmdb_open, /* sic */ /* open function */
160 dbmdb_check, /* sic */ /* check function */
161 dbmnz_find, /* find function */
162 dbmdb_close, /* sic */ /* close function */
163 NULL, /* no tidy function */
164 NULL /* no quoting function */
165};
166
167#ifdef DYNLOOKUP
168#define dbmdb_lookup_module_info _lookup_module_info
169#endif
170
171static lookup_info *_lookup_list[] = { &dbm_lookup_info, &dbmz_lookup_info };
172lookup_module_info dbmdb_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 2 };
173
0756eb3c 174/* End of lookups/dbmdb.c */