1*7f2fe78bSCy Schubert /*-
2*7f2fe78bSCy Schubert * Copyright (c) 1990, 1993
3*7f2fe78bSCy Schubert * The Regents of the University of California. All rights reserved.
4*7f2fe78bSCy Schubert *
5*7f2fe78bSCy Schubert * This code is derived from software contributed to Berkeley by
6*7f2fe78bSCy Schubert * Margo Seltzer.
7*7f2fe78bSCy Schubert *
8*7f2fe78bSCy Schubert * Redistribution and use in source and binary forms, with or without
9*7f2fe78bSCy Schubert * modification, are permitted provided that the following conditions
10*7f2fe78bSCy Schubert * are met:
11*7f2fe78bSCy Schubert * 1. Redistributions of source code must retain the above copyright
12*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer.
13*7f2fe78bSCy Schubert * 2. Redistributions in binary form must reproduce the above copyright
14*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer in the
15*7f2fe78bSCy Schubert * documentation and/or other materials provided with the distribution.
16*7f2fe78bSCy Schubert * 3. All advertising materials mentioning features or use of this software
17*7f2fe78bSCy Schubert * must display the following acknowledgement:
18*7f2fe78bSCy Schubert * This product includes software developed by the University of
19*7f2fe78bSCy Schubert * California, Berkeley and its contributors.
20*7f2fe78bSCy Schubert * 4. Neither the name of the University nor the names of its contributors
21*7f2fe78bSCy Schubert * may be used to endorse or promote products derived from this software
22*7f2fe78bSCy Schubert * without specific prior written permission.
23*7f2fe78bSCy Schubert *
24*7f2fe78bSCy Schubert * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25*7f2fe78bSCy Schubert * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26*7f2fe78bSCy Schubert * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27*7f2fe78bSCy Schubert * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28*7f2fe78bSCy Schubert * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29*7f2fe78bSCy Schubert * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30*7f2fe78bSCy Schubert * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31*7f2fe78bSCy Schubert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32*7f2fe78bSCy Schubert * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33*7f2fe78bSCy Schubert * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34*7f2fe78bSCy Schubert * SUCH DAMAGE.
35*7f2fe78bSCy Schubert */
36*7f2fe78bSCy Schubert
37*7f2fe78bSCy Schubert #if defined(LIBC_SCCS) && !defined(lint)
38*7f2fe78bSCy Schubert static char sccsid[] = "@(#)dbm.c 8.6 (Berkeley) 11/7/95";
39*7f2fe78bSCy Schubert #endif /* LIBC_SCCS and not lint */
40*7f2fe78bSCy Schubert
41*7f2fe78bSCy Schubert #include "db-int.h"
42*7f2fe78bSCy Schubert
43*7f2fe78bSCy Schubert #include <sys/param.h>
44*7f2fe78bSCy Schubert
45*7f2fe78bSCy Schubert #include <fcntl.h>
46*7f2fe78bSCy Schubert #include <stdio.h>
47*7f2fe78bSCy Schubert #include <string.h>
48*7f2fe78bSCy Schubert
49*7f2fe78bSCy Schubert #include "db-ndbm.h"
50*7f2fe78bSCy Schubert #include "db-dbm.h"
51*7f2fe78bSCy Schubert #include "hash.h"
52*7f2fe78bSCy Schubert
53*7f2fe78bSCy Schubert /* If the two size fields of datum and DBMT are not equal, then
54*7f2fe78bSCy Schubert * casting between structures will result in stack garbage being
55*7f2fe78bSCy Schubert * transferred. Has been observed for DEC Alpha OSF, but will handle
56*7f2fe78bSCy Schubert * the general case.
57*7f2fe78bSCy Schubert */
58*7f2fe78bSCy Schubert
59*7f2fe78bSCy Schubert #define NEED_COPY
60*7f2fe78bSCy Schubert
61*7f2fe78bSCy Schubert /*
62*7f2fe78bSCy Schubert *
63*7f2fe78bSCy Schubert * This package provides dbm and ndbm compatible interfaces to DB.
64*7f2fe78bSCy Schubert * First are the DBM routines, which call the NDBM routines, and
65*7f2fe78bSCy Schubert * the NDBM routines, which call the DB routines.
66*7f2fe78bSCy Schubert */
67*7f2fe78bSCy Schubert static DBM *__cur_db;
68*7f2fe78bSCy Schubert
69*7f2fe78bSCy Schubert static void no_open_db __P((void));
70*7f2fe78bSCy Schubert
71*7f2fe78bSCy Schubert int
kdb2_dbminit(file)72*7f2fe78bSCy Schubert kdb2_dbminit(file)
73*7f2fe78bSCy Schubert char *file;
74*7f2fe78bSCy Schubert {
75*7f2fe78bSCy Schubert if (__cur_db != NULL)
76*7f2fe78bSCy Schubert (void)kdb2_dbm_close(__cur_db);
77*7f2fe78bSCy Schubert if ((__cur_db = kdb2_dbm_open(file, O_RDWR|O_BINARY, 0)) != NULL)
78*7f2fe78bSCy Schubert return (0);
79*7f2fe78bSCy Schubert if ((__cur_db = kdb2_dbm_open(file, O_RDONLY|O_BINARY, 0)) != NULL)
80*7f2fe78bSCy Schubert return (0);
81*7f2fe78bSCy Schubert return (-1);
82*7f2fe78bSCy Schubert }
83*7f2fe78bSCy Schubert
84*7f2fe78bSCy Schubert datum
kdb2_fetch(key)85*7f2fe78bSCy Schubert kdb2_fetch(key)
86*7f2fe78bSCy Schubert datum key;
87*7f2fe78bSCy Schubert {
88*7f2fe78bSCy Schubert datum item;
89*7f2fe78bSCy Schubert
90*7f2fe78bSCy Schubert if (__cur_db == NULL) {
91*7f2fe78bSCy Schubert no_open_db();
92*7f2fe78bSCy Schubert item.dptr = 0;
93*7f2fe78bSCy Schubert item.dsize = 0;
94*7f2fe78bSCy Schubert return (item);
95*7f2fe78bSCy Schubert }
96*7f2fe78bSCy Schubert return (kdb2_dbm_fetch(__cur_db, key));
97*7f2fe78bSCy Schubert }
98*7f2fe78bSCy Schubert
99*7f2fe78bSCy Schubert datum
kdb2_firstkey()100*7f2fe78bSCy Schubert kdb2_firstkey()
101*7f2fe78bSCy Schubert {
102*7f2fe78bSCy Schubert datum item;
103*7f2fe78bSCy Schubert
104*7f2fe78bSCy Schubert if (__cur_db == NULL) {
105*7f2fe78bSCy Schubert no_open_db();
106*7f2fe78bSCy Schubert item.dptr = 0;
107*7f2fe78bSCy Schubert item.dsize = 0;
108*7f2fe78bSCy Schubert return (item);
109*7f2fe78bSCy Schubert }
110*7f2fe78bSCy Schubert return (kdb2_dbm_firstkey(__cur_db));
111*7f2fe78bSCy Schubert }
112*7f2fe78bSCy Schubert
113*7f2fe78bSCy Schubert datum
kdb2_nextkey(key)114*7f2fe78bSCy Schubert kdb2_nextkey(key)
115*7f2fe78bSCy Schubert datum key;
116*7f2fe78bSCy Schubert {
117*7f2fe78bSCy Schubert datum item;
118*7f2fe78bSCy Schubert
119*7f2fe78bSCy Schubert if (__cur_db == NULL) {
120*7f2fe78bSCy Schubert no_open_db();
121*7f2fe78bSCy Schubert item.dptr = 0;
122*7f2fe78bSCy Schubert item.dsize = 0;
123*7f2fe78bSCy Schubert return (item);
124*7f2fe78bSCy Schubert }
125*7f2fe78bSCy Schubert return (kdb2_dbm_nextkey(__cur_db));
126*7f2fe78bSCy Schubert }
127*7f2fe78bSCy Schubert
128*7f2fe78bSCy Schubert int
kdb2_delete(key)129*7f2fe78bSCy Schubert kdb2_delete(key)
130*7f2fe78bSCy Schubert datum key;
131*7f2fe78bSCy Schubert {
132*7f2fe78bSCy Schubert if (__cur_db == NULL) {
133*7f2fe78bSCy Schubert no_open_db();
134*7f2fe78bSCy Schubert return (-1);
135*7f2fe78bSCy Schubert }
136*7f2fe78bSCy Schubert return (kdb2_dbm_delete(__cur_db, key));
137*7f2fe78bSCy Schubert }
138*7f2fe78bSCy Schubert
139*7f2fe78bSCy Schubert int
kdb2_store(key,dat)140*7f2fe78bSCy Schubert kdb2_store(key, dat)
141*7f2fe78bSCy Schubert datum key, dat;
142*7f2fe78bSCy Schubert {
143*7f2fe78bSCy Schubert if (__cur_db == NULL) {
144*7f2fe78bSCy Schubert no_open_db();
145*7f2fe78bSCy Schubert return (-1);
146*7f2fe78bSCy Schubert }
147*7f2fe78bSCy Schubert return (kdb2_dbm_store(__cur_db, key, dat, DBM_REPLACE));
148*7f2fe78bSCy Schubert }
149*7f2fe78bSCy Schubert
150*7f2fe78bSCy Schubert static void
no_open_db()151*7f2fe78bSCy Schubert no_open_db()
152*7f2fe78bSCy Schubert {
153*7f2fe78bSCy Schubert (void)fprintf(stderr, "dbm: no open database.\n");
154*7f2fe78bSCy Schubert }
155*7f2fe78bSCy Schubert
156*7f2fe78bSCy Schubert /*
157*7f2fe78bSCy Schubert * Returns:
158*7f2fe78bSCy Schubert * *DBM on success
159*7f2fe78bSCy Schubert * NULL on failure
160*7f2fe78bSCy Schubert */
161*7f2fe78bSCy Schubert DBM *
kdb2_dbm_open(file,flags,mode)162*7f2fe78bSCy Schubert kdb2_dbm_open(file, flags, mode)
163*7f2fe78bSCy Schubert const char *file;
164*7f2fe78bSCy Schubert int flags, mode;
165*7f2fe78bSCy Schubert {
166*7f2fe78bSCy Schubert HASHINFO info;
167*7f2fe78bSCy Schubert char path[MAXPATHLEN];
168*7f2fe78bSCy Schubert
169*7f2fe78bSCy Schubert info.bsize = 4096;
170*7f2fe78bSCy Schubert info.ffactor = 40;
171*7f2fe78bSCy Schubert info.nelem = 1;
172*7f2fe78bSCy Schubert info.cachesize = 0;
173*7f2fe78bSCy Schubert info.hash = NULL;
174*7f2fe78bSCy Schubert info.lorder = 0;
175*7f2fe78bSCy Schubert (void)strncpy(path, file, sizeof(path) - 1);
176*7f2fe78bSCy Schubert path[sizeof(path) - 1] = '\0';
177*7f2fe78bSCy Schubert (void)strncat(path, DBM_SUFFIX, sizeof(path) - 1 - strlen(path));
178*7f2fe78bSCy Schubert return ((DBM *)__hash_open(path, flags, mode, &info, 0));
179*7f2fe78bSCy Schubert }
180*7f2fe78bSCy Schubert
181*7f2fe78bSCy Schubert /*
182*7f2fe78bSCy Schubert * Returns:
183*7f2fe78bSCy Schubert * Nothing.
184*7f2fe78bSCy Schubert */
185*7f2fe78bSCy Schubert void
kdb2_dbm_close(db)186*7f2fe78bSCy Schubert kdb2_dbm_close(db)
187*7f2fe78bSCy Schubert DBM *db;
188*7f2fe78bSCy Schubert {
189*7f2fe78bSCy Schubert (void)(db->close)(db);
190*7f2fe78bSCy Schubert }
191*7f2fe78bSCy Schubert
192*7f2fe78bSCy Schubert /*
193*7f2fe78bSCy Schubert * Returns:
194*7f2fe78bSCy Schubert * DATUM on success
195*7f2fe78bSCy Schubert * NULL on failure
196*7f2fe78bSCy Schubert */
197*7f2fe78bSCy Schubert datum
kdb2_dbm_fetch(db,key)198*7f2fe78bSCy Schubert kdb2_dbm_fetch(db, key)
199*7f2fe78bSCy Schubert DBM *db;
200*7f2fe78bSCy Schubert datum key;
201*7f2fe78bSCy Schubert {
202*7f2fe78bSCy Schubert datum retval;
203*7f2fe78bSCy Schubert int status;
204*7f2fe78bSCy Schubert
205*7f2fe78bSCy Schubert #ifdef NEED_COPY
206*7f2fe78bSCy Schubert DBT k, r;
207*7f2fe78bSCy Schubert
208*7f2fe78bSCy Schubert k.data = key.dptr;
209*7f2fe78bSCy Schubert k.size = key.dsize;
210*7f2fe78bSCy Schubert status = (db->get)(db, &k, &r, 0);
211*7f2fe78bSCy Schubert retval.dptr = r.data;
212*7f2fe78bSCy Schubert retval.dsize = r.size;
213*7f2fe78bSCy Schubert #else
214*7f2fe78bSCy Schubert status = (db->get)(db, (DBT *)&key, (DBT *)&retval, 0);
215*7f2fe78bSCy Schubert #endif
216*7f2fe78bSCy Schubert if (status) {
217*7f2fe78bSCy Schubert retval.dptr = NULL;
218*7f2fe78bSCy Schubert retval.dsize = 0;
219*7f2fe78bSCy Schubert }
220*7f2fe78bSCy Schubert return (retval);
221*7f2fe78bSCy Schubert }
222*7f2fe78bSCy Schubert
223*7f2fe78bSCy Schubert /*
224*7f2fe78bSCy Schubert * Returns:
225*7f2fe78bSCy Schubert * DATUM on success
226*7f2fe78bSCy Schubert * NULL on failure
227*7f2fe78bSCy Schubert */
228*7f2fe78bSCy Schubert datum
kdb2_dbm_firstkey(db)229*7f2fe78bSCy Schubert kdb2_dbm_firstkey(db)
230*7f2fe78bSCy Schubert DBM *db;
231*7f2fe78bSCy Schubert {
232*7f2fe78bSCy Schubert int status;
233*7f2fe78bSCy Schubert datum retkey;
234*7f2fe78bSCy Schubert
235*7f2fe78bSCy Schubert #ifdef NEED_COPY
236*7f2fe78bSCy Schubert DBT k, r;
237*7f2fe78bSCy Schubert
238*7f2fe78bSCy Schubert status = (db->seq)(db, &k, &r, R_FIRST);
239*7f2fe78bSCy Schubert retkey.dptr = k.data;
240*7f2fe78bSCy Schubert retkey.dsize = k.size;
241*7f2fe78bSCy Schubert #else
242*7f2fe78bSCy Schubert datum retdata;
243*7f2fe78bSCy Schubert
244*7f2fe78bSCy Schubert status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST);
245*7f2fe78bSCy Schubert #endif
246*7f2fe78bSCy Schubert if (status)
247*7f2fe78bSCy Schubert retkey.dptr = NULL;
248*7f2fe78bSCy Schubert return (retkey);
249*7f2fe78bSCy Schubert }
250*7f2fe78bSCy Schubert
251*7f2fe78bSCy Schubert /*
252*7f2fe78bSCy Schubert * Returns:
253*7f2fe78bSCy Schubert * DATUM on success
254*7f2fe78bSCy Schubert * NULL on failure
255*7f2fe78bSCy Schubert */
256*7f2fe78bSCy Schubert datum
kdb2_dbm_nextkey(db)257*7f2fe78bSCy Schubert kdb2_dbm_nextkey(db)
258*7f2fe78bSCy Schubert DBM *db;
259*7f2fe78bSCy Schubert {
260*7f2fe78bSCy Schubert int status;
261*7f2fe78bSCy Schubert datum retkey;
262*7f2fe78bSCy Schubert
263*7f2fe78bSCy Schubert #ifdef NEED_COPY
264*7f2fe78bSCy Schubert DBT k, r;
265*7f2fe78bSCy Schubert
266*7f2fe78bSCy Schubert status = (db->seq)(db, &k, &r, R_NEXT);
267*7f2fe78bSCy Schubert retkey.dptr = k.data;
268*7f2fe78bSCy Schubert retkey.dsize = k.size;
269*7f2fe78bSCy Schubert #else
270*7f2fe78bSCy Schubert datum retdata;
271*7f2fe78bSCy Schubert
272*7f2fe78bSCy Schubert status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT);
273*7f2fe78bSCy Schubert #endif
274*7f2fe78bSCy Schubert if (status)
275*7f2fe78bSCy Schubert retkey.dptr = NULL;
276*7f2fe78bSCy Schubert return (retkey);
277*7f2fe78bSCy Schubert }
278*7f2fe78bSCy Schubert
279*7f2fe78bSCy Schubert /*
280*7f2fe78bSCy Schubert * Returns:
281*7f2fe78bSCy Schubert * 0 on success
282*7f2fe78bSCy Schubert * <0 failure
283*7f2fe78bSCy Schubert */
284*7f2fe78bSCy Schubert int
kdb2_dbm_delete(db,key)285*7f2fe78bSCy Schubert kdb2_dbm_delete(db, key)
286*7f2fe78bSCy Schubert DBM *db;
287*7f2fe78bSCy Schubert datum key;
288*7f2fe78bSCy Schubert {
289*7f2fe78bSCy Schubert int status;
290*7f2fe78bSCy Schubert
291*7f2fe78bSCy Schubert #ifdef NEED_COPY
292*7f2fe78bSCy Schubert DBT k;
293*7f2fe78bSCy Schubert
294*7f2fe78bSCy Schubert k.data = key.dptr;
295*7f2fe78bSCy Schubert k.size = key.dsize;
296*7f2fe78bSCy Schubert status = (db->del)(db, &k, 0);
297*7f2fe78bSCy Schubert #else
298*7f2fe78bSCy Schubert status = (db->del)(db, (DBT *)&key, 0);
299*7f2fe78bSCy Schubert #endif
300*7f2fe78bSCy Schubert if (status)
301*7f2fe78bSCy Schubert return (-1);
302*7f2fe78bSCy Schubert else
303*7f2fe78bSCy Schubert return (0);
304*7f2fe78bSCy Schubert }
305*7f2fe78bSCy Schubert
306*7f2fe78bSCy Schubert /*
307*7f2fe78bSCy Schubert * Returns:
308*7f2fe78bSCy Schubert * 0 on success
309*7f2fe78bSCy Schubert * <0 failure
310*7f2fe78bSCy Schubert * 1 if DBM_INSERT and entry exists
311*7f2fe78bSCy Schubert */
312*7f2fe78bSCy Schubert int
kdb2_dbm_store(db,key,content,flags)313*7f2fe78bSCy Schubert kdb2_dbm_store(db, key, content, flags)
314*7f2fe78bSCy Schubert DBM *db;
315*7f2fe78bSCy Schubert datum key, content;
316*7f2fe78bSCy Schubert int flags;
317*7f2fe78bSCy Schubert {
318*7f2fe78bSCy Schubert #ifdef NEED_COPY
319*7f2fe78bSCy Schubert DBT k, c;
320*7f2fe78bSCy Schubert
321*7f2fe78bSCy Schubert k.data = key.dptr;
322*7f2fe78bSCy Schubert k.size = key.dsize;
323*7f2fe78bSCy Schubert c.data = content.dptr;
324*7f2fe78bSCy Schubert c.size = content.dsize;
325*7f2fe78bSCy Schubert return ((db->put)(db, &k, &c,
326*7f2fe78bSCy Schubert (flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
327*7f2fe78bSCy Schubert #else
328*7f2fe78bSCy Schubert return ((db->put)(db, (DBT *)&key, (DBT *)&content,
329*7f2fe78bSCy Schubert (flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
330*7f2fe78bSCy Schubert #endif
331*7f2fe78bSCy Schubert }
332*7f2fe78bSCy Schubert
333*7f2fe78bSCy Schubert int
kdb2_dbm_error(db)334*7f2fe78bSCy Schubert kdb2_dbm_error(db)
335*7f2fe78bSCy Schubert DBM *db;
336*7f2fe78bSCy Schubert {
337*7f2fe78bSCy Schubert HTAB *hp;
338*7f2fe78bSCy Schubert
339*7f2fe78bSCy Schubert hp = (HTAB *)db->internal;
340*7f2fe78bSCy Schubert return (hp->local_errno);
341*7f2fe78bSCy Schubert }
342*7f2fe78bSCy Schubert
343*7f2fe78bSCy Schubert int
kdb2_dbm_clearerr(db)344*7f2fe78bSCy Schubert kdb2_dbm_clearerr(db)
345*7f2fe78bSCy Schubert DBM *db;
346*7f2fe78bSCy Schubert {
347*7f2fe78bSCy Schubert HTAB *hp;
348*7f2fe78bSCy Schubert
349*7f2fe78bSCy Schubert hp = (HTAB *)db->internal;
350*7f2fe78bSCy Schubert hp->local_errno = 0;
351*7f2fe78bSCy Schubert return (0);
352*7f2fe78bSCy Schubert }
353*7f2fe78bSCy Schubert
354*7f2fe78bSCy Schubert int
kdb2_dbm_dirfno(db)355*7f2fe78bSCy Schubert kdb2_dbm_dirfno(db)
356*7f2fe78bSCy Schubert DBM *db;
357*7f2fe78bSCy Schubert {
358*7f2fe78bSCy Schubert return(((HTAB *)db->internal)->fp);
359*7f2fe78bSCy Schubert }
360