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