xref: /titanic_44/usr/src/cmd/sendmail/libsmdb/smdb2.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate ** Copyright (c) 1999-2003 Sendmail, Inc. and its suppliers.
3*7c478bd9Sstevel@tonic-gate **	All rights reserved.
4*7c478bd9Sstevel@tonic-gate **
5*7c478bd9Sstevel@tonic-gate ** By using this file, you agree to the terms and conditions set
6*7c478bd9Sstevel@tonic-gate ** forth in the LICENSE file which can be found at the top level of
7*7c478bd9Sstevel@tonic-gate ** the sendmail distribution.
8*7c478bd9Sstevel@tonic-gate */
9*7c478bd9Sstevel@tonic-gate 
10*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
11*7c478bd9Sstevel@tonic-gate 
12*7c478bd9Sstevel@tonic-gate #include <sm/gen.h>
13*7c478bd9Sstevel@tonic-gate SM_RCSID("@(#)$Id: smdb2.c,v 8.72.2.7 2003/06/24 17:16:10 ca Exp $")
14*7c478bd9Sstevel@tonic-gate 
15*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
16*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
17*7c478bd9Sstevel@tonic-gate #include <unistd.h>
18*7c478bd9Sstevel@tonic-gate 
19*7c478bd9Sstevel@tonic-gate 
20*7c478bd9Sstevel@tonic-gate #include <sendmail/sendmail.h>
21*7c478bd9Sstevel@tonic-gate #include <libsmdb/smdb.h>
22*7c478bd9Sstevel@tonic-gate 
23*7c478bd9Sstevel@tonic-gate #if (DB_VERSION_MAJOR >= 2)
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate # define SMDB2_FILE_EXTENSION "db"
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate struct smdb_db2_database
28*7c478bd9Sstevel@tonic-gate {
29*7c478bd9Sstevel@tonic-gate 	DB	*smdb2_db;
30*7c478bd9Sstevel@tonic-gate 	int	smdb2_lock_fd;
31*7c478bd9Sstevel@tonic-gate };
32*7c478bd9Sstevel@tonic-gate typedef struct smdb_db2_database SMDB_DB2_DATABASE;
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate /*
35*7c478bd9Sstevel@tonic-gate **  SMDB_TYPE_TO_DB2_TYPE -- Translates smdb database type to db2 type.
36*7c478bd9Sstevel@tonic-gate **
37*7c478bd9Sstevel@tonic-gate **	Parameters:
38*7c478bd9Sstevel@tonic-gate **		type -- The type to translate.
39*7c478bd9Sstevel@tonic-gate **
40*7c478bd9Sstevel@tonic-gate **	Returns:
41*7c478bd9Sstevel@tonic-gate **		The DB2 type that corresponsds to the passed in SMDB type.
42*7c478bd9Sstevel@tonic-gate **		Returns -1 if there is no equivalent type.
43*7c478bd9Sstevel@tonic-gate **
44*7c478bd9Sstevel@tonic-gate */
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate DBTYPE
47*7c478bd9Sstevel@tonic-gate smdb_type_to_db2_type(type)
48*7c478bd9Sstevel@tonic-gate 	SMDB_DBTYPE type;
49*7c478bd9Sstevel@tonic-gate {
50*7c478bd9Sstevel@tonic-gate 	if (type == SMDB_TYPE_DEFAULT)
51*7c478bd9Sstevel@tonic-gate 		return DB_HASH;
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate 	if (strncmp(type, SMDB_TYPE_HASH, SMDB_TYPE_HASH_LEN) == 0)
54*7c478bd9Sstevel@tonic-gate 		return DB_HASH;
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate 	if (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0)
57*7c478bd9Sstevel@tonic-gate 		return DB_BTREE;
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate 	return DB_UNKNOWN;
60*7c478bd9Sstevel@tonic-gate }
61*7c478bd9Sstevel@tonic-gate /*
62*7c478bd9Sstevel@tonic-gate **  DB2_ERROR_TO_SMDB -- Translates db2 errors to smdbe errors
63*7c478bd9Sstevel@tonic-gate **
64*7c478bd9Sstevel@tonic-gate **	Parameters:
65*7c478bd9Sstevel@tonic-gate **		error -- The error to translate.
66*7c478bd9Sstevel@tonic-gate **
67*7c478bd9Sstevel@tonic-gate **	Returns:
68*7c478bd9Sstevel@tonic-gate **		The SMDBE error corresponding to the db2 error.
69*7c478bd9Sstevel@tonic-gate **		If we don't have a corresponding error, it returs errno.
70*7c478bd9Sstevel@tonic-gate **
71*7c478bd9Sstevel@tonic-gate */
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate int
74*7c478bd9Sstevel@tonic-gate db2_error_to_smdb(error)
75*7c478bd9Sstevel@tonic-gate 	int error;
76*7c478bd9Sstevel@tonic-gate {
77*7c478bd9Sstevel@tonic-gate 	int result;
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate 	switch (error)
80*7c478bd9Sstevel@tonic-gate 	{
81*7c478bd9Sstevel@tonic-gate # ifdef DB_INCOMPLETE
82*7c478bd9Sstevel@tonic-gate 		case DB_INCOMPLETE:
83*7c478bd9Sstevel@tonic-gate 			result = SMDBE_INCOMPLETE;
84*7c478bd9Sstevel@tonic-gate 			break;
85*7c478bd9Sstevel@tonic-gate # endif /* DB_INCOMPLETE */
86*7c478bd9Sstevel@tonic-gate 
87*7c478bd9Sstevel@tonic-gate # ifdef DB_NOTFOUND
88*7c478bd9Sstevel@tonic-gate 		case DB_NOTFOUND:
89*7c478bd9Sstevel@tonic-gate 			result = SMDBE_NOT_FOUND;
90*7c478bd9Sstevel@tonic-gate 			break;
91*7c478bd9Sstevel@tonic-gate # endif /* DB_NOTFOUND */
92*7c478bd9Sstevel@tonic-gate 
93*7c478bd9Sstevel@tonic-gate # ifdef DB_KEYEMPTY
94*7c478bd9Sstevel@tonic-gate 		case DB_KEYEMPTY:
95*7c478bd9Sstevel@tonic-gate 			result = SMDBE_KEY_EMPTY;
96*7c478bd9Sstevel@tonic-gate 			break;
97*7c478bd9Sstevel@tonic-gate # endif /* DB_KEYEMPTY */
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate # ifdef DB_KEYEXIST
100*7c478bd9Sstevel@tonic-gate 		case DB_KEYEXIST:
101*7c478bd9Sstevel@tonic-gate 			result = SMDBE_KEY_EXIST;
102*7c478bd9Sstevel@tonic-gate 			break;
103*7c478bd9Sstevel@tonic-gate # endif /* DB_KEYEXIST */
104*7c478bd9Sstevel@tonic-gate 
105*7c478bd9Sstevel@tonic-gate # ifdef DB_LOCK_DEADLOCK
106*7c478bd9Sstevel@tonic-gate 		case DB_LOCK_DEADLOCK:
107*7c478bd9Sstevel@tonic-gate 			result = SMDBE_LOCK_DEADLOCK;
108*7c478bd9Sstevel@tonic-gate 			break;
109*7c478bd9Sstevel@tonic-gate # endif /* DB_LOCK_DEADLOCK */
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate # ifdef DB_LOCK_NOTGRANTED
112*7c478bd9Sstevel@tonic-gate 		case DB_LOCK_NOTGRANTED:
113*7c478bd9Sstevel@tonic-gate 			result = SMDBE_LOCK_NOT_GRANTED;
114*7c478bd9Sstevel@tonic-gate 			break;
115*7c478bd9Sstevel@tonic-gate # endif /* DB_LOCK_NOTGRANTED */
116*7c478bd9Sstevel@tonic-gate 
117*7c478bd9Sstevel@tonic-gate # ifdef DB_LOCK_NOTHELD
118*7c478bd9Sstevel@tonic-gate 		case DB_LOCK_NOTHELD:
119*7c478bd9Sstevel@tonic-gate 			result = SMDBE_LOCK_NOT_HELD;
120*7c478bd9Sstevel@tonic-gate 			break;
121*7c478bd9Sstevel@tonic-gate # endif /* DB_LOCK_NOTHELD */
122*7c478bd9Sstevel@tonic-gate 
123*7c478bd9Sstevel@tonic-gate # ifdef DB_RUNRECOVERY
124*7c478bd9Sstevel@tonic-gate 		case DB_RUNRECOVERY:
125*7c478bd9Sstevel@tonic-gate 			result = SMDBE_RUN_RECOVERY;
126*7c478bd9Sstevel@tonic-gate 			break;
127*7c478bd9Sstevel@tonic-gate # endif /* DB_RUNRECOVERY */
128*7c478bd9Sstevel@tonic-gate 
129*7c478bd9Sstevel@tonic-gate # ifdef DB_OLD_VERSION
130*7c478bd9Sstevel@tonic-gate 		case DB_OLD_VERSION:
131*7c478bd9Sstevel@tonic-gate 			result = SMDBE_OLD_VERSION;
132*7c478bd9Sstevel@tonic-gate 			break;
133*7c478bd9Sstevel@tonic-gate # endif /* DB_OLD_VERSION */
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate 		case 0:
136*7c478bd9Sstevel@tonic-gate 			result = SMDBE_OK;
137*7c478bd9Sstevel@tonic-gate 			break;
138*7c478bd9Sstevel@tonic-gate 
139*7c478bd9Sstevel@tonic-gate 		default:
140*7c478bd9Sstevel@tonic-gate 			result = error;
141*7c478bd9Sstevel@tonic-gate 	}
142*7c478bd9Sstevel@tonic-gate 	return result;
143*7c478bd9Sstevel@tonic-gate }
144*7c478bd9Sstevel@tonic-gate /*
145*7c478bd9Sstevel@tonic-gate **  SMDB_PUT_FLAGS_TO_DB2_FLAGS -- Translates smdb put flags to db2 put flags.
146*7c478bd9Sstevel@tonic-gate **
147*7c478bd9Sstevel@tonic-gate **	Parameters:
148*7c478bd9Sstevel@tonic-gate **		flags -- The flags to translate.
149*7c478bd9Sstevel@tonic-gate **
150*7c478bd9Sstevel@tonic-gate **	Returns:
151*7c478bd9Sstevel@tonic-gate **		The db2 flags that are equivalent to the smdb flags.
152*7c478bd9Sstevel@tonic-gate **
153*7c478bd9Sstevel@tonic-gate **	Notes:
154*7c478bd9Sstevel@tonic-gate **		Any invalid flags are ignored.
155*7c478bd9Sstevel@tonic-gate **
156*7c478bd9Sstevel@tonic-gate */
157*7c478bd9Sstevel@tonic-gate 
158*7c478bd9Sstevel@tonic-gate unsigned int
159*7c478bd9Sstevel@tonic-gate smdb_put_flags_to_db2_flags(flags)
160*7c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
161*7c478bd9Sstevel@tonic-gate {
162*7c478bd9Sstevel@tonic-gate 	int return_flags;
163*7c478bd9Sstevel@tonic-gate 
164*7c478bd9Sstevel@tonic-gate 	return_flags = 0;
165*7c478bd9Sstevel@tonic-gate 
166*7c478bd9Sstevel@tonic-gate 	if (bitset(SMDBF_NO_OVERWRITE, flags))
167*7c478bd9Sstevel@tonic-gate 		return_flags |= DB_NOOVERWRITE;
168*7c478bd9Sstevel@tonic-gate 
169*7c478bd9Sstevel@tonic-gate 	return return_flags;
170*7c478bd9Sstevel@tonic-gate }
171*7c478bd9Sstevel@tonic-gate /*
172*7c478bd9Sstevel@tonic-gate **  SMDB_CURSOR_GET_FLAGS_TO_DB2 -- Translates smdb cursor get flags to db2
173*7c478bd9Sstevel@tonic-gate **	getflags.
174*7c478bd9Sstevel@tonic-gate **
175*7c478bd9Sstevel@tonic-gate **	Parameters:
176*7c478bd9Sstevel@tonic-gate **		flags -- The flags to translate.
177*7c478bd9Sstevel@tonic-gate **
178*7c478bd9Sstevel@tonic-gate **	Returns:
179*7c478bd9Sstevel@tonic-gate **		The db2 flags that are equivalent to the smdb flags.
180*7c478bd9Sstevel@tonic-gate **
181*7c478bd9Sstevel@tonic-gate **	Notes:
182*7c478bd9Sstevel@tonic-gate **		-1 is returned if flag is unknown.
183*7c478bd9Sstevel@tonic-gate **
184*7c478bd9Sstevel@tonic-gate */
185*7c478bd9Sstevel@tonic-gate 
186*7c478bd9Sstevel@tonic-gate int
187*7c478bd9Sstevel@tonic-gate smdb_cursor_get_flags_to_db2(flags)
188*7c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
189*7c478bd9Sstevel@tonic-gate {
190*7c478bd9Sstevel@tonic-gate 	switch (flags)
191*7c478bd9Sstevel@tonic-gate 	{
192*7c478bd9Sstevel@tonic-gate 		case SMDB_CURSOR_GET_FIRST:
193*7c478bd9Sstevel@tonic-gate 			return DB_FIRST;
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate 		case SMDB_CURSOR_GET_LAST:
196*7c478bd9Sstevel@tonic-gate 			return DB_LAST;
197*7c478bd9Sstevel@tonic-gate 
198*7c478bd9Sstevel@tonic-gate 		case SMDB_CURSOR_GET_NEXT:
199*7c478bd9Sstevel@tonic-gate 			return DB_NEXT;
200*7c478bd9Sstevel@tonic-gate 
201*7c478bd9Sstevel@tonic-gate 		case SMDB_CURSOR_GET_RANGE:
202*7c478bd9Sstevel@tonic-gate 			return DB_SET_RANGE;
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate 		default:
205*7c478bd9Sstevel@tonic-gate 			return -1;
206*7c478bd9Sstevel@tonic-gate 	}
207*7c478bd9Sstevel@tonic-gate }
208*7c478bd9Sstevel@tonic-gate 
209*7c478bd9Sstevel@tonic-gate /*
210*7c478bd9Sstevel@tonic-gate **  Except for smdb_db_open, the rest of these functions correspond to the
211*7c478bd9Sstevel@tonic-gate **  interface laid out in smdb.h.
212*7c478bd9Sstevel@tonic-gate */
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate SMDB_DB2_DATABASE *
215*7c478bd9Sstevel@tonic-gate smdb2_malloc_database()
216*7c478bd9Sstevel@tonic-gate {
217*7c478bd9Sstevel@tonic-gate 	SMDB_DB2_DATABASE *db2;
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate 	db2 = (SMDB_DB2_DATABASE *) malloc(sizeof(SMDB_DB2_DATABASE));
220*7c478bd9Sstevel@tonic-gate 	if (db2 != NULL)
221*7c478bd9Sstevel@tonic-gate 		db2->smdb2_lock_fd = -1;
222*7c478bd9Sstevel@tonic-gate 
223*7c478bd9Sstevel@tonic-gate 	return db2;
224*7c478bd9Sstevel@tonic-gate }
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate int
227*7c478bd9Sstevel@tonic-gate smdb2_close(database)
228*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
229*7c478bd9Sstevel@tonic-gate {
230*7c478bd9Sstevel@tonic-gate 	int result;
231*7c478bd9Sstevel@tonic-gate 	SMDB_DB2_DATABASE *db2 = (SMDB_DB2_DATABASE *) database->smdb_impl;
232*7c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate 	result = db2_error_to_smdb(db->close(db, 0));
235*7c478bd9Sstevel@tonic-gate 	if (db2->smdb2_lock_fd != -1)
236*7c478bd9Sstevel@tonic-gate 		close(db2->smdb2_lock_fd);
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate 	free(db2);
239*7c478bd9Sstevel@tonic-gate 	database->smdb_impl = NULL;
240*7c478bd9Sstevel@tonic-gate 
241*7c478bd9Sstevel@tonic-gate 	return result;
242*7c478bd9Sstevel@tonic-gate }
243*7c478bd9Sstevel@tonic-gate 
244*7c478bd9Sstevel@tonic-gate int
245*7c478bd9Sstevel@tonic-gate smdb2_del(database, key, flags)
246*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
247*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
248*7c478bd9Sstevel@tonic-gate 	unsigned int flags;
249*7c478bd9Sstevel@tonic-gate {
250*7c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
251*7c478bd9Sstevel@tonic-gate 	DBT dbkey;
252*7c478bd9Sstevel@tonic-gate 
253*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
254*7c478bd9Sstevel@tonic-gate 	dbkey.data = key->data;
255*7c478bd9Sstevel@tonic-gate 	dbkey.size = key->size;
256*7c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(db->del(db, NULL, &dbkey, flags));
257*7c478bd9Sstevel@tonic-gate }
258*7c478bd9Sstevel@tonic-gate 
259*7c478bd9Sstevel@tonic-gate int
260*7c478bd9Sstevel@tonic-gate smdb2_fd(database, fd)
261*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
262*7c478bd9Sstevel@tonic-gate 	int *fd;
263*7c478bd9Sstevel@tonic-gate {
264*7c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
265*7c478bd9Sstevel@tonic-gate 
266*7c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(db->fd(db, fd));
267*7c478bd9Sstevel@tonic-gate }
268*7c478bd9Sstevel@tonic-gate 
269*7c478bd9Sstevel@tonic-gate int
270*7c478bd9Sstevel@tonic-gate smdb2_lockfd(database)
271*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
272*7c478bd9Sstevel@tonic-gate {
273*7c478bd9Sstevel@tonic-gate 	SMDB_DB2_DATABASE *db2 = (SMDB_DB2_DATABASE *) database->smdb_impl;
274*7c478bd9Sstevel@tonic-gate 
275*7c478bd9Sstevel@tonic-gate 	return db2->smdb2_lock_fd;
276*7c478bd9Sstevel@tonic-gate }
277*7c478bd9Sstevel@tonic-gate 
278*7c478bd9Sstevel@tonic-gate int
279*7c478bd9Sstevel@tonic-gate smdb2_get(database, key, data, flags)
280*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
281*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
282*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *data;
283*7c478bd9Sstevel@tonic-gate 	unsigned int flags;
284*7c478bd9Sstevel@tonic-gate {
285*7c478bd9Sstevel@tonic-gate 	int result;
286*7c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
287*7c478bd9Sstevel@tonic-gate 	DBT dbkey, dbdata;
288*7c478bd9Sstevel@tonic-gate 
289*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
290*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
291*7c478bd9Sstevel@tonic-gate 	dbkey.data = key->data;
292*7c478bd9Sstevel@tonic-gate 	dbkey.size = key->size;
293*7c478bd9Sstevel@tonic-gate 
294*7c478bd9Sstevel@tonic-gate 	result = db->get(db, NULL, &dbkey, &dbdata, flags);
295*7c478bd9Sstevel@tonic-gate 	data->data = dbdata.data;
296*7c478bd9Sstevel@tonic-gate 	data->size = dbdata.size;
297*7c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(result);
298*7c478bd9Sstevel@tonic-gate }
299*7c478bd9Sstevel@tonic-gate 
300*7c478bd9Sstevel@tonic-gate int
301*7c478bd9Sstevel@tonic-gate smdb2_put(database, key, data, flags)
302*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
303*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
304*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *data;
305*7c478bd9Sstevel@tonic-gate 	unsigned int flags;
306*7c478bd9Sstevel@tonic-gate {
307*7c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
308*7c478bd9Sstevel@tonic-gate 	DBT dbkey, dbdata;
309*7c478bd9Sstevel@tonic-gate 
310*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
311*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
312*7c478bd9Sstevel@tonic-gate 	dbkey.data = key->data;
313*7c478bd9Sstevel@tonic-gate 	dbkey.size = key->size;
314*7c478bd9Sstevel@tonic-gate 	dbdata.data = data->data;
315*7c478bd9Sstevel@tonic-gate 	dbdata.size = data->size;
316*7c478bd9Sstevel@tonic-gate 
317*7c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(db->put(db, NULL, &dbkey, &dbdata,
318*7c478bd9Sstevel@tonic-gate 					 smdb_put_flags_to_db2_flags(flags)));
319*7c478bd9Sstevel@tonic-gate }
320*7c478bd9Sstevel@tonic-gate 
321*7c478bd9Sstevel@tonic-gate 
322*7c478bd9Sstevel@tonic-gate int
323*7c478bd9Sstevel@tonic-gate smdb2_set_owner(database, uid, gid)
324*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
325*7c478bd9Sstevel@tonic-gate 	uid_t uid;
326*7c478bd9Sstevel@tonic-gate 	gid_t gid;
327*7c478bd9Sstevel@tonic-gate {
328*7c478bd9Sstevel@tonic-gate # if HASFCHOWN
329*7c478bd9Sstevel@tonic-gate 	int fd;
330*7c478bd9Sstevel@tonic-gate 	int result;
331*7c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
332*7c478bd9Sstevel@tonic-gate 
333*7c478bd9Sstevel@tonic-gate 	result = db->fd(db, &fd);
334*7c478bd9Sstevel@tonic-gate 	if (result != 0)
335*7c478bd9Sstevel@tonic-gate 		return result;
336*7c478bd9Sstevel@tonic-gate 
337*7c478bd9Sstevel@tonic-gate 	result = fchown(fd, uid, gid);
338*7c478bd9Sstevel@tonic-gate 	if (result < 0)
339*7c478bd9Sstevel@tonic-gate 		return errno;
340*7c478bd9Sstevel@tonic-gate # endif /* HASFCHOWN */
341*7c478bd9Sstevel@tonic-gate 
342*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
343*7c478bd9Sstevel@tonic-gate }
344*7c478bd9Sstevel@tonic-gate 
345*7c478bd9Sstevel@tonic-gate int
346*7c478bd9Sstevel@tonic-gate smdb2_sync(database, flags)
347*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
348*7c478bd9Sstevel@tonic-gate 	unsigned int flags;
349*7c478bd9Sstevel@tonic-gate {
350*7c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
351*7c478bd9Sstevel@tonic-gate 
352*7c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(db->sync(db, flags));
353*7c478bd9Sstevel@tonic-gate }
354*7c478bd9Sstevel@tonic-gate 
355*7c478bd9Sstevel@tonic-gate int
356*7c478bd9Sstevel@tonic-gate smdb2_cursor_close(cursor)
357*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
358*7c478bd9Sstevel@tonic-gate {
359*7c478bd9Sstevel@tonic-gate 	int ret;
360*7c478bd9Sstevel@tonic-gate 	DBC *dbc = (DBC *) cursor->smdbc_impl;
361*7c478bd9Sstevel@tonic-gate 
362*7c478bd9Sstevel@tonic-gate 	ret = db2_error_to_smdb(dbc->c_close(dbc));
363*7c478bd9Sstevel@tonic-gate 	free(cursor);
364*7c478bd9Sstevel@tonic-gate 	return ret;
365*7c478bd9Sstevel@tonic-gate }
366*7c478bd9Sstevel@tonic-gate 
367*7c478bd9Sstevel@tonic-gate int
368*7c478bd9Sstevel@tonic-gate smdb2_cursor_del(cursor, flags)
369*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
370*7c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
371*7c478bd9Sstevel@tonic-gate {
372*7c478bd9Sstevel@tonic-gate 	DBC *dbc = (DBC *) cursor->smdbc_impl;
373*7c478bd9Sstevel@tonic-gate 
374*7c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(dbc->c_del(dbc, 0));
375*7c478bd9Sstevel@tonic-gate }
376*7c478bd9Sstevel@tonic-gate 
377*7c478bd9Sstevel@tonic-gate int
378*7c478bd9Sstevel@tonic-gate smdb2_cursor_get(cursor, key, value, flags)
379*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
380*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
381*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *value;
382*7c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
383*7c478bd9Sstevel@tonic-gate {
384*7c478bd9Sstevel@tonic-gate 	int db2_flags;
385*7c478bd9Sstevel@tonic-gate 	int result;
386*7c478bd9Sstevel@tonic-gate 	DBC *dbc = (DBC *) cursor->smdbc_impl;
387*7c478bd9Sstevel@tonic-gate 	DBT dbkey, dbdata;
388*7c478bd9Sstevel@tonic-gate 
389*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
390*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
391*7c478bd9Sstevel@tonic-gate 
392*7c478bd9Sstevel@tonic-gate 	db2_flags = smdb_cursor_get_flags_to_db2(flags);
393*7c478bd9Sstevel@tonic-gate 	result = dbc->c_get(dbc, &dbkey, &dbdata, db2_flags);
394*7c478bd9Sstevel@tonic-gate 	if (result == DB_NOTFOUND)
395*7c478bd9Sstevel@tonic-gate 		return SMDBE_LAST_ENTRY;
396*7c478bd9Sstevel@tonic-gate 	key->data = dbkey.data;
397*7c478bd9Sstevel@tonic-gate 	key->size = dbkey.size;
398*7c478bd9Sstevel@tonic-gate 	value->data = dbdata.data;
399*7c478bd9Sstevel@tonic-gate 	value->size = dbdata.size;
400*7c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(result);
401*7c478bd9Sstevel@tonic-gate }
402*7c478bd9Sstevel@tonic-gate 
403*7c478bd9Sstevel@tonic-gate int
404*7c478bd9Sstevel@tonic-gate smdb2_cursor_put(cursor, key, value, flags)
405*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
406*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
407*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *value;
408*7c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
409*7c478bd9Sstevel@tonic-gate {
410*7c478bd9Sstevel@tonic-gate 	DBC *dbc = (DBC *) cursor->smdbc_impl;
411*7c478bd9Sstevel@tonic-gate 	DBT dbkey, dbdata;
412*7c478bd9Sstevel@tonic-gate 
413*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
414*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
415*7c478bd9Sstevel@tonic-gate 	dbkey.data = key->data;
416*7c478bd9Sstevel@tonic-gate 	dbkey.size = key->size;
417*7c478bd9Sstevel@tonic-gate 	dbdata.data = value->data;
418*7c478bd9Sstevel@tonic-gate 	dbdata.size = value->size;
419*7c478bd9Sstevel@tonic-gate 
420*7c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(dbc->c_put(dbc, &dbkey, &dbdata, 0));
421*7c478bd9Sstevel@tonic-gate }
422*7c478bd9Sstevel@tonic-gate 
423*7c478bd9Sstevel@tonic-gate int
424*7c478bd9Sstevel@tonic-gate smdb2_cursor(database, cursor, flags)
425*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
426*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR **cursor;
427*7c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
428*7c478bd9Sstevel@tonic-gate {
429*7c478bd9Sstevel@tonic-gate 	int result;
430*7c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB2_DATABASE *) database->smdb_impl)->smdb2_db;
431*7c478bd9Sstevel@tonic-gate 	DBC *db2_cursor;
432*7c478bd9Sstevel@tonic-gate 
433*7c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR > 2 || DB_VERSION_MINOR >= 6
434*7c478bd9Sstevel@tonic-gate 	result = db->cursor(db, NULL, &db2_cursor, 0);
435*7c478bd9Sstevel@tonic-gate # else /* DB_VERSION_MAJOR > 2 || DB_VERSION_MINOR >= 6 */
436*7c478bd9Sstevel@tonic-gate 	result = db->cursor(db, NULL, &db2_cursor);
437*7c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR > 2 || DB_VERSION_MINOR >= 6 */
438*7c478bd9Sstevel@tonic-gate 	if (result != 0)
439*7c478bd9Sstevel@tonic-gate 		return db2_error_to_smdb(result);
440*7c478bd9Sstevel@tonic-gate 
441*7c478bd9Sstevel@tonic-gate 	*cursor = (SMDB_CURSOR *) malloc(sizeof(SMDB_CURSOR));
442*7c478bd9Sstevel@tonic-gate 	if (*cursor == NULL)
443*7c478bd9Sstevel@tonic-gate 		return SMDBE_MALLOC;
444*7c478bd9Sstevel@tonic-gate 
445*7c478bd9Sstevel@tonic-gate 	(*cursor)->smdbc_close = smdb2_cursor_close;
446*7c478bd9Sstevel@tonic-gate 	(*cursor)->smdbc_del = smdb2_cursor_del;
447*7c478bd9Sstevel@tonic-gate 	(*cursor)->smdbc_get = smdb2_cursor_get;
448*7c478bd9Sstevel@tonic-gate 	(*cursor)->smdbc_put = smdb2_cursor_put;
449*7c478bd9Sstevel@tonic-gate 	(*cursor)->smdbc_impl = db2_cursor;
450*7c478bd9Sstevel@tonic-gate 
451*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
452*7c478bd9Sstevel@tonic-gate }
453*7c478bd9Sstevel@tonic-gate 
454*7c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR == 2
455*7c478bd9Sstevel@tonic-gate static int
456*7c478bd9Sstevel@tonic-gate smdb_db_open_internal(db_name, db_type, db_flags, db_params, db)
457*7c478bd9Sstevel@tonic-gate 	char *db_name;
458*7c478bd9Sstevel@tonic-gate 	DBTYPE db_type;
459*7c478bd9Sstevel@tonic-gate 	int db_flags;
460*7c478bd9Sstevel@tonic-gate 	SMDB_DBPARAMS *db_params;
461*7c478bd9Sstevel@tonic-gate 	DB **db;
462*7c478bd9Sstevel@tonic-gate {
463*7c478bd9Sstevel@tonic-gate 	void *params;
464*7c478bd9Sstevel@tonic-gate 	DB_INFO db_info;
465*7c478bd9Sstevel@tonic-gate 
466*7c478bd9Sstevel@tonic-gate 	params = NULL;
467*7c478bd9Sstevel@tonic-gate 	(void) memset(&db_info, '\0', sizeof db_info);
468*7c478bd9Sstevel@tonic-gate 	if (db_params != NULL)
469*7c478bd9Sstevel@tonic-gate 	{
470*7c478bd9Sstevel@tonic-gate 		db_info.db_cachesize = db_params->smdbp_cache_size;
471*7c478bd9Sstevel@tonic-gate 		if (db_type == DB_HASH)
472*7c478bd9Sstevel@tonic-gate 			db_info.h_nelem = db_params->smdbp_num_elements;
473*7c478bd9Sstevel@tonic-gate 		if (db_params->smdbp_allow_dup)
474*7c478bd9Sstevel@tonic-gate 			db_info.flags |= DB_DUP;
475*7c478bd9Sstevel@tonic-gate 		params = &db_info;
476*7c478bd9Sstevel@tonic-gate 	}
477*7c478bd9Sstevel@tonic-gate 	return db_open(db_name, db_type, db_flags, DBMMODE, NULL, params, db);
478*7c478bd9Sstevel@tonic-gate }
479*7c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR == 2 */
480*7c478bd9Sstevel@tonic-gate 
481*7c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR > 2
482*7c478bd9Sstevel@tonic-gate static int
483*7c478bd9Sstevel@tonic-gate smdb_db_open_internal(db_name, db_type, db_flags, db_params, db)
484*7c478bd9Sstevel@tonic-gate 	char *db_name;
485*7c478bd9Sstevel@tonic-gate 	DBTYPE db_type;
486*7c478bd9Sstevel@tonic-gate 	int db_flags;
487*7c478bd9Sstevel@tonic-gate 	SMDB_DBPARAMS *db_params;
488*7c478bd9Sstevel@tonic-gate 	DB **db;
489*7c478bd9Sstevel@tonic-gate {
490*7c478bd9Sstevel@tonic-gate 	int result;
491*7c478bd9Sstevel@tonic-gate 
492*7c478bd9Sstevel@tonic-gate 	result = db_create(db, NULL, 0);
493*7c478bd9Sstevel@tonic-gate 	if (result != 0 || *db == NULL)
494*7c478bd9Sstevel@tonic-gate 		return result;
495*7c478bd9Sstevel@tonic-gate 
496*7c478bd9Sstevel@tonic-gate 	if (db_params != NULL)
497*7c478bd9Sstevel@tonic-gate 	{
498*7c478bd9Sstevel@tonic-gate 		result = (*db)->set_cachesize(*db, 0,
499*7c478bd9Sstevel@tonic-gate 					      db_params->smdbp_cache_size, 0);
500*7c478bd9Sstevel@tonic-gate 		if (result != 0)
501*7c478bd9Sstevel@tonic-gate 		{
502*7c478bd9Sstevel@tonic-gate 			(void) (*db)->close((*db), 0);
503*7c478bd9Sstevel@tonic-gate 			*db = NULL;
504*7c478bd9Sstevel@tonic-gate 			return db2_error_to_smdb(result);
505*7c478bd9Sstevel@tonic-gate 		}
506*7c478bd9Sstevel@tonic-gate 		if (db_type == DB_HASH)
507*7c478bd9Sstevel@tonic-gate 		{
508*7c478bd9Sstevel@tonic-gate 			result = (*db)->set_h_nelem(*db, db_params->smdbp_num_elements);
509*7c478bd9Sstevel@tonic-gate 			if (result != 0)
510*7c478bd9Sstevel@tonic-gate 			{
511*7c478bd9Sstevel@tonic-gate 				(void) (*db)->close(*db, 0);
512*7c478bd9Sstevel@tonic-gate 				*db = NULL;
513*7c478bd9Sstevel@tonic-gate 				return db2_error_to_smdb(result);
514*7c478bd9Sstevel@tonic-gate 			}
515*7c478bd9Sstevel@tonic-gate 		}
516*7c478bd9Sstevel@tonic-gate 		if (db_params->smdbp_allow_dup)
517*7c478bd9Sstevel@tonic-gate 		{
518*7c478bd9Sstevel@tonic-gate 			result = (*db)->set_flags(*db, DB_DUP);
519*7c478bd9Sstevel@tonic-gate 			if (result != 0)
520*7c478bd9Sstevel@tonic-gate 			{
521*7c478bd9Sstevel@tonic-gate 				(void) (*db)->close(*db, 0);
522*7c478bd9Sstevel@tonic-gate 				*db = NULL;
523*7c478bd9Sstevel@tonic-gate 				return db2_error_to_smdb(result);
524*7c478bd9Sstevel@tonic-gate 			}
525*7c478bd9Sstevel@tonic-gate 		}
526*7c478bd9Sstevel@tonic-gate 	}
527*7c478bd9Sstevel@tonic-gate 
528*7c478bd9Sstevel@tonic-gate 	result = (*db)->open(*db,
529*7c478bd9Sstevel@tonic-gate 			     DBTXN	/* transaction for DB 4.1 */
530*7c478bd9Sstevel@tonic-gate 			     db_name, NULL, db_type, db_flags, DBMMODE);
531*7c478bd9Sstevel@tonic-gate 	if (result != 0)
532*7c478bd9Sstevel@tonic-gate 	{
533*7c478bd9Sstevel@tonic-gate 		(void) (*db)->close(*db, 0);
534*7c478bd9Sstevel@tonic-gate 		*db = NULL;
535*7c478bd9Sstevel@tonic-gate 	}
536*7c478bd9Sstevel@tonic-gate 	return db2_error_to_smdb(result);
537*7c478bd9Sstevel@tonic-gate }
538*7c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR > 2 */
539*7c478bd9Sstevel@tonic-gate /*
540*7c478bd9Sstevel@tonic-gate **  SMDB_DB_OPEN -- Opens a db database.
541*7c478bd9Sstevel@tonic-gate **
542*7c478bd9Sstevel@tonic-gate **	Parameters:
543*7c478bd9Sstevel@tonic-gate **		database -- An unallocated database pointer to a pointer.
544*7c478bd9Sstevel@tonic-gate **		db_name -- The name of the database without extension.
545*7c478bd9Sstevel@tonic-gate **		mode -- File permisions for a created database.
546*7c478bd9Sstevel@tonic-gate **		mode_mask -- Mode bits that must match on an opened database.
547*7c478bd9Sstevel@tonic-gate **		sff -- Flags for safefile.
548*7c478bd9Sstevel@tonic-gate **		type -- The type of database to open
549*7c478bd9Sstevel@tonic-gate **			See smdb_type_to_db2_type for valid types.
550*7c478bd9Sstevel@tonic-gate **		user_info -- User information for file permissions.
551*7c478bd9Sstevel@tonic-gate **		db_params --
552*7c478bd9Sstevel@tonic-gate **			An SMDB_DBPARAMS struct including params. These
553*7c478bd9Sstevel@tonic-gate **			are processed according to the type of the
554*7c478bd9Sstevel@tonic-gate **			database. Currently supported params (only for
555*7c478bd9Sstevel@tonic-gate **			HASH type) are:
556*7c478bd9Sstevel@tonic-gate **			   num_elements
557*7c478bd9Sstevel@tonic-gate **			   cache_size
558*7c478bd9Sstevel@tonic-gate **
559*7c478bd9Sstevel@tonic-gate **	Returns:
560*7c478bd9Sstevel@tonic-gate **		SMDBE_OK -- Success, other errno:
561*7c478bd9Sstevel@tonic-gate **		SMDBE_MALLOC -- Cannot allocate memory.
562*7c478bd9Sstevel@tonic-gate **		SMDBE_BAD_OPEN -- db_open didn't return an error, but
563*7c478bd9Sstevel@tonic-gate **				 somehow the DB pointer is NULL.
564*7c478bd9Sstevel@tonic-gate **		Anything else: translated error from db2
565*7c478bd9Sstevel@tonic-gate */
566*7c478bd9Sstevel@tonic-gate 
567*7c478bd9Sstevel@tonic-gate int
568*7c478bd9Sstevel@tonic-gate smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info, db_params)
569*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE **database;
570*7c478bd9Sstevel@tonic-gate 	char *db_name;
571*7c478bd9Sstevel@tonic-gate 	int mode;
572*7c478bd9Sstevel@tonic-gate 	int mode_mask;
573*7c478bd9Sstevel@tonic-gate 	long sff;
574*7c478bd9Sstevel@tonic-gate 	SMDB_DBTYPE type;
575*7c478bd9Sstevel@tonic-gate 	SMDB_USER_INFO *user_info;
576*7c478bd9Sstevel@tonic-gate 	SMDB_DBPARAMS *db_params;
577*7c478bd9Sstevel@tonic-gate {
578*7c478bd9Sstevel@tonic-gate 	bool lockcreated = false;
579*7c478bd9Sstevel@tonic-gate 	int result;
580*7c478bd9Sstevel@tonic-gate 	int db_flags;
581*7c478bd9Sstevel@tonic-gate 	int lock_fd;
582*7c478bd9Sstevel@tonic-gate 	int db_fd;
583*7c478bd9Sstevel@tonic-gate 	int major_v, minor_v, patch_v;
584*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *smdb_db;
585*7c478bd9Sstevel@tonic-gate 	SMDB_DB2_DATABASE *db2;
586*7c478bd9Sstevel@tonic-gate 	DB *db;
587*7c478bd9Sstevel@tonic-gate 	DBTYPE db_type;
588*7c478bd9Sstevel@tonic-gate 	struct stat stat_info;
589*7c478bd9Sstevel@tonic-gate 	char db_file_name[MAXPATHLEN];
590*7c478bd9Sstevel@tonic-gate 
591*7c478bd9Sstevel@tonic-gate 	(void) db_version(&major_v, &minor_v, &patch_v);
592*7c478bd9Sstevel@tonic-gate 	if (major_v != DB_VERSION_MAJOR || minor_v != DB_VERSION_MINOR)
593*7c478bd9Sstevel@tonic-gate 		return SMDBE_VERSION_MISMATCH;
594*7c478bd9Sstevel@tonic-gate 
595*7c478bd9Sstevel@tonic-gate 	*database = NULL;
596*7c478bd9Sstevel@tonic-gate 
597*7c478bd9Sstevel@tonic-gate 	result = smdb_add_extension(db_file_name, sizeof db_file_name,
598*7c478bd9Sstevel@tonic-gate 				    db_name, SMDB2_FILE_EXTENSION);
599*7c478bd9Sstevel@tonic-gate 	if (result != SMDBE_OK)
600*7c478bd9Sstevel@tonic-gate 		return result;
601*7c478bd9Sstevel@tonic-gate 
602*7c478bd9Sstevel@tonic-gate 	result = smdb_setup_file(db_name, SMDB2_FILE_EXTENSION,
603*7c478bd9Sstevel@tonic-gate 				 mode_mask, sff, user_info, &stat_info);
604*7c478bd9Sstevel@tonic-gate 	if (result != SMDBE_OK)
605*7c478bd9Sstevel@tonic-gate 		return result;
606*7c478bd9Sstevel@tonic-gate 
607*7c478bd9Sstevel@tonic-gate 	lock_fd = -1;
608*7c478bd9Sstevel@tonic-gate 
609*7c478bd9Sstevel@tonic-gate 	if (stat_info.st_mode == ST_MODE_NOFILE &&
610*7c478bd9Sstevel@tonic-gate 	    bitset(mode, O_CREAT))
611*7c478bd9Sstevel@tonic-gate 		lockcreated = true;
612*7c478bd9Sstevel@tonic-gate 
613*7c478bd9Sstevel@tonic-gate 	result = smdb_lock_file(&lock_fd, db_name, mode, sff,
614*7c478bd9Sstevel@tonic-gate 				SMDB2_FILE_EXTENSION);
615*7c478bd9Sstevel@tonic-gate 	if (result != SMDBE_OK)
616*7c478bd9Sstevel@tonic-gate 		return result;
617*7c478bd9Sstevel@tonic-gate 
618*7c478bd9Sstevel@tonic-gate 	if (lockcreated)
619*7c478bd9Sstevel@tonic-gate 	{
620*7c478bd9Sstevel@tonic-gate 		mode |= O_TRUNC;
621*7c478bd9Sstevel@tonic-gate 		mode &= ~(O_CREAT|O_EXCL);
622*7c478bd9Sstevel@tonic-gate 	}
623*7c478bd9Sstevel@tonic-gate 
624*7c478bd9Sstevel@tonic-gate 	smdb_db = smdb_malloc_database();
625*7c478bd9Sstevel@tonic-gate 	if (smdb_db == NULL)
626*7c478bd9Sstevel@tonic-gate 		return SMDBE_MALLOC;
627*7c478bd9Sstevel@tonic-gate 
628*7c478bd9Sstevel@tonic-gate 	db2 = smdb2_malloc_database();
629*7c478bd9Sstevel@tonic-gate 	if (db2 == NULL)
630*7c478bd9Sstevel@tonic-gate 		return SMDBE_MALLOC;
631*7c478bd9Sstevel@tonic-gate 
632*7c478bd9Sstevel@tonic-gate 	db2->smdb2_lock_fd = lock_fd;
633*7c478bd9Sstevel@tonic-gate 
634*7c478bd9Sstevel@tonic-gate 	db_type = smdb_type_to_db2_type(type);
635*7c478bd9Sstevel@tonic-gate 
636*7c478bd9Sstevel@tonic-gate 	db = NULL;
637*7c478bd9Sstevel@tonic-gate 
638*7c478bd9Sstevel@tonic-gate 	db_flags = 0;
639*7c478bd9Sstevel@tonic-gate 	if (bitset(O_CREAT, mode))
640*7c478bd9Sstevel@tonic-gate 		db_flags |= DB_CREATE;
641*7c478bd9Sstevel@tonic-gate 	if (bitset(O_TRUNC, mode))
642*7c478bd9Sstevel@tonic-gate 		db_flags |= DB_TRUNCATE;
643*7c478bd9Sstevel@tonic-gate 	if (mode == O_RDONLY)
644*7c478bd9Sstevel@tonic-gate 		db_flags |= DB_RDONLY;
645*7c478bd9Sstevel@tonic-gate 	SM_DB_FLAG_ADD(db_flags);
646*7c478bd9Sstevel@tonic-gate 
647*7c478bd9Sstevel@tonic-gate 	result = smdb_db_open_internal(db_file_name, db_type,
648*7c478bd9Sstevel@tonic-gate 				       db_flags, db_params, &db);
649*7c478bd9Sstevel@tonic-gate 
650*7c478bd9Sstevel@tonic-gate 	if (result == 0 && db != NULL)
651*7c478bd9Sstevel@tonic-gate 	{
652*7c478bd9Sstevel@tonic-gate 		result = db->fd(db, &db_fd);
653*7c478bd9Sstevel@tonic-gate 		if (result == 0)
654*7c478bd9Sstevel@tonic-gate 			result = SMDBE_OK;
655*7c478bd9Sstevel@tonic-gate 	}
656*7c478bd9Sstevel@tonic-gate 	else
657*7c478bd9Sstevel@tonic-gate 	{
658*7c478bd9Sstevel@tonic-gate 		/* Try and narrow down on the problem */
659*7c478bd9Sstevel@tonic-gate 		if (result != 0)
660*7c478bd9Sstevel@tonic-gate 			result = db2_error_to_smdb(result);
661*7c478bd9Sstevel@tonic-gate 		else
662*7c478bd9Sstevel@tonic-gate 			result = SMDBE_BAD_OPEN;
663*7c478bd9Sstevel@tonic-gate 	}
664*7c478bd9Sstevel@tonic-gate 
665*7c478bd9Sstevel@tonic-gate 	if (result == SMDBE_OK)
666*7c478bd9Sstevel@tonic-gate 		result = smdb_filechanged(db_name, SMDB2_FILE_EXTENSION, db_fd,
667*7c478bd9Sstevel@tonic-gate 					  &stat_info);
668*7c478bd9Sstevel@tonic-gate 
669*7c478bd9Sstevel@tonic-gate 	if (result == SMDBE_OK)
670*7c478bd9Sstevel@tonic-gate 	{
671*7c478bd9Sstevel@tonic-gate 		/* Everything is ok. Setup driver */
672*7c478bd9Sstevel@tonic-gate 		db2->smdb2_db = db;
673*7c478bd9Sstevel@tonic-gate 
674*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_close = smdb2_close;
675*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_del = smdb2_del;
676*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_fd = smdb2_fd;
677*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_lockfd = smdb2_lockfd;
678*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_get = smdb2_get;
679*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_put = smdb2_put;
680*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_set_owner = smdb2_set_owner;
681*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_sync = smdb2_sync;
682*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_cursor = smdb2_cursor;
683*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_impl = db2;
684*7c478bd9Sstevel@tonic-gate 
685*7c478bd9Sstevel@tonic-gate 		*database = smdb_db;
686*7c478bd9Sstevel@tonic-gate 
687*7c478bd9Sstevel@tonic-gate 		return SMDBE_OK;
688*7c478bd9Sstevel@tonic-gate 	}
689*7c478bd9Sstevel@tonic-gate 
690*7c478bd9Sstevel@tonic-gate 	if (db != NULL)
691*7c478bd9Sstevel@tonic-gate 		db->close(db, 0);
692*7c478bd9Sstevel@tonic-gate 
693*7c478bd9Sstevel@tonic-gate 	smdb_unlock_file(db2->smdb2_lock_fd);
694*7c478bd9Sstevel@tonic-gate 	free(db2);
695*7c478bd9Sstevel@tonic-gate 	smdb_free_database(smdb_db);
696*7c478bd9Sstevel@tonic-gate 
697*7c478bd9Sstevel@tonic-gate 	return result;
698*7c478bd9Sstevel@tonic-gate }
699*7c478bd9Sstevel@tonic-gate 
700*7c478bd9Sstevel@tonic-gate #endif /* (DB_VERSION_MAJOR >= 2) */
701