2 * See the file LICENSE for redistribution information.
4 * Copyright (c) 1996, 1997, 1998
5 * Sleepycat Software. All rights reserved.
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
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
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
50 static const char sccsid
[] = "@(#)dbm.c 10.16 (Sleepycat) 5/7/98";
53 #ifndef NO_SYSTEM_INCLUDES
54 #include <sys/types.h>
61 #define DB_DBM_HSEARCH 1
69 * This package provides dbm and ndbm compatible interfaces to DB.
71 * The DBM routines, which call the NDBM routines.
75 static void __db_no_open
__P((void));
82 (void)dbm_close(__cur_db
);
84 dbm_open(file
, O_CREAT
| O_RDWR
, __db_omode("rw----"))) != NULL
)
86 if ((__cur_db
= dbm_open(file
, O_RDONLY
, 0)) != NULL
)
90 weak_alias (__db_dbm_init
, dbminit
)
98 if (__cur_db
== NULL
) {
103 return (dbm_fetch(__cur_db
, key
));
105 weak_alias (__db_dbm_fetch
, fetch
)
112 if (__cur_db
== NULL
) {
117 return (dbm_firstkey(__cur_db
));
120 weak_alias (__db_dbm_firstkey
, firstkey
)
123 __db_dbm_nextkey(key
)
128 COMPQUIET(key
.dsize
, 0);
130 if (__cur_db
== NULL
) {
135 return (dbm_nextkey(__cur_db
));
137 weak_alias (__db_dbm_nextkey
, nextkey
)
145 if (__cur_db
== NULL
) {
149 ret
= dbm_delete(__cur_db
, key
);
151 ret
= (((DB
*)__cur_db
)->sync
)((DB
*)__cur_db
, 0);
154 weak_alias (__db_dbm_delete
, delete)
157 __db_dbm_store(key
, dat
)
162 if (__cur_db
== NULL
) {
166 ret
= dbm_store(__cur_db
, key
, dat
, DBM_REPLACE
);
168 ret
= (((DB
*)__cur_db
)->sync
)((DB
*)__cur_db
, 0);
171 weak_alias (__db_dbm_store
, store
)
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.
190 __db_ndbm_open(file
, oflags
, mode
)
196 char path
[MAXPATHLEN
];
198 memset(&dbinfo
, 0, sizeof(dbinfo
));
199 dbinfo
.db_pagesize
= 4096;
200 dbinfo
.h_ffactor
= 40;
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
;
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)
220 weak_alias (__db_ndbm_open
, dbm_open
)
230 (void)db
->close(db
, 0);
232 weak_alias (__db_ndbm_close
, dbm_close
)
240 __db_ndbm_fetch(db
, key
)
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
;
258 __set_errno (ret
== DB_NOTFOUND
? ENOENT
: ret
);
262 weak_alias (__db_ndbm_fetch
, dbm_fetch
)
270 __db_ndbm_firstkey(db
)
279 if ((cp
= TAILQ_FIRST(&db
->curs_queue
)) == NULL
)
280 if ((errno
= db
->cursor(db
, NULL
, &cp
)) != 0) {
281 memset(&key
, 0, sizeof(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
;
293 __set_errno (ret
== DB_NOTFOUND
? ENOENT
: ret
);
297 weak_alias (__db_ndbm_firstkey
, dbm_firstkey
)
305 __db_ndbm_nextkey(db
)
313 if ((cp
= TAILQ_FIRST(&db
->curs_queue
)) == NULL
)
314 if ((errno
= db
->cursor(db
, NULL
, &cp
)) != 0) {
315 memset(&key
, 0, sizeof(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
;
327 __set_errno (ret
== DB_NOTFOUND
? ENOENT
: ret
);
331 weak_alias (__db_ndbm_nextkey
, dbm_nextkey
)
339 __db_ndbm_delete(db
, key
)
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)
351 errno
= ret
== DB_NOTFOUND
? ENOENT
: ret
;
354 weak_alias (__db_ndbm_delete
, dbm_delete
)
360 * 1 if DBM_INSERT and entry exists
363 __db_ndbm_store(db
, key
, data
, flags
)
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)
380 if (ret
== DB_KEYEXIST
)
385 weak_alias (__db_ndbm_store
, dbm_store
)
393 hp
= (HTAB
*)db
->internal
;
394 return (hp
->local_errno
);
396 weak_alias (__db_ndbm_error
, dbm_error
)
399 __db_ndbm_clearerr(db
)
404 hp
= (HTAB
*)db
->internal
;
408 weak_alias (__db_ndbm_clearerr
, dbm_clearerr
)
419 return (F_ISSET((DB
*)db
, DB_AM_RDONLY
) ? 1 : 0);
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.
434 (void)db
->fd(db
, &fd
);
437 weak_alias (__db_ndbm_dirfno
, dbm_dirfno
)
445 (void)db
->fd(db
, &fd
);
448 weak_alias (__db_ndbm_pagfno
, dbm_pagfno
)