ncurses 5.7 - patch 20090411
[ncurses.git] / ncurses / tinfo / hashed_db.c
1 /****************************************************************************
2  * Copyright (c) 2006,2008 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-on                 *
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.14 2008/12/13 20:59:02 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     int code;
53
54 #if HASHED_DB_API >= 4
55     db_create(&result, NULL, 0);
56     if ((code = result->open(result,
57                              NULL,
58                              path,
59                              NULL,
60                              DB_HASH,
61                              modify ? DB_CREATE : DB_RDONLY,
62                              0644)) != 0) {
63         result = 0;
64     }
65 #elif HASHED_DB_API >= 3
66     db_create(&result, NULL, 0);
67     if ((code = result->open(result,
68                              path,
69                              NULL,
70                              DB_HASH,
71                              modify ? DB_CREATE : DB_RDONLY,
72                              0644)) != 0) {
73         result = 0;
74     }
75 #elif HASHED_DB_API >= 2
76     if ((code = db_open(path,
77                         DB_HASH,
78                         modify ? DB_CREATE : DB_RDONLY,
79                         0644,
80                         (DB_ENV *) 0,
81                         (DB_INFO *) 0,
82                         &result)) != 0) {
83         result = 0;
84     }
85 #else
86     if ((result = dbopen(path,
87                          modify ? (O_CREAT | O_RDWR) : O_RDONLY,
88                          0644,
89                          DB_HASH,
90                          NULL)) == 0) {
91         code = errno;
92     }
93 #endif
94     if (result != 0) {
95         T(("opened %s", path));
96     } else {
97         T(("cannot open %s: %s", path, strerror(code)));
98     }
99     return result;
100 }
101
102 /*
103  * Close the database.  Do not attempt to use the 'db' handle after this call.
104  */
105 NCURSES_EXPORT(int)
106 _nc_db_close(DB * db)
107 {
108     int result;
109
110 #if HASHED_DB_API >= 2
111     result = db->close(db, 0);
112 #else
113     result = db->close(db);
114 #endif
115     return result;
116 }
117
118 /*
119  * Write a record to the database.
120  *
121  * Returns 0 on success.
122  *
123  * FIXME:  the FreeBSD cap_mkdb program assumes the database could have
124  * duplicates.  There appears to be no good reason for that (review/fix).
125  */
126 NCURSES_EXPORT(int)
127 _nc_db_put(DB * db, DBT * key, DBT * data)
128 {
129     int result;
130 #if HASHED_DB_API >= 2
131     /* remove any pre-existing value, since we do not want duplicates */
132     (void) db->del(db, NULL, key, 0);
133     result = db->put(db, NULL, key, data, DB_NOOVERWRITE);
134 #else
135     result = db->put(db, key, data, R_NOOVERWRITE);
136 #endif
137     return result;
138 }
139
140 /*
141  * Read a record from the database.
142  *
143  * Returns 0 on success.
144  */
145 NCURSES_EXPORT(int)
146 _nc_db_get(DB * db, DBT * key, DBT * data)
147 {
148     int result;
149
150     memset(data, 0, sizeof(*data));
151 #if HASHED_DB_API >= 2
152     result = db->get(db, NULL, key, data, 0);
153 #else
154     result = db->get(db, key, data, 0);
155 #endif
156     return result;
157 }
158
159 /*
160  * Read the first record from the database, ignoring order.
161  *
162  * Returns 0 on success.
163  */
164 NCURSES_EXPORT(int)
165 _nc_db_first(DB * db, DBT * key, DBT * data)
166 {
167     int result;
168
169     memset(key, 0, sizeof(*key));
170     memset(data, 0, sizeof(*data));
171 #if HASHED_DB_API >= 2
172     if ((result = db->cursor(db, NULL, &cursor, 0)) == 0) {
173         result = cursor->c_get(cursor, key, data, DB_FIRST);
174     }
175 #else
176     result = db->seq(db, key, data, 0);
177 #endif
178     return result;
179 }
180
181 /*
182  * Read the next record from the database, ignoring order.
183  *
184  * Returns 0 on success.
185  */
186 NCURSES_EXPORT(int)
187 _nc_db_next(DB * db, DBT * key, DBT * data)
188 {
189     int result;
190
191 #if HASHED_DB_API >= 2
192     (void) db;
193     if (cursor != 0) {
194         result = cursor->c_get(cursor, key, data, DB_NEXT);
195     } else {
196         result = -1;
197     }
198 #else
199     result = db->seq(db, key, data, 0);
200 #endif
201     return result;
202 }
203
204 /*
205  * Check if a record is a terminfo index record.  Index records are those that
206  * contain only an alias pointing to a list of aliases.
207  */
208 NCURSES_EXPORT(bool)
209 _nc_db_have_index(DBT * key, DBT * data, char **buffer, int *size)
210 {
211     bool result = FALSE;
212     int used = data->size - 1;
213     char *have = (char *) data->data;
214
215     (void) key;
216     if (*have++ == 2) {
217         result = TRUE;
218     }
219     /*
220      * Update params in any case for consistency with _nc_db_have_data().
221      */
222     *buffer = have;
223     *size = used;
224     return result;
225 }
226
227 /*
228  * Check if a record is the terminfo data record.  Ignore index records, e.g.,
229  * those that contain only an alias pointing to a list of aliases.
230  */
231 NCURSES_EXPORT(bool)
232 _nc_db_have_data(DBT * key, DBT * data, char **buffer, int *size)
233 {
234     bool result = FALSE;
235     int used = data->size - 1;
236     char *have = (char *) data->data;
237
238     if (*have++ == 0) {
239         if (data->size > key->size
240             && IS_TIC_MAGIC(have)) {
241             result = TRUE;
242         }
243     }
244     /*
245      * Update params in any case to make it simple to follow a index record
246      * to the data record.
247      */
248     *buffer = have;
249     *size = used;
250     return result;
251 }
252
253 #else
254
255 extern
256 NCURSES_EXPORT(void)
257 _nc_hashed_db(void);
258
259 NCURSES_EXPORT(void)
260 _nc_hashed_db(void)
261 {
262 }
263
264 #endif /* USE_HASHED_DB */