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