smdb1.c revision 261363
1246074Sgabor/* 2246074Sgabor** Copyright (c) 1999-2002, 2004, 2009 Proofpoint, Inc. and its suppliers. 3246074Sgabor** All rights reserved. 4246074Sgabor** 5246074Sgabor** By using this file, you agree to the terms and conditions set 6246074Sgabor** forth in the LICENSE file which can be found at the top level of 7246074Sgabor** the sendmail distribution. 8246074Sgabor*/ 9246074Sgabor 10246074Sgabor#include <sm/gen.h> 11246074SgaborSM_RCSID("@(#)$Id: smdb1.c,v 8.63 2013/11/22 20:51:49 ca Exp $") 12246074Sgabor 13246074Sgabor#include <unistd.h> 14246074Sgabor#include <stdlib.h> 15246074Sgabor#include <fcntl.h> 16246074Sgabor 17246074Sgabor#include <sendmail/sendmail.h> 18246074Sgabor#include <libsmdb/smdb.h> 19246074Sgabor 20246074Sgabor#if (DB_VERSION_MAJOR == 1) 21246074Sgabor 22246074Sgabor# define SMDB1_FILE_EXTENSION "db" 23246074Sgabor 24246074Sgaborstruct smdb_db1_struct 25246074Sgabor{ 26246091Sdelphij DB *smdb1_db; 27246091Sdelphij int smdb1_lock_fd; 28246074Sgabor bool smdb1_cursor_in_use; 29246074Sgabor}; 30246074Sgabortypedef struct smdb_db1_struct SMDB_DB1_DATABASE; 31246074Sgabor 32246074Sgaborstruct smdb_db1_cursor 33246074Sgabor{ 34285976Sdelphij SMDB_DB1_DATABASE *db; 35246074Sgabor}; 36246074Sgabortypedef struct smdb_db1_cursor SMDB_DB1_CURSOR; 37285976Sdelphij 38246074Sgaborstatic DBTYPE smdb_type_to_db1_type __P((SMDB_DBTYPE)); 39287223Sdelphijstatic unsigned int smdb_put_flags_to_db1_flags __P((SMDB_FLAG)); 40287223Sdelphijstatic int smdb_cursor_get_flags_to_smdb1 __P((SMDB_FLAG)); 41246074Sgaborstatic SMDB_DB1_DATABASE *smdb1_malloc_database __P((void)); 42287223Sdelphijstatic int smdb1_close __P((SMDB_DATABASE *)); 43246074Sgaborstatic int smdb1_del __P((SMDB_DATABASE *, SMDB_DBENT *, unsigned int)); 44246074Sgaborstatic int smdb1_fd __P((SMDB_DATABASE *, int *)); 45246074Sgaborstatic int smdb1_lockfd __P((SMDB_DATABASE *)); 46246074Sgaborstatic int smdb1_get __P((SMDB_DATABASE *, SMDB_DBENT *, SMDB_DBENT *, unsigned int)); 47246074Sgaborstatic int smdb1_put __P((SMDB_DATABASE *, SMDB_DBENT *, SMDB_DBENT *, unsigned int)); 48246074Sgaborstatic int smdb1_set_owner __P((SMDB_DATABASE *, uid_t, gid_t)); 49246074Sgaborstatic int smdb1_sync __P((SMDB_DATABASE *, unsigned int)); 50246074Sgaborstatic int smdb1_cursor_close __P((SMDB_CURSOR *)); 51246074Sgaborstatic int smdb1_cursor_del __P((SMDB_CURSOR *, unsigned int)); 52246074Sgaborstatic int smdb1_cursor_get __P((SMDB_CURSOR *, SMDB_DBENT *, SMDB_DBENT *, SMDB_FLAG)); 53246074Sgaborstatic int smdb1_cursor_put __P((SMDB_CURSOR *, SMDB_DBENT *, SMDB_DBENT *, SMDB_FLAG)); 54246074Sgaborstatic int smdb1_cursor __P((SMDB_DATABASE *, SMDB_CURSOR **, unsigned int)); 55246074Sgabor 56246074Sgabor/* 57246074Sgabor** SMDB_TYPE_TO_DB1_TYPE -- Translates smdb database type to db1 type. 58246074Sgabor** 59246074Sgabor** Parameters: 60246074Sgabor** type -- The type to translate. 61246074Sgabor** 62246074Sgabor** Returns: 63246074Sgabor** The DB1 type that corresponsds to the passed in SMDB type. 64246074Sgabor** Returns -1 if there is no equivalent type. 65246074Sgabor** 66246074Sgabor*/ 67246074Sgabor 68246074Sgaborstatic DBTYPE 69246074Sgaborsmdb_type_to_db1_type(type) 70246074Sgabor SMDB_DBTYPE type; 71246074Sgabor{ 72246074Sgabor if (type == SMDB_TYPE_DEFAULT) 73246074Sgabor return DB_HASH; 74246074Sgabor 75246074Sgabor if (strncmp(type, SMDB_TYPE_HASH, SMDB_TYPE_HASH_LEN) == 0) 76246074Sgabor return DB_HASH; 77246074Sgabor 78246074Sgabor if (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0) 79246074Sgabor return DB_BTREE; 80246074Sgabor 81246074Sgabor /* Should never get here thanks to test in smdb_db_open() */ 82246074Sgabor return DB_HASH; 83246074Sgabor} 84246074Sgabor/* 85246074Sgabor** SMDB_PUT_FLAGS_TO_DB1_FLAGS -- Translates smdb put flags to db1 put flags. 86246074Sgabor** 87246074Sgabor** Parameters: 88246074Sgabor** flags -- The flags to translate. 89246074Sgabor** 90246074Sgabor** Returns: 91246074Sgabor** The db1 flags that are equivalent to the smdb flags. 92246074Sgabor** 93246074Sgabor** Notes: 94246074Sgabor** Any invalid flags are ignored. 95246074Sgabor** 96246074Sgabor*/ 97246074Sgabor 98246074Sgaborstatic unsigned int 99246074Sgaborsmdb_put_flags_to_db1_flags(flags) 100246074Sgabor SMDB_FLAG flags; 101246074Sgabor{ 102246074Sgabor int return_flags; 103246074Sgabor 104246074Sgabor return_flags = 0; 105246074Sgabor 106246074Sgabor if (bitset(SMDBF_NO_OVERWRITE, flags)) 107246074Sgabor return_flags |= R_NOOVERWRITE; 108246074Sgabor 109246074Sgabor return return_flags; 110246074Sgabor} 111246074Sgabor/* 112246074Sgabor** SMDB_CURSOR_GET_FLAGS_TO_SMDB1 113246074Sgabor** 114246074Sgabor** Parameters: 115246074Sgabor** flags -- The flags to translate. 116246074Sgabor** 117246074Sgabor** Returns: 118246074Sgabor** The db1 flags that are equivalent to the smdb flags. 119246074Sgabor** 120246074Sgabor** Notes: 121246074Sgabor** Returns -1 if we don't support the flag. 122246074Sgabor** 123246074Sgabor*/ 124246074Sgabor 125246074Sgaborstatic int 126246074Sgaborsmdb_cursor_get_flags_to_smdb1(flags) 127246074Sgabor SMDB_FLAG flags; 128246074Sgabor{ 129246074Sgabor switch(flags) 130246074Sgabor { 131246074Sgabor case SMDB_CURSOR_GET_FIRST: 132246074Sgabor return R_FIRST; 133246074Sgabor 134246074Sgabor case SMDB_CURSOR_GET_LAST: 135246074Sgabor return R_LAST; 136246074Sgabor 137246074Sgabor case SMDB_CURSOR_GET_NEXT: 138246074Sgabor return R_NEXT; 139287223Sdelphij 140246074Sgabor case SMDB_CURSOR_GET_RANGE: 141246074Sgabor return R_CURSOR; 142246074Sgabor 143246074Sgabor default: 144246074Sgabor return -1; 145285976Sdelphij } 146246074Sgabor} 147246074Sgabor 148246074Sgabor/* 149246074Sgabor** The rest of these functions correspond to the interface laid out in smdb.h. 150246074Sgabor*/ 151246074Sgabor 152246074Sgaborstatic SMDB_DB1_DATABASE * 153246074Sgaborsmdb1_malloc_database() 154246074Sgabor{ 155246074Sgabor SMDB_DB1_DATABASE *db1; 156246074Sgabor 157246074Sgabor db1 = (SMDB_DB1_DATABASE *) malloc(sizeof(SMDB_DB1_DATABASE)); 158246074Sgabor 159246074Sgabor if (db1 != NULL) 160246074Sgabor { 161246074Sgabor db1->smdb1_lock_fd = -1; 162246074Sgabor db1->smdb1_cursor_in_use = false; 163246074Sgabor } 164246074Sgabor 165246074Sgabor return db1; 166246074Sgabor} 167246074Sgabor 168246074Sgaborstatic int 169246074Sgaborsmdb1_close(database) 170246074Sgabor SMDB_DATABASE *database; 171246074Sgabor{ 172246074Sgabor int result; 173285976Sdelphij SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl; 174285976Sdelphij DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 175246074Sgabor 176246074Sgabor result = db->close(db); 177246074Sgabor if (db1->smdb1_lock_fd != -1) 178246074Sgabor (void) close(db1->smdb1_lock_fd); 179246074Sgabor 180285976Sdelphij free(db1); 181246074Sgabor database->smdb_impl = NULL; 182287223Sdelphij 183287223Sdelphij return result; 184287223Sdelphij} 185246074Sgabor 186246074Sgaborstatic int 187246074Sgaborsmdb1_del(database, key, flags) 188246074Sgabor SMDB_DATABASE *database; 189246074Sgabor SMDB_DBENT *key; 190285976Sdelphij unsigned int flags; 191246074Sgabor{ 192246074Sgabor DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 193246074Sgabor DBT dbkey; 194287223Sdelphij 195287223Sdelphij (void) memset(&dbkey, '\0', sizeof dbkey); 196246074Sgabor dbkey.data = key->data; 197285976Sdelphij dbkey.size = key->size; 198246074Sgabor return db->del(db, &dbkey, flags); 199246074Sgabor} 200246074Sgabor 201246074Sgaborstatic int 202246074Sgaborsmdb1_fd(database, fd) 203285976Sdelphij SMDB_DATABASE *database; 204285976Sdelphij int *fd; 205285976Sdelphij{ 206246074Sgabor DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 207246074Sgabor 208246074Sgabor *fd = db->fd(db); 209246074Sgabor if (*fd == -1) 210285976Sdelphij return errno; 211285976Sdelphij 212246074Sgabor return SMDBE_OK; 213246074Sgabor} 214246074Sgabor 215246074Sgaborstatic int 216246074Sgaborsmdb1_lockfd(database) 217246074Sgabor SMDB_DATABASE *database; 218246074Sgabor{ 219285976Sdelphij SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl; 220285976Sdelphij 221287223Sdelphij return db1->smdb1_lock_fd; 222287223Sdelphij} 223287223Sdelphij 224287223Sdelphij 225287223Sdelphijstatic int 226287223Sdelphijsmdb1_get(database, key, data, flags) 227287223Sdelphij SMDB_DATABASE *database; 228287223Sdelphij SMDB_DBENT *key; 229287223Sdelphij SMDB_DBENT *data; 230287223Sdelphij unsigned int flags; 231287223Sdelphij{ 232287223Sdelphij int result; 233287223Sdelphij DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 234287223Sdelphij DBT dbkey, dbdata; 235287223Sdelphij 236246074Sgabor (void) memset(&dbdata, '\0', sizeof dbdata); 237285976Sdelphij (void) memset(&dbkey, '\0', sizeof dbkey); 238246074Sgabor dbkey.data = key->data; 239285976Sdelphij dbkey.size = key->size; 240285976Sdelphij 241285976Sdelphij result = db->get(db, &dbkey, &dbdata, flags); 242287223Sdelphij if (result != 0) 243287223Sdelphij { 244287223Sdelphij if (result == 1) 245287223Sdelphij return SMDBE_NOT_FOUND; 246287223Sdelphij return errno; 247287223Sdelphij } 248287223Sdelphij data->data = dbdata.data; 249287223Sdelphij data->size = dbdata.size; 250287223Sdelphij return SMDBE_OK; 251287223Sdelphij} 252287223Sdelphij 253287223Sdelphijstatic int 254285976Sdelphijsmdb1_put(database, key, data, flags) 255285976Sdelphij SMDB_DATABASE *database; 256246074Sgabor SMDB_DBENT *key; 257285976Sdelphij SMDB_DBENT *data; 258285976Sdelphij unsigned int flags; 259246074Sgabor{ 260285976Sdelphij DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 261246074Sgabor DBT dbkey, dbdata; 262246074Sgabor 263246074Sgabor (void) memset(&dbdata, '\0', sizeof dbdata); 264246074Sgabor (void) memset(&dbkey, '\0', sizeof dbkey); 265246074Sgabor dbkey.data = key->data; 266246074Sgabor dbkey.size = key->size; 267246074Sgabor dbdata.data = data->data; 268246074Sgabor dbdata.size = data->size; 269246074Sgabor 270246074Sgabor return db->put(db, &dbkey, &dbdata, 271246074Sgabor smdb_put_flags_to_db1_flags(flags)); 272246074Sgabor} 273246074Sgabor 274246074Sgaborstatic int 275246074Sgaborsmdb1_set_owner(database, uid, gid) 276246074Sgabor SMDB_DATABASE *database; 277246074Sgabor uid_t uid; 278246074Sgabor gid_t gid; 279246074Sgabor{ 280246074Sgabor# if HASFCHOWN 281246074Sgabor int fd; 282246074Sgabor int result; 283246074Sgabor DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 284246074Sgabor 285246074Sgabor fd = db->fd(db); 286246074Sgabor if (fd == -1) 287246074Sgabor return errno; 288246074Sgabor 289246074Sgabor result = fchown(fd, uid, gid); 290246074Sgabor if (result < 0) 291246074Sgabor return errno; 292246074Sgabor# endif /* HASFCHOWN */ 293246074Sgabor 294246074Sgabor return SMDBE_OK; 295246074Sgabor} 296246074Sgabor 297246074Sgaborstatic int 298246074Sgaborsmdb1_sync(database, flags) 299246074Sgabor SMDB_DATABASE *database; 300246074Sgabor unsigned int flags; 301246074Sgabor{ 302246074Sgabor DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 303246074Sgabor 304246074Sgabor return db->sync(db, flags); 305246074Sgabor} 306246074Sgabor 307246074Sgaborstatic int 308246074Sgaborsmdb1_cursor_close(cursor) 309246074Sgabor SMDB_CURSOR *cursor; 310246074Sgabor{ 311246074Sgabor SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 312246074Sgabor SMDB_DB1_DATABASE *db1 = db1_cursor->db; 313246074Sgabor 314246074Sgabor if (!db1->smdb1_cursor_in_use) 315246074Sgabor return SMDBE_NOT_A_VALID_CURSOR; 316246074Sgabor 317246074Sgabor db1->smdb1_cursor_in_use = false; 318246074Sgabor free(cursor); 319246074Sgabor 320246074Sgabor return SMDBE_OK; 321246074Sgabor} 322246074Sgabor 323246074Sgaborstatic int 324246074Sgaborsmdb1_cursor_del(cursor, flags) 325246074Sgabor SMDB_CURSOR *cursor; 326246074Sgabor unsigned int flags; 327246074Sgabor{ 328246074Sgabor SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 329246074Sgabor SMDB_DB1_DATABASE *db1 = db1_cursor->db; 330246074Sgabor DB *db = db1->smdb1_db; 331246074Sgabor 332246074Sgabor return db->del(db, NULL, R_CURSOR); 333246074Sgabor} 334246074Sgabor 335246074Sgaborstatic int 336246074Sgaborsmdb1_cursor_get(cursor, key, value, flags) 337246074Sgabor SMDB_CURSOR *cursor; 338246074Sgabor SMDB_DBENT *key; 339246074Sgabor SMDB_DBENT *value; 340246074Sgabor SMDB_FLAG flags; 341246074Sgabor{ 342246074Sgabor int db1_flags; 343246074Sgabor int result; 344246074Sgabor SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 345246074Sgabor SMDB_DB1_DATABASE *db1 = db1_cursor->db; 346246074Sgabor DB *db = db1->smdb1_db; 347246074Sgabor DBT dbkey, dbdata; 348246074Sgabor 349246074Sgabor (void) memset(&dbdata, '\0', sizeof dbdata); 350246074Sgabor (void) memset(&dbkey, '\0', sizeof dbkey); 351246074Sgabor 352246074Sgabor db1_flags = smdb_cursor_get_flags_to_smdb1(flags); 353246074Sgabor result = db->seq(db, &dbkey, &dbdata, db1_flags); 354246074Sgabor if (result == -1) 355246074Sgabor return errno; 356246074Sgabor if (result == 1) 357246074Sgabor return SMDBE_LAST_ENTRY; 358246074Sgabor value->data = dbdata.data; 359246074Sgabor value->size = dbdata.size; 360246074Sgabor key->data = dbkey.data; 361246074Sgabor key->size = dbkey.size; 362246074Sgabor return SMDBE_OK; 363246074Sgabor} 364246074Sgabor 365246074Sgaborstatic int 366246074Sgaborsmdb1_cursor_put(cursor, key, value, flags) 367246074Sgabor SMDB_CURSOR *cursor; 368246074Sgabor SMDB_DBENT *key; 369246074Sgabor SMDB_DBENT *value; 370246074Sgabor SMDB_FLAG flags; 371246074Sgabor{ 372246074Sgabor SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 373246074Sgabor SMDB_DB1_DATABASE *db1 = db1_cursor->db; 374246074Sgabor DB *db = db1->smdb1_db; 375246074Sgabor DBT dbkey, dbdata; 376246074Sgabor 377246074Sgabor (void) memset(&dbdata, '\0', sizeof dbdata); 378246074Sgabor (void) memset(&dbkey, '\0', sizeof dbkey); 379246074Sgabor dbkey.data = key->data; 380246074Sgabor dbkey.size = key->size; 381246074Sgabor dbdata.data = value->data; 382246074Sgabor dbdata.size = value->size; 383246074Sgabor 384246074Sgabor return db->put(db, &dbkey, &dbdata, R_CURSOR); 385246074Sgabor} 386246074Sgabor 387246074Sgaborstatic int 388246074Sgaborsmdb1_cursor(database, cursor, flags) 389246074Sgabor SMDB_DATABASE *database; 390246074Sgabor SMDB_CURSOR **cursor; 391246074Sgabor unsigned int flags; 392246074Sgabor{ 393246074Sgabor SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl; 394246074Sgabor SMDB_CURSOR *cur; 395246074Sgabor SMDB_DB1_CURSOR *db1_cursor; 396246074Sgabor 397246074Sgabor if (db1->smdb1_cursor_in_use) 398246074Sgabor return SMDBE_ONLY_SUPPORTS_ONE_CURSOR; 399246074Sgabor 400246074Sgabor db1_cursor = (SMDB_DB1_CURSOR *) malloc(sizeof(SMDB_DB1_CURSOR)); 401246074Sgabor if (db1_cursor == NULL) 402246074Sgabor return SMDBE_MALLOC; 403246074Sgabor 404246074Sgabor cur = (SMDB_CURSOR *) malloc(sizeof(SMDB_CURSOR)); 405246074Sgabor if (cur == NULL) 406246074Sgabor { 407246074Sgabor free(db1_cursor); 408246074Sgabor return SMDBE_MALLOC; 409246074Sgabor } 410246074Sgabor 411246074Sgabor db1->smdb1_cursor_in_use = true; 412246074Sgabor db1_cursor->db = db1; 413246074Sgabor cur->smdbc_impl = db1_cursor; 414246074Sgabor cur->smdbc_close = smdb1_cursor_close; 415246074Sgabor cur->smdbc_del = smdb1_cursor_del; 416246074Sgabor cur->smdbc_get = smdb1_cursor_get; 417246074Sgabor cur->smdbc_put = smdb1_cursor_put; 418246074Sgabor *cursor = cur; 419246074Sgabor 420246074Sgabor return SMDBE_OK; 421246074Sgabor} 422246074Sgabor/* 423246074Sgabor** SMDB_DB_OPEN -- Opens a db1 database. 424246074Sgabor** 425246074Sgabor** Parameters: 426246074Sgabor** database -- An unallocated database pointer to a pointer. 427246074Sgabor** db_name -- The name of the database without extension. 428246074Sgabor** mode -- File permisions on the database if created. 429246074Sgabor** mode_mask -- Mode bits that must match on an existing database. 430246074Sgabor** sff -- Flags for safefile. 431246074Sgabor** type -- The type of database to open 432246074Sgabor** See smdb_type_to_db1_type for valid types. 433246074Sgabor** user_info -- Information on the user to use for file 434246074Sgabor** permissions. 435246074Sgabor** db_params -- 436246074Sgabor** An SMDB_DBPARAMS struct including params. These 437246074Sgabor** are processed according to the type of the 438246074Sgabor** database. Currently supported params (only for 439246074Sgabor** HASH type) are: 440246074Sgabor** num_elements 441246074Sgabor** cache_size 442246074Sgabor** 443246074Sgabor** Returns: 444246074Sgabor** SMDBE_OK -- Success, otherwise errno. 445246074Sgabor*/ 446246074Sgabor 447246074Sgaborint 448246074Sgaborsmdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info, 449246074Sgabor db_params) 450246074Sgabor SMDB_DATABASE **database; 451246074Sgabor char *db_name; 452246074Sgabor int mode; 453246074Sgabor int mode_mask; 454246074Sgabor long sff; 455246074Sgabor SMDB_DBTYPE type; 456246074Sgabor SMDB_USER_INFO *user_info; 457246074Sgabor SMDB_DBPARAMS *db_params; 458246074Sgabor{ 459246074Sgabor bool lockcreated = false; 460246074Sgabor int db_fd; 461246074Sgabor int lock_fd; 462246074Sgabor int result; 463246074Sgabor void *params; 464246074Sgabor SMDB_DATABASE *smdb_db; 465246074Sgabor SMDB_DB1_DATABASE *db1; 466246074Sgabor DB *db; 467246074Sgabor HASHINFO hash_info; 468246074Sgabor BTREEINFO btree_info; 469246074Sgabor DBTYPE db_type; 470246074Sgabor struct stat stat_info; 471246074Sgabor char db_file_name[MAXPATHLEN]; 472246074Sgabor 473246074Sgabor if (type == NULL || 474246074Sgabor (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) != 0 && 475246074Sgabor strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) != 0)) 476246074Sgabor return SMDBE_UNKNOWN_DB_TYPE; 477246074Sgabor 478246074Sgabor result = smdb_add_extension(db_file_name, sizeof db_file_name, 479246074Sgabor db_name, SMDB1_FILE_EXTENSION); 480246074Sgabor if (result != SMDBE_OK) 481246074Sgabor return result; 482246074Sgabor 483246074Sgabor result = smdb_setup_file(db_name, SMDB1_FILE_EXTENSION, mode_mask, 484246074Sgabor sff, user_info, &stat_info); 485246074Sgabor if (result != SMDBE_OK) 486246074Sgabor return result; 487246074Sgabor 488246074Sgabor if (stat_info.st_mode == ST_MODE_NOFILE && 489246074Sgabor bitset(mode, O_CREAT)) 490246074Sgabor lockcreated = true; 491246074Sgabor 492246074Sgabor lock_fd = -1; 493246074Sgabor result = smdb_lock_file(&lock_fd, db_name, mode, sff, 494246074Sgabor SMDB1_FILE_EXTENSION); 495246074Sgabor if (result != SMDBE_OK) 496246074Sgabor return result; 497246074Sgabor 498246074Sgabor if (lockcreated) 499246074Sgabor { 500246074Sgabor mode |= O_TRUNC; 501246074Sgabor mode &= ~(O_CREAT|O_EXCL); 502246074Sgabor } 503246074Sgabor 504246074Sgabor *database = NULL; 505 506 smdb_db = smdb_malloc_database(); 507 db1 = smdb1_malloc_database(); 508 if (smdb_db == NULL || db1 == NULL) 509 { 510 (void) smdb_unlock_file(lock_fd); 511 smdb_free_database(smdb_db); 512 free(db1); 513 return SMDBE_MALLOC; 514 } 515 db1->smdb1_lock_fd = lock_fd; 516 517 params = NULL; 518 if (db_params != NULL && 519 (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) == 0)) 520 { 521 (void) memset(&hash_info, '\0', sizeof hash_info); 522 hash_info.nelem = db_params->smdbp_num_elements; 523 hash_info.cachesize = db_params->smdbp_cache_size; 524 params = &hash_info; 525 } 526 527 if (db_params != NULL && 528 (strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) == 0)) 529 { 530 (void) memset(&btree_info, '\0', sizeof btree_info); 531 btree_info.cachesize = db_params->smdbp_cache_size; 532 if (db_params->smdbp_allow_dup) 533 btree_info.flags |= R_DUP; 534 params = &btree_info; 535 } 536 537 db_type = smdb_type_to_db1_type(type); 538 db = dbopen(db_file_name, mode, DBMMODE, db_type, params); 539 if (db != NULL) 540 { 541 db_fd = db->fd(db); 542 result = smdb_filechanged(db_name, SMDB1_FILE_EXTENSION, db_fd, 543 &stat_info); 544 } 545 else 546 { 547 if (errno == 0) 548 result = SMDBE_BAD_OPEN; 549 else 550 result = errno; 551 } 552 553 if (result == SMDBE_OK) 554 { 555 /* Everything is ok. Setup driver */ 556 db1->smdb1_db = db; 557 558 smdb_db->smdb_close = smdb1_close; 559 smdb_db->smdb_del = smdb1_del; 560 smdb_db->smdb_fd = smdb1_fd; 561 smdb_db->smdb_lockfd = smdb1_lockfd; 562 smdb_db->smdb_get = smdb1_get; 563 smdb_db->smdb_put = smdb1_put; 564 smdb_db->smdb_set_owner = smdb1_set_owner; 565 smdb_db->smdb_sync = smdb1_sync; 566 smdb_db->smdb_cursor = smdb1_cursor; 567 smdb_db->smdb_impl = db1; 568 569 *database = smdb_db; 570 return SMDBE_OK; 571 } 572 573 if (db != NULL) 574 (void) db->close(db); 575 576 /* Error opening database */ 577 (void) smdb_unlock_file(db1->smdb1_lock_fd); 578 free(db1); 579 smdb_free_database(smdb_db); 580 581 return result; 582} 583 584#endif /* (DB_VERSION_MAJOR == 1) */ 585