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