1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) The Exim Maintainers 2020 - 2024 */
6 /* Copyright (c) University of Cambridge 1995 - 2018 */
7 /* See the file NOTICE for conditions of use and distribution. */
8 /* SPDX-License-Identifier: GPL-2.0-or-later */
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. More 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 Most recently, sqlite3 was added.
18 For convenience, the definitions of the structures used in the various hints
19 databases are also kept in this file, which is used by the maintenance
20 utilities as well as the main Exim binary.
22 A key/value store is supported (only). Keys are strings; values arbitrary
27 exim_lockfile_needed API semantics predicate
29 exim_dbopen_multi only for no-lockfile-needed
31 exim_dbclose_multi only for no-lockfile-needed
32 exim_dbtransaction_start only for no-lockfile-needed
33 exim_dbtransaction_commit only for no-lockfile-needed
36 exim_dbputb non-overwriting put
39 exim_dbscan get, and bump cursor
42 exim_datum_size_get/set
43 exim_datum_data_get/set
47 EXIM_CURSOR datatype for cursor
48 EXIM_DATUM datatype for "value"
49 EXIM_DBTYPE text for logging & debuug
51 Selection of the shim layer implementation, and backend, is by #defines.
53 The users of this API are:
54 hintsdb interface dbfn.c
55 hintsdb utilities exim_dbutil.c and exim_dbmvuild.c
56 autoreply transport transports/autoreply.c
58 Future: consider re-architecting to support caching of the open-handle
59 for hintsdb uses (the dbmdb use gets that already). This would need APIs
60 for transaction locks. Perhaps merge the implementation with the lookups
61 layer, in some way, for the open-handle caching (since that manages closes
62 required by Exim's process transitions)?
68 /* Include file ordering problem */
69 extern void debug_printf_indent(const char *, ...) PRINTF_FUNCTION(1,2);
73 # if defined(USE_DB) || defined(USE_GDBM) || defined(USE_TDB)
74 # error USE_SQLITE conflict with alternate definition
76 # include "hintsdb/hints_sqlite.h"
77 #elif defined(USE_TDB)
79 # if defined(USE_DB) || defined(USE_GDBM) || defined(USE_SQLITE)
80 # error USE_TDB conflict with alternate definition
82 # include "hintsdb/hints_tdb.h"
85 # if defined(USE_TDB) || defined(USE_GDBM) || defined(USE_SQLITE)
86 # error USE_DB conflict with alternate definition
88 # include "hintsdb/hints_bdb.h"
90 #elif defined USE_GDBM
91 # if defined(USE_TDB) || defined(USE_DB) || defined(USE_SQLITE)
92 # error USE_GDBM conflict with alternate definition
94 # include "hintsdb/hints_gdbm.h"
98 /* If none of USE_{DB,GDBM,SQLITE,TDB} are set
99 the default is the NDBM interface (which seems to be a wrapper for GDBM) */
101 # include "hintsdb/hints_ndbm.h"
102 #endif /* !USE_GDBM */
109 /* Wrappers for open/close with debug tracing */
111 extern void debug_printf_indent(const char *, ...);
112 static inline BOOL is_tainted(const void *);
114 static inline EXIM_DB *
115 exim_dbopen(const uschar * name, const uschar * dirname, int flags,
119 DEBUG(D_hints_lookup)
120 debug_printf_indent("EXIM_DBOPEN: file <%s> dir <%s> flags=%s\n",
122 flags == O_RDONLY ? "O_RDONLY"
123 : flags == O_RDWR ? "O_RDWR"
124 : flags == (O_RDWR|O_CREAT) ? "O_RDWR|O_CREAT"
126 if (is_tainted(name) || is_tainted(dirname))
128 log_write(0, LOG_MAIN|LOG_PANIC, "Tainted name for DB file not permitted");
132 dbp = exim_dbopen__(name, dirname, flags, mode);
134 DEBUG(D_hints_lookup) debug_printf_indent("returned from EXIM_DBOPEN: %p\n", dbp);
138 static inline EXIM_DB *
139 exim_dbopen_multi(const uschar * name, const uschar * dirname, int flags,
143 DEBUG(D_hints_lookup)
144 debug_printf_indent("EXIM_DBOPEN_MULTI: file <%s> dir <%s> flags=%s\n",
146 flags == O_RDONLY ? "O_RDONLY"
147 : flags == O_RDWR ? "O_RDWR"
148 : flags == (O_RDWR|O_CREAT) ? "O_RDWR|O_CREAT"
150 if (is_tainted(name) || is_tainted(dirname))
152 log_write(0, LOG_MAIN|LOG_PANIC, "Tainted name for DB file not permitted");
156 dbp = exim_dbopen_multi__(name, dirname, flags, mode);
158 DEBUG(D_hints_lookup) debug_printf_indent("returned from EXIM_DBOPEN_MULTI: %p\n", dbp);
163 exim_dbclose(EXIM_DB * dbp)
165 DEBUG(D_hints_lookup) debug_printf_indent("EXIM_DBCLOSE(%p)\n", dbp);
169 exim_dbclose_multi(EXIM_DB * dbp)
171 DEBUG(D_hints_lookup) debug_printf_indent("EXIM_DBCLOSE_MULTI(%p)\n", dbp);
172 exim_dbclose_multi__(dbp);
176 /********************* End of dbm library definitions **********************/
178 #endif /* whole file */
179 /* End of hintsdb.h */