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
smdb_put_flags_to_ndbm_flags(flags)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 *
smdbm_malloc_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
smdbm_close(database)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
smdbm_del(database,key,flags)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
smdbm_fd(database,fd)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
smdbm_lockfd(database)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
smdbm_get(database,key,data,flags)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
smdbm_put(database,key,data,flags)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
smndbm_set_owner(database,uid,gid)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
smdbm_sync(database,flags)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
smdbm_cursor_close(cursor)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
smdbm_cursor_del(cursor,flags)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
smdbm_cursor_get(cursor,key,value,flags)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
smdbm_cursor_put(cursor,key,value,flags)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
smdbm_cursor(database,cursor,flags)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
smdb_ndbm_open(database,db_name,mode,mode_mask,sff,type,user_info,db_params)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