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 *
dbm_open(const char * file,int flags,mode_t mode)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
dbm_close(DBM * db)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
dbm_fetch(DBM * db,datum key)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
dbm_firstkey(DBM * db)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
dbm_nextkey(DBM * db)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
dbm_delete(DBM * db,datum key)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
dbm_store(DBM * db,datum key,datum data,int flags)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
dbm_error(DBM * db)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
dbm_clearerr(DBM * db)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
dbm_dirfno(DBM * db)244 dbm_dirfno(DBM *db)
245 {
246 return(((HTAB *)db->internal)->fp);
247 }
248