diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 1999-03-02 06:23:57 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 1999-03-02 06:23:57 +0000 |
commit | e52ae7d7cb3b9267a450ee786b056b14391f2f50 (patch) | |
tree | 852bbb003a1438d75ce8016c9feef856d56fd2fd /lib/libcurses/tinfo/read_entry.c | |
parent | aedffcef562be3c46e9a21641c0a65c968b1d889 (diff) |
ncurses-4.2-990301
Diffstat (limited to 'lib/libcurses/tinfo/read_entry.c')
-rw-r--r-- | lib/libcurses/tinfo/read_entry.c | 333 |
1 files changed, 227 insertions, 106 deletions
diff --git a/lib/libcurses/tinfo/read_entry.c b/lib/libcurses/tinfo/read_entry.c index 133152bbaef..09902edc114 100644 --- a/lib/libcurses/tinfo/read_entry.c +++ b/lib/libcurses/tinfo/read_entry.c @@ -1,7 +1,7 @@ -/* $OpenBSD: read_entry.c,v 1.3 1999/01/23 18:31:02 millert Exp $ */ +/* $OpenBSD: read_entry.c,v 1.4 1999/03/02 06:23:29 millert Exp $ */ /**************************************************************************** - * Copyright (c) 1998 Free Software Foundation, Inc. * + * Copyright (c) 1999 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -46,16 +46,21 @@ #include <fcntl.h> #endif -#include <term.h> #include <tic.h> #include <term_entry.h> -MODULE_ID("$From: read_entry.c,v 1.47 1998/12/20 02:51:50 tom Exp $") +MODULE_ID("$From: read_entry.c,v 1.60 1999/03/01 23:59:28 tom Exp $") #ifndef O_BINARY #define O_BINARY 0 #endif +#if 0 +#define TRACE_IN(p) DEBUG(2, p) +#else +#define TRACE_IN(p) /*nothing*/ +#endif + /* * int * _nc_read_file_entry(filename, ptr) @@ -107,60 +112,101 @@ void _nc_keep_tic_dir(const char *path) keep_tic_directory = TRUE; } -int _nc_read_file_entry(const char *const filename, TERMTYPE *ptr) -/* return 1 if read, 0 if not found or garbled */ +static void convert_shorts(char *buf, short *Numbers, int count) { - int name_size, bool_count, num_count, str_count, str_size; - int i, fd, numread; - char buf[MAX_ENTRY_SIZE]; + int i; + for (i = 0; i < count; i++) + { + if (IS_NEG1(buf + 2*i)) + Numbers[i] = ABSENT_NUMERIC; + else if (IS_NEG2(buf + 2*i)) + Numbers[i] = CANCELLED_NUMERIC; + else + Numbers[i] = LOW_MSB(buf + 2*i); + TRACE_IN(("get Numbers[%d]=%d", i, Numbers[i])); + } +} -#ifdef __OpenBSD__ - if (_nc_read_bsd_terminfo_file(filename, ptr) == 1) - return(1); -#endif /* __OpenBSD__ */ +static void convert_strings(char *buf, char **Strings, int count, int size, char *table) +{ + int i; + char *p; + + for (i = 0; i < count; i++) { + if (IS_NEG1(buf + 2*i)) { + Strings[i] = ABSENT_STRING; + } else if (IS_NEG2(buf + 2*i)) { + Strings[i] = CANCELLED_STRING; + } else if (LOW_MSB(buf + 2*i) > size) { + Strings[i] = ABSENT_STRING; + } else { + Strings[i] = (LOW_MSB(buf+2*i) + table); + TRACE_IN(("Strings[%d] = %s", i, _nc_visbuf(Strings[i]))); + } - if (_nc_access(filename, R_OK) < 0 - || (fd = open(filename, O_RDONLY|O_BINARY)) < 0) { - T(("cannot open terminfo %s (errno=%d)", filename, errno)); - return(0); + /* make sure all strings are NUL terminated */ + if (VALID_STRING(Strings[i])) { + for (p = Strings[i]; p <= table + size; p++) + if (*p == '\0') + break; + /* if there is no NUL, ignore the string */ + if (p > table + size) + Strings[i] = ABSENT_STRING; + } } +} - T(("read terminfo %s", filename)); +#define read_shorts(fd, buf, count) (read(fd, buf, (count)*2) == (count)*2) + +#define even_boundary(value) \ + if ((value) % 2 != 0) read(fd, buf, 1) + +static int read_termtype(int fd, TERMTYPE *ptr) +/* return 1 if read, 0 if not found or garbled */ +{ + int name_size, bool_count, num_count, str_count, str_size; + int i; + char buf[MAX_ENTRY_SIZE]; + + TRACE_IN(("READ termtype header @%d", tell(fd))); /* grab the header */ - (void) read(fd, buf, 12); - if (LOW_MSB(buf) != MAGIC) - { - close(fd); + if (!read_shorts(fd, buf, 6) + || LOW_MSB(buf) != MAGIC) { return(0); } + + _nc_free_termtype(ptr); name_size = LOW_MSB(buf + 2); bool_count = LOW_MSB(buf + 4); num_count = LOW_MSB(buf + 6); str_count = LOW_MSB(buf + 8); str_size = LOW_MSB(buf + 10); - if (str_size) - { + TRACE_IN(("header is %d/%d/%d/%d(%d)", name_size, bool_count, num_count, str_count, str_size)); + if (name_size < 0 + || bool_count < 0 + || num_count < 0 + || str_count < 0 + || str_size < 0) { + return(0); + } + + if (str_size) { /* try to allocate space for the string table */ - ptr->str_table = malloc((unsigned)str_size); - if (ptr->str_table == 0) - { - close(fd); + if (str_count*2 >= (int) sizeof(buf) + || (ptr->str_table = typeMalloc(char, (unsigned)str_size)) == 0) { return(0); } - } - else + } else { str_count = 0; + } - /* grab the name */ + /* grab the name (a null-terminate string) */ read(fd, buf, min(MAX_NAME_SIZE, (unsigned)name_size)); buf[MAX_NAME_SIZE] = '\0'; - ptr->term_names = calloc(strlen(buf) + 1, sizeof(char)); + ptr->term_names = typeCalloc(char, strlen(buf) + 1); if (ptr->term_names == NULL) { - if (str_size) - free(ptr->str_table); - close(fd); return(0); } (void) strcpy(ptr->term_names, buf); @@ -168,12 +214,10 @@ int _nc_read_file_entry(const char *const filename, TERMTYPE *ptr) lseek(fd, (off_t) (name_size - MAX_NAME_SIZE), 1); /* grab the booleans */ - read(fd, ptr->Booleans, min(BOOLCOUNT, (unsigned)bool_count)); - if (bool_count > BOOLCOUNT) - lseek(fd, (off_t) (bool_count - BOOLCOUNT), 1); - else - for (i=bool_count; i < BOOLCOUNT; i++) - ptr->Booleans[i] = 0; + if ((ptr->Booleans = typeCalloc(char, max(BOOLCOUNT, bool_count))) == 0 + || read(fd, ptr->Booleans, (unsigned)bool_count) < bool_count) { + return(0); + } /* * If booleans end on an odd byte, skip it. The machine they @@ -181,90 +225,168 @@ int _nc_read_file_entry(const char *const filename, TERMTYPE *ptr) * word-oriented machine that would trap out if you tried a * word access off a 2-byte boundary. */ - if ((name_size + bool_count) % 2 != 0) - read(fd, buf, 1); + even_boundary(name_size + bool_count); /* grab the numbers */ - (void) read(fd, buf, min(NUMCOUNT*2, (unsigned)num_count*2)); - for (i = 0; i < min(num_count, NUMCOUNT); i++) - { - if (IS_NEG1(buf + 2*i)) - ptr->Numbers[i] = ABSENT_NUMERIC; - else if (IS_NEG2(buf + 2*i)) - ptr->Numbers[i] = CANCELLED_NUMERIC; - else - ptr->Numbers[i] = LOW_MSB(buf + 2*i); + if ((ptr->Numbers = typeCalloc(short, max(NUMCOUNT, num_count))) == 0 + || !read_shorts(fd, buf, num_count)) { + return(0); } - if (num_count > NUMCOUNT) - lseek(fd, (off_t) (2 * (num_count - NUMCOUNT)), 1); - else - for (i=num_count; i < NUMCOUNT; i++) - ptr->Numbers[i] = ABSENT_NUMERIC; + convert_shorts(buf, ptr->Numbers, num_count); + + if ((ptr->Strings = typeCalloc(char *, max(STRCOUNT, str_count))) == 0) + return(0); if (str_count) { - if (str_count*2 >= MAX_ENTRY_SIZE) - { - close(fd); - return(0); - } /* grab the string offsets */ - numread = read(fd, buf, (unsigned)(str_count*2)); - if (numread < str_count*2) - { - close(fd); + if (!read_shorts(fd, buf, str_count)) { return(0); } - for (i = 0; i < numread/2; i++) - { - if (i >= STRCOUNT) - break; - if (IS_NEG1(buf + 2*i)) - ptr->Strings[i] = ABSENT_STRING; - else if (IS_NEG2(buf + 2*i)) - ptr->Strings[i] = CANCELLED_STRING; - else if (LOW_MSB(buf + 2*i) > str_size) - ptr->Strings[i] = ABSENT_STRING; - else - ptr->Strings[i] = (LOW_MSB(buf+2*i) + ptr->str_table); - } + /* finally, grab the string table itself */ + if (read(fd, ptr->str_table, (unsigned)str_size) != str_size) + return(0); + convert_strings(buf, ptr->Strings, str_count, str_size, ptr->str_table); } - if (str_count > STRCOUNT) - lseek(fd, (off_t) (2 * (str_count - STRCOUNT)), 1); - else - for (i = str_count; i < STRCOUNT; i++) - ptr->Strings[i] = ABSENT_STRING; +#if NCURSES_XNAMES - if (str_size) - { - /* finally, grab the string table itself */ - numread = read(fd, ptr->str_table, (unsigned)str_size); - if (numread != str_size) - { - close(fd); + ptr->num_Booleans = BOOLCOUNT; + ptr->num_Numbers = NUMCOUNT; + ptr->num_Strings = STRCOUNT; + + /* + * Read extended entries, if any, after the normal end of terminfo data. + */ + even_boundary(str_size); + TRACE_IN(("READ extended_header @%d", tell(fd))); + if (_nc_user_definable && read_shorts(fd, buf, 5)) { + int ext_bool_count = LOW_MSB(buf + 0); + int ext_num_count = LOW_MSB(buf + 2); + int ext_str_count = LOW_MSB(buf + 4); + int ext_str_size = LOW_MSB(buf + 6); + int ext_str_limit = LOW_MSB(buf + 8); + int need = (ext_bool_count + ext_num_count + ext_str_count); + int base = 0; + + if (need >= (int) sizeof(buf) + || ext_str_size >= (int) sizeof(buf) + || ext_str_limit >= (int) sizeof(buf) + || ext_bool_count < 0 + || ext_num_count < 0 + || ext_str_count < 0 + || ext_str_size < 0 + || ext_str_limit < 0) return(0); + + ptr->num_Booleans = BOOLCOUNT + ext_bool_count; + ptr->num_Numbers = NUMCOUNT + ext_num_count; + ptr->num_Strings = STRCOUNT + ext_str_count; + + ptr->Booleans = typeRealloc(char, ptr->num_Booleans,ptr->Booleans); + ptr->Numbers = typeRealloc(short, ptr->num_Numbers, ptr->Numbers); + ptr->Strings = typeRealloc(char*, ptr->num_Strings, ptr->Strings); + + TRACE_IN(("extended header is %d/%d/%d(%d:%d)", ext_bool_count, ext_num_count, ext_str_count, ext_str_size, ext_str_limit)); + + TRACE_IN(("READ %d extended-booleans @%d", ext_bool_count, tell(fd))); + if ((ptr->ext_Booleans = ext_bool_count) != 0) { + if (read(fd, ptr->Booleans + BOOLCOUNT, (unsigned)ext_bool_count) != ext_bool_count) + return(0); } - } + even_boundary(ext_bool_count); - /* make sure all strings are NUL terminated */ - for (i = str_count; i < STRCOUNT; i++) { - char *p; + TRACE_IN(("READ %d extended-numbers @%d", ext_num_count, tell(fd))); + if ((ptr->ext_Numbers = ext_num_count) != 0) { + if (!read_shorts(fd, buf, ext_num_count)) + return(0); + TRACE_IN(("Before converting extended-numbers")); + convert_shorts(buf, ptr->Numbers + NUMCOUNT, ext_num_count); + } - if (VALID_STRING(ptr->Strings[i])) { - for (p = ptr->Strings[i]; p <= ptr->str_table + str_size; p++) - if (*p == '\0') - break; - /* if there is no NUL, ignore the string */ - if (p > ptr->str_table + str_size) - ptr->Strings[i] = ABSENT_STRING; + TRACE_IN(("READ extended-offsets @%d", tell(fd))); + if ((ext_str_count || need) + && !read_shorts(fd, buf, ext_str_count+need)) + return(0); + + TRACE_IN(("READ %d bytes of extended-strings @%d", ext_str_limit, tell(fd))); + if (ext_str_limit) { + if ((ptr->ext_str_table = typeMalloc(char, ext_str_limit)) == 0) + return(0); + if (read(fd, ptr->ext_str_table, ext_str_limit) != ext_str_limit) + return(0); + TRACE_IN(("first extended-string is %s", _nc_visbuf(ptr->ext_str_table))); + } + + if ((ptr->ext_Strings = ext_str_count) != 0) { + TRACE_IN(("Before computing extended-string capabilities str_count=%d, ext_str_count=%d", str_count, ext_str_count)); + convert_strings(buf, ptr->Strings + str_count, ext_str_count, ext_str_limit, ptr->ext_str_table); + for (i = ext_str_count-1; i >= 0; i--) { + TRACE_IN(("MOVE from [%d:%d] %s", i, i+str_count, _nc_visbuf(ptr->Strings[i+str_count]))); + ptr->Strings[i+STRCOUNT] = ptr->Strings[i+str_count]; + if (VALID_STRING(ptr->Strings[i+STRCOUNT])) + base += (strlen(ptr->Strings[i+STRCOUNT]) + 1); + TRACE_IN(("... to [%d] %s", i+STRCOUNT, _nc_visbuf(ptr->Strings[i+STRCOUNT]))); + } + } + + if (need) { + if ((ptr->ext_Names = typeCalloc(char *, need)) == 0) + return(0); + TRACE_IN(("ext_NAMES starting @%d in extended_strings, first = %s", base, _nc_visbuf(ptr->ext_str_table+base))); + convert_strings(buf + (2 * ext_str_count), ptr->ext_Names, need, ext_str_limit, ptr->ext_str_table + base); } + + T(("...done reading terminfo bool %d(%d) num %d(%d) str %d(%d)", + ptr->num_Booleans, ptr->ext_Booleans, + ptr->num_Numbers, ptr->ext_Numbers, + ptr->num_Strings, ptr->ext_Strings)); + + TRACE_IN(("extend: num_Booleans:%d", ptr->num_Booleans)); + } else +#endif /* NCURSES_XNAMES */ + { + T(("...done reading terminfo bool %d num %d str %d", + bool_count, + num_count, + str_count)); + TRACE_IN(("normal: num_Booleans:%d", ptr->num_Booleans)); } - close(fd); + for (i = bool_count; i < BOOLCOUNT; i++) + ptr->Booleans[i] = FALSE; + for (i = num_count; i < NUMCOUNT; i++) + ptr->Numbers[i] = ABSENT_NUMERIC; + for (i = str_count; i < STRCOUNT; i++) + ptr->Strings[i] = ABSENT_STRING; + return(1); } +int _nc_read_file_entry(const char *const filename, TERMTYPE *ptr) +/* return 1 if read, 0 if not found or garbled */ +{ + int code, fd; + +#ifdef __OpenBSD__ + if (_nc_read_bsd_terminfo_file(filename, ptr) == 1) + return(1); +#endif /* __OpenBSD__ */ + + if (_nc_access(filename, R_OK) < 0 + || (fd = open(filename, O_RDONLY|O_BINARY)) < 0) { + T(("cannot open terminfo %s (errno=%d)", filename, errno)); + return(0); + } + + T(("read terminfo %s", filename)); + if ((code = read_termtype(fd, ptr)) == 0) + _nc_free_termtype(ptr); + close(fd); + + return (code); +} + /* * Build a terminfo pathname and try to read the data. Returns 1 on success, * 0 on failure. @@ -292,9 +414,8 @@ static int _nc_read_terminfo_dirs(const char *dirs, char *const filename, const int code = 0; /* we'll modify the argument, so we must copy */ - if ((b = a = list = malloc(strlen(dirs) + 1)) == NULL) + if ((b = a = list = strdup(dirs)) == NULL) return(0); - (void) strcpy(list, dirs); for (;;) { int c = *a; @@ -351,7 +472,7 @@ char ttn[MAX_ALIAS + 3]; && _nc_read_tic_entry(filename, _nc_tic_dir(envp), ttn, tp) == 1) return 1; - if (!issetugid() && (envp = _nc_home_terminfo()) != 0) { + if ((envp = _nc_home_terminfo()) != 0) { if (_nc_read_tic_entry(filename, envp, ttn, tp) == 1) { return(1); } |