Remove obsolete $Cambridge$ CVS revision strings.
[exim.git] / src / src / lookups / dbmdb.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2009 */
6 /* See the file NOTICE for conditions of use and distribution. */
7
8 #include "../exim.h"
9 #include "lf_functions.h"
10
11
12 /*************************************************
13 *              Open entry point                  *
14 *************************************************/
15
16 /* See local README for interface description */
17
18 static void *
19 dbmdb_open(uschar *filename, uschar **errmsg)
20 {
21 EXIM_DB *yield;
22 EXIM_DBOPEN(filename, O_RDONLY, 0, &yield);
23 if (yield == NULL)
24   {
25   int save_errno = errno;
26   *errmsg = string_open_failed(errno, "%s as a %s file", filename, EXIM_DBTYPE);
27   errno = save_errno;
28   }
29 return yield;
30 }
31
32
33
34 /*************************************************
35 *             Check entry point                  *
36 *************************************************/
37
38 /* This needs to know more about the underlying files than is good for it!
39 We need to know what the real file names are in order to check the owners and
40 modes. If USE_DB is set, we know it is Berkeley DB, which uses an unmodified
41 file name. If USE_TDB or USE_GDBM is set, we know it is tdb or gdbm, which do
42 the same. Otherwise, for safety, we have to check for x.db or x.dir and x.pag.
43 */
44
45 static BOOL
46 dbmdb_check(void *handle, uschar *filename, int modemask, uid_t *owners,
47   gid_t *owngroups, uschar **errmsg)
48 {
49 int rc;
50 handle = handle;    /* Keep picky compilers happy */
51
52 #if defined(USE_DB) || defined(USE_TDB) || defined(USE_GDBM)
53 rc = lf_check_file(-1, filename, S_IFREG, modemask, owners, owngroups,
54   "dbm", errmsg);
55 #else
56   {
57   uschar filebuffer[256];
58   (void)sprintf(CS filebuffer, "%.250s.db", filename);
59   rc = lf_check_file(-1, filebuffer, S_IFREG, modemask, owners, owngroups,
60     "dbm", errmsg);
61   if (rc < 0)        /* stat() failed */
62     {
63     (void)sprintf(CS filebuffer, "%.250s.dir", filename);
64     rc = lf_check_file(-1, filebuffer, S_IFREG, modemask, owners, owngroups,
65       "dbm", errmsg);
66     if (rc == 0)     /* x.dir was OK */
67       {
68       (void)sprintf(CS filebuffer, "%.250s.pag", filename);
69       rc = lf_check_file(-1, filebuffer, S_IFREG, modemask, owners, owngroups,
70         "dbm", errmsg);
71       }
72     }
73   }
74 #endif
75
76 return rc == 0;
77 }
78
79
80
81 /*************************************************
82 *              Find entry point                  *
83 *************************************************/
84
85 /* See local README for interface description. This function adds 1 to
86 the keylength in order to include the terminating zero. */
87
88 static int
89 dbmdb_find(void *handle, uschar *filename, uschar *keystring, int length,
90   uschar **result, uschar **errmsg, BOOL *do_cache)
91 {
92 EXIM_DB *d = (EXIM_DB *)handle;
93 EXIM_DATUM key, data;
94
95 filename = filename;    /* Keep picky compilers happy */
96 errmsg = errmsg;
97 do_cache = do_cache;
98
99 EXIM_DATUM_INIT(key);               /* Some DBM libraries require datums to */
100 EXIM_DATUM_INIT(data);              /* be cleared before use. */
101 EXIM_DATUM_DATA(key) = CS keystring;
102 EXIM_DATUM_SIZE(key) = length + 1;
103
104 if (EXIM_DBGET(d, key, data))
105   {
106   *result = string_copyn(US EXIM_DATUM_DATA(data), EXIM_DATUM_SIZE(data));
107   EXIM_DATUM_FREE(data);            /* Some DBM libraries need a free() call */
108   return OK;
109   }
110 return FAIL;
111 }
112
113
114
115 /*************************************************
116 *      Find entry point - no zero on key         *
117 *************************************************/
118
119 /* See local README for interface description */
120
121 int
122 static dbmnz_find(void *handle, uschar *filename, uschar *keystring, int length,
123   uschar **result, uschar **errmsg, BOOL *do_cache)
124 {
125 return dbmdb_find(handle, filename, keystring, length-1, result, errmsg,
126   do_cache);
127 }
128
129
130
131 /*************************************************
132 *              Close entry point                 *
133 *************************************************/
134
135 /* See local README for interface description */
136
137 void
138 static dbmdb_close(void *handle)
139 {
140 EXIM_DBCLOSE((EXIM_DB *)handle);
141 }
142
143
144
145 /*************************************************
146 *         Version reporting entry point          *
147 *************************************************/
148
149 /* See local README for interface description. */
150
151 #include "../version.h"
152
153 void
154 dbm_version_report(FILE *f)
155 {
156 #ifdef DYNLOOKUP
157 fprintf(f, "Library version: DBM: Exim version %s\n", EXIM_VERSION_STR);
158 #endif
159 }
160
161
162 lookup_info dbm_lookup_info = {
163   US"dbm",                       /* lookup name */
164   lookup_absfile,                /* uses absolute file name */
165   dbmdb_open,                    /* open function */
166   dbmdb_check,                   /* check function */
167   dbmdb_find,                    /* find function */
168   dbmdb_close,                   /* close function */
169   NULL,                          /* no tidy function */
170   NULL,                          /* no quoting function */
171   dbm_version_report             /* version reporting */
172 };
173
174 lookup_info dbmz_lookup_info = {
175   US"dbmnz",                     /* lookup name */
176   lookup_absfile,                /* uses absolute file name */
177   dbmdb_open,      /* sic */     /* open function */
178   dbmdb_check,     /* sic */     /* check function */
179   dbmnz_find,                    /* find function */
180   dbmdb_close,     /* sic */     /* close function */
181   NULL,                          /* no tidy function */
182   NULL,                          /* no quoting function */
183   NULL                           /* no version reporting (redundant) */
184 };
185
186 #ifdef DYNLOOKUP
187 #define dbmdb_lookup_module_info _lookup_module_info
188 #endif
189
190 static lookup_info *_lookup_list[] = { &dbm_lookup_info, &dbmz_lookup_info };
191 lookup_module_info dbmdb_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 2 };
192
193 /* End of lookups/dbmdb.c */