]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/apr-util/dbm/apr_dbm_ndbm.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / apr-util / dbm / apr_dbm_ndbm.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "apr_strings.h"
18
19 #if APR_HAVE_STDLIB_H
20 #include <stdlib.h>     /* for free() */
21 #endif
22
23 #include "apu_config.h"
24 #include "apu.h"
25
26 #if APU_HAVE_NDBM
27 #include "apr_dbm_private.h"
28
29 #include <ndbm.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33
34 #define APR_DBM_DBMODE_RO       O_RDONLY
35 #define APR_DBM_DBMODE_RW       O_RDWR
36 #define APR_DBM_DBMODE_RWCREATE (O_RDWR|O_CREAT)
37 #define APR_DBM_DBMODE_RWTRUNC  (O_RDWR|O_CREAT|O_TRUNC)
38
39 /* map a NDBM error to an apr_status_t */
40 static apr_status_t ndbm2s(int ndbmerr)
41 {
42     if (ndbmerr == -1) {
43         /* ### need to fix this */
44         return APR_EGENERAL;
45     }
46
47     return APR_SUCCESS;
48 }
49
50 static apr_status_t set_error(apr_dbm_t *dbm, apr_status_t dbm_said)
51 {
52     apr_status_t rv = APR_SUCCESS;
53
54     /* ### ignore whatever the DBM said (dbm_said); ask it explicitly */
55
56     dbm->errmsg = NULL;
57     if (dbm_error((DBM*)dbm->file)) {
58         dbm->errmsg = NULL;
59         rv = APR_EGENERAL;        /* ### need something better */
60     }
61
62     /* captured it. clear it now. */
63     dbm_clearerr((DBM*)dbm->file);
64
65     return rv;
66 }
67
68 /* --------------------------------------------------------------------------
69 **
70 ** DEFINE THE VTABLE FUNCTIONS FOR NDBM
71 */
72
73 static apr_status_t vt_ndbm_open(apr_dbm_t **pdb, const char *pathname,
74                                  apr_int32_t mode, apr_fileperms_t perm,
75                                  apr_pool_t *pool)
76 {
77     DBM *file;
78     int dbmode;
79
80     *pdb = NULL;
81
82     switch (mode) {
83     case APR_DBM_READONLY:
84         dbmode = APR_DBM_DBMODE_RO;
85         break;
86     case APR_DBM_READWRITE:
87         dbmode = APR_DBM_DBMODE_RW;
88         break;
89     case APR_DBM_RWCREATE:
90         dbmode = APR_DBM_DBMODE_RWCREATE;
91         break;
92     case APR_DBM_RWTRUNC:
93         dbmode = APR_DBM_DBMODE_RWTRUNC;
94         break;
95     default:
96         return APR_EINVAL;
97     }
98
99     {
100         file = dbm_open(pathname, dbmode, apr_posix_perms2mode(perm));
101         if (file == NULL)
102             return APR_EGENERAL;      /* ### need a better error */
103     }
104
105     /* we have an open database... return it */
106     *pdb = apr_pcalloc(pool, sizeof(**pdb));
107     (*pdb)->pool = pool;
108     (*pdb)->type = &apr_dbm_type_ndbm;
109     (*pdb)->file = file;
110
111     /* ### register a cleanup to close the DBM? */
112
113     return APR_SUCCESS;
114 }
115
116 static void vt_ndbm_close(apr_dbm_t *dbm)
117 {
118     dbm_close(dbm->file);
119 }
120
121 static apr_status_t vt_ndbm_fetch(apr_dbm_t *dbm, apr_datum_t key,
122                                   apr_datum_t *pvalue)
123 {
124     datum kd, rd;
125
126     kd.dptr = key.dptr;
127     kd.dsize = key.dsize;
128
129     rd = dbm_fetch(dbm->file, kd);
130
131     pvalue->dptr = rd.dptr;
132     pvalue->dsize = rd.dsize;
133
134     /* store the error info into DBM, and return a status code. Also, note
135        that *pvalue should have been cleared on error. */
136     return set_error(dbm, APR_SUCCESS);
137 }
138
139 static apr_status_t vt_ndbm_store(apr_dbm_t *dbm, apr_datum_t key,
140                                   apr_datum_t value)
141 {
142     int rc;
143     datum kd, vd;
144
145     kd.dptr = key.dptr;
146     kd.dsize = key.dsize;
147
148     vd.dptr = value.dptr;
149     vd.dsize = value.dsize;
150
151     rc = dbm_store(dbm->file, kd, vd, DBM_REPLACE);
152
153     /* store any error info into DBM, and return a status code. */
154     return set_error(dbm, ndbm2s(rc));
155 }
156
157 static apr_status_t vt_ndbm_del(apr_dbm_t *dbm, apr_datum_t key)
158 {
159     int rc;
160     datum kd;
161
162     kd.dptr = key.dptr;
163     kd.dsize = key.dsize;
164
165     rc = dbm_delete(dbm->file, kd);
166
167     /* store any error info into DBM, and return a status code. */
168     return set_error(dbm, ndbm2s(rc));
169 }
170
171 static int vt_ndbm_exists(apr_dbm_t *dbm, apr_datum_t key)
172 {
173     datum kd, rd;
174
175     kd.dptr = key.dptr;
176     kd.dsize = key.dsize;
177
178     rd = dbm_fetch(dbm->file, kd);
179
180     return rd.dptr != NULL;
181 }
182
183 static apr_status_t vt_ndbm_firstkey(apr_dbm_t *dbm, apr_datum_t *pkey)
184 {
185     datum rd;
186
187     rd = dbm_firstkey(dbm->file);
188
189     pkey->dptr = rd.dptr;
190     pkey->dsize = rd.dsize;
191
192     /* store any error info into DBM, and return a status code. */
193     return set_error(dbm, APR_SUCCESS);
194 }
195
196 static apr_status_t vt_ndbm_nextkey(apr_dbm_t *dbm, apr_datum_t *pkey)
197 {
198     datum kd, rd;
199
200     kd.dptr = pkey->dptr;
201     kd.dsize = pkey->dsize;
202
203     rd = dbm_nextkey(dbm->file);
204
205     pkey->dptr = rd.dptr;
206     pkey->dsize = rd.dsize;
207
208     /* store any error info into DBM, and return a status code. */
209     return set_error(dbm, APR_SUCCESS);
210 }
211
212 static void vt_ndbm_freedatum(apr_dbm_t *dbm, apr_datum_t data)
213 {
214   /* nothing to do */
215 }
216
217 static void vt_ndbm_usednames(apr_pool_t *pool, const char *pathname,
218                               const char **used1, const char **used2)
219 {
220     *used1 = apr_pstrdup(pool, pathname);
221     *used2 = NULL;
222 }
223
224 APU_MODULE_DECLARE_DATA const apr_dbm_type_t apr_dbm_type_ndbm = {
225     "ndbm",
226     vt_ndbm_open,
227     vt_ndbm_close,
228     vt_ndbm_fetch,
229     vt_ndbm_store,
230     vt_ndbm_del,
231     vt_ndbm_exists,
232     vt_ndbm_firstkey,
233     vt_ndbm_nextkey,
234     vt_ndbm_freedatum,
235     vt_ndbm_usednames
236 };
237
238 #endif /* APU_HAVE_NDBM  */