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