-/*
- * Process the list of :-separated directories, looking for the terminal type.
- * We don't use strtok because it does not show us empty tokens.
- */
-static int
-_nc_read_terminfo_dirs(const char *dirs, char *const filename, const char *const
- ttn, TERMTYPE * const tp)
-{
- char *list, *a;
- const char *b;
- int code = 0;
-
- /* we'll modify the argument, so we must copy */
- if ((b = a = list = strdup(dirs)) == NULL)
- return (0);
-
- for (;;) {
- int c = *a;
- if (c == 0 || c == NCURSES_PATHSEP) {
- *a = 0;
- if ((b + 1) >= a)
- b = TERMINFO;
- if (_nc_read_tic_entry(filename, b, ttn, tp) == 1) {
- code = 1;
- break;
+ if (need <= limit) {
+ (void) sprintf(filename, "%s/" LEAF_FMT "/%s", path, *name, name);
+ result = _nc_read_file_entry(filename, tp);
+ }
+ }
+#if USE_HASHED_DB
+ else {
+ static const char suffix[] = DBM_SUFFIX;
+ DB *capdbp;
+ unsigned lens = sizeof(suffix) - 1;
+ unsigned size = strlen(path);
+ unsigned need = lens + size;
+
+ if (need <= limit) {
+ if (size >= lens
+ && !strcmp(path + size - lens, suffix))
+ (void) strcpy(filename, path);
+ else
+ (void) sprintf(filename, "%s%s", path, suffix);
+
+ /*
+ * It would be nice to optimize the dbopen/close activity, as
+ * done in the cgetent implementation for tc= clauses. However,
+ * since we support multiple database locations, we cannot do
+ * that.
+ */
+ if ((capdbp = _nc_db_open(filename, FALSE)) != 0) {
+ DBT key, data;
+ int reccnt = 0;
+ char *save = strdup(name);
+
+ memset(&key, 0, sizeof(key));
+ key.data = save;
+ key.size = strlen(save);
+
+ /*
+ * This lookup could return termcap data, which we do not want.
+ * We are looking for compiled (binary) terminfo data.
+ *
+ * cgetent uses a two-level lookup. On the first it uses the
+ * given name to return a record containing only the aliases
+ * for an entry. On the second (using that list of aliases as
+ * a key), it returns the content of the terminal description.
+ * We expect second lookup to return data beginning with the
+ * same set of aliases.
+ *
+ * For compiled terminfo, the list of aliases in the second
+ * case will be null-terminated. A termcap entry will not be,
+ * and will run on into the description. So we can easily
+ * distinguish between the two (source/binary) by checking the
+ * lengths.
+ */
+ while (_nc_db_get(capdbp, &key, &data) == 0) {
+ int used = data.size - 1;
+ char *have = (char *) data.data;
+
+ if (*have++ == 0) {
+ if (data.size > key.size
+ && IS_TIC_MAGIC(have)) {
+ result = _nc_read_termtype(tp, have, used);
+ if (result == TGETENT_NO) {
+ _nc_free_termtype(tp);
+ }
+ }
+ break;
+ }
+
+ /*
+ * Just in case we have a corrupt database, do not waste
+ * time with it.
+ */
+ if (++reccnt >= 3)
+ break;
+
+ /*
+ * Prepare for the second level.
+ */
+ key.data = have;
+ key.size = used;
+ }
+
+ _nc_db_close(capdbp);
+ free(save);