[BACK]Return to term.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libterminfo

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/lib/libterminfo/term.c between version 1.9 and 1.17.6.1

version 1.9, 2010/02/12 12:18:33 version 1.17.6.1, 2016/12/12 07:37:53
Line 1 
Line 1 
 /* $NetBSD$ */  /* $NetBSD$ */
   
 /*  /*
  * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.   * Copyright (c) 2009, 2010, 2011 The NetBSD Foundation, Inc.
  *   *
  * This code is derived from software contributed to The NetBSD Foundation   * This code is derived from software contributed to The NetBSD Foundation
  * by Roy Marples.   * by Roy Marples.
Line 33  __RCSID("$NetBSD$");
Line 33  __RCSID("$NetBSD$");
 #include <sys/stat.h>  #include <sys/stat.h>
   
 #include <assert.h>  #include <assert.h>
   #include <cdbr.h>
 #include <ctype.h>  #include <ctype.h>
 #include <errno.h>  #include <errno.h>
 #include <fcntl.h>  #include <fcntl.h>
 #include <limits.h>  #include <limits.h>
 #include <ndbm.h>  
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
Line 54  const char *_ti_database;
Line 54  const char *_ti_database;
 #include "compiled_terms.c"  #include "compiled_terms.c"
   
 static int  static int
   allocset(void *pp, int init, size_t nelem, size_t elemsize)
   {
           void **p = pp;
           if (*p) {
                   memset(*p, init, nelem * elemsize);
                   return 0;
           }
   
           if ((*p = calloc(nelem, elemsize)) == NULL)
                   return -1;
   
           if (init != 0)
                   memset(*p, init, nelem * elemsize);
           return 0;
   }
   
   static int
 _ti_readterm(TERMINAL *term, const char *cap, size_t caplen, int flags)  _ti_readterm(TERMINAL *term, const char *cap, size_t caplen, int flags)
 {  {
         uint8_t ver;          uint8_t ver;
Line 61  _ti_readterm(TERMINAL *term, const char 
Line 78  _ti_readterm(TERMINAL *term, const char 
         size_t len;          size_t len;
         TERMUSERDEF *ud;          TERMUSERDEF *ud;
   
           if (caplen == 0)
                   goto out;
         ver = *cap++;          ver = *cap++;
         /* Only read version 1 and 2 structures */          caplen--;
         if (ver != 1 && ver != 2) {          /* Only read version 1 structures */
                 errno = EINVAL;          if (ver != 1)
                   goto out;
   
   
           if (allocset(&term->flags, 0, TIFLAGMAX + 1, sizeof(*term->flags)) == -1)
                 return -1;                  return -1;
         }  
   
         term->flags = calloc(TIFLAGMAX + 1, sizeof(char));          if (allocset(&term->nums, -1, TINUMMAX + 1, sizeof(*term->nums)) == -1)
         if (term->flags == NULL)                  return -1;
                 goto err;  
         term->nums = malloc((TINUMMAX + 1) * sizeof(short));          if (allocset(&term->strs, 0, TISTRMAX + 1, sizeof(*term->strs)) == -1)
         if (term->nums == NULL)                  return -1;
                 goto err;  
         memset(term->nums, (short)-1, (TINUMMAX + 1) * sizeof(short));          if (term->_arealen != caplen) {
         term->strs = calloc(TISTRMAX + 1, sizeof(char *));                  term->_arealen = caplen;
         if (term->strs == NULL)                  term->_area = realloc(term->_area, term->_arealen);
                 goto err;                  if (term->_area == NULL)
         term->_arealen = caplen;                          return -1;
         term->_area = malloc(term->_arealen);          }
         if (term->_area == NULL)  
                 goto err;  
         memcpy(term->_area, cap, term->_arealen);          memcpy(term->_area, cap, term->_arealen);
   
         cap = term->_area;          cap = term->_area;
