11573Srgrimes/**************************************************************************** 21573Srgrimes * Copyright (c) 2006 Free Software Foundation, Inc. * 31573Srgrimes * * 41573Srgrimes * Permission is hereby granted, free of charge, to any person obtaining a * 51573Srgrimes * copy of this software and associated documentation files (the * 61573Srgrimes * "Software"), to deal in the Software without restriction, including * 71573Srgrimes * without limitation the rights to use, copy, modify, merge, publish, * 81573Srgrimes * distribute, distribute with modifications, sublicense, and/or sell * 91573Srgrimes * copies of the Software, and to permit persons to whom the Software is * 101573Srgrimes * furnished to do so, subject to the following conditions: * 111573Srgrimes * * 121573Srgrimes * The above copyright notice and this permission notice shall be included * 131573Srgrimes * in all copies or substantial portions of the Software. * 141573Srgrimes * * 151573Srgrimes * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 161573Srgrimes * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 171573Srgrimes * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 181573Srgrimes * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 191573Srgrimes * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 201573Srgrimes * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 211573Srgrimes * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 221573Srgrimes * * 231573Srgrimes * Except as contained in this notice, the name(s) of the above copyright * 241573Srgrimes * holders shall not be used in advertising or otherwise to promote the * 251573Srgrimes * sale, use or other dealings in this Software without prior written * 261573Srgrimes * authorization. * 271573Srgrimes ****************************************************************************/ 281573Srgrimes 291573Srgrimes/**************************************************************************** 301573Srgrimes * Author: Thomas E. Dickey 2006 * 311573Srgrimes ****************************************************************************/ 321573Srgrimes 3392986Sobrien#include <curses.priv.h> 3492986Sobrien#include <tic.h> 351573Srgrimes#include <hashed_db.h> 361573Srgrimes 371573Srgrimes#if USE_HASHED_DB 381573Srgrimes 391573SrgrimesMODULE_ID("$Id: hashed_db.c,v 1.13 2006/08/19 19:48:38 tom Exp $") 401573Srgrimes 411573Srgrimes#if HASHED_DB_API >= 2 421573Srgrimesstatic DBC *cursor; 431573Srgrimes#endif 4411659Sphk 451573Srgrimes/* 46204170Sed * Open the database. 47204170Sed */ 48111010SnectarNCURSES_EXPORT(DB *) 491573Srgrimes_nc_db_open(const char *path, bool modify) 50204170Sed{ 51204170Sed DB *result = 0; 521573Srgrimes 531573Srgrimes#if HASHED_DB_API >= 4 541573Srgrimes db_create(&result, NULL, 0); 551573Srgrimes result->open(result, 561573Srgrimes NULL, 571573Srgrimes path, 581573Srgrimes NULL, 591573Srgrimes DB_HASH, 601573Srgrimes modify ? DB_CREATE : DB_RDONLY, 611573Srgrimes 0644); 621573Srgrimes#elif HASHED_DB_API >= 3 631573Srgrimes db_create(&result, NULL, 0); 641573Srgrimes result->open(result, 651573Srgrimes path, 661573Srgrimes NULL, 6742353Sdes DB_HASH, 6842353Sdes modify ? DB_CREATE : DB_RDONLY, 6942353Sdes 0644); 7042353Sdes#elif HASHED_DB_API >= 2 711573Srgrimes int code; 721573Srgrimes 731573Srgrimes if ((code = db_open(path, 741573Srgrimes DB_HASH, 751573Srgrimes modify ? DB_CREATE : DB_RDONLY, 761573Srgrimes 0644, 7742353Sdes (DB_ENV *) 0, 7842353Sdes (DB_INFO *) 0, 7942353Sdes &result)) != 0) { 8042353Sdes T(("cannot open %s: %s", path, strerror(code))); 811573Srgrimes result = 0; 821573Srgrimes } else { 831573Srgrimes T(("opened %s", path)); 841573Srgrimes } 851573Srgrimes#else 861573Srgrimes result = dbopen(path, 871573Srgrimes modify ? (O_CREAT | O_RDWR) : O_RDONLY, 881573Srgrimes 0644, 891573Srgrimes DB_HASH, 901573Srgrimes NULL); 911573Srgrimes if (result != 0) { 921573Srgrimes T(("opened %s", path)); 931573Srgrimes } 941573Srgrimes#endif 951573Srgrimes return result; 961573Srgrimes} 971573Srgrimes 981573Srgrimes/* 991573Srgrimes * Close the database. Do not attempt to use the 'db' handle after this call. 1001573Srgrimes */ 1011573SrgrimesNCURSES_EXPORT(int) 1021573Srgrimes_nc_db_close(DB * db) 1031573Srgrimes{ 1041573Srgrimes int result; 1051573Srgrimes 1061573Srgrimes#if HASHED_DB_API >= 2 1071573Srgrimes result = db->close(db, 0); 1081573Srgrimes#else 1091573Srgrimes result = db->close(db); 1101573Srgrimes#endif 1111573Srgrimes return result; 1121573Srgrimes} 1131573Srgrimes 1141573Srgrimes/* 1151573Srgrimes * Write a record to the database. 1161573Srgrimes * 1171573Srgrimes * Returns 0 on success. 1181573Srgrimes * 1191573Srgrimes * FIXME: the FreeBSD cap_mkdb program assumes the database could have 1201573Srgrimes * duplicates. There appears to be no good reason for that (review/fix). 1211573Srgrimes */ 1221573SrgrimesNCURSES_EXPORT(int) 1231573Srgrimes_nc_db_put(DB * db, DBT * key, DBT * data) 1241573Srgrimes{ 1251573Srgrimes int result; 1261573Srgrimes#if HASHED_DB_API >= 2 1271573Srgrimes /* remove any pre-existing value, since we do not want duplicates */ 1281573Srgrimes (void) db->del(db, NULL, key, 0); 1291573Srgrimes result = db->put(db, NULL, key, data, DB_NOOVERWRITE); 1301573Srgrimes#else 1311573Srgrimes result = db->put(db, key, data, R_NOOVERWRITE); 1321573Srgrimes#endif 1331573Srgrimes return result; 1341573Srgrimes} 1351573Srgrimes 1361573Srgrimes/* 1371573Srgrimes * Read a record from the database. 1381573Srgrimes * 1391573Srgrimes * Returns 0 on success. 1401573Srgrimes */ 1411573SrgrimesNCURSES_EXPORT(int) 1421573Srgrimes_nc_db_get(DB * db, DBT * key, DBT * data) 1431573Srgrimes{ 1441573Srgrimes int result; 1451573Srgrimes 1461573Srgrimes memset(data, 0, sizeof(*data)); 1471573Srgrimes#if HASHED_DB_API >= 2 1481573Srgrimes result = db->get(db, NULL, key, data, 0); 1491573Srgrimes#else 1501573Srgrimes result = db->get(db, key, data, 0); 1511573Srgrimes#endif 1521573Srgrimes return result; 1531573Srgrimes} 1541573Srgrimes 1551573Srgrimes/* 1561573Srgrimes * Read the first record from the database, ignoring order. 1571573Srgrimes * 1581573Srgrimes * Returns 0 on success. 1591573Srgrimes */ 1601573SrgrimesNCURSES_EXPORT(int) 1611573Srgrimes_nc_db_first(DB * db, DBT * key, DBT * data) 1621573Srgrimes{ 1631573Srgrimes int result; 1641573Srgrimes 1651573Srgrimes memset(key, 0, sizeof(*key)); 1661573Srgrimes memset(data, 0, sizeof(*data)); 1671573Srgrimes#if HASHED_DB_API >= 2 1681573Srgrimes if ((result = db->cursor(db, NULL, &cursor, 0)) == 0) { 1691573Srgrimes result = cursor->c_get(cursor, key, data, DB_FIRST); 1701573Srgrimes } 1711573Srgrimes#else 1721573Srgrimes result = db->seq(db, key, data, 0); 1731573Srgrimes#endif 1741573Srgrimes return result; 1751573Srgrimes} 1761573Srgrimes 1771573Srgrimes/* 1781573Srgrimes * Read the next record from the database, ignoring order. 1791573Srgrimes * 1801573Srgrimes * 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