xref: /titanic_44/usr/src/cmd/sendmail/libsmdb/smdb1.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate ** Copyright (c) 1999-2002 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: smdb1.c,v 8.59 2004/08/03 20:58:39 ca Exp $")
14*7c478bd9Sstevel@tonic-gate 
15*7c478bd9Sstevel@tonic-gate #include <unistd.h>
16*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
17*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
18*7c478bd9Sstevel@tonic-gate 
19*7c478bd9Sstevel@tonic-gate #include <sendmail/sendmail.h>
20*7c478bd9Sstevel@tonic-gate #include <libsmdb/smdb.h>
21*7c478bd9Sstevel@tonic-gate 
22*7c478bd9Sstevel@tonic-gate #if (DB_VERSION_MAJOR == 1)
23*7c478bd9Sstevel@tonic-gate 
24*7c478bd9Sstevel@tonic-gate # define SMDB1_FILE_EXTENSION "db"
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate struct smdb_db1_struct
27*7c478bd9Sstevel@tonic-gate {
28*7c478bd9Sstevel@tonic-gate 	DB	*smdb1_db;
29*7c478bd9Sstevel@tonic-gate 	int	smdb1_lock_fd;
30*7c478bd9Sstevel@tonic-gate 	bool	smdb1_cursor_in_use;
31*7c478bd9Sstevel@tonic-gate };
32*7c478bd9Sstevel@tonic-gate typedef struct smdb_db1_struct SMDB_DB1_DATABASE;
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate struct smdb_db1_cursor
35*7c478bd9Sstevel@tonic-gate {
36*7c478bd9Sstevel@tonic-gate 	SMDB_DB1_DATABASE	*db;
37*7c478bd9Sstevel@tonic-gate };
38*7c478bd9Sstevel@tonic-gate typedef struct smdb_db1_cursor SMDB_DB1_CURSOR;
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate static DBTYPE		smdb_type_to_db1_type __P((SMDB_DBTYPE));
41*7c478bd9Sstevel@tonic-gate static unsigned int	smdb_put_flags_to_db1_flags __P((SMDB_FLAG));
42*7c478bd9Sstevel@tonic-gate static int		smdb_cursor_get_flags_to_smdb1 __P((SMDB_FLAG));
43*7c478bd9Sstevel@tonic-gate static SMDB_DB1_DATABASE *smdb1_malloc_database __P((void));
44*7c478bd9Sstevel@tonic-gate static int		smdb1_close __P((SMDB_DATABASE *));
45*7c478bd9Sstevel@tonic-gate static int		smdb1_del __P((SMDB_DATABASE *, SMDB_DBENT *, unsigned int));
46*7c478bd9Sstevel@tonic-gate static int		smdb1_fd __P((SMDB_DATABASE *, int *));
47*7c478bd9Sstevel@tonic-gate static int		smdb1_lockfd __P((SMDB_DATABASE *));
48*7c478bd9Sstevel@tonic-gate static int		smdb1_get __P((SMDB_DATABASE *, SMDB_DBENT *, SMDB_DBENT *, unsigned int));
49*7c478bd9Sstevel@tonic-gate static int		smdb1_put __P((SMDB_DATABASE *, SMDB_DBENT *, SMDB_DBENT *, unsigned int));
50*7c478bd9Sstevel@tonic-gate static int		smdb1_set_owner __P((SMDB_DATABASE *, uid_t, gid_t));
51*7c478bd9Sstevel@tonic-gate static int		smdb1_sync __P((SMDB_DATABASE *, unsigned int));
52*7c478bd9Sstevel@tonic-gate static int		smdb1_cursor_close __P((SMDB_CURSOR *));
53*7c478bd9Sstevel@tonic-gate static int		smdb1_cursor_del __P((SMDB_CURSOR *, unsigned int));
54*7c478bd9Sstevel@tonic-gate static int		smdb1_cursor_get __P((SMDB_CURSOR *, SMDB_DBENT *, SMDB_DBENT *, SMDB_FLAG));
55*7c478bd9Sstevel@tonic-gate static int		smdb1_cursor_put __P((SMDB_CURSOR *, SMDB_DBENT *, SMDB_DBENT *, SMDB_FLAG));
56*7c478bd9Sstevel@tonic-gate static int		smdb1_cursor __P((SMDB_DATABASE *, SMDB_CURSOR **, unsigned int));
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate /*
59*7c478bd9Sstevel@tonic-gate **  SMDB_TYPE_TO_DB1_TYPE -- Translates smdb database type to db1 type.
60*7c478bd9Sstevel@tonic-gate **
61*7c478bd9Sstevel@tonic-gate **	Parameters:
62*7c478bd9Sstevel@tonic-gate **		type -- The type to translate.
63*7c478bd9Sstevel@tonic-gate **
64*7c478bd9Sstevel@tonic-gate **	Returns:
65*7c478bd9Sstevel@tonic-gate **		The DB1 type that corresponsds to the passed in SMDB type.
66*7c478bd9Sstevel@tonic-gate **		Returns -1 if there is no equivalent type.
67*7c478bd9Sstevel@tonic-gate **
68*7c478bd9Sstevel@tonic-gate */
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate static DBTYPE
71*7c478bd9Sstevel@tonic-gate smdb_type_to_db1_type(type)
72*7c478bd9Sstevel@tonic-gate 	SMDB_DBTYPE type;
73*7c478bd9Sstevel@tonic-gate {
74*7c478bd9Sstevel@tonic-gate 	if (type == SMDB_TYPE_DEFAULT)
75*7c478bd9Sstevel@tonic-gate 		return DB_HASH;
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate 	if (strncmp(type, SMDB_TYPE_HASH, SMDB_TYPE_HASH_LEN) == 0)
78*7c478bd9Sstevel@tonic-gate 		return DB_HASH;
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate 	if (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0)
81*7c478bd9Sstevel@tonic-gate 		return DB_BTREE;
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate 	/* Should never get here thanks to test in smdb_db_open() */
84*7c478bd9Sstevel@tonic-gate 	return DB_HASH;
85*7c478bd9Sstevel@tonic-gate }
86*7c478bd9Sstevel@tonic-gate /*
87*7c478bd9Sstevel@tonic-gate **  SMDB_PUT_FLAGS_TO_DB1_FLAGS -- Translates smdb put flags to db1 put flags.
88*7c478bd9Sstevel@tonic-gate **
89*7c478bd9Sstevel@tonic-gate **	Parameters:
90*7c478bd9Sstevel@tonic-gate **		flags -- The flags to translate.
91*7c478bd9Sstevel@tonic-gate **
92*7c478bd9Sstevel@tonic-gate **	Returns:
93*7c478bd9Sstevel@tonic-gate **		The db1 flags that are equivalent to the smdb flags.
94*7c478bd9Sstevel@tonic-gate **
95*7c478bd9Sstevel@tonic-gate **	Notes:
96*7c478bd9Sstevel@tonic-gate **		Any invalid flags are ignored.
97*7c478bd9Sstevel@tonic-gate **
98*7c478bd9Sstevel@tonic-gate */
99*7c478bd9Sstevel@tonic-gate 
100*7c478bd9Sstevel@tonic-gate static unsigned int
101*7c478bd9Sstevel@tonic-gate smdb_put_flags_to_db1_flags(flags)
102*7c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
103*7c478bd9Sstevel@tonic-gate {
104*7c478bd9Sstevel@tonic-gate 	int return_flags;
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate 	return_flags = 0;
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate 	if (bitset(SMDBF_NO_OVERWRITE, flags))
109*7c478bd9Sstevel@tonic-gate 		return_flags |= R_NOOVERWRITE;
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate 	return return_flags;
112*7c478bd9Sstevel@tonic-gate }
113*7c478bd9Sstevel@tonic-gate /*
114*7c478bd9Sstevel@tonic-gate **  SMDB_CURSOR_GET_FLAGS_TO_SMDB1
115*7c478bd9Sstevel@tonic-gate **
116*7c478bd9Sstevel@tonic-gate **	Parameters:
117*7c478bd9Sstevel@tonic-gate **		flags -- The flags to translate.
118*7c478bd9Sstevel@tonic-gate **
119*7c478bd9Sstevel@tonic-gate **	Returns:
120*7c478bd9Sstevel@tonic-gate **		The db1 flags that are equivalent to the smdb flags.
121*7c478bd9Sstevel@tonic-gate **
122*7c478bd9Sstevel@tonic-gate **	Notes:
123*7c478bd9Sstevel@tonic-gate **		Returns -1 if we don't support the flag.
124*7c478bd9Sstevel@tonic-gate **
125*7c478bd9Sstevel@tonic-gate */
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate static int
128*7c478bd9Sstevel@tonic-gate smdb_cursor_get_flags_to_smdb1(flags)
129*7c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
130*7c478bd9Sstevel@tonic-gate {
131*7c478bd9Sstevel@tonic-gate 	switch(flags)
132*7c478bd9Sstevel@tonic-gate 	{
133*7c478bd9Sstevel@tonic-gate 		case SMDB_CURSOR_GET_FIRST:
134*7c478bd9Sstevel@tonic-gate 			return R_FIRST;
135*7c478bd9Sstevel@tonic-gate 
136*7c478bd9Sstevel@tonic-gate 		case SMDB_CURSOR_GET_LAST:
137*7c478bd9Sstevel@tonic-gate 			return R_LAST;
138*7c478bd9Sstevel@tonic-gate 
139*7c478bd9Sstevel@tonic-gate 		case SMDB_CURSOR_GET_NEXT:
140*7c478bd9Sstevel@tonic-gate 			return R_NEXT;
141*7c478bd9Sstevel@tonic-gate 
142*7c478bd9Sstevel@tonic-gate 		case SMDB_CURSOR_GET_RANGE:
143*7c478bd9Sstevel@tonic-gate 			return R_CURSOR;
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate 		default:
146*7c478bd9Sstevel@tonic-gate 			return -1;
147*7c478bd9Sstevel@tonic-gate 	}
148*7c478bd9Sstevel@tonic-gate }
149*7c478bd9Sstevel@tonic-gate 
150*7c478bd9Sstevel@tonic-gate /*
151*7c478bd9Sstevel@tonic-gate **  The rest of these functions correspond to the interface laid out in smdb.h.
152*7c478bd9Sstevel@tonic-gate */
153*7c478bd9Sstevel@tonic-gate 
154*7c478bd9Sstevel@tonic-gate static SMDB_DB1_DATABASE *
155*7c478bd9Sstevel@tonic-gate smdb1_malloc_database()
156*7c478bd9Sstevel@tonic-gate {
157*7c478bd9Sstevel@tonic-gate 	SMDB_DB1_DATABASE *db1;
158*7c478bd9Sstevel@tonic-gate 
159*7c478bd9Sstevel@tonic-gate 	db1 = (SMDB_DB1_DATABASE *) malloc(sizeof(SMDB_DB1_DATABASE));
160*7c478bd9Sstevel@tonic-gate 
161*7c478bd9Sstevel@tonic-gate 	if (db1 != NULL)
162*7c478bd9Sstevel@tonic-gate 	{
163*7c478bd9Sstevel@tonic-gate 		db1->smdb1_lock_fd = -1;
164*7c478bd9Sstevel@tonic-gate 		db1->smdb1_cursor_in_use = false;
165*7c478bd9Sstevel@tonic-gate 	}
166*7c478bd9Sstevel@tonic-gate 
167*7c478bd9Sstevel@tonic-gate 	return db1;
168*7c478bd9Sstevel@tonic-gate }
169*7c478bd9Sstevel@tonic-gate 
170*7c478bd9Sstevel@tonic-gate static int
171*7c478bd9Sstevel@tonic-gate smdb1_close(database)
172*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
173*7c478bd9Sstevel@tonic-gate {
174*7c478bd9Sstevel@tonic-gate 	int result;
175*7c478bd9Sstevel@tonic-gate 	SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl;
176*7c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate 	result = db->close(db);
179*7c478bd9Sstevel@tonic-gate 	if (db1->smdb1_lock_fd != -1)
180*7c478bd9Sstevel@tonic-gate 		(void) close(db1->smdb1_lock_fd);
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate 	free(db1);
183*7c478bd9Sstevel@tonic-gate 	database->smdb_impl = NULL;
184*7c478bd9Sstevel@tonic-gate 
185*7c478bd9Sstevel@tonic-gate 	return result;
186*7c478bd9Sstevel@tonic-gate }
187*7c478bd9Sstevel@tonic-gate 
188*7c478bd9Sstevel@tonic-gate static int
189*7c478bd9Sstevel@tonic-gate smdb1_del(database, key, flags)
190*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
191*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
192*7c478bd9Sstevel@tonic-gate 	unsigned int flags;
193*7c478bd9Sstevel@tonic-gate {
194*7c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
195*7c478bd9Sstevel@tonic-gate 	DBT dbkey;
196*7c478bd9Sstevel@tonic-gate 
197*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
198*7c478bd9Sstevel@tonic-gate 	dbkey.data = key->data;
199*7c478bd9Sstevel@tonic-gate 	dbkey.size = key->size;
200*7c478bd9Sstevel@tonic-gate 	return db->del(db, &dbkey, flags);
201*7c478bd9Sstevel@tonic-gate }
202*7c478bd9Sstevel@tonic-gate 
203*7c478bd9Sstevel@tonic-gate static int
204*7c478bd9Sstevel@tonic-gate smdb1_fd(database, fd)
205*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
206*7c478bd9Sstevel@tonic-gate 	int *fd;
207*7c478bd9Sstevel@tonic-gate {
208*7c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
209*7c478bd9Sstevel@tonic-gate 
210*7c478bd9Sstevel@tonic-gate 	*fd = db->fd(db);
211*7c478bd9Sstevel@tonic-gate 	if (*fd == -1)
212*7c478bd9Sstevel@tonic-gate 		return errno;
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
215*7c478bd9Sstevel@tonic-gate }
216*7c478bd9Sstevel@tonic-gate 
217*7c478bd9Sstevel@tonic-gate static int
218*7c478bd9Sstevel@tonic-gate smdb1_lockfd(database)
219*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
220*7c478bd9Sstevel@tonic-gate {
221*7c478bd9Sstevel@tonic-gate 	SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl;
222*7c478bd9Sstevel@tonic-gate 
223*7c478bd9Sstevel@tonic-gate 	return db1->smdb1_lock_fd;
224*7c478bd9Sstevel@tonic-gate }
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate 
227*7c478bd9Sstevel@tonic-gate static int
228*7c478bd9Sstevel@tonic-gate smdb1_get(database, key, data, flags)
229*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
230*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
231*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *data;
232*7c478bd9Sstevel@tonic-gate 	unsigned int flags;
233*7c478bd9Sstevel@tonic-gate {
234*7c478bd9Sstevel@tonic-gate 	int result;
235*7c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
236*7c478bd9Sstevel@tonic-gate 	DBT dbkey, dbdata;
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
239*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
240*7c478bd9Sstevel@tonic-gate 	dbkey.data = key->data;
241*7c478bd9Sstevel@tonic-gate 	dbkey.size = key->size;
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate 	result = db->get(db, &dbkey, &dbdata, flags);
244*7c478bd9Sstevel@tonic-gate 	if (result != 0)
245*7c478bd9Sstevel@tonic-gate 	{
246*7c478bd9Sstevel@tonic-gate 		if (result == 1)
247*7c478bd9Sstevel@tonic-gate 			return SMDBE_NOT_FOUND;
248*7c478bd9Sstevel@tonic-gate 		return errno;
249*7c478bd9Sstevel@tonic-gate 	}
250*7c478bd9Sstevel@tonic-gate 	data->data = dbdata.data;
251*7c478bd9Sstevel@tonic-gate 	data->size = dbdata.size;
252*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
253*7c478bd9Sstevel@tonic-gate }
254*7c478bd9Sstevel@tonic-gate 
255*7c478bd9Sstevel@tonic-gate static int
256*7c478bd9Sstevel@tonic-gate smdb1_put(database, key, data, flags)
257*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
258*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
259*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *data;
260*7c478bd9Sstevel@tonic-gate 	unsigned int flags;
261*7c478bd9Sstevel@tonic-gate {
262*7c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
263*7c478bd9Sstevel@tonic-gate 	DBT dbkey, dbdata;
264*7c478bd9Sstevel@tonic-gate 
265*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
266*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
267*7c478bd9Sstevel@tonic-gate 	dbkey.data = key->data;
268*7c478bd9Sstevel@tonic-gate 	dbkey.size = key->size;
269*7c478bd9Sstevel@tonic-gate 	dbdata.data = data->data;
270*7c478bd9Sstevel@tonic-gate 	dbdata.size = data->size;
271*7c478bd9Sstevel@tonic-gate 
272*7c478bd9Sstevel@tonic-gate 	return db->put(db, &dbkey, &dbdata,
273*7c478bd9Sstevel@tonic-gate 		       smdb_put_flags_to_db1_flags(flags));
274*7c478bd9Sstevel@tonic-gate }
275*7c478bd9Sstevel@tonic-gate 
276*7c478bd9Sstevel@tonic-gate static int
277*7c478bd9Sstevel@tonic-gate smdb1_set_owner(database, uid, gid)
278*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
279*7c478bd9Sstevel@tonic-gate 	uid_t uid;
280*7c478bd9Sstevel@tonic-gate 	gid_t gid;
281*7c478bd9Sstevel@tonic-gate {
282*7c478bd9Sstevel@tonic-gate # if HASFCHOWN
283*7c478bd9Sstevel@tonic-gate 	int fd;
284*7c478bd9Sstevel@tonic-gate 	int result;
285*7c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
286*7c478bd9Sstevel@tonic-gate 
287*7c478bd9Sstevel@tonic-gate 	fd = db->fd(db);
288*7c478bd9Sstevel@tonic-gate 	if (fd == -1)
289*7c478bd9Sstevel@tonic-gate 		return errno;
290*7c478bd9Sstevel@tonic-gate 
291*7c478bd9Sstevel@tonic-gate 	result = fchown(fd, uid, gid);
292*7c478bd9Sstevel@tonic-gate 	if (result < 0)
293*7c478bd9Sstevel@tonic-gate 		return errno;
294*7c478bd9Sstevel@tonic-gate # endif /* HASFCHOWN */
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
297*7c478bd9Sstevel@tonic-gate }
298*7c478bd9Sstevel@tonic-gate 
299*7c478bd9Sstevel@tonic-gate static int
300*7c478bd9Sstevel@tonic-gate smdb1_sync(database, flags)
301*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
302*7c478bd9Sstevel@tonic-gate 	unsigned int flags;
303*7c478bd9Sstevel@tonic-gate {
304*7c478bd9Sstevel@tonic-gate 	DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
305*7c478bd9Sstevel@tonic-gate 
306*7c478bd9Sstevel@tonic-gate 	return db->sync(db, flags);
307*7c478bd9Sstevel@tonic-gate }
308*7c478bd9Sstevel@tonic-gate 
309*7c478bd9Sstevel@tonic-gate static int
310*7c478bd9Sstevel@tonic-gate smdb1_cursor_close(cursor)
311*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
312*7c478bd9Sstevel@tonic-gate {
313*7c478bd9Sstevel@tonic-gate 	SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
314*7c478bd9Sstevel@tonic-gate 	SMDB_DB1_DATABASE *db1 = db1_cursor->db;
315*7c478bd9Sstevel@tonic-gate 
316*7c478bd9Sstevel@tonic-gate 	if (!db1->smdb1_cursor_in_use)
317*7c478bd9Sstevel@tonic-gate 		return SMDBE_NOT_A_VALID_CURSOR;
318*7c478bd9Sstevel@tonic-gate 
319*7c478bd9Sstevel@tonic-gate 	db1->smdb1_cursor_in_use = false;
320*7c478bd9Sstevel@tonic-gate 	free(cursor);
321*7c478bd9Sstevel@tonic-gate 
322*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
323*7c478bd9Sstevel@tonic-gate }
324*7c478bd9Sstevel@tonic-gate 
325*7c478bd9Sstevel@tonic-gate static int
326*7c478bd9Sstevel@tonic-gate smdb1_cursor_del(cursor, flags)
327*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
328*7c478bd9Sstevel@tonic-gate 	unsigned int flags;
329*7c478bd9Sstevel@tonic-gate {
330*7c478bd9Sstevel@tonic-gate 	SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
331*7c478bd9Sstevel@tonic-gate 	SMDB_DB1_DATABASE *db1 = db1_cursor->db;
332*7c478bd9Sstevel@tonic-gate 	DB *db = db1->smdb1_db;
333*7c478bd9Sstevel@tonic-gate 
334*7c478bd9Sstevel@tonic-gate 	return db->del(db, NULL, R_CURSOR);
335*7c478bd9Sstevel@tonic-gate }
336*7c478bd9Sstevel@tonic-gate 
337*7c478bd9Sstevel@tonic-gate static int
338*7c478bd9Sstevel@tonic-gate smdb1_cursor_get(cursor, key, value, flags)
339*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
340*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
341*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *value;
342*7c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
343*7c478bd9Sstevel@tonic-gate {
344*7c478bd9Sstevel@tonic-gate 	int db1_flags;
345*7c478bd9Sstevel@tonic-gate 	int result;
346*7c478bd9Sstevel@tonic-gate 	SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
347*7c478bd9Sstevel@tonic-gate 	SMDB_DB1_DATABASE *db1 = db1_cursor->db;
348*7c478bd9Sstevel@tonic-gate 	DB *db = db1->smdb1_db;
349*7c478bd9Sstevel@tonic-gate 	DBT dbkey, dbdata;
350*7c478bd9Sstevel@tonic-gate 
351*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
352*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
353*7c478bd9Sstevel@tonic-gate 
354*7c478bd9Sstevel@tonic-gate 	db1_flags = smdb_cursor_get_flags_to_smdb1(flags);
355*7c478bd9Sstevel@tonic-gate 	result = db->seq(db, &dbkey, &dbdata, db1_flags);
356*7c478bd9Sstevel@tonic-gate 	if (result == -1)
357*7c478bd9Sstevel@tonic-gate 		return errno;
358*7c478bd9Sstevel@tonic-gate 	if (result == 1)
359*7c478bd9Sstevel@tonic-gate 		return SMDBE_LAST_ENTRY;
360*7c478bd9Sstevel@tonic-gate 	value->data = dbdata.data;
361*7c478bd9Sstevel@tonic-gate 	value->size = dbdata.size;
362*7c478bd9Sstevel@tonic-gate 	key->data = dbkey.data;
363*7c478bd9Sstevel@tonic-gate 	key->size = dbkey.size;
364*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
365*7c478bd9Sstevel@tonic-gate }
366*7c478bd9Sstevel@tonic-gate 
367*7c478bd9Sstevel@tonic-gate static int
368*7c478bd9Sstevel@tonic-gate smdb1_cursor_put(cursor, key, value, flags)
369*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
370*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
371*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *value;
372*7c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
373*7c478bd9Sstevel@tonic-gate {
374*7c478bd9Sstevel@tonic-gate 	SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
375*7c478bd9Sstevel@tonic-gate 	SMDB_DB1_DATABASE *db1 = db1_cursor->db;
376*7c478bd9Sstevel@tonic-gate 	DB *db = db1->smdb1_db;
377*7c478bd9Sstevel@tonic-gate 	DBT dbkey, dbdata;
378*7c478bd9Sstevel@tonic-gate 
379*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
380*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
381*7c478bd9Sstevel@tonic-gate 	dbkey.data = key->data;
382*7c478bd9Sstevel@tonic-gate 	dbkey.size = key->size;
383*7c478bd9Sstevel@tonic-gate 	dbdata.data = value->data;
384*7c478bd9Sstevel@tonic-gate 	dbdata.size = value->size;
385*7c478bd9Sstevel@tonic-gate 
386*7c478bd9Sstevel@tonic-gate 	return db->put(db, &dbkey, &dbdata, R_CURSOR);
387*7c478bd9Sstevel@tonic-gate }
388*7c478bd9Sstevel@tonic-gate 
389*7c478bd9Sstevel@tonic-gate static int
390*7c478bd9Sstevel@tonic-gate smdb1_cursor(database, cursor, flags)
391*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
392*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR **cursor;
393*7c478bd9Sstevel@tonic-gate 	unsigned int flags;
394*7c478bd9Sstevel@tonic-gate {
395*7c478bd9Sstevel@tonic-gate 	SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl;
396*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cur;
397*7c478bd9Sstevel@tonic-gate 	SMDB_DB1_CURSOR *db1_cursor;
398*7c478bd9Sstevel@tonic-gate 
399*7c478bd9Sstevel@tonic-gate 	if (db1->smdb1_cursor_in_use)
400*7c478bd9Sstevel@tonic-gate 		return SMDBE_ONLY_SUPPORTS_ONE_CURSOR;
401*7c478bd9Sstevel@tonic-gate 
402*7c478bd9Sstevel@tonic-gate 	db1->smdb1_cursor_in_use = true;
403*7c478bd9Sstevel@tonic-gate 	db1_cursor = (SMDB_DB1_CURSOR *) malloc(sizeof(SMDB_DB1_CURSOR));
404*7c478bd9Sstevel@tonic-gate 	db1_cursor->db = db1;
405*7c478bd9Sstevel@tonic-gate 
406*7c478bd9Sstevel@tonic-gate 	cur = (SMDB_CURSOR *) malloc(sizeof(SMDB_CURSOR));
407*7c478bd9Sstevel@tonic-gate 
408*7c478bd9Sstevel@tonic-gate 	if (cur == NULL)
409*7c478bd9Sstevel@tonic-gate 		return SMDBE_MALLOC;
410*7c478bd9Sstevel@tonic-gate 
411*7c478bd9Sstevel@tonic-gate 	cur->smdbc_impl = db1_cursor;
412*7c478bd9Sstevel@tonic-gate 	cur->smdbc_close = smdb1_cursor_close;
413*7c478bd9Sstevel@tonic-gate 	cur->smdbc_del = smdb1_cursor_del;
414*7c478bd9Sstevel@tonic-gate 	cur->smdbc_get = smdb1_cursor_get;
415*7c478bd9Sstevel@tonic-gate 	cur->smdbc_put = smdb1_cursor_put;
416*7c478bd9Sstevel@tonic-gate 	*cursor = cur;
417*7c478bd9Sstevel@tonic-gate 
418*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
419*7c478bd9Sstevel@tonic-gate }
420*7c478bd9Sstevel@tonic-gate /*
421*7c478bd9Sstevel@tonic-gate **  SMDB_DB_OPEN -- Opens a db1 database.
422*7c478bd9Sstevel@tonic-gate **
423*7c478bd9Sstevel@tonic-gate **	Parameters:
424*7c478bd9Sstevel@tonic-gate **		database -- An unallocated database pointer to a pointer.
425*7c478bd9Sstevel@tonic-gate **		db_name -- The name of the database without extension.
426*7c478bd9Sstevel@tonic-gate **		mode -- File permisions on the database if created.
427*7c478bd9Sstevel@tonic-gate **		mode_mask -- Mode bits that must match on an existing database.
428*7c478bd9Sstevel@tonic-gate **		sff -- Flags for safefile.
429*7c478bd9Sstevel@tonic-gate **		type -- The type of database to open
430*7c478bd9Sstevel@tonic-gate **			See smdb_type_to_db1_type for valid types.
431*7c478bd9Sstevel@tonic-gate **		user_info -- Information on the user to use for file
432*7c478bd9Sstevel@tonic-gate **			    permissions.
433*7c478bd9Sstevel@tonic-gate **		db_params --
434*7c478bd9Sstevel@tonic-gate **			An SMDB_DBPARAMS struct including params. These
435*7c478bd9Sstevel@tonic-gate **			are processed according to the type of the
436*7c478bd9Sstevel@tonic-gate **			database. Currently supported params (only for
437*7c478bd9Sstevel@tonic-gate **			HASH type) are:
438*7c478bd9Sstevel@tonic-gate **			   num_elements
439*7c478bd9Sstevel@tonic-gate **			   cache_size
440*7c478bd9Sstevel@tonic-gate **
441*7c478bd9Sstevel@tonic-gate **	Returns:
442*7c478bd9Sstevel@tonic-gate **		SMDBE_OK -- Success, otherwise errno.
443*7c478bd9Sstevel@tonic-gate */
444*7c478bd9Sstevel@tonic-gate 
445*7c478bd9Sstevel@tonic-gate int
446*7c478bd9Sstevel@tonic-gate smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info,
447*7c478bd9Sstevel@tonic-gate 	     db_params)
448*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE **database;
449*7c478bd9Sstevel@tonic-gate 	char *db_name;
450*7c478bd9Sstevel@tonic-gate 	int mode;
451*7c478bd9Sstevel@tonic-gate 	int mode_mask;
452*7c478bd9Sstevel@tonic-gate 	long sff;
453*7c478bd9Sstevel@tonic-gate 	SMDB_DBTYPE type;
454*7c478bd9Sstevel@tonic-gate 	SMDB_USER_INFO *user_info;
455*7c478bd9Sstevel@tonic-gate 	SMDB_DBPARAMS *db_params;
456*7c478bd9Sstevel@tonic-gate {
457*7c478bd9Sstevel@tonic-gate 	bool lockcreated = false;
458*7c478bd9Sstevel@tonic-gate 	int db_fd;
459*7c478bd9Sstevel@tonic-gate 	int lock_fd;
460*7c478bd9Sstevel@tonic-gate 	int result;
461*7c478bd9Sstevel@tonic-gate 	void *params;
462*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *smdb_db;
463*7c478bd9Sstevel@tonic-gate 	SMDB_DB1_DATABASE *db1;
464*7c478bd9Sstevel@tonic-gate 	DB *db;
465*7c478bd9Sstevel@tonic-gate 	HASHINFO hash_info;
466*7c478bd9Sstevel@tonic-gate 	BTREEINFO btree_info;
467*7c478bd9Sstevel@tonic-gate 	DBTYPE db_type;
468*7c478bd9Sstevel@tonic-gate 	struct stat stat_info;
469*7c478bd9Sstevel@tonic-gate 	char db_file_name[MAXPATHLEN];
470*7c478bd9Sstevel@tonic-gate 
471*7c478bd9Sstevel@tonic-gate 	if (type == NULL ||
472*7c478bd9Sstevel@tonic-gate 	    (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) != 0 &&
473*7c478bd9Sstevel@tonic-gate 	     strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) != 0))
474*7c478bd9Sstevel@tonic-gate 		return SMDBE_UNKNOWN_DB_TYPE;
475*7c478bd9Sstevel@tonic-gate 
476*7c478bd9Sstevel@tonic-gate 	result = smdb_add_extension(db_file_name, sizeof db_file_name,
477*7c478bd9Sstevel@tonic-gate 				    db_name, SMDB1_FILE_EXTENSION);
478*7c478bd9Sstevel@tonic-gate 	if (result != SMDBE_OK)
479*7c478bd9Sstevel@tonic-gate 		return result;
480*7c478bd9Sstevel@tonic-gate 
481*7c478bd9Sstevel@tonic-gate 	result = smdb_setup_file(db_name, SMDB1_FILE_EXTENSION, mode_mask,
482*7c478bd9Sstevel@tonic-gate 				 sff, user_info, &stat_info);
483*7c478bd9Sstevel@tonic-gate 	if (result != SMDBE_OK)
484*7c478bd9Sstevel@tonic-gate 		return result;
485*7c478bd9Sstevel@tonic-gate 
486*7c478bd9Sstevel@tonic-gate 	if (stat_info.st_mode == ST_MODE_NOFILE &&
487*7c478bd9Sstevel@tonic-gate 	    bitset(mode, O_CREAT))
488*7c478bd9Sstevel@tonic-gate 		lockcreated = true;
489*7c478bd9Sstevel@tonic-gate 
490*7c478bd9Sstevel@tonic-gate 	lock_fd = -1;
491*7c478bd9Sstevel@tonic-gate 	result = smdb_lock_file(&lock_fd, db_name, mode, sff,
492*7c478bd9Sstevel@tonic-gate 				SMDB1_FILE_EXTENSION);
493*7c478bd9Sstevel@tonic-gate 	if (result != SMDBE_OK)
494*7c478bd9Sstevel@tonic-gate 		return result;
495*7c478bd9Sstevel@tonic-gate 
496*7c478bd9Sstevel@tonic-gate 	if (lockcreated)
497*7c478bd9Sstevel@tonic-gate 	{
498*7c478bd9Sstevel@tonic-gate 		mode |= O_TRUNC;
499*7c478bd9Sstevel@tonic-gate 		mode &= ~(O_CREAT|O_EXCL);
500*7c478bd9Sstevel@tonic-gate 	}
501*7c478bd9Sstevel@tonic-gate 
502*7c478bd9Sstevel@tonic-gate 	*database = NULL;
503*7c478bd9Sstevel@tonic-gate 
504*7c478bd9Sstevel@tonic-gate 	smdb_db = smdb_malloc_database();
505*7c478bd9Sstevel@tonic-gate 	db1 = smdb1_malloc_database();
506*7c478bd9Sstevel@tonic-gate 	if (smdb_db == NULL || db1 == NULL)
507*7c478bd9Sstevel@tonic-gate 		return SMDBE_MALLOC;
508*7c478bd9Sstevel@tonic-gate 	db1->smdb1_lock_fd = lock_fd;
509*7c478bd9Sstevel@tonic-gate 
510*7c478bd9Sstevel@tonic-gate 	params = NULL;
511*7c478bd9Sstevel@tonic-gate 	if (db_params != NULL &&
512*7c478bd9Sstevel@tonic-gate 	    (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) == 0))
513*7c478bd9Sstevel@tonic-gate 	{
514*7c478bd9Sstevel@tonic-gate 		(void) memset(&hash_info, '\0', sizeof hash_info);
515*7c478bd9Sstevel@tonic-gate 		hash_info.nelem = db_params->smdbp_num_elements;
516*7c478bd9Sstevel@tonic-gate 		hash_info.cachesize = db_params->smdbp_cache_size;
517*7c478bd9Sstevel@tonic-gate 		params = &hash_info;
518*7c478bd9Sstevel@tonic-gate 	}
519*7c478bd9Sstevel@tonic-gate 
520*7c478bd9Sstevel@tonic-gate 	if (db_params != NULL &&
521*7c478bd9Sstevel@tonic-gate 	    (strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) == 0))
522*7c478bd9Sstevel@tonic-gate 	{
523*7c478bd9Sstevel@tonic-gate 		(void) memset(&btree_info, '\0', sizeof btree_info);
524*7c478bd9Sstevel@tonic-gate 		btree_info.cachesize = db_params->smdbp_cache_size;
525*7c478bd9Sstevel@tonic-gate 		if (db_params->smdbp_allow_dup)
526*7c478bd9Sstevel@tonic-gate 			btree_info.flags |= R_DUP;
527*7c478bd9Sstevel@tonic-gate 		params = &btree_info;
528*7c478bd9Sstevel@tonic-gate 	}
529*7c478bd9Sstevel@tonic-gate 
530*7c478bd9Sstevel@tonic-gate 	db_type = smdb_type_to_db1_type(type);
531*7c478bd9Sstevel@tonic-gate 	db = dbopen(db_file_name, mode, DBMMODE, db_type, params);
532*7c478bd9Sstevel@tonic-gate 	if (db != NULL)
533*7c478bd9Sstevel@tonic-gate 	{
534*7c478bd9Sstevel@tonic-gate 		db_fd = db->fd(db);
535*7c478bd9Sstevel@tonic-gate 		result = smdb_filechanged(db_name, SMDB1_FILE_EXTENSION, db_fd,
536*7c478bd9Sstevel@tonic-gate 					  &stat_info);
537*7c478bd9Sstevel@tonic-gate 	}
538*7c478bd9Sstevel@tonic-gate 	else
539*7c478bd9Sstevel@tonic-gate 	{
540*7c478bd9Sstevel@tonic-gate 		if (errno == 0)
541*7c478bd9Sstevel@tonic-gate 			result = SMDBE_BAD_OPEN;
542*7c478bd9Sstevel@tonic-gate 		else
543*7c478bd9Sstevel@tonic-gate 			result = errno;
544*7c478bd9Sstevel@tonic-gate 	}
545*7c478bd9Sstevel@tonic-gate 
546*7c478bd9Sstevel@tonic-gate 	if (result == SMDBE_OK)
547*7c478bd9Sstevel@tonic-gate 	{
548*7c478bd9Sstevel@tonic-gate 		/* Everything is ok. Setup driver */
549*7c478bd9Sstevel@tonic-gate 		db1->smdb1_db = db;
550*7c478bd9Sstevel@tonic-gate 
551*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_close = smdb1_close;
552*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_del = smdb1_del;
553*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_fd = smdb1_fd;
554*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_lockfd = smdb1_lockfd;
555*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_get = smdb1_get;
556*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_put = smdb1_put;
557*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_set_owner = smdb1_set_owner;
558*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_sync = smdb1_sync;
559*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_cursor = smdb1_cursor;
560*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_impl = db1;
561*7c478bd9Sstevel@tonic-gate 
562*7c478bd9Sstevel@tonic-gate 		*database = smdb_db;
563*7c478bd9Sstevel@tonic-gate 		return SMDBE_OK;
564*7c478bd9Sstevel@tonic-gate 	}
565*7c478bd9Sstevel@tonic-gate 
566*7c478bd9Sstevel@tonic-gate 	if (db != NULL)
567*7c478bd9Sstevel@tonic-gate 		(void) db->close(db);
568*7c478bd9Sstevel@tonic-gate 
569*7c478bd9Sstevel@tonic-gate 	/* Error opening database */
570*7c478bd9Sstevel@tonic-gate 	(void) smdb_unlock_file(db1->smdb1_lock_fd);
571*7c478bd9Sstevel@tonic-gate 	free(db1);
572*7c478bd9Sstevel@tonic-gate 	smdb_free_database(smdb_db);
573*7c478bd9Sstevel@tonic-gate 
574*7c478bd9Sstevel@tonic-gate 	return result;
575*7c478bd9Sstevel@tonic-gate }
576*7c478bd9Sstevel@tonic-gate 
577*7c478bd9Sstevel@tonic-gate #endif /* (DB_VERSION_MAJOR == 1) */
578