]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - ncurses/tinfo/read_termcap.c
ncurses 5.0
[ncurses.git] / ncurses / tinfo / read_termcap.c
similarity index 93%
rename from ncurses/read_termcap.c
rename to ncurses/tinfo/read_termcap.c
index d67a3bc9c3c55288cdeca13c8c7b512476193cb4..d60a92d63f0ad6a84747cb73a70297b4622c8fab 100644 (file)
@@ -53,7 +53,6 @@
 #include <curses.priv.h>
 
 #include <ctype.h>
-#include <term.h>
 #include <tic.h>
 #include <term_entry.h>
 
@@ -61,7 +60,9 @@
 #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] == '/')) \
@@ -155,7 +156,7 @@ _nc_cgetset(const char *ent)
                return (0);
        }
        topreclen = strlen(ent);
-       if ((toprec = malloc (topreclen + 1)) == 0) {
+       if ((toprec = typeMalloc(char, topreclen + 1)) == 0) {
                errno = ENOMEM;
                return (-1);
        }
@@ -258,6 +259,7 @@ _nc_cgetent(char **buf, int *oline, char **db_array, const char *name)
  *       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 */
@@ -272,7 +274,7 @@ _nc_getent(
 {
        register char *r_end, *rp;
        int myfd = FALSE;
-       char *record;
+       char *record = 0;
        int tc_not_resolved;
        int current;
        int lineno;
@@ -288,7 +290,7 @@ _nc_getent(
         * 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);
                }
@@ -302,7 +304,7 @@ _nc_getent(
                /*
                 * Allocate first chunk of memory.
                 */
-               if ((record = malloc(BFRAG)) == 0) {
+               if ((record = DOALLOC(BFRAG)) == 0) {
                        errno = ENOMEM;
                        return (TC_SYS_ERR);
                }
@@ -320,15 +322,14 @@ _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) {
+                               /* 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;
@@ -398,11 +399,11 @@ _nc_getent(
 
                                                        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;
@@ -533,12 +534,12 @@ _nc_getent(
                                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;
@@ -570,9 +571,9 @@ _nc_getent(
         */
        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);
                }
@@ -800,19 +801,21 @@ _nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
         */
        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) {
@@ -884,9 +887,8 @@ _nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
         * 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);
@@ -894,6 +896,24 @@ _nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
 #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;
@@ -941,19 +961,18 @@ int _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
         * 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 */
                {
@@ -970,13 +989,9 @@ int _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
                                        *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 */
@@ -989,21 +1004,21 @@ int _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
                 * 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 */
@@ -1062,7 +1077,7 @@ int _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
                                 * 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;
 
                                /*
@@ -1095,3 +1110,7 @@ int _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
        _nc_free_entries(_nc_head);
        return(found);
 }
+#else
+extern void _nc_read_termcap(void);
+       void _nc_read_termcap(void) { }
+#endif /* PURE_TERMINFO */