X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Fread_termcap.c;h=c9696b70ae41f14b8174c99b2e3c88956a2c4305;hp=ea4a58c0d3876565149e5334a3a5b0113874f57d;hb=HEAD;hpb=e348f7adec279f5453349ad13246a952a16e2094 diff --git a/ncurses/tinfo/read_termcap.c b/ncurses/tinfo/read_termcap.c index ea4a58c0..1a294848 100644 --- a/ncurses/tinfo/read_termcap.c +++ b/ncurses/tinfo/read_termcap.c @@ -1,5 +1,6 @@ /**************************************************************************** - * Copyright (c) 1998-2017,2018 Free Software Foundation, Inc. * + * Copyright 2018-2021,2023 Thomas E. Dickey * + * Copyright 1998-2016,2017 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 * @@ -56,7 +57,7 @@ #include #include -MODULE_ID("$Id: read_termcap.c,v 1.94 2018/02/24 22:36:15 tom Exp $") +MODULE_ID("$Id: read_termcap.c,v 1.104 2023/06/24 21:53:16 tom Exp $") #if !PURE_TERMINFO @@ -66,10 +67,10 @@ MODULE_ID("$Id: read_termcap.c,v 1.94 2018/02/24 22:36:15 tom Exp $") #define TC_REF_LOOP -3 #define TC_UNRESOLVED -4 /* this is not returned by BSD cgetent */ -static NCURSES_CONST char * +static const char * get_termpath(void) { - NCURSES_CONST char *result; + const char *result; if (!use_terminfo_vars() || (result = getenv("TERMPATH")) == 0) result = TERMPATH; @@ -186,7 +187,7 @@ _nc_cgetcap(char *buf, const char *cap, int type) bp = buf; for (;;) { /* - * Skip past the current capability field - it's either the + * Skip past the current capability field - it is either the * name field if this is the first time through the loop, or * the remainder of a field whose name failed to match cap. */ @@ -323,7 +324,7 @@ _nc_getent( if (fd >= 0) { (void) lseek(fd, (off_t) 0, SEEK_SET); } else if ((_nc_access(db_array[current], R_OK) < 0) - || (fd = open(db_array[current], O_RDONLY, 0)) < 0) { + || (fd = safe_open2(db_array[current], O_RDONLY)) < 0) { /* No error on unfound file. */ if (errno == ENOENT) continue; @@ -364,7 +365,7 @@ _nc_getent( if (bp >= b_end) { int n; - n = read(fd, buf, sizeof(buf)); + n = (int) read(fd, buf, sizeof(buf)); if (n <= 0) { if (myfd) (void) close(fd); @@ -393,7 +394,7 @@ _nc_getent( || *(rp - 1) != '\\') break; } - *rp++ = c; + *rp++ = (char) c; /* * Enforce loop invariant: if no room @@ -404,8 +405,8 @@ _nc_getent( unsigned pos; size_t newsize; - pos = rp - record; - newsize = r_end - record + BFRAG; + pos = (unsigned) (rp - record); + newsize = (size_t) (r_end - record + BFRAG); record = DOALLOC(newsize); if (record == 0) { if (myfd) @@ -492,14 +493,14 @@ _nc_getent( } } tcstart = tc - 3; - tclen = s - tcstart; + tclen = (int) (s - tcstart); tcend = s; icap = 0; iret = _nc_getent(&icap, &ilen, &oline, current, db_array, fd, tc, depth + 1, 0); newicap = icap; /* Put into a register. */ - newilen = ilen; + newilen = (int) ilen; if (iret != TC_SUCCESS) { /* an error */ if (iret < TC_NOT_FOUND) { @@ -523,7 +524,7 @@ _nc_getent( /* not interested in name field of tc'ed record */ s = newicap; while (*s != '\0' && *s++ != ':') ; - newilen -= s - newicap; + newilen -= (int) (s - newicap); newicap = s; /* make sure interpolated record is `:'-terminated */ @@ -542,10 +543,10 @@ _nc_getent( unsigned pos, tcpos, tcposend; size_t newsize; - pos = rp - record; - newsize = r_end - record + diff + BFRAG; - tcpos = tcstart - record; - tcposend = tcend - record; + pos = (unsigned) (rp - record); + newsize = (size_t) (r_end - record + diff + BFRAG); + tcpos = (unsigned) (tcstart - record); + tcposend = (unsigned) (tcend - record); record = DOALLOC(newsize); if (record == 0) { if (myfd) @@ -583,7 +584,7 @@ _nc_getent( */ if (myfd) (void) close(fd); - *len = rp - record - 1; /* don't count NUL */ + *len = (unsigned) (rp - record - 1); /* don't count NUL */ if (r_end > rp) { if ((record = DOALLOC((size_t) (rp - record))) == 0) { errno = ENOMEM; @@ -791,7 +792,7 @@ _nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name) int i; char pathbuf[PBUFSIZ]; /* holds raw path of filenames */ CGETENT_CONST char *pathvec[PVECSIZ]; /* point to names in pathbuf */ - NCURSES_CONST char *termpath; + const char *termpath; string_desc desc; *lineno = 1; @@ -802,7 +803,7 @@ _nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name) /* * TERMCAP can have one of two things in it. It can be the name of a file * to use instead of /etc/termcap. In this case it better start with a - * "/". Or it can be an entry to use so we don't have to read the file. + * "/". Or it can be an entry to use so we don't have to read the file. * In this case it has to already have the newlines crunched out. If * TERMCAP does not hold a file name then a path of names is searched * instead. The path is found in the TERMPATH variable, or becomes @@ -965,6 +966,7 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE2 *const tp) #endif #if USE_GETCAP char *p, tc[TBUFSIZ]; + char *tc_buf = 0; #define MY_SIZE sizeof(tc) - 1 int status; static char *source; @@ -983,8 +985,7 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE2 *const tp) if (use_terminfo_vars() && (p = getenv("TERMCAP")) != 0 && !_nc_is_abs_path(p) && _nc_name_match(p, tn, "|:")) { /* TERMCAP holds a termcap entry */ - _nc_STRNCPY(tc, p, MY_SIZE); - tc[MY_SIZE] = '\0'; + tc_buf = strdup(p); _nc_set_source("TERMCAP"); } else { /* we're using getcap(3) */ @@ -993,8 +994,13 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE2 *const tp) _nc_curr_line = lineno; _nc_set_source(source); + tc_buf = tc; } - _nc_read_entry_source((FILE *) 0, tc, FALSE, TRUE, NULLHOOK); + if (tc_buf == 0) + return (TGETENT_ERR); + _nc_read_entry_source((FILE *) 0, tc_buf, FALSE, TRUE, NULLHOOK); + if (tc_buf != tc) + free(tc_buf); #else /* * Here is what the 4.4BSD termcap(3) page prescribes: @@ -1028,7 +1034,7 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE2 *const tp) int j, k; bool use_buffer = FALSE; bool normal = TRUE; - char tc_buf[1024]; + char *tc_buf = 0; char pathbuf[PATH_MAX]; char *copied = 0; char *cp; @@ -1040,10 +1046,8 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE2 *const tp) ADD_TC(tc, 0); normal = FALSE; } else if (_nc_name_match(tc, tn, "|:")) { /* treat as a capability file */ - use_buffer = TRUE; - _nc_SPRINTF(tc_buf, - _nc_SLIMIT(sizeof(tc_buf)) - "%.*s\n", (int) sizeof(tc_buf) - 2, tc); + tc_buf = strdup(tc); + use_buffer = (tc_buf != 0); normal = FALSE; } } @@ -1051,23 +1055,25 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE2 *const tp) if (normal) { /* normal case */ char envhome[PATH_MAX], *h; - copied = strdup(get_termpath()); - for (cp = copied; *cp; cp++) { - if (*cp == NCURSES_PATHSEP) - *cp = '\0'; - else if (cp == copied || cp[-1] == '\0') { - ADD_TC(cp, filecount); + if ((copied = strdup(get_termpath())) != 0) { + for (cp = copied; *cp; cp++) { + if (*cp == NCURSES_PATHSEP) + *cp = '\0'; + else if (cp == copied || cp[-1] == '\0') { + ADD_TC(cp, filecount); + } } } - -#define PRIVATE_CAP "%s/.termcap" +#define PRIVATE_CAP "%.*s/.termcap" if (use_terminfo_vars() && (h = getenv("HOME")) != NULL && *h != '\0' && (strlen(h) + sizeof(PRIVATE_CAP)) < PATH_MAX) { /* user's .termcap, if any, should override it */ _nc_STRCPY(envhome, h, sizeof(envhome)); _nc_SPRINTF(pathbuf, _nc_SLIMIT(sizeof(pathbuf)) - PRIVATE_CAP, envhome); + PRIVATE_CAP, + (int) (sizeof(pathbuf) - sizeof(PRIVATE_CAP)), + envhome); ADD_TC(pathbuf, filecount); } } @@ -1109,9 +1115,10 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE2 *const tp) /* * We don't suppress warning messages here. The presumption is - * that since it's just a single entry, they won't be a pain. + * that since it is just a single entry, they won't be a pain. */ _nc_read_entry_source((FILE *) 0, tc_buf, FALSE, FALSE, NULLHOOK); + free(tc_buf); } else { int i; @@ -1119,7 +1126,7 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE2 *const tp) TR(TRACE_DATABASE, ("Looking for %s in %s", tn, termpaths[i])); if (_nc_access(termpaths[i], R_OK) == 0 - && (fp = fopen(termpaths[i], "r")) != (FILE *) 0) { + && (fp = safe_fopen(termpaths[i], "r")) != (FILE *) 0) { _nc_set_source(termpaths[i]); /* @@ -1159,7 +1166,7 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE2 *const tp) _nc_free_entry(_nc_head, &(ep->tterm)); /* - * OK, now try to write the type to user's terminfo directory. + * OK, now try to write the type to user's terminfo directory. * Next time he loads this, it will come through terminfo. * * Advantage: Second and subsequent fetches of this entry will