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