xref: /illumos-gate/usr/src/lib/krb5/plugins/kdb/db2/libdb2/hash/dbm.c (revision bea83d026ee1bd1b2a2419e1d0232f107a5d7d9b)
1 /*
2  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 #pragma ident	"%Z%%M%	%I%	%E% SMI"
7 
8 /*-
9  * Copyright (c) 1990, 1993
10  *	The Regents of the University of California.  All rights reserved.
11  *
12  * This code is derived from software contributed to Berkeley by
13  * Margo Seltzer.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  * 3. All advertising materials mentioning features or use of this software
24  *    must display the following acknowledgement:
25  *	This product includes software developed by the University of
26  *	California, Berkeley and its contributors.
27  * 4. Neither the name of the University nor the names of its contributors
28  *    may be used to endorse or promote products derived from this software
29  *    without specific prior written permission.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
32  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
35  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41  * SUCH DAMAGE.
42  */
43 
44 #if defined(LIBC_SCCS) && !defined(lint)
45 static char sccsid[] = "@(#)dbm.c	8.6 (Berkeley) 11/7/95";
46 #endif /* LIBC_SCCS and not lint */
47 
48 #include "db-int.h"
49 
50 #include <sys/param.h>
51 
52 #include <fcntl.h>
53 #include <stdio.h>
54 #include <string.h>
55 #include <libintl.h>
56 #include "db-ndbm.h"
57 #include "hash.h"
58 
59 /* If the two size fields of datum and DBMT are not equal, then
60  * casting between structures will result in stack garbage being
61  * transfered. Has been observed for DEC Alpha OSF, but will handle
62  *  the general case.
63  */
64 
65 #define NEED_COPY
66 
67 /*
68  *
69  * This package provides dbm and ndbm compatible interfaces to DB.
70  * First are the DBM routines, which call the NDBM routines, and
71  * the NDBM routines, which call the DB routines.
72  */
73 static DBM *__cur_db;
74 
75 static void no_open_db __P((void));
76 
77 int
78 kdb2_dbminit(file)
79 	char *file;
80 {
81 	if (__cur_db != NULL)
82 		(void)kdb2_dbm_close(__cur_db);
83 	if ((__cur_db = kdb2_dbm_open(file, O_RDWR|O_BINARY, 0)) != NULL)
84 		return (0);
85 	if ((__cur_db = kdb2_dbm_open(file, O_RDONLY|O_BINARY, 0)) != NULL)
86 		return (0);
87 	return (-1);
88 }
89 
90 datum
91 kdb2_fetch(key)
92 	datum key;
93 {
94 	datum item;
95 
96 	if (__cur_db == NULL) {
97 		no_open_db();
98 		item.dptr = 0;
99 		return (item);
100 	}
101 	return (kdb2_dbm_fetch(__cur_db, key));
102 }
103 
104 datum
105 kdb2_firstkey()
106 {
107 	datum item;
108 
109 	if (__cur_db == NULL) {
110 		no_open_db();
111 		item.dptr = 0;
112 		return (item);
113 	}
114 	return (kdb2_dbm_firstkey(__cur_db));
115 }
116 
117 datum
118 kdb2_nextkey(key)
119 	datum key;
120 {
121 	datum item;
122 
123 	if (__cur_db == NULL) {
124 		no_open_db();
125 		item.dptr = 0;
126 		return (item);
127 	}
128 	return (kdb2_dbm_nextkey(__cur_db));
129 }
130 
131 int
132 kdb2_delete(key)
133 	datum key;
134 {
135 	if (__cur_db == NULL) {
136 		no_open_db();
137 		return (-1);
138 	}
139 	return (kdb2_dbm_delete(__cur_db, key));
140 }
141 
142 int
143 kdb2_store(key, dat)
144 	datum key, dat;
145 {
146 	if (__cur_db == NULL) {
147 		no_open_db();
148 		return (-1);
149 	}
150 	return (kdb2_dbm_store(__cur_db, key, dat, DBM_REPLACE));
151 }
152 
153 static void
154 no_open_db()
155 {
156 	(void)fprintf(stderr, dgettext(TEXT_DOMAIN,
157 			"dbm: no open database.\n"));
158 }
159 
160 /*
161  * Returns:
162  * 	*DBM on success
163  *	 NULL on failure
164  */
165 DBM *
166 kdb2_dbm_open(file, flags, mode)
167 	const char *file;
168 	int flags, mode;
169 {
170 	HASHINFO info;
171 	char path[MAXPATHLEN];
172 
173 	info.bsize = 4096;
174 	info.ffactor = 40;
175 	info.nelem = 1;
176 	info.cachesize = 0;
177 	info.hash = NULL;
178 	info.lorder = 0;
179 	(void)strncpy(path, file, sizeof(path) - 1);
180 	path[sizeof(path) - 1] = '\0';
181 	(void)strncat(path, DBM_SUFFIX, sizeof(path) - 1 - strlen(path));
182 	return ((DBM *)__hash_open(path, flags, mode, &info, 0));
183 }
184 
185 /*
186  * Returns:
187  *	Nothing.
188  */
189 void
190 kdb2_dbm_close(db)
191 	DBM *db;
192 {
193 	(void)(db->close)(db);
194 }
195 
196 /*
197  * Returns:
198  *	DATUM on success
199  *	NULL on failure
200  */
201 datum
202 kdb2_dbm_fetch(db, key)
203 	DBM *db;
204 	datum key;
205 {
206 	datum retval;
207 	int status;
208 
209 #ifdef NEED_COPY
210 	DBT k, r;
211 
212 	k.data = key.dptr;
213 	k.size = key.dsize;
214 	status = (db->get)(db, &k, &r, 0);
215 	retval.dptr = r.data;
216 	retval.dsize = r.size;
217 #else
218 	status = (db->get)(db, (DBT *)&key, (DBT *)&retval, 0);
219 #endif
220 	if (status) {
221 		retval.dptr = NULL;
222 		retval.dsize = 0;
223 	}
224 	return (retval);
225 }
226 
227 /*
228  * Returns:
229  *	DATUM on success
230  *	NULL on failure
231  */
232 datum
233 kdb2_dbm_firstkey(db)
234 	DBM *db;
235 {
236 	int status;
237 	datum retkey;
238 
239 #ifdef NEED_COPY
240 	DBT k, r;
241 
242 	status = (db->seq)(db, &k, &r, R_FIRST);
243 	retkey.dptr = k.data;
244 	retkey.dsize = k.size;
245 #else
246 	datum retdata;
247 
248 	status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST);
249 #endif
250 	if (status)
251 		retkey.dptr = NULL;
252 	return (retkey);
253 }
254 
255 /*
256  * Returns:
257  *	DATUM on success
258  *	NULL on failure
259  */
260 datum
261 kdb2_dbm_nextkey(db)
262 	DBM *db;
263 {
264 	int status;
265 	datum retkey;
266 
267 #ifdef NEED_COPY
268 	DBT k, r;
269 
270 	status = (db->seq)(db, &k, &r, R_NEXT);
271 	retkey.dptr = k.data;
272 	retkey.dsize = k.size;
273 #else
274 	datum retdata;
275 
276 	status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT);
277 #endif
278 	if (status)
279 		retkey.dptr = NULL;
280 	return (retkey);
281 }
282 
283 /*
284  * Returns:
285  *	 0 on success
286  *	<0 failure
287  */
288 int
289 kdb2_dbm_delete(db, key)
290 	DBM *db;
291 	datum key;
292 {
293 	int status;
294 
295 #ifdef NEED_COPY
296 	DBT k;
297 
298 	k.data = key.dptr;
299 	k.size = key.dsize;
300 	status = (db->del)(db, &k, 0);
301 #else
302 	status = (db->del)(db, (DBT *)&key, 0);
303 #endif
304 	if (status)
305 		return (-1);
306 	else
307 		return (0);
308 }
309 
310 /*
311  * Returns:
312  *	 0 on success
313  *	<0 failure
314  *	 1 if DBM_INSERT and entry exists
315  */
316 int
317 kdb2_dbm_store(db, key, content, flags)
318 	DBM *db;
319 	datum key, content;
320 	int flags;
321 {
322 #ifdef NEED_COPY
323 	DBT k, c;
324 
325 	k.data = key.dptr;
326 	k.size = key.dsize;
327 	c.data = content.dptr;
328 	c.size = content.dsize;
329 	return ((db->put)(db, &k, &c,
330 	    (flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
331 #else
332 	return ((db->put)(db, (DBT *)&key, (DBT *)&content,
333 	    (flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
334 #endif
335 }
336 
337 int
338 kdb2_dbm_error(db)
339 	DBM *db;
340 {
341 	HTAB *hp;
342 
343 	hp = (HTAB *)db->internal;
344 	return (hp->local_errno);
345 }
346 
347 int
348 kdb2_dbm_clearerr(db)
349 	DBM *db;
350 {
351 	HTAB *hp;
352 
353 	hp = (HTAB *)db->internal;
354 	hp->local_errno = 0;
355 	return (0);
356 }
357 
358 int
359 kdb2_dbm_dirfno(db)
360 	DBM *db;
361 {
362 	return(((HTAB *)db->internal)->fp);
363 }
364