Use of pre_cleanups is not the default for reslists.
[apr-util.git] / dbm / apr_dbm_ndbm.c
blob42ddbed38a9e12e34455cf4efa1ece1aec43cc1b
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "apr_strings.h"
19 #if APR_HAVE_STDLIB_H
20 #include <stdlib.h> /* for free() */
21 #endif
23 #include "apu.h"
25 #if APU_HAVE_NDBM
26 #include "apr_dbm_private.h"
28 #include <ndbm.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
33 #define APR_DBM_DBMODE_RO O_RDONLY
34 #define APR_DBM_DBMODE_RW O_RDWR
35 #define APR_DBM_DBMODE_RWCREATE (O_RDWR|O_CREAT)
36 #define APR_DBM_DBMODE_RWTRUNC (O_RDWR|O_CREAT|O_TRUNC)
38 /* map a NDBM error to an apr_status_t */
39 static apr_status_t ndbm2s(int ndbmerr)
41 if (ndbmerr == -1) {
42 /* ### need to fix this */
43 return APR_EGENERAL;
46 return APR_SUCCESS;
49 static apr_status_t set_error(apr_dbm_t *dbm, apr_status_t dbm_said)
51 apr_status_t rv = APR_SUCCESS;
53 /* ### ignore whatever the DBM said (dbm_said); ask it explicitly */
55 dbm->errmsg = NULL;
56 if (dbm_error((DBM*)dbm->file)) {
57 dbm->errmsg = NULL;
58 rv = APR_EGENERAL; /* ### need something better */
61 /* captured it. clear it now. */
62 dbm_clearerr((DBM*)dbm->file);
64 return rv;
67 /* --------------------------------------------------------------------------
69 ** DEFINE THE VTABLE FUNCTIONS FOR NDBM
72 static apr_status_t vt_ndbm_open(apr_dbm_t **pdb, const char *pathname,
73 apr_int32_t mode, apr_fileperms_t perm,
74 apr_pool_t *pool)
76 DBM *file;
77 int dbmode;
79 *pdb = NULL;
81 switch (mode) {
82 case APR_DBM_READONLY:
83 dbmode = APR_DBM_DBMODE_RO;
84 break;
85 case APR_DBM_READWRITE:
86 dbmode = APR_DBM_DBMODE_RW;
87 break;
88 case APR_DBM_RWCREATE:
89 dbmode = APR_DBM_DBMODE_RWCREATE;
90 break;
91 case APR_DBM_RWTRUNC:
92 dbmode = APR_DBM_DBMODE_RWTRUNC;
93 break;
94 default:
95 return APR_EINVAL;
99 file = dbm_open(pathname, dbmode, apr_posix_perms2mode(perm));
100 if (file == NULL)
101 return APR_EGENERAL; /* ### need a better error */
104 /* we have an open database... return it */
105 *pdb = apr_pcalloc(pool, sizeof(**pdb));
106 (*pdb)->pool = pool;
107 (*pdb)->type = &apr_dbm_type_ndbm;
108 (*pdb)->file = file;
110 /* ### register a cleanup to close the DBM? */
112 return APR_SUCCESS;
115 static void vt_ndbm_close(apr_dbm_t *dbm)
117 dbm_close(dbm->file);
120 static apr_status_t vt_ndbm_fetch(apr_dbm_t *dbm, apr_datum_t key,
121 apr_datum_t *pvalue)
123 datum kd, rd;
125 kd.dptr = key.dptr;
126 kd.dsize = key.dsize;
128 rd = dbm_fetch(dbm->file, kd);
130 pvalue->dptr = rd.dptr;
131 pvalue->dsize = rd.dsize;
133 /* store the error info into DBM, and return a status code. Also, note
134 that *pvalue should have been cleared on error. */
135 return set_error(dbm, APR_SUCCESS);
138 static apr_status_t vt_ndbm_store(apr_dbm_t *dbm, apr_datum_t key,
139 apr_datum_t value)
141 int rc;
142 datum kd, vd;
144 kd.dptr = key.dptr;
145 kd.dsize = key.dsize;
147 vd.dptr = value.dptr;
148 vd.dsize = value.dsize;
150 rc = dbm_store(dbm->file, kd, vd, DBM_REPLACE);
152 /* store any error info into DBM, and return a status code. */
153 return set_error(dbm, ndbm2s(rc));
156 static apr_status_t vt_ndbm_del(apr_dbm_t *dbm, apr_datum_t key)
158 int rc;
159 datum kd;
161 kd.dptr = key.dptr;
162 kd.dsize = key.dsize;
164 rc = dbm_delete(dbm->file, kd);
166 /* store any error info into DBM, and return a status code. */
167 return set_error(dbm, ndbm2s(rc));
170 static int vt_ndbm_exists(apr_dbm_t *dbm, apr_datum_t key)
172 datum kd, rd;
174 kd.dptr = key.dptr;
175 kd.dsize = key.dsize;
177 rd = dbm_fetch(dbm->file, kd);
179 return rd.dptr != NULL;
182 static apr_status_t vt_ndbm_firstkey(apr_dbm_t *dbm, apr_datum_t *pkey)
184 datum rd;
186 rd = dbm_firstkey(dbm->file);
188 pkey->dptr = rd.dptr;
189 pkey->dsize = rd.dsize;
191 /* store any error info into DBM, and return a status code. */
192 return set_error(dbm, APR_SUCCESS);
195 static apr_status_t vt_ndbm_nextkey(apr_dbm_t *dbm, apr_datum_t *pkey)
197 datum kd, rd;
199 kd.dptr = pkey->dptr;
200 kd.dsize = pkey->dsize;
202 rd = dbm_nextkey(dbm->file);
204 pkey->dptr = rd.dptr;
205 pkey->dsize = rd.dsize;
207 /* store any error info into DBM, and return a status code. */
208 return set_error(dbm, APR_SUCCESS);
211 static void vt_ndbm_freedatum(apr_dbm_t *dbm, apr_datum_t data)
213 /* nothing to do */
216 static void vt_ndbm_usednames(apr_pool_t *pool, const char *pathname,
217 const char **used1, const char **used2)
219 *used1 = apr_pstrdup(pool, pathname);
220 *used2 = NULL;
223 APU_DECLARE_DATA const apr_dbm_type_t apr_dbm_type_ndbm = {
224 "ndbm",
225 vt_ndbm_open,
226 vt_ndbm_close,
227 vt_ndbm_fetch,
228 vt_ndbm_store,
229 vt_ndbm_del,
230 vt_ndbm_exists,
231 vt_ndbm_firstkey,
232 vt_ndbm_nextkey,
233 vt_ndbm_freedatum,
234 vt_ndbm_usednames
237 #endif /* APU_HAVE_NDBM */