Line 89  _ti_readterm(TERMINAL *term, const char 
Line 109  _ti_readterm(TERMINAL *term, const char 
         cap += sizeof(uint16_t);          cap += sizeof(uint16_t);
         term->name = cap;          term->name = cap;
         cap += len;          cap += len;
         if (ver == 1)          len = le16dec(cap);
           cap += sizeof(uint16_t);
           if (len == 0)
                 term->_alias = NULL;                  term->_alias = NULL;
         else {          else {
                 len = le16dec(cap);                  term->_alias = cap;
                 cap += sizeof(uint16_t);                  cap += len;
                 if (len == 0)  
                         term->_alias = NULL;  
                 else {  
                         term->_alias = cap;  
                         cap += len;  
                 }  
         }          }
         len = le16dec(cap);          len = le16dec(cap);
         cap += sizeof(uint16_t);          cap += sizeof(uint16_t);
Line 123  _ti_readterm(TERMINAL *term, const char 
Line 139  _ti_readterm(TERMINAL *term, const char 
                                 term->flags[ind] = 0;                                  term->flags[ind] = 0;
                 }                  }
         }          }
   
         num = le16dec(cap);          num = le16dec(cap);
         cap += sizeof(uint16_t);          cap += sizeof(uint16_t);
         if (num != 0) {          if (num != 0) {
Line 138  _ti_readterm(TERMINAL *term, const char 
Line 154  _ti_readterm(TERMINAL *term, const char 
                         cap += sizeof(uint16_t);                          cap += sizeof(uint16_t);
                 }                  }
         }          }
   
         num = le16dec(cap);          num = le16dec(cap);
         cap += sizeof(uint16_t);          cap += sizeof(uint16_t);
         if (num != 0) {          if (num != 0) {
Line 158  _ti_readterm(TERMINAL *term, const char 
Line 174  _ti_readterm(TERMINAL *term, const char 
                         cap += len;                          cap += len;
                 }                  }
         }          }
   
         num = le16dec(cap);          num = le16dec(cap);
         cap += sizeof(uint16_t);          cap += sizeof(uint16_t);
         if (num != 0) {          if (num != 0) {
                 term->_nuserdefs = le16dec(cap);                  num = le16dec(cap);
                 term->_userdefs = malloc(sizeof(*term->_userdefs) * num);  
                 cap += sizeof(uint16_t);                  cap += sizeof(uint16_t);
                   if (num != term->_nuserdefs) {
                           free(term->_userdefs);
                           term->_userdefs = NULL;
                           term->_nuserdefs = num;
                   }
                   if (allocset(&term->_userdefs, 0, term->_nuserdefs,
                       sizeof(*term->_userdefs)) == -1)
                           return -1;
                 for (num = 0; num < term->_nuserdefs; num++) {                  for (num = 0; num < term->_nuserdefs; num++) {
                         ud = &term->_userdefs[num];                          ud = &term->_userdefs[num];
                         len = le16dec(cap);                          len = le16dec(cap);
Line 204  _ti_readterm(TERMINAL *term, const char 
Line 227  _ti_readterm(TERMINAL *term, const char 
                                 cap += len;                                  cap += len;
                                 break;                                  break;
                         default:                          default:
                                 errno = EINVAL;                                  goto out;
                                 goto err;  
                         }                          }
                 }                  }
           } else {
                   term->_nuserdefs = 0;
                   if (term->_userdefs) {
                           free(term->_userdefs);
                           term->_userdefs = NULL;
                   }
         }          }
   
         return 1;          return 1;
   out:
 err:          errno = EINVAL;
         _ti_freeterm(term);  
         return -1;          return -1;
 }  }
   
 static int  static int
 _ti_dbgetterm(TERMINAL *term, const char *path, const char *name, int flags)  _ti_dbgetterm(TERMINAL *term, const char *path, const char *name, int flags)
 {  {
         DBM *db;          struct cdbr *db;
         datum dt;          const void *data;
         char *p;          char *db_name;
           const uint8_t *data8;
           size_t len, klen;
         int r;          int r;
   
         db = dbm_open(path, O_RDONLY, 0644);          if (asprintf(&db_name, "%s.cdb", path) < 0)
                   return -1;
   
           db = cdbr_open(db_name, CDBR_DEFAULT);
           free(db_name);
         if (db == NULL)          if (db == NULL)
                 return -1;                  return -1;
   
           klen = strlen(name) + 1;
           if (cdbr_find(db, name, klen, &data, &len) == -1)
                   goto fail;
           data8 = data;
           if (len == 0)
                   goto fail;
           /* Check for alias first, fall through to processing normal entries. */
           if (data8[0] == 2) {
                   if (klen + 7 > len || le16dec(data8 + 5) != klen)
                           goto fail;
                   if (memcmp(data8 + 7, name, klen))
                           goto fail;
                   if (cdbr_get(db, le32dec(data8 + 1), &data, &len))
                           goto fail;
                   data8 = data;
                   if (data8[0] != 1)
                           goto fail;
           } else if (data8[0] != 1)
                   goto fail;
           else if (klen + 3 >= len || le16dec(data8 + 1) != klen)
                   goto fail;
           else if (memcmp(data8 + 3, name, klen))
                   goto fail;
   
         strlcpy(database, path, sizeof(database));          strlcpy(database, path, sizeof(database));
         _ti_database = database;          _ti_database = database;
         dt.dptr = (void *)__UNCONST(name);  
         dt.dsize = strlen(name);  
         dt = dbm_fetch(db, dt);  
         if (dt.dptr == NULL) {  
                 dbm_close(db);  
                 return 0;  
         }  
   
         for (;;) {          r = _ti_readterm(term, data, len, flags);
                 p = (char *)dt.dptr;          cdbr_close(db);
                 if (*p++ != 0) /* not alias */  
                         break;  
                 dt.dsize = le16dec(p) - 1;  
                 p += sizeof(uint16_t);  
                 dt.dptr = p;  
                 dt = dbm_fetch(db, dt);  
                 if (dt.dptr == NULL) {  
                         dbm_close(db);  
                         return 0;  
                 }  
         }  
   
         r = _ti_readterm(term, (char *)dt.dptr, dt.dsize, flags);  
         dbm_close(db);  
         return r;          return r;
   
    fail:
           cdbr_close(db);
           return 0;
 }  }
   
 static int  static int
