1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) University of Cambridge 1995 - 2018 */
6 /* See the file NOTICE for conditions of use and distribution. */
8 /* This header file contains macro definitions so that a variety of DBM
9 libraries can be used by Exim. Nigel Metheringham provided the original set for
10 Berkeley DB 1.x in native mode and ndbm. Subsequently, versions for Berkeley DB
11 2.x and 3.x were added. Later still, support for tdb was added, courtesy of
12 James Antill. Most recently, support for native mode gdbm was added, with code
13 from Pierre A. Humblet, so Exim could be made to work with Cygwin.
15 For convenience, the definitions of the structures used in the various hints
16 databases are also kept in this file, which is used by the maintenance
17 utilities as well as the main Exim binary. */
22 /* ************************* tdb interface ************************ */
27 #define EXIM_DB TDB_CONTEXT
29 /* Cursor type: tdb uses the previous "key" in _nextkey() (really it wants
30 tdb_traverse to be called) */
31 #define EXIM_CURSOR TDB_DATA
33 /* The datum type used for queries */
34 #define EXIM_DATUM TDB_DATA
36 /* Some text for messages */
37 #define EXIM_DBTYPE "tdb"
39 /* Access functions */
41 /* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed */
42 #define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
43 *(dbpp) = tdb_open(CS name, 0, TDB_DEFAULT, flags, mode)
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)
49 /* EXIM_DBPUT - returns nothing useful, assumes replace mode */
50 #define EXIM_DBPUT(db, key, data) \
51 tdb_store(db, key, data, TDB_REPLACE)
53 /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
54 #define EXIM_DBPUTB(db, key, data) \
55 tdb_store(db, key, data, TDB_INSERT)
57 /* Returns from EXIM_DBPUTB */
59 #define EXIM_DBPUTB_OK 0
60 #define EXIM_DBPUTB_DUP (-1)
63 #define EXIM_DBDEL(db, key) tdb_delete(db, key)
65 /* EXIM_DBCREATE_CURSOR - initialize for scanning operation */
66 #define EXIM_DBCREATE_CURSOR(db, cursor) { \
67 *(cursor) = store_malloc(sizeof(TDB_DATA)); (*(cursor))->dptr = NULL; }
69 /* EXIM_DBSCAN - This is complicated because we have to free the last datum
70 free() 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, \
76 /* EXIM_DBDELETE_CURSOR - terminate scanning operation. */
77 #define EXIM_DBDELETE_CURSOR(cursor) free(cursor)
80 #define EXIM_DBCLOSE__(db) tdb_close(db)
82 /* Datum access types - these are intended to be assignable */
84 #define EXIM_DATUM_SIZE(datum) (datum).dsize
85 #define EXIM_DATUM_DATA(datum) (datum).dptr
87 /* Free the stuff inside the datum. */
89 #define EXIM_DATUM_FREE(datum) (free((datum).dptr), (datum).dptr = NULL)
91 /* No initialization is needed. */
93 #define EXIM_DATUM_INIT(datum)
97 /********************* Berkeley db native definitions **********************/
104 /* We can distinguish between versions 1.x and 2.x/3.x by looking for a
105 definition of DB_VERSION_STRING, which is present in versions 2.x onwards. */
107 #ifdef DB_VERSION_STRING
109 # if DB_VERSION_MAJOR >= 6
110 # error Version 6 and later BDB API is not supported
113 /* The API changed (again!) between the 2.x and 3.x versions */
115 #if DB_VERSION_MAJOR >= 3
117 /***************** Berkeley db 3.x/4.x native definitions ******************/
120 # if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
121 # define EXIM_DB DB_ENV
122 /* Cursor type, for scanning */
123 # define EXIM_CURSOR DBC
125 /* The datum type used for queries */
126 # define EXIM_DATUM DBT
128 /* Some text for messages */
129 # define EXIM_DBTYPE "db (v4.1+)"
131 /* Only more-recent versions. 5+ ? */
132 # ifndef DB_FORCESYNC
133 # define DB_FORCESYNC 0
137 /* Access functions */
139 /* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed. The
140 API changed for DB 4.1. - and we also starting using the "env" with a
141 specified working dir, to avoid the DBCONFIG file trap. */
143 # define ENV_TO_DB(env) ((DB *)((env)->app_private))
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\
151 else if (db_create((DB **) &((*dbpp)->app_private), *dbpp, 0) != 0) \
153 ((DB_ENV *)(*dbpp))->close((DB_ENV *)(*dbpp), 0); \
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, \
162 ENV_TO_DB(*dbpp)->close(ENV_TO_DB(*dbpp), 0); \
163 ((DB_ENV *)(*dbpp))->close((DB_ENV *)(*dbpp), 0); \
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)
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)
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)
179 /* Return values from EXIM_DBPUTB */
181 # define EXIM_DBPUTB_OK 0
182 # define EXIM_DBPUTB_DUP DB_KEYEXIST
185 # define EXIM_DBDEL(db, key) ENV_TO_DB(db)->del(ENV_TO_DB(db), NULL, &key, 0)
187 /* EXIM_DBCREATE_CURSOR - initialize for scanning operation */
189 # define EXIM_DBCREATE_CURSOR(db, cursor) \
190 ENV_TO_DB(db)->cursor(ENV_TO_DB(db), NULL, cursor, 0)
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)
197 /* EXIM_DBDELETE_CURSOR - terminate scanning operation */
198 # define EXIM_DBDELETE_CURSOR(cursor) \
199 (cursor)->c_close(cursor)
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))
205 /* Datum access types - these are intended to be assignable. */
207 # define EXIM_DATUM_SIZE(datum) (datum).size
208 # define EXIM_DATUM_DATA(datum) (datum).data
210 /* The whole datum structure contains other fields that must be cleared
211 before use, but we don't have to free anything after reading data. */
213 # define EXIM_DATUM_INIT(datum) memset(&datum, 0, sizeof(datum))
214 # define EXIM_DATUM_FREE(datum)
216 # else /* pre- 4.1 */
220 /* Cursor type, for scanning */
221 # define EXIM_CURSOR DBC
223 /* The datum type used for queries */
224 # define EXIM_DATUM DBT
226 /* Some text for messages */
227 # define EXIM_DBTYPE "db (v3/4)"
229 /* Access functions */
231 /* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed. */
233 # define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
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
241 /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
242 # define EXIM_DBGET(db, key, data) \
243 ((db)->get(db, NULL, &key, &data, 0) == 0)
245 /* EXIM_DBPUT - returns nothing useful, assumes replace mode */
246 # define EXIM_DBPUT(db, key, data) \
247 (db)->put(db, NULL, &key, &data, 0)
249 /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
250 # define EXIM_DBPUTB(db, key, data) \
251 (db)->put(db, NULL, &key, &data, DB_NOOVERWRITE)
253 /* Return values from EXIM_DBPUTB */
255 # define EXIM_DBPUTB_OK 0
256 # define EXIM_DBPUTB_DUP DB_KEYEXIST
259 # define EXIM_DBDEL(db, key) (db)->del(db, NULL, &key, 0)
261 /* EXIM_DBCREATE_CURSOR - initialize for scanning operation */
263 # define EXIM_DBCREATE_CURSOR(db, cursor) \
264 (db)->cursor(db, NULL, cursor, 0)
266 /* EXIM_DBSCAN - returns TRUE if data is returned, FALSE at end */
267 # define EXIM_DBSCAN(db, key, data, first, cursor) \
268 ((cursor)->c_get(cursor, &key, &data, \
269 (first? DB_FIRST : DB_NEXT)) == 0)
271 /* EXIM_DBDELETE_CURSOR - terminate scanning operation */
272 # define EXIM_DBDELETE_CURSOR(cursor) \
273 (cursor)->c_close(cursor)
276 # define EXIM_DBCLOSE__(db) (db)->close(db, 0)
278 /* Datum access types - these are intended to be assignable. */
280 # define EXIM_DATUM_SIZE(datum) (datum).size
281 # define EXIM_DATUM_DATA(datum) (datum).data
283 /* The whole datum structure contains other fields that must be cleared
284 before use, but we don't have to free anything after reading data. */
286 # define EXIM_DATUM_INIT(datum) memset(&datum, 0, sizeof(datum))
287 # define EXIM_DATUM_FREE(datum)
292 #else /* DB_VERSION_MAJOR >= 3 */
294 /******************* Berkeley db 2.x native definitions ********************/
299 /* Cursor type, for scanning */
300 #define EXIM_CURSOR DBC
302 /* The datum type used for queries */
303 #define EXIM_DATUM DBT
305 /* Some text for messages */
306 #define EXIM_DBTYPE "db (v2)"
308 /* Access functions */
310 /* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed */
311 #define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
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
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)
320 /* EXIM_DBPUT - returns nothing useful, assumes replace mode */
321 #define EXIM_DBPUT(db, key, data) \
322 (db)->put(db, NULL, &key, &data, 0)
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)
328 /* Return values from EXIM_DBPUTB */
330 #define EXIM_DBPUTB_OK 0
331 #define EXIM_DBPUTB_DUP DB_KEYEXIST
334 #define EXIM_DBDEL(db, key) (db)->del(db, NULL, &key, 0)
336 /* EXIM_DBCREATE_CURSOR - initialize for scanning operation */
338 /* The API of this function was changed between releases 2.4.14 and 2.7.3. I do
339 not know exactly where the change happened, but the Change Log for 2.5.9 lists
340 the new option that is available, so I guess that it happened at 2.5.x. */
342 #if DB_VERSION_MINOR >= 5
343 #define EXIM_DBCREATE_CURSOR(db, cursor) \
344 (db)->cursor(db, NULL, cursor, 0)
346 #define EXIM_DBCREATE_CURSOR(db, cursor) \
347 (db)->cursor(db, NULL, cursor)
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)
355 /* EXIM_DBDELETE_CURSOR - terminate scanning operation */
356 #define EXIM_DBDELETE_CURSOR(cursor) \
357 (cursor)->c_close(cursor)
360 #define EXIM_DBCLOSE__(db) (db)->close(db, 0)
362 /* Datum access types - these are intended to be assignable. */
364 #define EXIM_DATUM_SIZE(datum) (datum).size
365 #define EXIM_DATUM_DATA(datum) (datum).data
367 /* The whole datum structure contains other fields that must be cleared
368 before use, but we don't have to free anything after reading data. */
370 #define EXIM_DATUM_INIT(datum) memset(&datum, 0, sizeof(datum))
371 #define EXIM_DATUM_FREE(datum)
373 #endif /* DB_VERSION_MAJOR >= 3 */
376 /* If DB_VERSION_TYPE is not defined, we have version 1.x */
378 #else /* DB_VERSION_TYPE */
380 /******************* Berkeley db 1.x native definitions ********************/
385 /* Cursor type, not used with DB 1.x: just set up a dummy */
386 #define EXIM_CURSOR int
388 /* The datum type used for queries */
389 #define EXIM_DATUM DBT
391 /* Some text for messages */
392 #define EXIM_DBTYPE "db (v1)"
394 /* When scanning, for the non-first case we historically just passed 0
395 as the flags field and it worked. On FreeBSD 8 it no longer works and
396 instead leads to memory exhaustion. The man-page on FreeBSD says to use
397 R_NEXT, but this 1.x is a historical fallback and I've no idea how portable
398 the use of that flag is; so the solution is to define R_NEXT here if it's not
399 already defined, with a default value of 0 because that's what we've always
400 before been able to pass successfully. */
405 /* Access functions */
407 /* EXIM_DBOPEN - sets *dbpp to point to an EXIM_DB, NULL if failed */
408 #define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
409 *(dbpp) = dbopen(CS name, flags, mode, DB_HASH, NULL)
411 /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
412 #define EXIM_DBGET(db, key, data) \
413 ((db)->get(db, &key, &data, 0) == 0)
415 /* EXIM_DBPUT - returns nothing useful, assumes replace mode */
416 #define EXIM_DBPUT(db, key, data) \
417 (db)->put(db, &key, &data, 0)
419 /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
420 #define EXIM_DBPUTB(db, key, data) \
421 (db)->put(db, &key, &data, R_NOOVERWRITE)
423 /* Returns from EXIM_DBPUTB */
425 #define EXIM_DBPUTB_OK 0
426 #define EXIM_DBPUTB_DUP 1
429 #define EXIM_DBDEL(db, key) (db)->del(db, &key, 0)
431 /* EXIM_DBCREATE_CURSOR - initialize for scanning operation (null) */
432 #define EXIM_DBCREATE_CURSOR(db, cursor) {}
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)
438 /* EXIM_DBDELETE_CURSOR - terminate scanning operation (null). Make it
439 refer to cursor, to keep picky compilers happy. */
440 #define EXIM_DBDELETE_CURSOR(cursor) { cursor = cursor; }
443 #define EXIM_DBCLOSE__(db) (db)->close(db)
445 /* Datum access types - these are intended to be assignable */
447 #define EXIM_DATUM_SIZE(datum) (datum).size
448 #define EXIM_DATUM_DATA(datum) (datum).data
450 /* There's no clearing required before use, and we don't have to free anything
451 after reading data. */
453 #define EXIM_DATUM_INIT(datum)
454 #define EXIM_DATUM_FREE(datum)
456 #endif /* DB_VERSION_STRING */
460 /********************* gdbm interface definitions **********************/
462 #elif defined USE_GDBM
468 GDBM_FILE gdbm; /* Database */
469 datum lkey; /* Last key, for scans */
472 /* Cursor type, not used with gdbm: just set up a dummy */
473 #define EXIM_CURSOR int
475 /* The datum type used for queries */
476 #define EXIM_DATUM datum
478 /* Some text for messages */
480 #define EXIM_DBTYPE "gdbm"
482 /* Access functions */
484 /* EXIM_DBOPEN - returns a EXIM_DB *, NULL if failed */
485 #define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
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) {\
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)
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)
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)
509 /* Returns from EXIM_DBPUTB */
511 #define EXIM_DBPUTB_OK 0
512 #define EXIM_DBPUTB_DUP 1
515 #define EXIM_DBDEL(db, key) gdbm_delete(db->gdbm, key)
517 /* EXIM_DBCREATE_CURSOR - initialize for scanning operation (null) */
518 #define EXIM_DBCREATE_CURSOR(db, cursor) {}
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)
526 /* EXIM_DBDELETE_CURSOR - terminate scanning operation (null). Make it
527 refer to cursor, to keep picky compilers happy. */
528 #define EXIM_DBDELETE_CURSOR(cursor) { cursor = cursor; }
531 #define EXIM_DBCLOSE__(db) \
532 { gdbm_close((db)->gdbm);\
533 if ((db)->lkey.dptr != NULL) free((db)->lkey.dptr);\
536 /* Datum access types - these are intended to be assignable */
538 #define EXIM_DATUM_SIZE(datum) (datum).dsize
539 #define EXIM_DATUM_DATA(datum) (datum).dptr
541 /* There's no clearing required before use, but we have to free the dptr
542 after reading data. */
544 #define EXIM_DATUM_INIT(datum)
545 #define EXIM_DATUM_FREE(datum) free(datum.dptr)
550 /* If none of USE_DB, USG_GDBM, or USE_TDB are set, the default is the NDBM
554 /********************* ndbm interface definitions **********************/
561 /* Cursor type, not used with ndbm: just set up a dummy */
562 #define EXIM_CURSOR int
564 /* The datum type used for queries */
565 #define EXIM_DATUM datum
567 /* Some text for messages */
569 #define EXIM_DBTYPE "ndbm"
571 /* Access functions */
573 /* EXIM_DBOPEN - returns a EXIM_DB *, NULL if failed */
574 #define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
575 *(dbpp) = dbm_open(CS name, flags, mode)
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)
581 /* EXIM_DBPUT - returns nothing useful, assumes replace mode */
582 #define EXIM_DBPUT(db, key, data) \
583 dbm_store(db, key, data, DBM_REPLACE)
585 /* EXIM_DBPUTB - non-overwriting for use by dbmbuild */
586 #define EXIM_DBPUTB(db, key, data) \
587 dbm_store(db, key, data, DBM_INSERT)
589 /* Returns from EXIM_DBPUTB */
591 #define EXIM_DBPUTB_OK 0
592 #define EXIM_DBPUTB_DUP 1
595 #define EXIM_DBDEL(db, key) dbm_delete(db, key)
597 /* EXIM_DBCREATE_CURSOR - initialize for scanning operation (null) */
598 #define EXIM_DBCREATE_CURSOR(db, cursor) {}
601 #define EXIM_DBSCAN(db, key, data, first, cursor) \
602 (key = (first? dbm_firstkey(db) : dbm_nextkey(db)), key.dptr != NULL)
604 /* EXIM_DBDELETE_CURSOR - terminate scanning operation (null). Make it
605 refer to cursor, to keep picky compilers happy. */
606 #define EXIM_DBDELETE_CURSOR(cursor) { cursor = cursor; }
609 #define EXIM_DBCLOSE__(db) dbm_close(db)
611 /* Datum access types - these are intended to be assignable */
613 #define EXIM_DATUM_SIZE(datum) (datum).dsize
614 #define EXIM_DATUM_DATA(datum) (datum).dptr
616 /* There's no clearing required before use, and we don't have to free anything
617 after reading data. */
619 #define EXIM_DATUM_INIT(datum)
620 #define EXIM_DATUM_FREE(datum)
622 #endif /* USE_GDBM */
628 # ifdef COMPILE_UTILITY
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)
636 # define EXIM_DBOPEN(name, dirname, flags, mode, dbpp) \
638 DEBUG(D_hints_lookup) \
639 debug_printf("EXIM_DBOPEN: file <%s> dir <%s> flags=%s\n", \
641 (flags) == O_RDONLY ? "O_RDONLY" \
642 : (flags) == O_RDWR ? "O_RDWR" \
643 : (flags) == (O_RDWR|O_CREAT) ? "O_RDWR|O_CREAT" \
645 EXIM_DBOPEN__(name, dirname, flags, mode, dbpp); \
646 DEBUG(D_hints_lookup) debug_printf("returned from EXIM_DBOPEN: %p\n", *dbpp); \
648 # define EXIM_DBCLOSE(db) \
650 DEBUG(D_hints_lookup) debug_printf("EXIM_DBCLOSE(%p)\n", db); \
651 EXIM_DBCLOSE__(db); \
656 /********************* End of dbm library definitions **********************/
659 /* Structure for carrying around an open DBM file, and an open locking file
660 that relates to it. */
668 /* Structures for records stored in exim database dbm files. They all
669 start with the same fields, described in the generic type. */
673 time_t time_stamp; /* Timestamp of writing */
677 /* This structure keeps track of retry information for a host or a local
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 */
692 /* These structures keep track of addresses that have had callout verification
693 performed on them. There are two groups of records:
695 1. keyed by localpart@domain -
696 Full address was tested and record holds result
699 Domain response upto MAIL FROM:<>, postmaster, random local part;
701 If a record exists, the result field is either ccache_accept or ccache_reject,
702 or, for a domain record only, ccache_reject_mfnull when MAIL FROM:<> was
703 rejected. The other fields, however, (which are only relevant to domain
704 records) may also contain ccache_unknown if that particular test has not been
707 Originally, there was only one structure, used for both types. However, it got
708 expanded for domain records, so it got split. To make it possible for Exim to
709 handle the old type of record, we retain the old definition. The different
710 kinds of record can be distinguished by their different lengths. */
716 int postmaster_result; /* Postmaster is accepted */
717 int random_result; /* Random local part was accepted */
718 } dbdata_callout_cache_obs;
721 time_t time_stamp; /* Timestamp of last address check */
723 int result; /* accept or reject */
724 } dbdata_callout_cache_address;
726 /* For this new layout, we put the additional fields (the timestamps)
727 last so that if somebody reverts to an older Exim, the new records will
728 still make sense because they match the old layout. */
731 time_t time_stamp; /* Time stamp of last connection */
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;
740 /* This structure keeps track of messages that are waiting for a particular
741 host for a particular transport. */
746 int count; /* Count of message ids */
747 int sequence; /* Sequence for continued records */
748 uschar text[1]; /* One long character string */
752 /* The contents of the "misc" database are a mixture of different kinds of
753 record, as defined below. The keys used for a specific type all start with a
754 given string such as "etrn-" or "host-serialize-". */
757 /* This structure records a connection to a particular host, for the
758 purpose of serializing access to certain hosts. For possible future extension,
759 a field is defined for holding the count of connections, but it is not
760 at present in use. The same structure is used for recording a running ETRN
766 int count; /* Reserved for possible connection count */
770 /* This structure records the information required for the ratelimit
776 int time_usec; /* Fractional part of time, from gettimeofday() */
777 double rate; /* Smoothed sending rate at that time */
780 /* Same as above, plus a Bloom filter for uniquifying events. */
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;
790 /* End of dbstuff.h */