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