Line 283  _ti_dbgettermp(TERMINAL *term, const cha
Line 325  _ti_dbgettermp(TERMINAL *term, const cha
 }  }
   
 static int  static int
   ticcmp(const TIC *tic, const char *name)
   {
           char *alias, *s;
           size_t len, l;
   
           if (strcmp(tic->name, name) == 0)
                   return 0;
           if (tic->alias == NULL)
                   return -1;
   
           len = strlen(name);
           alias = tic->alias;
           while (*alias != '\0') {
                   s = strchr(alias, '|');
                   if (s == NULL)
                           l = strlen(alias);
                   else
                           l = s - alias;
                   if (len == l && memcmp(alias, name, l) == 0)
                           return 0;
                   if (s == NULL)
                           break;
                   alias = s + 1;
           }
           return 1;
   }
   
   static int
 _ti_findterm(TERMINAL *term, const char *name, int flags)  _ti_findterm(TERMINAL *term, const char *name, int flags)
 {  {
         int r;          int r;
         char *e, h[PATH_MAX];          char *c, *e, h[PATH_MAX];
           TIC *tic;
           uint8_t *f;
           ssize_t len;
   
         _DIAGASSERT(term != NULL);          _DIAGASSERT(term != NULL);
         _DIAGASSERT(name != NULL);          _DIAGASSERT(name != NULL);
   
         database[0] = '\0';          database[0] = '\0';
         _ti_database = NULL;          _ti_database = NULL;
           r = 0;
   
         if ((e = getenv("TERMINFO")) != NULL) {          if ((e = getenv("TERMINFO")) != NULL && *e != '\0')
                 if (e[0] == '/')                  if (e[0] == '/')
                         return _ti_dbgetterm(term, e, name, flags);                          return _ti_dbgetterm(term, e, name, flags);
   
           c = NULL;
           if (e == NULL && (c = getenv("TERMCAP")) != NULL) {
                   if (*c != '\0' && *c != '/') {
                           c = strdup(c);
                           if (c != NULL) {
                                   e = captoinfo(c);
                                   free(c);
                           }
                   }
           }
   
           if (e != NULL) {
                   if (c == NULL)
                           e = strdup(e); /* So we don't destroy env */
                   if (e == NULL)
                           tic = NULL;
                   else {
                           tic = _ti_compile(e, TIC_WARNING |
                               TIC_ALIAS | TIC_DESCRIPTION | TIC_EXTRA);
                           free(e);
                   }
                   if (tic != NULL && ticcmp(tic, name) == 0) {
                           len = _ti_flatten(&f, tic);
                           if (len != -1) {
                                   r = _ti_readterm(term, (char *)f, (size_t)len,
                                       flags);
                                   free(f);
                           }
                   }
                   _ti_freetic(tic);
                   if (r == 1) {
                           if (c == NULL)
                                   _ti_database = "$TERMINFO";
                           else
                                   _ti_database = "$TERMCAP";
                           return r;
                   }
         }          }
   
         if ((e = getenv("TERMINFO_DIRS")) != NULL)          if ((e = getenv("TERMINFO_DIRS")) != NULL)
                 return _ti_dbgettermp(term, e, name, flags);                  return _ti_dbgettermp(term, e, name, flags);
   
         r = 0;  
         if ((e = getenv("HOME")) != NULL) {          if ((e = getenv("HOME")) != NULL) {
                 snprintf(h, sizeof(h), "%s/.terminfo", e);                  snprintf(h, sizeof(h), "%s/.terminfo", e);
                 r = _ti_dbgetterm(term, h, name, flags);                  r = _ti_dbgetterm(term, h, name, flags);
Line 323  _ti_getterm(TERMINAL *term, const char *
Line 434  _ti_getterm(TERMINAL *term, const char *
   
         r = _ti_findterm(term, name, flags);          r = _ti_findterm(term, name, flags);
         if (r == 1)          if (r == 1)
                 return 1;                  return r;
   
         for (i = 0; i < __arraycount(compiled_terms); i++) {          for (i = 0; i < __arraycount(compiled_terms); i++) {
                 t = &compiled_terms[i];                  t = &compiled_terms[i];
Line 335  _ti_getterm(TERMINAL *term, const char *
Line 446  _ti_getterm(TERMINAL *term, const char *
   
         return r;          return r;
 }  }
   
 void  
 _ti_freeterm(TERMINAL *term)  
 {  
   
         _DIAGASSERT(term != NULL);  
   
         free(term->_area);  
         term->_area = NULL;  
         free(term->strs);  
         term->strs = NULL;  
         free(term->nums);  
         term->nums = NULL;  
         free(term->flags);  
         term->flags = NULL;  
         free(term->_userdefs);  
         term->_userdefs = NULL;  
 }  

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.17.6.1

CVSweb <webmaster@jp.NetBSD.org>