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 #include <sm/gen.h>
11*7c478bd9Sstevel@tonic-gate SM_RCSID("@(#)$Id: smndbm.c,v 8.52 2002/05/21 22:30:30 gshapiro Exp $")
12*7c478bd9Sstevel@tonic-gate 
13*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
14*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
15*7c478bd9Sstevel@tonic-gate #include <unistd.h>
16*7c478bd9Sstevel@tonic-gate 
17*7c478bd9Sstevel@tonic-gate #include <sendmail/sendmail.h>
18*7c478bd9Sstevel@tonic-gate #include <libsmdb/smdb.h>
19*7c478bd9Sstevel@tonic-gate 
20*7c478bd9Sstevel@tonic-gate #ifdef NDBM
21*7c478bd9Sstevel@tonic-gate 
22*7c478bd9Sstevel@tonic-gate # define SMNDB_DIR_FILE_EXTENSION "dir"
23*7c478bd9Sstevel@tonic-gate # define SMNDB_PAG_FILE_EXTENSION "pag"
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate struct smdb_dbm_database_struct
26*7c478bd9Sstevel@tonic-gate {
27*7c478bd9Sstevel@tonic-gate 	DBM	*smndbm_dbm;
28*7c478bd9Sstevel@tonic-gate 	int	smndbm_lock_fd;
29*7c478bd9Sstevel@tonic-gate 	bool	smndbm_cursor_in_use;
30*7c478bd9Sstevel@tonic-gate };
31*7c478bd9Sstevel@tonic-gate typedef struct smdb_dbm_database_struct SMDB_DBM_DATABASE;
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate struct smdb_dbm_cursor_struct
34*7c478bd9Sstevel@tonic-gate {
35*7c478bd9Sstevel@tonic-gate 	SMDB_DBM_DATABASE	*smndbmc_db;
36*7c478bd9Sstevel@tonic-gate 	datum			smndbmc_current_key;
37*7c478bd9Sstevel@tonic-gate };
38*7c478bd9Sstevel@tonic-gate typedef struct smdb_dbm_cursor_struct SMDB_DBM_CURSOR;
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate /*
41*7c478bd9Sstevel@tonic-gate **  SMDB_PUT_FLAGS_TO_NDBM_FLAGS -- Translates smdb put flags to ndbm put flags.
42*7c478bd9Sstevel@tonic-gate **
43*7c478bd9Sstevel@tonic-gate **	Parameters:
44*7c478bd9Sstevel@tonic-gate **		flags -- The flags to translate.
45*7c478bd9Sstevel@tonic-gate **
46*7c478bd9Sstevel@tonic-gate **	Returns:
47*7c478bd9Sstevel@tonic-gate **		The ndbm flags that are equivalent to the smdb flags.
48*7c478bd9Sstevel@tonic-gate **
49*7c478bd9Sstevel@tonic-gate **	Notes:
50*7c478bd9Sstevel@tonic-gate **		Any invalid flags are ignored.
51*7c478bd9Sstevel@tonic-gate **
52*7c478bd9Sstevel@tonic-gate */
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate int
smdb_put_flags_to_ndbm_flags(flags)55*7c478bd9Sstevel@tonic-gate smdb_put_flags_to_ndbm_flags(flags)
56*7c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
57*7c478bd9Sstevel@tonic-gate {
58*7c478bd9Sstevel@tonic-gate 	int return_flags;
59*7c478bd9Sstevel@tonic-gate 
60*7c478bd9Sstevel@tonic-gate 	return_flags = 0;
61*7c478bd9Sstevel@tonic-gate 	if (bitset(SMDBF_NO_OVERWRITE, flags))
62*7c478bd9Sstevel@tonic-gate 		return_flags = DBM_INSERT;
63*7c478bd9Sstevel@tonic-gate 	else
64*7c478bd9Sstevel@tonic-gate 		return_flags = DBM_REPLACE;
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate 	return return_flags;
67*7c478bd9Sstevel@tonic-gate }
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate /*
70*7c478bd9Sstevel@tonic-gate **  Except for smdb_ndbm_open, the rest of these function correspond to the
71*7c478bd9Sstevel@tonic-gate **  interface laid out in smdb.h.
72*7c478bd9Sstevel@tonic-gate */
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate SMDB_DBM_DATABASE *
smdbm_malloc_database()75*7c478bd9Sstevel@tonic-gate smdbm_malloc_database()
76*7c478bd9Sstevel@tonic-gate {
77*7c478bd9Sstevel@tonic-gate 	SMDB_DBM_DATABASE *db;
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate 	db = (SMDB_DBM_DATABASE *) malloc(sizeof(SMDB_DBM_DATABASE));
80*7c478bd9Sstevel@tonic-gate 	if (db != NULL)
81*7c478bd9Sstevel@tonic-gate 	{
82*7c478bd9Sstevel@tonic-gate 		db->smndbm_dbm = NULL;
83*7c478bd9Sstevel@tonic-gate 		db->smndbm_lock_fd = -1;
84*7c478bd9Sstevel@tonic-gate 		db->smndbm_cursor_in_use = false;
85*7c478bd9Sstevel@tonic-gate 	}
86*7c478bd9Sstevel@tonic-gate 
87*7c478bd9Sstevel@tonic-gate 	return db;
88*7c478bd9Sstevel@tonic-gate }
89*7c478bd9Sstevel@tonic-gate 
90*7c478bd9Sstevel@tonic-gate int
smdbm_close(database)91*7c478bd9Sstevel@tonic-gate smdbm_close(database)
92*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
93*7c478bd9Sstevel@tonic-gate {
94*7c478bd9Sstevel@tonic-gate 	SMDB_DBM_DATABASE *db = (SMDB_DBM_DATABASE *) database->smdb_impl;
95*7c478bd9Sstevel@tonic-gate 	DBM *dbm = ((SMDB_DBM_DATABASE *) database->smdb_impl)->smndbm_dbm;
96*7c478bd9Sstevel@tonic-gate 
97*7c478bd9Sstevel@tonic-gate 	dbm_close(dbm);
98*7c478bd9Sstevel@tonic-gate 	if (db->smndbm_lock_fd != -1)
99*7c478bd9Sstevel@tonic-gate 		close(db->smndbm_lock_fd);
100*7c478bd9Sstevel@tonic-gate 
101*7c478bd9Sstevel@tonic-gate 	free(db);
102*7c478bd9Sstevel@tonic-gate 	database->smdb_impl = NULL;
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
105*7c478bd9Sstevel@tonic-gate }
106*7c478bd9Sstevel@tonic-gate 
107*7c478bd9Sstevel@tonic-gate int
smdbm_del(database,key,flags)108*7c478bd9Sstevel@tonic-gate smdbm_del(database, key, flags)
109*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
110*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
111*7c478bd9Sstevel@tonic-gate 	unsigned int flags;
112*7c478bd9Sstevel@tonic-gate {
113*7c478bd9Sstevel@tonic-gate 	int result;
114*7c478bd9Sstevel@tonic-gate 	DBM *dbm = ((SMDB_DBM_DATABASE *) database->smdb_impl)->smndbm_dbm;
115*7c478bd9Sstevel@tonic-gate 	datum dbkey;
116*7c478bd9Sstevel@tonic-gate 
117*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
118*7c478bd9Sstevel@tonic-gate 	dbkey.dptr = key->data;
119*7c478bd9Sstevel@tonic-gate 	dbkey.dsize = key->size;
120*7c478bd9Sstevel@tonic-gate 
121*7c478bd9Sstevel@tonic-gate 	errno = 0;
122*7c478bd9Sstevel@tonic-gate 	result = dbm_delete(dbm, dbkey);
123*7c478bd9Sstevel@tonic-gate 	if (result != 0)
124*7c478bd9Sstevel@tonic-gate 	{
125*7c478bd9Sstevel@tonic-gate 		int save_errno = errno;
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate 		if (dbm_error(dbm))
128*7c478bd9Sstevel@tonic-gate 			return SMDBE_IO_ERROR;
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate 		if (save_errno != 0)
131*7c478bd9Sstevel@tonic-gate 			return save_errno;
132*7c478bd9Sstevel@tonic-gate 
133*7c478bd9Sstevel@tonic-gate 		return SMDBE_NOT_FOUND;
134*7c478bd9Sstevel@tonic-gate 	}
135*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
136*7c478bd9Sstevel@tonic-gate }
137*7c478bd9Sstevel@tonic-gate 
138*7c478bd9Sstevel@tonic-gate int
smdbm_fd(database,fd)139*7c478bd9Sstevel@tonic-gate smdbm_fd(database, fd)
140*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
141*7c478bd9Sstevel@tonic-gate 	int *fd;
142*7c478bd9Sstevel@tonic-gate {
143*7c478bd9Sstevel@tonic-gate 	DBM *dbm = ((SMDB_DBM_DATABASE *) database->smdb_impl)->smndbm_dbm;
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate 	*fd = dbm_dirfno(dbm);
146*7c478bd9Sstevel@tonic-gate 	if (*fd <= 0)
147*7c478bd9Sstevel@tonic-gate 		return EINVAL;
148*7c478bd9Sstevel@tonic-gate 
149*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
150*7c478bd9Sstevel@tonic-gate }
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate int
smdbm_lockfd(database)153*7c478bd9Sstevel@tonic-gate smdbm_lockfd(database)
154*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
155*7c478bd9Sstevel@tonic-gate {
156*7c478bd9Sstevel@tonic-gate 	SMDB_DBM_DATABASE *db = (SMDB_DBM_DATABASE *) database->smdb_impl;
157*7c478bd9Sstevel@tonic-gate 
158*7c478bd9Sstevel@tonic-gate 	return db->smndbm_lock_fd;
159*7c478bd9Sstevel@tonic-gate }
160*7c478bd9Sstevel@tonic-gate 
161*7c478bd9Sstevel@tonic-gate int
smdbm_get(database,key,data,flags)162*7c478bd9Sstevel@tonic-gate smdbm_get(database, key, data, flags)
163*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
164*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
165*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *data;
166*7c478bd9Sstevel@tonic-gate 	unsigned int flags;
167*7c478bd9Sstevel@tonic-gate {
168*7c478bd9Sstevel@tonic-gate 	DBM *dbm = ((SMDB_DBM_DATABASE *) database->smdb_impl)->smndbm_dbm;
169*7c478bd9Sstevel@tonic-gate 	datum dbkey, dbdata;
170*7c478bd9Sstevel@tonic-gate 
171*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
172*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
173*7c478bd9Sstevel@tonic-gate 	dbkey.dptr = key->data;
174*7c478bd9Sstevel@tonic-gate 	dbkey.dsize = key->size;
175*7c478bd9Sstevel@tonic-gate 
176*7c478bd9Sstevel@tonic-gate 	errno = 0;
177*7c478bd9Sstevel@tonic-gate 	dbdata = dbm_fetch(dbm, dbkey);
178*7c478bd9Sstevel@tonic-gate 	if (dbdata.dptr == NULL)
179*7c478bd9Sstevel@tonic-gate 	{
180*7c478bd9Sstevel@tonic-gate 		int save_errno = errno;
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate 		if (dbm_error(dbm))
183*7c478bd9Sstevel@tonic-gate 			return SMDBE_IO_ERROR;
184*7c478bd9Sstevel@tonic-gate 
185*7c478bd9Sstevel@tonic-gate 		if (save_errno != 0)
186*7c478bd9Sstevel@tonic-gate 			return save_errno;
187*7c478bd9Sstevel@tonic-gate 
188*7c478bd9Sstevel@tonic-gate 		return SMDBE_NOT_FOUND;
189*7c478bd9Sstevel@tonic-gate 	}
190*7c478bd9Sstevel@tonic-gate 	data->data = dbdata.dptr;
191*7c478bd9Sstevel@tonic-gate 	data->size = dbdata.dsize;
192*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
193*7c478bd9Sstevel@tonic-gate }
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate int
smdbm_put(database,key,data,flags)196*7c478bd9Sstevel@tonic-gate smdbm_put(database, key, data, flags)
197*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
198*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
199*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *data;
200*7c478bd9Sstevel@tonic-gate 	unsigned int flags;
201*7c478bd9Sstevel@tonic-gate {
202*7c478bd9Sstevel@tonic-gate 	int result;
203*7c478bd9Sstevel@tonic-gate 	int save_errno;
204*7c478bd9Sstevel@tonic-gate 	DBM *dbm = ((SMDB_DBM_DATABASE *) database->smdb_impl)->smndbm_dbm;
205*7c478bd9Sstevel@tonic-gate 	datum dbkey, dbdata;
206*7c478bd9Sstevel@tonic-gate 
207*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
208*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
209*7c478bd9Sstevel@tonic-gate 	dbkey.dptr = key->data;
210*7c478bd9Sstevel@tonic-gate 	dbkey.dsize = key->size;
211*7c478bd9Sstevel@tonic-gate 	dbdata.dptr = data->data;
212*7c478bd9Sstevel@tonic-gate 	dbdata.dsize = data->size;
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate 	errno = 0;
215*7c478bd9Sstevel@tonic-gate 	result = dbm_store(dbm, dbkey, dbdata,
216*7c478bd9Sstevel@tonic-gate 			   smdb_put_flags_to_ndbm_flags(flags));
217*7c478bd9Sstevel@tonic-gate 	switch (result)
218*7c478bd9Sstevel@tonic-gate 	{
219*7c478bd9Sstevel@tonic-gate 	  case 1:
220*7c478bd9Sstevel@tonic-gate 		return SMDBE_DUPLICATE;
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate 	  case 0:
223*7c478bd9Sstevel@tonic-gate 		return SMDBE_OK;
224*7c478bd9Sstevel@tonic-gate 
225*7c478bd9Sstevel@tonic-gate 	  default:
226*7c478bd9Sstevel@tonic-gate 		save_errno = errno;
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate 		if (dbm_error(dbm))
229*7c478bd9Sstevel@tonic-gate 			return SMDBE_IO_ERROR;
230*7c478bd9Sstevel@tonic-gate 
231*7c478bd9Sstevel@tonic-gate 		if (save_errno != 0)
232*7c478bd9Sstevel@tonic-gate 			return save_errno;
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate 		return SMDBE_IO_ERROR;
235*7c478bd9Sstevel@tonic-gate 	}
236*7c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
237*7c478bd9Sstevel@tonic-gate }
238*7c478bd9Sstevel@tonic-gate 
239*7c478bd9Sstevel@tonic-gate int
smndbm_set_owner(database,uid,gid)240*7c478bd9Sstevel@tonic-gate smndbm_set_owner(database, uid, gid)
241*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
242*7c478bd9Sstevel@tonic-gate 	uid_t uid;
243*7c478bd9Sstevel@tonic-gate 	gid_t gid;
244*7c478bd9Sstevel@tonic-gate {
245*7c478bd9Sstevel@tonic-gate # if HASFCHOWN
246*7c478bd9Sstevel@tonic-gate 	int fd;
247*7c478bd9Sstevel@tonic-gate 	int result;
248*7c478bd9Sstevel@tonic-gate 	DBM *dbm = ((SMDB_DBM_DATABASE *) database->smdb_impl)->smndbm_dbm;
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate 	fd = dbm_dirfno(dbm);
251*7c478bd9Sstevel@tonic-gate 	if (fd <= 0)
252*7c478bd9Sstevel@tonic-gate 		return EINVAL;
253*7c478bd9Sstevel@tonic-gate 
254*7c478bd9Sstevel@tonic-gate 	result = fchown(fd, uid, gid);
255*7c478bd9Sstevel@tonic-gate 	if (result < 0)
256*7c478bd9Sstevel@tonic-gate 		return errno;
257*7c478bd9Sstevel@tonic-gate 
258*7c478bd9Sstevel@tonic-gate 	fd = dbm_pagfno(dbm);
259*7c478bd9Sstevel@tonic-gate 	if (fd <= 0)
260*7c478bd9Sstevel@tonic-gate 		return EINVAL;
261*7c478bd9Sstevel@tonic-gate 
262*7c478bd9Sstevel@tonic-gate 	result = fchown(fd, uid, gid);
263*7c478bd9Sstevel@tonic-gate 	if (result < 0)
264*7c478bd9Sstevel@tonic-gate 		return errno;
265*7c478bd9Sstevel@tonic-gate # endif /* HASFCHOWN */
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
268*7c478bd9Sstevel@tonic-gate }
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate int
smdbm_sync(database,flags)271*7c478bd9Sstevel@tonic-gate smdbm_sync(database, flags)
272*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
273*7c478bd9Sstevel@tonic-gate 	unsigned int flags;
274*7c478bd9Sstevel@tonic-gate {
275*7c478bd9Sstevel@tonic-gate 	return SMDBE_UNSUPPORTED;
276*7c478bd9Sstevel@tonic-gate }
277*7c478bd9Sstevel@tonic-gate 
278*7c478bd9Sstevel@tonic-gate int
smdbm_cursor_close(cursor)279*7c478bd9Sstevel@tonic-gate smdbm_cursor_close(cursor)
280*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
281*7c478bd9Sstevel@tonic-gate {
282*7c478bd9Sstevel@tonic-gate 	SMDB_DBM_CURSOR *dbm_cursor = (SMDB_DBM_CURSOR *) cursor->smdbc_impl;
283*7c478bd9Sstevel@tonic-gate 	SMDB_DBM_DATABASE *db = dbm_cursor->smndbmc_db;
284*7c478bd9Sstevel@tonic-gate 
285*7c478bd9Sstevel@tonic-gate 	if (!db->smndbm_cursor_in_use)
286*7c478bd9Sstevel@tonic-gate 		return SMDBE_NOT_A_VALID_CURSOR;
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate 	db->smndbm_cursor_in_use = false;
289*7c478bd9Sstevel@tonic-gate 	free(dbm_cursor);
290*7c478bd9Sstevel@tonic-gate 	free(cursor);
291*7c478bd9Sstevel@tonic-gate 
292*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
293*7c478bd9Sstevel@tonic-gate }
294*7c478bd9Sstevel@tonic-gate 
295*7c478bd9Sstevel@tonic-gate int
smdbm_cursor_del(cursor,flags)296*7c478bd9Sstevel@tonic-gate smdbm_cursor_del(cursor, flags)
297*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
298*7c478bd9Sstevel@tonic-gate 	unsigned int flags;
299*7c478bd9Sstevel@tonic-gate {
300*7c478bd9Sstevel@tonic-gate 	int result;
301*7c478bd9Sstevel@tonic-gate 	SMDB_DBM_CURSOR *dbm_cursor = (SMDB_DBM_CURSOR *) cursor->smdbc_impl;
302*7c478bd9Sstevel@tonic-gate 	SMDB_DBM_DATABASE *db = dbm_cursor->smndbmc_db;
303*7c478bd9Sstevel@tonic-gate 	DBM *dbm = db->smndbm_dbm;
304*7c478bd9Sstevel@tonic-gate 
305*7c478bd9Sstevel@tonic-gate 	errno = 0;
306*7c478bd9Sstevel@tonic-gate 	result = dbm_delete(dbm, dbm_cursor->smndbmc_current_key);
307*7c478bd9Sstevel@tonic-gate 	if (result != 0)
308*7c478bd9Sstevel@tonic-gate 	{
309*7c478bd9Sstevel@tonic-gate 		int save_errno = errno;
310*7c478bd9Sstevel@tonic-gate 
311*7c478bd9Sstevel@tonic-gate 		if (dbm_error(dbm))
312*7c478bd9Sstevel@tonic-gate 			return SMDBE_IO_ERROR;
313*7c478bd9Sstevel@tonic-gate 
314*7c478bd9Sstevel@tonic-gate 		if (save_errno != 0)
315*7c478bd9Sstevel@tonic-gate 			return save_errno;
316*7c478bd9Sstevel@tonic-gate 
317*7c478bd9Sstevel@tonic-gate 		return SMDBE_NOT_FOUND;
318*7c478bd9Sstevel@tonic-gate 	}
319*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
320*7c478bd9Sstevel@tonic-gate }
321*7c478bd9Sstevel@tonic-gate 
322*7c478bd9Sstevel@tonic-gate int
smdbm_cursor_get(cursor,key,value,flags)323*7c478bd9Sstevel@tonic-gate smdbm_cursor_get(cursor, key, value, flags)
324*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
325*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
326*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *value;
327*7c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
328*7c478bd9Sstevel@tonic-gate {
329*7c478bd9Sstevel@tonic-gate 	SMDB_DBM_CURSOR *dbm_cursor = (SMDB_DBM_CURSOR *) cursor->smdbc_impl;
330*7c478bd9Sstevel@tonic-gate 	SMDB_DBM_DATABASE *db = dbm_cursor->smndbmc_db;
331*7c478bd9Sstevel@tonic-gate 	DBM *dbm = db->smndbm_dbm;
332*7c478bd9Sstevel@tonic-gate 	datum dbkey, dbdata;
333*7c478bd9Sstevel@tonic-gate 
334*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbkey, '\0', sizeof dbkey);
335*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
336*7c478bd9Sstevel@tonic-gate 
337*7c478bd9Sstevel@tonic-gate 	if (flags == SMDB_CURSOR_GET_RANGE)
338*7c478bd9Sstevel@tonic-gate 		return SMDBE_UNSUPPORTED;
339*7c478bd9Sstevel@tonic-gate 
340*7c478bd9Sstevel@tonic-gate 	if (dbm_cursor->smndbmc_current_key.dptr == NULL)
341*7c478bd9Sstevel@tonic-gate 	{
342*7c478bd9Sstevel@tonic-gate 		dbm_cursor->smndbmc_current_key = dbm_firstkey(dbm);
343*7c478bd9Sstevel@tonic-gate 		if (dbm_cursor->smndbmc_current_key.dptr == NULL)
344*7c478bd9Sstevel@tonic-gate 		{
345*7c478bd9Sstevel@tonic-gate 			if (dbm_error(dbm))
346*7c478bd9Sstevel@tonic-gate 				return SMDBE_IO_ERROR;
347*7c478bd9Sstevel@tonic-gate 			return SMDBE_LAST_ENTRY;
348*7c478bd9Sstevel@tonic-gate 		}
349*7c478bd9Sstevel@tonic-gate 	}
350*7c478bd9Sstevel@tonic-gate 	else
351*7c478bd9Sstevel@tonic-gate 	{
352*7c478bd9Sstevel@tonic-gate 		dbm_cursor->smndbmc_current_key = dbm_nextkey(dbm);
353*7c478bd9Sstevel@tonic-gate 		if (dbm_cursor->smndbmc_current_key.dptr == NULL)
354*7c478bd9Sstevel@tonic-gate 		{
355*7c478bd9Sstevel@tonic-gate 			if (dbm_error(dbm))
356*7c478bd9Sstevel@tonic-gate 				return SMDBE_IO_ERROR;
357*7c478bd9Sstevel@tonic-gate 			return SMDBE_LAST_ENTRY;
358*7c478bd9Sstevel@tonic-gate 		}
359*7c478bd9Sstevel@tonic-gate 	}
360*7c478bd9Sstevel@tonic-gate 
361*7c478bd9Sstevel@tonic-gate 	errno = 0;
362*7c478bd9Sstevel@tonic-gate 	dbdata = dbm_fetch(dbm, dbm_cursor->smndbmc_current_key);
363*7c478bd9Sstevel@tonic-gate 	if (dbdata.dptr == NULL)
364*7c478bd9Sstevel@tonic-gate 	{
365*7c478bd9Sstevel@tonic-gate 		int save_errno = errno;
366*7c478bd9Sstevel@tonic-gate 
367*7c478bd9Sstevel@tonic-gate 		if (dbm_error(dbm))
368*7c478bd9Sstevel@tonic-gate 			return SMDBE_IO_ERROR;
369*7c478bd9Sstevel@tonic-gate 
370*7c478bd9Sstevel@tonic-gate 		if (save_errno != 0)
371*7c478bd9Sstevel@tonic-gate 			return save_errno;
372*7c478bd9Sstevel@tonic-gate 
373*7c478bd9Sstevel@tonic-gate 		return SMDBE_NOT_FOUND;
374*7c478bd9Sstevel@tonic-gate 	}
375*7c478bd9Sstevel@tonic-gate 	value->data = dbdata.dptr;
376*7c478bd9Sstevel@tonic-gate 	value->size = dbdata.dsize;
377*7c478bd9Sstevel@tonic-gate 	key->data = dbm_cursor->smndbmc_current_key.dptr;
378*7c478bd9Sstevel@tonic-gate 	key->size = dbm_cursor->smndbmc_current_key.dsize;
379*7c478bd9Sstevel@tonic-gate 
380*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
381*7c478bd9Sstevel@tonic-gate }
382*7c478bd9Sstevel@tonic-gate 
383*7c478bd9Sstevel@tonic-gate int
smdbm_cursor_put(cursor,key,value,flags)384*7c478bd9Sstevel@tonic-gate smdbm_cursor_put(cursor, key, value, flags)
385*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
386*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *key;
387*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT *value;
388*7c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
389*7c478bd9Sstevel@tonic-gate {
390*7c478bd9Sstevel@tonic-gate 	int result;
391*7c478bd9Sstevel@tonic-gate 	int save_errno;
392*7c478bd9Sstevel@tonic-gate 	SMDB_DBM_CURSOR *dbm_cursor = (SMDB_DBM_CURSOR *) cursor->smdbc_impl;
393*7c478bd9Sstevel@tonic-gate 	SMDB_DBM_DATABASE *db = dbm_cursor->smndbmc_db;
394*7c478bd9Sstevel@tonic-gate 	DBM *dbm = db->smndbm_dbm;
395*7c478bd9Sstevel@tonic-gate 	datum dbdata;
396*7c478bd9Sstevel@tonic-gate 
397*7c478bd9Sstevel@tonic-gate 	(void) memset(&dbdata, '\0', sizeof dbdata);
398*7c478bd9Sstevel@tonic-gate 	dbdata.dptr = value->data;
399*7c478bd9Sstevel@tonic-gate 	dbdata.dsize = value->size;
400*7c478bd9Sstevel@tonic-gate 
401*7c478bd9Sstevel@tonic-gate 	errno = 0;
402*7c478bd9Sstevel@tonic-gate 	result = dbm_store(dbm, dbm_cursor->smndbmc_current_key, dbdata,
403*7c478bd9Sstevel@tonic-gate 			   smdb_put_flags_to_ndbm_flags(flags));
404*7c478bd9Sstevel@tonic-gate 	switch (result)
405*7c478bd9Sstevel@tonic-gate 	{
406*7c478bd9Sstevel@tonic-gate 	  case 1:
407*7c478bd9Sstevel@tonic-gate 		return SMDBE_DUPLICATE;
408*7c478bd9Sstevel@tonic-gate 
409*7c478bd9Sstevel@tonic-gate 	  case 0:
410*7c478bd9Sstevel@tonic-gate 		return SMDBE_OK;
411*7c478bd9Sstevel@tonic-gate 
412*7c478bd9Sstevel@tonic-gate 	  default:
413*7c478bd9Sstevel@tonic-gate 		save_errno = errno;
414*7c478bd9Sstevel@tonic-gate 
415*7c478bd9Sstevel@tonic-gate 		if (dbm_error(dbm))
416*7c478bd9Sstevel@tonic-gate 			return SMDBE_IO_ERROR;
417*7c478bd9Sstevel@tonic-gate 
418*7c478bd9Sstevel@tonic-gate 		if (save_errno != 0)
419*7c478bd9Sstevel@tonic-gate 			return save_errno;
420*7c478bd9Sstevel@tonic-gate 
421*7c478bd9Sstevel@tonic-gate 		return SMDBE_IO_ERROR;
422*7c478bd9Sstevel@tonic-gate 	}
423*7c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
424*7c478bd9Sstevel@tonic-gate }
425*7c478bd9Sstevel@tonic-gate 
426*7c478bd9Sstevel@tonic-gate int
smdbm_cursor(database,cursor,flags)427*7c478bd9Sstevel@tonic-gate smdbm_cursor(database, cursor, flags)
428*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
429*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR **cursor;
430*7c478bd9Sstevel@tonic-gate 	SMDB_FLAG flags;
431*7c478bd9Sstevel@tonic-gate {
432*7c478bd9Sstevel@tonic-gate 	SMDB_DBM_DATABASE *db = (SMDB_DBM_DATABASE *) database->smdb_impl;
433*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cur;
434*7c478bd9Sstevel@tonic-gate 	SMDB_DBM_CURSOR *dbm_cursor;
435*7c478bd9Sstevel@tonic-gate 
436*7c478bd9Sstevel@tonic-gate 	if (db->smndbm_cursor_in_use)
437*7c478bd9Sstevel@tonic-gate 		return SMDBE_ONLY_SUPPORTS_ONE_CURSOR;
438*7c478bd9Sstevel@tonic-gate 
439*7c478bd9Sstevel@tonic-gate 	db->smndbm_cursor_in_use = true;
440*7c478bd9Sstevel@tonic-gate 	dbm_cursor = (SMDB_DBM_CURSOR *) malloc(sizeof(SMDB_DBM_CURSOR));
441*7c478bd9Sstevel@tonic-gate 	dbm_cursor->smndbmc_db = db;
442*7c478bd9Sstevel@tonic-gate 	dbm_cursor->smndbmc_current_key.dptr = NULL;
443*7c478bd9Sstevel@tonic-gate 	dbm_cursor->smndbmc_current_key.dsize = 0;
444*7c478bd9Sstevel@tonic-gate 
445*7c478bd9Sstevel@tonic-gate 	cur = (SMDB_CURSOR*) malloc(sizeof(SMDB_CURSOR));
446*7c478bd9Sstevel@tonic-gate 	if (cur == NULL)
447*7c478bd9Sstevel@tonic-gate 		return SMDBE_MALLOC;
448*7c478bd9Sstevel@tonic-gate 
449*7c478bd9Sstevel@tonic-gate 	cur->smdbc_impl = dbm_cursor;
450*7c478bd9Sstevel@tonic-gate 	cur->smdbc_close = smdbm_cursor_close;
451*7c478bd9Sstevel@tonic-gate 	cur->smdbc_del = smdbm_cursor_del;
452*7c478bd9Sstevel@tonic-gate 	cur->smdbc_get = smdbm_cursor_get;
453*7c478bd9Sstevel@tonic-gate 	cur->smdbc_put = smdbm_cursor_put;
454*7c478bd9Sstevel@tonic-gate 	*cursor = cur;
455*7c478bd9Sstevel@tonic-gate 
456*7c478bd9Sstevel@tonic-gate 	return SMDBE_OK;
457*7c478bd9Sstevel@tonic-gate }
458*7c478bd9Sstevel@tonic-gate /*
459*7c478bd9Sstevel@tonic-gate **  SMDB_NDBM_OPEN -- Opens a ndbm database.
460*7c478bd9Sstevel@tonic-gate **
461*7c478bd9Sstevel@tonic-gate **	Parameters:
462*7c478bd9Sstevel@tonic-gate **		database -- An unallocated database pointer to a pointer.
463*7c478bd9Sstevel@tonic-gate **		db_name -- The name of the database without extension.
464*7c478bd9Sstevel@tonic-gate **		mode -- File permisions on a created database.
465*7c478bd9Sstevel@tonic-gate **		mode_mask -- Mode bits that much match on an opened database.
466*7c478bd9Sstevel@tonic-gate **		sff -- Flags to safefile.
467*7c478bd9Sstevel@tonic-gate **		type -- The type of database to open.
468*7c478bd9Sstevel@tonic-gate **			Only SMDB_NDBM is supported.
469*7c478bd9Sstevel@tonic-gate **		user_info -- Information on the user to use for file
470*7c478bd9Sstevel@tonic-gate **			    permissions.
471*7c478bd9Sstevel@tonic-gate **		db_params -- No params are supported.
472*7c478bd9Sstevel@tonic-gate **
473*7c478bd9Sstevel@tonic-gate **	Returns:
474*7c478bd9Sstevel@tonic-gate **		SMDBE_OK -- Success, otherwise errno:
475*7c478bd9Sstevel@tonic-gate **		SMDBE_MALLOC -- Cannot allocate memory.
476*7c478bd9Sstevel@tonic-gate **		SMDBE_UNSUPPORTED -- The type is not supported.
477*7c478bd9Sstevel@tonic-gate **		SMDBE_GDBM_IS_BAD -- We have detected GDBM and we don't
478*7c478bd9Sstevel@tonic-gate **				    like it.
479*7c478bd9Sstevel@tonic-gate **		SMDBE_BAD_OPEN -- dbm_open failed and errno was not set.
480*7c478bd9Sstevel@tonic-gate **		Anything else: errno
481*7c478bd9Sstevel@tonic-gate */
482*7c478bd9Sstevel@tonic-gate 
483*7c478bd9Sstevel@tonic-gate int
smdb_ndbm_open(database,db_name,mode,mode_mask,sff,type,user_info,db_params)484*7c478bd9Sstevel@tonic-gate smdb_ndbm_open(database, db_name, mode, mode_mask, sff, type, user_info,
485*7c478bd9Sstevel@tonic-gate 	       db_params)
486*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE **database;
487*7c478bd9Sstevel@tonic-gate 	char *db_name;
488*7c478bd9Sstevel@tonic-gate 	int mode;
489*7c478bd9Sstevel@tonic-gate 	int mode_mask;
490*7c478bd9Sstevel@tonic-gate 	long sff;
491*7c478bd9Sstevel@tonic-gate 	SMDB_DBTYPE type;
492*7c478bd9Sstevel@tonic-gate 	SMDB_USER_INFO *user_info;
493*7c478bd9Sstevel@tonic-gate 	SMDB_DBPARAMS *db_params;
494*7c478bd9Sstevel@tonic-gate {
495*7c478bd9Sstevel@tonic-gate 	bool lockcreated = false;
496*7c478bd9Sstevel@tonic-gate 	int result;
497*7c478bd9Sstevel@tonic-gate 	int lock_fd;
498*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *smdb_db;
499*7c478bd9Sstevel@tonic-gate 	SMDB_DBM_DATABASE *db;
500*7c478bd9Sstevel@tonic-gate 	DBM *dbm = NULL;
501*7c478bd9Sstevel@tonic-gate 	struct stat dir_stat_info;
502*7c478bd9Sstevel@tonic-gate 	struct stat pag_stat_info;
503*7c478bd9Sstevel@tonic-gate 
504*7c478bd9Sstevel@tonic-gate 	result = SMDBE_OK;
505*7c478bd9Sstevel@tonic-gate 	*database = NULL;
506*7c478bd9Sstevel@tonic-gate 
507*7c478bd9Sstevel@tonic-gate 	if (type == NULL)
508*7c478bd9Sstevel@tonic-gate 		return SMDBE_UNKNOWN_DB_TYPE;
509*7c478bd9Sstevel@tonic-gate 
510*7c478bd9Sstevel@tonic-gate 	result = smdb_setup_file(db_name, SMNDB_DIR_FILE_EXTENSION, mode_mask,
511*7c478bd9Sstevel@tonic-gate 				 sff, user_info, &dir_stat_info);
512*7c478bd9Sstevel@tonic-gate 	if (result != SMDBE_OK)
513*7c478bd9Sstevel@tonic-gate 		return result;
514*7c478bd9Sstevel@tonic-gate 
515*7c478bd9Sstevel@tonic-gate 	result = smdb_setup_file(db_name, SMNDB_PAG_FILE_EXTENSION, mode_mask,
516*7c478bd9Sstevel@tonic-gate 				 sff, user_info, &pag_stat_info);
517*7c478bd9Sstevel@tonic-gate 	if (result != SMDBE_OK)
518*7c478bd9Sstevel@tonic-gate 		return result;
519*7c478bd9Sstevel@tonic-gate 
520*7c478bd9Sstevel@tonic-gate 	if ((dir_stat_info.st_mode == ST_MODE_NOFILE ||
521*7c478bd9Sstevel@tonic-gate 	     pag_stat_info.st_mode == ST_MODE_NOFILE) &&
522*7c478bd9Sstevel@tonic-gate 	    bitset(mode, O_CREAT))
523*7c478bd9Sstevel@tonic-gate 		lockcreated = true;
524*7c478bd9Sstevel@tonic-gate 
525*7c478bd9Sstevel@tonic-gate 	lock_fd = -1;
526*7c478bd9Sstevel@tonic-gate 	result = smdb_lock_file(&lock_fd, db_name, mode, sff,
527*7c478bd9Sstevel@tonic-gate 				SMNDB_DIR_FILE_EXTENSION);
528*7c478bd9Sstevel@tonic-gate 	if (result != SMDBE_OK)
529*7c478bd9Sstevel@tonic-gate 		return result;
530*7c478bd9Sstevel@tonic-gate 
531*7c478bd9Sstevel@tonic-gate 	if (lockcreated)
532*7c478bd9Sstevel@tonic-gate 	{
533*7c478bd9Sstevel@tonic-gate 		int pag_fd;
534*7c478bd9Sstevel@tonic-gate 
535*7c478bd9Sstevel@tonic-gate 		/* Need to pre-open the .pag file as well with O_EXCL */
536*7c478bd9Sstevel@tonic-gate 		result = smdb_lock_file(&pag_fd, db_name, mode, sff,
537*7c478bd9Sstevel@tonic-gate 					SMNDB_PAG_FILE_EXTENSION);
538*7c478bd9Sstevel@tonic-gate 		if (result != SMDBE_OK)
539*7c478bd9Sstevel@tonic-gate 		{
540*7c478bd9Sstevel@tonic-gate 			(void) close(lock_fd);
541*7c478bd9Sstevel@tonic-gate 			return result;
542*7c478bd9Sstevel@tonic-gate 		}
543*7c478bd9Sstevel@tonic-gate 		(void) close(pag_fd);
544*7c478bd9Sstevel@tonic-gate 
545*7c478bd9Sstevel@tonic-gate 		mode |= O_TRUNC;
546*7c478bd9Sstevel@tonic-gate 		mode &= ~(O_CREAT|O_EXCL);
547*7c478bd9Sstevel@tonic-gate 	}
548*7c478bd9Sstevel@tonic-gate 
549*7c478bd9Sstevel@tonic-gate 	smdb_db = smdb_malloc_database();
550*7c478bd9Sstevel@tonic-gate 	if (smdb_db == NULL)
551*7c478bd9Sstevel@tonic-gate 		result = SMDBE_MALLOC;
552*7c478bd9Sstevel@tonic-gate 
553*7c478bd9Sstevel@tonic-gate 	db = smdbm_malloc_database();
554*7c478bd9Sstevel@tonic-gate 	if (db == NULL)
555*7c478bd9Sstevel@tonic-gate 		result = SMDBE_MALLOC;
556*7c478bd9Sstevel@tonic-gate 
557*7c478bd9Sstevel@tonic-gate 	/* Try to open database */
558*7c478bd9Sstevel@tonic-gate 	if (result == SMDBE_OK)
559*7c478bd9Sstevel@tonic-gate 	{
560*7c478bd9Sstevel@tonic-gate 		db->smndbm_lock_fd = lock_fd;
561*7c478bd9Sstevel@tonic-gate 
562*7c478bd9Sstevel@tonic-gate 		errno = 0;
563*7c478bd9Sstevel@tonic-gate 		dbm = dbm_open(db_name, mode, DBMMODE);
564*7c478bd9Sstevel@tonic-gate 		if (dbm == NULL)
565*7c478bd9Sstevel@tonic-gate 		{
566*7c478bd9Sstevel@tonic-gate 			if (errno == 0)
567*7c478bd9Sstevel@tonic-gate 				result = SMDBE_BAD_OPEN;
568*7c478bd9Sstevel@tonic-gate 			else
569*7c478bd9Sstevel@tonic-gate 				result = errno;
570*7c478bd9Sstevel@tonic-gate 		}
571*7c478bd9Sstevel@tonic-gate 		db->smndbm_dbm = dbm;
572*7c478bd9Sstevel@tonic-gate 	}
573*7c478bd9Sstevel@tonic-gate 
574*7c478bd9Sstevel@tonic-gate 	/* Check for GDBM */
575*7c478bd9Sstevel@tonic-gate 	if (result == SMDBE_OK)
576*7c478bd9Sstevel@tonic-gate 	{
577*7c478bd9Sstevel@tonic-gate 		if (dbm_dirfno(dbm) == dbm_pagfno(dbm))
578*7c478bd9Sstevel@tonic-gate 			result = SMDBE_GDBM_IS_BAD;
579*7c478bd9Sstevel@tonic-gate 	}
580*7c478bd9Sstevel@tonic-gate 
581*7c478bd9Sstevel@tonic-gate 	/* Check for filechanged */
582*7c478bd9Sstevel@tonic-gate 	if (result == SMDBE_OK)
583*7c478bd9Sstevel@tonic-gate 	{
584*7c478bd9Sstevel@tonic-gate 		result = smdb_filechanged(db_name, SMNDB_DIR_FILE_EXTENSION,
585*7c478bd9Sstevel@tonic-gate 					  dbm_dirfno(dbm), &dir_stat_info);
586*7c478bd9Sstevel@tonic-gate 		if (result == SMDBE_OK)
587*7c478bd9Sstevel@tonic-gate 		{
588*7c478bd9Sstevel@tonic-gate 			result = smdb_filechanged(db_name,
589*7c478bd9Sstevel@tonic-gate 						  SMNDB_PAG_FILE_EXTENSION,
590*7c478bd9Sstevel@tonic-gate 						  dbm_pagfno(dbm),
591*7c478bd9Sstevel@tonic-gate 						  &pag_stat_info);
592*7c478bd9Sstevel@tonic-gate 		}
593*7c478bd9Sstevel@tonic-gate 	}
594*7c478bd9Sstevel@tonic-gate 
595*7c478bd9Sstevel@tonic-gate 	/* XXX Got to get fchown stuff in here */
596*7c478bd9Sstevel@tonic-gate 
597*7c478bd9Sstevel@tonic-gate 	/* Setup driver if everything is ok */
598*7c478bd9Sstevel@tonic-gate 	if (result == SMDBE_OK)
599*7c478bd9Sstevel@tonic-gate 	{
600*7c478bd9Sstevel@tonic-gate 		*database = smdb_db;
601*7c478bd9Sstevel@tonic-gate 
602*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_close = smdbm_close;
603*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_del = smdbm_del;
604*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_fd = smdbm_fd;
605*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_lockfd = smdbm_lockfd;
606*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_get = smdbm_get;
607*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_put = smdbm_put;
608*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_set_owner = smndbm_set_owner;
609*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_sync = smdbm_sync;
610*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_cursor = smdbm_cursor;
611*7c478bd9Sstevel@tonic-gate 
612*7c478bd9Sstevel@tonic-gate 		smdb_db->smdb_impl = db;
613*7c478bd9Sstevel@tonic-gate 
614*7c478bd9Sstevel@tonic-gate 		return SMDBE_OK;
615*7c478bd9Sstevel@tonic-gate 	}
616*7c478bd9Sstevel@tonic-gate 
617*7c478bd9Sstevel@tonic-gate 	/* If we're here, something bad happened, clean up */
618*7c478bd9Sstevel@tonic-gate 	if (dbm != NULL)
619*7c478bd9Sstevel@tonic-gate 		dbm_close(dbm);
620*7c478bd9Sstevel@tonic-gate 
621*7c478bd9Sstevel@tonic-gate 	smdb_unlock_file(db->smndbm_lock_fd);
622*7c478bd9Sstevel@tonic-gate 	free(db);
623*7c478bd9Sstevel@tonic-gate 	smdb_free_database(smdb_db);
624*7c478bd9Sstevel@tonic-gate 
625*7c478bd9Sstevel@tonic-gate 	return result;
626*7c478bd9Sstevel@tonic-gate }
627*7c478bd9Sstevel@tonic-gate #endif /* NDBM */
628