~ubuntu-branches/ubuntu/natty/ncurses/natty

« back to all changes in this revision

Viewing changes to ncurses/tinfo/read_entry.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-05-17 09:00:42 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20070517090042-86fgxrr6j5jzagot
Tags: 5.6-0ubuntu1
* New upstream version.
  - Remove patches applied upstream: ncurses.upstream, signed-chars.
  - Update patches: debian-backspace.
* Build-depend on g++-multilib instead of lib{32,64}c*-dev-*.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/****************************************************************************
2
 
 * Copyright (c) 1998-2004,2005 Free Software Foundation, Inc.              *
 
2
 * Copyright (c) 1998-2005,2006 Free Software Foundation, Inc.              *
3
3
 *                                                                          *
4
4
 * Permission is hereby granted, free of charge, to any person obtaining a  *
5
5
 * copy of this software and associated documentation files (the            *
34
34
 
35
35
/*
36
36
 *      read_entry.c -- Routine for reading in a compiled terminfo file
37
 
 *
38
37
 */
39
38
 
40
39
#include <curses.priv.h>
 
40
#include <hashed_db.h>
41
41
 
42
42
#include <tic.h>
43
43
#include <term_entry.h>
44
44
 
45
 
MODULE_ID("$Id: read_entry.c,v 1.81 2005/06/02 22:04:32 tom Exp $")
46
 
 
47
 
#if !HAVE_TELL
48
 
#define tell(fd) lseek(fd, 0, SEEK_CUR)         /* lseek() is POSIX, but not tell() */
49
 
#endif
 
45
MODULE_ID("$Id: read_entry.c,v 1.99 2006/08/19 15:58:50 tom Exp $")
50
46
 
51
47
#define TYPE_CALLOC(type,elts) typeCalloc(type, (unsigned)(elts))
52
48
 
53
 
/*
54
 
 *      int
55
 
 *      _nc_read_file_entry(filename, ptr)
56
 
 *
57
 
 *      Read the compiled terminfo entry in the given file into the
58
 
 *      structure pointed to by ptr, allocating space for the string
59
 
 *      table.
60
 
 */
61
 
 
62
 
#undef  BYTE
63
 
#define BYTE(p,n)       (unsigned char)((p)[n])
64
 
 
65
 
#define IS_NEG1(p)      ((BYTE(p,0) == 0377) && (BYTE(p,1) == 0377))
66
 
#define IS_NEG2(p)      ((BYTE(p,0) == 0376) && (BYTE(p,1) == 0377))
67
 
#define LOW_MSB(p)      (BYTE(p,0) + 256*BYTE(p,1))
68
 
 
69
 
static bool have_tic_directory = FALSE;
70
 
static bool keep_tic_directory = FALSE;
71
 
 
72
 
/*
73
 
 * Record the "official" location of the terminfo directory, according to
74
 
 * the place where we're writing to, or the normal default, if not.
75
 
 */
76
 
NCURSES_EXPORT(const char *)
77
 
_nc_tic_dir(const char *path)
78
 
{
79
 
    static const char *result = TERMINFO;
80
 
 
81
 
    if (!keep_tic_directory) {
82
 
        if (path != 0) {
83
 
            result = path;
84
 
            have_tic_directory = TRUE;
85
 
        } else if (!have_tic_directory && use_terminfo_vars()) {
86
 
            char *envp;
87
 
            if ((envp = getenv("TERMINFO")) != 0)
88
 
                return _nc_tic_dir(envp);
89
 
        }
90
 
    }
91
 
    return result;
92
 
}
93
 
 
94
 
/*
95
 
 * Special fix to prevent the terminfo directory from being moved after tic
96
 
 * has chdir'd to it.  If we let it be changed, then if $TERMINFO has a
97
 
 * relative path, we'll lose track of the actual directory.
98
 
 */
99
 
NCURSES_EXPORT(void)
100
 
_nc_keep_tic_dir(const char *path)
101
 
{
102
 
    _nc_tic_dir(path);
103
 
    keep_tic_directory = TRUE;
104
 
}
105
 
 
 
