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