350 lines
8.0 KiB
C
350 lines
8.0 KiB
C
#ifndef lint
|
|
static char sccsid[] = "@(#)setmode.c 1.1 94/10/31 SMI";
|
|
#endif
|
|
|
|
/*
|
|
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
|
*/
|
|
|
|
/*
|
|
* Stolen from ucb/lpr/printjob.c
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <syslog.h>
|
|
#include <sys/termios.h>
|
|
#include <sys/ttold.h>
|
|
|
|
static struct termios termios_set;
|
|
static struct termios termios_clear;
|
|
|
|
setmode(modes, fd)
|
|
char *modes;
|
|
int fd;
|
|
{
|
|
parse_modes(modes);
|
|
setty(fd);
|
|
}
|
|
|
|
struct mds {
|
|
char *string;
|
|
unsigned long set;
|
|
unsigned long reset;
|
|
};
|
|
/* Control Modes */
|
|
static struct mds cmodes[] = {
|
|
"-parity", CS8, PARENB|CSIZE,
|
|
"-evenp", CS8, PARENB|CSIZE,
|
|
"-oddp", CS8, PARENB|PARODD|CSIZE,
|
|
"parity", PARENB|CS7, PARODD|CSIZE,
|
|
"evenp", PARENB|CS7, PARODD|CSIZE,
|
|
"oddp", PARENB|PARODD|CS7, CSIZE,
|
|
"parenb", PARENB, 0,
|
|
"-parenb", 0, PARENB,
|
|
"parodd", PARODD, 0,
|
|
"-parodd", 0, PARODD,
|
|
"cs8", CS8, CSIZE,
|
|
"cs7", CS7, CSIZE,
|
|
"cs6", CS6, CSIZE,
|
|
"cs5", CS5, CSIZE,
|
|
"cstopb", CSTOPB, 0,
|
|
"-cstopb", 0, CSTOPB,
|
|
"stopb", CSTOPB, 0,
|
|
"-stopb", 0, CSTOPB,
|
|
"hupcl", HUPCL, 0,
|
|
"hup", HUPCL, 0,
|
|
"-hupcl", 0, HUPCL,
|
|
"-hup", 0, HUPCL,
|
|
"clocal", CLOCAL, 0,
|
|
"-clocal", 0, CLOCAL,
|
|
"nohang", CLOCAL, 0,
|
|
"-nohang", 0, CLOCAL,
|
|
#if 0 /* this bit isn't supported */
|
|
"loblk", LOBLK, 0,
|
|
"-loblk", 0, LOBLK,
|
|
#endif
|
|
"cread", CREAD, 0,
|
|
"-cread", 0, CREAD,
|
|
"crtscts", CRTSCTS, 0,
|
|
"-crtscts", 0, CRTSCTS,
|
|
"litout", CS8, (CSIZE|PARENB),
|
|
"-litout", (CS7|PARENB), CSIZE,
|
|
"pass8", CS8, (CSIZE|PARENB),
|
|
"-pass8", (CS7|PARENB), CSIZE,
|
|
"raw", CS8, (CSIZE|PARENB),
|
|
"-raw", (CS7|PARENB), CSIZE,
|
|
"cooked", (CS7|PARENB), CSIZE,
|
|
"sane", (CS7|PARENB|CREAD), (CSIZE|PARODD|CLOCAL),
|
|
0
|
|
};
|
|
/* Input Modes */
|
|
static struct mds imodes[] = {
|
|
"ignbrk", IGNBRK, 0,
|
|
"-ignbrk", 0, IGNBRK,
|
|
"brkint", BRKINT, 0,
|
|
"-brkint", 0, BRKINT,
|
|
"ignpar", IGNPAR, 0,
|
|
"-ignpar", 0, IGNPAR,
|
|
"parmrk", PARMRK, 0,
|
|
"-parmrk", 0, PARMRK,
|
|
"inpck", INPCK, 0,
|
|
"-inpck", 0, INPCK,
|
|
"istrip", ISTRIP, 0,
|
|
"-istrip", 0, ISTRIP,
|
|
"inlcr", INLCR, 0,
|
|
"-inlcr", 0, INLCR,
|
|
"igncr", IGNCR, 0,
|
|
"-igncr", 0, IGNCR,
|
|
"icrnl", ICRNL, 0,
|
|
"-icrnl", 0, ICRNL,
|
|
"-nl", ICRNL, (INLCR|IGNCR),
|
|
"nl", 0, ICRNL,
|
|
"iuclc", IUCLC, 0,
|
|
"-iuclc", 0, IUCLC,
|
|
"lcase", IUCLC, 0,
|
|
"-lcase", 0, IUCLC,
|
|
"LCASE", IUCLC, 0,
|
|
"-LCASE", 0, IUCLC,
|
|
"ixon", IXON, 0,
|
|
"-ixon", 0, IXON,
|
|
"ixany", IXANY, 0,
|
|
"-ixany", 0, IXANY,
|
|
"decctlq", 0, IXANY,
|
|
"-decctlq", IXANY, 0,
|
|
"ixoff", IXOFF, 0,
|
|
"-ixoff", 0, IXOFF,
|
|
"tandem", IXOFF, 0,
|
|
"-tandem", 0, IXOFF,
|
|
"imaxbel", IMAXBEL, 0,
|
|
"-imaxbel", 0, IMAXBEL,
|
|
"pass8", 0, ISTRIP,
|
|
"-pass8", ISTRIP, 0,
|
|
"raw", 0, -1,
|
|
"-raw", (BRKINT|IGNPAR|ISTRIP|ICRNL|IXON|IMAXBEL), 0,
|
|
"cooked", (BRKINT|IGNPAR|ISTRIP|ICRNL|IXON), 0,
|
|
"sane", (BRKINT|IGNPAR|ISTRIP|ICRNL|IXON|IMAXBEL),
|
|
(IGNBRK|PARMRK|INPCK|INLCR|IGNCR|IUCLC|IXOFF),
|
|
0
|
|
};
|
|
/* Local Modes */
|
|
static struct mds lmodes[] = {
|
|
"isig", ISIG, 0,
|
|
"-isig", 0, ISIG,
|
|
"noisig", 0, ISIG,
|
|
"-noisig", ISIG, 0,
|
|
"iexten", IEXTEN, 0,
|
|
"-iexten", 0, IEXTEN,
|
|
"icanon", ICANON, 0,
|
|
"-icanon", 0, ICANON,
|
|
"cbreak", 0, ICANON,
|
|
"-cbreak", ICANON, 0,
|
|
"xcase", XCASE, 0,
|
|
"-xcase", 0, XCASE,
|
|
"lcase", XCASE, 0,
|
|
"-lcase", 0, XCASE,
|
|
"LCASE", XCASE, 0,
|
|
"-LCASE", 0, XCASE,
|
|
"echo", ECHO, 0,
|
|
"-echo", 0, ECHO,
|
|
"echoe", ECHOE, 0,
|
|
"-echoe", 0, ECHOE,
|
|
"crterase", ECHOE, 0,
|
|
"-crterase", 0, ECHOE,
|
|
"echok", ECHOK, 0,
|
|
"-echok", 0, ECHOK,
|
|
"lfkc", ECHOK, 0,
|
|
"-lfkc", 0, ECHOK,
|
|
"echonl", ECHONL, 0,
|
|
"-echonl", 0, ECHONL,
|
|
"noflsh", NOFLSH, 0,
|
|
"-noflsh", 0, NOFLSH,
|
|
"tostop", TOSTOP, 0,
|
|
"-tostop", 0, TOSTOP,
|
|
"echoctl", ECHOCTL, 0,
|
|
"-echoctl", 0, ECHOCTL,
|
|
"ctlecho", ECHOCTL, 0,
|
|
"-ctlecho", 0, ECHOCTL,
|
|
"echoprt", ECHOPRT, 0,
|
|
"-echoprt", 0, ECHOPRT,
|
|
"prterase", ECHOPRT, 0,
|
|
"-prterase", 0, ECHOPRT,
|
|
"echoke", ECHOKE, 0,
|
|
"-echoke", 0, ECHOKE,
|
|
"crtkill", ECHOKE, 0,
|
|
"-crtkill", 0, ECHOKE,
|
|
#if 0 /* this bit isn't supported yet */
|
|
"defecho", DEFECHO, 0,
|
|
"-defecho", 0, DEFECHO,
|
|
#endif
|
|
"raw", 0, (ISIG|ICANON|XCASE|IEXTEN),
|
|
"-raw", (ISIG|ICANON|IEXTEN), 0,
|
|
"cooked", (ISIG|ICANON), 0,
|
|
"sane", (ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE),
|
|
(XCASE|ECHOPRT|ECHONL|NOFLSH),
|
|
0,
|
|
};
|
|
/* Output Modes */
|
|
static struct mds omodes[] = {
|
|
"opost", OPOST, 0,
|
|
"-opost", 0, OPOST,
|
|
"nopost", 0, OPOST,
|
|
"-nopost", OPOST, 0,
|
|
"olcuc", OLCUC, 0,
|
|
"-olcuc", 0, OLCUC,
|
|
"lcase", OLCUC, 0,
|
|
"-lcase", 0, OLCUC,
|
|
"LCASE", OLCUC, 0,
|
|
"-LCASE", 0, OLCUC,
|
|
"onlcr", ONLCR, 0,
|
|
"-onlcr", 0, ONLCR,
|
|
"-nl", ONLCR, (OCRNL|ONLRET),
|
|
"nl", 0, ONLCR,
|
|
"ocrnl", OCRNL, 0,
|
|
"-ocrnl", 0, OCRNL,
|
|
"onocr", ONOCR, 0,
|
|
"-onocr", 0, ONOCR,
|
|
"onlret", ONLRET, 0,
|
|
"-onlret", 0, ONLRET,
|
|
"fill", OFILL, OFDEL,
|
|
"-fill", 0, OFILL|OFDEL,
|
|
"nul-fill", OFILL, OFDEL,
|
|
"del-fill", OFILL|OFDEL, 0,
|
|
"ofill", OFILL, 0,
|
|
"-ofill", 0, OFILL,
|
|
"ofdel", OFDEL, 0,
|
|
"-ofdel", 0, OFDEL,
|
|
"cr0", CR0, CRDLY,
|
|
"cr1", CR1, CRDLY,
|
|
"cr2", CR2, CRDLY,
|
|
"cr3", CR3, CRDLY,
|
|
"tab0", TAB0, TABDLY,
|
|
"tabs", TAB0, TABDLY,
|
|
"tab1", TAB1, TABDLY,
|
|
"tab2", TAB2, TABDLY,
|
|
"-tabs", XTABS, TABDLY,
|
|
"tab3", XTABS, TABDLY,
|
|
"nl0", NL0, NLDLY,
|
|
"nl1", NL1, NLDLY,
|
|
"ff0", FF0, FFDLY,
|
|
"ff1", FF1, FFDLY,
|
|
"vt0", VT0, VTDLY,
|
|
"vt1", VT1, VTDLY,
|
|
"bs0", BS0, BSDLY,
|
|
"bs1", BS1, BSDLY,
|
|
#if 0 /* these bits aren't supported yet */
|
|
"pageout", PAGEOUT, 0,
|
|
"-pageout", 0, PAGEOUT,
|
|
"wrap", WRAP, 0,
|
|
"-wrap", 0, WRAP,
|
|
#endif
|
|
"litout", 0, OPOST,
|
|
"-litout", OPOST, 0,
|
|
"raw", 0, OPOST,
|
|
"-raw", OPOST, 0,
|
|
"cooked", OPOST, 0,
|
|
"33", CR1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
|
|
"tty33", CR1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
|
|
"tn", CR1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
|
|
"tn300", CR1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
|
|
"ti", CR2, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
|
|
"ti700", CR2, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
|
|
"05", NL1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
|
|
"vt05", NL1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
|
|
"tek", FF1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY),
|
|
"37", (FF1|VT1|CR2|TAB1|NL1), (NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY),
|
|
"tty37", (FF1|VT1|CR2|TAB1|NL1), (NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY),
|
|
"sane", (OPOST|ONLCR), (OLCUC|OCRNL|ONOCR|ONLRET|OFILL|OFDEL|
|
|
NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY),
|
|
0,
|
|
};
|
|
|
|
/*
|
|
* Parse a set of modes.
|
|
*/
|
|
static
|
|
parse_modes(modes)
|
|
char *modes;
|
|
{
|
|
register char *curtoken;
|
|
register int match;
|
|
register int i;
|
|
|
|
termios_clear.c_iflag = 0;
|
|
termios_clear.c_oflag = 0;
|
|
termios_clear.c_cflag = 0;
|
|
termios_clear.c_lflag = 0;
|
|
termios_set.c_iflag = 0;
|
|
termios_set.c_oflag = 0;
|
|
termios_set.c_cflag = 0;
|
|
termios_set.c_lflag = 0;
|
|
|
|
curtoken = strtok(modes, ",");
|
|
while (curtoken != NULL) {
|
|
match = 0;
|
|
for (i = 0; imodes[i].string != NULL; i++) {
|
|
if (strcmp(curtoken, imodes[i].string) == 0) {
|
|
match++;
|
|
termios_clear.c_iflag |= imodes[i].reset;
|
|
termios_set.c_iflag |= imodes[i].set;
|
|
}
|
|
}
|
|
for (i = 0; omodes[i].string != NULL; i++) {
|
|
if (strcmp(curtoken, omodes[i].string) == 0) {
|
|
match++;
|
|
termios_clear.c_oflag |= omodes[i].reset;
|
|
termios_set.c_oflag |= omodes[i].set;
|
|
}
|
|
}
|
|
for (i = 0; cmodes[i].string != NULL; i++) {
|
|
if (strcmp(curtoken, cmodes[i].string) == 0) {
|
|
match++;
|
|
termios_clear.c_cflag |= cmodes[i].reset;
|
|
termios_set.c_cflag |= cmodes[i].set;
|
|
}
|
|
}
|
|
for (i = 0; lmodes[i].string != NULL; i++) {
|
|
if (strcmp(curtoken, lmodes[i].string) == 0) {
|
|
match++;
|
|
termios_clear.c_lflag |= lmodes[i].reset;
|
|
termios_set.c_lflag |= lmodes[i].set;
|
|
}
|
|
}
|
|
if (!match) {
|
|
syslog(LOG_ERR,
|
|
"unknown mode %s in ms/m0/m1/m2 capability",
|
|
curtoken);
|
|
exit(1);
|
|
}
|
|
curtoken = strtok((char *)NULL, ",");
|
|
}
|
|
}
|
|
|
|
/*
|
|
* setup tty lines.
|
|
*/
|
|
static
|
|
setty(fd)
|
|
{
|
|
struct termios termios;
|
|
|
|
if (ioctl(fd, TCGETS, &termios) < 0) {
|
|
syslog(LOG_ERR, "ioctl(TCGETS): %m");
|
|
return;
|
|
}
|
|
|
|
termios.c_iflag &= ~termios_clear.c_iflag;
|
|
termios.c_iflag |= termios_set.c_iflag;
|
|
termios.c_oflag &= ~termios_clear.c_oflag;
|
|
termios.c_oflag |= termios_set.c_oflag;
|
|
termios.c_cflag &= ~termios_clear.c_cflag;
|
|
termios.c_cflag |= termios_set.c_cflag;
|
|
termios.c_lflag &= ~termios_clear.c_lflag;
|
|
termios.c_lflag |= termios_set.c_lflag;
|
|
|
|
if (ioctl(fd, TCSETSF, &termios) < 0) {
|
|
syslog(LOG_ERR, "ioctl(TCSETSF): %m");
|
|
return;
|
|
}
|
|
}
|