1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate ** Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers. 3*7c478bd9Sstevel@tonic-gate ** All rights reserved. 4*7c478bd9Sstevel@tonic-gate ** 5*7c478bd9Sstevel@tonic-gate ** By using this file, you agree to the terms and conditions set 6*7c478bd9Sstevel@tonic-gate ** forth in the LICENSE file which can be found at the top level of 7*7c478bd9Sstevel@tonic-gate ** the sendmail distribution. 8*7c478bd9Sstevel@tonic-gate */ 9*7c478bd9Sstevel@tonic-gate 10*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 11*7c478bd9Sstevel@tonic-gate 12*7c478bd9Sstevel@tonic-gate #include <sm/gen.h> 13*7c478bd9Sstevel@tonic-gate SM_RCSID("@(#)$Id: smdb1.c,v 8.59 2004/08/03 20:58:39 ca Exp $") 14*7c478bd9Sstevel@tonic-gate 15*7c478bd9Sstevel@tonic-gate #include <unistd.h> 16*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 17*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 18*7c478bd9Sstevel@tonic-gate 19*7c478bd9Sstevel@tonic-gate #include <sendmail/sendmail.h> 20*7c478bd9Sstevel@tonic-gate #include <libsmdb/smdb.h> 21*7c478bd9Sstevel@tonic-gate 22*7c478bd9Sstevel@tonic-gate #if (DB_VERSION_MAJOR == 1) 23*7c478bd9Sstevel@tonic-gate 24*7c478bd9Sstevel@tonic-gate # define SMDB1_FILE_EXTENSION "db" 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate struct smdb_db1_struct 27*7c478bd9Sstevel@tonic-gate { 28*7c478bd9Sstevel@tonic-gate DB *smdb1_db; 29*7c478bd9Sstevel@tonic-gate int smdb1_lock_fd; 30*7c478bd9Sstevel@tonic-gate bool smdb1_cursor_in_use; 31*7c478bd9Sstevel@tonic-gate }; 32*7c478bd9Sstevel@tonic-gate typedef struct smdb_db1_struct SMDB_DB1_DATABASE; 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate struct smdb_db1_cursor 35*7c478bd9Sstevel@tonic-gate { 36*7c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db; 37*7c478bd9Sstevel@tonic-gate }; 38*7c478bd9Sstevel@tonic-gate typedef struct smdb_db1_cursor SMDB_DB1_CURSOR; 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate static DBTYPE smdb_type_to_db1_type __P((SMDB_DBTYPE)); 41*7c478bd9Sstevel@tonic-gate static unsigned int smdb_put_flags_to_db1_flags __P((SMDB_FLAG)); 42*7c478bd9Sstevel@tonic-gate static int smdb_cursor_get_flags_to_smdb1 __P((SMDB_FLAG)); 43*7c478bd9Sstevel@tonic-gate static SMDB_DB1_DATABASE *smdb1_malloc_database __P((void)); 44*7c478bd9Sstevel@tonic-gate static int smdb1_close __P((SMDB_DATABASE *)); 45*7c478bd9Sstevel@tonic-gate static int smdb1_del __P((SMDB_DATABASE *, SMDB_DBENT *, unsigned int)); 46*7c478bd9Sstevel@tonic-gate static int smdb1_fd __P((SMDB_DATABASE *, int *)); 47*7c478bd9Sstevel@tonic-gate static int smdb1_lockfd __P((SMDB_DATABASE *)); 48*7c478bd9Sstevel@tonic-gate static int smdb1_get __P((SMDB_DATABASE *, SMDB_DBENT *, SMDB_DBENT *, unsigned int)); 49*7c478bd9Sstevel@tonic-gate static int smdb1_put __P((SMDB_DATABASE *, SMDB_DBENT *, SMDB_DBENT *, unsigned int)); 50*7c478bd9Sstevel@tonic-gate static int smdb1_set_owner __P((SMDB_DATABASE *, uid_t, gid_t)); 51*7c478bd9Sstevel@tonic-gate static int smdb1_sync __P((SMDB_DATABASE *, unsigned int)); 52*7c478bd9Sstevel@tonic-gate static int smdb1_cursor_close __P((SMDB_CURSOR *)); 53*7c478bd9Sstevel@tonic-gate static int smdb1_cursor_del __P((SMDB_CURSOR *, unsigned int)); 54*7c478bd9Sstevel@tonic-gate static int smdb1_cursor_get __P((SMDB_CURSOR *, SMDB_DBENT *, SMDB_DBENT *, SMDB_FLAG)); 55*7c478bd9Sstevel@tonic-gate static int smdb1_cursor_put __P((SMDB_CURSOR *, SMDB_DBENT *, SMDB_DBENT *, SMDB_FLAG)); 56*7c478bd9Sstevel@tonic-gate static int smdb1_cursor __P((SMDB_DATABASE *, SMDB_CURSOR **, unsigned int)); 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate /* 59*7c478bd9Sstevel@tonic-gate ** SMDB_TYPE_TO_DB1_TYPE -- Translates smdb database type to db1 type. 60*7c478bd9Sstevel@tonic-gate ** 61*7c478bd9Sstevel@tonic-gate ** Parameters: 62*7c478bd9Sstevel@tonic-gate ** type -- The type to translate. 63*7c478bd9Sstevel@tonic-gate ** 64*7c478bd9Sstevel@tonic-gate ** Returns: 65*7c478bd9Sstevel@tonic-gate ** The DB1 type that corresponsds to the passed in SMDB type. 66*7c478bd9Sstevel@tonic-gate ** Returns -1 if there is no equivalent type. 67*7c478bd9Sstevel@tonic-gate ** 68*7c478bd9Sstevel@tonic-gate */ 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate static DBTYPE 71*7c478bd9Sstevel@tonic-gate smdb_type_to_db1_type(type) 72*7c478bd9Sstevel@tonic-gate SMDB_DBTYPE type; 73*7c478bd9Sstevel@tonic-gate { 74*7c478bd9Sstevel@tonic-gate if (type == SMDB_TYPE_DEFAULT) 75*7c478bd9Sstevel@tonic-gate return DB_HASH; 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate if (strncmp(type, SMDB_TYPE_HASH, SMDB_TYPE_HASH_LEN) == 0) 78*7c478bd9Sstevel@tonic-gate return DB_HASH; 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate if (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0) 81*7c478bd9Sstevel@tonic-gate return DB_BTREE; 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate /* Should never get here thanks to test in smdb_db_open() */ 84*7c478bd9Sstevel@tonic-gate return DB_HASH; 85*7c478bd9Sstevel@tonic-gate } 86*7c478bd9Sstevel@tonic-gate /* 87*7c478bd9Sstevel@tonic-gate ** SMDB_PUT_FLAGS_TO_DB1_FLAGS -- Translates smdb put flags to db1 put flags. 88*7c478bd9Sstevel@tonic-gate ** 89*7c478bd9Sstevel@tonic-gate ** Parameters: 90*7c478bd9Sstevel@tonic-gate ** flags -- The flags to translate. 91*7c478bd9Sstevel@tonic-gate ** 92*7c478bd9Sstevel@tonic-gate ** Returns: 93*7c478bd9Sstevel@tonic-gate ** The db1 flags that are equivalent to the smdb flags. 94*7c478bd9Sstevel@tonic-gate ** 95*7c478bd9Sstevel@tonic-gate ** Notes: 96*7c478bd9Sstevel@tonic-gate ** Any invalid flags are ignored. 97*7c478bd9Sstevel@tonic-gate ** 98*7c478bd9Sstevel@tonic-gate */ 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate static unsigned int 101*7c478bd9Sstevel@tonic-gate smdb_put_flags_to_db1_flags(flags) 102*7c478bd9Sstevel@tonic-gate SMDB_FLAG flags; 103*7c478bd9Sstevel@tonic-gate { 104*7c478bd9Sstevel@tonic-gate int return_flags; 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate return_flags = 0; 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate if (bitset(SMDBF_NO_OVERWRITE, flags)) 109*7c478bd9Sstevel@tonic-gate return_flags |= R_NOOVERWRITE; 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate return return_flags; 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate /* 114*7c478bd9Sstevel@tonic-gate ** SMDB_CURSOR_GET_FLAGS_TO_SMDB1 115*7c478bd9Sstevel@tonic-gate ** 116*7c478bd9Sstevel@tonic-gate ** Parameters: 117*7c478bd9Sstevel@tonic-gate ** flags -- The flags to translate. 118*7c478bd9Sstevel@tonic-gate ** 119*7c478bd9Sstevel@tonic-gate ** Returns: 120*7c478bd9Sstevel@tonic-gate ** The db1 flags that are equivalent to the smdb flags. 121*7c478bd9Sstevel@tonic-gate ** 122*7c478bd9Sstevel@tonic-gate ** Notes: 123*7c478bd9Sstevel@tonic-gate ** Returns -1 if we don't support the flag. 124*7c478bd9Sstevel@tonic-gate ** 125*7c478bd9Sstevel@tonic-gate */ 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate static int 128*7c478bd9Sstevel@tonic-gate smdb_cursor_get_flags_to_smdb1(flags) 129*7c478bd9Sstevel@tonic-gate SMDB_FLAG flags; 130*7c478bd9Sstevel@tonic-gate { 131*7c478bd9Sstevel@tonic-gate switch(flags) 132*7c478bd9Sstevel@tonic-gate { 133*7c478bd9Sstevel@tonic-gate case SMDB_CURSOR_GET_FIRST: 134*7c478bd9Sstevel@tonic-gate return R_FIRST; 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate case SMDB_CURSOR_GET_LAST: 137*7c478bd9Sstevel@tonic-gate return R_LAST; 138*7c478bd9Sstevel@tonic-gate 139*7c478bd9Sstevel@tonic-gate case SMDB_CURSOR_GET_NEXT: 140*7c478bd9Sstevel@tonic-gate return R_NEXT; 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate case SMDB_CURSOR_GET_RANGE: 143*7c478bd9Sstevel@tonic-gate return R_CURSOR; 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate default: 146*7c478bd9Sstevel@tonic-gate return -1; 147*7c478bd9Sstevel@tonic-gate } 148*7c478bd9Sstevel@tonic-gate } 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate /* 151*7c478bd9Sstevel@tonic-gate ** The rest of these functions correspond to the interface laid out in smdb.h. 152*7c478bd9Sstevel@tonic-gate */ 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate static SMDB_DB1_DATABASE * 155*7c478bd9Sstevel@tonic-gate smdb1_malloc_database() 156*7c478bd9Sstevel@tonic-gate { 157*7c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1; 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate db1 = (SMDB_DB1_DATABASE *) malloc(sizeof(SMDB_DB1_DATABASE)); 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate if (db1 != NULL) 162*7c478bd9Sstevel@tonic-gate { 163*7c478bd9Sstevel@tonic-gate db1->smdb1_lock_fd = -1; 164*7c478bd9Sstevel@tonic-gate db1->smdb1_cursor_in_use = false; 165*7c478bd9Sstevel@tonic-gate } 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate return db1; 168*7c478bd9Sstevel@tonic-gate } 169*7c478bd9Sstevel@tonic-gate 170*7c478bd9Sstevel@tonic-gate static int 171*7c478bd9Sstevel@tonic-gate smdb1_close(database) 172*7c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 173*7c478bd9Sstevel@tonic-gate { 174*7c478bd9Sstevel@tonic-gate int result; 175*7c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl; 176*7c478bd9Sstevel@tonic-gate DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate result = db->close(db); 179*7c478bd9Sstevel@tonic-gate if (db1->smdb1_lock_fd != -1) 180*7c478bd9Sstevel@tonic-gate (void) close(db1->smdb1_lock_fd); 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate free(db1); 183*7c478bd9Sstevel@tonic-gate database->smdb_impl = NULL; 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate return result; 186*7c478bd9Sstevel@tonic-gate } 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate static int 189*7c478bd9Sstevel@tonic-gate smdb1_del(database, key, flags) 190*7c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 191*7c478bd9Sstevel@tonic-gate SMDB_DBENT *key; 192*7c478bd9Sstevel@tonic-gate unsigned int flags; 193*7c478bd9Sstevel@tonic-gate { 194*7c478bd9Sstevel@tonic-gate DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 195*7c478bd9Sstevel@tonic-gate DBT dbkey; 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate (void) memset(&dbkey, '\0', sizeof dbkey); 198*7c478bd9Sstevel@tonic-gate dbkey.data = key->data; 199*7c478bd9Sstevel@tonic-gate dbkey.size = key->size; 200*7c478bd9Sstevel@tonic-gate return db->del(db, &dbkey, flags); 201*7c478bd9Sstevel@tonic-gate } 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate static int 204*7c478bd9Sstevel@tonic-gate smdb1_fd(database, fd) 205*7c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 206*7c478bd9Sstevel@tonic-gate int *fd; 207*7c478bd9Sstevel@tonic-gate { 208*7c478bd9Sstevel@tonic-gate DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate *fd = db->fd(db); 211*7c478bd9Sstevel@tonic-gate if (*fd == -1) 212*7c478bd9Sstevel@tonic-gate return errno; 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate return SMDBE_OK; 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate static int 218*7c478bd9Sstevel@tonic-gate smdb1_lockfd(database) 219*7c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 220*7c478bd9Sstevel@tonic-gate { 221*7c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl; 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate return db1->smdb1_lock_fd; 224*7c478bd9Sstevel@tonic-gate } 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate static int 228*7c478bd9Sstevel@tonic-gate smdb1_get(database, key, data, flags) 229*7c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 230*7c478bd9Sstevel@tonic-gate SMDB_DBENT *key; 231*7c478bd9Sstevel@tonic-gate SMDB_DBENT *data; 232*7c478bd9Sstevel@tonic-gate unsigned int flags; 233*7c478bd9Sstevel@tonic-gate { 234*7c478bd9Sstevel@tonic-gate int result; 235*7c478bd9Sstevel@tonic-gate DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 236*7c478bd9Sstevel@tonic-gate DBT dbkey, dbdata; 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate (void) memset(&dbdata, '\0', sizeof dbdata); 239*7c478bd9Sstevel@tonic-gate (void) memset(&dbkey, '\0', sizeof dbkey); 240*7c478bd9Sstevel@tonic-gate dbkey.data = key->data; 241*7c478bd9Sstevel@tonic-gate dbkey.size = key->size; 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate result = db->get(db, &dbkey, &dbdata, flags); 244*7c478bd9Sstevel@tonic-gate if (result != 0) 245*7c478bd9Sstevel@tonic-gate { 246*7c478bd9Sstevel@tonic-gate if (result == 1) 247*7c478bd9Sstevel@tonic-gate return SMDBE_NOT_FOUND; 248*7c478bd9Sstevel@tonic-gate return errno; 249*7c478bd9Sstevel@tonic-gate } 250*7c478bd9Sstevel@tonic-gate data->data = dbdata.data; 251*7c478bd9Sstevel@tonic-gate data->size = dbdata.size; 252*7c478bd9Sstevel@tonic-gate return SMDBE_OK; 253*7c478bd9Sstevel@tonic-gate } 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate static int 256*7c478bd9Sstevel@tonic-gate smdb1_put(database, key, data, flags) 257*7c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 258*7c478bd9Sstevel@tonic-gate SMDB_DBENT *key; 259*7c478bd9Sstevel@tonic-gate SMDB_DBENT *data; 260*7c478bd9Sstevel@tonic-gate unsigned int flags; 261*7c478bd9Sstevel@tonic-gate { 262*7c478bd9Sstevel@tonic-gate DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 263*7c478bd9Sstevel@tonic-gate DBT dbkey, dbdata; 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate (void) memset(&dbdata, '\0', sizeof dbdata); 266*7c478bd9Sstevel@tonic-gate (void) memset(&dbkey, '\0', sizeof dbkey); 267*7c478bd9Sstevel@tonic-gate dbkey.data = key->data; 268*7c478bd9Sstevel@tonic-gate dbkey.size = key->size; 269*7c478bd9Sstevel@tonic-gate dbdata.data = data->data; 270*7c478bd9Sstevel@tonic-gate dbdata.size = data->size; 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate return db->put(db, &dbkey, &dbdata, 273*7c478bd9Sstevel@tonic-gate smdb_put_flags_to_db1_flags(flags)); 274*7c478bd9Sstevel@tonic-gate } 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate static int 277*7c478bd9Sstevel@tonic-gate smdb1_set_owner(database, uid, gid) 278*7c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 279*7c478bd9Sstevel@tonic-gate uid_t uid; 280*7c478bd9Sstevel@tonic-gate gid_t gid; 281*7c478bd9Sstevel@tonic-gate { 282*7c478bd9Sstevel@tonic-gate # if HASFCHOWN 283*7c478bd9Sstevel@tonic-gate int fd; 284*7c478bd9Sstevel@tonic-gate int result; 285*7c478bd9Sstevel@tonic-gate DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 286*7c478bd9Sstevel@tonic-gate 287*7c478bd9Sstevel@tonic-gate fd = db->fd(db); 288*7c478bd9Sstevel@tonic-gate if (fd == -1) 289*7c478bd9Sstevel@tonic-gate return errno; 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate result = fchown(fd, uid, gid); 292*7c478bd9Sstevel@tonic-gate if (result < 0) 293*7c478bd9Sstevel@tonic-gate return errno; 294*7c478bd9Sstevel@tonic-gate # endif /* HASFCHOWN */ 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate return SMDBE_OK; 297*7c478bd9Sstevel@tonic-gate } 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate static int 300*7c478bd9Sstevel@tonic-gate smdb1_sync(database, flags) 301*7c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 302*7c478bd9Sstevel@tonic-gate unsigned int flags; 303*7c478bd9Sstevel@tonic-gate { 304*7c478bd9Sstevel@tonic-gate DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate return db->sync(db, flags); 307*7c478bd9Sstevel@tonic-gate } 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate static int 310*7c478bd9Sstevel@tonic-gate smdb1_cursor_close(cursor) 311*7c478bd9Sstevel@tonic-gate SMDB_CURSOR *cursor; 312*7c478bd9Sstevel@tonic-gate { 313*7c478bd9Sstevel@tonic-gate SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 314*7c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1 = db1_cursor->db; 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate if (!db1->smdb1_cursor_in_use) 317*7c478bd9Sstevel@tonic-gate return SMDBE_NOT_A_VALID_CURSOR; 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate db1->smdb1_cursor_in_use = false; 320*7c478bd9Sstevel@tonic-gate free(cursor); 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate return SMDBE_OK; 323*7c478bd9Sstevel@tonic-gate } 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate static int 326*7c478bd9Sstevel@tonic-gate smdb1_cursor_del(cursor, flags) 327*7c478bd9Sstevel@tonic-gate SMDB_CURSOR *cursor; 328*7c478bd9Sstevel@tonic-gate unsigned int flags; 329*7c478bd9Sstevel@tonic-gate { 330*7c478bd9Sstevel@tonic-gate SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 331*7c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1 = db1_cursor->db; 332*7c478bd9Sstevel@tonic-gate DB *db = db1->smdb1_db; 333*7c478bd9Sstevel@tonic-gate 334*7c478bd9Sstevel@tonic-gate return db->del(db, NULL, R_CURSOR); 335*7c478bd9Sstevel@tonic-gate } 336*7c478bd9Sstevel@tonic-gate 337*7c478bd9Sstevel@tonic-gate static int 338*7c478bd9Sstevel@tonic-gate smdb1_cursor_get(cursor, key, value, flags) 339*7c478bd9Sstevel@tonic-gate SMDB_CURSOR *cursor; 340*7c478bd9Sstevel@tonic-gate SMDB_DBENT *key; 341*7c478bd9Sstevel@tonic-gate SMDB_DBENT *value; 342*7c478bd9Sstevel@tonic-gate SMDB_FLAG flags; 343*7c478bd9Sstevel@tonic-gate { 344*7c478bd9Sstevel@tonic-gate int db1_flags; 345*7c478bd9Sstevel@tonic-gate int result; 346*7c478bd9Sstevel@tonic-gate SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 347*7c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1 = db1_cursor->db; 348*7c478bd9Sstevel@tonic-gate DB *db = db1->smdb1_db; 349*7c478bd9Sstevel@tonic-gate DBT dbkey, dbdata; 350*7c478bd9Sstevel@tonic-gate 351*7c478bd9Sstevel@tonic-gate (void) memset(&dbdata, '\0', sizeof dbdata); 352*7c478bd9Sstevel@tonic-gate (void) memset(&dbkey, '\0', sizeof dbkey); 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate db1_flags = smdb_cursor_get_flags_to_smdb1(flags); 355*7c478bd9Sstevel@tonic-gate result = db->seq(db, &dbkey, &dbdata, db1_flags); 356*7c478bd9Sstevel@tonic-gate if (result == -1) 357*7c478bd9Sstevel@tonic-gate return errno; 358*7c478bd9Sstevel@tonic-gate if (result == 1) 359*7c478bd9Sstevel@tonic-gate return SMDBE_LAST_ENTRY; 360*7c478bd9Sstevel@tonic-gate value->data = dbdata.data; 361*7c478bd9Sstevel@tonic-gate value->size = dbdata.size; 362*7c478bd9Sstevel@tonic-gate key->data = dbkey.data; 363*7c478bd9Sstevel@tonic-gate key->size = dbkey.size; 364*7c478bd9Sstevel@tonic-gate return SMDBE_OK; 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate static int 368*7c478bd9Sstevel@tonic-gate smdb1_cursor_put(cursor, key, value, flags) 369*7c478bd9Sstevel@tonic-gate SMDB_CURSOR *cursor; 370*7c478bd9Sstevel@tonic-gate SMDB_DBENT *key; 371*7c478bd9Sstevel@tonic-gate SMDB_DBENT *value; 372*7c478bd9Sstevel@tonic-gate SMDB_FLAG flags; 373*7c478bd9Sstevel@tonic-gate { 374*7c478bd9Sstevel@tonic-gate SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 375*7c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1 = db1_cursor->db; 376*7c478bd9Sstevel@tonic-gate DB *db = db1->smdb1_db; 377*7c478bd9Sstevel@tonic-gate DBT dbkey, dbdata; 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate (void) memset(&dbdata, '\0', sizeof dbdata); 380*7c478bd9Sstevel@tonic-gate (void) memset(&dbkey, '\0', sizeof dbkey); 381*7c478bd9Sstevel@tonic-gate dbkey.data = key->data; 382*7c478bd9Sstevel@tonic-gate dbkey.size = key->size; 383*7c478bd9Sstevel@tonic-gate dbdata.data = value->data; 384*7c478bd9Sstevel@tonic-gate dbdata.size = value->size; 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate return db->put(db, &dbkey, &dbdata, R_CURSOR); 387*7c478bd9Sstevel@tonic-gate } 388*7c478bd9Sstevel@tonic-gate 389*7c478bd9Sstevel@tonic-gate static int 390*7c478bd9Sstevel@tonic-gate smdb1_cursor(database, cursor, flags) 391*7c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 392*7c478bd9Sstevel@tonic-gate SMDB_CURSOR **cursor; 393*7c478bd9Sstevel@tonic-gate unsigned int flags; 394*7c478bd9Sstevel@tonic-gate { 395*7c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl; 396*7c478bd9Sstevel@tonic-gate SMDB_CURSOR *cur; 397*7c478bd9Sstevel@tonic-gate SMDB_DB1_CURSOR *db1_cursor; 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate if (db1->smdb1_cursor_in_use) 400*7c478bd9Sstevel@tonic-gate return SMDBE_ONLY_SUPPORTS_ONE_CURSOR; 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate db1->smdb1_cursor_in_use = true; 403*7c478bd9Sstevel@tonic-gate db1_cursor = (SMDB_DB1_CURSOR *) malloc(sizeof(SMDB_DB1_CURSOR)); 404*7c478bd9Sstevel@tonic-gate db1_cursor->db = db1; 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate cur = (SMDB_CURSOR *) malloc(sizeof(SMDB_CURSOR)); 407*7c478bd9Sstevel@tonic-gate 408*7c478bd9Sstevel@tonic-gate if (cur == NULL) 409*7c478bd9Sstevel@tonic-gate return SMDBE_MALLOC; 410*7c478bd9Sstevel@tonic-gate 411*7c478bd9Sstevel@tonic-gate cur->smdbc_impl = db1_cursor; 412*7c478bd9Sstevel@tonic-gate cur->smdbc_close = smdb1_cursor_close; 413*7c478bd9Sstevel@tonic-gate cur->smdbc_del = smdb1_cursor_del; 414*7c478bd9Sstevel@tonic-gate cur->smdbc_get = smdb1_cursor_get; 415*7c478bd9Sstevel@tonic-gate cur->smdbc_put = smdb1_cursor_put; 416*7c478bd9Sstevel@tonic-gate *cursor = cur; 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate return SMDBE_OK; 419*7c478bd9Sstevel@tonic-gate } 420*7c478bd9Sstevel@tonic-gate /* 421*7c478bd9Sstevel@tonic-gate ** SMDB_DB_OPEN -- Opens a db1 database. 422*7c478bd9Sstevel@tonic-gate ** 423*7c478bd9Sstevel@tonic-gate ** Parameters: 424*7c478bd9Sstevel@tonic-gate ** database -- An unallocated database pointer to a pointer. 425*7c478bd9Sstevel@tonic-gate ** db_name -- The name of the database without extension. 426*7c478bd9Sstevel@tonic-gate ** mode -- File permisions on the database if created. 427*7c478bd9Sstevel@tonic-gate ** mode_mask -- Mode bits that must match on an existing database. 428*7c478bd9Sstevel@tonic-gate ** sff -- Flags for safefile. 429*7c478bd9Sstevel@tonic-gate ** type -- The type of database to open 430*7c478bd9Sstevel@tonic-gate ** See smdb_type_to_db1_type for valid types. 431*7c478bd9Sstevel@tonic-gate ** user_info -- Information on the user to use for file 432*7c478bd9Sstevel@tonic-gate ** permissions. 433*7c478bd9Sstevel@tonic-gate ** db_params -- 434*7c478bd9Sstevel@tonic-gate ** An SMDB_DBPARAMS struct including params. These 435*7c478bd9Sstevel@tonic-gate ** are processed according to the type of the 436*7c478bd9Sstevel@tonic-gate ** database. Currently supported params (only for 437*7c478bd9Sstevel@tonic-gate ** HASH type) are: 438*7c478bd9Sstevel@tonic-gate ** num_elements 439*7c478bd9Sstevel@tonic-gate ** cache_size 440*7c478bd9Sstevel@tonic-gate ** 441*7c478bd9Sstevel@tonic-gate ** Returns: 442*7c478bd9Sstevel@tonic-gate ** SMDBE_OK -- Success, otherwise errno. 443*7c478bd9Sstevel@tonic-gate */ 444*7c478bd9Sstevel@tonic-gate 445*7c478bd9Sstevel@tonic-gate int 446*7c478bd9Sstevel@tonic-gate smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info, 447*7c478bd9Sstevel@tonic-gate db_params) 448*7c478bd9Sstevel@tonic-gate SMDB_DATABASE **database; 449*7c478bd9Sstevel@tonic-gate char *db_name; 450*7c478bd9Sstevel@tonic-gate int mode; 451*7c478bd9Sstevel@tonic-gate int mode_mask; 452*7c478bd9Sstevel@tonic-gate long sff; 453*7c478bd9Sstevel@tonic-gate SMDB_DBTYPE type; 454*7c478bd9Sstevel@tonic-gate SMDB_USER_INFO *user_info; 455*7c478bd9Sstevel@tonic-gate SMDB_DBPARAMS *db_params; 456*7c478bd9Sstevel@tonic-gate { 457*7c478bd9Sstevel@tonic-gate bool lockcreated = false; 458*7c478bd9Sstevel@tonic-gate int db_fd; 459*7c478bd9Sstevel@tonic-gate int lock_fd; 460*7c478bd9Sstevel@tonic-gate int result; 461*7c478bd9Sstevel@tonic-gate void *params; 462*7c478bd9Sstevel@tonic-gate SMDB_DATABASE *smdb_db; 463*7c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1; 464*7c478bd9Sstevel@tonic-gate DB *db; 465*7c478bd9Sstevel@tonic-gate HASHINFO hash_info; 466*7c478bd9Sstevel@tonic-gate BTREEINFO btree_info; 467*7c478bd9Sstevel@tonic-gate DBTYPE db_type; 468*7c478bd9Sstevel@tonic-gate struct stat stat_info; 469*7c478bd9Sstevel@tonic-gate char db_file_name[MAXPATHLEN]; 470*7c478bd9Sstevel@tonic-gate 471*7c478bd9Sstevel@tonic-gate if (type == NULL || 472*7c478bd9Sstevel@tonic-gate (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) != 0 && 473*7c478bd9Sstevel@tonic-gate strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) != 0)) 474*7c478bd9Sstevel@tonic-gate return SMDBE_UNKNOWN_DB_TYPE; 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate result = smdb_add_extension(db_file_name, sizeof db_file_name, 477*7c478bd9Sstevel@tonic-gate db_name, SMDB1_FILE_EXTENSION); 478*7c478bd9Sstevel@tonic-gate if (result != SMDBE_OK) 479*7c478bd9Sstevel@tonic-gate return result; 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate result = smdb_setup_file(db_name, SMDB1_FILE_EXTENSION, mode_mask, 482*7c478bd9Sstevel@tonic-gate sff, user_info, &stat_info); 483*7c478bd9Sstevel@tonic-gate if (result != SMDBE_OK) 484*7c478bd9Sstevel@tonic-gate return result; 485*7c478bd9Sstevel@tonic-gate 486*7c478bd9Sstevel@tonic-gate if (stat_info.st_mode == ST_MODE_NOFILE && 487*7c478bd9Sstevel@tonic-gate bitset(mode, O_CREAT)) 488*7c478bd9Sstevel@tonic-gate lockcreated = true; 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate lock_fd = -1; 491*7c478bd9Sstevel@tonic-gate result = smdb_lock_file(&lock_fd, db_name, mode, sff, 492*7c478bd9Sstevel@tonic-gate SMDB1_FILE_EXTENSION); 493*7c478bd9Sstevel@tonic-gate if (result != SMDBE_OK) 494*7c478bd9Sstevel@tonic-gate return result; 495*7c478bd9Sstevel@tonic-gate 496*7c478bd9Sstevel@tonic-gate if (lockcreated) 497*7c478bd9Sstevel@tonic-gate { 498*7c478bd9Sstevel@tonic-gate mode |= O_TRUNC; 499*7c478bd9Sstevel@tonic-gate mode &= ~(O_CREAT|O_EXCL); 500*7c478bd9Sstevel@tonic-gate } 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate *database = NULL; 503*7c478bd9Sstevel@tonic-gate 504*7c478bd9Sstevel@tonic-gate smdb_db = smdb_malloc_database(); 505*7c478bd9Sstevel@tonic-gate db1 = smdb1_malloc_database(); 506*7c478bd9Sstevel@tonic-gate if (smdb_db == NULL || db1 == NULL) 507*7c478bd9Sstevel@tonic-gate return SMDBE_MALLOC; 508*7c478bd9Sstevel@tonic-gate db1->smdb1_lock_fd = lock_fd; 509*7c478bd9Sstevel@tonic-gate 510*7c478bd9Sstevel@tonic-gate params = NULL; 511*7c478bd9Sstevel@tonic-gate if (db_params != NULL && 512*7c478bd9Sstevel@tonic-gate (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) == 0)) 513*7c478bd9Sstevel@tonic-gate { 514*7c478bd9Sstevel@tonic-gate (void) memset(&hash_info, '\0', sizeof hash_info); 515*7c478bd9Sstevel@tonic-gate hash_info.nelem = db_params->smdbp_num_elements; 516*7c478bd9Sstevel@tonic-gate hash_info.cachesize = db_params->smdbp_cache_size; 517*7c478bd9Sstevel@tonic-gate params = &hash_info; 518*7c478bd9Sstevel@tonic-gate } 519*7c478bd9Sstevel@tonic-gate 520*7c478bd9Sstevel@tonic-gate if (db_params != NULL && 521*7c478bd9Sstevel@tonic-gate (strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) == 0)) 522*7c478bd9Sstevel@tonic-gate { 523*7c478bd9Sstevel@tonic-gate (void) memset(&btree_info, '\0', sizeof btree_info); 524*7c478bd9Sstevel@tonic-gate btree_info.cachesize = db_params->smdbp_cache_size; 525*7c478bd9Sstevel@tonic-gate if (db_params->smdbp_allow_dup) 526*7c478bd9Sstevel@tonic-gate btree_info.flags |= R_DUP; 527*7c478bd9Sstevel@tonic-gate params = &btree_info; 528*7c478bd9Sstevel@tonic-gate } 529*7c478bd9Sstevel@tonic-gate 530*7c478bd9Sstevel@tonic-gate db_type = smdb_type_to_db1_type(type); 531*7c478bd9Sstevel@tonic-gate db = dbopen(db_file_name, mode, DBMMODE, db_type, params); 532*7c478bd9Sstevel@tonic-gate if (db != NULL) 533*7c478bd9Sstevel@tonic-gate { 534*7c478bd9Sstevel@tonic-gate db_fd = db->fd(db); 535*7c478bd9Sstevel@tonic-gate result = smdb_filechanged(db_name, SMDB1_FILE_EXTENSION, db_fd, 536*7c478bd9Sstevel@tonic-gate &stat_info); 537*7c478bd9Sstevel@tonic-gate } 538*7c478bd9Sstevel@tonic-gate else 539*7c478bd9Sstevel@tonic-gate { 540*7c478bd9Sstevel@tonic-gate if (errno == 0) 541*7c478bd9Sstevel@tonic-gate result = SMDBE_BAD_OPEN; 542*7c478bd9Sstevel@tonic-gate else 543*7c478bd9Sstevel@tonic-gate result = errno; 544*7c478bd9Sstevel@tonic-gate } 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate if (result == SMDBE_OK) 547*7c478bd9Sstevel@tonic-gate { 548*7c478bd9Sstevel@tonic-gate /* Everything is ok. Setup driver */ 549*7c478bd9Sstevel@tonic-gate db1->smdb1_db = db; 550*7c478bd9Sstevel@tonic-gate 551*7c478bd9Sstevel@tonic-gate smdb_db->smdb_close = smdb1_close; 552*7c478bd9Sstevel@tonic-gate smdb_db->smdb_del = smdb1_del; 553*7c478bd9Sstevel@tonic-gate smdb_db->smdb_fd = smdb1_fd; 554*7c478bd9Sstevel@tonic-gate smdb_db->smdb_lockfd = smdb1_lockfd; 555*7c478bd9Sstevel@tonic-gate smdb_db->smdb_get = smdb1_get; 556*7c478bd9Sstevel@tonic-gate smdb_db->smdb_put = smdb1_put; 557*7c478bd9Sstevel@tonic-gate smdb_db->smdb_set_owner = smdb1_set_owner; 558*7c478bd9Sstevel@tonic-gate smdb_db->smdb_sync = smdb1_sync; 559*7c478bd9Sstevel@tonic-gate smdb_db->smdb_cursor = smdb1_cursor; 560*7c478bd9Sstevel@tonic-gate smdb_db->smdb_impl = db1; 561*7c478bd9Sstevel@tonic-gate 562*7c478bd9Sstevel@tonic-gate *database = smdb_db; 563*7c478bd9Sstevel@tonic-gate return SMDBE_OK; 564*7c478bd9Sstevel@tonic-gate } 565*7c478bd9Sstevel@tonic-gate 566*7c478bd9Sstevel@tonic-gate if (db != NULL) 567*7c478bd9Sstevel@tonic-gate (void) db->close(db); 568*7c478bd9Sstevel@tonic-gate 569*7c478bd9Sstevel@tonic-gate /* Error opening database */ 570*7c478bd9Sstevel@tonic-gate (void) smdb_unlock_file(db1->smdb1_lock_fd); 571*7c478bd9Sstevel@tonic-gate free(db1); 572*7c478bd9Sstevel@tonic-gate smdb_free_database(smdb_db); 573*7c478bd9Sstevel@tonic-gate 574*7c478bd9Sstevel@tonic-gate return result; 575*7c478bd9Sstevel@tonic-gate } 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate #endif /* (DB_VERSION_MAJOR == 1) */ 578