200a204e88881d9a1c0d121ec49bc78f9bb9b14f
[users/jgh/exim.git] / src / src / lookups / dbmdb.c
1 /* $Cambridge: exim/src/src/lookups/dbmdb.c,v 1.6 2009/11/16 19:50:38 nm4 Exp $ */
2
3 /*************************************************
4 *     Exim - an Internet mail transport agent    *
5 *************************************************/
6
7 /* Copyright (c) University of Cambridge 1995 - 2009 */
8 /* See the file NOTICE for conditions of use and distribution. */
9
10 #include "../exim.h"
11 #include "lf_functions.h"
12 #include "dbmdb.h"
13
14
15 /*************************************************
16 *              Open entry point                  *
17 *************************************************/
18
19 /* See local README for interface description */
20
21 void *
22 dbmdb_open(uschar *filename, uschar **errmsg)
23 {
24 EXIM_DB *yield;
25 EXIM_DBOPEN(filename, O_RDONLY, 0, &yield);
26 if (yield == NULL)
27   {
28   int save_errno = errno;
29   *errmsg = string_open_failed(errno, "%s as a %s file", filename, EXIM_DBTYPE);
30   errno = save_errno;
31   }
32 return yield;
33 }
34
35
36
37 /*************************************************
38 *             Check entry point                  *
39 *************************************************/
40
41 /* This needs to know more about the underlying files than is good for it!
42 We need to know what the real file names are in order to check the owners and
43 modes. If USE_DB is set, we know it is Berkeley DB, which uses an unmodified
44 file name. If USE_TDB or USE_GDBM is set, we know it is tdb or gdbm, which do
45 the same. Otherwise, for safety, we have to check for x.db or x.dir and x.pag.
46 */
47
48 BOOL
49 dbmdb_check(void *handle, uschar *filename, int modemask, uid_t *owners,
50   gid_t *owngroups, uschar **errmsg)
51 {
52 int rc;
53 handle = handle;    /* Keep picky compilers happy */
54
55 #if defined(USE_DB) || defined(USE_TDB) || defined(USE_GDBM)
56 rc = lf_check_file(-1, filename, S_IFREG, modemask, owners, owngroups,
57   "dbm", errmsg);
58 #else
59   {
60   uschar filebuffer[256];
61   (void)sprintf(CS filebuffer, "%.250s.db", filename);
62   rc = lf_check_file(-1, filebuffer, S_IFREG, modemask, owners, owngroups,
63     "dbm", errmsg);
64   if (rc < 0)        /* stat() failed */
65     {
66     (void)sprintf(CS filebuffer, "%.250s.dir", filename);
67     rc = lf_check_file(-1, filebuffer, S_IFREG, modemask, owners, owngroups,
68       "dbm", errmsg);
69     if (rc == 0)     /* x.dir was OK */
70       {
71       (void)sprintf(CS filebuffer, "%.250s.pag", filename);
72       rc = lf_check_file(-1, filebuffer, S_IFREG, modemask, owners, owngroups,
73         "dbm", errmsg);
74       }
75     }
76   }
77 #endif
78
79 return rc == 0;
80 }
81
82
83
84 /*************************************************
85 *              Find entry point                  *
86 *************************************************/
87
88 /* See local README for interface description. This function adds 1 to
89 the keylength in order to include the terminating zero. */
90
91 int
92 dbmdb_find(void *handle, uschar *filename, uschar *keystring, int length,
93   uschar **result, uschar **errmsg, BOOL *do_cache)
94 {
95 EXIM_DB *d = (EXIM_DB *)handle;
96 EXIM_DATUM key, data;
97
98 filename = filename;    /* Keep picky compilers happy */
99 errmsg = errmsg;
100 do_cache = do_cache;
101
102 EXIM_DATUM_INIT(key);               /* Some DBM libraries require datums to */
103 EXIM_DATUM_INIT(data);              /* be cleared before use. */
104 EXIM_DATUM_DATA(key) = CS keystring;
105 EXIM_DATUM_SIZE(key) = length + 1;
106
107 if (EXIM_DBGET(d, key, data))
108   {
109   *result = string_copyn(US EXIM_DATUM_DATA(data), EXIM_DATUM_SIZE(data));
110   EXIM_DATUM_FREE(data);            /* Some DBM libraries need a free() call */
111   return OK;
112   }
113 return FAIL;
114 }
115
116
117
118 /*************************************************
119 *      Find entry point - no zero on key         *
120 *************************************************/
121
122 /* See local README for interface description */
123
124 int
125 dbmnz_find(void *handle, uschar *filename, uschar *keystring, int length,
126   uschar **result, uschar **errmsg, BOOL *do_cache)
127 {
128 return dbmdb_find(handle, filename, keystring, length-1, result, errmsg,
129   do_cache);
130 }
131
132
133
134 /*************************************************
135 *              Close entry point                 *
136 *************************************************/
137
138 /* See local README for interface description */
139
140 void
141 dbmdb_close(void *handle)
142 {
143 EXIM_DBCLOSE((EXIM_DB *)handle);
144 }
145
146 /* End of lookups/dbmdb.c */