164562Sgshapiro/* 2261363Sgshapiro** Copyright (c) 1999-2002, 2004, 2009 Proofpoint, Inc. and its suppliers. 364562Sgshapiro** All rights reserved. 464562Sgshapiro** 564562Sgshapiro** By using this file, you agree to the terms and conditions set 664562Sgshapiro** forth in the LICENSE file which can be found at the top level of 764562Sgshapiro** the sendmail distribution. 864562Sgshapiro*/ 964562Sgshapiro 1090792Sgshapiro#include <sm/gen.h> 11266692SgshapiroSM_RCSID("@(#)$Id: smdb1.c,v 8.63 2013-11-22 20:51:49 ca Exp $") 1264562Sgshapiro 1364562Sgshapiro#include <unistd.h> 1464562Sgshapiro#include <stdlib.h> 1564562Sgshapiro#include <fcntl.h> 1664562Sgshapiro 1764562Sgshapiro#include <sendmail/sendmail.h> 1864562Sgshapiro#include <libsmdb/smdb.h> 1964562Sgshapiro 2064562Sgshapiro#if (DB_VERSION_MAJOR == 1) 2164562Sgshapiro 2264562Sgshapiro# define SMDB1_FILE_EXTENSION "db" 2364562Sgshapiro 2464562Sgshapirostruct smdb_db1_struct 2564562Sgshapiro{ 2664562Sgshapiro DB *smdb1_db; 2764562Sgshapiro int smdb1_lock_fd; 2864562Sgshapiro bool smdb1_cursor_in_use; 2964562Sgshapiro}; 3064562Sgshapirotypedef struct smdb_db1_struct SMDB_DB1_DATABASE; 3164562Sgshapiro 3264562Sgshapirostruct smdb_db1_cursor 3364562Sgshapiro{ 3464562Sgshapiro SMDB_DB1_DATABASE *db; 3564562Sgshapiro}; 3664562Sgshapirotypedef struct smdb_db1_cursor SMDB_DB1_CURSOR; 3764562Sgshapiro 38141858Sgshapirostatic DBTYPE smdb_type_to_db1_type __P((SMDB_DBTYPE)); 39141858Sgshapirostatic unsigned int smdb_put_flags_to_db1_flags __P((SMDB_FLAG)); 40141858Sgshapirostatic int smdb_cursor_get_flags_to_smdb1 __P((SMDB_FLAG)); 41141858Sgshapirostatic SMDB_DB1_DATABASE *smdb1_malloc_database __P((void)); 42141858Sgshapirostatic int smdb1_close __P((SMDB_DATABASE *)); 43141858Sgshapirostatic int smdb1_del __P((SMDB_DATABASE *, SMDB_DBENT *, unsigned int)); 44141858Sgshapirostatic int smdb1_fd __P((SMDB_DATABASE *, int *)); 45141858Sgshapirostatic int smdb1_lockfd __P((SMDB_DATABASE *)); 46141858Sgshapirostatic int smdb1_get __P((SMDB_DATABASE *, SMDB_DBENT *, SMDB_DBENT *, unsigned int)); 47141858Sgshapirostatic int smdb1_put __P((SMDB_DATABASE *, SMDB_DBENT *, SMDB_DBENT *, unsigned int)); 48141858Sgshapirostatic int smdb1_set_owner __P((SMDB_DATABASE *, uid_t, gid_t)); 49141858Sgshapirostatic int smdb1_sync __P((SMDB_DATABASE *, unsigned int)); 50141858Sgshapirostatic int smdb1_cursor_close __P((SMDB_CURSOR *)); 51141858Sgshapirostatic int smdb1_cursor_del __P((SMDB_CURSOR *, unsigned int)); 52141858Sgshapirostatic int smdb1_cursor_get __P((SMDB_CURSOR *, SMDB_DBENT *, SMDB_DBENT *, SMDB_FLAG)); 53141858Sgshapirostatic int smdb1_cursor_put __P((SMDB_CURSOR *, SMDB_DBENT *, SMDB_DBENT *, SMDB_FLAG)); 54141858Sgshapirostatic int smdb1_cursor __P((SMDB_DATABASE *, SMDB_CURSOR **, unsigned int)); 55141858Sgshapiro 5690792Sgshapiro/* 5764562Sgshapiro** SMDB_TYPE_TO_DB1_TYPE -- Translates smdb database type to db1 type. 5864562Sgshapiro** 5964562Sgshapiro** Parameters: 6064562Sgshapiro** type -- The type to translate. 6164562Sgshapiro** 6264562Sgshapiro** Returns: 6364562Sgshapiro** The DB1 type that corresponsds to the passed in SMDB type. 6464562Sgshapiro** Returns -1 if there is no equivalent type. 6564562Sgshapiro** 6664562Sgshapiro*/ 6764562Sgshapiro 68141858Sgshapirostatic DBTYPE 6964562Sgshapirosmdb_type_to_db1_type(type) 7064562Sgshapiro SMDB_DBTYPE type; 7164562Sgshapiro{ 7264562Sgshapiro if (type == SMDB_TYPE_DEFAULT) 7364562Sgshapiro return DB_HASH; 7464562Sgshapiro 7564562Sgshapiro if (strncmp(type, SMDB_TYPE_HASH, SMDB_TYPE_HASH_LEN) == 0) 7664562Sgshapiro return DB_HASH; 7764562Sgshapiro 7864562Sgshapiro if (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0) 7964562Sgshapiro return DB_BTREE; 8064562Sgshapiro 8164562Sgshapiro /* Should never get here thanks to test in smdb_db_open() */ 8264562Sgshapiro return DB_HASH; 8364562Sgshapiro} 8490792Sgshapiro/* 8564562Sgshapiro** SMDB_PUT_FLAGS_TO_DB1_FLAGS -- Translates smdb put flags to db1 put flags. 8664562Sgshapiro** 8764562Sgshapiro** Parameters: 8864562Sgshapiro** flags -- The flags to translate. 8964562Sgshapiro** 9064562Sgshapiro** Returns: 9164562Sgshapiro** The db1 flags that are equivalent to the smdb flags. 9264562Sgshapiro** 9364562Sgshapiro** Notes: 9464562Sgshapiro** Any invalid flags are ignored. 9564562Sgshapiro** 9664562Sgshapiro*/ 9764562Sgshapiro 98141858Sgshapirostatic unsigned int 9964562Sgshapirosmdb_put_flags_to_db1_flags(flags) 10064562Sgshapiro SMDB_FLAG flags; 10164562Sgshapiro{ 10264562Sgshapiro int return_flags; 10364562Sgshapiro 10464562Sgshapiro return_flags = 0; 10564562Sgshapiro 10664562Sgshapiro if (bitset(SMDBF_NO_OVERWRITE, flags)) 10764562Sgshapiro return_flags |= R_NOOVERWRITE; 10864562Sgshapiro 10964562Sgshapiro return return_flags; 11064562Sgshapiro} 11190792Sgshapiro/* 11264562Sgshapiro** SMDB_CURSOR_GET_FLAGS_TO_SMDB1 11364562Sgshapiro** 11464562Sgshapiro** Parameters: 11564562Sgshapiro** flags -- The flags to translate. 11664562Sgshapiro** 11764562Sgshapiro** Returns: 11864562Sgshapiro** The db1 flags that are equivalent to the smdb flags. 11964562Sgshapiro** 12064562Sgshapiro** Notes: 12164562Sgshapiro** Returns -1 if we don't support the flag. 12264562Sgshapiro** 12364562Sgshapiro*/ 12464562Sgshapiro 125141858Sgshapirostatic int 12664562Sgshapirosmdb_cursor_get_flags_to_smdb1(flags) 12764562Sgshapiro SMDB_FLAG flags; 12864562Sgshapiro{ 12964562Sgshapiro switch(flags) 13064562Sgshapiro { 13164562Sgshapiro case SMDB_CURSOR_GET_FIRST: 13264562Sgshapiro return R_FIRST; 13364562Sgshapiro 13464562Sgshapiro case SMDB_CURSOR_GET_LAST: 13564562Sgshapiro return R_LAST; 13664562Sgshapiro 13764562Sgshapiro case SMDB_CURSOR_GET_NEXT: 13864562Sgshapiro return R_NEXT; 13964562Sgshapiro 14064562Sgshapiro case SMDB_CURSOR_GET_RANGE: 14164562Sgshapiro return R_CURSOR; 14264562Sgshapiro 14364562Sgshapiro default: 14464562Sgshapiro return -1; 14564562Sgshapiro } 14664562Sgshapiro} 14764562Sgshapiro 14890792Sgshapiro/* 14990792Sgshapiro** The rest of these functions correspond to the interface laid out in smdb.h. 15090792Sgshapiro*/ 15190792Sgshapiro 152141858Sgshapirostatic SMDB_DB1_DATABASE * 15364562Sgshapirosmdb1_malloc_database() 15464562Sgshapiro{ 15564562Sgshapiro SMDB_DB1_DATABASE *db1; 15664562Sgshapiro 15764562Sgshapiro db1 = (SMDB_DB1_DATABASE *) malloc(sizeof(SMDB_DB1_DATABASE)); 15864562Sgshapiro 15964562Sgshapiro if (db1 != NULL) 16064562Sgshapiro { 16164562Sgshapiro db1->smdb1_lock_fd = -1; 16290792Sgshapiro db1->smdb1_cursor_in_use = false; 16364562Sgshapiro } 16464562Sgshapiro 16564562Sgshapiro return db1; 16664562Sgshapiro} 16764562Sgshapiro 168141858Sgshapirostatic int 16964562Sgshapirosmdb1_close(database) 17064562Sgshapiro SMDB_DATABASE *database; 17164562Sgshapiro{ 17290792Sgshapiro int result; 17364562Sgshapiro SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl; 17464562Sgshapiro DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 17564562Sgshapiro 17690792Sgshapiro result = db->close(db); 17764562Sgshapiro if (db1->smdb1_lock_fd != -1) 17864562Sgshapiro (void) close(db1->smdb1_lock_fd); 17964562Sgshapiro 18064562Sgshapiro free(db1); 18164562Sgshapiro database->smdb_impl = NULL; 18264562Sgshapiro 18390792Sgshapiro return result; 18464562Sgshapiro} 18564562Sgshapiro 186141858Sgshapirostatic int 18764562Sgshapirosmdb1_del(database, key, flags) 18864562Sgshapiro SMDB_DATABASE *database; 18964562Sgshapiro SMDB_DBENT *key; 19090792Sgshapiro unsigned int flags; 19164562Sgshapiro{ 19264562Sgshapiro DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 19371345Sgshapiro DBT dbkey; 19464562Sgshapiro 19590792Sgshapiro (void) memset(&dbkey, '\0', sizeof dbkey); 19671345Sgshapiro dbkey.data = key->data; 19771345Sgshapiro dbkey.size = key->size; 19871345Sgshapiro return db->del(db, &dbkey, flags); 19964562Sgshapiro} 20064562Sgshapiro 201141858Sgshapirostatic int 20264562Sgshapirosmdb1_fd(database, fd) 20364562Sgshapiro SMDB_DATABASE *database; 20464562Sgshapiro int *fd; 20564562Sgshapiro{ 20664562Sgshapiro DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 20764562Sgshapiro 20864562Sgshapiro *fd = db->fd(db); 20964562Sgshapiro if (*fd == -1) 21064562Sgshapiro return errno; 21164562Sgshapiro 21264562Sgshapiro return SMDBE_OK; 21364562Sgshapiro} 21464562Sgshapiro 215141858Sgshapirostatic int 21666494Sgshapirosmdb1_lockfd(database) 21766494Sgshapiro SMDB_DATABASE *database; 21866494Sgshapiro{ 21966494Sgshapiro SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl; 22066494Sgshapiro 22166494Sgshapiro return db1->smdb1_lock_fd; 22266494Sgshapiro} 22366494Sgshapiro 22466494Sgshapiro 225141858Sgshapirostatic int 22664562Sgshapirosmdb1_get(database, key, data, flags) 22764562Sgshapiro SMDB_DATABASE *database; 22864562Sgshapiro SMDB_DBENT *key; 22964562Sgshapiro SMDB_DBENT *data; 23090792Sgshapiro unsigned int flags; 23164562Sgshapiro{ 23264562Sgshapiro int result; 23364562Sgshapiro DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 23471345Sgshapiro DBT dbkey, dbdata; 23564562Sgshapiro 23690792Sgshapiro (void) memset(&dbdata, '\0', sizeof dbdata); 23790792Sgshapiro (void) memset(&dbkey, '\0', sizeof dbkey); 23871345Sgshapiro dbkey.data = key->data; 23971345Sgshapiro dbkey.size = key->size; 24071345Sgshapiro 24171345Sgshapiro result = db->get(db, &dbkey, &dbdata, flags); 24264562Sgshapiro if (result != 0) 24364562Sgshapiro { 24464562Sgshapiro if (result == 1) 24564562Sgshapiro return SMDBE_NOT_FOUND; 24664562Sgshapiro return errno; 24764562Sgshapiro } 24871345Sgshapiro data->data = dbdata.data; 24971345Sgshapiro data->size = dbdata.size; 25064562Sgshapiro return SMDBE_OK; 25164562Sgshapiro} 25264562Sgshapiro 253141858Sgshapirostatic int 25464562Sgshapirosmdb1_put(database, key, data, flags) 25564562Sgshapiro SMDB_DATABASE *database; 25664562Sgshapiro SMDB_DBENT *key; 25764562Sgshapiro SMDB_DBENT *data; 25890792Sgshapiro unsigned int flags; 25964562Sgshapiro{ 26064562Sgshapiro DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 26171345Sgshapiro DBT dbkey, dbdata; 26264562Sgshapiro 26390792Sgshapiro (void) memset(&dbdata, '\0', sizeof dbdata); 26490792Sgshapiro (void) memset(&dbkey, '\0', sizeof dbkey); 26571345Sgshapiro dbkey.data = key->data; 26671345Sgshapiro dbkey.size = key->size; 26771345Sgshapiro dbdata.data = data->data; 26871345Sgshapiro dbdata.size = data->size; 26971345Sgshapiro 27071345Sgshapiro return db->put(db, &dbkey, &dbdata, 27171345Sgshapiro smdb_put_flags_to_db1_flags(flags)); 27264562Sgshapiro} 27364562Sgshapiro 274141858Sgshapirostatic int 27564562Sgshapirosmdb1_set_owner(database, uid, gid) 27664562Sgshapiro SMDB_DATABASE *database; 27764562Sgshapiro uid_t uid; 27864562Sgshapiro gid_t gid; 27964562Sgshapiro{ 28064562Sgshapiro# if HASFCHOWN 28164562Sgshapiro int fd; 28264562Sgshapiro int result; 28364562Sgshapiro DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 28464562Sgshapiro 28564562Sgshapiro fd = db->fd(db); 28664562Sgshapiro if (fd == -1) 28764562Sgshapiro return errno; 28864562Sgshapiro 28964562Sgshapiro result = fchown(fd, uid, gid); 29064562Sgshapiro if (result < 0) 29164562Sgshapiro return errno; 29264562Sgshapiro# endif /* HASFCHOWN */ 29364562Sgshapiro 29464562Sgshapiro return SMDBE_OK; 29564562Sgshapiro} 29664562Sgshapiro 297141858Sgshapirostatic int 29864562Sgshapirosmdb1_sync(database, flags) 29964562Sgshapiro SMDB_DATABASE *database; 30090792Sgshapiro unsigned int flags; 30164562Sgshapiro{ 30264562Sgshapiro DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 30364562Sgshapiro 30464562Sgshapiro return db->sync(db, flags); 30564562Sgshapiro} 30664562Sgshapiro 307141858Sgshapirostatic int 30864562Sgshapirosmdb1_cursor_close(cursor) 30964562Sgshapiro SMDB_CURSOR *cursor; 31064562Sgshapiro{ 31164562Sgshapiro SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 31264562Sgshapiro SMDB_DB1_DATABASE *db1 = db1_cursor->db; 31364562Sgshapiro 31464562Sgshapiro if (!db1->smdb1_cursor_in_use) 31564562Sgshapiro return SMDBE_NOT_A_VALID_CURSOR; 31664562Sgshapiro 31790792Sgshapiro db1->smdb1_cursor_in_use = false; 31864562Sgshapiro free(cursor); 31964562Sgshapiro 32064562Sgshapiro return SMDBE_OK; 32164562Sgshapiro} 32264562Sgshapiro 323141858Sgshapirostatic int 32464562Sgshapirosmdb1_cursor_del(cursor, flags) 32564562Sgshapiro SMDB_CURSOR *cursor; 32690792Sgshapiro unsigned int flags; 32764562Sgshapiro{ 32864562Sgshapiro SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 32964562Sgshapiro SMDB_DB1_DATABASE *db1 = db1_cursor->db; 33064562Sgshapiro DB *db = db1->smdb1_db; 33164562Sgshapiro 33264562Sgshapiro return db->del(db, NULL, R_CURSOR); 33364562Sgshapiro} 33464562Sgshapiro 335141858Sgshapirostatic int 33664562Sgshapirosmdb1_cursor_get(cursor, key, value, flags) 33764562Sgshapiro SMDB_CURSOR *cursor; 33864562Sgshapiro SMDB_DBENT *key; 33964562Sgshapiro SMDB_DBENT *value; 34064562Sgshapiro SMDB_FLAG flags; 34164562Sgshapiro{ 34264562Sgshapiro int db1_flags; 34364562Sgshapiro int result; 34464562Sgshapiro SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 34564562Sgshapiro SMDB_DB1_DATABASE *db1 = db1_cursor->db; 34664562Sgshapiro DB *db = db1->smdb1_db; 34771345Sgshapiro DBT dbkey, dbdata; 34864562Sgshapiro 34990792Sgshapiro (void) memset(&dbdata, '\0', sizeof dbdata); 35090792Sgshapiro (void) memset(&dbkey, '\0', sizeof dbkey); 35171345Sgshapiro 35264562Sgshapiro db1_flags = smdb_cursor_get_flags_to_smdb1(flags); 35371345Sgshapiro result = db->seq(db, &dbkey, &dbdata, db1_flags); 35464562Sgshapiro if (result == -1) 35564562Sgshapiro return errno; 35664562Sgshapiro if (result == 1) 35764562Sgshapiro return SMDBE_LAST_ENTRY; 35871345Sgshapiro value->data = dbdata.data; 35971345Sgshapiro value->size = dbdata.size; 36071345Sgshapiro key->data = dbkey.data; 36171345Sgshapiro key->size = dbkey.size; 36264562Sgshapiro return SMDBE_OK; 36364562Sgshapiro} 36464562Sgshapiro 365141858Sgshapirostatic int 36664562Sgshapirosmdb1_cursor_put(cursor, key, value, flags) 36764562Sgshapiro SMDB_CURSOR *cursor; 36864562Sgshapiro SMDB_DBENT *key; 36964562Sgshapiro SMDB_DBENT *value; 37064562Sgshapiro SMDB_FLAG flags; 37164562Sgshapiro{ 37264562Sgshapiro SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 37364562Sgshapiro SMDB_DB1_DATABASE *db1 = db1_cursor->db; 37464562Sgshapiro DB *db = db1->smdb1_db; 37571345Sgshapiro DBT dbkey, dbdata; 37664562Sgshapiro 37790792Sgshapiro (void) memset(&dbdata, '\0', sizeof dbdata); 37890792Sgshapiro (void) memset(&dbkey, '\0', sizeof dbkey); 37971345Sgshapiro dbkey.data = key->data; 38071345Sgshapiro dbkey.size = key->size; 38171345Sgshapiro dbdata.data = value->data; 38271345Sgshapiro dbdata.size = value->size; 38371345Sgshapiro 38471345Sgshapiro return db->put(db, &dbkey, &dbdata, R_CURSOR); 38564562Sgshapiro} 38664562Sgshapiro 387141858Sgshapirostatic int 38864562Sgshapirosmdb1_cursor(database, cursor, flags) 38964562Sgshapiro SMDB_DATABASE *database; 39064562Sgshapiro SMDB_CURSOR **cursor; 39190792Sgshapiro unsigned int flags; 39264562Sgshapiro{ 39364562Sgshapiro SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl; 39464562Sgshapiro SMDB_CURSOR *cur; 39564562Sgshapiro SMDB_DB1_CURSOR *db1_cursor; 39664562Sgshapiro 39764562Sgshapiro if (db1->smdb1_cursor_in_use) 39864562Sgshapiro return SMDBE_ONLY_SUPPORTS_ONE_CURSOR; 39964562Sgshapiro 40064562Sgshapiro db1_cursor = (SMDB_DB1_CURSOR *) malloc(sizeof(SMDB_DB1_CURSOR)); 401203004Sgshapiro if (db1_cursor == NULL) 402203004Sgshapiro return SMDBE_MALLOC; 40364562Sgshapiro 40464562Sgshapiro cur = (SMDB_CURSOR *) malloc(sizeof(SMDB_CURSOR)); 40564562Sgshapiro if (cur == NULL) 406203004Sgshapiro { 407203004Sgshapiro free(db1_cursor); 40864562Sgshapiro return SMDBE_MALLOC; 409203004Sgshapiro } 41064562Sgshapiro 411203004Sgshapiro db1->smdb1_cursor_in_use = true; 412203004Sgshapiro db1_cursor->db = db1; 41364562Sgshapiro cur->smdbc_impl = db1_cursor; 41464562Sgshapiro cur->smdbc_close = smdb1_cursor_close; 41564562Sgshapiro cur->smdbc_del = smdb1_cursor_del; 41664562Sgshapiro cur->smdbc_get = smdb1_cursor_get; 41764562Sgshapiro cur->smdbc_put = smdb1_cursor_put; 41864562Sgshapiro *cursor = cur; 41964562Sgshapiro 42064562Sgshapiro return SMDBE_OK; 42164562Sgshapiro} 42290792Sgshapiro/* 42364562Sgshapiro** SMDB_DB_OPEN -- Opens a db1 database. 42464562Sgshapiro** 42564562Sgshapiro** Parameters: 42664562Sgshapiro** database -- An unallocated database pointer to a pointer. 42764562Sgshapiro** db_name -- The name of the database without extension. 42864562Sgshapiro** mode -- File permisions on the database if created. 42964562Sgshapiro** mode_mask -- Mode bits that must match on an existing database. 43064562Sgshapiro** sff -- Flags for safefile. 43164562Sgshapiro** type -- The type of database to open 43264562Sgshapiro** See smdb_type_to_db1_type for valid types. 43364562Sgshapiro** user_info -- Information on the user to use for file 43464562Sgshapiro** permissions. 43564562Sgshapiro** db_params -- 43664562Sgshapiro** An SMDB_DBPARAMS struct including params. These 43764562Sgshapiro** are processed according to the type of the 43864562Sgshapiro** database. Currently supported params (only for 43964562Sgshapiro** HASH type) are: 44064562Sgshapiro** num_elements 44164562Sgshapiro** cache_size 44264562Sgshapiro** 44364562Sgshapiro** Returns: 44464562Sgshapiro** SMDBE_OK -- Success, otherwise errno. 44564562Sgshapiro*/ 44664562Sgshapiro 44764562Sgshapiroint 44864562Sgshapirosmdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info, 44964562Sgshapiro db_params) 45064562Sgshapiro SMDB_DATABASE **database; 45164562Sgshapiro char *db_name; 45264562Sgshapiro int mode; 45364562Sgshapiro int mode_mask; 45464562Sgshapiro long sff; 45564562Sgshapiro SMDB_DBTYPE type; 45664562Sgshapiro SMDB_USER_INFO *user_info; 45764562Sgshapiro SMDB_DBPARAMS *db_params; 45864562Sgshapiro{ 45994334Sgshapiro bool lockcreated = false; 46064562Sgshapiro int db_fd; 46164562Sgshapiro int lock_fd; 46264562Sgshapiro int result; 46364562Sgshapiro void *params; 46464562Sgshapiro SMDB_DATABASE *smdb_db; 46564562Sgshapiro SMDB_DB1_DATABASE *db1; 46664562Sgshapiro DB *db; 46764562Sgshapiro HASHINFO hash_info; 46864562Sgshapiro BTREEINFO btree_info; 46964562Sgshapiro DBTYPE db_type; 47064562Sgshapiro struct stat stat_info; 47198121Sgshapiro char db_file_name[MAXPATHLEN]; 47264562Sgshapiro 47364562Sgshapiro if (type == NULL || 47464562Sgshapiro (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) != 0 && 47564562Sgshapiro strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) != 0)) 47664562Sgshapiro return SMDBE_UNKNOWN_DB_TYPE; 47764562Sgshapiro 47898121Sgshapiro result = smdb_add_extension(db_file_name, sizeof db_file_name, 47964562Sgshapiro db_name, SMDB1_FILE_EXTENSION); 48064562Sgshapiro if (result != SMDBE_OK) 48164562Sgshapiro return result; 48264562Sgshapiro 48364562Sgshapiro result = smdb_setup_file(db_name, SMDB1_FILE_EXTENSION, mode_mask, 48464562Sgshapiro sff, user_info, &stat_info); 48564562Sgshapiro if (result != SMDBE_OK) 48664562Sgshapiro return result; 48764562Sgshapiro 48894334Sgshapiro if (stat_info.st_mode == ST_MODE_NOFILE && 48994334Sgshapiro bitset(mode, O_CREAT)) 49094334Sgshapiro lockcreated = true; 49194334Sgshapiro 49264562Sgshapiro lock_fd = -1; 49364562Sgshapiro result = smdb_lock_file(&lock_fd, db_name, mode, sff, 49464562Sgshapiro SMDB1_FILE_EXTENSION); 49564562Sgshapiro if (result != SMDBE_OK) 49664562Sgshapiro return result; 49764562Sgshapiro 49894334Sgshapiro if (lockcreated) 49994334Sgshapiro { 50094334Sgshapiro mode |= O_TRUNC; 50194334Sgshapiro mode &= ~(O_CREAT|O_EXCL); 50294334Sgshapiro } 50394334Sgshapiro 50464562Sgshapiro *database = NULL; 50564562Sgshapiro 50664562Sgshapiro smdb_db = smdb_malloc_database(); 50764562Sgshapiro db1 = smdb1_malloc_database(); 50864562Sgshapiro if (smdb_db == NULL || db1 == NULL) 509203004Sgshapiro { 510203004Sgshapiro (void) smdb_unlock_file(lock_fd); 511203004Sgshapiro smdb_free_database(smdb_db); 512203004Sgshapiro free(db1); 51364562Sgshapiro return SMDBE_MALLOC; 514203004Sgshapiro } 51564562Sgshapiro db1->smdb1_lock_fd = lock_fd; 51664562Sgshapiro 51764562Sgshapiro params = NULL; 51864562Sgshapiro if (db_params != NULL && 51964562Sgshapiro (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) == 0)) 52064562Sgshapiro { 52190792Sgshapiro (void) memset(&hash_info, '\0', sizeof hash_info); 52264562Sgshapiro hash_info.nelem = db_params->smdbp_num_elements; 52364562Sgshapiro hash_info.cachesize = db_params->smdbp_cache_size; 52464562Sgshapiro params = &hash_info; 52564562Sgshapiro } 52664562Sgshapiro 52764562Sgshapiro if (db_params != NULL && 52864562Sgshapiro (strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) == 0)) 52964562Sgshapiro { 53090792Sgshapiro (void) memset(&btree_info, '\0', sizeof btree_info); 53164562Sgshapiro btree_info.cachesize = db_params->smdbp_cache_size; 53264562Sgshapiro if (db_params->smdbp_allow_dup) 53364562Sgshapiro btree_info.flags |= R_DUP; 53464562Sgshapiro params = &btree_info; 53564562Sgshapiro } 53664562Sgshapiro 53764562Sgshapiro db_type = smdb_type_to_db1_type(type); 53898121Sgshapiro db = dbopen(db_file_name, mode, DBMMODE, db_type, params); 53964562Sgshapiro if (db != NULL) 54064562Sgshapiro { 54164562Sgshapiro db_fd = db->fd(db); 54264562Sgshapiro result = smdb_filechanged(db_name, SMDB1_FILE_EXTENSION, db_fd, 54364562Sgshapiro &stat_info); 54464562Sgshapiro } 54564562Sgshapiro else 54664562Sgshapiro { 54764562Sgshapiro if (errno == 0) 54864562Sgshapiro result = SMDBE_BAD_OPEN; 54964562Sgshapiro else 55064562Sgshapiro result = errno; 55164562Sgshapiro } 55264562Sgshapiro 55364562Sgshapiro if (result == SMDBE_OK) 55464562Sgshapiro { 55564562Sgshapiro /* Everything is ok. Setup driver */ 55664562Sgshapiro db1->smdb1_db = db; 55764562Sgshapiro 55864562Sgshapiro smdb_db->smdb_close = smdb1_close; 55964562Sgshapiro smdb_db->smdb_del = smdb1_del; 56064562Sgshapiro smdb_db->smdb_fd = smdb1_fd; 56166494Sgshapiro smdb_db->smdb_lockfd = smdb1_lockfd; 56264562Sgshapiro smdb_db->smdb_get = smdb1_get; 56364562Sgshapiro smdb_db->smdb_put = smdb1_put; 56464562Sgshapiro smdb_db->smdb_set_owner = smdb1_set_owner; 56564562Sgshapiro smdb_db->smdb_sync = smdb1_sync; 56664562Sgshapiro smdb_db->smdb_cursor = smdb1_cursor; 56764562Sgshapiro smdb_db->smdb_impl = db1; 56864562Sgshapiro 56964562Sgshapiro *database = smdb_db; 57064562Sgshapiro return SMDBE_OK; 57164562Sgshapiro } 57264562Sgshapiro 57364562Sgshapiro if (db != NULL) 57464562Sgshapiro (void) db->close(db); 57564562Sgshapiro 57664562Sgshapiro /* Error opening database */ 57764562Sgshapiro (void) smdb_unlock_file(db1->smdb1_lock_fd); 57864562Sgshapiro free(db1); 57964562Sgshapiro smdb_free_database(smdb_db); 58064562Sgshapiro 58164562Sgshapiro return result; 58264562Sgshapiro} 58364562Sgshapiro 58464562Sgshapiro#endif /* (DB_VERSION_MAJOR == 1) */ 585