Merge branch 'router_dynamic_modules'
[exim.git] / src / src / hintsdb.h
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
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 */
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. 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.
17
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.
21
22 A key/value store is supported (only).  Keys are strings; values arbitrary
23 binary blobs.
24
25 The API is:
26   Functions:
27     exim_lockfile_needed        API semantics predicate
28     exim_dbopen
29     exim_dbopen_multi           only for no-lockfile-needed
30     exim_dbclose
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
34     exim_dbget
35     exim_dbput
36     exim_dbputb                 non-overwriting put
37     exim_dbdel
38     exim_dbcreate_cursor
39     exim_dbscan                 get, and bump cursor
40     exim_dbdelete_cursor
41     exim_datum_init
42     exim_datum_size_get/set
43     exim_datum_data_get/set
44     exim_datum_free
45   Defines:
46     EXIM_DB             access handle
47     EXIM_CURSOR         datatype for cursor
48     EXIM_DATUM          datatype for "value"
49     EXIM_DBTYPE         text for logging & debuug
50
51 Selection of the shim layer implementation, and backend, is by #defines.
52
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
57
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)?
63 */
64
65 #ifndef HINTSDB_H
66 #define HINTSDB_H
67
68 /* Include file ordering problem */
69 extern void    debug_printf_indent(const char *, ...) PRINTF_FUNCTION(1,2);
70
71
72 #ifdef USE_SQLITE
73 # if defined(USE_DB) || defined(USE_GDBM) || defined(USE_TDB)
74 #  error USE_SQLITE conflict with alternate definition
75 # endif
76 # include "hintsdb/hints_sqlite.h"
77 #elif defined(USE_TDB)
78
79 # if defined(USE_DB) || defined(USE_GDBM) || defined(USE_SQLITE)
80 #  error USE_TDB conflict with alternate definition
81 # endif
82 # include "hintsdb/hints_tdb.h"
83
84 #elif defined USE_DB
85 # if defined(USE_TDB) || defined(USE_GDBM) || defined(USE_SQLITE)
86 #  error USE_DB conflict with alternate definition
87 # endif
88 # include "hintsdb/hints_bdb.h"
89
90 #elif defined USE_GDBM
91 # if defined(USE_TDB) || defined(USE_DB) || defined(USE_SQLITE)
92 #  error USE_GDBM conflict with alternate definition
93 # endif
94 # include "hintsdb/hints_gdbm.h"
95
96 #else
97
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) */
100
101 # include "hintsdb/hints_ndbm.h"
102 #endif /* !USE_GDBM */
103
104
105
106
107
108
109 /* Wrappers for open/close with debug tracing */
110
111 extern void debug_printf_indent(const char *, ...);
112 static inline BOOL is_tainted(const void *);
113
114 static inline EXIM_DB *
115 exim_dbopen(const uschar * name, const uschar * dirname, int flags,
116   unsigned mode)
117 {
118 void * dbp;
119 DEBUG(D_hints_lookup)
120   debug_printf_indent("EXIM_DBOPEN: file <%s> dir <%s> flags=%s\n",
121     name, dirname,
122     flags == O_RDONLY ? "O_RDONLY"
123     : flags == O_RDWR ? "O_RDWR"
124     : flags == (O_RDWR|O_CREAT) ? "O_RDWR|O_CREAT"
125     : "??");
126 if (is_tainted(name) || is_tainted(dirname))
127   {
128   log_write(0, LOG_MAIN|LOG_PANIC, "Tainted name for DB file not permitted");
129   dbp = NULL;
130   }
131 else
132   dbp = exim_dbopen__(name, dirname, flags, mode);
133
134 DEBUG(D_hints_lookup) debug_printf_indent("returned from EXIM_DBOPEN: %p\n", dbp);
135 return dbp;
136 }
137
138 static inline EXIM_DB *
139 exim_dbopen_multi(const uschar * name, const uschar * dirname, int flags,
140   unsigned mode)
141 {
142 void * dbp;
143 DEBUG(D_hints_lookup)
144   debug_printf_indent("EXIM_DBOPEN_MULTI: file <%s> dir <%s> flags=%s\n",
145     name, dirname,
146     flags == O_RDONLY ? "O_RDONLY"
147     : flags == O_RDWR ? "O_RDWR"
148     : flags == (O_RDWR|O_CREAT) ? "O_RDWR|O_CREAT"
149     : "??");
150 if (is_tainted(name) || is_tainted(dirname))
151   {
152   log_write(0, LOG_MAIN|LOG_PANIC, "Tainted name for DB file not permitted");
153   dbp = NULL;
154   }
155 else
156   dbp = exim_dbopen_multi__(name, dirname, flags, mode);
157
158 DEBUG(D_hints_lookup) debug_printf_indent("returned from EXIM_DBOPEN_MULTI: %p\n", dbp);
159 return dbp;
160 }
161
162 static inline void
163 exim_dbclose(EXIM_DB * dbp)
164 {
165 DEBUG(D_hints_lookup) debug_printf_indent("EXIM_DBCLOSE(%p)\n", dbp);
166 exim_dbclose__(dbp);
167 }
168 static inline void
169 exim_dbclose_multi(EXIM_DB * dbp)
170 {
171 DEBUG(D_hints_lookup) debug_printf_indent("EXIM_DBCLOSE_MULTI(%p)\n", dbp);
172 exim_dbclose_multi__(dbp);
173 }
174
175
176 /********************* End of dbm library definitions **********************/
177
178 #endif  /* whole file */
179 /* End of hintsdb.h */
180 /* vi: aw ai sw=2
181 */