[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.15 and 1.28

version 1.15, 2012/06/03 23:19:10 version 1.28, 2017/05/16 12:03:41
Line 46  __RCSID("$NetBSD$");
Line 46  __RCSID("$NetBSD$");
   
 #define _PATH_TERMINFO          "/usr/share/misc/terminfo"  #define _PATH_TERMINFO          "/usr/share/misc/terminfo"
   
 static char database[PATH_MAX];  static char __ti_database[PATH_MAX];
 static char pathbuf[PATH_MAX];  
 const char *_ti_database;  const char *_ti_database;
   
 /* Include a generated list of pre-compiled terminfo descriptions. */  /* Include a generated list of pre-compiled terminfo descriptions. */
 #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;          char ver;
         uint16_t ind, num;          uint16_t ind, num;
         size_t len;          size_t len;
         TERMUSERDEF *ud;          TERMUSERDEF *ud;
   
           if (caplen == 0)
                   goto out;
         ver = *cap++;          ver = *cap++;
           caplen--;
         /* Only read version 1 structures */          /* Only read version 1 structures */
         if (ver != 1) {          if (ver != 1)
                 errno = EINVAL;                  goto out;
                 return -1;  
         }  
   
         term->flags = calloc(TIFLAGMAX + 1, sizeof(char));          if (allocset(&term->flags, 0, TIFLAGMAX+1, sizeof(*term->flags)) == -1)
         if (term->flags == NULL)  
                 return -1;  
         term->nums = malloc((TINUMMAX + 1) * sizeof(short));  
         if (term->nums == NULL)  
                 return -1;                  return -1;
         memset(term->nums, (short)-1, (TINUMMAX + 1) * sizeof(short));  
         term->strs = calloc(TISTRMAX + 1, sizeof(char *));          if (allocset(&term->nums, -1, TINUMMAX+1, sizeof(*term->nums)) == -1)
         if (term->strs == NULL)  
                 return -1;                  return -1;
         term->_arealen = caplen;  
         term->_area = malloc(term->_arealen);          if (allocset(&term->strs, 0, TISTRMAX+1, sizeof(*term->strs)) == -1)
         if (term->_area == NULL)  
                 return -1;                  return -1;
   
           if (term->_arealen != caplen) {
                   term->_arealen = caplen;
                   term->_area = realloc(term->_area, term->_arealen);
                   if (term->_area == NULL)
                           return -1;
           }
         memcpy(term->_area, cap, term->_arealen);          memcpy(term->_area, cap, term->_arealen);
   
         cap = term->_area;          cap = term->_area;
Line 119  _ti_readterm(TERMINAL *term, const char 
Line 137  _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 128  _ti_readterm(TERMINAL *term, const char 
Line 146  _ti_readterm(TERMINAL *term, const char 
                 for (; num != 0; num--) {                  for (; num != 0; num--) {
                         ind = le16dec(cap);                          ind = le16dec(cap);
                         cap += sizeof(uint16_t);                          cap += sizeof(uint16_t);
                         term->nums[ind] = le16dec(cap);                          term->nums[ind] = (short)le16dec(cap);
                         if (flags == 0 && !VALID_NUMERIC(term->nums[ind]))                          if (flags == 0 && !VALID_NUMERIC(term->nums[ind]))
                                 term->nums[ind] = ABSENT_NUMERIC;                                  term->nums[ind] = ABSENT_NUMERIC;
                         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 154  _ti_readterm(TERMINAL *term, const char 
Line 172  _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 179  _ti_readterm(TERMINAL *term, const char 
Line 204  _ti_readterm(TERMINAL *term, const char 
                                 break;                                  break;
                         case 'n':                          case 'n':
                                 ud->flag = ABSENT_BOOLEAN;                                  ud->flag = ABSENT_BOOLEAN;
                                 ud->num = le16dec(cap);                                  ud->num = (short)le16dec(cap);
                                 if (flags == 0 &&                                  if (flags == 0 &&
                                     !VALID_NUMERIC(ud->num))                                      !VALID_NUMERIC(ud->num))
                                         ud->num = ABSENT_NUMERIC;                                          ud->num = ABSENT_NUMERIC;
Line 200  _ti_readterm(TERMINAL *term, const char 
Line 225  _ti_readterm(TERMINAL *term, const char 
                                 cap += len;                                  cap += len;
                                 break;                                  break;
                         default:                          default:
                                 errno = EINVAL;                                  goto out;
                                 return -1;  
                         }                          }
                 }                  }
           } else {
                   term->_nuserdefs = 0;
                   if (term->_userdefs) {
                           free(term->_userdefs);
                           term->_userdefs = NULL;
                   }
         }          }
   
         return 1;          return 1;
   out:
           errno = EINVAL;
           return -1;
   }
   
   static int
   _ti_checkname(const char *name, const char *termname, const char *termalias)
   {
           const char *alias, *s;
           size_t len, l;
   
           /* Check terminal name matches. */
           if (strcmp(termname, name) == 0)
                   return 1;
   
           /* Check terminal aliases match. */
           if (termalias == NULL)
                   return 0;
   
           len = strlen(name);
           alias = termalias;
           while (*alias != '\0') {
                   s = strchr(alias, '|');
                   if (s == NULL)
                           l = strlen(alias);
                   else
                           l = (size_t)(s - alias);
                   if (len == l && memcmp(alias, name, l) == 0)
                           return 1;
                   if (s == NULL)
                           break;
                   alias = s + 1;
           }
   
           /* No match. */
           return 0;
 }  }
   
 static int  static int
Line 213  _ti_dbgetterm(TERMINAL *term, const char
Line 280  _ti_dbgetterm(TERMINAL *term, const char
 {  {
         struct cdbr *db;          struct cdbr *db;
         const void *data;          const void *data;
         char *db_name;  
         const uint8_t *data8;          const uint8_t *data8;
         size_t len, klen;          size_t len, klen;
         int r;          int r;
   
         if (asprintf(&db_name, "%s.cdb", path) < 0)          if (snprintf(__ti_database, sizeof(__ti_database), "%s.cdb", path) < 0)
                 return -1;                  return -1;
           db = cdbr_open(__ti_database, CDBR_DEFAULT);
         db = cdbr_open(db_name, CDBR_DEFAULT);  
         free(db_name);  
         if (db == NULL)          if (db == NULL)
                 return -1;                  return -1;
   
           r = 0;
         klen = strlen(name) + 1;          klen = strlen(name) + 1;
         if (cdbr_find(db, name, klen, &data, &len) == -1)          if (cdbr_find(db, name, klen, &data, &len) == -1)
                 goto fail;                  goto out;
         data8 = data;          data8 = data;
         if (len == 0)          if (len == 0)
                 goto fail;                  goto out;
         /* Check for alias first, fall through to processing normal entries. */  
           /* If the entry is an alias, load the indexed terminfo description. */
         if (data8[0] == 2) {          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))                  if (cdbr_get(db, le32dec(data8 + 1), &data, &len))
                         goto fail;                          goto out;
                 data8 = data;                  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));  
         _ti_database = database;  
   
         r = _ti_readterm(term, data, len, flags);          r = _ti_readterm(term, data, len, flags);
         cdbr_close(db);          /* Ensure that this is the right terminfo description. */
         return r;          if (r == 1)
                   r = _ti_checkname(name, term->name, term->_alias);
           /* Remember the database we read. */
           if (r == 1)
                   _ti_database = __ti_database;
   
  fail:  out:
         cdbr_close(db);          cdbr_close(db);
         return 0;          return r;
 }  }
   
 static int  static int
 _ti_dbgettermp(TERMINAL *term, const char *path, const char *name, int flags)  _ti_dbgettermp(TERMINAL *term, const char *path, const char *name, int flags)
 {  {
         const char *p;          const char *p;
           char pathbuf[PATH_MAX];
         size_t l;          size_t l;
         int r, e;          int r, e;
   
Line 274  _ti_dbgettermp(TERMINAL *term, const cha
Line 331  _ti_dbgettermp(TERMINAL *term, const cha
         do {          do {
                 for (p = path; *path != '\0' && *path != ':'; path++)                  for (p = path; *path != '\0' && *path != ':'; path++)
                         continue;                          continue;
                 l = path - p;                  l = (size_t)(path - p);
                 if (l != 0 && l + 1 < sizeof(pathbuf)) {                  if (l != 0 && l + 1 < sizeof(pathbuf)) {
                         memcpy(pathbuf, p, l);                          memcpy(pathbuf, p, l);
                         pathbuf[l] = '\0';                          pathbuf[l] = '\0';
Line 289  _ti_dbgettermp(TERMINAL *term, const cha
Line 346  _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 *c, *e, h[PATH_MAX];          char *c, *e;
         TIC *tic;  
         uint8_t *f;  
         ssize_t len;  
   
         _DIAGASSERT(term != NULL);          _DIAGASSERT(term != NULL);
         _DIAGASSERT(name != NULL);          _DIAGASSERT(name != NULL);
   
         database[0] = '\0';  
         _ti_database = NULL;          _ti_database = NULL;
         r = 0;          r = 0;
   
         if ((e = getenv("TERMINFO")) != NULL && *e != '\0')          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;          c = NULL;
         if (e == NULL && (c = getenv("TERMCAP")) != NULL) {          if (e == NULL && (c = getenv("TERMCAP")) != NULL) {
Line 348  _ti_findterm(TERMINAL *term, const char 
Line 374  _ti_findterm(TERMINAL *term, const char 
         }          }
   
         if (e != NULL) {          if (e != NULL) {
                   TIC *tic;
   
                 if (c == NULL)                  if (c == NULL)
                         e = strdup(e); /* So we don't destroy env */                          e = strdup(e); /* So we don't destroy env */
                 if (e  == NULL)                  if (e == NULL)
                         tic = NULL;                          tic = NULL;
                 else                  else {
                         tic = _ti_compile(e, TIC_WARNING |                          tic = _ti_compile(e, TIC_WARNING |
                             TIC_ALIAS | TIC_DESCRIPTION | TIC_EXTRA);                              TIC_ALIAS | TIC_DESCRIPTION | TIC_EXTRA);
                 if (c == NULL && e != NULL)  
                         free(e);                          free(e);
                 if (tic != NULL && ticcmp(tic, name) == 0) {                  }
                   if (tic != NULL &&
                       _ti_checkname(name, tic->name, tic->alias) == 1)
                   {
                           uint8_t *f;
                           ssize_t len;
   
                         len = _ti_flatten(&f, tic);                          len = _ti_flatten(&f, tic);
                         if (len != -1) {                          if (len != -1) {
                                 r = _ti_readterm(term, (char *)f, (size_t)len,                                  r = _ti_readterm(term, (char *)f, (size_t)len,
Line 379  _ti_findterm(TERMINAL *term, const char 
Line 412  _ti_findterm(TERMINAL *term, const char 
                 return _ti_dbgettermp(term, e, name, flags);                  return _ti_dbgettermp(term, e, name, flags);
   
         if ((e = getenv("HOME")) != NULL) {          if ((e = getenv("HOME")) != NULL) {
                 snprintf(h, sizeof(h), "%s/.terminfo", e);                  char homepath[PATH_MAX];
                 r = _ti_dbgetterm(term, h, name, flags);  
                   if (snprintf(homepath, sizeof(homepath), "%s/.terminfo", e) > 0)
                           r = _ti_dbgetterm(term, homepath, name, flags);
         }          }
         if (r != 1)          if (r != 1)
                 r = _ti_dbgettermp(term, _PATH_TERMINFO, name, flags);                  r = _ti_dbgettermp(term, _PATH_TERMINFO, name, flags);
   
         return r;          return r;
   
 }  }
   
 int  int

Legend:
Removed from v.1.15  
changed lines
  Added in v.1.28

CVSweb <webmaster@jp.NetBSD.org>