summaryrefslogtreecommitdiff
path: root/lib/libcurses/tinfo/read_entry.c
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1999-03-02 06:23:57 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1999-03-02 06:23:57 +0000
commite52ae7d7cb3b9267a450ee786b056b14391f2f50 (patch)
tree852bbb003a1438d75ce8016c9feef856d56fd2fd /lib/libcurses/tinfo/read_entry.c
parentaedffcef562be3c46e9a21641c0a65c968b1d889 (diff)
ncurses-4.2-990301
Diffstat (limited to 'lib/libcurses/tinfo/read_entry.c')
-rw-r--r--lib/libcurses/tinfo/read_entry.c333
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);
}