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