Update.
[glibc.git] / db2 / dbm / dbm.c
blob261fe81ff2b3aee4834c4e606d18bcae9a6ad2cc
1 /*-
2 * See the file LICENSE for redistribution information.
4 * Copyright (c) 1996, 1997, 1998
5 * Sleepycat Software. All rights reserved.
6 */
7 /*
8 * Copyright (c) 1990, 1993
9 * Margo Seltzer. All rights reserved.
12 * Copyright (c) 1990, 1993
13 * The Regents of the University of California. All rights reserved.
15 * This code is derived from software contributed to Berkeley by
16 * Margo Seltzer.
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 * 3. All advertising materials mentioning features or use of this software
27 * must display the following acknowledgement:
28 * This product includes software developed by the University of
29 * California, Berkeley and its contributors.
30 * 4. Neither the name of the University nor the names of its contributors
31 * may be used to endorse or promote products derived from this software
32 * without specific prior written permission.
34 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
47 #include "config.h"
49 #ifndef lint
50 static const char sccsid[] = "@(#)dbm.c 10.16 (Sleepycat) 5/7/98";
51 #endif /* not lint */
53 #ifndef NO_SYSTEM_INCLUDES
54 #include <sys/types.h>
56 #include <errno.h>
57 #include <fcntl.h>
58 #include <string.h>
59 #endif
61 #define DB_DBM_HSEARCH 1
62 #include "db_int.h"
64 #include "db_page.h"
65 #include "hash.h"
69 * This package provides dbm and ndbm compatible interfaces to DB.
71 * The DBM routines, which call the NDBM routines.
73 static DBM *__cur_db;
75 static void __db_no_open __P((void));
77 int
78 __db_dbm_init(file)
79 char *file;
81 if (__cur_db != NULL)
82 (void)dbm_close(__cur_db);
83 if ((__cur_db =
84 dbm_open(file, O_CREAT | O_RDWR, __db_omode("rw----"))) != NULL)
85 return (0);
86 if ((__cur_db = dbm_open(file, O_RDONLY, 0)) != NULL)
87 return (0);
88 return (-1);
90 weak_alias (__db_dbm_init, dbminit)
92 datum
93 __db_dbm_fetch(key)
94 datum key;
96 datum item;
98 if (__cur_db == NULL) {
99 __db_no_open();
100 item.dptr = 0;
101 return (item);
103 return (dbm_fetch(__cur_db, key));
105 weak_alias (__db_dbm_fetch, fetch)
107 datum
108 __db_dbm_firstkey()
110 datum item;
112 if (__cur_db == NULL) {
113 __db_no_open();
114 item.dptr = 0;
115 return (item);
117 return (dbm_firstkey(__cur_db));
119 #undef firstkey
120 weak_alias (__db_dbm_firstkey, firstkey)
122 datum
123 __db_dbm_nextkey(key)
124 datum key;
126 datum item;
128 COMPQUIET(key.dsize, 0);
130 if (__cur_db == NULL) {
131 __db_no_open();
132 item.dptr = 0;
133 return (item);
135 return (dbm_nextkey(__cur_db));
137 weak_alias (__db_dbm_nextkey, nextkey)
140 __db_dbm_delete(key)
141 datum key;
143 int ret;
145 if (__cur_db == NULL) {
146 __db_no_open();
147 return (-1);
149 ret = dbm_delete(__cur_db, key);
150 if (ret == 0)
151 ret = (((DB *)__cur_db)->sync)((DB *)__cur_db, 0);
152 return (ret);
154 weak_alias (__db_dbm_delete, delete)
157 __db_dbm_store(key, dat)
158 datum key, dat;
160 int ret;
162 if (__cur_db == NULL) {
163 __db_no_open();
164 return (-1);
166 ret = dbm_store(__cur_db, key, dat, DBM_REPLACE);
167 if (ret == 0)
168 ret = (((DB *)__cur_db)->sync)((DB *)__cur_db, 0);
169 return (ret);
171 weak_alias (__db_dbm_store, store)
173 static void
174 __db_no_open()
176 (void)fprintf(stderr, "dbm: no open database.\n");
180 * This package provides dbm and ndbm compatible interfaces to DB.
182 * The NDBM routines, which call the DB routines.
185 * Returns:
186 * *DBM on success
187 * NULL on failure
189 DBM *
190 __db_ndbm_open(file, oflags, mode)
191 const char *file;
192 int oflags, mode;
194 DB *dbp;
195 DB_INFO dbinfo;
196 char path[MAXPATHLEN];
198 memset(&dbinfo, 0, sizeof(dbinfo));
199 dbinfo.db_pagesize = 4096;
200 dbinfo.h_ffactor = 40;
201 dbinfo.h_nelem = 1;
204 * XXX
205 * Don't use sprintf(3)/snprintf(3) -- the former is dangerous, and
206 * the latter isn't standard, and we're manipulating strings handed
207 * us by the application.
209 if (strlen(file) + strlen(DBM_SUFFIX) + 1 > sizeof(path)) {
210 errno = ENAMETOOLONG;
211 return (NULL);
213 (void)strcpy(path, file);
214 (void)strcat(path, DBM_SUFFIX);
215 if ((errno = db_open(path,
216 DB_HASH, __db_oflags(oflags), mode, NULL, &dbinfo, &dbp)) != 0)
217 return (NULL);
218 return ((DBM *)dbp);
220 weak_alias (__db_ndbm_open, dbm_open)
223 * Returns:
224 * Nothing.
226 void
227 __db_ndbm_close(db)
228 DBM *db;
230 (void)db->close(db, 0);
232 weak_alias (__db_ndbm_close, dbm_close)
235 * Returns:
236 * DATUM on success
237 * NULL on failure
239 datum
240 __db_ndbm_fetch(db, key)
241 DBM *db;
242 datum key;
244 DBT _key, _data;
245 datum data;
246 int ret;
248 memset(&_key, 0, sizeof(DBT));
249 memset(&_data, 0, sizeof(DBT));
250 _key.size = key.dsize;
251 _key.data = key.dptr;
252 if ((ret = db->get((DB *)db, NULL, &_key, &_data, 0)) == 0) {
253 data.dptr = _data.data;
254 data.dsize = _data.size;
255 } else {
256 data.dptr = NULL;
257 data.dsize = 0;
258 __set_errno (ret == DB_NOTFOUND ? ENOENT : ret);
260 return (data);
262 weak_alias (__db_ndbm_fetch, dbm_fetch)
265 * Returns:
266 * DATUM on success
267 * NULL on failure
269 datum
270 __db_ndbm_firstkey(db)
271 DBM *db;
273 DBT _key, _data;
274 datum key;
275 int ret;
277 DBC *cp;
279 if ((cp = TAILQ_FIRST(&db->curs_queue)) == NULL)
280 if ((errno = db->cursor(db, NULL, &cp)) != 0) {
281 memset(&key, 0, sizeof(key));
282 return (key);
285 memset(&_key, 0, sizeof(DBT));
286 memset(&_data, 0, sizeof(DBT));
287 if ((ret = (cp->c_get)(cp, &_key, &_data, DB_FIRST)) == 0) {
288 key.dptr = _key.data;
289 key.dsize = _key.size;
290 } else {
291 key.dptr = NULL;
292 key.dsize = 0;
293 __set_errno (ret == DB_NOTFOUND ? ENOENT : ret);
295 return (key);
297 weak_alias (__db_ndbm_firstkey, dbm_firstkey)
300 * Returns:
301 * DATUM on success
302 * NULL on failure
304 datum
305 __db_ndbm_nextkey(db)
306 DBM *db;
308 DBC *cp;
309 DBT _key, _data;
310 datum key;
311 int ret;
313 if ((cp = TAILQ_FIRST(&db->curs_queue)) == NULL)
314 if ((errno = db->cursor(db, NULL, &cp)) != 0) {
315 memset(&key, 0, sizeof(key));
316 return (key);
319 memset(&_key, 0, sizeof(DBT));
320 memset(&_data, 0, sizeof(DBT));
321 if ((ret = (cp->c_get)(cp, &_key, &_data, DB_NEXT)) == 0) {
322 key.dptr = _key.data;
323 key.dsize = _key.size;
324 } else {
325 key.dptr = NULL;
326 key.dsize = 0;
327 __set_errno (ret == DB_NOTFOUND ? ENOENT : ret);
329 return (key);
331 weak_alias (__db_ndbm_nextkey, dbm_nextkey)
334 * Returns:
335 * 0 on success
336 * <0 failure
339 __db_ndbm_delete(db, key)
340 DBM *db;
341 datum key;
343 DBT _key;
344 int ret;
346 memset(&_key, 0, sizeof(DBT));
347 _key.data = key.dptr;
348 _key.size = key.dsize;
349 if ((ret = (((DB *)db)->del)((DB *)db, NULL, &_key, 0)) == 0)
350 return (0);
351 errno = ret == DB_NOTFOUND ? ENOENT : ret;
352 return (-1);
354 weak_alias (__db_ndbm_delete, dbm_delete)
357 * Returns:
358 * 0 on success
359 * <0 failure
360 * 1 if DBM_INSERT and entry exists
363 __db_ndbm_store(db, key, data, flags)
364 DBM *db;
365 datum key, data;
366 int flags;
368 DBT _key, _data;
369 int ret;
371 memset(&_key, 0, sizeof(DBT));
372 memset(&_data, 0, sizeof(DBT));
373 _key.data = key.dptr;
374 _key.size = key.dsize;
375 _data.data = data.dptr;
376 _data.size = data.dsize;
377 if ((ret = db->put((DB *)db, NULL,
378 &_key, &_data, flags == DBM_INSERT ? DB_NOOVERWRITE : 0)) == 0)
379 return (0);
380 if (ret == DB_KEYEXIST)
381 return (1);
382 errno = ret;
383 return (-1);
385 weak_alias (__db_ndbm_store, dbm_store)
388 __db_ndbm_error(db)
389 DBM *db;
391 HTAB *hp;
393 hp = (HTAB *)db->internal;
394 return (hp->local_errno);
396 weak_alias (__db_ndbm_error, dbm_error)
399 __db_ndbm_clearerr(db)
400 DBM *db;
402 HTAB *hp;
404 hp = (HTAB *)db->internal;
405 hp->local_errno = 0;
406 return (0);
408 weak_alias (__db_ndbm_clearerr, dbm_clearerr)
411 * Returns:
412 * 1 if read-only
413 * 0 if not read-only
416 __db_ndbm_rdonly(db)
417 DBM *db;
419 return (F_ISSET((DB *)db, DB_AM_RDONLY) ? 1 : 0);
423 * XXX
424 * We only have a single file descriptor that we can return, not two. Return
425 * the same one for both files. Hopefully, the user is using it for locking
426 * and picked one to use at random.
429 __db_ndbm_dirfno(db)
430 DBM *db;
432 int fd;
434 (void)db->fd(db, &fd);
435 return (fd);
437 weak_alias (__db_ndbm_dirfno, dbm_dirfno)
440 __db_ndbm_pagfno(db)
441 DBM *db;
443 int fd;
445 (void)db->fd(db, &fd);
446 return (fd);
448 weak_alias (__db_ndbm_pagfno, dbm_pagfno)