49
#if USE_DATABASE
106
50
static void
107
51
convert_shorts(char *buf, short *Numbers, int count)
108
52
{
148
92
    }
149
93
}
150
94
 
151
 
#define read_shorts(fd, buf, count) \
152
 
        (read(fd, buf, (unsigned) (count)*2) == (int) (count)*2)
 
95
static int
 
96
fake_read(char *src, int *offset, int limit, char *dst, unsigned want)
 
97
{
 
98
    int have = (limit - *offset);
 
99
 
 
100
    if (have > 0) {
 
101
        if ((int) want > have)
 
102
            want = have;
 
103
        memcpy(dst, src + *offset, want);
 
104
        *offset += want;
 
105
    } else {
 
106
        want = 0;
 
107
    }
 
108
    return (int) want;
 
109
}
 
110
 
 
111
#define Read(buf, count) fake_read(buffer, &offset, limit, buf, count)
 
112
 
 
113
#define read_shorts(buf, count) \
 
114
        (Read(buf, (unsigned) (count)*2) == (int) (count)*2)
153
115
 
154
116
#define even_boundary(value) \
155
 
    if ((value) % 2 != 0) read(fd, buf, 1)
 
117
    if ((value) % 2 != 0) Read(buf, 1)
156
118
 
157
 
static int
158
 
read_termtype(int fd, TERMTYPE *ptr)
 
119
NCURSES_EXPORT(int)
 
