1*7c478bd9Sstevel@tonic-gate /*- 2*7c478bd9Sstevel@tonic-gate * See the file LICENSE for redistribution information. 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * Copyright (c) 1996, 1997, 1998 5*7c478bd9Sstevel@tonic-gate * Sleepycat Software. All rights reserved. 6*7c478bd9Sstevel@tonic-gate */ 7*7c478bd9Sstevel@tonic-gate /* 8*7c478bd9Sstevel@tonic-gate * Copyright (c) 1990, 1993 9*7c478bd9Sstevel@tonic-gate * Margo Seltzer. All rights reserved. 10*7c478bd9Sstevel@tonic-gate */ 11*7c478bd9Sstevel@tonic-gate /* 12*7c478bd9Sstevel@tonic-gate * Copyright (c) 1990, 1993 13*7c478bd9Sstevel@tonic-gate * The Regents of the University of California. All rights reserved. 14*7c478bd9Sstevel@tonic-gate * 15*7c478bd9Sstevel@tonic-gate * This code is derived from software contributed to Berkeley by 16*7c478bd9Sstevel@tonic-gate * Margo Seltzer. 17*7c478bd9Sstevel@tonic-gate * 18*7c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 19*7c478bd9Sstevel@tonic-gate * modification, are permitted provided that the following conditions 20*7c478bd9Sstevel@tonic-gate * are met: 21*7c478bd9Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 22*7c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 23*7c478bd9Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 24*7c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 25*7c478bd9Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 26*7c478bd9Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 27*7c478bd9Sstevel@tonic-gate * must display the following acknowledgement: 28*7c478bd9Sstevel@tonic-gate * This product includes software developed by the University of 29*7c478bd9Sstevel@tonic-gate * California, Berkeley and its contributors. 30*7c478bd9Sstevel@tonic-gate * 4. Neither the name of the University nor the names of its contributors 31*7c478bd9Sstevel@tonic-gate * may be used to endorse or promote products derived from this software 32*7c478bd9Sstevel@tonic-gate * without specific prior written permission. 33*7c478bd9Sstevel@tonic-gate * 34*7c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 35*7c478bd9Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36*7c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 37*7c478bd9Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 38*7c478bd9Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 39*7c478bd9Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 40*7c478bd9Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 41*7c478bd9Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 42*7c478bd9Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 43*7c478bd9Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 44*7c478bd9Sstevel@tonic-gate * SUCH DAMAGE. 45*7c478bd9Sstevel@tonic-gate */ 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate #include "config.h" 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate #ifndef lint 50*7c478bd9Sstevel@tonic-gate static const char sccsid[] = "@(#)dbm.c 10.23 (Sleepycat) 11/22/98"; 51*7c478bd9Sstevel@tonic-gate #endif /* not lint */ 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate #ifndef NO_SYSTEM_INCLUDES 54*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate #include <errno.h> 57*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 58*7c478bd9Sstevel@tonic-gate #include <string.h> 59*7c478bd9Sstevel@tonic-gate #endif 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate #define DB_DBM_HSEARCH 1 62*7c478bd9Sstevel@tonic-gate #include "db_int.h" 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate #include "db_page.h" 65*7c478bd9Sstevel@tonic-gate #include "hash.h" 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate /* 68*7c478bd9Sstevel@tonic-gate * 69*7c478bd9Sstevel@tonic-gate * This package provides dbm and ndbm compatible interfaces to DB. 70*7c478bd9Sstevel@tonic-gate * 71*7c478bd9Sstevel@tonic-gate * The DBM routines, which call the NDBM routines. 72*7c478bd9Sstevel@tonic-gate */ 73*7c478bd9Sstevel@tonic-gate static DBM *__cur_db; 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate static void __db_no_open __P((void)); 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate int 78*7c478bd9Sstevel@tonic-gate __db_dbm_init(file) 79*7c478bd9Sstevel@tonic-gate char *file; 80*7c478bd9Sstevel@tonic-gate { 81*7c478bd9Sstevel@tonic-gate if (__cur_db != NULL) 82*7c478bd9Sstevel@tonic-gate (void)dbm_close(__cur_db); 83*7c478bd9Sstevel@tonic-gate if ((__cur_db = 84*7c478bd9Sstevel@tonic-gate dbm_open(file, O_CREAT | O_RDWR, __db_omode("rw----"))) != NULL) 85*7c478bd9Sstevel@tonic-gate return (0); 86*7c478bd9Sstevel@tonic-gate if ((__cur_db = dbm_open(file, O_RDONLY, 0)) != NULL) 87*7c478bd9Sstevel@tonic-gate return (0); 88*7c478bd9Sstevel@tonic-gate return (-1); 89*7c478bd9Sstevel@tonic-gate } 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate int 92*7c478bd9Sstevel@tonic-gate __db_dbm_close() 93*7c478bd9Sstevel@tonic-gate { 94*7c478bd9Sstevel@tonic-gate if (__cur_db != NULL) { 95*7c478bd9Sstevel@tonic-gate dbm_close(__cur_db); 96*7c478bd9Sstevel@tonic-gate __cur_db = NULL; 97*7c478bd9Sstevel@tonic-gate } 98*7c478bd9Sstevel@tonic-gate return (0); 99*7c478bd9Sstevel@tonic-gate } 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate datum 102*7c478bd9Sstevel@tonic-gate __db_dbm_fetch(key) 103*7c478bd9Sstevel@tonic-gate datum key; 104*7c478bd9Sstevel@tonic-gate { 105*7c478bd9Sstevel@tonic-gate datum item; 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate if (__cur_db == NULL) { 108*7c478bd9Sstevel@tonic-gate __db_no_open(); 109*7c478bd9Sstevel@tonic-gate item.dptr = 0; 110*7c478bd9Sstevel@tonic-gate return (item); 111*7c478bd9Sstevel@tonic-gate } 112*7c478bd9Sstevel@tonic-gate return (dbm_fetch(__cur_db, key)); 113*7c478bd9Sstevel@tonic-gate } 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate datum 116*7c478bd9Sstevel@tonic-gate __db_dbm_firstkey() 117*7c478bd9Sstevel@tonic-gate { 118*7c478bd9Sstevel@tonic-gate datum item; 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate if (__cur_db == NULL) { 121*7c478bd9Sstevel@tonic-gate __db_no_open(); 122*7c478bd9Sstevel@tonic-gate item.dptr = 0; 123*7c478bd9Sstevel@tonic-gate return (item); 124*7c478bd9Sstevel@tonic-gate } 125*7c478bd9Sstevel@tonic-gate return (dbm_firstkey(__cur_db)); 126*7c478bd9Sstevel@tonic-gate } 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate datum 129*7c478bd9Sstevel@tonic-gate __db_dbm_nextkey(key) 130*7c478bd9Sstevel@tonic-gate datum key; 131*7c478bd9Sstevel@tonic-gate { 132*7c478bd9Sstevel@tonic-gate datum item; 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate COMPQUIET(key.dsize, 0); 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate if (__cur_db == NULL) { 137*7c478bd9Sstevel@tonic-gate __db_no_open(); 138*7c478bd9Sstevel@tonic-gate item.dptr = 0; 139*7c478bd9Sstevel@tonic-gate return (item); 140*7c478bd9Sstevel@tonic-gate } 141*7c478bd9Sstevel@tonic-gate return (dbm_nextkey(__cur_db)); 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate int 145*7c478bd9Sstevel@tonic-gate __db_dbm_delete(key) 146*7c478bd9Sstevel@tonic-gate datum key; 147*7c478bd9Sstevel@tonic-gate { 148*7c478bd9Sstevel@tonic-gate if (__cur_db == NULL) { 149*7c478bd9Sstevel@tonic-gate __db_no_open(); 150*7c478bd9Sstevel@tonic-gate return (-1); 151*7c478bd9Sstevel@tonic-gate } 152*7c478bd9Sstevel@tonic-gate return (dbm_delete(__cur_db, key)); 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate int 156*7c478bd9Sstevel@tonic-gate __db_dbm_store(key, dat) 157*7c478bd9Sstevel@tonic-gate datum key, dat; 158*7c478bd9Sstevel@tonic-gate { 159*7c478bd9Sstevel@tonic-gate if (__cur_db == NULL) { 160*7c478bd9Sstevel@tonic-gate __db_no_open(); 161*7c478bd9Sstevel@tonic-gate return (-1); 162*7c478bd9Sstevel@tonic-gate } 163*7c478bd9Sstevel@tonic-gate return (dbm_store(__cur_db, key, dat, DBM_REPLACE)); 164*7c478bd9Sstevel@tonic-gate } 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate static void 167*7c478bd9Sstevel@tonic-gate __db_no_open() 168*7c478bd9Sstevel@tonic-gate { 169*7c478bd9Sstevel@tonic-gate (void)fprintf(stderr, "dbm: no open database.\n"); 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate /* 173*7c478bd9Sstevel@tonic-gate * This package provides dbm and ndbm compatible interfaces to DB. 174*7c478bd9Sstevel@tonic-gate * 175*7c478bd9Sstevel@tonic-gate * The NDBM routines, which call the DB routines. 176*7c478bd9Sstevel@tonic-gate */ 177*7c478bd9Sstevel@tonic-gate /* 178*7c478bd9Sstevel@tonic-gate * Returns: 179*7c478bd9Sstevel@tonic-gate * *DBM on success 180*7c478bd9Sstevel@tonic-gate * NULL on failure 181*7c478bd9Sstevel@tonic-gate */ 182*7c478bd9Sstevel@tonic-gate DBM * 183*7c478bd9Sstevel@tonic-gate __db_ndbm_open(file, oflags, mode) 184*7c478bd9Sstevel@tonic-gate const char *file; 185*7c478bd9Sstevel@tonic-gate int oflags, mode; 186*7c478bd9Sstevel@tonic-gate { 187*7c478bd9Sstevel@tonic-gate DB *dbp; 188*7c478bd9Sstevel@tonic-gate DBC *dbc; 189*7c478bd9Sstevel@tonic-gate DB_INFO dbinfo; 190*7c478bd9Sstevel@tonic-gate int sv_errno; 191*7c478bd9Sstevel@tonic-gate char path[MAXPATHLEN]; 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate memset(&dbinfo, 0, sizeof(dbinfo)); 194*7c478bd9Sstevel@tonic-gate dbinfo.db_pagesize = 4096; 195*7c478bd9Sstevel@tonic-gate dbinfo.h_ffactor = 40; 196*7c478bd9Sstevel@tonic-gate dbinfo.h_nelem = 1; 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate /* 199*7c478bd9Sstevel@tonic-gate * XXX 200*7c478bd9Sstevel@tonic-gate * Don't use sprintf(3)/snprintf(3) -- the former is dangerous, and 201*7c478bd9Sstevel@tonic-gate * the latter isn't standard, and we're manipulating strings handed 202*7c478bd9Sstevel@tonic-gate * us by the application. 203*7c478bd9Sstevel@tonic-gate */ 204*7c478bd9Sstevel@tonic-gate if (strlen(file) + strlen(DBM_SUFFIX) + 1 > sizeof(path)) { 205*7c478bd9Sstevel@tonic-gate errno = ENAMETOOLONG; 206*7c478bd9Sstevel@tonic-gate return (NULL); 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate (void)strcpy(path, file); 209*7c478bd9Sstevel@tonic-gate (void)strcat(path, DBM_SUFFIX); 210*7c478bd9Sstevel@tonic-gate if ((errno = db_open(path, 211*7c478bd9Sstevel@tonic-gate DB_HASH, __db_oflags(oflags), mode, NULL, &dbinfo, &dbp)) != 0) 212*7c478bd9Sstevel@tonic-gate return (NULL); 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate if ((errno = dbp->cursor(dbp, NULL, &dbc, 0)) != 0) { 215*7c478bd9Sstevel@tonic-gate sv_errno = errno; 216*7c478bd9Sstevel@tonic-gate (void)dbp->close(dbp, 0); 217*7c478bd9Sstevel@tonic-gate errno = sv_errno; 218*7c478bd9Sstevel@tonic-gate return (NULL); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate return ((DBM *)dbc); 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate /* 225*7c478bd9Sstevel@tonic-gate * Returns: 226*7c478bd9Sstevel@tonic-gate * Nothing. 227*7c478bd9Sstevel@tonic-gate */ 228*7c478bd9Sstevel@tonic-gate void 229*7c478bd9Sstevel@tonic-gate __db_ndbm_close(dbm) 230*7c478bd9Sstevel@tonic-gate DBM *dbm; 231*7c478bd9Sstevel@tonic-gate { 232*7c478bd9Sstevel@tonic-gate DBC *dbc; 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate dbc = (DBC *)dbm; 235*7c478bd9Sstevel@tonic-gate 236*7c478bd9Sstevel@tonic-gate (void)dbc->dbp->close(dbc->dbp, 0); 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate /* 240*7c478bd9Sstevel@tonic-gate * Returns: 241*7c478bd9Sstevel@tonic-gate * DATUM on success 242*7c478bd9Sstevel@tonic-gate * NULL on failure 243*7c478bd9Sstevel@tonic-gate */ 244*7c478bd9Sstevel@tonic-gate datum 245*7c478bd9Sstevel@tonic-gate __db_ndbm_fetch(dbm, key) 246*7c478bd9Sstevel@tonic-gate DBM *dbm; 247*7c478bd9Sstevel@tonic-gate datum key; 248*7c478bd9Sstevel@tonic-gate { 249*7c478bd9Sstevel@tonic-gate DBC *dbc; 250*7c478bd9Sstevel@tonic-gate DBT _key, _data; 251*7c478bd9Sstevel@tonic-gate datum data; 252*7c478bd9Sstevel@tonic-gate int ret; 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate dbc = (DBC *)dbm; 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate memset(&_key, 0, sizeof(DBT)); 257*7c478bd9Sstevel@tonic-gate memset(&_data, 0, sizeof(DBT)); 258*7c478bd9Sstevel@tonic-gate _key.size = key.dsize; 259*7c478bd9Sstevel@tonic-gate _key.data = key.dptr; 260*7c478bd9Sstevel@tonic-gate 261*7c478bd9Sstevel@tonic-gate /* 262*7c478bd9Sstevel@tonic-gate * Note that we can't simply use the dbc we have to do a c_get/SET, 263*7c478bd9Sstevel@tonic-gate * because that cursor is the one used for sequential iteration and 264*7c478bd9Sstevel@tonic-gate * it has to remain stable in the face of intervening gets and puts. 265*7c478bd9Sstevel@tonic-gate */ 266*7c478bd9Sstevel@tonic-gate if ((ret = dbc->dbp->get(dbc->dbp, NULL, &_key, &_data, 0)) == 0) { 267*7c478bd9Sstevel@tonic-gate data.dptr = _data.data; 268*7c478bd9Sstevel@tonic-gate data.dsize = _data.size; 269*7c478bd9Sstevel@tonic-gate } else { 270*7c478bd9Sstevel@tonic-gate data.dptr = NULL; 271*7c478bd9Sstevel@tonic-gate data.dsize = 0; 272*7c478bd9Sstevel@tonic-gate if (ret == DB_NOTFOUND) 273*7c478bd9Sstevel@tonic-gate errno = ENOENT; 274*7c478bd9Sstevel@tonic-gate else { 275*7c478bd9Sstevel@tonic-gate errno = ret; 276*7c478bd9Sstevel@tonic-gate F_SET(dbc->dbp, DB_DBM_ERROR); 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate return (data); 280*7c478bd9Sstevel@tonic-gate } 281*7c478bd9Sstevel@tonic-gate 282*7c478bd9Sstevel@tonic-gate /* 283*7c478bd9Sstevel@tonic-gate * Returns: 284*7c478bd9Sstevel@tonic-gate * DATUM on success 285*7c478bd9Sstevel@tonic-gate * NULL on failure 286*7c478bd9Sstevel@tonic-gate */ 287*7c478bd9Sstevel@tonic-gate datum 288*7c478bd9Sstevel@tonic-gate __db_ndbm_firstkey(dbm) 289*7c478bd9Sstevel@tonic-gate DBM *dbm; 290*7c478bd9Sstevel@tonic-gate { 291*7c478bd9Sstevel@tonic-gate DBC *dbc; 292*7c478bd9Sstevel@tonic-gate DBT _key, _data; 293*7c478bd9Sstevel@tonic-gate datum key; 294*7c478bd9Sstevel@tonic-gate int ret; 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate dbc = (DBC *)dbm; 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate memset(&_key, 0, sizeof(DBT)); 299*7c478bd9Sstevel@tonic-gate memset(&_data, 0, sizeof(DBT)); 300*7c478bd9Sstevel@tonic-gate 301*7c478bd9Sstevel@tonic-gate if ((ret = dbc->c_get(dbc, &_key, &_data, DB_FIRST)) == 0) { 302*7c478bd9Sstevel@tonic-gate key.dptr = _key.data; 303*7c478bd9Sstevel@tonic-gate key.dsize = _key.size; 304*7c478bd9Sstevel@tonic-gate } else { 305*7c478bd9Sstevel@tonic-gate key.dptr = NULL; 306*7c478bd9Sstevel@tonic-gate key.dsize = 0; 307*7c478bd9Sstevel@tonic-gate if (ret == DB_NOTFOUND) 308*7c478bd9Sstevel@tonic-gate errno = ENOENT; 309*7c478bd9Sstevel@tonic-gate else { 310*7c478bd9Sstevel@tonic-gate errno = ret; 311*7c478bd9Sstevel@tonic-gate F_SET(dbc->dbp, DB_DBM_ERROR); 312*7c478bd9Sstevel@tonic-gate } 313*7c478bd9Sstevel@tonic-gate } 314*7c478bd9Sstevel@tonic-gate return (key); 315*7c478bd9Sstevel@tonic-gate } 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate /* 318*7c478bd9Sstevel@tonic-gate * Returns: 319*7c478bd9Sstevel@tonic-gate * DATUM on success 320*7c478bd9Sstevel@tonic-gate * NULL on failure 321*7c478bd9Sstevel@tonic-gate */ 322*7c478bd9Sstevel@tonic-gate datum 323*7c478bd9Sstevel@tonic-gate __db_ndbm_nextkey(dbm) 324*7c478bd9Sstevel@tonic-gate DBM *dbm; 325*7c478bd9Sstevel@tonic-gate { 326*7c478bd9Sstevel@tonic-gate DBC *dbc; 327*7c478bd9Sstevel@tonic-gate DBT _key, _data; 328*7c478bd9Sstevel@tonic-gate datum key; 329*7c478bd9Sstevel@tonic-gate int ret; 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate dbc = (DBC *)dbm; 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate memset(&_key, 0, sizeof(DBT)); 334*7c478bd9Sstevel@tonic-gate memset(&_data, 0, sizeof(DBT)); 335*7c478bd9Sstevel@tonic-gate 336*7c478bd9Sstevel@tonic-gate if ((ret = dbc->c_get(dbc, &_key, &_data, DB_NEXT)) == 0) { 337*7c478bd9Sstevel@tonic-gate key.dptr = _key.data; 338*7c478bd9Sstevel@tonic-gate key.dsize = _key.size; 339*7c478bd9Sstevel@tonic-gate } else { 340*7c478bd9Sstevel@tonic-gate key.dptr = NULL; 341*7c478bd9Sstevel@tonic-gate key.dsize = 0; 342*7c478bd9Sstevel@tonic-gate if (ret == DB_NOTFOUND) 343*7c478bd9Sstevel@tonic-gate errno = ENOENT; 344*7c478bd9Sstevel@tonic-gate else { 345*7c478bd9Sstevel@tonic-gate errno = ret; 346*7c478bd9Sstevel@tonic-gate F_SET(dbc->dbp, DB_DBM_ERROR); 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate } 349*7c478bd9Sstevel@tonic-gate return (key); 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate /* 353*7c478bd9Sstevel@tonic-gate * Returns: 354*7c478bd9Sstevel@tonic-gate * 0 on success 355*7c478bd9Sstevel@tonic-gate * <0 failure 356*7c478bd9Sstevel@tonic-gate */ 357*7c478bd9Sstevel@tonic-gate int 358*7c478bd9Sstevel@tonic-gate __db_ndbm_delete(dbm, key) 359*7c478bd9Sstevel@tonic-gate DBM *dbm; 360*7c478bd9Sstevel@tonic-gate datum key; 361*7c478bd9Sstevel@tonic-gate { 362*7c478bd9Sstevel@tonic-gate DBC *dbc; 363*7c478bd9Sstevel@tonic-gate DBT _key; 364*7c478bd9Sstevel@tonic-gate int ret; 365*7c478bd9Sstevel@tonic-gate 366*7c478bd9Sstevel@tonic-gate dbc = (DBC *)dbm; 367*7c478bd9Sstevel@tonic-gate 368*7c478bd9Sstevel@tonic-gate memset(&_key, 0, sizeof(DBT)); 369*7c478bd9Sstevel@tonic-gate _key.data = key.dptr; 370*7c478bd9Sstevel@tonic-gate _key.size = key.dsize; 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate if ((ret = dbc->dbp->del(dbc->dbp, NULL, &_key, 0)) == 0) 373*7c478bd9Sstevel@tonic-gate return (0); 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate if (ret == DB_NOTFOUND) 376*7c478bd9Sstevel@tonic-gate errno = ENOENT; 377*7c478bd9Sstevel@tonic-gate else { 378*7c478bd9Sstevel@tonic-gate errno = ret; 379*7c478bd9Sstevel@tonic-gate F_SET(dbc->dbp, DB_DBM_ERROR); 380*7c478bd9Sstevel@tonic-gate } 381*7c478bd9Sstevel@tonic-gate return (-1); 382*7c478bd9Sstevel@tonic-gate } 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate /* 385*7c478bd9Sstevel@tonic-gate * Returns: 386*7c478bd9Sstevel@tonic-gate * 0 on success 387*7c478bd9Sstevel@tonic-gate * <0 failure 388*7c478bd9Sstevel@tonic-gate * 1 if DBM_INSERT and entry exists 389*7c478bd9Sstevel@tonic-gate */ 390*7c478bd9Sstevel@tonic-gate int 391*7c478bd9Sstevel@tonic-gate __db_ndbm_store(dbm, key, data, flags) 392*7c478bd9Sstevel@tonic-gate DBM *dbm; 393*7c478bd9Sstevel@tonic-gate datum key, data; 394*7c478bd9Sstevel@tonic-gate int flags; 395*7c478bd9Sstevel@tonic-gate { 396*7c478bd9Sstevel@tonic-gate DBC *dbc; 397*7c478bd9Sstevel@tonic-gate DBT _key, _data; 398*7c478bd9Sstevel@tonic-gate int ret; 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate dbc = (DBC *)dbm; 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate memset(&_key, 0, sizeof(DBT)); 403*7c478bd9Sstevel@tonic-gate _key.data = key.dptr; 404*7c478bd9Sstevel@tonic-gate _key.size = key.dsize; 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate memset(&_data, 0, sizeof(DBT)); 407*7c478bd9Sstevel@tonic-gate _data.data = data.dptr; 408*7c478bd9Sstevel@tonic-gate _data.size = data.dsize; 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate if ((ret = dbc->dbp->put(dbc->dbp, NULL, 411*7c478bd9Sstevel@tonic-gate &_key, &_data, flags == DBM_INSERT ? DB_NOOVERWRITE : 0)) == 0) 412*7c478bd9Sstevel@tonic-gate return (0); 413*7c478bd9Sstevel@tonic-gate 414*7c478bd9Sstevel@tonic-gate if (ret == DB_KEYEXIST) 415*7c478bd9Sstevel@tonic-gate return (1); 416*7c478bd9Sstevel@tonic-gate 417*7c478bd9Sstevel@tonic-gate errno = ret; 418*7c478bd9Sstevel@tonic-gate F_SET(dbc->dbp, DB_DBM_ERROR); 419*7c478bd9Sstevel@tonic-gate return (-1); 420*7c478bd9Sstevel@tonic-gate } 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate int 423*7c478bd9Sstevel@tonic-gate __db_ndbm_error(dbm) 424*7c478bd9Sstevel@tonic-gate DBM *dbm; 425*7c478bd9Sstevel@tonic-gate { 426*7c478bd9Sstevel@tonic-gate DBC *dbc; 427*7c478bd9Sstevel@tonic-gate 428*7c478bd9Sstevel@tonic-gate dbc = (DBC *)dbm; 429*7c478bd9Sstevel@tonic-gate 430*7c478bd9Sstevel@tonic-gate return (F_ISSET(dbc->dbp, DB_DBM_ERROR)); 431*7c478bd9Sstevel@tonic-gate } 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate int 434*7c478bd9Sstevel@tonic-gate __db_ndbm_clearerr(dbm) 435*7c478bd9Sstevel@tonic-gate DBM *dbm; 436*7c478bd9Sstevel@tonic-gate { 437*7c478bd9Sstevel@tonic-gate DBC *dbc; 438*7c478bd9Sstevel@tonic-gate 439*7c478bd9Sstevel@tonic-gate dbc = (DBC *)dbm; 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate F_CLR(dbc->dbp, DB_DBM_ERROR); 442*7c478bd9Sstevel@tonic-gate return (0); 443*7c478bd9Sstevel@tonic-gate } 444*7c478bd9Sstevel@tonic-gate 445*7c478bd9Sstevel@tonic-gate /* 446*7c478bd9Sstevel@tonic-gate * Returns: 447*7c478bd9Sstevel@tonic-gate * 1 if read-only 448*7c478bd9Sstevel@tonic-gate * 0 if not read-only 449*7c478bd9Sstevel@tonic-gate */ 450*7c478bd9Sstevel@tonic-gate int 451*7c478bd9Sstevel@tonic-gate __db_ndbm_rdonly(dbm) 452*7c478bd9Sstevel@tonic-gate DBM *dbm; 453*7c478bd9Sstevel@tonic-gate { 454*7c478bd9Sstevel@tonic-gate DBC *dbc; 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate dbc = (DBC *)dbm; 457*7c478bd9Sstevel@tonic-gate 458*7c478bd9Sstevel@tonic-gate return (F_ISSET(dbc->dbp, DB_AM_RDONLY) ? 1 : 0); 459*7c478bd9Sstevel@tonic-gate } 460*7c478bd9Sstevel@tonic-gate 461*7c478bd9Sstevel@tonic-gate /* 462*7c478bd9Sstevel@tonic-gate * XXX 463*7c478bd9Sstevel@tonic-gate * We only have a single file descriptor that we can return, not two. Return 464*7c478bd9Sstevel@tonic-gate * the same one for both files. Hopefully, the user is using it for locking 465*7c478bd9Sstevel@tonic-gate * and picked one to use at random. 466*7c478bd9Sstevel@tonic-gate */ 467*7c478bd9Sstevel@tonic-gate int 468*7c478bd9Sstevel@tonic-gate __db_ndbm_dirfno(dbm) 469*7c478bd9Sstevel@tonic-gate DBM *dbm; 470*7c478bd9Sstevel@tonic-gate { 471*7c478bd9Sstevel@tonic-gate return (dbm_pagfno(dbm)); 472*7c478bd9Sstevel@tonic-gate } 473*7c478bd9Sstevel@tonic-gate 474*7c478bd9Sstevel@tonic-gate int 475*7c478bd9Sstevel@tonic-gate __db_ndbm_pagfno(dbm) 476*7c478bd9Sstevel@tonic-gate DBM *dbm; 477*7c478bd9Sstevel@tonic-gate { 478*7c478bd9Sstevel@tonic-gate DBC *dbc; 479*7c478bd9Sstevel@tonic-gate int fd; 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate dbc = (DBC *)dbm; 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate (void)dbc->dbp->fd(dbc->dbp, &fd); 484*7c478bd9Sstevel@tonic-gate return (fd); 485*7c478bd9Sstevel@tonic-gate } 486