1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1996-2009 Oracle. All rights reserved. 5 */ 6/* 7 * Copyright (c) 1990, 1993 8 * Margo Seltzer. All rights reserved. 9 */ 10/* 11 * Copyright (c) 1990, 1993 12 * The Regents of the University of California. All rights reserved. 13 * 14 * This code is derived from software contributed to Berkeley by 15 * Margo Seltzer. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions 19 * are met: 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution. 25 * 3. Neither the name of the University nor the names of its contributors 26 * may be used to endorse or promote products derived from this software 27 * without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * $Id$ 42 */ 43 44#define DB_DBM_HSEARCH 1 45#include "db_config.h" 46 47#include "db_int.h" 48 49static DB *dbp; 50static ENTRY retval; 51 52/* 53 * Translate HSEARCH calls into DB calls so that DB doesn't step on the 54 * application's name space. 55 * 56 * EXTERN: #if DB_DBM_HSEARCH != 0 57 * 58 * EXTERN: int __db_hcreate __P((size_t)); 59 * EXTERN: ENTRY *__db_hsearch __P((ENTRY, ACTION)); 60 * EXTERN: void __db_hdestroy __P((void)); 61 * 62 * EXTERN: #endif 63 */ 64int 65__db_hcreate(nel) 66 size_t nel; 67{ 68 int ret; 69 70 if ((ret = db_create(&dbp, NULL, 0)) != 0) { 71 __os_set_errno(ret); 72 return (1); 73 } 74 75 if ((ret = dbp->set_pagesize(dbp, 512)) != 0 || 76 (ret = dbp->set_h_ffactor(dbp, 16)) != 0 || 77 (ret = dbp->set_h_nelem(dbp, (u_int32_t)nel)) != 0 || 78 (ret = dbp->open(dbp, NULL, 79 NULL, NULL, DB_HASH, DB_CREATE, DB_MODE_600)) != 0) 80 __os_set_errno(ret); 81 82 /* 83 * !!! 84 * Hsearch returns 0 on error, not 1. 85 */ 86 return (ret == 0 ? 1 : 0); 87} 88 89ENTRY * 90__db_hsearch(item, action) 91 ENTRY item; 92 ACTION action; 93{ 94 DBT key, val; 95 int ret; 96 97 if (dbp == NULL) { 98 __os_set_errno(EINVAL); 99 return (NULL); 100 } 101 DB_INIT_DBT(key, item.key, strlen(item.key) + 1); 102 memset(&val, 0, sizeof(val)); 103 104 switch (action) { 105 case ENTER: 106 DB_SET_DBT(val, item.data, strlen(item.data) + 1); 107 108 /* 109 * Try and add the key to the database. If we fail because 110 * the key already exists, return the existing key. 111 */ 112 if ((ret = 113 dbp->put(dbp, NULL, &key, &val, DB_NOOVERWRITE)) == 0) 114 break; 115 if (ret == DB_KEYEXIST && 116 (ret = dbp->get(dbp, NULL, &key, &val, 0)) == 0) 117 break; 118 /* 119 * The only possible DB error is DB_NOTFOUND, and it can't 120 * happen. Check for a DB error, and lie if we find one. 121 */ 122 __os_set_errno(ret > 0 ? ret : EINVAL); 123 return (NULL); 124 case FIND: 125 if ((ret = dbp->get(dbp, NULL, &key, &val, 0)) != 0) { 126 if (ret != DB_NOTFOUND) 127 __os_set_errno(ret); 128 return (NULL); 129 } 130 item.data = (char *)val.data; 131 break; 132 default: 133 __os_set_errno(EINVAL); 134 return (NULL); 135 } 136 retval.key = item.key; 137 retval.data = item.data; 138 return (&retval); 139} 140 141void 142__db_hdestroy() 143{ 144 if (dbp != NULL) { 145 (void)dbp->close(dbp, 0); 146 dbp = NULL; 147 } 148} 149