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