tidying
[exim.git] / src / src / dbstuff.h
CommitLineData
059ec3d9
PH
1/*************************************************
2* Exim - an Internet mail transport agent *
3*************************************************/
4
0a49a7a4 5/* Copyright (c) University of Cambridge 1995 - 2009 */
059ec3d9
PH
6/* See the file NOTICE for conditions of use and distribution. */
7
8/* This header file contains macro definitions so that a variety of DBM
9libraries can be used by Exim. Nigel Metheringham provided the original set for
10Berkeley DB 1.x in native mode and ndbm. Subsequently, versions for Berkeley DB
112.x and 3.x were added. Later still, support for tdb was added, courtesy of
12James Antill. Most recently, support for native mode gdbm was added, with code
13from Pierre A. Humblet, so Exim could be made to work with Cygwin.
14
15For convenience, the definitions of the structures used in the various hints
16databases are also kept in this file, which is used by the maintenance
17utilities as well as the main Exim binary. */
18
19
20# ifdef USE_TDB
21
22/* ************************* tdb interface ************************ */
23
24#include <tdb.h>
25
26/* Basic DB type */
27#define EXIM_DB TDB_CONTEXT
28
29/* Cursor type: tdb uses the previous "key" in _nextkey() (really it wants
30tdb_traverse to be called) */
31#define EXIM_CURSOR TDB_DATA
32
33/* The datum type used for queries */
34#define EXIM_DATUM TDB_DATA
35
36/* Some text for messages */
37#define EXIM_DBTYPE "tdb"
38
39/* Access functions */
40
41/* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed */
0a6c178c 42#define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
059ec3d9
PH
43 *(dbpp) = tdb_open(CS name, 0, TDB_DEFAULT, flags, mode)
44
45/* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
46#define EXIM_DBGET(db, key, data) \
47 (data = tdb_fetch(db, key), data.dptr != NULL)
48
49/* EXIM_DBPUT - returns nothing useful, assumes replace mode */
50#define EXIM_DBPUT(db, key, data) \
51 tdb_store(db, key, data, TDB_REPLACE)
52
53/* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
54#define EXIM_DBPUTB(db, key, data) \
55 tdb_store(db, key, data, TDB_INSERT)
56
57/* Returns from EXIM_DBPUTB */
58
59#define EXIM_DBPUTB_OK 0
60#define EXIM_DBPUTB_DUP (-1)
61
62/* EXIM_DBDEL */
63#define EXIM_DBDEL(db, key) tdb_delete(db, key)
64
65/* EXIM_DBCREATE_CURSOR - initialize for scanning operation */
66#define EXIM_DBCREATE_CURSOR(db, cursor) { \
40c90bca 67 *(cursor) = store_malloc(sizeof(TDB_DATA)); (*(cursor))->dptr = NULL; }
059ec3d9
PH
68
69/* EXIM_DBSCAN - This is complicated because we have to free the last datum
70free() must not die when passed NULL */
71#define EXIM_DBSCAN(db, key, data, first, cursor) \
72 (key = (first ? tdb_firstkey(db) : tdb_nextkey(db, *(cursor))), \
73 free((cursor)->dptr), *(cursor) = key, \
74 key.dptr != NULL)
75
76/* EXIM_DBDELETE_CURSOR - terminate scanning operation. */
77#define EXIM_DBDELETE_CURSOR(cursor) free(cursor)
78
79/* EXIM_DBCLOSE */
0a6c178c 80#define EXIM_DBCLOSE__(db) tdb_close(db)
059ec3d9
PH
81
82/* Datum access types - these are intended to be assignable */
83
84#define EXIM_DATUM_SIZE(datum) (datum).dsize
85#define EXIM_DATUM_DATA(datum) (datum).dptr
86
87/* Free the stuff inside the datum. */
88
89#define EXIM_DATUM_FREE(datum) (free((datum).dptr), (datum).dptr = NULL)
90
91/* No initialization is needed. */
92
93#define EXIM_DATUM_INIT(datum)
94
95
96
97/********************* Berkeley db native definitions **********************/
98
99#elif defined USE_DB
100
101#include <db.h>
102
103
104/* We can distinguish between versions 1.x and 2.x/3.x by looking for a
105definition of DB_VERSION_STRING, which is present in versions 2.x onwards. */
106
107#ifdef DB_VERSION_STRING
108
109/* The API changed (again!) between the 2.x and 3.x versions */
110
111#if DB_VERSION_MAJOR >= 3
112
113/***************** Berkeley db 3.x/4.x native definitions ******************/
114
115/* Basic DB type */
0a6c178c
JH
116#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
117# define EXIM_DB DB_ENV
059ec3d9
PH
118/* Cursor type, for scanning */
119#define EXIM_CURSOR DBC
120
121/* The datum type used for queries */
122#define EXIM_DATUM DBT
123
124/* Some text for messages */
0a6c178c 125#define EXIM_DBTYPE "db (v4.1+)"
059ec3d9
PH
126
127/* Access functions */
128
129/* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed. The
0a6c178c
JH
130API changed for DB 4.1. - and we also starting using the "env" with a
131specified working dir, to avoid the DBCONFIG file trap. */
132
133# define ENV_TO_DB(env) ((DB *)((env)->app_private))
134
135# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
136 if ( db_env_create(dbpp, 0) != 0 \
137 || ((*dbpp)->set_errcall(*dbpp, dbfn_bdb_error_callback), 0) \
138 || (*dbpp)->open(*dbpp, CS dirname, DB_CREATE|DB_INIT_MPOOL|DB_PRIVATE, 0) != 0\
139 ) \
140 *dbpp = NULL; \
141 else if (db_create((DB **) &((*dbpp)->app_private), *dbpp, 0) != 0) \
142 { \
143 ((DB_ENV *)(*dbpp))->close((DB_ENV *)(*dbpp), 0); \
144 *dbpp = NULL; \
145 } \
146 else if (ENV_TO_DB(*dbpp)->open(ENV_TO_DB(*dbpp), NULL, CS name, NULL, \
147 (flags) == O_RDONLY ? DB_UNKNOWN : DB_HASH, \
148 (flags) == O_RDONLY ? DB_RDONLY : DB_CREATE, \
149 mode) != 0 \
150 ) \
151 { \
152 ENV_TO_DB(*dbpp)->close(ENV_TO_DB(*dbpp), 0); \
153 ((DB_ENV *)(*dbpp))->close((DB_ENV *)(*dbpp), 0); \
154 *dbpp = NULL; \
155 }
059ec3d9 156
0a6c178c
JH
157/* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
158# define EXIM_DBGET(db, key, data) \
159 (ENV_TO_DB(db)->get(ENV_TO_DB(db), NULL, &key, &data, 0) == 0)
160
161/* EXIM_DBPUT - returns nothing useful, assumes replace mode */
162# define EXIM_DBPUT(db, key, data) \
163 ENV_TO_DB(db)->put(ENV_TO_DB(db), NULL, &key, &data, 0)
164
165/* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
166# define EXIM_DBPUTB(db, key, data) \
167 ENV_TO_DB(db)->put(ENV_TO_DB(db), NULL, &key, &data, DB_NOOVERWRITE)
168
169/* Return values from EXIM_DBPUTB */
170
171# define EXIM_DBPUTB_OK 0
172# define EXIM_DBPUTB_DUP DB_KEYEXIST
173
174/* EXIM_DBDEL */
175# define EXIM_DBDEL(db, key) ENV_TO_DB(db)->del(ENV_TO_DB(db), NULL, &key, 0)
176
177/* EXIM_DBCREATE_CURSOR - initialize for scanning operation */
178
179# define EXIM_DBCREATE_CURSOR(db, cursor) \
180 ENV_TO_DB(db)->cursor(ENV_TO_DB(db), NULL, cursor, 0)
181
182/* EXIM_DBSCAN - returns TRUE if data is returned, FALSE at end */
183# define EXIM_DBSCAN(db, key, data, first, cursor) \
184 ((cursor)->c_get(cursor, &key, &data, \
185 (first? DB_FIRST : DB_NEXT)) == 0)
186
187/* EXIM_DBDELETE_CURSOR - terminate scanning operation */
188# define EXIM_DBDELETE_CURSOR(cursor) \
189 (cursor)->c_close(cursor)
190
191/* EXIM_DBCLOSE */
192# define EXIM_DBCLOSE__(db) \
193 (ENV_TO_DB(db)->close(ENV_TO_DB(db), 0) , ((DB_ENV *)(db))->close((DB_ENV *)(db), DB_FORCESYNC))
194
195/* Datum access types - these are intended to be assignable. */
196
197# define EXIM_DATUM_SIZE(datum) (datum).size
198# define EXIM_DATUM_DATA(datum) (datum).data
199
200/* The whole datum structure contains other fields that must be cleared
201before use, but we don't have to free anything after reading data. */
202
203# define EXIM_DATUM_INIT(datum) memset(&datum, 0, sizeof(datum))
204# define EXIM_DATUM_FREE(datum)
205
206#else /* pre- 4.1 */
207
208# define EXIM_DB DB
209
210/* Cursor type, for scanning */
211# define EXIM_CURSOR DBC
212
213/* The datum type used for queries */
214# define EXIM_DATUM DBT
215
216/* Some text for messages */
217# define EXIM_DBTYPE "db (v3/4)"
218
219/* Access functions */
220
221/* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed. */
222
223# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
059ec3d9
PH
224 if (db_create(dbpp, NULL, 0) != 0 || \
225 ((*dbpp)->set_errcall(*dbpp, dbfn_bdb_error_callback), \
19897d52 226 ((*dbpp)->open)(*dbpp, CS name, NULL, \
059ec3d9
PH
227 ((flags) == O_RDONLY)? DB_UNKNOWN : DB_HASH, \
228 ((flags) == O_RDONLY)? DB_RDONLY : DB_CREATE, \
229 mode)) != 0) *(dbpp) = NULL
059ec3d9
PH
230
231/* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
0a6c178c 232# define EXIM_DBGET(db, key, data) \
059ec3d9
PH
233 ((db)->get(db, NULL, &key, &data, 0) == 0)
234
235/* EXIM_DBPUT - returns nothing useful, assumes replace mode */
0a6c178c 236# define EXIM_DBPUT(db, key, data) \
059ec3d9
PH
237 (db)->put(db, NULL, &key, &data, 0)
238
239/* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
0a6c178c 240# define EXIM_DBPUTB(db, key, data) \
059ec3d9
PH
241 (db)->put(db, NULL, &key, &data, DB_NOOVERWRITE)
242
243/* Return values from EXIM_DBPUTB */
244
0a6c178c
JH
245# define EXIM_DBPUTB_OK 0
246# define EXIM_DBPUTB_DUP DB_KEYEXIST
059ec3d9
PH
247
248/* EXIM_DBDEL */
0a6c178c 249# define EXIM_DBDEL(db, key) (db)->del(db, NULL, &key, 0)
059ec3d9
PH
250
251/* EXIM_DBCREATE_CURSOR - initialize for scanning operation */
252
0a6c178c 253# define EXIM_DBCREATE_CURSOR(db, cursor) \
059ec3d9
PH
254 (db)->cursor(db, NULL, cursor, 0)
255
256/* EXIM_DBSCAN - returns TRUE if data is returned, FALSE at end */
0a6c178c 257# define EXIM_DBSCAN(db, key, data, first, cursor) \
059ec3d9
PH
258 ((cursor)->c_get(cursor, &key, &data, \
259 (first? DB_FIRST : DB_NEXT)) == 0)
260
261/* EXIM_DBDELETE_CURSOR - terminate scanning operation */
0a6c178c 262# define EXIM_DBDELETE_CURSOR(cursor) \
059ec3d9
PH
263 (cursor)->c_close(cursor)
264
265/* EXIM_DBCLOSE */
0a6c178c 266# define EXIM_DBCLOSE__(db) (db)->close(db, 0)
059ec3d9
PH
267
268/* Datum access types - these are intended to be assignable. */
269
0a6c178c
JH
270# define EXIM_DATUM_SIZE(datum) (datum).size
271# define EXIM_DATUM_DATA(datum) (datum).data
059ec3d9
PH
272
273/* The whole datum structure contains other fields that must be cleared
274before use, but we don't have to free anything after reading data. */
275
0a6c178c
JH
276# define EXIM_DATUM_INIT(datum) memset(&datum, 0, sizeof(datum))
277# define EXIM_DATUM_FREE(datum)
278
279#endif
059ec3d9
PH
280
281
282#else /* DB_VERSION_MAJOR >= 3 */
283
284/******************* Berkeley db 2.x native definitions ********************/
285
286/* Basic DB type */
287#define EXIM_DB DB
288
289/* Cursor type, for scanning */
290#define EXIM_CURSOR DBC
291
292/* The datum type used for queries */
293#define EXIM_DATUM DBT
294
295/* Some text for messages */
296#define EXIM_DBTYPE "db (v2)"
297
298/* Access functions */
299
300/* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed */
0a6c178c 301#define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
059ec3d9
PH
302 if ((errno = db_open(CS name, DB_HASH, \
303 ((flags) == O_RDONLY)? DB_RDONLY : DB_CREATE, \
304 mode, NULL, NULL, dbpp)) != 0) *(dbpp) = NULL
305
306/* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
307#define EXIM_DBGET(db, key, data) \
308 ((db)->get(db, NULL, &key, &data, 0) == 0)
309
310/* EXIM_DBPUT - returns nothing useful, assumes replace mode */
311#define EXIM_DBPUT(db, key, data) \
312 (db)->put(db, NULL, &key, &data, 0)
313
314/* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
315#define EXIM_DBPUTB(db, key, data) \
316 (db)->put(db, NULL, &key, &data, DB_NOOVERWRITE)
317
318/* Return values from EXIM_DBPUTB */
319
320#define EXIM_DBPUTB_OK 0
321#define EXIM_DBPUTB_DUP DB_KEYEXIST
322
323/* EXIM_DBDEL */
324#define EXIM_DBDEL(db, key) (db)->del(db, NULL, &key, 0)
325
326/* EXIM_DBCREATE_CURSOR - initialize for scanning operation */
327
328/* The API of this function was changed between releases 2.4.14 and 2.7.3. I do
329not know exactly where the change happened, but the Change Log for 2.5.9 lists
330the new option that is available, so I guess that it happened at 2.5.x. */
331
332#if DB_VERSION_MINOR >= 5
333#define EXIM_DBCREATE_CURSOR(db, cursor) \
334 (db)->cursor(db, NULL, cursor, 0)
335#else
336#define EXIM_DBCREATE_CURSOR(db, cursor) \
337 (db)->cursor(db, NULL, cursor)
338#endif
339
340/* EXIM_DBSCAN - returns TRUE if data is returned, FALSE at end */
341#define EXIM_DBSCAN(db, key, data, first, cursor) \
342 ((cursor)->c_get(cursor, &key, &data, \
343 (first? DB_FIRST : DB_NEXT)) == 0)
344
345/* EXIM_DBDELETE_CURSOR - terminate scanning operation */
346#define EXIM_DBDELETE_CURSOR(cursor) \
347 (cursor)->c_close(cursor)
348
349/* EXIM_DBCLOSE */
0a6c178c 350#define EXIM_DBCLOSE__(db) (db)->close(db, 0)
059ec3d9
PH
351
352/* Datum access types - these are intended to be assignable. */
353
354#define EXIM_DATUM_SIZE(datum) (datum).size
355#define EXIM_DATUM_DATA(datum) (datum).data
356
357/* The whole datum structure contains other fields that must be cleared
358before use, but we don't have to free anything after reading data. */
359
360#define EXIM_DATUM_INIT(datum) memset(&datum, 0, sizeof(datum))
361#define EXIM_DATUM_FREE(datum)
362
363#endif /* DB_VERSION_MAJOR >= 3 */
364
365
366/* If DB_VERSION_TYPE is not defined, we have version 1.x */
367
368#else /* DB_VERSION_TYPE */
369
370/******************* Berkeley db 1.x native definitions ********************/
371
372/* Basic DB type */
373#define EXIM_DB DB
374
375/* Cursor type, not used with DB 1.x: just set up a dummy */
376#define EXIM_CURSOR int
377
378/* The datum type used for queries */
379#define EXIM_DATUM DBT
380
381/* Some text for messages */
382#define EXIM_DBTYPE "db (v1)"
383
9ad41a42
TK
384/* When scanning, for the non-first case we historically just passed 0
385as the flags field and it worked. On FreeBSD 8 it no longer works and
386instead leads to memory exhaustion. The man-page on FreeBSD says to use
387R_NEXT, but this 1.x is a historical fallback and I've no idea how portable
388the use of that flag is; so the solution is to define R_NEXT here if it's not
389already defined, with a default value of 0 because that's what we've always
390before been able to pass successfully. */
391#ifndef R_NEXT
392#define R_NEXT 0
393#endif
394
059ec3d9
PH
395/* Access functions */
396
397/* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed */
0a6c178c 398#define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
059ec3d9
PH
399 *(dbpp) = dbopen(CS name, flags, mode, DB_HASH, NULL)
400
401/* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
402#define EXIM_DBGET(db, key, data) \
403 ((db)->get(db, &key, &data, 0) == 0)
404
405/* EXIM_DBPUT - returns nothing useful, assumes replace mode */
406#define EXIM_DBPUT(db, key, data) \
407 (db)->put(db, &key, &data, 0)
408
409/* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
410#define EXIM_DBPUTB(db, key, data) \
411 (db)->put(db, &key, &data, R_NOOVERWRITE)
412
413/* Returns from EXIM_DBPUTB */
414
415#define EXIM_DBPUTB_OK 0
416#define EXIM_DBPUTB_DUP 1
417
418/* EXIM_DBDEL */
419#define EXIM_DBDEL(db, key) (db)->del(db, &key, 0)
420
421/* EXIM_DBCREATE_CURSOR - initialize for scanning operation (null) */
422#define EXIM_DBCREATE_CURSOR(db, cursor) {}
423
424/* EXIM_DBSCAN - returns TRUE if data is returned, FALSE at end */
425#define EXIM_DBSCAN(db, key, data, first, cursor) \
9ad41a42 426 ((db)->seq(db, &key, &data, (first? R_FIRST : R_NEXT)) == 0)
059ec3d9
PH
427
428/* EXIM_DBDELETE_CURSOR - terminate scanning operation (null). Make it
429refer to cursor, to keep picky compilers happy. */
430#define EXIM_DBDELETE_CURSOR(cursor) { cursor = cursor; }
431
432/* EXIM_DBCLOSE */
0a6c178c 433#define EXIM_DBCLOSE__(db) (db)->close(db)
059ec3d9
PH
434
435/* Datum access types - these are intended to be assignable */
436
437#define EXIM_DATUM_SIZE(datum) (datum).size
438#define EXIM_DATUM_DATA(datum) (datum).data
439
440/* There's no clearing required before use, and we don't have to free anything
441after reading data. */
442
443#define EXIM_DATUM_INIT(datum)
444#define EXIM_DATUM_FREE(datum)
445
446#endif /* DB_VERSION_STRING */
447
448
449
450/********************* gdbm interface definitions **********************/
451
452#elif defined USE_GDBM
453
454#include <gdbm.h>
455
456/* Basic DB type */
457typedef struct {
870f6ba8
TF
458 GDBM_FILE gdbm; /* Database */
459 datum lkey; /* Last key, for scans */
059ec3d9
PH
460} EXIM_DB;
461
462/* Cursor type, not used with gdbm: just set up a dummy */
463#define EXIM_CURSOR int
464
465/* The datum type used for queries */
466#define EXIM_DATUM datum
467
468/* Some text for messages */
469
470#define EXIM_DBTYPE "gdbm"
471
472/* Access functions */
473
474/* EXIM_DBOPEN - returns a EXIM_DB *, NULL if failed */
0a6c178c 475#define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
059ec3d9
PH
476 { (*(dbpp)) = (EXIM_DB *) malloc(sizeof(EXIM_DB));\
477 if (*(dbpp) != NULL) { \
478 (*(dbpp))->lkey.dptr = NULL;\
479 (*(dbpp))->gdbm = gdbm_open(CS name, 0, (((flags) & O_CREAT))?GDBM_WRCREAT:(((flags) & (O_RDWR|O_WRONLY))?GDBM_WRITER:GDBM_READER), mode, 0);\
480 if ((*(dbpp))->gdbm == NULL) {\
481 free(*(dbpp));\
482 *(dbpp) = NULL;\
483 }\
484 }\
485 }
486
487/* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
488#define EXIM_DBGET(db, key, data) \
489 (data = gdbm_fetch(db->gdbm, key), data.dptr != NULL)
490
491/* EXIM_DBPUT - returns nothing useful, assumes replace mode */
492#define EXIM_DBPUT(db, key, data) \
493 gdbm_store(db->gdbm, key, data, GDBM_REPLACE)
494
495/* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
496#define EXIM_DBPUTB(db, key, data) \
497 gdbm_store(db->gdbm, key, data, GDBM_INSERT)
498
499/* Returns from EXIM_DBPUTB */
500
501#define EXIM_DBPUTB_OK 0
502#define EXIM_DBPUTB_DUP 1
503
504/* EXIM_DBDEL */
505#define EXIM_DBDEL(db, key) gdbm_delete(db->gdbm, key)
506
507/* EXIM_DBCREATE_CURSOR - initialize for scanning operation (null) */
508#define EXIM_DBCREATE_CURSOR(db, cursor) {}
509
510/* EXIM_DBSCAN */
511#define EXIM_DBSCAN(db, key, data, first, cursor) \
512 ( key = ((first)? gdbm_firstkey(db->gdbm) : gdbm_nextkey(db->gdbm, db->lkey)), \
513 (((db)->lkey.dptr != NULL)? (free((db)->lkey.dptr),1) : 1),\
514 db->lkey = key, key.dptr != NULL)
515
516/* EXIM_DBDELETE_CURSOR - terminate scanning operation (null). Make it
517refer to cursor, to keep picky compilers happy. */
518#define EXIM_DBDELETE_CURSOR(cursor) { cursor = cursor; }
519
520/* EXIM_DBCLOSE */
0a6c178c 521#define EXIM_DBCLOSE__(db) \
059ec3d9
PH
522{ gdbm_close((db)->gdbm);\
523 if ((db)->lkey.dptr != NULL) free((db)->lkey.dptr);\
524 free(db); }
525
526/* Datum access types - these are intended to be assignable */
527
528#define EXIM_DATUM_SIZE(datum) (datum).dsize
529#define EXIM_DATUM_DATA(datum) (datum).dptr
530
531/* There's no clearing required before use, but we have to free the dptr
532after reading data. */
533
534#define EXIM_DATUM_INIT(datum)
535#define EXIM_DATUM_FREE(datum) free(datum.dptr)
536
537#else /* USE_GDBM */
538
539
540/* If none of USE_DB, USG_GDBM, or USE_TDB are set, the default is the NDBM
541interface */
542
543
544/********************* ndbm interface definitions **********************/
545
546#include <ndbm.h>
547
548/* Basic DB type */
549#define EXIM_DB DBM
550
551/* Cursor type, not used with ndbm: just set up a dummy */
552#define EXIM_CURSOR int
553
554/* The datum type used for queries */
555#define EXIM_DATUM datum
556
557/* Some text for messages */
558
559#define EXIM_DBTYPE "ndbm"
560
561/* Access functions */
562
563/* EXIM_DBOPEN - returns a EXIM_DB *, NULL if failed */
0a6c178c 564#define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
059ec3d9
PH
565 *(dbpp) = dbm_open(CS name, flags, mode)
566
567/* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
568#define EXIM_DBGET(db, key, data) \
569 (data = dbm_fetch(db, key), data.dptr != NULL)
570
571/* EXIM_DBPUT - returns nothing useful, assumes replace mode */
572#define EXIM_DBPUT(db, key, data) \
573 dbm_store(db, key, data, DBM_REPLACE)
574
575/* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
576#define EXIM_DBPUTB(db, key, data) \
577 dbm_store(db, key, data, DBM_INSERT)
578
579/* Returns from EXIM_DBPUTB */
580
581#define EXIM_DBPUTB_OK 0
582#define EXIM_DBPUTB_DUP 1
583
584/* EXIM_DBDEL */
585#define EXIM_DBDEL(db, key) dbm_delete(db, key)
586
587/* EXIM_DBCREATE_CURSOR - initialize for scanning operation (null) */
588#define EXIM_DBCREATE_CURSOR(db, cursor) {}
589
590/* EXIM_DBSCAN */
591#define EXIM_DBSCAN(db, key, data, first, cursor) \
592 (key = (first? dbm_firstkey(db) : dbm_nextkey(db)), key.dptr != NULL)
593
594/* EXIM_DBDELETE_CURSOR - terminate scanning operation (null). Make it
595refer to cursor, to keep picky compilers happy. */
596#define EXIM_DBDELETE_CURSOR(cursor) { cursor = cursor; }
597
598/* EXIM_DBCLOSE */
0a6c178c 599#define EXIM_DBCLOSE__(db) dbm_close(db)
059ec3d9
PH
600
601/* Datum access types - these are intended to be assignable */
602
603#define EXIM_DATUM_SIZE(datum) (datum).dsize
604#define EXIM_DATUM_DATA(datum) (datum).dptr
605
606/* There's no clearing required before use, and we don't have to free anything
607after reading data. */
608
609#define EXIM_DATUM_INIT(datum)
610#define EXIM_DATUM_FREE(datum)
611
612#endif /* USE_GDBM */
613
0a6c178c
JH
614
615
616
617
618# ifdef COMPILE_UTILITY
619
620# define EXIM_DBOPEN(name, dirname, flags, mode, dbpp) \
621 EXIM_DBOPEN__(name, dirname, flags, mode, dbpp)
622# define EXIM_DBCLOSE(db) EXIM_DBCLOSE__(db)
623
624# else
625
626# define EXIM_DBOPEN(name, dirname, flags, mode, dbpp) \
627 do { \
628 DEBUG(D_hints_lookup) \
629 debug_printf("EXIM_DBOPEN: file <%s> dir <%s> flags 0x%x\n", \
630 (name), (dirname), flags); \
631 EXIM_DBOPEN__(name, dirname, flags, mode, dbpp); \
632 DEBUG(D_hints_lookup) debug_printf("returned from EXIM_DBOPEN: %p\n", *dbpp); \
633 } while(0)
634# define EXIM_DBCLOSE(db) \
635 do { \
636 DEBUG(D_hints_lookup) debug_printf("EXIM_DBCLOSE(%p)\n", db); \
637 EXIM_DBCLOSE__(db); \
638 } while(0)
639
640# endif
641
059ec3d9
PH
642/********************* End of dbm library definitions **********************/
643
644
645/* Structure for carrying around an open DBM file, and an open locking file
646that relates to it. */
647
648typedef struct {
649 EXIM_DB *dbptr;
650 int lockfd;
651} open_db;
652
653
654/* Structures for records stored in exim database dbm files. They all
655start with the same fields, described in the generic type. */
656
657
658typedef struct {
659 time_t time_stamp; /* Timestamp of writing */
660} dbdata_generic;
661
662
663/* This structure keeps track of retry information for a host or a local
664address. */
665
666typedef struct {
667 time_t time_stamp;
668 /*************/
669 time_t first_failed; /* Time of first failure */
670 time_t last_try; /* Time of last try */
671 time_t next_try; /* Time of next try */
672 BOOL expired; /* Retry time has expired */
673 int basic_errno; /* Errno of last failure */
674 int more_errno; /* Additional information */
675 uschar text[1]; /* Text message for last failure */
676} dbdata_retry;
677
678/* These structures keep track of addresses that have had callout verification
679performed on them. There are two groups of records:
680
6811. keyed by localpart@domain -
682 Full address was tested and record holds result
683
6842. keyed by domain -
685 Domain response upto MAIL FROM:<>, postmaster, random local part;
686
2b1c6e3a
PH
687If a record exists, the result field is either ccache_accept or ccache_reject,
688or, for a domain record only, ccache_reject_mfnull when MAIL FROM:<> was
689rejected. The other fields, however, (which are only relevant to domain
690records) may also contain ccache_unknown if that particular test has not been
691done.
059ec3d9
PH
692
693Originally, there was only one structure, used for both types. However, it got
694expanded for domain records, so it got split. To make it possible for Exim to
695handle the old type of record, we retain the old definition. The different
4c04137d 696kinds of record can be distinguished by their different lengths. */
059ec3d9
PH
697
698typedef struct {
699 time_t time_stamp;
700 /*************/
701 int result;
702 int postmaster_result; /* Postmaster is accepted */
703 int random_result; /* Random local part was accepted */
704} dbdata_callout_cache_obs;
705
706typedef struct {
707 time_t time_stamp; /* Timestamp of last address check */
708 /*************/
709 int result; /* accept or reject */
710} dbdata_callout_cache_address;
711
712/* For this new layout, we put the additional fields (the timestamps)
713last so that if somebody reverts to an older Exim, the new records will
714still make sense because they match the old layout. */
715
716typedef struct {
717 time_t time_stamp; /* Time stamp of last connection */
718 /*************/
719 int result; /* Domain reject or accept */
720 int postmaster_result; /* Postmaster result */
721 int random_result; /* Random result */
722 time_t postmaster_stamp; /* Timestamp of postmaster check */
723 time_t random_stamp; /* Timestamp of random check */
724} dbdata_callout_cache;
725
726/* This structure keeps track of messages that are waiting for a particular
727host for a particular transport. */
728
729typedef struct {
730 time_t time_stamp;
731 /*************/
732 int count; /* Count of message ids */
733 int sequence; /* Sequence for continued records */
734 uschar text[1]; /* One long character string */
735} dbdata_wait;
736
737
738/* The contents of the "misc" database are a mixture of different kinds of
739record, as defined below. The keys used for a specific type all start with a
740given string such as "etrn-" or "host-serialize-". */
741
742
743/* This structure records a connection to a particular host, for the
744purpose of serializing access to certain hosts. For possible future extension,
745a field is defined for holding the count of connections, but it is not
746at present in use. The same structure is used for recording a running ETRN
747process. */
748
749typedef struct {
750 time_t time_stamp;
751 /*************/
752 int count; /* Reserved for possible connection count */
753} dbdata_serialize;
754
755
870f6ba8
TF
756/* This structure records the information required for the ratelimit
757ACL condition. */
758
759typedef struct {
760 time_t time_stamp;
761 /*************/
762 int time_usec; /* Fractional part of time, from gettimeofday() */
763 double rate; /* Smoothed sending rate at that time */
764} dbdata_ratelimit;
765
c99ce5c9
TF
766/* Same as above, plus a Bloom filter for uniquifying events. */
767
768typedef struct {
769 dbdata_ratelimit dbd;
770 time_t bloom_epoch; /* When the Bloom filter was last reset */
771 unsigned bloom_size; /* Number of bytes in the Bloom filter */
772 uschar bloom[40]; /* Bloom filter which may be larger than this */
773} dbdata_ratelimit_unique;
774
870f6ba8 775
059ec3d9 776/* End of dbstuff.h */