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