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 #pragma ident "%Z%%M% %I% %E% SMI" 9*7c478bd9Sstevel@tonic-gate 10*7c478bd9Sstevel@tonic-gate #include "config.h" 11*7c478bd9Sstevel@tonic-gate 12*7c478bd9Sstevel@tonic-gate #ifndef lint 13*7c478bd9Sstevel@tonic-gate static const char sccsid[] = "@(#)db_iface.c 10.40 (Sleepycat) 12/19/98"; 14*7c478bd9Sstevel@tonic-gate #endif /* not lint */ 15*7c478bd9Sstevel@tonic-gate 16*7c478bd9Sstevel@tonic-gate #ifndef NO_SYSTEM_INCLUDES 17*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 18*7c478bd9Sstevel@tonic-gate 19*7c478bd9Sstevel@tonic-gate #include <errno.h> 20*7c478bd9Sstevel@tonic-gate #endif 21*7c478bd9Sstevel@tonic-gate 22*7c478bd9Sstevel@tonic-gate #include "db_int.h" 23*7c478bd9Sstevel@tonic-gate #include "db_page.h" 24*7c478bd9Sstevel@tonic-gate #include "db_auto.h" 25*7c478bd9Sstevel@tonic-gate #include "db_ext.h" 26*7c478bd9Sstevel@tonic-gate #include "common_ext.h" 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate static int __db_keyempty __P((const DB_ENV *)); 29*7c478bd9Sstevel@tonic-gate static int __db_rdonly __P((const DB_ENV *, const char *)); 30*7c478bd9Sstevel@tonic-gate static int __dbt_ferr __P((const DB *, const char *, const DBT *, int)); 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate /* 33*7c478bd9Sstevel@tonic-gate * __db_cdelchk -- 34*7c478bd9Sstevel@tonic-gate * Common cursor delete argument checking routine. 35*7c478bd9Sstevel@tonic-gate * 36*7c478bd9Sstevel@tonic-gate * PUBLIC: int __db_cdelchk __P((const DB *, u_int32_t, int, int)); 37*7c478bd9Sstevel@tonic-gate */ 38*7c478bd9Sstevel@tonic-gate int 39*7c478bd9Sstevel@tonic-gate __db_cdelchk(dbp, flags, isrdonly, isvalid) 40*7c478bd9Sstevel@tonic-gate const DB *dbp; 41*7c478bd9Sstevel@tonic-gate u_int32_t flags; 42*7c478bd9Sstevel@tonic-gate int isrdonly, isvalid; 43*7c478bd9Sstevel@tonic-gate { 44*7c478bd9Sstevel@tonic-gate /* Check for changes to a read-only tree. */ 45*7c478bd9Sstevel@tonic-gate if (isrdonly) 46*7c478bd9Sstevel@tonic-gate return (__db_rdonly(dbp->dbenv, "c_del")); 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate /* Check for invalid function flags. */ 49*7c478bd9Sstevel@tonic-gate switch (flags) { 50*7c478bd9Sstevel@tonic-gate case 0: 51*7c478bd9Sstevel@tonic-gate break; 52*7c478bd9Sstevel@tonic-gate default: 53*7c478bd9Sstevel@tonic-gate return (__db_ferr(dbp->dbenv, "DBcursor->c_del", 0)); 54*7c478bd9Sstevel@tonic-gate } 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate /* 57*7c478bd9Sstevel@tonic-gate * The cursor must be initialized, return -1 for an invalid cursor, 58*7c478bd9Sstevel@tonic-gate * otherwise 0. 59*7c478bd9Sstevel@tonic-gate */ 60*7c478bd9Sstevel@tonic-gate return (isvalid ? 0 : EINVAL); 61*7c478bd9Sstevel@tonic-gate } 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate /* 64*7c478bd9Sstevel@tonic-gate * __db_cgetchk -- 65*7c478bd9Sstevel@tonic-gate * Common cursor get argument checking routine. 66*7c478bd9Sstevel@tonic-gate * 67*7c478bd9Sstevel@tonic-gate * PUBLIC: int __db_cgetchk __P((const DB *, DBT *, DBT *, u_int32_t, int)); 68*7c478bd9Sstevel@tonic-gate */ 69*7c478bd9Sstevel@tonic-gate int 70*7c478bd9Sstevel@tonic-gate __db_cgetchk(dbp, key, data, flags, isvalid) 71*7c478bd9Sstevel@tonic-gate const DB *dbp; 72*7c478bd9Sstevel@tonic-gate DBT *key, *data; 73*7c478bd9Sstevel@tonic-gate u_int32_t flags; 74*7c478bd9Sstevel@tonic-gate int isvalid; 75*7c478bd9Sstevel@tonic-gate { 76*7c478bd9Sstevel@tonic-gate int key_einval, key_flags, ret; 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate key_einval = key_flags = 0; 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate /* Check for invalid function flags. */ 81*7c478bd9Sstevel@tonic-gate LF_CLR(DB_RMW); 82*7c478bd9Sstevel@tonic-gate switch (flags) { 83*7c478bd9Sstevel@tonic-gate case DB_NEXT_DUP: 84*7c478bd9Sstevel@tonic-gate if (dbp->type == DB_RECNO) 85*7c478bd9Sstevel@tonic-gate goto err; 86*7c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 87*7c478bd9Sstevel@tonic-gate case DB_CURRENT: 88*7c478bd9Sstevel@tonic-gate case DB_FIRST: 89*7c478bd9Sstevel@tonic-gate case DB_LAST: 90*7c478bd9Sstevel@tonic-gate case DB_NEXT: 91*7c478bd9Sstevel@tonic-gate case DB_PREV: 92*7c478bd9Sstevel@tonic-gate key_flags = 1; 93*7c478bd9Sstevel@tonic-gate break; 94*7c478bd9Sstevel@tonic-gate case DB_GET_BOTH: 95*7c478bd9Sstevel@tonic-gate case DB_SET_RANGE: 96*7c478bd9Sstevel@tonic-gate key_einval = key_flags = 1; 97*7c478bd9Sstevel@tonic-gate break; 98*7c478bd9Sstevel@tonic-gate case DB_SET: 99*7c478bd9Sstevel@tonic-gate key_einval = 1; 100*7c478bd9Sstevel@tonic-gate break; 101*7c478bd9Sstevel@tonic-gate case DB_GET_RECNO: 102*7c478bd9Sstevel@tonic-gate if (!F_ISSET(dbp, DB_BT_RECNUM)) 103*7c478bd9Sstevel@tonic-gate goto err; 104*7c478bd9Sstevel@tonic-gate break; 105*7c478bd9Sstevel@tonic-gate case DB_SET_RECNO: 106*7c478bd9Sstevel@tonic-gate if (!F_ISSET(dbp, DB_BT_RECNUM)) 107*7c478bd9Sstevel@tonic-gate goto err; 108*7c478bd9Sstevel@tonic-gate key_einval = key_flags = 1; 109*7c478bd9Sstevel@tonic-gate break; 110*7c478bd9Sstevel@tonic-gate default: 111*7c478bd9Sstevel@tonic-gate err: return (__db_ferr(dbp->dbenv, "DBcursor->c_get", 0)); 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate /* Check for invalid key/data flags. */ 115*7c478bd9Sstevel@tonic-gate if ((ret = __dbt_ferr(dbp, "key", key, 0)) != 0) 116*7c478bd9Sstevel@tonic-gate return (ret); 117*7c478bd9Sstevel@tonic-gate if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0) 118*7c478bd9Sstevel@tonic-gate return (ret); 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate /* Check for missing keys. */ 121*7c478bd9Sstevel@tonic-gate if (key_einval && (key->data == NULL || key->size == 0)) 122*7c478bd9Sstevel@tonic-gate return (__db_keyempty(dbp->dbenv)); 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate /* 125*7c478bd9Sstevel@tonic-gate * The cursor must be initialized for DB_CURRENT, return -1 for an 126*7c478bd9Sstevel@tonic-gate * invalid cursor, otherwise 0. 127*7c478bd9Sstevel@tonic-gate */ 128*7c478bd9Sstevel@tonic-gate return (isvalid || flags != DB_CURRENT ? 0 : EINVAL); 129*7c478bd9Sstevel@tonic-gate } 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate /* 132*7c478bd9Sstevel@tonic-gate * __db_cputchk -- 133*7c478bd9Sstevel@tonic-gate * Common cursor put argument checking routine. 134*7c478bd9Sstevel@tonic-gate * 135*7c478bd9Sstevel@tonic-gate * PUBLIC: int __db_cputchk __P((const DB *, 136*7c478bd9Sstevel@tonic-gate * PUBLIC: const DBT *, DBT *, u_int32_t, int, int)); 137*7c478bd9Sstevel@tonic-gate */ 138*7c478bd9Sstevel@tonic-gate int 139*7c478bd9Sstevel@tonic-gate __db_cputchk(dbp, key, data, flags, isrdonly, isvalid) 140*7c478bd9Sstevel@tonic-gate const DB *dbp; 141*7c478bd9Sstevel@tonic-gate const DBT *key; 142*7c478bd9Sstevel@tonic-gate DBT *data; 143*7c478bd9Sstevel@tonic-gate u_int32_t flags; 144*7c478bd9Sstevel@tonic-gate int isrdonly, isvalid; 145*7c478bd9Sstevel@tonic-gate { 146*7c478bd9Sstevel@tonic-gate int key_einval, key_flags, ret; 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate key_einval = key_flags = 0; 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate /* Check for changes to a read-only tree. */ 151*7c478bd9Sstevel@tonic-gate if (isrdonly) 152*7c478bd9Sstevel@tonic-gate return (__db_rdonly(dbp->dbenv, "c_put")); 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate /* Check for invalid function flags. */ 155*7c478bd9Sstevel@tonic-gate switch (flags) { 156*7c478bd9Sstevel@tonic-gate case DB_AFTER: 157*7c478bd9Sstevel@tonic-gate case DB_BEFORE: 158*7c478bd9Sstevel@tonic-gate if (dbp->dup_compare != NULL) 159*7c478bd9Sstevel@tonic-gate goto err; 160*7c478bd9Sstevel@tonic-gate if (dbp->type == DB_RECNO && !F_ISSET(dbp, DB_RE_RENUMBER)) 161*7c478bd9Sstevel@tonic-gate goto err; 162*7c478bd9Sstevel@tonic-gate if (dbp->type != DB_RECNO && !F_ISSET(dbp, DB_AM_DUP)) 163*7c478bd9Sstevel@tonic-gate goto err; 164*7c478bd9Sstevel@tonic-gate break; 165*7c478bd9Sstevel@tonic-gate case DB_CURRENT: 166*7c478bd9Sstevel@tonic-gate /* 167*7c478bd9Sstevel@tonic-gate * If there is a comparison function, doing a DB_CURRENT 168*7c478bd9Sstevel@tonic-gate * must not change the part of the data item that is used 169*7c478bd9Sstevel@tonic-gate * for the comparison. 170*7c478bd9Sstevel@tonic-gate */ 171*7c478bd9Sstevel@tonic-gate break; 172*7c478bd9Sstevel@tonic-gate case DB_KEYFIRST: 173*7c478bd9Sstevel@tonic-gate case DB_KEYLAST: 174*7c478bd9Sstevel@tonic-gate if (dbp->type == DB_RECNO) 175*7c478bd9Sstevel@tonic-gate goto err; 176*7c478bd9Sstevel@tonic-gate key_einval = key_flags = 1; 177*7c478bd9Sstevel@tonic-gate break; 178*7c478bd9Sstevel@tonic-gate default: 179*7c478bd9Sstevel@tonic-gate err: return (__db_ferr(dbp->dbenv, "DBcursor->c_put", 0)); 180*7c478bd9Sstevel@tonic-gate } 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate /* Check for invalid key/data flags. */ 183*7c478bd9Sstevel@tonic-gate if (key_flags && (ret = __dbt_ferr(dbp, "key", key, 0)) != 0) 184*7c478bd9Sstevel@tonic-gate return (ret); 185*7c478bd9Sstevel@tonic-gate if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0) 186*7c478bd9Sstevel@tonic-gate return (ret); 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate /* Check for missing keys. */ 189*7c478bd9Sstevel@tonic-gate if (key_einval && (key->data == NULL || key->size == 0)) 190*7c478bd9Sstevel@tonic-gate return (__db_keyempty(dbp->dbenv)); 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate /* 193*7c478bd9Sstevel@tonic-gate * The cursor must be initialized for anything other than DB_KEYFIRST 194*7c478bd9Sstevel@tonic-gate * and DB_KEYLAST, return -1 for an invalid cursor, otherwise 0. 195*7c478bd9Sstevel@tonic-gate */ 196*7c478bd9Sstevel@tonic-gate return (isvalid || 197*7c478bd9Sstevel@tonic-gate flags == DB_KEYFIRST || flags == DB_KEYLAST ? 0 : EINVAL); 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate /* 201*7c478bd9Sstevel@tonic-gate * __db_closechk -- 202*7c478bd9Sstevel@tonic-gate * DB->close flag check. 203*7c478bd9Sstevel@tonic-gate * 204*7c478bd9Sstevel@tonic-gate * PUBLIC: int __db_closechk __P((const DB *, u_int32_t)); 205*7c478bd9Sstevel@tonic-gate */ 206*7c478bd9Sstevel@tonic-gate int 207*7c478bd9Sstevel@tonic-gate __db_closechk(dbp, flags) 208*7c478bd9Sstevel@tonic-gate const DB *dbp; 209*7c478bd9Sstevel@tonic-gate u_int32_t flags; 210*7c478bd9Sstevel@tonic-gate { 211*7c478bd9Sstevel@tonic-gate /* Check for invalid function flags. */ 212*7c478bd9Sstevel@tonic-gate if (flags != 0 && flags != DB_NOSYNC) 213*7c478bd9Sstevel@tonic-gate return (__db_ferr(dbp->dbenv, "DB->close", 0)); 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate return (0); 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate /* 219*7c478bd9Sstevel@tonic-gate * __db_delchk -- 220*7c478bd9Sstevel@tonic-gate * Common delete argument checking routine. 221*7c478bd9Sstevel@tonic-gate * 222*7c478bd9Sstevel@tonic-gate * PUBLIC: int __db_delchk __P((const DB *, DBT *, u_int32_t, int)); 223*7c478bd9Sstevel@tonic-gate */ 224*7c478bd9Sstevel@tonic-gate int 225*7c478bd9Sstevel@tonic-gate __db_delchk(dbp, key, flags, isrdonly) 226*7c478bd9Sstevel@tonic-gate const DB *dbp; 227*7c478bd9Sstevel@tonic-gate DBT *key; 228*7c478bd9Sstevel@tonic-gate u_int32_t flags; 229*7c478bd9Sstevel@tonic-gate int isrdonly; 230*7c478bd9Sstevel@tonic-gate { 231*7c478bd9Sstevel@tonic-gate /* Check for changes to a read-only tree. */ 232*7c478bd9Sstevel@tonic-gate if (isrdonly) 233*7c478bd9Sstevel@tonic-gate return (__db_rdonly(dbp->dbenv, "delete")); 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate /* Check for invalid function flags. */ 236*7c478bd9Sstevel@tonic-gate switch (flags) { 237*7c478bd9Sstevel@tonic-gate case 0: 238*7c478bd9Sstevel@tonic-gate break; 239*7c478bd9Sstevel@tonic-gate default: 240*7c478bd9Sstevel@tonic-gate return (__db_ferr(dbp->dbenv, "DB->del", 0)); 241*7c478bd9Sstevel@tonic-gate } 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate /* Check for missing keys. */ 244*7c478bd9Sstevel@tonic-gate if (key->data == NULL || key->size == 0) 245*7c478bd9Sstevel@tonic-gate return (__db_keyempty(dbp->dbenv)); 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate return (0); 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate /* 251*7c478bd9Sstevel@tonic-gate * __db_getchk -- 252*7c478bd9Sstevel@tonic-gate * Common get argument checking routine. 253*7c478bd9Sstevel@tonic-gate * 254*7c478bd9Sstevel@tonic-gate * PUBLIC: int __db_getchk __P((const DB *, const DBT *, DBT *, u_int32_t)); 255*7c478bd9Sstevel@tonic-gate */ 256*7c478bd9Sstevel@tonic-gate int 257*7c478bd9Sstevel@tonic-gate __db_getchk(dbp, key, data, flags) 258*7c478bd9Sstevel@tonic-gate const DB *dbp; 259*7c478bd9Sstevel@tonic-gate const DBT *key; 260*7c478bd9Sstevel@tonic-gate DBT *data; 261*7c478bd9Sstevel@tonic-gate u_int32_t flags; 262*7c478bd9Sstevel@tonic-gate { 263*7c478bd9Sstevel@tonic-gate int ret; 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate /* Check for invalid function flags. */ 266*7c478bd9Sstevel@tonic-gate LF_CLR(DB_RMW); 267*7c478bd9Sstevel@tonic-gate switch (flags) { 268*7c478bd9Sstevel@tonic-gate case 0: 269*7c478bd9Sstevel@tonic-gate case DB_GET_BOTH: 270*7c478bd9Sstevel@tonic-gate break; 271*7c478bd9Sstevel@tonic-gate case DB_SET_RECNO: 272*7c478bd9Sstevel@tonic-gate if (!F_ISSET(dbp, DB_BT_RECNUM)) 273*7c478bd9Sstevel@tonic-gate goto err; 274*7c478bd9Sstevel@tonic-gate break; 275*7c478bd9Sstevel@tonic-gate default: 276*7c478bd9Sstevel@tonic-gate err: return (__db_ferr(dbp->dbenv, "DB->get", 0)); 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate /* Check for invalid key/data flags. */ 280*7c478bd9Sstevel@tonic-gate if ((ret = __dbt_ferr(dbp, "key", key, flags == DB_SET_RECNO)) != 0) 281*7c478bd9Sstevel@tonic-gate return (ret); 282*7c478bd9Sstevel@tonic-gate if ((ret = __dbt_ferr(dbp, "data", data, 1)) != 0) 283*7c478bd9Sstevel@tonic-gate return (ret); 284*7c478bd9Sstevel@tonic-gate 285*7c478bd9Sstevel@tonic-gate /* Check for missing keys. */ 286*7c478bd9Sstevel@tonic-gate if (key->data == NULL || key->size == 0) 287*7c478bd9Sstevel@tonic-gate return (__db_keyempty(dbp->dbenv)); 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate return (0); 290*7c478bd9Sstevel@tonic-gate } 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate /* 293*7c478bd9Sstevel@tonic-gate * __db_joinchk -- 294*7c478bd9Sstevel@tonic-gate * Common join argument checking routine. 295*7c478bd9Sstevel@tonic-gate * 296*7c478bd9Sstevel@tonic-gate * PUBLIC: int __db_joinchk __P((const DB *, u_int32_t)); 297*7c478bd9Sstevel@tonic-gate */ 298*7c478bd9Sstevel@tonic-gate int 299*7c478bd9Sstevel@tonic-gate __db_joinchk(dbp, flags) 300*7c478bd9Sstevel@tonic-gate const DB *dbp; 301*7c478bd9Sstevel@tonic-gate u_int32_t flags; 302*7c478bd9Sstevel@tonic-gate { 303*7c478bd9Sstevel@tonic-gate if (flags != 0) 304*7c478bd9Sstevel@tonic-gate return (__db_ferr(dbp->dbenv, "DB->join", 0)); 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate return (0); 307*7c478bd9Sstevel@tonic-gate } 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate /* 310*7c478bd9Sstevel@tonic-gate * __db_putchk -- 311*7c478bd9Sstevel@tonic-gate * Common put argument checking routine. 312*7c478bd9Sstevel@tonic-gate * 313*7c478bd9Sstevel@tonic-gate * PUBLIC: int __db_putchk 314*7c478bd9Sstevel@tonic-gate * PUBLIC: __P((const DB *, DBT *, const DBT *, u_int32_t, int, int)); 315*7c478bd9Sstevel@tonic-gate */ 316*7c478bd9Sstevel@tonic-gate int 317*7c478bd9Sstevel@tonic-gate __db_putchk(dbp, key, data, flags, isrdonly, isdup) 318*7c478bd9Sstevel@tonic-gate const DB *dbp; 319*7c478bd9Sstevel@tonic-gate DBT *key; 320*7c478bd9Sstevel@tonic-gate const DBT *data; 321*7c478bd9Sstevel@tonic-gate u_int32_t flags; 322*7c478bd9Sstevel@tonic-gate int isrdonly, isdup; 323*7c478bd9Sstevel@tonic-gate { 324*7c478bd9Sstevel@tonic-gate int ret; 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate /* Check for changes to a read-only tree. */ 327*7c478bd9Sstevel@tonic-gate if (isrdonly) 328*7c478bd9Sstevel@tonic-gate return (__db_rdonly(dbp->dbenv, "put")); 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate /* Check for invalid function flags. */ 331*7c478bd9Sstevel@tonic-gate switch (flags) { 332*7c478bd9Sstevel@tonic-gate case 0: 333*7c478bd9Sstevel@tonic-gate case DB_NOOVERWRITE: 334*7c478bd9Sstevel@tonic-gate break; 335*7c478bd9Sstevel@tonic-gate case DB_APPEND: 336*7c478bd9Sstevel@tonic-gate if (dbp->type != DB_RECNO) 337*7c478bd9Sstevel@tonic-gate goto err; 338*7c478bd9Sstevel@tonic-gate break; 339*7c478bd9Sstevel@tonic-gate default: 340*7c478bd9Sstevel@tonic-gate err: return (__db_ferr(dbp->dbenv, "DB->put", 0)); 341*7c478bd9Sstevel@tonic-gate } 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate /* Check for invalid key/data flags. */ 344*7c478bd9Sstevel@tonic-gate if ((ret = __dbt_ferr(dbp, "key", key, 0)) != 0) 345*7c478bd9Sstevel@tonic-gate return (ret); 346*7c478bd9Sstevel@tonic-gate if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0) 347*7c478bd9Sstevel@tonic-gate return (ret); 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate /* Check for missing keys. */ 350*7c478bd9Sstevel@tonic-gate if (key->data == NULL || key->size == 0) 351*7c478bd9Sstevel@tonic-gate return (__db_keyempty(dbp->dbenv)); 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate /* Check for partial puts in the presence of duplicates. */ 354*7c478bd9Sstevel@tonic-gate if (isdup && F_ISSET(data, DB_DBT_PARTIAL)) { 355*7c478bd9Sstevel@tonic-gate __db_err(dbp->dbenv, 356*7c478bd9Sstevel@tonic-gate "a partial put in the presence of duplicates requires a cursor operation"); 357*7c478bd9Sstevel@tonic-gate return (EINVAL); 358*7c478bd9Sstevel@tonic-gate } 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate return (0); 361*7c478bd9Sstevel@tonic-gate } 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate /* 364*7c478bd9Sstevel@tonic-gate * __db_statchk -- 365*7c478bd9Sstevel@tonic-gate * Common stat argument checking routine. 366*7c478bd9Sstevel@tonic-gate * 367*7c478bd9Sstevel@tonic-gate * PUBLIC: int __db_statchk __P((const DB *, u_int32_t)); 368*7c478bd9Sstevel@tonic-gate */ 369*7c478bd9Sstevel@tonic-gate int 370*7c478bd9Sstevel@tonic-gate __db_statchk(dbp, flags) 371*7c478bd9Sstevel@tonic-gate const DB *dbp; 372*7c478bd9Sstevel@tonic-gate u_int32_t flags; 373*7c478bd9Sstevel@tonic-gate { 374*7c478bd9Sstevel@tonic-gate /* Check for invalid function flags. */ 375*7c478bd9Sstevel@tonic-gate switch (flags) { 376*7c478bd9Sstevel@tonic-gate case 0: 377*7c478bd9Sstevel@tonic-gate break; 378*7c478bd9Sstevel@tonic-gate case DB_RECORDCOUNT: 379*7c478bd9Sstevel@tonic-gate if (dbp->type == DB_RECNO) 380*7c478bd9Sstevel@tonic-gate break; 381*7c478bd9Sstevel@tonic-gate if (dbp->type == DB_BTREE && F_ISSET(dbp, DB_BT_RECNUM)) 382*7c478bd9Sstevel@tonic-gate break; 383*7c478bd9Sstevel@tonic-gate goto err; 384*7c478bd9Sstevel@tonic-gate default: 385*7c478bd9Sstevel@tonic-gate err: return (__db_ferr(dbp->dbenv, "DB->stat", 0)); 386*7c478bd9Sstevel@tonic-gate } 387*7c478bd9Sstevel@tonic-gate 388*7c478bd9Sstevel@tonic-gate return (0); 389*7c478bd9Sstevel@tonic-gate } 390*7c478bd9Sstevel@tonic-gate 391*7c478bd9Sstevel@tonic-gate /* 392*7c478bd9Sstevel@tonic-gate * __db_syncchk -- 393*7c478bd9Sstevel@tonic-gate * Common sync argument checking routine. 394*7c478bd9Sstevel@tonic-gate * 395*7c478bd9Sstevel@tonic-gate * PUBLIC: int __db_syncchk __P((const DB *, u_int32_t)); 396*7c478bd9Sstevel@tonic-gate */ 397*7c478bd9Sstevel@tonic-gate int 398*7c478bd9Sstevel@tonic-gate __db_syncchk(dbp, flags) 399*7c478bd9Sstevel@tonic-gate const DB *dbp; 400*7c478bd9Sstevel@tonic-gate u_int32_t flags; 401*7c478bd9Sstevel@tonic-gate { 402*7c478bd9Sstevel@tonic-gate /* Check for invalid function flags. */ 403*7c478bd9Sstevel@tonic-gate switch (flags) { 404*7c478bd9Sstevel@tonic-gate case 0: 405*7c478bd9Sstevel@tonic-gate break; 406*7c478bd9Sstevel@tonic-gate default: 407*7c478bd9Sstevel@tonic-gate return (__db_ferr(dbp->dbenv, "DB->sync", 0)); 408*7c478bd9Sstevel@tonic-gate } 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate return (0); 411*7c478bd9Sstevel@tonic-gate } 412*7c478bd9Sstevel@tonic-gate 413*7c478bd9Sstevel@tonic-gate /* 414*7c478bd9Sstevel@tonic-gate * __dbt_ferr -- 415*7c478bd9Sstevel@tonic-gate * Check a DBT for flag errors. 416*7c478bd9Sstevel@tonic-gate */ 417*7c478bd9Sstevel@tonic-gate static int 418*7c478bd9Sstevel@tonic-gate __dbt_ferr(dbp, name, dbt, check_thread) 419*7c478bd9Sstevel@tonic-gate const DB *dbp; 420*7c478bd9Sstevel@tonic-gate const char *name; 421*7c478bd9Sstevel@tonic-gate const DBT *dbt; 422*7c478bd9Sstevel@tonic-gate int check_thread; 423*7c478bd9Sstevel@tonic-gate { 424*7c478bd9Sstevel@tonic-gate int ret; 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate /* 427*7c478bd9Sstevel@tonic-gate * Check for invalid DBT flags. We allow any of the flags to be 428*7c478bd9Sstevel@tonic-gate * specified to any DB or DBcursor call so that applications can 429*7c478bd9Sstevel@tonic-gate * set DB_DBT_MALLOC when retrieving a data item from a secondary 430*7c478bd9Sstevel@tonic-gate * database and then specify that same DBT as a key to a primary 431*7c478bd9Sstevel@tonic-gate * database, without having to clear flags. 432*7c478bd9Sstevel@tonic-gate */ 433*7c478bd9Sstevel@tonic-gate if ((ret = __db_fchk(dbp->dbenv, name, dbt->flags, 434*7c478bd9Sstevel@tonic-gate DB_DBT_MALLOC | DB_DBT_USERMEM | DB_DBT_PARTIAL)) != 0) 435*7c478bd9Sstevel@tonic-gate return (ret); 436*7c478bd9Sstevel@tonic-gate if ((ret = __db_fcchk(dbp->dbenv, name, 437*7c478bd9Sstevel@tonic-gate dbt->flags, DB_DBT_MALLOC, DB_DBT_USERMEM)) != 0) 438*7c478bd9Sstevel@tonic-gate return (ret); 439*7c478bd9Sstevel@tonic-gate 440*7c478bd9Sstevel@tonic-gate if (check_thread && F_ISSET(dbp, DB_AM_THREAD) && 441*7c478bd9Sstevel@tonic-gate !F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_USERMEM)) { 442*7c478bd9Sstevel@tonic-gate __db_err(dbp->dbenv, 443*7c478bd9Sstevel@tonic-gate "missing flag thread flag for %s DBT", name); 444*7c478bd9Sstevel@tonic-gate return (EINVAL); 445*7c478bd9Sstevel@tonic-gate } 446*7c478bd9Sstevel@tonic-gate return (0); 447*7c478bd9Sstevel@tonic-gate } 448*7c478bd9Sstevel@tonic-gate 449*7c478bd9Sstevel@tonic-gate /* 450*7c478bd9Sstevel@tonic-gate * __db_eopnotsup -- 451*7c478bd9Sstevel@tonic-gate * Common operation not supported message. 452*7c478bd9Sstevel@tonic-gate * 453*7c478bd9Sstevel@tonic-gate * PUBLIC: int __db_eopnotsup __P((const DB_ENV *)); 454*7c478bd9Sstevel@tonic-gate */ 455*7c478bd9Sstevel@tonic-gate int 456*7c478bd9Sstevel@tonic-gate __db_eopnotsup(dbenv) 457*7c478bd9Sstevel@tonic-gate const DB_ENV *dbenv; 458*7c478bd9Sstevel@tonic-gate { 459*7c478bd9Sstevel@tonic-gate __db_err(dbenv, "operation not supported"); 460*7c478bd9Sstevel@tonic-gate #ifdef EOPNOTSUPP 461*7c478bd9Sstevel@tonic-gate return (EOPNOTSUPP); 462*7c478bd9Sstevel@tonic-gate #else 463*7c478bd9Sstevel@tonic-gate return (EINVAL); 464*7c478bd9Sstevel@tonic-gate #endif 465*7c478bd9Sstevel@tonic-gate } 466*7c478bd9Sstevel@tonic-gate 467*7c478bd9Sstevel@tonic-gate /* 468*7c478bd9Sstevel@tonic-gate * __db_keyempty -- 469*7c478bd9Sstevel@tonic-gate * Common missing or empty key value message. 470*7c478bd9Sstevel@tonic-gate */ 471*7c478bd9Sstevel@tonic-gate static int 472*7c478bd9Sstevel@tonic-gate __db_keyempty(dbenv) 473*7c478bd9Sstevel@tonic-gate const DB_ENV *dbenv; 474*7c478bd9Sstevel@tonic-gate { 475*7c478bd9Sstevel@tonic-gate __db_err(dbenv, "missing or empty key value specified"); 476*7c478bd9Sstevel@tonic-gate return (EINVAL); 477*7c478bd9Sstevel@tonic-gate } 478*7c478bd9Sstevel@tonic-gate 479*7c478bd9Sstevel@tonic-gate /* 480*7c478bd9Sstevel@tonic-gate * __db_rdonly -- 481*7c478bd9Sstevel@tonic-gate * Common readonly message. 482*7c478bd9Sstevel@tonic-gate */ 483*7c478bd9Sstevel@tonic-gate static int 484*7c478bd9Sstevel@tonic-gate __db_rdonly(dbenv, name) 485*7c478bd9Sstevel@tonic-gate const DB_ENV *dbenv; 486*7c478bd9Sstevel@tonic-gate const char *name; 487*7c478bd9Sstevel@tonic-gate { 488*7c478bd9Sstevel@tonic-gate __db_err(dbenv, "%s: attempt to modify a read-only tree", name); 489*7c478bd9Sstevel@tonic-gate return (EACCES); 490*7c478bd9Sstevel@tonic-gate } 491