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