Version reporting & module ABI change.
[exim.git] / src / src / lookups / dbmdb.c
1 /* $Cambridge: exim/src/src/lookups/dbmdb.c,v 1.6 2009/11/16 19:50:38 nm4 Exp $ */
2
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
6
7 /* Copyright (c) University of Cambridge 1995 - 2009 */
8 /* See the file NOTICE for conditions of use and distribution. */
9
10 #include "../exim.h"
11 #include "lf_functions.h"
12
13
14 /*************************************************
15 * Open entry point *
16 *************************************************/
17
18 /* See local README for interface description */
19
20 static void *
21 dbmdb_open(uschar *filename, uschar **errmsg)
22 {
23 EXIM_DB *yield;
24 EXIM_DBOPEN(filename, O_RDONLY, 0, &yield);
25 if (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 }
31 return 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!
41 We need to know what the real file names are in order to check the owners and
42 modes. If USE_DB is set, we know it is Berkeley DB, which uses an unmodified
43 file name. If USE_TDB or USE_GDBM is set, we know it is tdb or gdbm, which do
44 the same. Otherwise, for safety, we have to check for x.db or x.dir and x.pag.
45 */
46
47 static BOOL
48 dbmdb_check(void *handle, uschar *filename, int modemask, uid_t *owners,
49 gid_t *owngroups, uschar **errmsg)
50 {
51 int rc;
52 handle = handle; /* Keep picky compilers happy */
53
54 #if defined(USE_DB) || defined(USE_TDB) || defined(USE_GDBM)
55 rc = lf_check_file(-1, filename, S_IFREG, modemask, owners, owngroups,
56 "dbm", errmsg);
57 #else
58 {
59 uschar filebuffer[256];
60 (void)sprintf(CS filebuffer, "%.250s.db", filename);
61 rc = lf_check_file(-1, filebuffer, S_IFREG, modemask, owners, owngroups,
62 "dbm", errmsg);
63 if (rc < 0) /* stat() failed */
64 {
65 (void)sprintf(CS filebuffer, "%.250s.dir", filename);
66 rc = lf_check_file(-1, filebuffer, S_IFREG, modemask, owners, owngroups,
67 "dbm", errmsg);
68 if (rc == 0) /* x.dir was OK */
69 {
70 (void)sprintf(CS filebuffer, "%.250s.pag", filename);
71 rc = lf_check_file(-1, filebuffer, S_IFREG, modemask, owners, owngroups,
72 "dbm", errmsg);
73 }
74 }
75 }
76 #endif
77
78 return 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
88 the keylength in order to include the terminating zero. */
89
90 static int
91 dbmdb_find(void *handle, uschar *filename, uschar *keystring, int length,
92 uschar **result, uschar **errmsg, BOOL *do_cache)
93 {
94 EXIM_DB *d = (EXIM_DB *)handle;
95 EXIM_DATUM key, data;
96
97 filename = filename; /* Keep picky compilers happy */
98 errmsg = errmsg;
99 do_cache = do_cache;
100
101 EXIM_DATUM_INIT(key); /* Some DBM libraries require datums to */
102 EXIM_DATUM_INIT(data); /* be cleared before use. */
103 EXIM_DATUM_DATA(key) = CS keystring;
104 EXIM_DATUM_SIZE(key) = length + 1;
105
106 if (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 }
112 return FAIL;
113 }
114
115
116
117 /*************************************************
118 * Find entry point - no zero on key *
119 *************************************************/
120
121 /* See local README for interface description */
122
123 int
124 static dbmnz_find(void *handle, uschar *filename, uschar *keystring, int length,
125 uschar **result, uschar **errmsg, BOOL *do_cache)
126 {
127 return 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
139 void
140 static dbmdb_close(void *handle)
141 {
142 EXIM_DBCLOSE((EXIM_DB *)handle);
143 }
144
145
146
147 /*************************************************
148 * Version reporting entry point *
149 *************************************************/
150
151 /* See local README for interface description. */
152
153 #include "../version.h"
154
155 void
156 dbm_version_report(FILE *f)
157 {
158 #ifdef DYNLOOKUP
159 fprintf(f, "Library version: DBM: Exim version %s\n", EXIM_VERSION_STR);
160 #endif
161 }
162
163
164 lookup_info dbm_lookup_info = {
165 US"dbm", /* lookup name */
166 lookup_absfile, /* uses absolute file name */
167 dbmdb_open, /* open function */
168 dbmdb_check, /* check function */
169 dbmdb_find, /* find function */
170 dbmdb_close, /* close function */
171 NULL, /* no tidy function */
172 NULL, /* no quoting function */
173 dbm_version_report /* version reporting */
174 };
175
176 lookup_info dbmz_lookup_info = {
177 US"dbmnz", /* lookup name */
178 lookup_absfile, /* uses absolute file name */
179 dbmdb_open, /* sic */ /* open function */
180 dbmdb_check, /* sic */ /* check function */
181 dbmnz_find, /* find function */
182 dbmdb_close, /* sic */ /* close function */
183 NULL, /* no tidy function */
184 NULL, /* no quoting function */
185 NULL /* no version reporting (redundant) */
186 };
187
188 #ifdef DYNLOOKUP
189 #define dbmdb_lookup_module_info _lookup_module_info
190 #endif
191
192 static lookup_info *_lookup_list[] = { &dbm_lookup_info, &dbmz_lookup_info };
193 lookup_module_info dbmdb_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 2 };
194
195 /* End of lookups/dbmdb.c */