#ifdef HAVE_CONFIG_H
#include <config.h>
#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#else
extern char *getenv ();
extern char *malloc ();
extern char *realloc ();
#endif
#if defined (HAVE_STRING_H)
#include <string.h>
#endif
#if !defined (HAVE_BCOPY) && (defined (HAVE_STRING_H) || defined (STDC_HEADERS))
# define bcopy(s, d, n) memcpy ((d), (s), (n))
#endif
#else
#ifdef STDC_HEADERS
#include <stdlib.h>
#include <string.h>
#else
char *getenv ();
char *malloc ();
char *realloc ();
#endif
#if (defined(HAVE_STRING_H) || defined(STDC_HEADERS)) && !defined(bcopy)
#define bcopy(s, d, n) memcpy ((d), (s), (n))
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef _POSIX_VERSION
#include <fcntl.h>
#endif
#endif
#ifndef NULL
#define NULL (char *) 0
#endif
#ifndef O_RDONLY
#define O_RDONLY 0
#endif
#ifndef BUFSIZE
#ifdef DEBUG
#define BUFSIZE bufsize
int bufsize = 128;
#else
#define BUFSIZE 2048
#endif
#endif
#include "ltcap.h"
#ifndef TERMCAP_FILE
#define TERMCAP_FILE "/etc/termcap"
#endif
#ifndef emacs
static void
memory_out ()
{
write (2, "virtual memory exhausted\n", 25);
exit (1);
}
static char *
xmalloc (size)
unsigned size;
{
register char *tem = malloc (size);
if (!tem)
memory_out ();
return tem;
}
static char *
xrealloc (ptr, size)
char *ptr;
unsigned size;
{
register char *tem = realloc (ptr, size);
if (!tem)
memory_out ();
return tem;
}
#endif
static char *term_entry;
static char *tgetst1 ();
static char *
find_capability (bp, cap)
register char *bp, *cap;
{
for (; *bp; bp++)
if (bp[0] == ':'
&& bp[1] == cap[0]
&& bp[2] == cap[1])
return &bp[4];
return NULL;
}
__private_extern__
int
tgetnum (cap)
char *cap;
{
register char *ptr = find_capability (term_entry, cap);
if (!ptr || ptr[-1] != '#')
return -1;
return atoi (ptr);
}
__private_extern__
int
tgetflag (cap)
char *cap;
{
register char *ptr = find_capability (term_entry, cap);
return ptr && ptr[-1] == ':';
}
__private_extern__
char *
tgetstr (cap, area)
char *cap;
char **area;
{
register char *ptr = find_capability (term_entry, cap);
if (!ptr || (ptr[-1] != '=' && ptr[-1] != '~'))
return NULL;
return tgetst1 (ptr, area);
}
static char esctab[]
= " \007\010 \033\014 \
\012 \
\015 \011 \013 \
";
static char *
tgetst1 (ptr, area)
char *ptr;
char **area;
{
register char *p, *r;
register int c;
register int size;
char *ret;
register int c1;
if (!ptr)
return NULL;
if (!area)
{
p = ptr;
while ((c = *p++) && c != ':' && c != '\n')
;
ret = (char *) xmalloc (p - ptr + 1);
}
else
ret = *area;
p = ptr;
r = ret;
while ((c = *p++) && c != ':' && c != '\n')
{
if (c == '^')
{
c = *p++;
if (c == '?')
c = 0177;
else
c &= 037;
}
else if (c == '\\')
{
c = *p++;
if (c >= '0' && c <= '7')
{
c -= '0';
size = 0;
while (++size < 3 && (c1 = *p) >= '0' && c1 <= '7')
{
c *= 8;
c += c1 - '0';
p++;
}
}
else if (c >= 0100 && c < 0200)
{
c1 = esctab[(c & ~040) - 0100];
if (c1 != ' ')
c = c1;
}
}
*r++ = c;
}
*r = '\0';
if (area)
*area = r + 1;
return ret;
}
short ospeed;
int tputs_baud_rate;
__private_extern__ char PC = '\0';
static int speeds[] =
{
#ifdef VMS
0, 50, 75, 110, 134, 150, -3, -6, -12, -18,
-20, -24, -36, -48, -72, -96, -192
#else
0, 50, 75, 110, 135, 150, -2, -3, -6, -12,
-18, -24, -48, -96, -192, -288, -384, -576, -1152
#endif
};
__private_extern__
void
tputs (str, nlines, outfun)
register char *str;
int nlines;
register int (*outfun) ();
{
register int padcount = 0;
register int speed;
#ifdef emacs
extern baud_rate;
speed = baud_rate;
if (speed > 10000)
speed = - speed / 100;
#else
if (ospeed == 0)
speed = tputs_baud_rate;
else if (ospeed > 0 && ospeed < (sizeof speeds / sizeof speeds[0]))
speed = speeds[ospeed];
else
speed = 0;
#endif
if (!str)
return;
while (*str >= '0' && *str <= '9')
{
padcount += *str++ - '0';
padcount *= 10;
}
if (*str == '.')
{
str++;
padcount += *str++ - '0';
}
if (*str == '*')
{
str++;
padcount *= nlines;
}
while (*str)
(*outfun) (*str++);
padcount *= speed;
padcount += 500;
padcount /= 1000;
if (speed < 0)
padcount = -padcount;
else
{
padcount += 50;
padcount /= 100;
}
while (padcount-- > 0)
(*outfun) (PC);
}
struct buffer
{
char *beg;
int size;
char *ptr;
int ateof;
int full;
};
static int scan_file ();
static char *gobble_line ();
static int compare_contin ();
static int name_match ();
#ifdef VMS
#include <rmsdef.h>
#include <fab.h>
#include <nam.h>
static int
valid_filename_p (fn)
char *fn;
{
struct FAB fab = cc$rms_fab;
struct NAM nam = cc$rms_nam;
char esa[NAM$C_MAXRSS];
fab.fab$l_fna = fn;
fab.fab$b_fns = strlen(fn);
fab.fab$l_nam = &nam;
fab.fab$l_fop = FAB$M_NAM;
nam.nam$l_esa = esa;
nam.nam$b_ess = sizeof esa;
return SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL;
}
#else
#ifdef MSDOS
static int
valid_filename_p (fn)
char *fn;
{
return *fn == '\\' || *fn == '/' ||
(*fn >= 'A' && *fn <= 'z' && fn[1] == ':');
}
#else
#define valid_filename_p(fn) (*(fn) == '/')
#endif
#endif
__private_extern__
int
tgetent (bp, name)
char *bp, *name;
{
register char *termcap_name;
register int fd;
struct buffer buf;
register char *bp1;
char *bp2;
char *term;
int malloc_size = 0;
register int c;
char *tcenv;
char *indirect = NULL;
int filep;
#ifdef INTERNAL_TERMINAL
if (!strcmp (name, "internal"))
{
term = INTERNAL_TERMINAL;
if (!bp)
{
malloc_size = 1 + strlen (term);
bp = (char *) xmalloc (malloc_size);
}
strcpy (bp, term);
goto ret;
}
#endif
if (bp)
term_entry = bp;
termcap_name = getenv ("TERMCAP");
if (termcap_name && *termcap_name == '\0')
termcap_name = NULL;
#if 0
#if defined (MSDOS) && !defined (TEST)
if (termcap_name && (*termcap_name == '\\'
|| *termcap_name == '/'
|| termcap_name[1] == ':'))
dostounix_filename(termcap_name);
#endif
#endif
filep = termcap_name && valid_filename_p (termcap_name);
if (termcap_name && !filep && !strcmp (name, getenv ("TERM")))
{
indirect = tgetst1 (find_capability (termcap_name, "tc"), (char **) 0);
if (!indirect)
{
if (!bp)
bp = termcap_name;
else
strcpy (bp, termcap_name);
goto ret;
}
else
{
tcenv = termcap_name;
termcap_name = NULL;
}
}
if (!termcap_name || !filep)
termcap_name = TERMCAP_FILE;
#ifdef MSDOS
fd = open (termcap_name, O_RDONLY|O_TEXT, 0);
#else
fd = open (termcap_name, O_RDONLY, 0);
#endif
if (fd < 0)
return -1;
buf.size = BUFSIZE;
buf.beg = (char *) xmalloc (buf.size + 1);
term = indirect ? indirect : name;
if (!bp)
{
malloc_size = indirect ? strlen (tcenv) + 1 : buf.size;
bp = (char *) xmalloc (malloc_size);
}
bp1 = bp;
if (indirect)
{
strcpy (bp, tcenv);
bp1 += strlen (tcenv);
}
while (term)
{
if (scan_file (term, fd, &buf) == 0)
{
close (fd);
free (buf.beg);
if (malloc_size)
free (bp);
return 0;
}
if (term != name)
free (term);
if (malloc_size)
{
malloc_size = bp1 - bp + buf.size;
termcap_name = (char *) xrealloc (bp, malloc_size);
bp1 += termcap_name - bp;
bp = termcap_name;
}
bp2 = bp1;
termcap_name = buf.ptr;
while ((*bp1++ = c = *termcap_name++) && c != '\n')
if (c == '\\' && *termcap_name == '\n')
{
bp1--;
termcap_name++;
}
*bp1 = '\0';
term = tgetst1 (find_capability (bp2, "tc"), (char **) 0);
}
close (fd);
free (buf.beg);
if (malloc_size)
bp = (char *) xrealloc (bp, bp1 - bp + 1);
ret:
term_entry = bp;
return 1;
}
static int
scan_file (str, fd, bufp)
char *str;
int fd;
register struct buffer *bufp;
{
register char *end;
bufp->ptr = bufp->beg;
bufp->full = 0;
bufp->ateof = 0;
*bufp->ptr = '\0';
lseek (fd, 0L, 0);
while (!bufp->ateof)
{
end = NULL;
do
{
end = gobble_line (fd, bufp, end);
}
while (!bufp->ateof && end[-2] == '\\');
if (*bufp->ptr != '#'
&& name_match (bufp->ptr, str))
return 1;
bufp->ptr = end;
}
return 0;
}
static int
name_match (line, name)
char *line, *name;
{
register char *tem;
if (!compare_contin (line, name))
return 1;
for (tem = line; *tem && *tem != '\n' && *tem != ':'; tem++)
if (*tem == '|' && !compare_contin (tem + 1, name))
return 1;
return 0;
}
static int
compare_contin (str1, str2)
register char *str1, *str2;
{
register int c1, c2;
while (1)
{
c1 = *str1++;
c2 = *str2++;
while (c1 == '\\' && *str1 == '\n')
{
str1++;
while ((c1 = *str1++) == ' ' || c1 == '\t');
}
if (c2 == '\0')
{
if (c1 == '|' || c1 == ':')
return 0;
else
return 1;
}
else if (c1 != c2)
return 1;
}
}
static char *
gobble_line (fd, bufp, append_end)
int fd;
register struct buffer *bufp;
char *append_end;
{
register char *end;
register int nread;
register char *buf = bufp->beg;
register char *tem;
if (!append_end)
append_end = bufp->ptr;
while (1)
{
end = append_end;
while (*end && *end != '\n') end++;
if (*end)
break;
if (bufp->ateof)
return buf + bufp->full;
if (bufp->ptr == buf)
{
if (bufp->full == bufp->size)
{
bufp->size *= 2;
tem = (char *) xrealloc (buf, bufp->size + 1);
bufp->ptr = (bufp->ptr - buf) + tem;
append_end = (append_end - buf) + tem;
bufp->beg = buf = tem;
}
}
else
{
append_end -= bufp->ptr - buf;
bcopy (bufp->ptr, buf, bufp->full -= bufp->ptr - buf);
bufp->ptr = buf;
}
if (!(nread = read (fd, buf + bufp->full, bufp->size - bufp->full)))
bufp->ateof = 1;
bufp->full += nread;
buf[bufp->full] = '\0';
}
return end + 1;
}
#ifdef TEST
#ifdef NULL
#undef NULL
#endif
#include <stdio.h>
main (argc, argv)
int argc;
char **argv;
{
char *term;
char *buf;
term = argv[1];
printf ("TERM: %s\n", term);
buf = (char *) tgetent (0, term);
if ((int) buf <= 0)
{
printf ("No entry.\n");
return 0;
}
printf ("Entry: %s\n", buf);
tprint ("cm");
tprint ("AL");
printf ("co: %d\n", tgetnum ("co"));
printf ("am: %d\n", tgetflag ("am"));
}
tprint (cap)
char *cap;
{
char *x = tgetstr (cap, 0);
register char *y;
printf ("%s: ", cap);
if (x)
{
for (y = x; *y; y++)
if (*y <= ' ' || *y == 0177)
printf ("\\%0o", *y);
else
putchar (*y);
free (x);
}
else
printf ("none");
putchar ('\n');
}
#endif