Back to index

tetex-bin  3.0
Defines | Functions | Variables
read_entry.c File Reference
#include <curses.priv.h>
#include <tic.h>
#include <term_entry.h>

Go to the source code of this file.

Defines

#define tell(fd)   lseek(fd, 0, SEEK_CUR) /* lseek() is POSIX, but not tell() */
#define TYPE_CALLOC(type, elts)   typeCalloc(type, (unsigned)(elts))
#define BYTE(p, n)   (unsigned char)((p)[n])
#define IS_NEG1(p)   ((BYTE(p,0) == 0377) && (BYTE(p,1) == 0377))
#define IS_NEG2(p)   ((BYTE(p,0) == 0376) && (BYTE(p,1) == 0377))
#define LOW_MSB(p)   (BYTE(p,0) + 256*BYTE(p,1))
#define read_shorts(fd, buf, count)   (read(fd, buf, (unsigned) (count)*2) == (int) (count)*2)
#define even_boundary(value)   if ((value) % 2 != 0) read(fd, buf, 1)

Functions

 _nc_tic_dir (const char *path)
 _nc_keep_tic_dir (const char *path)
static void convert_shorts (char *buf, short *Numbers, int count)
static void convert_strings (char *buf, char **Strings, int count, int size, char *table)
static int read_termtype (int fd, TERMTYPE *ptr)
 _nc_read_file_entry (const char *const filename, TERMTYPE *ptr)
static int _nc_read_tic_entry (char *const filename, const char *const dir, const char *ttn, TERMTYPE *const tp)
static int _nc_read_terminfo_dirs (const char *dirs, char *const filename, const char *const ttn, TERMTYPE *const tp)
 _nc_read_entry (const char *const tn, char *const filename, TERMTYPE *const tp)

Variables

static bool have_tic_directory = FALSE
static bool keep_tic_directory = FALSE

Define Documentation

#define BYTE (   p,
  n 
)    (unsigned char)((p)[n])

Definition at line 63 of file read_entry.c.

#define even_boundary (   value)    if ((value) % 2 != 0) read(fd, buf, 1)

Definition at line 154 of file read_entry.c.

#define IS_NEG1 (   p)    ((BYTE(p,0) == 0377) && (BYTE(p,1) == 0377))

Definition at line 65 of file read_entry.c.

#define IS_NEG2 (   p)    ((BYTE(p,0) == 0376) && (BYTE(p,1) == 0377))

Definition at line 66 of file read_entry.c.

#define LOW_MSB (   p)    (BYTE(p,0) + 256*BYTE(p,1))

Definition at line 67 of file read_entry.c.

#define read_shorts (   fd,
  buf,
  count 
)    (read(fd, buf, (unsigned) (count)*2) == (int) (count)*2)

Definition at line 151 of file read_entry.c.

#define tell (   fd)    lseek(fd, 0, SEEK_CUR) /* lseek() is POSIX, but not tell() */

Definition at line 48 of file read_entry.c.

#define TYPE_CALLOC (   type,
  elts 
)    typeCalloc(type, (unsigned)(elts))

Definition at line 51 of file read_entry.c.


Function Documentation

_nc_keep_tic_dir ( const char *  path)

Definition at line 100 of file read_entry.c.

Here is the call graph for this function:

Here is the caller graph for this function:

_nc_read_entry ( const char *const  tn,
char *const  filename,
TERMTYPE *const  tp 
)

Definition at line 468 of file read_entry.c.

