hashed_db.c revision 166125
1/**************************************************************************** 2 * Copyright (c) 2006 Free Software Foundation, Inc. * 3 * * 4 * Permission is hereby granted, free of charge, to any person obtaining a * 5 * copy of this software and associated documentation files (the * 6 * "Software"), to deal in the Software without restriction, including * 7 * without limitation the rights to use, copy, modify, merge, publish, * 8 * distribute, distribute with modifications, sublicense, and/or sell * 9 * copies of the Software, and to permit persons to whom the Software is * 10 * furnished to do so, subject to the following conditions: * 11 * * 12 * The above copyright notice and this permission notice shall be included * 13 * in all copies or substantial portions of the Software. * 14 * * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 22 * * 23 * Except as contained in this notice, the name(s) of the above copyright * 24 * holders shall not be used in advertising or otherwise to promote the * 25 * sale, use or other dealings in this Software without prior written * 26 * authorization. * 27 ****************************************************************************/ 28 29/**************************************************************************** 30 * Author: Thomas E. Dickey 2006 * 31 ****************************************************************************/ 32 33#include <curses.priv.h> 34#include <tic.h> 35#include <hashed_db.h> 36 37#if USE_HASHED_DB 38 39MODULE_ID("$Id: hashed_db.c,v 1.13 2006/08/19 19:48:38 tom Exp $") 40 41#if HASHED_DB_API >= 2 42static DBC *cursor; 43#endif 44 45/* 46 * Open the database. 47 */ 48NCURSES_EXPORT(DB *) 49_nc_db_open(const char *path, bool modify) 50{ 51 DB *result = 0; 52 53#if HASHED_DB_API >= 4 54 db_create(&result, NULL, 0); 55 result->open(result, 56 NULL, 57 path, 58 NULL, 59 DB_HASH, 60 modify ? DB_CREATE : DB_RDONLY, 61 0644); 62#elif HASHED_DB_API >= 3 63 db_create(&result, NULL, 0); 64 result->open(result, 65 path, 66 NULL, 67 DB_HASH, 68 modify ? DB_CREATE : DB_RDONLY, 69 0644); 70#elif HASHED_DB_API >= 2 71 int code; 72 73 if ((code = db_open(path, 74 DB_HASH, 75 modify ? DB_CREATE : DB_RDONLY, 76 0644, 77 (DB_ENV *) 0, 78 (DB_INFO *) 0, 79 &result)) != 0) { 80 T(("cannot open %s: %s", path, strerror(code))); 81 result = 0; 82 } else { 83 T(("opened %s", path)); 84 } 85#else 86 result = dbopen(path, 87 modify ? (O_CREAT | O_RDWR) : O_RDONLY, 88 0644, 89 DB_HASH, 90 NULL); 91 if (result != 0) { 92 T(("opened %s", path)); 93 } 94#endif 95 return result; 96} 97 98/* 99 * Close the database. Do not attempt to use the 'db' handle after this call. 100 */ 101NCURSES_EXPORT(int) 102_nc_db_close(DB * db) 103{ 104 int result; 105 106#if HASHED_DB_API >= 2 107 result = db->close(db, 0); 108#else 109 result = db->close(db); 110#endif 111 return result; 112} 113 114/* 115 * Write a record to the database. 116 * 117 * Returns 0 on success. 118 * 119 * FIXME: the FreeBSD cap_mkdb program assumes the database could have 120 * duplicates. There appears to be no good reason for that (review/fix). 121 */ 122NCURSES_EXPORT(int) 123_nc_db_put(DB * db, DBT * key, DBT * data) 124{ 125 int result; 126#if HASHED_DB_API >= 2 127 /* remove any pre-existing value, since we do not want duplicates */ 128 (void) db->del(db, NULL, key, 0); 129 result = db->put(db, NULL, key, data, DB_NOOVERWRITE); 130#else 131 result = db->put(db, key, data, R_NOOVERWRITE); 132#endif 133 return result; 134} 135 136/* 137 * Read a record from the database. 138 * 139 * Returns 0 on success. 140 */ 141NCURSES_EXPORT(int) 142_nc_db_get(DB * db, DBT * key, DBT * data) 143{ 144 int result; 145 146 memset(data, 0, sizeof(*data)); 147#if HASHED_DB_API >= 2 148 result = db->get(db, NULL, key, data, 0); 149#else 150 result = db->get(db, key, data, 0); 151#endif 152 return result; 153} 154 155/* 156 * Read the first record from the database, ignoring order. 157 * 158 * Returns 0 on success. 159 */ 160NCURSES_EXPORT(int) 161_nc_db_first(DB * db, DBT * key, DBT * data) 162{ 163 int result; 164 165 memset(key, 0, sizeof(*key)); 166 memset(data, 0, sizeof(*data)); 167#if HASHED_DB_API >= 2 168 if ((result = db->cursor(db, NULL, &cursor, 0)) == 0) { 169 result = cursor->c_get(cursor, key, data, DB_FIRST); 170 } 171#else 172 result = db->seq(db, key, data, 0); 173#endif 174 return result; 175} 176 177/* 178 * Read the next record from the database, ignoring order. 179 * 180 * Returns 0 on success. 181 */ 182NCURSES_EXPORT(int) 183_nc_db_next(DB * db, DBT * key, DBT * data) 184{ 185 int result; 186 187#if HASHED_DB_API >= 2 188 (void) db; 189 if (cursor != 0) { 190 result = cursor->c_get(cursor, key, data, DB_NEXT); 191 } else { 192 result = -1; 193 } 194#else 195 result = db->seq(db, key, data, 0); 196#endif 197 return result; 198} 199 200/* 201 * Check if a record is a terminfo index record. Index records are those that 202 * contain only an alias pointing to a list of aliases. 203 */ 204NCURSES_EXPORT(bool) 205_nc_db_have_index(DBT * key, DBT * data, char **buffer, int *size) 206{ 207 bool result = FALSE; 208 int used = data->size - 1; 209 char *have = (char *) data->data; 210 211 (void) key; 212 if (*have++ == 2) { 213 result = TRUE; 214 } 215 /* 216 * Update params in any case for consistency with _nc_db_have_data(). 217 */ 218 *buffer = have; 219 *size = used; 220 return result; 221} 222 223/* 224 * Check if a record is the terminfo data record. Ignore index records, e.g., 225 * those that contain only an alias pointing to a list of aliases. 226 */ 227NCURSES_EXPORT(bool) 228_nc_db_have_data(DBT * key, DBT * data, char **buffer, int *size) 229{ 230 bool result = FALSE; 231 int used = data->size - 1; 232 char *have = (char *) data->data; 233 234 if (*have++ == 0) { 235 if (data->size > key->size 236 && IS_TIC_MAGIC(have)) { 237 result = TRUE; 238 } 239 } 240 /* 241 * Update params in any case to make it simple to follow a index record 242 * to the data record. 243 */ 244 *buffer = have; 245 *size = used; 246 return result; 247} 248 249#else 250 251extern 252NCURSES_EXPORT(void) 253_nc_hashed_db(void); 254 255NCURSES_EXPORT(void) 256_nc_hashed_db(void) 257{ 258} 259 260#endif /* USE_HASHED_DB */ 261