#include <curses.h>
#include <term.h>
#include <fcntl.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <locale.h>
extern int tigetnum();
static int outputcap(char *cap, int argc, char **argv);
static int allnumeric(char *string);
static int getpad(char *cap);
static void setdelay();
static void settabs();
static void cat(char *file);
static void initterm();
static void reset_term();
static char *progname;
static int CurrentBaudRate;
static int reset = 0;
static int fildes = 1;
int
main(int argc, char **argv)
{
int i, std_argc;
char *term = getenv("TERM");
char *cap, std_input = FALSE;
int setuperr;
(void) setlocale(LC_ALL, "");
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
(void) textdomain(TEXT_DOMAIN);
progname = argv[0];
while ((i = getopt(argc, argv, "ST:")) != EOF) {
switch (i) {
case 'T':
fildes = -1;
(void) putenv("LINES=");
(void) putenv("COLUMNS=");
term = optarg;
break;
case 'S':
std_input = TRUE;
break;
case '?':
usage:
default:
(void) fprintf(stderr, gettext(
"usage:\t%s [-T [term]] capname "
"[parm argument...]\n"), progname);
(void) fprintf(stderr, gettext("OR:\t%s -S <<\n"),
progname);
exit(2);
}
}
if (!term || !*term) {
(void) fprintf(stderr,
gettext("%s: No value for $TERM and no -T specified\n"),
progname);
exit(2);
}
(void) setupterm(term, fildes, &setuperr);
switch (setuperr) {
case -2:
(void) fprintf(stderr,
gettext("%s: unreadable terminal descriptor \"%s\"\n"),
progname, term);
exit(3);
break;
case -1:
(void) fprintf(stderr,
gettext("%s: no terminfo database\n"), progname);
exit(3);
break;
case 0:
(void) fprintf(stderr,
gettext("%s: unknown terminal \"%s\"\n"),
progname, term);
exit(3);
}
reset_shell_mode();
if (!std_input) {
if (argc == optind)
goto usage;
cap = argv[optind++];
if (strcmp(cap, "init") == 0)
initterm();
else if (strcmp(cap, "reset") == 0)
reset_term();
else if (strcmp(cap, "longname") == 0)
(void) printf("%s\n", longname());
else
exit(outputcap(cap, argc, argv));
return (0);
} else {
char buff[128];
char **v;
v = (char **)malloc(10 * sizeof (char *));
for (i = 0; i < 10; i++)
v[i] = (char *)malloc(32 * sizeof (char));
while (fgets(buff, sizeof (buff), stdin) != NULL) {
if ((std_argc =
sscanf(buff,
"%31s %31s %31s %31s %31s %31s %31s %31s "
"%31s %31s",
v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7],
v[8], v[9])) < 1) {
continue;
}
cap = v[0];
optind = 1;
if (strcmp(cap, "init") == 0) {
initterm();
} else if (strcmp(cap, "reset") == 0) {
reset_term();
} else if (strcmp(cap, "longname") == 0) {
(void) printf("%s\n", longname());
} else {
(void) outputcap(cap, std_argc, v);
}
(void) fflush(stdout);
}
return (0);
}
}
static long parm[9] = {
0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int
outputcap(char *cap, int argc, char **argv)
{
int parmset = 0;
char *thisstr;
int i;
if ((i = tigetflag(cap)) >= 0)
return (1 - i);
if ((i = tigetnum(cap)) >= -1) {
(void) printf("%d\n", i);
return (0);
}
if ((thisstr = tigetstr(cap)) != (char *)-1) {
if (!thisstr) {
return (1);
}
for (parmset = 0; optind < argc; optind++, parmset++)
if (allnumeric(argv[optind]))
parm[parmset] = atoi(argv[optind]);
else
parm[parmset] = (int)argv[optind];
if (parmset)
putp(tparm(thisstr,
parm[0], parm[1], parm[2], parm[3],
parm[4], parm[5], parm[6], parm[7], parm[8]));
else
putp(thisstr);
return (0);
}
(void) fprintf(stderr,
gettext("%s: unknown terminfo capability '%s'\n"), progname, cap);
exit(4);
}
static int
allnumeric(char *string)
{
if (*string) {
while (*string) {
if (!isdigit(*string++)) {
return (0);
}
}
return (1);
} else {
return (0);
}
}
struct delay
{
int d_delay;
int d_bits;
};
static int speeds[] = {
0,
50,
75,
110,
134,
150,
200,
300,
600,
1200,
1800,
2400,
4800,
9600,
19200,
38400,
57600,
76800,
115200,
153600,
230400,
307200,
460800,
921600,
1000000,
1152000,
1500000,
2000000,
2500000,
3000000,
3500000,
4000000,
0
};
#if defined(SYSV) || defined(USG)
static int CRbits = CRDLY;
static struct delay CRdelay[] =
{
0, CR0,
80, CR1,
100, CR2,
150, CR3,
-1
};
static int NLbits = NLDLY;
static struct delay NLdelay[] =
{
0, NL0,
100, NL1,
-1
};
static int BSbits = BSDLY;
static struct delay BSdelay[] =
{
0, BS0,
50, BS1,
-1
};
static int TBbits = TABDLY;
static struct delay TBdelay[] =
{
0, TAB0,
11, TAB1,
100, TAB2,
-1
};
static int FFbits = FFDLY;
static struct delay FFdelay[] =
{
0, FF0,
2000, FF1,
-1
};
#else
int CRbits = CRDELAY;
struct delay CRdelay[] =
{
0, CR0,
9, CR3,
80, CR1,
160, CR2,
-1
};
int NLbits = NLDELAY;
struct delay NLdelay[] =
{
0, NL0,
66, NL1,
100, NL2,
-1
};
int TBbits = TBDELAY;
struct delay TBdelay[] =
{
0, TAB0,
11, TAB1,
-1
};
int FFbits = VTDELAY;
struct delay FFdelay[] =
{
0, FF0,
2000, FF1,
-1
};
#endif
static int
getpad(char *cap)
{
int padding = 0;
if (padding_baud_rate > CurrentBaudRate || cap == NULL)
return (0);
while (*cap) {
if ((cap[0] == '$') && (cap[1] == '<')) {
cap++;
cap++;
padding += atoi(cap);
while (isdigit (*cap))
cap++;
while (*cap == '.' || *cap == '/' || *cap == '*' ||
isdigit(*cap))
cap++;
while (*cap == '>')
cap++;
} else {
cap++;
}
}
return (padding);
}
static void
setdelay(delay, delaytable, bits, flags)
register int delay;
struct delay delaytable[];
int bits;
#ifdef SYSV
tcflag_t *flags;
#else
unsigned short *flags;
#endif
{
register struct delay *p;
register struct delay *lastdelay;
*flags &= ~bits;
for (lastdelay = p = delaytable;
(p -> d_delay >= 0) && (p -> d_delay < delay);
p++) {
lastdelay = p;
}
*flags |= lastdelay -> d_bits;
}
static void
settabs()
{
register int c;
if (init_tabs == 8)
return;
if (set_tab) {
if (carriage_return)
putp(carriage_return);
else
(void) putchar('\r');
if (clear_all_tabs)
putp(clear_all_tabs);
for (c = 8; c < columns; c += 8) {
(void) fputs(" ", stdout);
putp(set_tab);
}
if (carriage_return)
putp(carriage_return);
else
(void) putchar('\r');
}
}
static void
cat(file)
char *file;
{
register int fd;
register ssize_t i;
char buf[BUFSIZ];
fd = open(file, O_RDONLY);
if (fd < 0) {
perror("Cannot open initialization file");
} else {
while ((i = read(fd, buf, BUFSIZ)) > (ssize_t)0)
(void) write(fileno(stdout), buf, (unsigned)i);
(int)close(fd);
}
}
static void
initterm()
{
register int filedes;
#if defined(SYSV) || defined(USG)
struct termio termmode;
struct termios termmodes;
int i;
int istermios = -1;
#define GTTY(fd, mode) ioctl(fd, TCGETA, mode)
#define GTTYS(fd, mode) \
(istermios = ioctl(fd, TCGETS, mode))
#define STTY(fd, mode) ioctl(fd, TCSETAW, mode)
#define STTYS(fd, mode) ioctl(fd, TCSETSW, mode)
#define SPEED(mode) (mode.c_cflag & CBAUD)
#define SPEEDS(mode) (cfgetospeed(&mode))
#define OFLAG(mode) mode.c_oflag
#else
struct sgttyb termmode;
#define GTTY(fd, mode) gtty(fd, mode)
#define STTY(fd, mode) stty(fd, mode)
#define SPEED(mode) (mode.sg_ospeed & 017)
#define OFLAG(mode) mode.sg_flags
#define TAB3 XTABS
#endif
#ifdef SYSV
if ((filedes = 1, GTTYS(filedes, &termmodes) < 0) ||
(filedes = 2, GTTYS(filedes, &termmodes) < 0) ||
(filedes = 0, GTTYS(filedes, &termmodes) < 0) ||
(filedes = open("/dev/tty", O_RDWR),
GTTYS(filedes, &termmodes) < 0)) {
#endif
if ((filedes = 1, GTTY(filedes, &termmode) == -1) ||
(filedes = 2, GTTY(filedes, &termmode) == -1) ||
(filedes = 0, GTTY(filedes, &termmode) == -1) ||
(filedes = open("/dev/tty", O_RDWR),
GTTY(filedes, &termmode) == -1)) {
filedes = -1;
CurrentBaudRate = speeds[B1200];
} else
CurrentBaudRate = speeds[SPEED(termmode)];
#ifdef SYSV
termmodes.c_lflag = termmode.c_lflag;
termmodes.c_oflag = termmode.c_oflag;
termmodes.c_iflag = termmode.c_iflag;
termmodes.c_cflag = termmode.c_cflag;
for (i = 0; i < NCC; i++)
termmodes.c_cc[i] = termmode.c_cc[i];
} else
CurrentBaudRate = speeds[SPEEDS(termmodes)];
#endif
if (xon_xoff) {
#ifdef SYSV
OFLAG(termmodes) &=
~(NLbits | CRbits | BSbits | FFbits | TBbits);
#else
OFLAG(termmode) &=
~(NLbits | CRbits | BSbits | FFbits | TBbits);
#endif
} else {
#ifdef SYSV
setdelay(getpad(carriage_return),
CRdelay, CRbits, &OFLAG(termmodes));
setdelay(getpad(scroll_forward),
NLdelay, NLbits, &OFLAG(termmodes));
setdelay(getpad(cursor_left),
BSdelay, BSbits, &OFLAG(termmodes));
setdelay(getpad(form_feed),
FFdelay, FFbits, &OFLAG(termmodes));
setdelay(getpad(tab),
TBdelay, TBbits, &OFLAG(termmodes));
#else
setdelay(getpad(carriage_return),
CRdelay, CRbits, &OFLAG(termmode));
setdelay(getpad(scroll_forward),
NLdelay, NLbits, &OFLAG(termmode));
setdelay(getpad(cursor_left),
BSdelay, BSbits, &OFLAG(termmode));
setdelay(getpad(form_feed),
FFdelay, FFbits, &OFLAG(termmode));
setdelay(getpad(tab),
TBdelay, TBbits, &OFLAG(termmode));
#endif
}
if (tab && set_tab || init_tabs == 8) {
#ifdef SYSV
OFLAG(termmodes) &= ~(TAB3);
#else
OFLAG(termmode) &= ~(TAB3);
#endif
} else {
#ifdef SYSV
OFLAG(termmodes) |= TAB3;
#else
OFLAG(termmode) |= TAB3;
#endif
}
#ifdef SYSV
if (istermios < 0) {
int i;
termmode.c_lflag = termmodes.c_lflag;
termmode.c_oflag = termmodes.c_oflag;
termmode.c_iflag = termmodes.c_iflag;
termmode.c_cflag = termmodes.c_cflag;
for (i = 0; i < NCC; i++)
termmode.c_cc[i] = termmodes.c_cc[i];
(void) STTY(filedes, &termmode);
} else
(void) STTYS(filedes, &termmodes);
#else
(void) STTY(filedes, &termmode);
#endif
if (init_prog)
(void) system(init_prog);
if (reset && reset_1string) {
putp(reset_1string);
} else if (init_1string) {
putp(init_1string);
}
if (reset && reset_2string) {
putp(reset_2string);
} else if (init_2string) {
putp(init_2string);
}
settabs();
if (reset && reset_file) {
cat(reset_file);
} else if (init_file) {
cat(init_file);
}
if (reset && reset_3string) {
putp(reset_3string);
} else if (init_3string) {
putp(init_3string);
}
if (carriage_return) {
putp(carriage_return);
} else {
(void) putchar('\r');
}
if (orig_colors)
putp(orig_colors);
if (orig_pair)
putp(orig_pair);
(void) fflush(stdout);
(void) sleep(1);
}
static void
reset_term()
{
reset++;
initterm();
}