17c478bd9Sstevel@tonic-gate /* 2*e9af4bc0SJohn Beck ** Copyright (c) 1999-2002, 2004, 2009 Sendmail, Inc. and its suppliers. 37c478bd9Sstevel@tonic-gate ** All rights reserved. 47c478bd9Sstevel@tonic-gate ** 57c478bd9Sstevel@tonic-gate ** By using this file, you agree to the terms and conditions set 67c478bd9Sstevel@tonic-gate ** forth in the LICENSE file which can be found at the top level of 77c478bd9Sstevel@tonic-gate ** the sendmail distribution. 87c478bd9Sstevel@tonic-gate */ 97c478bd9Sstevel@tonic-gate 107c478bd9Sstevel@tonic-gate #include <sm/gen.h> 11*e9af4bc0SJohn Beck SM_RCSID("@(#)$Id: smdb1.c,v 8.62 2009/11/12 23:04:18 ca Exp $") 127c478bd9Sstevel@tonic-gate 137c478bd9Sstevel@tonic-gate #include <unistd.h> 147c478bd9Sstevel@tonic-gate #include <stdlib.h> 157c478bd9Sstevel@tonic-gate #include <fcntl.h> 167c478bd9Sstevel@tonic-gate 177c478bd9Sstevel@tonic-gate #include <sendmail/sendmail.h> 187c478bd9Sstevel@tonic-gate #include <libsmdb/smdb.h> 197c478bd9Sstevel@tonic-gate 207c478bd9Sstevel@tonic-gate #if (DB_VERSION_MAJOR == 1) 217c478bd9Sstevel@tonic-gate 227c478bd9Sstevel@tonic-gate # define SMDB1_FILE_EXTENSION "db" 237c478bd9Sstevel@tonic-gate 247c478bd9Sstevel@tonic-gate struct smdb_db1_struct 257c478bd9Sstevel@tonic-gate { 267c478bd9Sstevel@tonic-gate DB *smdb1_db; 277c478bd9Sstevel@tonic-gate int smdb1_lock_fd; 287c478bd9Sstevel@tonic-gate bool smdb1_cursor_in_use; 297c478bd9Sstevel@tonic-gate }; 307c478bd9Sstevel@tonic-gate typedef struct smdb_db1_struct SMDB_DB1_DATABASE; 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate struct smdb_db1_cursor 337c478bd9Sstevel@tonic-gate { 347c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db; 357c478bd9Sstevel@tonic-gate }; 367c478bd9Sstevel@tonic-gate typedef struct smdb_db1_cursor SMDB_DB1_CURSOR; 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate static DBTYPE smdb_type_to_db1_type __P((SMDB_DBTYPE)); 397c478bd9Sstevel@tonic-gate static unsigned int smdb_put_flags_to_db1_flags __P((SMDB_FLAG)); 407c478bd9Sstevel@tonic-gate static int smdb_cursor_get_flags_to_smdb1 __P((SMDB_FLAG)); 417c478bd9Sstevel@tonic-gate static SMDB_DB1_DATABASE *smdb1_malloc_database __P((void)); 427c478bd9Sstevel@tonic-gate static int smdb1_close __P((SMDB_DATABASE *)); 437c478bd9Sstevel@tonic-gate static int smdb1_del __P((SMDB_DATABASE *, SMDB_DBENT *, unsigned int)); 447c478bd9Sstevel@tonic-gate static int smdb1_fd __P((SMDB_DATABASE *, int *)); 457c478bd9Sstevel@tonic-gate static int smdb1_lockfd __P((SMDB_DATABASE *)); 467c478bd9Sstevel@tonic-gate static int smdb1_get __P((SMDB_DATABASE *, SMDB_DBENT *, SMDB_DBENT *, unsigned int)); 477c478bd9Sstevel@tonic-gate static int smdb1_put __P((SMDB_DATABASE *, SMDB_DBENT *, SMDB_DBENT *, unsigned int)); 487c478bd9Sstevel@tonic-gate static int smdb1_set_owner __P((SMDB_DATABASE *, uid_t, gid_t)); 497c478bd9Sstevel@tonic-gate static int smdb1_sync __P((SMDB_DATABASE *, unsigned int)); 507c478bd9Sstevel@tonic-gate static int smdb1_cursor_close __P((SMDB_CURSOR *)); 517c478bd9Sstevel@tonic-gate static int smdb1_cursor_del __P((SMDB_CURSOR *, unsigned int)); 527c478bd9Sstevel@tonic-gate static int smdb1_cursor_get __P((SMDB_CURSOR *, SMDB_DBENT *, SMDB_DBENT *, SMDB_FLAG)); 537c478bd9Sstevel@tonic-gate static int smdb1_cursor_put __P((SMDB_CURSOR *, SMDB_DBENT *, SMDB_DBENT *, SMDB_FLAG)); 547c478bd9Sstevel@tonic-gate static int smdb1_cursor __P((SMDB_DATABASE *, SMDB_CURSOR **, unsigned int)); 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate /* 577c478bd9Sstevel@tonic-gate ** SMDB_TYPE_TO_DB1_TYPE -- Translates smdb database type to db1 type. 587c478bd9Sstevel@tonic-gate ** 597c478bd9Sstevel@tonic-gate ** Parameters: 607c478bd9Sstevel@tonic-gate ** type -- The type to translate. 617c478bd9Sstevel@tonic-gate ** 627c478bd9Sstevel@tonic-gate ** Returns: 637c478bd9Sstevel@tonic-gate ** The DB1 type that corresponsds to the passed in SMDB type. 647c478bd9Sstevel@tonic-gate ** Returns -1 if there is no equivalent type. 657c478bd9Sstevel@tonic-gate ** 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate static DBTYPE 697c478bd9Sstevel@tonic-gate smdb_type_to_db1_type(type) 707c478bd9Sstevel@tonic-gate SMDB_DBTYPE type; 717c478bd9Sstevel@tonic-gate { 727c478bd9Sstevel@tonic-gate if (type == SMDB_TYPE_DEFAULT) 737c478bd9Sstevel@tonic-gate return DB_HASH; 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate if (strncmp(type, SMDB_TYPE_HASH, SMDB_TYPE_HASH_LEN) == 0) 767c478bd9Sstevel@tonic-gate return DB_HASH; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate if (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0) 797c478bd9Sstevel@tonic-gate return DB_BTREE; 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate /* Should never get here thanks to test in smdb_db_open() */ 827c478bd9Sstevel@tonic-gate return DB_HASH; 837c478bd9Sstevel@tonic-gate } 847c478bd9Sstevel@tonic-gate /* 857c478bd9Sstevel@tonic-gate ** SMDB_PUT_FLAGS_TO_DB1_FLAGS -- Translates smdb put flags to db1 put flags. 867c478bd9Sstevel@tonic-gate ** 877c478bd9Sstevel@tonic-gate ** Parameters: 887c478bd9Sstevel@tonic-gate ** flags -- The flags to translate. 897c478bd9Sstevel@tonic-gate ** 907c478bd9Sstevel@tonic-gate ** Returns: 917c478bd9Sstevel@tonic-gate ** The db1 flags that are equivalent to the smdb flags. 927c478bd9Sstevel@tonic-gate ** 937c478bd9Sstevel@tonic-gate ** Notes: 947c478bd9Sstevel@tonic-gate ** Any invalid flags are ignored. 957c478bd9Sstevel@tonic-gate ** 967c478bd9Sstevel@tonic-gate */ 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate static unsigned int 997c478bd9Sstevel@tonic-gate smdb_put_flags_to_db1_flags(flags) 1007c478bd9Sstevel@tonic-gate SMDB_FLAG flags; 1017c478bd9Sstevel@tonic-gate { 1027c478bd9Sstevel@tonic-gate int return_flags; 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate return_flags = 0; 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate if (bitset(SMDBF_NO_OVERWRITE, flags)) 1077c478bd9Sstevel@tonic-gate return_flags |= R_NOOVERWRITE; 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate return return_flags; 1107c478bd9Sstevel@tonic-gate } 1117c478bd9Sstevel@tonic-gate /* 1127c478bd9Sstevel@tonic-gate ** SMDB_CURSOR_GET_FLAGS_TO_SMDB1 1137c478bd9Sstevel@tonic-gate ** 1147c478bd9Sstevel@tonic-gate ** Parameters: 1157c478bd9Sstevel@tonic-gate ** flags -- The flags to translate. 1167c478bd9Sstevel@tonic-gate ** 1177c478bd9Sstevel@tonic-gate ** Returns: 1187c478bd9Sstevel@tonic-gate ** The db1 flags that are equivalent to the smdb flags. 1197c478bd9Sstevel@tonic-gate ** 1207c478bd9Sstevel@tonic-gate ** Notes: 1217c478bd9Sstevel@tonic-gate ** Returns -1 if we don't support the flag. 1227c478bd9Sstevel@tonic-gate ** 1237c478bd9Sstevel@tonic-gate */ 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate static int 1267c478bd9Sstevel@tonic-gate smdb_cursor_get_flags_to_smdb1(flags) 1277c478bd9Sstevel@tonic-gate SMDB_FLAG flags; 1287c478bd9Sstevel@tonic-gate { 1297c478bd9Sstevel@tonic-gate switch(flags) 1307c478bd9Sstevel@tonic-gate { 1317c478bd9Sstevel@tonic-gate case SMDB_CURSOR_GET_FIRST: 1327c478bd9Sstevel@tonic-gate return R_FIRST; 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate case SMDB_CURSOR_GET_LAST: 1357c478bd9Sstevel@tonic-gate return R_LAST; 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate case SMDB_CURSOR_GET_NEXT: 1387c478bd9Sstevel@tonic-gate return R_NEXT; 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate case SMDB_CURSOR_GET_RANGE: 1417c478bd9Sstevel@tonic-gate return R_CURSOR; 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate default: 1447c478bd9Sstevel@tonic-gate return -1; 1457c478bd9Sstevel@tonic-gate } 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate /* 1497c478bd9Sstevel@tonic-gate ** The rest of these functions correspond to the interface laid out in smdb.h. 1507c478bd9Sstevel@tonic-gate */ 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate static SMDB_DB1_DATABASE * 1537c478bd9Sstevel@tonic-gate smdb1_malloc_database() 1547c478bd9Sstevel@tonic-gate { 1557c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1; 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate db1 = (SMDB_DB1_DATABASE *) malloc(sizeof(SMDB_DB1_DATABASE)); 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate if (db1 != NULL) 1607c478bd9Sstevel@tonic-gate { 1617c478bd9Sstevel@tonic-gate db1->smdb1_lock_fd = -1; 1627c478bd9Sstevel@tonic-gate db1->smdb1_cursor_in_use = false; 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate return db1; 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate static int 1697c478bd9Sstevel@tonic-gate smdb1_close(database) 1707c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 1717c478bd9Sstevel@tonic-gate { 1727c478bd9Sstevel@tonic-gate int result; 1737c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl; 1747c478bd9Sstevel@tonic-gate DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate result = db->close(db); 1777c478bd9Sstevel@tonic-gate if (db1->smdb1_lock_fd != -1) 1787c478bd9Sstevel@tonic-gate (void) close(db1->smdb1_lock_fd); 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate free(db1); 1817c478bd9Sstevel@tonic-gate database->smdb_impl = NULL; 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate return result; 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate static int 1877c478bd9Sstevel@tonic-gate smdb1_del(database, key, flags) 1887c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 1897c478bd9Sstevel@tonic-gate SMDB_DBENT *key; 1907c478bd9Sstevel@tonic-gate unsigned int flags; 1917c478bd9Sstevel@tonic-gate { 1927c478bd9Sstevel@tonic-gate DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 1937c478bd9Sstevel@tonic-gate DBT dbkey; 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate (void) memset(&dbkey, '\0', sizeof dbkey); 1967c478bd9Sstevel@tonic-gate dbkey.data = key->data; 1977c478bd9Sstevel@tonic-gate dbkey.size = key->size; 1987c478bd9Sstevel@tonic-gate return db->del(db, &dbkey, flags); 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate static int 2027c478bd9Sstevel@tonic-gate smdb1_fd(database, fd) 2037c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 2047c478bd9Sstevel@tonic-gate int *fd; 2057c478bd9Sstevel@tonic-gate { 2067c478bd9Sstevel@tonic-gate DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate *fd = db->fd(db); 2097c478bd9Sstevel@tonic-gate if (*fd == -1) 2107c478bd9Sstevel@tonic-gate return errno; 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate return SMDBE_OK; 2137c478bd9Sstevel@tonic-gate } 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate static int 2167c478bd9Sstevel@tonic-gate smdb1_lockfd(database) 2177c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 2187c478bd9Sstevel@tonic-gate { 2197c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl; 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate return db1->smdb1_lock_fd; 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate static int 2267c478bd9Sstevel@tonic-gate smdb1_get(database, key, data, flags) 2277c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 2287c478bd9Sstevel@tonic-gate SMDB_DBENT *key; 2297c478bd9Sstevel@tonic-gate SMDB_DBENT *data; 2307c478bd9Sstevel@tonic-gate unsigned int flags; 2317c478bd9Sstevel@tonic-gate { 2327c478bd9Sstevel@tonic-gate int result; 2337c478bd9Sstevel@tonic-gate DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 2347c478bd9Sstevel@tonic-gate DBT dbkey, dbdata; 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate (void) memset(&dbdata, '\0', sizeof dbdata); 2377c478bd9Sstevel@tonic-gate (void) memset(&dbkey, '\0', sizeof dbkey); 2387c478bd9Sstevel@tonic-gate dbkey.data = key->data; 2397c478bd9Sstevel@tonic-gate dbkey.size = key->size; 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate result = db->get(db, &dbkey, &dbdata, flags); 2427c478bd9Sstevel@tonic-gate if (result != 0) 2437c478bd9Sstevel@tonic-gate { 2447c478bd9Sstevel@tonic-gate if (result == 1) 2457c478bd9Sstevel@tonic-gate return SMDBE_NOT_FOUND; 2467c478bd9Sstevel@tonic-gate return errno; 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate data->data = dbdata.data; 2497c478bd9Sstevel@tonic-gate data->size = dbdata.size; 2507c478bd9Sstevel@tonic-gate return SMDBE_OK; 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate static int 2547c478bd9Sstevel@tonic-gate smdb1_put(database, key, data, flags) 2557c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 2567c478bd9Sstevel@tonic-gate SMDB_DBENT *key; 2577c478bd9Sstevel@tonic-gate SMDB_DBENT *data; 2587c478bd9Sstevel@tonic-gate unsigned int flags; 2597c478bd9Sstevel@tonic-gate { 2607c478bd9Sstevel@tonic-gate DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 2617c478bd9Sstevel@tonic-gate DBT dbkey, dbdata; 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate (void) memset(&dbdata, '\0', sizeof dbdata); 2647c478bd9Sstevel@tonic-gate (void) memset(&dbkey, '\0', sizeof dbkey); 2657c478bd9Sstevel@tonic-gate dbkey.data = key->data; 2667c478bd9Sstevel@tonic-gate dbkey.size = key->size; 2677c478bd9Sstevel@tonic-gate dbdata.data = data->data; 2687c478bd9Sstevel@tonic-gate dbdata.size = data->size; 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate return db->put(db, &dbkey, &dbdata, 2717c478bd9Sstevel@tonic-gate smdb_put_flags_to_db1_flags(flags)); 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate static int 2757c478bd9Sstevel@tonic-gate smdb1_set_owner(database, uid, gid) 2767c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 2777c478bd9Sstevel@tonic-gate uid_t uid; 2787c478bd9Sstevel@tonic-gate gid_t gid; 2797c478bd9Sstevel@tonic-gate { 2807c478bd9Sstevel@tonic-gate # if HASFCHOWN 2817c478bd9Sstevel@tonic-gate int fd; 2827c478bd9Sstevel@tonic-gate int result; 2837c478bd9Sstevel@tonic-gate DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate fd = db->fd(db); 2867c478bd9Sstevel@tonic-gate if (fd == -1) 2877c478bd9Sstevel@tonic-gate return errno; 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate result = fchown(fd, uid, gid); 2907c478bd9Sstevel@tonic-gate if (result < 0) 2917c478bd9Sstevel@tonic-gate return errno; 2927c478bd9Sstevel@tonic-gate # endif /* HASFCHOWN */ 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate return SMDBE_OK; 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate static int 2987c478bd9Sstevel@tonic-gate smdb1_sync(database, flags) 2997c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 3007c478bd9Sstevel@tonic-gate unsigned int flags; 3017c478bd9Sstevel@tonic-gate { 3027c478bd9Sstevel@tonic-gate DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db; 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate return db->sync(db, flags); 3057c478bd9Sstevel@tonic-gate } 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate static int 3087c478bd9Sstevel@tonic-gate smdb1_cursor_close(cursor) 3097c478bd9Sstevel@tonic-gate SMDB_CURSOR *cursor; 3107c478bd9Sstevel@tonic-gate { 3117c478bd9Sstevel@tonic-gate SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 3127c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1 = db1_cursor->db; 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate if (!db1->smdb1_cursor_in_use) 3157c478bd9Sstevel@tonic-gate return SMDBE_NOT_A_VALID_CURSOR; 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate db1->smdb1_cursor_in_use = false; 3187c478bd9Sstevel@tonic-gate free(cursor); 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate return SMDBE_OK; 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate static int 3247c478bd9Sstevel@tonic-gate smdb1_cursor_del(cursor, flags) 3257c478bd9Sstevel@tonic-gate SMDB_CURSOR *cursor; 3267c478bd9Sstevel@tonic-gate unsigned int flags; 3277c478bd9Sstevel@tonic-gate { 3287c478bd9Sstevel@tonic-gate SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 3297c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1 = db1_cursor->db; 3307c478bd9Sstevel@tonic-gate DB *db = db1->smdb1_db; 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate return db->del(db, NULL, R_CURSOR); 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate static int 3367c478bd9Sstevel@tonic-gate smdb1_cursor_get(cursor, key, value, flags) 3377c478bd9Sstevel@tonic-gate SMDB_CURSOR *cursor; 3387c478bd9Sstevel@tonic-gate SMDB_DBENT *key; 3397c478bd9Sstevel@tonic-gate SMDB_DBENT *value; 3407c478bd9Sstevel@tonic-gate SMDB_FLAG flags; 3417c478bd9Sstevel@tonic-gate { 3427c478bd9Sstevel@tonic-gate int db1_flags; 3437c478bd9Sstevel@tonic-gate int result; 3447c478bd9Sstevel@tonic-gate SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 3457c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1 = db1_cursor->db; 3467c478bd9Sstevel@tonic-gate DB *db = db1->smdb1_db; 3477c478bd9Sstevel@tonic-gate DBT dbkey, dbdata; 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate (void) memset(&dbdata, '\0', sizeof dbdata); 3507c478bd9Sstevel@tonic-gate (void) memset(&dbkey, '\0', sizeof dbkey); 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate db1_flags = smdb_cursor_get_flags_to_smdb1(flags); 3537c478bd9Sstevel@tonic-gate result = db->seq(db, &dbkey, &dbdata, db1_flags); 3547c478bd9Sstevel@tonic-gate if (result == -1) 3557c478bd9Sstevel@tonic-gate return errno; 3567c478bd9Sstevel@tonic-gate if (result == 1) 3577c478bd9Sstevel@tonic-gate return SMDBE_LAST_ENTRY; 3587c478bd9Sstevel@tonic-gate value->data = dbdata.data; 3597c478bd9Sstevel@tonic-gate value->size = dbdata.size; 3607c478bd9Sstevel@tonic-gate key->data = dbkey.data; 3617c478bd9Sstevel@tonic-gate key->size = dbkey.size; 3627c478bd9Sstevel@tonic-gate return SMDBE_OK; 3637c478bd9Sstevel@tonic-gate } 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate static int 3667c478bd9Sstevel@tonic-gate smdb1_cursor_put(cursor, key, value, flags) 3677c478bd9Sstevel@tonic-gate SMDB_CURSOR *cursor; 3687c478bd9Sstevel@tonic-gate SMDB_DBENT *key; 3697c478bd9Sstevel@tonic-gate SMDB_DBENT *value; 3707c478bd9Sstevel@tonic-gate SMDB_FLAG flags; 3717c478bd9Sstevel@tonic-gate { 3727c478bd9Sstevel@tonic-gate SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl; 3737c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1 = db1_cursor->db; 3747c478bd9Sstevel@tonic-gate DB *db = db1->smdb1_db; 3757c478bd9Sstevel@tonic-gate DBT dbkey, dbdata; 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate (void) memset(&dbdata, '\0', sizeof dbdata); 3787c478bd9Sstevel@tonic-gate (void) memset(&dbkey, '\0', sizeof dbkey); 3797c478bd9Sstevel@tonic-gate dbkey.data = key->data; 3807c478bd9Sstevel@tonic-gate dbkey.size = key->size; 3817c478bd9Sstevel@tonic-gate dbdata.data = value->data; 3827c478bd9Sstevel@tonic-gate dbdata.size = value->size; 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate return db->put(db, &dbkey, &dbdata, R_CURSOR); 3857c478bd9Sstevel@tonic-gate } 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate static int 3887c478bd9Sstevel@tonic-gate smdb1_cursor(database, cursor, flags) 3897c478bd9Sstevel@tonic-gate SMDB_DATABASE *database; 3907c478bd9Sstevel@tonic-gate SMDB_CURSOR **cursor; 3917c478bd9Sstevel@tonic-gate unsigned int flags; 3927c478bd9Sstevel@tonic-gate { 3937c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl; 3947c478bd9Sstevel@tonic-gate SMDB_CURSOR *cur; 3957c478bd9Sstevel@tonic-gate SMDB_DB1_CURSOR *db1_cursor; 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate if (db1->smdb1_cursor_in_use) 3987c478bd9Sstevel@tonic-gate return SMDBE_ONLY_SUPPORTS_ONE_CURSOR; 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate db1_cursor = (SMDB_DB1_CURSOR *) malloc(sizeof(SMDB_DB1_CURSOR)); 401*e9af4bc0SJohn Beck if (db1_cursor == NULL) 4027c478bd9Sstevel@tonic-gate return SMDBE_MALLOC; 4037c478bd9Sstevel@tonic-gate 404*e9af4bc0SJohn Beck cur = (SMDB_CURSOR *) malloc(sizeof(SMDB_CURSOR)); 405*e9af4bc0SJohn Beck if (cur == NULL) 406*e9af4bc0SJohn Beck { 407*e9af4bc0SJohn Beck free(db1_cursor); 408*e9af4bc0SJohn Beck return SMDBE_MALLOC; 409*e9af4bc0SJohn Beck } 410*e9af4bc0SJohn Beck 411*e9af4bc0SJohn Beck db1->smdb1_cursor_in_use = true; 412*e9af4bc0SJohn Beck db1_cursor->db = db1; 4137c478bd9Sstevel@tonic-gate cur->smdbc_impl = db1_cursor; 4147c478bd9Sstevel@tonic-gate cur->smdbc_close = smdb1_cursor_close; 4157c478bd9Sstevel@tonic-gate cur->smdbc_del = smdb1_cursor_del; 4167c478bd9Sstevel@tonic-gate cur->smdbc_get = smdb1_cursor_get; 4177c478bd9Sstevel@tonic-gate cur->smdbc_put = smdb1_cursor_put; 4187c478bd9Sstevel@tonic-gate *cursor = cur; 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate return SMDBE_OK; 4217c478bd9Sstevel@tonic-gate } 4227c478bd9Sstevel@tonic-gate /* 4237c478bd9Sstevel@tonic-gate ** SMDB_DB_OPEN -- Opens a db1 database. 4247c478bd9Sstevel@tonic-gate ** 4257c478bd9Sstevel@tonic-gate ** Parameters: 4267c478bd9Sstevel@tonic-gate ** database -- An unallocated database pointer to a pointer. 4277c478bd9Sstevel@tonic-gate ** db_name -- The name of the database without extension. 4287c478bd9Sstevel@tonic-gate ** mode -- File permisions on the database if created. 4297c478bd9Sstevel@tonic-gate ** mode_mask -- Mode bits that must match on an existing database. 4307c478bd9Sstevel@tonic-gate ** sff -- Flags for safefile. 4317c478bd9Sstevel@tonic-gate ** type -- The type of database to open 4327c478bd9Sstevel@tonic-gate ** See smdb_type_to_db1_type for valid types. 4337c478bd9Sstevel@tonic-gate ** user_info -- Information on the user to use for file 4347c478bd9Sstevel@tonic-gate ** permissions. 4357c478bd9Sstevel@tonic-gate ** db_params -- 4367c478bd9Sstevel@tonic-gate ** An SMDB_DBPARAMS struct including params. These 4377c478bd9Sstevel@tonic-gate ** are processed according to the type of the 4387c478bd9Sstevel@tonic-gate ** database. Currently supported params (only for 4397c478bd9Sstevel@tonic-gate ** HASH type) are: 4407c478bd9Sstevel@tonic-gate ** num_elements 4417c478bd9Sstevel@tonic-gate ** cache_size 4427c478bd9Sstevel@tonic-gate ** 4437c478bd9Sstevel@tonic-gate ** Returns: 4447c478bd9Sstevel@tonic-gate ** SMDBE_OK -- Success, otherwise errno. 4457c478bd9Sstevel@tonic-gate */ 4467c478bd9Sstevel@tonic-gate 4477c478bd9Sstevel@tonic-gate int 4487c478bd9Sstevel@tonic-gate smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info, 4497c478bd9Sstevel@tonic-gate db_params) 4507c478bd9Sstevel@tonic-gate SMDB_DATABASE **database; 4517c478bd9Sstevel@tonic-gate char *db_name; 4527c478bd9Sstevel@tonic-gate int mode; 4537c478bd9Sstevel@tonic-gate int mode_mask; 4547c478bd9Sstevel@tonic-gate long sff; 4557c478bd9Sstevel@tonic-gate SMDB_DBTYPE type; 4567c478bd9Sstevel@tonic-gate SMDB_USER_INFO *user_info; 4577c478bd9Sstevel@tonic-gate SMDB_DBPARAMS *db_params; 4587c478bd9Sstevel@tonic-gate { 4597c478bd9Sstevel@tonic-gate bool lockcreated = false; 4607c478bd9Sstevel@tonic-gate int db_fd; 4617c478bd9Sstevel@tonic-gate int lock_fd; 4627c478bd9Sstevel@tonic-gate int result; 4637c478bd9Sstevel@tonic-gate void *params; 4647c478bd9Sstevel@tonic-gate SMDB_DATABASE *smdb_db; 4657c478bd9Sstevel@tonic-gate SMDB_DB1_DATABASE *db1; 4667c478bd9Sstevel@tonic-gate DB *db; 4677c478bd9Sstevel@tonic-gate HASHINFO hash_info; 4687c478bd9Sstevel@tonic-gate BTREEINFO btree_info; 4697c478bd9Sstevel@tonic-gate DBTYPE db_type; 4707c478bd9Sstevel@tonic-gate struct stat stat_info; 4717c478bd9Sstevel@tonic-gate char db_file_name[MAXPATHLEN]; 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate if (type == NULL || 4747c478bd9Sstevel@tonic-gate (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) != 0 && 4757c478bd9Sstevel@tonic-gate strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) != 0)) 4767c478bd9Sstevel@tonic-gate return SMDBE_UNKNOWN_DB_TYPE; 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate result = smdb_add_extension(db_file_name, sizeof db_file_name, 4797c478bd9Sstevel@tonic-gate db_name, SMDB1_FILE_EXTENSION); 4807c478bd9Sstevel@tonic-gate if (result != SMDBE_OK) 4817c478bd9Sstevel@tonic-gate return result; 4827c478bd9Sstevel@tonic-gate 4837c478bd9Sstevel@tonic-gate result = smdb_setup_file(db_name, SMDB1_FILE_EXTENSION, mode_mask, 4847c478bd9Sstevel@tonic-gate sff, user_info, &stat_info); 4857c478bd9Sstevel@tonic-gate if (result != SMDBE_OK) 4867c478bd9Sstevel@tonic-gate return result; 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate if (stat_info.st_mode == ST_MODE_NOFILE && 4897c478bd9Sstevel@tonic-gate bitset(mode, O_CREAT)) 4907c478bd9Sstevel@tonic-gate lockcreated = true; 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate lock_fd = -1; 4937c478bd9Sstevel@tonic-gate result = smdb_lock_file(&lock_fd, db_name, mode, sff, 4947c478bd9Sstevel@tonic-gate SMDB1_FILE_EXTENSION); 4957c478bd9Sstevel@tonic-gate if (result != SMDBE_OK) 4967c478bd9Sstevel@tonic-gate return result; 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate if (lockcreated) 4997c478bd9Sstevel@tonic-gate { 5007c478bd9Sstevel@tonic-gate mode |= O_TRUNC; 5017c478bd9Sstevel@tonic-gate mode &= ~(O_CREAT|O_EXCL); 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate *database = NULL; 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate smdb_db = smdb_malloc_database(); 5077c478bd9Sstevel@tonic-gate db1 = smdb1_malloc_database(); 5087c478bd9Sstevel@tonic-gate if (smdb_db == NULL || db1 == NULL) 509*e9af4bc0SJohn Beck { 510*e9af4bc0SJohn Beck (void) smdb_unlock_file(lock_fd); 511*e9af4bc0SJohn Beck smdb_free_database(smdb_db); 512*e9af4bc0SJohn Beck free(db1); 5137c478bd9Sstevel@tonic-gate return SMDBE_MALLOC; 514*e9af4bc0SJohn Beck } 5157c478bd9Sstevel@tonic-gate db1->smdb1_lock_fd = lock_fd; 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate params = NULL; 5187c478bd9Sstevel@tonic-gate if (db_params != NULL && 5197c478bd9Sstevel@tonic-gate (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) == 0)) 5207c478bd9Sstevel@tonic-gate { 5217c478bd9Sstevel@tonic-gate (void) memset(&hash_info, '\0', sizeof hash_info); 5227c478bd9Sstevel@tonic-gate hash_info.nelem = db_params->smdbp_num_elements; 5237c478bd9Sstevel@tonic-gate hash_info.cachesize = db_params->smdbp_cache_size; 5247c478bd9Sstevel@tonic-gate params = &hash_info; 5257c478bd9Sstevel@tonic-gate } 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate if (db_params != NULL && 5287c478bd9Sstevel@tonic-gate (strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) == 0)) 5297c478bd9Sstevel@tonic-gate { 5307c478bd9Sstevel@tonic-gate (void) memset(&btree_info, '\0', sizeof btree_info); 5317c478bd9Sstevel@tonic-gate btree_info.cachesize = db_params->smdbp_cache_size; 5327c478bd9Sstevel@tonic-gate if (db_params->smdbp_allow_dup) 5337c478bd9Sstevel@tonic-gate btree_info.flags |= R_DUP; 5347c478bd9Sstevel@tonic-gate params = &btree_info; 5357c478bd9Sstevel@tonic-gate } 5367c478bd9Sstevel@tonic-gate 5377c478bd9Sstevel@tonic-gate db_type = smdb_type_to_db1_type(type); 5387c478bd9Sstevel@tonic-gate db = dbopen(db_file_name, mode, DBMMODE, db_type, params); 5397c478bd9Sstevel@tonic-gate if (db != NULL) 5407c478bd9Sstevel@tonic-gate { 5417c478bd9Sstevel@tonic-gate db_fd = db->fd(db); 5427c478bd9Sstevel@tonic-gate result = smdb_filechanged(db_name, SMDB1_FILE_EXTENSION, db_fd, 5437c478bd9Sstevel@tonic-gate &stat_info); 5447c478bd9Sstevel@tonic-gate } 5457c478bd9Sstevel@tonic-gate else 5467c478bd9Sstevel@tonic-gate { 5477c478bd9Sstevel@tonic-gate if (errno == 0) 5487c478bd9Sstevel@tonic-gate result = SMDBE_BAD_OPEN; 5497c478bd9Sstevel@tonic-gate else 5507c478bd9Sstevel@tonic-gate result = errno; 5517c478bd9Sstevel@tonic-gate } 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate if (result == SMDBE_OK) 5547c478bd9Sstevel@tonic-gate { 5557c478bd9Sstevel@tonic-gate /* Everything is ok. Setup driver */ 5567c478bd9Sstevel@tonic-gate db1->smdb1_db = db; 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate smdb_db->smdb_close = smdb1_close; 5597c478bd9Sstevel@tonic-gate smdb_db->smdb_del = smdb1_del; 5607c478bd9Sstevel@tonic-gate smdb_db->smdb_fd = smdb1_fd; 5617c478bd9Sstevel@tonic-gate smdb_db->smdb_lockfd = smdb1_lockfd; 5627c478bd9Sstevel@tonic-gate smdb_db->smdb_get = smdb1_get; 5637c478bd9Sstevel@tonic-gate smdb_db->smdb_put = smdb1_put; 5647c478bd9Sstevel@tonic-gate smdb_db->smdb_set_owner = smdb1_set_owner; 5657c478bd9Sstevel@tonic-gate smdb_db->smdb_sync = smdb1_sync; 5667c478bd9Sstevel@tonic-gate smdb_db->smdb_cursor = smdb1_cursor; 5677c478bd9Sstevel@tonic-gate smdb_db->smdb_impl = db1; 5687c478bd9Sstevel@tonic-gate 5697c478bd9Sstevel@tonic-gate *database = smdb_db; 5707c478bd9Sstevel@tonic-gate return SMDBE_OK; 5717c478bd9Sstevel@tonic-gate } 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate if (db != NULL) 5747c478bd9Sstevel@tonic-gate (void) db->close(db); 5757c478bd9Sstevel@tonic-gate 5767c478bd9Sstevel@tonic-gate /* Error opening database */ 5777c478bd9Sstevel@tonic-gate (void) smdb_unlock_file(db1->smdb1_lock_fd); 5787c478bd9Sstevel@tonic-gate free(db1); 5797c478bd9Sstevel@tonic-gate smdb_free_database(smdb_db); 5807c478bd9Sstevel@tonic-gate 5817c478bd9Sstevel@tonic-gate return result; 5827c478bd9Sstevel@tonic-gate } 5837c478bd9Sstevel@tonic-gate 5847c478bd9Sstevel@tonic-gate #endif /* (DB_VERSION_MAJOR == 1) */ 585