bottleneck testcase based on rubbos
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / srclib / apr-util / dbm / apr_dbm_ndbm.c
1 /* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
2  * applicable.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * 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.h"
24
25 #if APU_HAVE_NDBM 
26 #include "apr_dbm_private.h"
27
28 #include <ndbm.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32
33 /* this is used in a few places to define a noop "function". it is needed
34    to stop "no effect" warnings from GCC. */
35 #define NOOP_FUNCTION if (0) ; else
36
37 #define APR_DBM_DBMODE_RO       O_RDONLY
38 #define APR_DBM_DBMODE_RW       O_RDWR
39 #define APR_DBM_DBMODE_RWCREATE (O_RDWR|O_CREAT)
40 #define APR_DBM_DBMODE_RWTRUNC  (O_RDWR|O_CREAT|O_TRUNC)
41
42 /* map a NDBM error to an apr_status_t */
43 static apr_status_t ndbm2s(int ndbmerr)
44 {
45     if (ndbmerr == -1) {
46         /* ### need to fix this */
47         return APR_EGENERAL;
48     }
49
50     return APR_SUCCESS;
51 }
52
53 static apr_status_t set_error(apr_dbm_t *dbm, apr_status_t dbm_said)
54 {
55     apr_status_t rv = APR_SUCCESS;
56
57     /* ### ignore whatever the DBM said (dbm_said); ask it explicitly */
58
59     dbm->errmsg = NULL;
60     if (dbm_error((DBM*)dbm->file)) {
61         dbm->errmsg = NULL;
62         rv = APR_EGENERAL;        /* ### need something better */
63     }
64
65     /* captured it. clear it now. */
66     dbm_clearerr((DBM*)dbm->file);
67
68     return rv;
69 }
70
71 /* --------------------------------------------------------------------------
72 **
73 ** DEFINE THE VTABLE FUNCTIONS FOR NDBM
74 */
75
76 static apr_status_t vt_ndbm_open(apr_dbm_t **pdb, const char *pathname,
77                                  apr_int32_t mode, apr_fileperms_t perm,
78                                  apr_pool_t *pool)
79 {
80     DBM *file;
81     int dbmode;
82
83     *pdb = NULL;
84
85     switch (mode) {
86     case APR_DBM_READONLY:
87         dbmode = APR_DBM_DBMODE_RO;
88         break;
89     case APR_DBM_READWRITE:
90         dbmode = APR_DBM_DBMODE_RW;
91         break;
92     case APR_DBM_RWCREATE:
93         dbmode = APR_DBM_DBMODE_RWCREATE;
94         break;
95     case APR_DBM_RWTRUNC:
96         dbmode = APR_DBM_DBMODE_RWTRUNC;
97         break;
98     default:
99         return APR_EINVAL;
100     }
101
102     {
103         file = dbm_open(pathname, dbmode, apr_posix_perms2mode(perm));
104         if (file == NULL)
105             return APR_EGENERAL;      /* ### need a better error */
106     }
107
108     /* we have an open database... return it */
109     *pdb = apr_pcalloc(pool, sizeof(**pdb));
110     (*pdb)->pool = pool;
111     (*pdb)->type = &apr_dbm_type_ndbm;
112     (*pdb)->file = file;
113
114     /* ### register a cleanup to close the DBM? */
115
116     return APR_SUCCESS;
117 }
118
119 static void vt_ndbm_close(apr_dbm_t *dbm)
120 {
121     dbm_close(dbm->file);
122 }
123
124 static apr_status_t vt_ndbm_fetch(apr_dbm_t *dbm, apr_datum_t key,
125                                   apr_datum_t * pvalue)
126 {
127     datum *ckey;
128     datum rd;
129
130     ckey = (datum*)&key;
131     rd = dbm_fetch(dbm->file, *ckey);
132     *pvalue = *(apr_datum_t*)&rd;
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     apr_status_t rv;
143     datum *ckey;
144     datum *cvalue;
145
146     ckey =  (datum*)&key;
147     cvalue = (datum*)&value;
148     rv = ndbm2s( dbm_store( dbm->file, *ckey, *cvalue, DBM_REPLACE));
149
150     /* store any error info into DBM, and return a status code. */
151     return set_error(dbm, rv);
152 }
153
154 static apr_status_t vt_ndbm_del(apr_dbm_t *dbm, apr_datum_t key)
155 {
156     apr_status_t rv;
157     datum *ckey;
158
159     ckey = (datum*)&key;
160     rv = ndbm2s( dbm_delete(dbm->file, *ckey));
161
162     /* store any error info into DBM, and return a status code. */
163     return set_error(dbm, rv);
164 }
165
166 static int vt_ndbm_exists(apr_dbm_t *dbm, apr_datum_t key)
167 {
168     datum *ckey = (datum *)&key;
169     datum value;
170
171     value = dbm_fetch( dbm->file, *ckey);
172
173     return value.dptr != NULL;
174 }
175
176 static apr_status_t vt_ndbm_firstkey(apr_dbm_t *dbm, apr_datum_t * pkey)
177 {
178     datum rd;
179
180     rd = dbm_firstkey(dbm->file);
181     *pkey = *(apr_datum_t*)&rd;
182
183     /* store any error info into DBM, and return a status code. */
184     return set_error(dbm, APR_SUCCESS);
185 }
186
187 static apr_status_t vt_ndbm_nextkey(apr_dbm_t *dbm, apr_datum_t * pkey)
188 {
189     datum *ckey;
190     datum rd;
191
192     ckey = (datum*)pkey;
193     rd = dbm_nextkey(dbm->file);
194     *pkey = *(apr_datum_t*)&rd;
195
196     /* store any error info into DBM, and return a status code. */
197     return set_error(dbm, APR_SUCCESS);
198 }
199
200 static void vt_ndbm_freedatum(apr_dbm_t *dbm, apr_datum_t data)
201 {
202   /* nothing to do */
203 }
204
205 static void vt_ndbm_usednames(apr_pool_t *pool, const char *pathname,
206                               const char **used1, const char **used2)
207 {
208     *used1 = apr_pstrdup(pool, pathname);
209     *used2 = NULL;
210 }
211
212
213 APU_DECLARE_DATA const apr_dbm_type_t apr_dbm_type_ndbm = {
214     "ndbm",
215
216     vt_ndbm_open,
217     vt_ndbm_close,
218     vt_ndbm_fetch,
219     vt_ndbm_store,
220     vt_ndbm_del,
221     vt_ndbm_exists,
222     vt_ndbm_firstkey,
223     vt_ndbm_nextkey,
224     vt_ndbm_freedatum,
225     vt_ndbm_usednames
226 };
227 #endif /* APU_HAVE_NDBM  */