ba50ae1b976bfd75b4224d0ebb5cc064283cfc0c
[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. 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 A key/value store is supported (only).  Keys are strings; values arbitrary
22 binary blobs.
23
24 The API is:
25   Functions:
26     exim_lockfile_needed        API semantics predicate
27     exim_dbopen
28     exim_dbclose
29     exim_dbget
30     exim_dbput
31     exim_dbputb                 non-overwriting put
32     exim_dbdel
33     exim_dbcreate_cursor
34     exim_dbscan                 get, and bump cursor
35     exim_dbdelete_cursor
36     exim_datum_init
37     exim_datum_size_get/set
38     exim_datum_data_get/set
39     exim_datum_free
40   Defines:
41     EXIM_DB             access handle
42     EXIM_CURSOR         datatype for cursor
43     EXIM_DATUM          datatype for "value"
44     EXIM_DBTYPE         text for logging & debuug
45
46 Selection of the shim layer implementation, and backend, is by #defines.
47
48 The users of this API are:
49   hintsdb interface     dbfn.c
50   hintsdb utilities     exim_dbutil.c and exim_dbmvuild.c
51   dbmdb lookup          lookups/dbmdb,c
52   autoreply transport   transports/autoreply.c
53
54 Note that the dbmdb lookup use, bypassing the dbfn.c layer,
55 means that no file-locking is done.
56 XXX This feels like a layering violation; I don't see it commented on
57 anywhere.
58
59 Future: consider re-architecting to support caching of the open-handle
60 for hintsdb uses (the dbmdb use gets that already).  This would need APIs
61 for transaction locks.  Perhaps merge the implementation with the lookups
62 layer, in some way, for the open-handle caching (since that manages closes
63 required by Exim's process transitions)?
64 */
65
66 #ifndef HINTSDB_H
67 #define HINTSDB_H
68
69
70 #ifdef USE_SQLITE
71 # if defined(USE_DB) || defined(USE_GDBM) || defined(USE_TDB)
72 #  error USE_SQLITE conflict with alternate definition
73 # endif
74 # include "hintsdb/hints_sqlite.h"
75 #elif defined(USE_TDB)
76
77 # if defined(USE_DB) || defined(USE_GDBM) || defined(USE_SQLITE)
78 #  error USE_TDB conflict with alternate definition
79 # endif
80 # include "hintsdb/hints_tdb.h"
81
82 #elif defined USE_DB
83 # if defined(USE_TDB) || defined(USE_GDBM) || defined(USE_SQLITE)
84 #  error USE_DB conflict with alternate definition
85 # endif
86 # include "hintsdb/hints_bdb.h"
87
88 #elif defined USE_GDBM
89 # if defined(USE_TDB) || defined(USE_DB) || defined(USE_SQLITE)
90 #  error USE_GDBM conflict with alternate definition
91 # endif
92 # include "hintsdb/hints_gdbm.h"
93
94 #else
95
96 /* If none of USE_{DB,GDBM,SQLITE,TDB} are set
97 the default is the NDBM interface (which seems to be a wrapper for GDBM) */
98
99 # include "hintsdb/hints_ndbm.h"
100 #endif /* !USE_GDBM */
101
102
103
104
105
106 #if defined(COMPILE_UTILITY) || defined(MACRO_PREDEF)
107
108 static inline EXIM_DB *
109 exim_dbopen(const uschar * name, const uschar * dirname, int flags,
110   unsigned mode)
111 {
112 return exim_dbopen__(name, dirname, flags, mode);
113 }
114
115 static inline void
116 exim_dbclose(EXIM_DB * dbp)
117 { exim_dbclose__(dbp); }
118
119 #else   /*  exim mainline code */
120
121 /* Wrappers for open/close with debug tracing */
122
123 extern void debug_printf_indent(const char *, ...);
124 static inline BOOL is_tainted(const void *);
125
126 static inline EXIM_DB *
127 exim_dbopen(const uschar * name, const uschar * dirname, int flags,
128   unsigned mode)
129 {
130 void * dbp;
131 DEBUG(D_hints_lookup)
132   debug_printf_indent("EXIM_DBOPEN: file <%s> dir <%s> flags=%s\n",
133     name, dirname,
134     flags == O_RDONLY ? "O_RDONLY"
135     : flags == O_RDWR ? "O_RDWR"
136     : flags == (O_RDWR|O_CREAT) ? "O_RDWR|O_CREAT"
137     : "??");
138 if (is_tainted(name) || is_tainted(dirname))
139   {
140   log_write(0, LOG_MAIN|LOG_PANIC, "Tainted name for DB file not permitted");
141   dbp = NULL;
142   }
143 else
144   dbp = exim_dbopen__(name, dirname, flags, mode);
145
146 DEBUG(D_hints_lookup) debug_printf_indent("returned from EXIM_DBOPEN: %p\n", dbp);
147 return dbp;
148 }
149
150 static inline void
151 exim_dbclose(EXIM_DB * dbp)
152 {
153 DEBUG(D_hints_lookup) debug_printf_indent("EXIM_DBCLOSE(%p)\n", dbp);
154 exim_dbclose__(dbp);
155 }
156
157 #endif          /* defined(COMPILE_UTILITY) || defined(MACRO_PREDEF) */
158
159 /********************* End of dbm library definitions **********************/
160
161 #endif  /* whole file */
162 /* End of hintsdb.h */
163 /* vi: aw ai sw=2
164 */