xref: /trueos/contrib/apr-util/dbm/apr_dbm_ndbm.c (revision 1e5107043085964bba002e6a91aa04e864f74d02)
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 */
ndbm2s(int ndbmerr)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 
set_error(apr_dbm_t * dbm,apr_status_t dbm_said)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 
vt_ndbm_open(apr_dbm_t ** pdb,const char * pathname,apr_int32_t mode,apr_fileperms_t perm,apr_pool_t * pool)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 
vt_ndbm_close(apr_dbm_t * dbm)116 static void vt_ndbm_close(apr_dbm_t *dbm)
117 {
118     dbm_close(dbm->file);
119 }
120 
vt_ndbm_fetch(apr_dbm_t * dbm,apr_datum_t key,apr_datum_t * pvalue)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 
vt_ndbm_store(apr_dbm_t * dbm,apr_datum_t key,apr_datum_t value)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 
vt_ndbm_del(apr_dbm_t * dbm,apr_datum_t key)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 
vt_ndbm_exists(apr_dbm_t * dbm,apr_datum_t key)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 
vt_ndbm_firstkey(apr_dbm_t * dbm,apr_datum_t * pkey)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 
vt_ndbm_nextkey(apr_dbm_t * dbm,apr_datum_t * pkey)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 
vt_ndbm_freedatum(apr_dbm_t * dbm,apr_datum_t data)212 static void vt_ndbm_freedatum(apr_dbm_t *dbm, apr_datum_t data)
213 {
214   /* nothing to do */
215 }
216 
vt_ndbm_usednames(apr_pool_t * pool,const char * pathname,const char ** used1,const char ** used2)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  */
239