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 39 MODULE_ID("$Id: hashed_db.c,v 1.13 2006/08/19 19:48:38 tom Exp $") 40 41 #if HASHED_DB_API >= 2 42 static DBC *cursor; 43 #endif 44 45 /* 46 * Open the database. 47 */ 48 NCURSES_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 */ 101 NCURSES_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 */ 122 NCURSES_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 */ 141 NCURSES_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 */ 160 NCURSES_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 */ 182 NCURSES_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 */ 204 NCURSES_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 */ 227 NCURSES_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 251 extern 252 NCURSES_EXPORT(void) 253 _nc_hashed_db(void); 254 255 NCURSES_EXPORT(void) 256 _nc_hashed_db(void) 257 { 258 } 259 260 #endif /* USE_HASHED_DB */ 261