120
_nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
159
121
/* return 1 if read, 0 if not found or garbled */
160
122
{
 
123
    int offset = 0;
161
124
    int name_size, bool_count, num_count, str_count, str_size;
162
125
    int i;
163
126
    char buf[MAX_ENTRY_SIZE + 1];
 
127
    char *string_table;
164
128
    unsigned want, have;
165
129
 
166
 
    TR(TRACE_DATABASE, ("READ termtype header @%ld", (long) tell(fd)));
 
130
    TR(TRACE_DATABASE, ("READ termtype header @%d", offset));
167
131
 
168
132
    memset(ptr, 0, sizeof(*ptr));
169
133
 
170
134
    /* grab the header */
171
 
    if (!read_shorts(fd, buf, 6)
172
 
        || LOW_MSB(buf) != MAGIC) {
173
 
        return (0);
 
135
    if (!read_shorts(buf, 6)
 
136
        || !IS_TIC_MAGIC(buf)) {
 
137
        return (TGETENT_NO);
174
138
    }
175
139
 
176
140
    name_size = LOW_MSB(buf + 2);
188
152
        || num_count < 0
189
153
        || str_count < 0
190
154
        || str_size < 0) {
191
 
        return (0);
 
155
        return (TGETENT_NO);
192
156
    }
193
157
 
 
158
    want = str_size + name_size + 1;
194
159
    if (str_size) {
195
160
        /* try to allocate space for the string table */
196
161
        if (str_count * 2 >= (int) sizeof(buf)
197
 
            || (ptr->str_table = typeMalloc(char, (unsigned) str_size)) == 0) {
198
 
            return (0);
 
162
            || (string_table = typeMalloc(char, want)) == 0) {
 
163
            return (TGETENT_NO);
199
164
        }
200
165
    } else {
201
166
        str_count = 0;
 
167
        if ((string_table = typeMalloc(char, want)) == 0) {
 
168
            return (TGETENT_NO);
 
169
        }
202
170
    }
203
171
 
204
172
    /* grab the name (a null-terminated string) */
205
173
    want = min(MAX_NAME_SIZE, (unsigned) name_size);
206
 
    if ((have = read(fd, buf, want)) != want) {
207
 
        memset(buf + have, 0, want - have);
208
 
    }
209
 
    buf[want] = '\0';
210
 
    ptr->term_names = TYPE_CALLOC(char, strlen(buf) + 1);
211
 
    if (ptr->term_names == NULL) {
212
 
        return (0);
213
 
    }
214
 
    (void) strcpy(ptr->term_names, buf);
 
174
    ptr->str_table = string_table;
 
175
    ptr->term_names = string_table;
 
176
    if ((have = Read(ptr->term_names, want)) != want) {
 
177
        memset(ptr->term_names + have, 0, want - have);
 
178
    }
 
179
    ptr->term_names[want] = '\0';
 
180
    string_table += (want + 1);
 
181
 
215
182
    if (have > MAX_NAME_SIZE)
216
 
        lseek(fd, (off_t) (have - MAX_NAME_SIZE), 1);
 
183
        offset = (have - MAX_NAME_SIZE);
217
184
 
218
185
    /* grab the booleans */
219
 
    if ((ptr->Booleans = TYPE_CALLOC(char, max(BOOLCOUNT, bool_count))) == 0
220
 
        || read(fd, ptr->Booleans, (unsigned) bool_count) < bool_count) {
221
 
        return (0);
 
186
    if ((ptr->Booleans = TYPE_CALLOC(NCURSES_SBOOL,
 
187
                                     max(BOOLCOUNT, bool_count))) == 0
 
188
        || Read(ptr->Booleans, (unsigned) bool_count) < bool_count) {
 
189
        return (TGETENT_NO);
222
190
    }
223
191
 
224
192
    /*
231
199
 
232
200
    /* grab the numbers */
233
201
    if ((ptr->Numbers = TYPE_CALLOC(short, max(NUMCOUNT, num_count))) == 0
234
 
        || !read_shorts(fd, buf, num_count)) {
235
 
        return (0);
 
202
        || !read_shorts(buf, num_count)) {
 
203
        return (TGETENT_NO);
236
204
    }
237
205
    convert_shorts(buf, ptr->Numbers, num_count);
238
206
 
239
207
    if ((ptr->Strings = TYPE_CALLOC(char *, max(STRCOUNT, str_count))) == 0)
240
 
          return (0);
 
208
          return (TGETENT_NO);
241
209
 
242
210
    if (str_count) {
243
211
        /* grab the string offsets */
244
 
        if (!read_shorts(fd, buf, str_count)) {
245
 
            return (0);
 
212
        if (!read_shorts(buf, str_count)) {
 
213
            return (TGETENT_NO);
246
214
        }
247
215
        /* finally, grab the string table itself */
248
 
        if (read(fd, ptr->str_table, (unsigned) str_size) != str_size)
249
 
            return (0);
250
 
        convert_strings(buf, ptr->Strings, str_count, str_size, ptr->str_table);
 
216
        if (Read(string_table, (unsigned) str_size) != str_size)
 
217
            return (TGETENT_NO);
 
218
        convert_strings(buf, ptr->Strings, str_count, str_size, string_table);
251
219
    }
252
220
#if NCURSES_XNAMES
253
221
 
259
227
     * Read extended entries, if any, after the normal end of terminfo data.
260
228
     */
261
229
    even_boundary(str_size);
262
 
    TR(TRACE_DATABASE, ("READ extended_header @%ld", (long) tell(fd)));
263
 
    if (_nc_user_definable && read_shorts(fd, buf, 5)) {
 
230
    TR(TRACE_DATABASE, ("READ extended_header @%d", offset));
 
231
    if (_nc_user_definable && read_shorts(buf, 5)) {
264
232
        int ext_bool_count = LOW_MSB(buf + 0);
265
233
        int ext_num_count = LOW_MSB(buf + 2);
266
234
        int ext_str_count = LOW_MSB(buf + 4);
277
245
            || ext_str_count < 0
278
246
            || ext_str_size < 0
279
247
            || ext_str_limit < 0)
280
 
            return (0);
 
248
            return (TGETENT_NO);
281
249
 
282
250
        ptr->num_Booleans = BOOLCOUNT + ext_bool_count;
283
251
        ptr->num_Numbers = NUMCOUNT + ext_num_count;
284
252
        ptr->num_Strings = STRCOUNT + ext_str_count;
285
253
 
286
 
        ptr->Booleans = typeRealloc(char, ptr->num_Booleans, ptr->Booleans);
 
254
        ptr->Booleans = typeRealloc(NCURSES_SBOOL, ptr->num_Booleans, ptr->Booleans);
287
255
        ptr->Numbers = typeRealloc(short, ptr->num_Numbers, ptr->Numbers);
288
256
        ptr->Strings = typeRealloc(char *, ptr->num_Strings, ptr->Strings);
289
257
 
291
259
                            ext_bool_count, ext_num_count, ext_str_count,
292
260
                            ext_str_size, ext_str_limit));
293
261
 
294
 
        TR(TRACE_DATABASE, ("READ %d extended-booleans @%ld",
295
 
                            ext_bool_count, (long) tell(fd)));
 
262
        TR(TRACE_DATABASE, ("READ %d extended-booleans @%d",
 
263
                            ext_bool_count, offset));
296
264
        if ((ptr->ext_Booleans = ext_bool_count) != 0) {
297
 
            if (read(fd, ptr->Booleans + BOOLCOUNT, (unsigned)
 
265
            if (Read(ptr->Booleans + BOOLCOUNT, (unsigned)
298
266
                     ext_bool_count) != ext_bool_count)
299
 
                return (0);
 
267
                return (TGETENT_NO);
300
268
        }
301
269
        even_boundary(ext_bool_count);
302
270
 
303
 
        TR(TRACE_DATABASE, ("READ %d extended-numbers @%ld",
304
 
                            ext_num_count, (long) tell(fd)));
 
271
        TR(TRACE_DATABASE, ("READ %d extended-numbers @%d",
 
272
                            ext_num_count, offset));
305
273
        if ((ptr->ext_Numbers = ext_num_count) != 0) {
306
 
            if (!read_shorts(fd, buf, ext_num_count))
307
 
                return (0);
 
274
            if (!read_shorts(buf, ext_num_count))
 
275
                return (TGETENT_NO);
308
276
            TR(TRACE_DATABASE, ("Before converting extended-numbers"));
309
277
            convert_shorts(buf, ptr->Numbers + NUMCOUNT, ext_num_count);
310
278
        }
311
279
 
312
 
        TR(TRACE_DATABASE, ("READ extended-offsets @%ld", (long) tell(fd)));
 
280
        TR(TRACE_DATABASE, ("READ extended-offsets @%d", offset));
313
281
        if ((ext_str_count || need)
314
 
            && !read_shorts(fd, buf, ext_str_count + need))
315
 
            return (0);
 
282
            && !read_shorts(buf, ext_str_count + need))
 
283
            return (TGETENT_NO);
316
284
 
317
 
        TR(TRACE_DATABASE, ("READ %d bytes of extended-strings @%ld",
318
 
                            ext_str_limit, (long) tell(fd)));
 
285
        TR(TRACE_DATABASE, ("READ %d bytes of extended-strings @%d",
 
286
                            ext_str_limit, offset));
319
287
 
320
288
        if (ext_str_limit) {
321
289
            if ((ptr->ext_str_table = typeMalloc(char, ext_str_limit)) == 0)
322
 
                  return (0);
323
 
            if (read(fd, ptr->ext_str_table, (unsigned) ext_str_limit) != ext_str_limit)
324
 
                return (0);
 
290
                  return (TGETENT_NO);
 
291
            if (Read(ptr->ext_str_table, (unsigned) ext_str_limit) != ext_str_limit)
 
292
                return (TGETENT_NO);
325
293
            TR(TRACE_DATABASE, ("first extended-string is %s", _nc_visbuf(ptr->ext_str_table)));
326
294
        }
327
295
 
346
314
 
347
315
        if (need) {
348
316
            if ((ptr->ext_Names = TYPE_CALLOC(char *, need)) == 0)
349
 
                  return (0);
 
317
                  return (TGETENT_NO);
350
318
            TR(TRACE_DATABASE,
351
319
               ("ext_NAMES starting @%d in extended_strings, first = %s",
352
320
                base, _nc_visbuf(ptr->ext_str_table + base)));
379
347
    for (i = str_count; i < STRCOUNT; i++)
380
348
        ptr->Strings[i] = ABSENT_STRING;
381
349
 
382
 
    return (1);
 
350
    return (TGETENT_YES);
383
351
}
384
352
 
 
353
/*
 
354
 *      int
 
355
 *      _nc_read_file_entry(filename, ptr)
 
356
 *
 
357
 *      Read the compiled terminfo entry in the given file into the
 
358
 *      structure pointed to by ptr, allocating space for the string
 
359
 *      table.
 
360
 */
385
361
NCURSES_EXPORT(int)
386
362
_nc_read_file_entry(const char *const filename, TERMTYPE *ptr)
387
363
/* return 1 if read, 0 if not found or garbled */
388
364
{
389
365
    int code, fd = -1;
 
366
    int limit;
 
367
    char buffer[MAX_ENTRY_SIZE + 1];
390
368
 
391
369
    if (_nc_access(filename, R_OK) < 0
392
370
        || (fd = open(filename, O_RDONLY | O_BINARY)) < 0) {
393
371
        T(("cannot open terminfo %s (errno=%d)", filename, errno));
394
 
        code = 0;
 
372
        code = TGETENT_NO;
395
373
    } else {
396
 
        T(("read terminfo %s", filename));
397
 
        if ((code = read_termtype(fd, ptr)) == 0) {
398
 
            _nc_free_termtype(ptr);
 
374
        if ((limit = read(fd, buffer, sizeof(buffer))) > 0) {
 
375
 
 
376
            T(("read terminfo %s", filename));
 
377
            if ((code = _nc_read_termtype(ptr, buffer, limit)) == TGETENT_NO) {
 
378
                _nc_free_termtype(ptr);
 
379
            }
 
380
        } else {
 
381
            code = TGETENT_NO;
399
382
        }
400
383
        close(fd);
401
384
    }
404
387
}
405
388
 
406
389
/*
407
 
 * Build a terminfo pathname and try to read the data.  Returns 1 on success,
408
 
 * 0 on failure.
409
 
 */
410
 
static int
411
 
_nc_read_tic_entry(char *const filename,
412
 
                   const char *const dir, const char *ttn, TERMTYPE *const tp)
413
 
{
414
 
    int need = 2 + strlen(dir) + strlen(ttn);
415
 
 
416
 
    if (need > PATH_MAX)
417
 
        return 0;
418
 
    (void) sprintf(filename, "%s/%s", dir, ttn);
419
 
    return _nc_read_file_entry(filename, tp);
420
 
}
421
 
 
422
 
/*
423
 
 * Process the list of :-separated directories, looking for the terminal type.
424
 
 * We don't use strtok because it does not show us empty tokens.
425
 
 */
426
 
static int
427
 
_nc_read_terminfo_dirs(const char *dirs, char *const filename, const char *const
428
 
                       ttn, TERMTYPE *const tp)
429
 
{
430
 
    char *list, *a;
431
 
    const char *b;
432
 
    int code = 0;
433
 
 
434
 
    /* we'll modify the argument, so we must copy */
435
 
    if ((b = a = list = strdup(dirs)) == NULL)
436
 
        return (0);
437
 
 
438
 
    for (;;) {
439
 
        int c = *a;
440
 
        if (c == 0 || c == NCURSES_PATHSEP) {
441
 
            *a = 0;
442
 
            if ((b + 1) >= a)
443
 
                b = TERMINFO;
444
 
            if (_nc_read_tic_entry(filename, b, ttn, tp) == 1) {
445
 
                code = 1;
446
 
                break;
 
390
 * Build a terminfo pathname and try to read the data.  Returns TGETENT_YES on
 
391
 * success, TGETENT_NO on failure.
 
392
 */
 
393
static int
 
394
_nc_read_tic_entry(char *filename,
 
395
                   unsigned limit,
 
396
                   const char *const path,
 
397
                   const char *name,
 
398
                   TERMTYPE *const tp)
 
399
{
 
400
    int result = TGETENT_NO;
 
401
 
 
402
    /*
 
403
     * If we are looking in a directory, assume the entry is a file under that,
 
404
     * according to the normal rules.
 
405
     *
 
406
     * FIXME - add caseless-filename fixup.
 
407
     */
 
408
    if (_nc_is_dir_path(path)) {
 
409
        unsigned need = 4 + strlen(path) + strlen(name);
 
410
 
 
411
        if (need <= limit) {
 
412
            (void) sprintf(filename, "%s/%c/%s", path, *name, name);
 
413
            result = _nc_read_file_entry(filename, tp);
 
414
        }
 
415
    }
 
416
#if USE_HASHED_DB
 
417
    else {
 
418
        static const char suffix[] = DBM_SUFFIX;
 
419
        DB *capdbp;
 
420
        unsigned lens = sizeof(suffix) - 1;
 
421
        unsigned size = strlen(path);
 
422
        unsigned need = lens + size;
 
423
 
 
424
        if (need <= limit) {
 
425
            if (size >= lens
 
426
                && !strcmp(path + size - lens, suffix))
 
427
                (void) strcpy(filename, path);
 
428
            else
 
429
                (void) sprintf(filename, "%s%s", path, suffix);
 
430
 
 
431
            /*
 
432
             * It would be nice to optimize the dbopen/close activity, as
 
433
             * done in the cgetent implementation for tc= clauses.  However,
 
434
             * since we support multiple database locations, we cannot do
 
435
             * that.
 
436
             */
 
437
            if ((capdbp = _nc_db_open(filename, FALSE)) != 0) {
 
438
                DBT key, data;
 
439
                int reccnt = 0;
 
440
                char *save = strdup(name);
 
441
 
 
442
                memset(&key, 0, sizeof(key));
 
443
                key.data = save;
 
444
                key.size = strlen(save);
 
445
 
 
446
                /*
 
447
                 * This lookup could return termcap data, which we do not want. 
 
448
                 * We are looking for compiled (binary) terminfo data.
 
449
                 *
 
450
                 * cgetent uses a two-level lookup.  On the first it uses the
 
451
                 * given name to return a record containing only the aliases
 
452
                 * for an entry.  On the second (using that list of aliases as
 
453
                 * a key), it returns the content of the terminal description. 
 
454
                 * We expect second lookup to return data beginning with the
 
455
                 * same set of aliases.
 
456
                 *
 
457
                 * For compiled terminfo, the list of aliases in the second
 
458
                 * case will be null-terminated.  A termcap entry will not be,
 
459
                 * and will run on into the description.  So we can easily
 
460
                 * distinguish between the two (source/binary) by checking the
 
461
                 * lengths.
 
462
                 */
 
463
                while (_nc_db_get(capdbp, &key, &data) == 0) {
 
464
                    int used = data.size - 1;
 
465
                    char *have = (char *) data.data;
 
466
 
 
467
                    if (*have++ == 0) {
 
468
                        if (data.size > key.size
 
469
                            && IS_TIC_MAGIC(have)) {
 
470
                            result = _nc_read_termtype(tp, have, used);
 
471
                            if (result == TGETENT_NO) {
 
472
                                _nc_free_termtype(tp);
 
473
                            }
 
474
                        }
 
475
                        break;
 
476
                    }
 
477
 
 
478
                    /*
 
479
                     * Just in case we have a corrupt database, do not waste
 
480
                     * time with it.
 
481
                     */
 
482
                    if (++reccnt >= 3)
 
483
                        break;
 
484
 
 
485
                    /*
 
486
                     * Prepare for the second level.
 
487
                     */
 
488
                    key.data = have;
 
489
                    key.size = used;
 
490
                }
 
491
 
 
492
                _nc_db_close(capdbp);
 
493
                free(save);
447
494
            }
448
 
            b = a + 1;
449
 
            if (c == 0)
450
 
                break;
451
495
        }
452
 
        a++;
453
496
    }
454
 
 
455
 
    free(list);
456
 
    return (code);
 
497
#endif
 
498
    return result;
457
499
}
 
500
#endif /* USE_DATABASE */
458
501
 
459
502
/*
460
 
 *      _nc_read_entry(char *tn, char *filename, TERMTYPE *tp)
 
503
 *      _nc_read_entry(char *name, char *filename, TERMTYPE *tp)
461
504
 *
462
505
 *      Find and read the compiled entry for a given terminal type,
463
506
 *      if it exists.  We take pains here to make sure no combination
466
509
 */
467
510
 
468
511
NCURSES_EXPORT(int)
469
 
_nc_read_entry(const char *const tn, char *const filename, TERMTYPE *const tp)
 
512
_nc_read_entry(const char *const name, char *const filename, TERMTYPE *const tp)
470
513
{
471
 
    char *envp;
472
 
    char ttn[PATH_MAX];
473
 
 
474
 
    if (strlen(tn) == 0
475
 
        || strcmp(tn, ".") == 0
476
 
        || strcmp(tn, "..") == 0
477
 
        || _nc_pathlast(tn) != 0) {
478
 
        T(("illegal or missing entry name '%s'", tn));
479
 
        return 0;
480
 
    }
481
 
 
482
 
    /* truncate the terminal name to prevent buffer overflow */
483
 
    (void) sprintf(ttn, "%c/%.*s", *tn, (int) sizeof(ttn) - 3, tn);
484
 
 
485
 
    /* This is System V behavior, in conjunction with our requirements for
486
 
     * writing terminfo entries.
487
 
     */
488
 
    if (have_tic_directory
489
 
        && _nc_read_tic_entry(filename, _nc_tic_dir(0), ttn, tp) == 1)
490
 
        return 1;
491
 
 
492
 
    if (use_terminfo_vars()) {
493
 
        if ((envp = getenv("TERMINFO")) != 0
494
 
            && _nc_read_tic_entry(filename, _nc_tic_dir(envp), ttn, tp) == 1)
495
 
            return 1;
496
 
 
497
 
        /* this is an ncurses extension */
498
 
        if ((envp = _nc_home_terminfo()) != 0) {
499
 
            if (_nc_read_tic_entry(filename, envp, ttn, tp) == 1) {
500
 
                return 1;
 
514
    int code = TGETENT_NO;
 
515
 
 
516
    if (strlen(name) == 0
 
517
        || strcmp(name, ".") == 0
 
518
        || strcmp(name, "..") == 0
 
519
        || _nc_pathlast(name) != 0
 
520
        || strchr(name, NCURSES_PATHSEP) != 0) {
 
521
        T(("illegal or missing entry name '%s'", name));
 
522
    } else {
 
523
#if USE_DATABASE
 
524
        DBDIRS state = dbdTIC;
 
525
        int offset = 0;
 
526
        const char *path;
 
527
 
 
528
        while ((path = _nc_next_db(&state, &offset)) != 0) {
 
529
            code = _nc_read_tic_entry(filename, PATH_MAX, path, name, tp);
 
530
            if (code == TGETENT_YES) {
 
531
                _nc_last_db();
 
532
                break;
501
533
            }
502
534
        }
503
 
 
504
 
        /* this is an ncurses extension */
505
 
        if ((envp = getenv("TERMINFO_DIRS")) != 0)
506
 
            return _nc_read_terminfo_dirs(envp, filename, ttn, tp);
 
535
#endif
 
536
#if USE_TERMCAP
 
537
        if (code != TGETENT_YES) {
 
538
            code = _nc_read_termcap_entry(name, tp);
 
539
            sprintf(filename, "%.*s", PATH_MAX - 1, _nc_get_source());
 
540
        }
 
541
#endif
507
542
    }
508
 
 
509
 
    /* Try the system directory.  Note that the TERMINFO_DIRS value, if
510
 
     * defined by the configure script, begins with a ":", which will be
511
 
     * interpreted as TERMINFO.
512
 
     */
513
 
#ifdef TERMINFO_DIRS
514
 
    return _nc_read_terminfo_dirs(TERMINFO_DIRS, filename, ttn, tp);
515
 
#else
516
 
    return _nc_read_tic_entry(filename, TERMINFO, ttn, tp);
517
 
#endif
 
543
    return code;
518
544
}