dbm.c revision 7934:6aeeafc994de
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) 44static 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 */ 73static DBM *__cur_db; 74 75static void no_open_db __P((void)); 76 77int 78kdb2_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 90datum 91kdb2_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 105datum 106kdb2_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 119datum 120kdb2_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 134int 135kdb2_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 145int 146kdb2_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 156static void 157no_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 */ 168DBM * 169kdb2_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 */ 192void 193kdb2_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 */ 204datum 205kdb2_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 */ 235datum 236kdb2_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 */ 263datum 264kdb2_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 */ 291int 292kdb2_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 */ 319int 320kdb2_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 340int 341kdb2_dbm_error(db) 342 DBM *db; 343{ 344 HTAB *hp; 345 346 hp = (HTAB *)db->internal; 347 return (hp->local_errno); 348} 349 350int 351kdb2_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 361int 362kdb2_dbm_dirfno(db) 363 DBM *db; 364{ 365 return(((HTAB *)db->internal)->fp); 366} 367