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