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