Promote the pdkim variant-implementation sha routines to toplevel
[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 */
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
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 */
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
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 */
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
130API 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), \
19897d52 136 ((*dbpp)->open)(*dbpp, NULL, CS name, NULL, \
059ec3d9
PH
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), \
19897d52 144 ((*dbpp)->open)(*dbpp, CS name, NULL, \
059ec3d9
PH
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
193before 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
246not know exactly where the change happened, but the Change Log for 2.5.9 lists
247the 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
275before 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
9ad41a42
TK
301/* When scanning, for the non-first case we historically just passed 0
302as the flags field and it worked. On FreeBSD 8 it no longer works and
303instead leads to memory exhaustion. The man-page on FreeBSD says to use
304R_NEXT, but this 1.x is a historical fallback and I've no idea how portable
305the use of that flag is; so the solution is to define R_NEXT here if it's not
306already defined, with a default value of 0 because that's what we've always
307before been able to pass successfully. */
308#ifndef R_NEXT
309#define R_NEXT 0
310#endif
311
059ec3d9
PH
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) \
9ad41a42 343 ((db)->seq(db, &key, &data, (first? R_FIRST : R_NEXT)) == 0)
059ec3d9
PH
344
345/* EXIM_DBDELETE_CURSOR - terminate scanning operation (null). Make it
346refer 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
358after 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 */
374typedef struct {
870f6ba8
TF
375 GDBM_FILE gdbm; /* Database */
376 datum lkey; /* Last key, for scans */
059ec3d9
PH
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
434refer 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
449after 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
458interface */
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
512refer 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
524after 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
535that relates to it. */
536
537typedef 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
544start with the same fields, described in the generic type. */
545
546
547typedef 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
553address. */
554
555typedef 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
568performed on them. There are two groups of records:
569
5701. keyed by localpart@domain -
571 Full address was tested and record holds result
572
5732. keyed by domain -
574 Domain response upto MAIL FROM:<>, postmaster, random local part;
575
2b1c6e3a
PH
576If a record exists, the result field is either ccache_accept or ccache_reject,
577or, for a domain record only, ccache_reject_mfnull when MAIL FROM:<> was
578rejected. The other fields, however, (which are only relevant to domain
579records) may also contain ccache_unknown if that particular test has not been
580done.
059ec3d9
PH
581
582Originally, there was only one structure, used for both types. However, it got
583expanded for domain records, so it got split. To make it possible for Exim to
584handle the old type of record, we retain the old definition. The different
585kinds of record can be distinguised by their different lengths. */
586
587typedef 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
595typedef 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)
602last so that if somebody reverts to an older Exim, the new records will
603still make sense because they match the old layout. */
604
605typedef 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
616host for a particular transport. */
617
618typedef 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
628record, as defined below. The keys used for a specific type all start with a
629given string such as "etrn-" or "host-serialize-". */
630
631
632/* This structure records a connection to a particular host, for the
633purpose of serializing access to certain hosts. For possible future extension,
634a field is defined for holding the count of connections, but it is not
635at present in use. The same structure is used for recording a running ETRN
636process. */
637
638typedef struct {
639 time_t time_stamp;
640 /*************/
641 int count; /* Reserved for possible connection count */
642} dbdata_serialize;
643
644
870f6ba8
TF
645/* This structure records the information required for the ratelimit
646ACL condition. */
647
648typedef 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
c99ce5c9
TF
655/* Same as above, plus a Bloom filter for uniquifying events. */
656
657typedef 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
870f6ba8 664
059ec3d9 665/* End of dbstuff.h */