#include <curses.priv.h>
#include <ctype.h>
-#include <term.h>
#include <tic.h>
#include <term_entry.h>
#include <fcntl.h>
#endif
-MODULE_ID("$Id: read_termcap.c,v 1.27 1998/02/11 12:13:58 tom Exp $")
+MODULE_ID("$Id: read_termcap.c,v 1.43 1999/04/10 20:52:52 tom Exp $")
+
+#ifndef PURE_TERMINFO
#ifdef __EMX__
#define is_pathname(s) ((((s) != 0) && ((s)[0] == '/')) \
return (0);
}
topreclen = strlen(ent);
- if ((toprec = malloc (topreclen + 1)) == 0) {
+ if ((toprec = typeMalloc(char, topreclen + 1)) == 0) {
errno = ENOMEM;
return (-1);
}
* names interpolated, a name can't be found, or depth exceeds
* MAX_RECURSION.
*/
+#define DOALLOC(size) typeRealloc(char, size, record)
static int
_nc_getent(
char **cap, /* termcap-content */
{
register char *r_end, *rp;
int myfd = FALSE;
- char *record;
+ char *record = 0;
int tc_not_resolved;
int current;
int lineno;
* Check if we have a top record from cgetset().
*/
if (depth == 0 && toprec != 0 && _nc_cgetmatch(toprec, name) == 0) {
- if ((record = malloc (topreclen + BFRAG)) == 0) {
+ if ((record = DOALLOC(topreclen + BFRAG)) == 0) {
errno = ENOMEM;
return (TC_SYS_ERR);
}
/*
* Allocate first chunk of memory.
*/
- if ((record = malloc(BFRAG)) == 0) {
+ if ((record = DOALLOC(BFRAG)) == 0) {
errno = ENOMEM;
return (TC_SYS_ERR);
}
*/
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) {
+ /* No error on unfound file. */
+ if (errno == ENOENT)
+ continue;
+ free(record);
+ return (TC_SYS_ERR);
} else {
- fd = open(db_array[current], O_RDONLY, 0);
- if (fd < 0) {
- /* No error on unfound file. */
- if (errno == ENOENT)
- continue;
- free(record);
- return (TC_SYS_ERR);
- }
myfd = TRUE;
}
lineno = 0;
pos = rp - record;
newsize = r_end - record + BFRAG;
- record = realloc(record, newsize);
+ record = DOALLOC(newsize);
if (record == 0) {
- errno = ENOMEM;
if (myfd)
(void)close(fd);
+ errno = ENOMEM;
return (TC_SYS_ERR);
}
r_end = record + newsize;
newsize = r_end - record + diff + BFRAG;
tcpos = tcstart - record;
tcposend = tcend - record;
- record = realloc(record, newsize);
+ record = DOALLOC(newsize);
if (record == 0) {
- errno = ENOMEM;
if (myfd)
(void)close(fd);
free(icap);
+ errno = ENOMEM;
return (TC_SYS_ERR);
}
r_end = record + newsize;
*/
if (myfd)
(void)close(fd);
- *len = rp - record - 1; /* don't count NUL */
+ *len = rp - record - 1; /* don't count NUL */
if (r_end > rp) {
- if ((record = realloc(record, (size_t)(rp - record))) == 0) {
+ if ((record = DOALLOC((size_t)(rp - record))) == 0) {
errno = ENOMEM;
return (TC_SYS_ERR);
}
*/
if (!is_pathname(cp)) { /* no TERMCAP or it holds an entry */
if ((termpath = getenv("TERMPATH")) != 0) {
- strncpy(pathbuf, termpath, sizeof(pathbuf)-1);
+ strncpy(pathbuf, termpath, PBUFSIZ - 1);
} else {
- if ((home = getenv("HOME")) != 0) { /* setup path */
+ if ((home = getenv("HOME")) != 0 &&
+ strlen(home) < PBUFSIZ) { /* setup path */
p += strlen(home); /* path, looking in */
strcpy(pathbuf, home); /* $HOME first */
*p++ = '/';
} /* if no $HOME look in current directory */
#define MY_PATH_DEF ".termcap /etc/termcap /usr/share/misc/termcap"
- strncpy(p, MY_PATH_DEF, (size_t)(PBUFSIZ - (p - pathbuf)));
+ strncpy(p, MY_PATH_DEF, (size_t)(PBUFSIZ - (p - pathbuf) - 1));
}
}
else /* user-defined name in TERMCAP */
- strncpy(pathbuf, cp, PBUFSIZ); /* still can be tokenized */
+ strncpy(pathbuf, cp, PBUFSIZ - 1); /* still can be tokenized */
+ pathbuf[PBUFSIZ - 1] = '\0';
*fname++ = pathbuf; /* tokenize path into vector of names */
while (*++p) {
* cgetent, then it is the actual filename).
*/
if (i >= 0) {
- the_source = malloc(strlen(pathvec[i]) + 1);
- if (the_source != 0)
- *sourcename = strcpy(the_source, pathvec[i]);
+ if ((the_source = strdup(pathvec[i])) != 0)
+ *sourcename = the_source;
}
return(i);
#endif /* USE_BSD_TGETENT */
#endif /* USE_GETCAP */
+#define MAXPATHS 32
+
+/*
+ * Add a filename to the list in 'termpaths[]', checking that we really have
+ * a right to open the file.
+ */
+#if !USE_GETCAP
+static int add_tc(char *termpaths[], char *path, int count)
+{
+ if (count < MAXPATHS
+ && _nc_access(path, R_OK) == 0)
+ termpaths[count++] = path;
+ termpaths[count] = 0;
+ return count;
+}
+#define ADD_TC(path, count) filecount = add_tc(termpaths, path, count)
+#endif /* !USE_GETCAP */
+
int _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
{
int found = FALSE;
* if the database is not accessible.
*/
FILE *fp;
-#define MAXPATHS 32
char *tc, *termpaths[MAXPATHS];
- int filecount = 0;
+ int filecount = 0;
bool use_buffer = FALSE;
char tc_buf[1024];
char pathbuf[PATH_MAX];
+ termpaths[filecount] = 0;
if ((tc = getenv("TERMCAP")) != 0)
{
if (is_pathname(tc)) /* interpret as a filename */
{
- termpaths[0] = tc;
- termpaths[filecount = 1] = 0;
+ ADD_TC(tc, 0);
}
else if (_nc_name_match(tc, tn, "|:")) /* treat as a capability file */
{
*cp = '\0';
else if (cp == tc || cp[-1] == '\0')
{
- if (filecount >= MAXPATHS - 1)
- return(-1);
-
- termpaths[filecount++] = cp;
+ ADD_TC(cp, filecount);
}
}
- termpaths[filecount] = 0;
}
}
else /* normal case */
* Probably /etc/termcap is a symlink to /usr/share/misc/termcap.
* Avoid reading the same file twice.
*/
- if (access("/etc/termcap", R_OK) == 0)
- termpaths[filecount++] = "/etc/termcap";
- else if (access("/usr/share/misc/termcap", R_OK) == 0)
- termpaths[filecount++] = "/usr/share/misc/termcap";
+ if (_nc_access("/etc/termcap", F_OK) == 0)
+ ADD_TC("/etc/termcap", filecount);
+ else
+ ADD_TC("/usr/share/misc/termcap", filecount);
+
+#define PRIVATE_CAP "%s/.termcap"
- if ((h = getenv("HOME")) != (char *)NULL)
+ if ((h = getenv("HOME")) != NULL
+ && (strlen(h) + sizeof(PRIVATE_CAP)) < PATH_MAX)
{
- /* user's .termcap, if any, should override it */
- (void) strncpy(envhome, h, PATH_MAX - 10);
- envhome[PATH_MAX - 10] = '\0';
- (void) sprintf(pathbuf, "%s/.termcap", envhome);
- termpaths[filecount++] = pathbuf;
+ /* user's .termcap, if any, should override it */
+ (void) strcpy(envhome, h);
+ (void) sprintf(pathbuf, PRIVATE_CAP, envhome);
+ ADD_TC(pathbuf, filecount);
}
-
- termpaths[filecount] = 0;
}
/* parse the sources */
* we disconnected from the list by NULLing out
* ep->tterm.str_table above).
*/
- memcpy(tp, &ep->tterm, sizeof(TERMTYPE));
+ *tp = ep->tterm;
ep->tterm.str_table = (char *)0;
/*
_nc_free_entries(_nc_head);
return(found);
}
+#else
+extern void _nc_read_termcap(void);
+ void _nc_read_termcap(void) { }
+#endif /* PURE_TERMINFO */