xref: /dragonfly/lib/libc/db/hash/ndbm.c (revision 8f2ce533)
1 /*-
2  * Copyright (c) 1990, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Margo Seltzer.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * @(#)ndbm.c	8.4 (Berkeley) 7/21/94
33  * $FreeBSD: head/lib/libc/db/hash/ndbm.c 165903 2007-01-09 00:28:16Z imp $
34  */
35 
36 /*
37  * This package provides a dbm compatible interface to the new hashing
38  * package described in db(3).
39  */
40 
41 #include "namespace.h"
42 #include <sys/param.h>
43 
44 #include <stdio.h>
45 #include <string.h>
46 #include <errno.h>
47 #include <pthread.h>
48 
49 #include <ndbm.h>
50 #include "hash.h"
51 
52 /*
53  * Returns:
54  * 	*DBM on success
55  *	 NULL on failure
56  */
57 DBM *
58 dbm_open(const char *file, int flags, mode_t mode)
59 {
60 	HASHINFO info;
61 	char path[MAXPATHLEN];
62 	DBM *db;
63 
64 	info.bsize = 4096;
65 	info.ffactor = 40;
66 	info.nelem = 1;
67 	info.cachesize = 0;
68 	info.hash = NULL;
69 	info.lorder = 0;
70 
71 	if( strlen(file) >= sizeof(path) - strlen(DBM_SUFFIX)) {
72 		errno = ENAMETOOLONG;
73 		return(NULL);
74 	}
75 	strcpy(path, file);
76 	strcat(path, DBM_SUFFIX);
77 	db = ((DBM *)__hash_open(path, flags, mode, &info, 0));
78 	if (db)
79 		pthread_mutex_init((void *)&db->mutex, NULL);
80 
81 	return db;
82 }
83 
84 void
85 dbm_close(DBM *db)
86 {
87 	if (db)
88 		pthread_mutex_destroy((void *)&db->mutex);
89 	(db->close)(db);
90 }
91 
92 /*
93  * Returns:
94  *	DATUM on success
95  *	NULL on failure
96  */
97 datum
98 dbm_fetch(DBM *db, datum key)
99 {
100 	datum retdata;
101 	int status;
102 	DBT dbtkey, dbtretdata;
103 
104 	pthread_mutex_lock((void *)&db->mutex);
105 	dbtkey.data = key.dptr;
106 	dbtkey.size = key.dsize;
107 	status = (db->get)(db, &dbtkey, &dbtretdata, 0);
108 	if (status) {
109 		dbtretdata.data = NULL;
110 		dbtretdata.size = 0;
111 	}
112 	retdata.dptr = dbtretdata.data;
113 	retdata.dsize = dbtretdata.size;
114 	pthread_mutex_unlock((void *)&db->mutex);
115 
116 	return (retdata);
117 }
118 
119 /*
120  * Returns:
121  *	DATUM on success
122  *	NULL on failure
123  */
124 datum
125 dbm_firstkey(DBM *db)
126 {
127 	int status;
128 	datum retkey;
129 	DBT dbtretkey, dbtretdata;
130 
131 	pthread_mutex_lock((void *)&db->mutex);
132 	status = (db->seq)(db, &dbtretkey, &dbtretdata, R_FIRST);
133 	if (status)
134 		dbtretkey.data = NULL;
135 	retkey.dptr = dbtretkey.data;
136 	retkey.dsize = dbtretkey.size;
137 	pthread_mutex_unlock((void *)&db->mutex);
138 
139 	return (retkey);
140 }
141 
142 /*
143  * Returns:
144  *	DATUM on success
145  *	NULL on failure
146  */
147 datum
148 dbm_nextkey(DBM *db)
149 {
150 	int status;
151 	datum retkey;
152 	DBT dbtretkey, dbtretdata;
153 
154 	pthread_mutex_lock((void *)&db->mutex);
155 	status = (db->seq)(db, &dbtretkey, &dbtretdata, R_NEXT);
156 	if (status)
157 		dbtretkey.data = NULL;
158 	retkey.dptr = dbtretkey.data;
159 	retkey.dsize = dbtretkey.size;
160 	pthread_mutex_unlock((void *)&db->mutex);
161 
162 	return (retkey);
163 }
164 
165 /*
166  * Returns:
167  *	 0 on success
168  *	<0 failure
169  */
170 int
171 dbm_delete(DBM *db, datum key)
172 {
173 	int status;
174 	DBT dbtkey;
175 
176 	pthread_mutex_lock((void *)&db->mutex);
177 	dbtkey.data = key.dptr;
178 	dbtkey.size = key.dsize;
179 	sigblockall();
180 	status = (db->del)(db, &dbtkey, 0);
181 	sigunblockall();
182 	pthread_mutex_unlock((void *)&db->mutex);
183 
184 	if (status)
185 		return (-1);
186 	else
187 		return (0);
188 }
189 
190 /*
191  * Returns:
192  *	 0 on success
193  *	<0 failure
194  *	 1 if DBM_INSERT and entry exists
195  */
196 int
197 dbm_store(DBM *db, datum key, datum data, int flags)
198 {
199 	DBT dbtkey, dbtdata;
200 	int status;
201 
202 	pthread_mutex_lock((void *)&db->mutex);
203 	dbtkey.data = key.dptr;
204 	dbtkey.size = key.dsize;
205 	dbtdata.data = data.dptr;
206 	dbtdata.size = data.dsize;
207 	sigblockall();
208 	status = ((db->put)(db, &dbtkey, &dbtdata,
209 			    (flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
210 	sigunblockall();
211 	pthread_mutex_unlock((void *)&db->mutex);
212 
213 	return status;
214 }
215 
216 /*
217  * XXX not thread safe
218  */
219 int
220 dbm_error(DBM *db)
221 {
222 	HTAB *hp;
223 
224 	hp = (HTAB *)db->internal;
225 
226 	return (hp->error);
227 }
228 
229 /*
230  * XXX not thread safe
231  */
232 int
233 dbm_clearerr(DBM *db)
234 {
235 	HTAB *hp;
236 
237 	hp = (HTAB *)db->internal;
238 	hp->error = 0;
239 
240 	return (0);
241 }
242 
243 int
244 dbm_dirfno(DBM *db)
245 {
246 	return(((HTAB *)db->internal)->fp);
247 }
248