{
    char *envp;
    char ttn[PATH_MAX];

    if (strlen(tn) == 0
       || strcmp(tn, ".") == 0
       || strcmp(tn, "..") == 0
       || _nc_pathlast(tn) != 0) {
       T(("illegal or missing entry name '%s'", tn));
       return 0;
    }

    /* truncate the terminal name to prevent buffer overflow */
    (void) sprintf(ttn, "%c/%.*s", *tn, (int) sizeof(ttn) - 3, tn);

    /* This is System V behavior, in conjunction with our requirements for
     * writing terminfo entries.
     */
    if (have_tic_directory
       && _nc_read_tic_entry(filename, _nc_tic_dir(0), ttn, tp) == 1)
       return 1;

    if (use_terminfo_vars()) {
       if ((envp = getenv("TERMINFO")) != 0
           && _nc_read_tic_entry(filename, _nc_tic_dir(envp), ttn, tp) == 1)
           return 1;

       /* this is an ncurses extension */
       if ((envp = _nc_home_terminfo()) != 0) {
           if (_nc_read_tic_entry(filename, envp, ttn, tp) == 1) {
              return 1;
           }
       }

       /* this is an ncurses extension */
       if ((envp = getenv("TERMINFO_DIRS")) != 0)
           return _nc_read_terminfo_dirs(envp, filename, ttn, tp);
    }

    /* Try the system directory.  Note that the TERMINFO_DIRS value, if
     * defined by the configure script, begins with a ":", which will be
     * interpreted as TERMINFO.
     */
#ifdef TERMINFO_DIRS
    return _nc_read_terminfo_dirs(TERMINFO_DIRS, filename, ttn, tp);
#else
    return _nc_read_tic_entry(filename, TERMINFO, ttn, tp);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

_nc_read_file_entry ( const char *const  filename,
TERMTYPE *  ptr 
)

Definition at line 386 of file read_entry.c.

{
    int code, fd = -1;

    if (_nc_access(filename, R_OK) < 0
       || (fd = open(filename, O_RDONLY | O_BINARY)) < 0) {
       T(("cannot open terminfo %s (errno=%d)", filename, errno));
       code = 0;
    } else {
       T(("read terminfo %s", filename));
       if ((code = read_termtype(fd, ptr)) == 0)
           _nc_free_termtype(ptr);
       close(fd);
    }

    return (code);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int _nc_read_terminfo_dirs ( const char *  dirs,
char *const  filename,
const char *const  ttn,
TERMTYPE *const  tp 
) [static]

Definition at line 426 of file read_entry.c.

{
    char *list, *a;
    const char *b;
    int code = 0;

    /* we'll modify the argument, so we must copy */
    if ((b = a = list = strdup(dirs)) == NULL)
       return (0);

    for (;;) {
       int c = *a;
       if (c == 0 || c == NCURSES_PATHSEP) {
           *a = 0;
           if ((b + 1) >= a)
              b = TERMINFO;
           if (_nc_read_tic_entry(filename, b, ttn, tp) == 1) {
              code = 1;
              break;
           }
           b = a + 1;
           if (c == 0)
              break;
       }
       a++;
    }

    free(list);
    return (code);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int _nc_read_tic_entry ( char *const  filename,
const char *const  dir,
const char *  ttn,
TERMTYPE *const  tp 
) [static]

Definition at line 410 of file read_entry.c.

{
    int need = 2 + strlen(dir) + strlen(ttn);

    if (need > PATH_MAX)
       return 0;
    (void) sprintf(filename, "%s/%s", dir, ttn);
    return _nc_read_file_entry(filename, tp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

_nc_tic_dir ( const char *  path)

Definition at line 77 of file read_entry.c.

{
    static const char *result = TERMINFO;

    if (!keep_tic_directory) {
       if (path != 0) {
           result = path;
           have_tic_directory = TRUE;
       } else if (!have_tic_directory && use_terminfo_vars()) {
           char *envp;
           if ((envp = getenv("TERMINFO")) != 0)
              return _nc_tic_dir(envp);
       }
    }
    return result;
}

Here is the caller graph for this function:

static void convert_shorts ( char *  buf,
short Numbers,
int  count 
) [static]

Definition at line 107 of file read_entry.c.

{
    int i;
    for (i = 0; i < count; i++) {
       if (IS_NEG1(buf + 2 * i))
           Numbers[i] = ABSENT_NUMERIC;
       else if (IS_NEG2(buf + 2 * i))
           Numbers[i] = CANCELLED_NUMERIC;
       else
           Numbers[i] = LOW_MSB(buf + 2 * i);
       TR(TRACE_DATABASE, ("get Numbers[%d]=%d", i, Numbers[i]));
    }
}

Here is the caller graph for this function:

static void convert_strings ( char *  buf,
char **  Strings,
int  count,
int  size,
char *  table 
) [static]

Definition at line 122 of file read_entry.c.

{
    int i;
    char *p;

    for (i = 0; i < count; i++) {
       if (IS_NEG1(buf + 2 * i)) {
           Strings[i] = ABSENT_STRING;
       } else if (IS_NEG2(buf + 2 * i)) {
           Strings[i] = CANCELLED_STRING;
       } else if (LOW_MSB(buf + 2 * i) > size) {
           Strings[i] = ABSENT_STRING;
       } else {
           Strings[i] = (LOW_MSB(buf + 2 * i) + table);
           TR(TRACE_DATABASE, ("Strings[%d] = %s", i, _nc_visbuf(Strings[i])));
       }

       /* make sure all strings are NUL terminated */
       if (VALID_STRING(Strings[i])) {
           for (p = Strings[i]; p <= table + size; p++)
              if (*p == '\0')
                  break;
           /* if there is no NUL, ignore the string */
           if (p > table + size)
              Strings[i] = ABSENT_STRING;
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int read_termtype ( int  fd,
TERMTYPE *  ptr 
) [static]

Definition at line 158 of file read_entry.c.

{
    int name_size, bool_count, num_count, str_count, str_size;
    int i;
    char buf[MAX_ENTRY_SIZE + 1];
    unsigned want, have;

    TR(TRACE_DATABASE, ("READ termtype header @%ld", (long) tell(fd)));

    memset(ptr, 0, sizeof(*ptr));

    /* grab the header */
    if (!read_shorts(fd, buf, 6)
       || LOW_MSB(buf) != MAGIC) {
       return (0);
    }

    name_size = LOW_MSB(buf + 2);
    bool_count = LOW_MSB(buf + 4);
    num_count = LOW_MSB(buf + 6);
    str_count = LOW_MSB(buf + 8);
    str_size = LOW_MSB(buf + 10);

    TR(TRACE_DATABASE,
       ("TERMTYPE name_size=%d, bool=%d/%d, num=%d/%d str=%d/%d(%d)",
       name_size, bool_count, BOOLCOUNT, num_count, NUMCOUNT,
       str_count, STRCOUNT, str_size));
    if (name_size < 0
       || bool_count < 0
       || num_count < 0
       || str_count < 0
       || str_size < 0) {
       return (0);
    }

    if (str_size) {
       /* try to allocate space for the string table */
       if (str_count * 2 >= (int) sizeof(buf)
           || (ptr->str_table = typeMalloc(char, (unsigned) str_size)) == 0) {
           return (0);
       }
    } else {
       str_count = 0;
    }

    /* grab the name (a null-terminated string) */
    want = min(MAX_NAME_SIZE, (unsigned) name_size);
    if ((have = read(fd, buf, want)) != want) {
       memset(buf + have, 0, want - have);
    }
    buf[want] = '\0';
    ptr->term_names = TYPE_CALLOC(char, strlen(buf) + 1);
    if (ptr->term_names == NULL) {
       return (0);
    }
    (void) strcpy(ptr->term_names, buf);
    if (have > MAX_NAME_SIZE)
       lseek(fd, (off_t) (have - MAX_NAME_SIZE), 1);

    /* grab the booleans */
    if ((ptr->Booleans = TYPE_CALLOC(char, max(BOOLCOUNT, bool_count))) == 0
       || read(fd, ptr->Booleans, (unsigned) bool_count) < bool_count) {
       return (0);
    }

    /*
     * If booleans end on an odd byte, skip it.  The machine they
     * originally wrote terminfo on must have been a 16-bit
     * word-oriented machine that would trap out if you tried a
     * word access off a 2-byte boundary.
     */
    even_boundary(name_size + bool_count);

    /* grab the numbers */
    if ((ptr->Numbers = TYPE_CALLOC(short, max(NUMCOUNT, num_count))) == 0
       || !read_shorts(fd, buf, num_count)) {
       return (0);
    }
    convert_shorts(buf, ptr->Numbers, num_count);

    if ((ptr->Strings = TYPE_CALLOC(char *, max(STRCOUNT, str_count))) == 0)
         return (0);

    if (str_count) {
       /* grab the string offsets */
       if (!read_shorts(fd, buf, str_count)) {
           return (0);
       }
       /* finally, grab the string table itself */
       if (read(fd, ptr->str_table, (unsigned) str_size) != str_size)
           return (0);
       convert_strings(buf, ptr->Strings, str_count, str_size, ptr->str_table);
    }
#if NCURSES_XNAMES

    ptr->num_Booleans = BOOLCOUNT;
    ptr->num_Numbers = NUMCOUNT;
    ptr->num_Strings = STRCOUNT;

    /*
     * Read extended entries, if any, after the normal end of terminfo data.
     */
    even_boundary(str_size);
    TR(TRACE_DATABASE, ("READ extended_header @%ld", (long) tell(fd)));
    if (_nc_user_definable && read_shorts(fd, buf, 5)) {
       int ext_bool_count = LOW_MSB(buf + 0);
       int ext_num_count = LOW_MSB(buf + 2);
       int ext_str_count = LOW_MSB(buf + 4);
       int ext_str_size = LOW_MSB(buf + 6);
       int ext_str_limit = LOW_MSB(buf + 8);
       unsigned need = (ext_bool_count + ext_num_count + ext_str_count);
       int base = 0;

       if (need >= sizeof(buf)
           || ext_str_size >= (int) sizeof(buf)
           || ext_str_limit >= (int) sizeof(buf)
           || ext_bool_count < 0
           || ext_num_count < 0
           || ext_str_count < 0
           || ext_str_size < 0
           || ext_str_limit < 0)
           return (0);

       ptr->num_Booleans = BOOLCOUNT + ext_bool_count;
       ptr->num_Numbers = NUMCOUNT + ext_num_count;
       ptr->num_Strings = STRCOUNT + ext_str_count;

       ptr->Booleans = typeRealloc(char, ptr->num_Booleans, ptr->Booleans);
       ptr->Numbers = typeRealloc(short, ptr->num_Numbers, ptr->Numbers);
       ptr->Strings = typeRealloc(char *, ptr->num_Strings, ptr->Strings);

       TR(TRACE_DATABASE, ("extended header is %d/%d/%d(%d:%d)",
                         ext_bool_count, ext_num_count, ext_str_count,
                         ext_str_size, ext_str_limit));

       TR(TRACE_DATABASE, ("READ %d extended-booleans @%ld",
                         ext_bool_count, (long) tell(fd)));
       if ((ptr->ext_Booleans = ext_bool_count) != 0) {
           if (read(fd, ptr->Booleans + BOOLCOUNT, (unsigned)
                   ext_bool_count) != ext_bool_count)
              return (0);
       }
       even_boundary(ext_bool_count);

       TR(TRACE_DATABASE, ("READ %d extended-numbers @%ld",
                         ext_num_count, (long) tell(fd)));
       if ((ptr->ext_Numbers = ext_num_count) != 0) {
           if (!read_shorts(fd, buf, ext_num_count))
              return (0);
           TR(TRACE_DATABASE, ("Before converting extended-numbers"));
           convert_shorts(buf, ptr->Numbers + NUMCOUNT, ext_num_count);
       }

       TR(TRACE_DATABASE, ("READ extended-offsets @%ld", (long) tell(fd)));
       if ((ext_str_count || need)
           && !read_shorts(fd, buf, ext_str_count + need))
           return (0);

       TR(TRACE_DATABASE, ("READ %d bytes of extended-strings @%ld",
                         ext_str_limit, (long) tell(fd)));

       if (ext_str_limit) {
           if ((ptr->ext_str_table = typeMalloc(char, ext_str_limit)) == 0)
                return (0);
           if (read(fd, ptr->ext_str_table, (unsigned) ext_str_limit) != ext_str_limit)
              return (0);
           TR(TRACE_DATABASE, ("first extended-string is %s", _nc_visbuf(ptr->ext_str_table)));
       }

       if ((ptr->ext_Strings = ext_str_count) != 0) {
           TR(TRACE_DATABASE,
              ("Before computing extended-string capabilities str_count=%d, ext_str_count=%d",
              str_count, ext_str_count));
           convert_strings(buf, ptr->Strings + str_count, ext_str_count,
                         ext_str_limit, ptr->ext_str_table);
           for (i = ext_str_count - 1; i >= 0; i--) {
              TR(TRACE_DATABASE, ("MOVE from [%d:%d] %s",
                                i, i + str_count,
                                _nc_visbuf(ptr->Strings[i + str_count])));
              ptr->Strings[i + STRCOUNT] = ptr->Strings[i + str_count];
              if (VALID_STRING(ptr->Strings[i + STRCOUNT]))
                  base += (strlen(ptr->Strings[i + STRCOUNT]) + 1);
              TR(TRACE_DATABASE, ("... to    [%d] %s",
                                i + STRCOUNT,
                                _nc_visbuf(ptr->Strings[i + STRCOUNT])));
           }
       }

       if (need) {
           if ((ptr->ext_Names = TYPE_CALLOC(char *, need)) == 0)
                return (0);
           TR(TRACE_DATABASE,
              ("ext_NAMES starting @%d in extended_strings, first = %s",
              base, _nc_visbuf(ptr->ext_str_table + base)));
           convert_strings(buf + (2 * ext_str_count),
                         ptr->ext_Names,
                         (int) need,
                         ext_str_limit, ptr->ext_str_table + base);
       }

       T(("...done reading terminfo bool %d(%d) num %d(%d) str %d(%d)",
          ptr->num_Booleans, ptr->ext_Booleans,
          ptr->num_Numbers, ptr->ext_Numbers,
          ptr->num_Strings, ptr->ext_Strings));

       TR(TRACE_DATABASE, ("extend: num_Booleans:%d", ptr->num_Booleans));
    } else
#endif /* NCURSES_XNAMES */
    {
       T(("...done reading terminfo bool %d num %d str %d",
          bool_count, num_count, str_count));
#if NCURSES_XNAMES
       TR(TRACE_DATABASE, ("normal: num_Booleans:%d", ptr->num_Booleans));
#endif
    }

    for (i = bool_count; i < BOOLCOUNT; i++)
       ptr->Booleans[i] = FALSE;
    for (i = num_count; i < NUMCOUNT; i++)
       ptr->Numbers[i] = ABSENT_NUMERIC;
    for (i = str_count; i < STRCOUNT; i++)
       ptr->Strings[i] = ABSENT_STRING;

    return (1);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 69 of file read_entry.c.

Definition at line 70 of file read_entry.c.