xref: /titanic_50/usr/src/cmd/sendmail/libsmdb/smdb2.c (revision e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9be)
17c478bd9Sstevel@tonic-gate /*
2*e9af4bc0SJohn Beck ** Copyright (c) 1999-2003, 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: smdb2.c,v 8.80 2009/11/12 23:07:49 ca Exp $")
127c478bd9Sstevel@tonic-gate 
137c478bd9Sstevel@tonic-gate #include <fcntl.h>
147c478bd9Sstevel@tonic-gate #include <stdlib.h>
157c478bd9Sstevel@tonic-gate #include <unistd.h>
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate 
187c478bd9Sstevel@tonic-gate #include <sendmail/sendmail.h>
197c478bd9Sstevel@tonic-gate #include <libsmdb/smdb.h>
207c478bd9Sstevel@tonic-gate 
217c478bd9Sstevel@tonic-gate #if (DB_VERSION_MAJOR >= 2)
227c478bd9Sstevel@tonic-gate 
237c478bd9Sstevel@tonic-gate # define SMDB2_FILE_EXTENSION "db"
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate struct smdb_db2_database
267c478bd9Sstevel@tonic-gate {
277c478bd9Sstevel@tonic-gate 	DB	*smdb2_db;
287c478bd9Sstevel@tonic-gate 	int	smdb2_lock_fd;
297c478bd9Sstevel@tonic-gate };
307c478bd9Sstevel@tonic-gate typedef struct smdb_db2_database SMDB_DB2_DATABASE;
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate /*
337c478bd9Sstevel@tonic-gate **  SMDB_TYPE_TO_DB2_TYPE -- Translates smdb database type to db2 type.
347c478bd9Sstevel@tonic-gate **
357c478bd9Sstevel@tonic-gate **	Parameters:
367c478bd9Sstevel@tonic-gate **		type -- The type to translate.
377c478bd9Sstevel@tonic-gate **
387c478bd9Sstevel@tonic-gate **	Returns:
397c478bd9Sstevel@tonic-gate **		The DB2 type that corresponsds to the passed in SMDB type.
407c478bd9Sstevel@tonic-gate **		Returns -1 if there is no equivalent type.
417c478bd9Sstevel@tonic-gate **
427c478bd9Sstevel@tonic-gate */
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate DBTYPE
smdb_type_to_db2_type(type)457c478bd9Sstevel@tonic-gate smdb_type_to_db2_type(type)
467c478bd9Sstevel@tonic-gate 	SMDB_DBTYPE type;
477c478bd9Sstevel@tonic-gate {
487c478bd9Sstevel@tonic-gate 	if (type == SMDB_TYPE_DEFAULT)
497c478bd9Sstevel@tonic-gate 		return DB_HASH;
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate 	if (strncmp(type, SMDB_TYPE_HASH, SMDB_TYPE_HASH_LEN) == 0)
527c478bd9Sstevel@tonic-gate 		return DB_HASH;
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate 	if (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0)
557c478bd9Sstevel@tonic-gate 		return DB_BTREE;
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate 	return DB_UNKNOWN;
587c478bd9Sstevel@tonic-gate }
597c478bd9Sstevel@tonic-gate /*
607c478bd9Sstevel@tonic-gate **  DB2_ERROR_TO_SMDB -- Translates db2 errors to smdbe errors
617c478bd9Sstevel@tonic-gate **
627c478bd9Sstevel@tonic-gate **	Parameters:
637c478bd9Sstevel@tonic-gate **		error -- The error to translate.
647c478bd9Sstevel@tonic-gate **
657c478bd9Sstevel@tonic-gate **	Returns:
667c478bd9Sstevel@tonic-gate **		The SMDBE error corresponding to the db2 error.
677c478bd9Sstevel@tonic-gate **		If we don't have a corresponding error, it returs errno.
687c478bd9Sstevel@tonic-gate **
697c478bd9Sstevel@tonic-gate */
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate int
db2_error_to_smdb(error)727c478bd9Sstevel@tonic-gate db2_error_to_smdb(error)
737c478bd9Sstevel@tonic-gate 	int error;
747c478bd9Sstevel@tonic-gate {
757c478bd9Sstevel@tonic-gate 	int result;
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 	switch (error)
787c478bd9Sstevel@tonic-gate 	{
797c478bd9Sstevel@tonic-gate # ifdef DB_INCOMPLETE
807c478bd9Sstevel@tonic-gate 		case DB_INCOMPLETE:
817c478bd9Sstevel@tonic-gate 			result = SMDBE_INCOMPLETE;
827c478bd9Sstevel@tonic-gate 			break;
837c478bd9Sstevel@tonic-gate # endif /* DB_INCOMPLETE */
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate # ifdef DB_NOTFOUND
867c478bd9Sstevel@tonic-gate 		case DB_NOTFOUND:
877c478bd9Sstevel@tonic-gate 			result = SMDBE_NOT_FOUND;
887c478bd9Sstevel@tonic-gate 			break;
897c478bd9Sstevel@tonic-gate # endif /* DB_NOTFOUND */
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate # ifdef DB_KEYEMPTY
927c478bd9Sstevel@tonic-gate 		case DB_KEYEMPTY:
937c478bd9Sstevel@tonic-gate 			result = SMDBE_KEY_EMPTY;
947c478bd9Sstevel@tonic-gate 			break;
957c478bd9Sstevel@tonic-gate # endif /* DB_KEYEMPTY */
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate # ifdef DB_KEYEXIST
987c478bd9Sstevel@tonic-gate 		case DB_KEYEXIST:
997c478bd9Sstevel@tonic-gate 			result = SMDBE_KEY_EXIST;
1007c478bd9Sstevel@tonic-gate 			break;
1017c478bd9Sstevel@tonic-gate # endif /* DB_KEYEXIST */
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate # ifdef DB_LOCK_DEADLOCK
1047c478bd9Sstevel@tonic-gate 		case DB_LOCK_DEADLOCK:
1057c478bd9Sstevel@tonic-gate 			result = SMDBE_LOCK_DEADLOCK;
1067c478bd9Sstevel@tonic-gate 			break;
1077c478bd9Sstevel@tonic-gate # endif /* DB_LOCK_DEADLOCK */
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate # ifdef DB_LOCK_NOTGRANTED
1107c478bd9Sstevel@tonic-gate 		case DB_LOCK_NOTGRANTED:
1117c478bd9Sstevel@tonic-gate 			result = SMDBE_LOCK_NOT_GRANTED;
1127c478bd9Sstevel@tonic-gate 			break;
1137c478bd9Sstevel@tonic-gate # endif /* DB_LOCK_NOTGRANTED */
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate # ifdef DB_LOCK_NOTHELD
1167c478bd9Sstevel@tonic-gate 		case DB_LOCK_NOTHELD:
1177c478bd9Sstevel@tonic-gate 			result = SMDBE_LOCK_NOT_HELD;
1187c478bd9Sstevel@tonic-gate 			break;
1197c478bd9Sstevel@tonic-gate # endif /* DB_LOCK_NOTHELD */
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate # ifdef DB_RUNRECOVERY
1227c478bd9Sstevel@tonic-gate 		case DB_RUNRECOVERY:
1237c478bd9Sstevel@tonic-gate 			result = SMDBE_RUN_RECOVERY;
1247c478bd9Sstevel@tonic-gate 			break;
1257c478bd9Sstevel@tonic-gate # endif /* DB_RUNRECOVERY */
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate # ifdef DB_OLD_VERSION
1287c478bd9Sstevel@tonic-gate 		case DB_OLD_VERSION:
1297c478bd9Sstevel@tonic-gate 			result = SMDBE_OLD_VERSION;
1307c478bd9Sstevel@tonic-gate 			break;
1317c478bd9Sstevel@tonic-gate # endif /* DB_OLD_VERSION */
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 		case 0:
1347c478bd9Sstevel@tonic-gate 			result = SMDBE_OK;
1357c478bd9Sstevel@tonic-gate 			break;
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 		default:
1387c478bd9Sstevel@tonic-gate 			result = error;
1397c478bd9Sstevel@tonic-gate 	}
1407c478bd9Sstevel@tonic-gate 	return result;
1417c478bd9Sstevel@tonic-gate }
1427c478bd9Sstevel@tonic-gate /*
1437c478bd9Sstevel@tonic-gate **  SMDB_PUT_FLAGS_TO_DB2_FLAGS -- Translates smdb put flags to db2 put flags.
1447c478bd9Sstevel@tonic-gate **
1457c478bd9Sstevel@tonic-gate **	Parameters:
1467c478bd9Sstevel@tonic-gate **		flags -- The flags to translate.
1477c478bd9Sstevel@tonic-gate **
1487c478bd9Sstevel@tonic-gate **	Returns:
1497c478bd9Sstevel@tonic-gate **		The db2 flags that are equivalent to the smdb flags.
1507c478bd9Sstevel@tonic-gate **
1517c478bd9Sstevel@tonic-gate **	Notes:
1527c478bd9Sstevel@tonic-gate **		Any invalid flags are ignored.
1537c478bd9Sstevel@tonic-gate **
1547c478bd9Sstevel@tonic-gate */
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate unsigned int
smdb_put_flags_to_db2_flags(flags)1577c478bd9Sstevel@tonic-gate smdb_put_flags_to_db2_flags(flags)
1587c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
1597c478bd9Sstevel@tonic-gate {
1607c478bd9Sstevel@tonic-gate 	int return_flags;
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 	return_flags = 0;
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate 	if (bitset(SMDBF_NO_OVERWRITE, flags))
1657c478bd9Sstevel@tonic-gate 		return_flags |= DB_NOOVERWRITE;
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 	return return_flags;
1687c478bd9Sstevel@tonic-gate }
1697c478bd9Sstevel@tonic-gate /*
1707c478bd9Sstevel@tonic-gate **  SMDB_CURSOR_GET_FLAGS_TO_DB2 -- Translates smdb cursor get flags to db2
1717c478bd9Sstevel@tonic-gate **	getflags.
1727c478bd9Sstevel@tonic-gate **
1737c478bd9Sstevel@tonic-gate **	Parameters:
1747c478bd9Sstevel@tonic-gate **		flags -- The flags to translate.
1757c478bd9Sstevel@tonic-gate **
1767c478bd9Sstevel@tonic-gate **	Returns:
1777c478bd9Sstevel@tonic-gate **		The db2 flags that are equivalent to the smdb flags.
1787c478bd9Sstevel@tonic-gate **
1797c478bd9Sstevel@tonic-gate **	Notes:
1807c478bd9Sstevel@tonic-gate **		-1 is returned if flag is unknown.
1817c478bd9Sstevel@tonic-gate **
1827c478bd9Sstevel@tonic-gate */
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate int
smdb_cursor_get_flags_to_db2(flags)1857c478bd9Sstevel@tonic-gate smdb_cursor_get_flags_to_db2(flags)
1867c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
1877c478bd9Sstevel@tonic-gate {
1887c478bd9Sstevel@tonic-gate 	switch (flags)
1897c478bd9Sstevel@tonic-gate 	{
1907c478bd9Sstevel@tonic-gate 		case SMDB_CURSOR_GET_FIRST:
1917c478bd9Sstevel@tonic-gate 			return DB_FIRST;
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate 		case SMDB_CURSOR_GET_LAST:
1947c478bd9Sstevel@tonic-gate 			return DB_LAST;
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate 		case SMDB_CURSOR_GET_NEXT:
1977c478bd9Sstevel@tonic-gate 			return DB_NEXT;
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 		case SMDB_CURSOR_GET_RANGE:
2007c478bd9Sstevel@tonic-gate 			return DB_SET_RANGE;
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate 		default:
2037c478bd9Sstevel@tonic-gate 			return -1;
2047c478bd9Sstevel@tonic-gate 	}
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate /*
2087c478bd9Sstevel@tonic-gate **  Except for smdb_db_open, the rest of these functions correspond to the
2097c478bd9Sstevel@tonic-gate **  interface laid out in smdb.h.
2107c478bd9Sstevel@tonic-gate */
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate SMDB_DB2_DATABASE *
smdb2_malloc_database()2137c478bd9Sstevel@tonic-gate smdb2_malloc_database()
2147c478bd9Sstevel@tonic-gate {
2157c478bd9Sstevel@tonic-gate 	SMDB_DB2_DATABASE *db2;
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 	db2 = (SMDB_DB2_DATABASE *) malloc(sizeof(SMDB_DB2_DATABASE));
2187c478bd9Sstevel@tonic-gate 	if (db2 != NULL)
2197c478bd9Sstevel@tonic-gate 		db2->smdb2_lock_fd = -1;
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate 	return db2;
2227c478bd9Sstevel@tonic-gate }
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate int
smdb2_close(database)2257c478bd9Sstevel@tonic-gate smdb2_close(database)
2267c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
2277c478bd9Sstevel@tonic-gate {
2287c478bd9Sstevel@tonic-gate 	int result;
2297c478bd9Sstevel@tonic-gate 	SMDB_DB2_DATABASE *db2 = (SMDB_DB2_DATABASE *) database->smdb_impl;
2307c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate 	result = db2_error_to_smdb(db->close(db, 0));
2337c478bd9Sstevel@tonic-gate 	if (db2->smdb2_lock_fd != -1)
2347c478bd9Sstevel@tonic-gate 		close(db2->smdb2_lock_fd);
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate 	free(db2);
2377c478bd9Sstevel@tonic-gate 	database->smdb_impl = NULL;
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 	return result;
2407c478bd9Sstevel@tonic-gate }
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate int
smdb2_del(database,key,flags)2437c478bd9Sstevel@tonic-gate smdb2_del(database, key, flags)
2447c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
2457c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
2467c478bd9Sstevel@tonic-gate 	unsigned int flags;
2477c478bd9Sstevel@tonic-gate {
2487c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
2497c478bd9Sstevel@tonic-gate 	DBT dbkey;
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
2527c478bd9Sstevel@tonic-gate 	dbkey.data = key->data;
2537c478bd9Sstevel@tonic-gate 	dbkey.size = key->size;
2547c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(db->del(db, NULL, &dbkey, flags));
2557c478bd9Sstevel@tonic-gate }
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate int
smdb2_fd(database,fd)2587c478bd9Sstevel@tonic-gate smdb2_fd(database, fd)
2597c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
2607c478bd9Sstevel@tonic-gate 	int *fd;
2617c478bd9Sstevel@tonic-gate {
2627c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(db->fd(db, fd));
2657c478bd9Sstevel@tonic-gate }
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate int
smdb2_lockfd(database)2687c478bd9Sstevel@tonic-gate smdb2_lockfd(database)
2697c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
2707c478bd9Sstevel@tonic-gate {
2717c478bd9Sstevel@tonic-gate 	SMDB_DB2_DATABASE *db2 = (SMDB_DB2_DATABASE *) database->smdb_impl;
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate 	return db2->smdb2_lock_fd;
2747c478bd9Sstevel@tonic-gate }
2757c478bd9Sstevel@tonic-gate 
2767c478bd9Sstevel@tonic-gate int
smdb2_get(database,key,data,flags)2777c478bd9Sstevel@tonic-gate smdb2_get(database, key, data, flags)
2787c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
2797c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
2807c478bd9Sstevel@tonic-gate 	SMDB_DBENT *data;
2817c478bd9Sstevel@tonic-gate 	unsigned int flags;
2827c478bd9Sstevel@tonic-gate {
2837c478bd9Sstevel@tonic-gate 	int result;
2847c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
2857c478bd9Sstevel@tonic-gate 	DBT dbkey, dbdata;
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
2887c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
2897c478bd9Sstevel@tonic-gate 	dbkey.data = key->data;
2907c478bd9Sstevel@tonic-gate 	dbkey.size = key->size;
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 	result = db->get(db, NULL, &dbkey, &dbdata, flags);
2937c478bd9Sstevel@tonic-gate 	data->data = dbdata.data;
2947c478bd9Sstevel@tonic-gate 	data->size = dbdata.size;
2957c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(result);
2967c478bd9Sstevel@tonic-gate }
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate int
smdb2_put(database,key,data,flags)2997c478bd9Sstevel@tonic-gate smdb2_put(database, key, data, flags)
3007c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
3017c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
3027c478bd9Sstevel@tonic-gate 	SMDB_DBENT *data;
3037c478bd9Sstevel@tonic-gate 	unsigned int flags;
3047c478bd9Sstevel@tonic-gate {
3057c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
3067c478bd9Sstevel@tonic-gate 	DBT dbkey, dbdata;
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
3097c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
3107c478bd9Sstevel@tonic-gate 	dbkey.data = key->data;
3117c478bd9Sstevel@tonic-gate 	dbkey.size = key->size;
3127c478bd9Sstevel@tonic-gate 	dbdata.data = data->data;
3137c478bd9Sstevel@tonic-gate 	dbdata.size = data->size;
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(db->put(db, NULL, &dbkey, &dbdata,
3167c478bd9Sstevel@tonic-gate 					 smdb_put_flags_to_db2_flags(flags)));
3177c478bd9Sstevel@tonic-gate }
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate int
smdb2_set_owner(database,uid,gid)3217c478bd9Sstevel@tonic-gate smdb2_set_owner(database, uid, gid)
3227c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
3237c478bd9Sstevel@tonic-gate 	uid_t uid;
3247c478bd9Sstevel@tonic-gate 	gid_t gid;
3257c478bd9Sstevel@tonic-gate {
3267c478bd9Sstevel@tonic-gate # if HASFCHOWN
3277c478bd9Sstevel@tonic-gate 	int fd;
3287c478bd9Sstevel@tonic-gate 	int result;
3297c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate 	result = db->fd(db, &fd);
3327c478bd9Sstevel@tonic-gate 	if (result != 0)
3337c478bd9Sstevel@tonic-gate 		return result;
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate 	result = fchown(fd, uid, gid);
3367c478bd9Sstevel@tonic-gate 	if (result < 0)
3377c478bd9Sstevel@tonic-gate 		return errno;
3387c478bd9Sstevel@tonic-gate # endif /* HASFCHOWN */
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
3417c478bd9Sstevel@tonic-gate }
3427c478bd9Sstevel@tonic-gate 
3437c478bd9Sstevel@tonic-gate int
smdb2_sync(database,flags)3447c478bd9Sstevel@tonic-gate smdb2_sync(database, flags)
3457c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
3467c478bd9Sstevel@tonic-gate 	unsigned int flags;
3477c478bd9Sstevel@tonic-gate {
3487c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(db->sync(db, flags));
3517c478bd9Sstevel@tonic-gate }
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate int
smdb2_cursor_close(cursor)3547c478bd9Sstevel@tonic-gate smdb2_cursor_close(cursor)
3557c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
3567c478bd9Sstevel@tonic-gate {
3577c478bd9Sstevel@tonic-gate 	int ret;
3587c478bd9Sstevel@tonic-gate 	DBC *dbc = (DBC *) cursor->smdbc_impl;
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate 	ret = db2_error_to_smdb(dbc->c_close(dbc));
3617c478bd9Sstevel@tonic-gate 	free(cursor);
3627c478bd9Sstevel@tonic-gate 	return ret;
3637c478bd9Sstevel@tonic-gate }
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate int
smdb2_cursor_del(cursor,flags)3667c478bd9Sstevel@tonic-gate smdb2_cursor_del(cursor, flags)
3677c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
3687c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
3697c478bd9Sstevel@tonic-gate {
3707c478bd9Sstevel@tonic-gate 	DBC *dbc = (DBC *) cursor->smdbc_impl;
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(dbc->c_del(dbc, 0));
3737c478bd9Sstevel@tonic-gate }
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate int
smdb2_cursor_get(cursor,key,value,flags)3767c478bd9Sstevel@tonic-gate smdb2_cursor_get(cursor, key, value, flags)
3777c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
3787c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
3797c478bd9Sstevel@tonic-gate 	SMDB_DBENT *value;
3807c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
3817c478bd9Sstevel@tonic-gate {
3827c478bd9Sstevel@tonic-gate 	int db2_flags;
3837c478bd9Sstevel@tonic-gate 	int result;
3847c478bd9Sstevel@tonic-gate 	DBC *dbc = (DBC *) cursor->smdbc_impl;
3857c478bd9Sstevel@tonic-gate 	DBT dbkey, dbdata;
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
3887c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate 	db2_flags = smdb_cursor_get_flags_to_db2(flags);
3917c478bd9Sstevel@tonic-gate 	result = dbc->c_get(dbc, &dbkey, &dbdata, db2_flags);
3927c478bd9Sstevel@tonic-gate 	if (result == DB_NOTFOUND)
3937c478bd9Sstevel@tonic-gate 		return SMDBE_LAST_ENTRY;
3947c478bd9Sstevel@tonic-gate 	key->data = dbkey.data;
3957c478bd9Sstevel@tonic-gate 	key->size = dbkey.size;
3967c478bd9Sstevel@tonic-gate 	value->data = dbdata.data;
3977c478bd9Sstevel@tonic-gate 	value->size = dbdata.size;
3987c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(result);
3997c478bd9Sstevel@tonic-gate }
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate int
smdb2_cursor_put(cursor,key,value,flags)4027c478bd9Sstevel@tonic-gate smdb2_cursor_put(cursor, key, value, flags)
4037c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
4047c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
4057c478bd9Sstevel@tonic-gate 	SMDB_DBENT *value;
4067c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
4077c478bd9Sstevel@tonic-gate {
4087c478bd9Sstevel@tonic-gate 	DBC *dbc = (DBC *) cursor->smdbc_impl;
4097c478bd9Sstevel@tonic-gate 	DBT dbkey, dbdata;
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
4127c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
4137c478bd9Sstevel@tonic-gate 	dbkey.data = key->data;
4147c478bd9Sstevel@tonic-gate 	dbkey.size = key->size;
4157c478bd9Sstevel@tonic-gate 	dbdata.data = value->data;
4167c478bd9Sstevel@tonic-gate 	dbdata.size = value->size;
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(dbc->c_put(dbc, &dbkey, &dbdata, 0));
4197c478bd9Sstevel@tonic-gate }
4207c478bd9Sstevel@tonic-gate 
4217c478bd9Sstevel@tonic-gate int
smdb2_cursor(database,cursor,flags)4227c478bd9Sstevel@tonic-gate smdb2_cursor(database, cursor, flags)
4237c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
4247c478bd9Sstevel@tonic-gate 	SMDB_CURSOR **cursor;
4257c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
4267c478bd9Sstevel@tonic-gate {
4277c478bd9Sstevel@tonic-gate 	int result;
4287c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
4297c478bd9Sstevel@tonic-gate 	DBC *db2_cursor;
4307c478bd9Sstevel@tonic-gate 
4317c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR > 2 || DB_VERSION_MINOR >= 6
4327c478bd9Sstevel@tonic-gate 	result = db->cursor(db, NULL, &db2_cursor, 0);
4337c478bd9Sstevel@tonic-gate # else /* DB_VERSION_MAJOR > 2 || DB_VERSION_MINOR >= 6 */
4347c478bd9Sstevel@tonic-gate 	result = db->cursor(db, NULL, &db2_cursor);
4357c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR > 2 || DB_VERSION_MINOR >= 6 */
4367c478bd9Sstevel@tonic-gate 	if (result != 0)
4377c478bd9Sstevel@tonic-gate 		return db2_error_to_smdb(result);
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate 	*cursor = (SMDB_CURSOR *) malloc(sizeof(SMDB_CURSOR));
4407c478bd9Sstevel@tonic-gate 	if (*cursor == NULL)
4417c478bd9Sstevel@tonic-gate 		return SMDBE_MALLOC;
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate 	(*cursor)->smdbc_close = smdb2_cursor_close;
4447c478bd9Sstevel@tonic-gate 	(*cursor)->smdbc_del = smdb2_cursor_del;
4457c478bd9Sstevel@tonic-gate 	(*cursor)->smdbc_get = smdb2_cursor_get;
4467c478bd9Sstevel@tonic-gate 	(*cursor)->smdbc_put = smdb2_cursor_put;
4477c478bd9Sstevel@tonic-gate 	(*cursor)->smdbc_impl = db2_cursor;
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
4507c478bd9Sstevel@tonic-gate }
4517c478bd9Sstevel@tonic-gate 
4527c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR == 2
4537c478bd9Sstevel@tonic-gate static int
smdb_db_open_internal(db_name,db_type,db_flags,db_params,db)4547c478bd9Sstevel@tonic-gate smdb_db_open_internal(db_name, db_type, db_flags, db_params, db)
4557c478bd9Sstevel@tonic-gate 	char *db_name;
4567c478bd9Sstevel@tonic-gate 	DBTYPE db_type;
4577c478bd9Sstevel@tonic-gate 	int db_flags;
4587c478bd9Sstevel@tonic-gate 	SMDB_DBPARAMS *db_params;
4597c478bd9Sstevel@tonic-gate 	DB **db;
4607c478bd9Sstevel@tonic-gate {
4617c478bd9Sstevel@tonic-gate 	void *params;
4627c478bd9Sstevel@tonic-gate 	DB_INFO db_info;
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate 	params = NULL;
4657c478bd9Sstevel@tonic-gate 	(void) memset(&db_info, '\0', sizeof db_info);
4667c478bd9Sstevel@tonic-gate 	if (db_params != NULL)
4677c478bd9Sstevel@tonic-gate 	{
4687c478bd9Sstevel@tonic-gate 		db_info.db_cachesize = db_params->smdbp_cache_size;
4697c478bd9Sstevel@tonic-gate 		if (db_type == DB_HASH)
4707c478bd9Sstevel@tonic-gate 			db_info.h_nelem = db_params->smdbp_num_elements;
4717c478bd9Sstevel@tonic-gate 		if (db_params->smdbp_allow_dup)
4727c478bd9Sstevel@tonic-gate 			db_info.flags |= DB_DUP;
4737c478bd9Sstevel@tonic-gate 		params = &db_info;
4747c478bd9Sstevel@tonic-gate 	}
4757c478bd9Sstevel@tonic-gate 	return db_open(db_name, db_type, db_flags, DBMMODE, NULL, params, db);
4767c478bd9Sstevel@tonic-gate }
4777c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR == 2 */
4787c478bd9Sstevel@tonic-gate 
4797c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR > 2
4807c478bd9Sstevel@tonic-gate static int
smdb_db_open_internal(db_name,db_type,db_flags,db_params,db)4817c478bd9Sstevel@tonic-gate smdb_db_open_internal(db_name, db_type, db_flags, db_params, db)
4827c478bd9Sstevel@tonic-gate 	char *db_name;
4837c478bd9Sstevel@tonic-gate 	DBTYPE db_type;
4847c478bd9Sstevel@tonic-gate 	int db_flags;
4857c478bd9Sstevel@tonic-gate 	SMDB_DBPARAMS *db_params;
4867c478bd9Sstevel@tonic-gate 	DB **db;
4877c478bd9Sstevel@tonic-gate {
4887c478bd9Sstevel@tonic-gate 	int result;
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate 	result = db_create(db, NULL, 0);
4917c478bd9Sstevel@tonic-gate 	if (result != 0 || *db == NULL)
4927c478bd9Sstevel@tonic-gate 		return result;
4937c478bd9Sstevel@tonic-gate 
4947c478bd9Sstevel@tonic-gate 	if (db_params != NULL)
4957c478bd9Sstevel@tonic-gate 	{
4967c478bd9Sstevel@tonic-gate 		result = (*db)->set_cachesize(*db, 0,
4977c478bd9Sstevel@tonic-gate 					      db_params->smdbp_cache_size, 0);
4987c478bd9Sstevel@tonic-gate 		if (result != 0)
4997c478bd9Sstevel@tonic-gate 		{
5007c478bd9Sstevel@tonic-gate 			(void) (*db)->close((*db), 0);
5017c478bd9Sstevel@tonic-gate 			*db = NULL;
5027c478bd9Sstevel@tonic-gate 			return db2_error_to_smdb(result);
5037c478bd9Sstevel@tonic-gate 		}
5047c478bd9Sstevel@tonic-gate 		if (db_type == DB_HASH)
5057c478bd9Sstevel@tonic-gate 		{
5067c478bd9Sstevel@tonic-gate 			result = (*db)->set_h_nelem(*db, db_params->smdbp_num_elements);
5077c478bd9Sstevel@tonic-gate 			if (result != 0)
5087c478bd9Sstevel@tonic-gate 			{
5097c478bd9Sstevel@tonic-gate 				(void) (*db)->close(*db, 0);
5107c478bd9Sstevel@tonic-gate 				*db = NULL;
5117c478bd9Sstevel@tonic-gate 				return db2_error_to_smdb(result);
5127c478bd9Sstevel@tonic-gate 			}
5137c478bd9Sstevel@tonic-gate 		}
5147c478bd9Sstevel@tonic-gate 		if (db_params->smdbp_allow_dup)
5157c478bd9Sstevel@tonic-gate 		{
5167c478bd9Sstevel@tonic-gate 			result = (*db)->set_flags(*db, DB_DUP);
5177c478bd9Sstevel@tonic-gate 			if (result != 0)
5187c478bd9Sstevel@tonic-gate 			{
5197c478bd9Sstevel@tonic-gate 				(void) (*db)->close(*db, 0);
5207c478bd9Sstevel@tonic-gate 				*db = NULL;
5217c478bd9Sstevel@tonic-gate 				return db2_error_to_smdb(result);
5227c478bd9Sstevel@tonic-gate 			}
5237c478bd9Sstevel@tonic-gate 		}
5247c478bd9Sstevel@tonic-gate 	}
5257c478bd9Sstevel@tonic-gate 
5267c478bd9Sstevel@tonic-gate 	result = (*db)->open(*db,
5277c478bd9Sstevel@tonic-gate 			     DBTXN	/* transaction for DB 4.1 */
5287c478bd9Sstevel@tonic-gate 			     db_name, NULL, db_type, db_flags, DBMMODE);
5297c478bd9Sstevel@tonic-gate 	if (result != 0)
5307c478bd9Sstevel@tonic-gate 	{
5317c478bd9Sstevel@tonic-gate 		(void) (*db)->close(*db, 0);
5327c478bd9Sstevel@tonic-gate 		*db = NULL;
5337c478bd9Sstevel@tonic-gate 	}
5347c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(result);
5357c478bd9Sstevel@tonic-gate }
5367c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR > 2 */
5377c478bd9Sstevel@tonic-gate /*
5387c478bd9Sstevel@tonic-gate **  SMDB_DB_OPEN -- Opens a db database.
5397c478bd9Sstevel@tonic-gate **
5407c478bd9Sstevel@tonic-gate **	Parameters:
5417c478bd9Sstevel@tonic-gate **		database -- An unallocated database pointer to a pointer.
5427c478bd9Sstevel@tonic-gate **		db_name -- The name of the database without extension.
5437c478bd9Sstevel@tonic-gate **		mode -- File permisions for a created database.
5447c478bd9Sstevel@tonic-gate **		mode_mask -- Mode bits that must match on an opened database.
5457c478bd9Sstevel@tonic-gate **		sff -- Flags for safefile.
5467c478bd9Sstevel@tonic-gate **		type -- The type of database to open
5477c478bd9Sstevel@tonic-gate **			See smdb_type_to_db2_type for valid types.
5487c478bd9Sstevel@tonic-gate **		user_info -- User information for file permissions.
5497c478bd9Sstevel@tonic-gate **		db_params --
5507c478bd9Sstevel@tonic-gate **			An SMDB_DBPARAMS struct including params. These
5517c478bd9Sstevel@tonic-gate **			are processed according to the type of the
5527c478bd9Sstevel@tonic-gate **			database. Currently supported params (only for
5537c478bd9Sstevel@tonic-gate **			HASH type) are:
5547c478bd9Sstevel@tonic-gate **			   num_elements
5557c478bd9Sstevel@tonic-gate **			   cache_size
5567c478bd9Sstevel@tonic-gate **
5577c478bd9Sstevel@tonic-gate **	Returns:
5587c478bd9Sstevel@tonic-gate **		SMDBE_OK -- Success, other errno:
5597c478bd9Sstevel@tonic-gate **		SMDBE_MALLOC -- Cannot allocate memory.
5607c478bd9Sstevel@tonic-gate **		SMDBE_BAD_OPEN -- db_open didn't return an error, but
5617c478bd9Sstevel@tonic-gate **				 somehow the DB pointer is NULL.
5627c478bd9Sstevel@tonic-gate **		Anything else: translated error from db2
5637c478bd9Sstevel@tonic-gate */
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate int
smdb_db_open(database,db_name,mode,mode_mask,sff,type,user_info,db_params)5667c478bd9Sstevel@tonic-gate smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info, db_params)
5677c478bd9Sstevel@tonic-gate 	SMDB_DATABASE **database;
5687c478bd9Sstevel@tonic-gate 	char *db_name;
5697c478bd9Sstevel@tonic-gate 	int mode;
5707c478bd9Sstevel@tonic-gate 	int mode_mask;
5717c478bd9Sstevel@tonic-gate 	long sff;
5727c478bd9Sstevel@tonic-gate 	SMDB_DBTYPE type;
5737c478bd9Sstevel@tonic-gate 	SMDB_USER_INFO *user_info;
5747c478bd9Sstevel@tonic-gate 	SMDB_DBPARAMS *db_params;
5757c478bd9Sstevel@tonic-gate {
5767c478bd9Sstevel@tonic-gate 	bool lockcreated = false;
5777c478bd9Sstevel@tonic-gate 	int result;
5787c478bd9Sstevel@tonic-gate 	int db_flags;
5797c478bd9Sstevel@tonic-gate 	int lock_fd;
5807c478bd9Sstevel@tonic-gate 	int db_fd;
5817c478bd9Sstevel@tonic-gate 	int major_v, minor_v, patch_v;
5827c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *smdb_db;
5837c478bd9Sstevel@tonic-gate 	SMDB_DB2_DATABASE *db2;
5847c478bd9Sstevel@tonic-gate 	DB *db;
5857c478bd9Sstevel@tonic-gate 	DBTYPE db_type;
5867c478bd9Sstevel@tonic-gate 	struct stat stat_info;
5877c478bd9Sstevel@tonic-gate 	char db_file_name[MAXPATHLEN];
5887c478bd9Sstevel@tonic-gate 
5897c478bd9Sstevel@tonic-gate 	(void) db_version(&major_v, &minor_v, &patch_v);
5907c478bd9Sstevel@tonic-gate 	if (major_v != DB_VERSION_MAJOR || minor_v != DB_VERSION_MINOR)
5917c478bd9Sstevel@tonic-gate 		return SMDBE_VERSION_MISMATCH;
5927c478bd9Sstevel@tonic-gate 
5937c478bd9Sstevel@tonic-gate 	*database = NULL;
5947c478bd9Sstevel@tonic-gate 
5957c478bd9Sstevel@tonic-gate 	result = smdb_add_extension(db_file_name, sizeof db_file_name,
5967c478bd9Sstevel@tonic-gate 				    db_name, SMDB2_FILE_EXTENSION);
5977c478bd9Sstevel@tonic-gate 	if (result != SMDBE_OK)
5987c478bd9Sstevel@tonic-gate 		return result;
5997c478bd9Sstevel@tonic-gate 
6007c478bd9Sstevel@tonic-gate 	result = smdb_setup_file(db_name, SMDB2_FILE_EXTENSION,
6017c478bd9Sstevel@tonic-gate 				 mode_mask, sff, user_info, &stat_info);
6027c478bd9Sstevel@tonic-gate 	if (result != SMDBE_OK)
6037c478bd9Sstevel@tonic-gate 		return result;
6047c478bd9Sstevel@tonic-gate 
6057c478bd9Sstevel@tonic-gate 	lock_fd = -1;
6067c478bd9Sstevel@tonic-gate 
6077c478bd9Sstevel@tonic-gate 	if (stat_info.st_mode == ST_MODE_NOFILE &&
6087c478bd9Sstevel@tonic-gate 	    bitset(mode, O_CREAT))
6097c478bd9Sstevel@tonic-gate 		lockcreated = true;
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 	result = smdb_lock_file(&lock_fd, db_name, mode, sff,
6127c478bd9Sstevel@tonic-gate 				SMDB2_FILE_EXTENSION);
6137c478bd9Sstevel@tonic-gate 	if (result != SMDBE_OK)
6147c478bd9Sstevel@tonic-gate 		return result;
6157c478bd9Sstevel@tonic-gate 
6167c478bd9Sstevel@tonic-gate 	if (lockcreated)
6177c478bd9Sstevel@tonic-gate 	{
6187c478bd9Sstevel@tonic-gate 		mode |= O_TRUNC;
6197c478bd9Sstevel@tonic-gate 		mode &= ~(O_CREAT|O_EXCL);
6207c478bd9Sstevel@tonic-gate 	}
6217c478bd9Sstevel@tonic-gate 
6227c478bd9Sstevel@tonic-gate 	smdb_db = smdb_malloc_database();
6237c478bd9Sstevel@tonic-gate 	db2 = smdb2_malloc_database();
624*e9af4bc0SJohn Beck 	if (db2 == NULL || smdb_db == NULL)
625*e9af4bc0SJohn Beck 	{
626*e9af4bc0SJohn Beck 		smdb_unlock_file(lock_fd);
627*e9af4bc0SJohn Beck 		smdb_free_database(smdb_db);	/* ok to be NULL */
6287c478bd9Sstevel@tonic-gate 		return SMDBE_MALLOC;
629*e9af4bc0SJohn Beck 	}
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate 	db2->smdb2_lock_fd = lock_fd;
6327c478bd9Sstevel@tonic-gate 
6337c478bd9Sstevel@tonic-gate 	db_type = smdb_type_to_db2_type(type);
6347c478bd9Sstevel@tonic-gate 
6357c478bd9Sstevel@tonic-gate 	db = NULL;
6367c478bd9Sstevel@tonic-gate 
6377c478bd9Sstevel@tonic-gate 	db_flags = 0;
6387c478bd9Sstevel@tonic-gate 	if (bitset(O_CREAT, mode))
6397c478bd9Sstevel@tonic-gate 		db_flags |= DB_CREATE;
6407c478bd9Sstevel@tonic-gate 	if (bitset(O_TRUNC, mode))
6417c478bd9Sstevel@tonic-gate 		db_flags |= DB_TRUNCATE;
6427c478bd9Sstevel@tonic-gate 	if (mode == O_RDONLY)
6437c478bd9Sstevel@tonic-gate 		db_flags |= DB_RDONLY;
6447c478bd9Sstevel@tonic-gate 	SM_DB_FLAG_ADD(db_flags);
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate 	result = smdb_db_open_internal(db_file_name, db_type,
6477c478bd9Sstevel@tonic-gate 				       db_flags, db_params, &db);
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate 	if (result == 0 && db != NULL)
6507c478bd9Sstevel@tonic-gate 	{
6517c478bd9Sstevel@tonic-gate 		result = db->fd(db, &db_fd);
6527c478bd9Sstevel@tonic-gate 		if (result == 0)
6537c478bd9Sstevel@tonic-gate 			result = SMDBE_OK;
6547c478bd9Sstevel@tonic-gate 	}
6557c478bd9Sstevel@tonic-gate 	else
6567c478bd9Sstevel@tonic-gate 	{
6577c478bd9Sstevel@tonic-gate 		/* Try and narrow down on the problem */
6587c478bd9Sstevel@tonic-gate 		if (result != 0)
6597c478bd9Sstevel@tonic-gate 			result = db2_error_to_smdb(result);
6607c478bd9Sstevel@tonic-gate 		else
6617c478bd9Sstevel@tonic-gate 			result = SMDBE_BAD_OPEN;
6627c478bd9Sstevel@tonic-gate 	}
6637c478bd9Sstevel@tonic-gate 
6647c478bd9Sstevel@tonic-gate 	if (result == SMDBE_OK)
6657c478bd9Sstevel@tonic-gate 		result = smdb_filechanged(db_name, SMDB2_FILE_EXTENSION, db_fd,
6667c478bd9Sstevel@tonic-gate 					  &stat_info);
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate 	if (result == SMDBE_OK)
6697c478bd9Sstevel@tonic-gate 	{
6707c478bd9Sstevel@tonic-gate 		/* Everything is ok. Setup driver */
6717c478bd9Sstevel@tonic-gate 		db2->smdb2_db = db;
6727c478bd9Sstevel@tonic-gate 
6737c478bd9Sstevel@tonic-gate 		smdb_db->smdb_close = smdb2_close;
6747c478bd9Sstevel@tonic-gate 		smdb_db->smdb_del = smdb2_del;
6757c478bd9Sstevel@tonic-gate 		smdb_db->smdb_fd = smdb2_fd;
6767c478bd9Sstevel@tonic-gate 		smdb_db->smdb_lockfd = smdb2_lockfd;
6777c478bd9Sstevel@tonic-gate 		smdb_db->smdb_get = smdb2_get;
6787c478bd9Sstevel@tonic-gate 		smdb_db->smdb_put = smdb2_put;
6797c478bd9Sstevel@tonic-gate 		smdb_db->smdb_set_owner = smdb2_set_owner;
6807c478bd9Sstevel@tonic-gate 		smdb_db->smdb_sync = smdb2_sync;
6817c478bd9Sstevel@tonic-gate 		smdb_db->smdb_cursor = smdb2_cursor;
6827c478bd9Sstevel@tonic-gate 		smdb_db->smdb_impl = db2;
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate 		*database = smdb_db;
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate 		return SMDBE_OK;
6877c478bd9Sstevel@tonic-gate 	}
6887c478bd9Sstevel@tonic-gate 
6897c478bd9Sstevel@tonic-gate 	if (db != NULL)
6907c478bd9Sstevel@tonic-gate 		db->close(db, 0);
6917c478bd9Sstevel@tonic-gate 
6927c478bd9Sstevel@tonic-gate 	smdb_unlock_file(db2->smdb2_lock_fd);
6937c478bd9Sstevel@tonic-gate 	free(db2);
6947c478bd9Sstevel@tonic-gate 	smdb_free_database(smdb_db);
6957c478bd9Sstevel@tonic-gate 
6967c478bd9Sstevel@tonic-gate 	return result;
6977c478bd9Sstevel@tonic-gate }
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate #endif /* (DB_VERSION_MAJOR >= 2) */
700