hbase

heirloom base
git clone git://git.2f30.org/hbase
Log | Files | Refs | README

stty.c (31794B)


      1 /*
      2  * stty - set the options for a terminal
      3  *
      4  * Gunnar Ritter, Freiburg i. Br., Germany, May 2003.
      5  */
      6 /*
      7  * Copyright (c) 2003 Gunnar Ritter
      8  *
      9  * This software is provided 'as-is', without any express or implied
     10  * warranty. In no event will the authors be held liable for any damages
     11  * arising from the use of this software.
     12  *
     13  * Permission is granted to anyone to use this software for any purpose,
     14  * including commercial applications, and to alter it and redistribute
     15  * it freely, subject to the following restrictions:
     16  *
     17  * 1. The origin of this software must not be misrepresented; you must not
     18  *    claim that you wrote the original software. If you use this software
     19  *    in a product, an acknowledgment in the product documentation would be
     20  *    appreciated but is not required.
     21  *
     22  * 2. Altered source versions must be plainly marked as such, and must not be
     23  *    misrepresented as being the original software.
     24  *
     25  * 3. This notice may not be removed or altered from any source distribution.
     26  */
     27 
     28 #if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4
     29 #define	USED	__attribute__ ((used))
     30 #elif defined __GNUC__
     31 #define	USED	__attribute__ ((unused))
     32 #else
     33 #define	USED
     34 #endif
     35 #ifndef	UCB
     36 static const char sccsid[] USED = "@(#)stty.sl	1.23 (gritter) 1/22/06";
     37 #else	/* UCB */
     38 static const char sccsid[] USED = "@(#)/usr/ucb/stty.sl	1.23 (gritter) 1/22/06";
     39 #endif	/* UCB */
     40 
     41 #include <sys/types.h>
     42 #include <sys/stat.h>
     43 #include <fcntl.h>
     44 #include <errno.h>
     45 #include <termios.h>
     46 #include <unistd.h>
     47 #include <stdio.h>
     48 #include <stdlib.h>
     49 #include <string.h>
     50 #include <libgen.h>
     51 #include <ctype.h>
     52 #include <locale.h>
     53 #include <pathconf.h>
     54 #ifndef	TIOCGWINSZ
     55 #include <sys/ioctl.h>
     56 #endif
     57 
     58 #ifndef	VSWTCH
     59 #ifdef	VSWTC
     60 #define	VSWTCH	VSWTC
     61 #endif
     62 #endif
     63 
     64 #ifdef	TABDLY
     65 static void	tabs(int);
     66 #endif
     67 static void	evenp(int);
     68 static void	oddp(int);
     69 static void	spacep(int);
     70 static void	markp(int);
     71 static void	raw(int);
     72 static void	cooked(int);
     73 static void	nl(int);
     74 static void	sane(int);
     75 #ifdef	OFDEL
     76 static void	fill(int);
     77 #endif
     78 #ifdef	XCASE
     79 static void	lcase(int);
     80 #endif
     81 static void	ek(int);
     82 #ifdef	TABDLY
     83 static void	tty33(int);
     84 static void	tty37(int);
     85 static void	vt05(int);
     86 static void	tn300(int);
     87 static void	ti700(int);
     88 static void	tek(int);
     89 #endif
     90 static void	rows(int);
     91 static void	columns(int);
     92 static void	ypixels(int);
     93 static void	xpixels(int);
     94 static void	vmin(int);
     95 static void	vtime(int);
     96 static void	line(int);
     97 #ifdef	UCB
     98 static void	litout(int);
     99 static void	pass8(int);
    100 static void	crt(int);
    101 static void	dec(int);
    102 #endif	/* UCB */
    103 
    104 static const struct	mode {
    105 	const char	*m_name;	/* name of mode */
    106 	void	(*m_func)(int);		/* handler function */
    107 	long	m_val;			/* flag value */
    108 	long	m_dfl;			/* default (not sane!) value */
    109 	int	m_flg;			/* print flags:
    110 					     01 print regardless of difference
    111 					     02 print only if -a is not set
    112 					     04 print only if -a is set
    113 					    010 print under all circumstances
    114 					    020 print only if equal
    115 					    040 ignore for printing
    116 					   0100 ignore for setting
    117 					   0200 use m_dfl as mask
    118 					   0400 print only if equal even if -a
    119 					  01000 negate for setting
    120 					*/
    121 	enum {
    122 		M_SEPAR,		/* separator */
    123 		M_NSEPAR,		/* new separator */
    124 		M_IFLAG,		/* in c_iflag */
    125 		M_OFLAG,		/* in c_oflag */
    126 		M_CFLAG,		/* in c_cflag */
    127 		M_PCFLAG,		/* in c_cflag, but printed w/o -a */
    128 		M_LFLAG,		/* in c_lflag */
    129 		M_CC,			/* in c_cc */
    130 		M_FUNCT,		/* handled via function */
    131 		M_INVAL			/* invalid */
    132 	}	m_type;
    133 } modes[] = {
    134 	{ "oddp",	0, PARENB|PARODD,PARENB|PARODD,0122,	M_PCFLAG },
    135 	{ "evenp",	0, PARENB|PARODD,PARENB,	0122,	M_PCFLAG },
    136 	{ "parity",	0, PARENB,	0,	0122,	M_PCFLAG },
    137 	{ "cstopb",	0,	CSTOPB,	0,	02,	M_PCFLAG },
    138 	{ "hupcl",	0,	HUPCL,	0,	02,	M_PCFLAG },
    139 	{ "cread",	0,	CREAD,	CREAD,	02,	M_PCFLAG },
    140 	{ "clocal",	0,	CLOCAL,	0,	02,	M_PCFLAG },
    141 	{ "intr",	0,	VINTR,	'\177',	0,	M_CC },
    142 	{ "quit",	0,	VQUIT,	'\34',	0,	M_CC },
    143 	{ "erase",	0,	VERASE,	'#',	0,	M_CC },
    144 	{ "kill",	0,	VKILL,	'@',	0,	M_CC },
    145 	{ "\n",		0,	0,	0,	04,	M_NSEPAR },
    146 	{ "eof",	0,	VEOF,	'\4',	0,	M_CC },
    147 	{ "eol",	0,	VEOL,	'\0',	0,	M_CC },
    148 	{ "eol2",	0,	VEOL2,	'\0',	0,	M_CC },
    149 #ifdef	VSWTCH
    150 	{ "swtch",	0,	VSWTCH,	'\32',	0,	M_CC },
    151 #endif
    152 	{ "\n",		0,	0,	0,	04,	M_NSEPAR },
    153 	{ "start",	0,	VSTART,	'\21',	0,	M_CC },
    154 	{ "stop",	0,	VSTOP,	'\23',	0,	M_CC },
    155 	{ "susp",	0,	VSUSP,	'\32',	0,	M_CC },
    156 #ifdef	VDSUSP
    157 	{ "dsusp",	0,	VDSUSP,	'\31',	0,	M_CC },
    158 #else
    159 	{ "dsusp",	0,	-1,	'\0',	0,	M_CC },
    160 #endif
    161 	{ "\n",		0,	0,	0,	04,	M_NSEPAR },
    162 #ifdef	VREPRINT
    163 	{ "rprnt",	0,	VREPRINT,'\22',	0,	M_CC },
    164 #else
    165 	{ "rprnt",	0,	-1,	'\0',	0,	M_CC },
    166 #endif
    167 #ifdef	VDISCARD
    168 	{ "flush",	0,	VDISCARD,'\17',	0,	M_CC },
    169 #else
    170 	{ "flush",	0,	-1,	'\0',	0,	M_CC },
    171 #endif
    172 #ifdef	VWERASE
    173 	{ "werase",	0,	VWERASE,'\27',	0,	M_CC },
    174 #else
    175 	{ "werase",	0,	-1,	'\0',	0,	M_CC },
    176 #endif
    177 	{ "lnext",	0,	VLNEXT,	'\26',	0,	M_CC },
    178 	{ "\n",		0,	0,	0,	010,	M_SEPAR },
    179 	{ "parenb",	0,	PARENB,	0,	04,	M_CFLAG },
    180 	{ "parodd",	0,	PARODD,	0,	04,	M_CFLAG },
    181 	{ "cs5",	0,	CS5,	CSIZE,	0604,	M_CFLAG },
    182 	{ "cs6",	0,	CS6,	CSIZE,	0604,	M_CFLAG },
    183 	{ "cs7",	0,	CS7,	CSIZE,	0604,	M_CFLAG },
    184 	{ "cs8",	0,	CS8,	CSIZE,	0604,	M_CFLAG },
    185 	{ "cstopb",	0,	CSTOPB,	0,	04,	M_CFLAG },
    186 	{ "hupcl",	0,	HUPCL,	0,	04,	M_CFLAG },
    187 	{ "hup",	0,	HUPCL,	0,	040,	M_CFLAG },
    188 	{ "cread",	0,	CREAD,	CREAD,	04,	M_CFLAG },
    189 	{ "clocal",	0,	CLOCAL,	0,	04,	M_CFLAG },
    190 #ifdef	LOBLK
    191 	{ "loblk",	0,	LOBLK,	0,	04,	M_CFLAG },
    192 #else
    193 	{ "loblk",	0,	0,	0,	04,	M_INVAL },
    194 #endif
    195 #ifdef	PAREXT
    196 	{ "parext",	0,	PAREXT,	0,	04,	M_CFLAG },
    197 #else
    198 	{ "parext",	0,	0,	0,	04,	M_INVAL },
    199 #endif
    200 	{ "\n",		0,	0,	0,	04,	M_SEPAR },
    201 	{ "ignbrk",	0,	IGNBRK,	0,	0,	M_IFLAG },
    202 	{ "brkint",	0,	BRKINT,	0,	04,	M_IFLAG },
    203 #ifndef	UCB
    204 	{ "brkint",	0,IGNBRK|BRKINT,BRKINT,	0122,	M_IFLAG },
    205 #else	/* UCB */
    206 	{ "brkint",	0,	0,	BRKINT,	0122,	M_IFLAG },
    207 #endif	/* UCB */
    208 	{ "ignpar",	0,	IGNPAR,	IGNPAR,	04,	M_IFLAG },
    209 	{ "inpck",	0,	INPCK,	INPCK,	0102,	M_IFLAG },
    210 	{ "ignpar",	0,INPCK|IGNPAR,	IGNPAR,	0102,	M_IFLAG },
    211 	{ "parmrk",	0,	PARMRK,	0,	0,	M_IFLAG },
    212 	{ "inpck",	0,	INPCK,	INPCK,	04,	M_IFLAG },
    213 	{ "istrip",	0,	ISTRIP,	ISTRIP,	0,	M_IFLAG },
    214 	{ "inlcr",	0,	INLCR,	0,	0,	M_IFLAG },
    215 	{ "igncr",	0,	IGNCR,	0,	0,	M_IFLAG },
    216 #ifndef	UCB
    217 	{ "icrnl",	0,	ICRNL,	0,	0,	M_IFLAG },
    218 #else	/* UCB */
    219 	{ "icrnl",	0,	ICRNL,	ICRNL,	0,	M_IFLAG },
    220 #endif	/* UCB */
    221 #ifdef	IUCLC
    222 	{ "iuclc",	0,	IUCLC,	0,	0,	M_IFLAG },
    223 #endif
    224 	{ "\n",		0,	0,	0,	04,	M_SEPAR },
    225 	{ "ixon",	0,	IXON,	IXON,	04,	M_IFLAG },
    226 #ifndef	UCB
    227 	{ "ixany",	0,	IXANY,	IXANY,	04,	M_IFLAG },
    228 #else	/* UCB */
    229 	{ "ixany",	0,	IXANY,	0,	0,	M_IFLAG },
    230 	{ "decctlq",	0,	IXANY,	0,	01040,	M_IFLAG },
    231 #endif	/* UCB */
    232 	{ "ixon",	0,	0,	IXON,	0302,	M_IFLAG },
    233 	{ "ixoff",	0,	IXOFF,	0,	0,	M_IFLAG },
    234 #ifdef	UCB
    235 	{ "tandem",	0,	IXOFF,	0,	040,	M_IFLAG },
    236 #endif	/* UCB */
    237 	{ "imaxbel",	0,	IMAXBEL,0,	0,	M_IFLAG },
    238 #ifdef	IUTF8
    239 	{ "iutf8",	0,	IUTF8,	0,	0,	M_IFLAG },
    240 #endif
    241 	{ "\n",		0,	0,	0,	04,	M_SEPAR },
    242 	{ "isig",	0,	ISIG,	ISIG,	04,	M_LFLAG },
    243 	{ "icanon",	0,	ICANON,	ICANON,	04,	M_LFLAG },
    244 	{ "cbreak",	0,	ICANON,	0,	01040,	M_LFLAG },
    245 #ifdef	XCASE
    246 	{ "xcase",	0,	XCASE,	0,	04,	M_LFLAG },
    247 #endif
    248 	{ "opost",	0,	OPOST,	OPOST,	0102,	M_OFLAG },
    249 #ifdef	OLCUC
    250 	{ "olcuc",	0,	OLCUC,	0,	0102,	M_OFLAG },
    251 #endif
    252 #ifndef	UCB
    253 	{ "onlcr",	0,	ONLCR,	0,	0102,	M_OFLAG },
    254 #else	/* UCB */
    255 	{ "onlcr",	0,	ONLCR,	ONLCR,	0102,	M_OFLAG },
    256 #endif	/* UCB */
    257 	{ "ocrnl",	0,	OCRNL,	0,	0102,	M_OFLAG },
    258 	{ "onocr",	0,	ONOCR,	0,	0102,	M_OFLAG },
    259 	{ "onlret",	0,	ONLRET,	0,	0102,	M_OFLAG },
    260 #if defined (OFILL) && defined (OFDEL)
    261 	{ "nul-fill",	0,	OFILL,OFILL|OFDEL,0202,	M_OFLAG },
    262 	{ "del-fill",	0,OFILL|OFDEL,OFILL|OFDEL,0202,	M_OFLAG },
    263 #endif
    264 #ifdef	TAB1
    265 	{ "tab1",	0,	TAB1,	TABDLY,	0302,	M_OFLAG },
    266 #endif
    267 #ifdef	TAB2
    268 	{ "tab2",	0,	TAB2,	TABDLY,	0302,	M_OFLAG },
    269 #endif
    270 #ifdef	TAB3
    271 	{ "tab3",	0,	TAB3,	TABDLY,	0302,	M_OFLAG },
    272 #endif
    273 	{ "\n",		0,	0,	0,	02,	M_SEPAR },
    274 	{ "isig",	0,	ISIG,	ISIG,	0102,	M_LFLAG },
    275 	{ "icanon",	0,	ICANON,	ICANON,	0102,	M_LFLAG },
    276 #ifdef	XCASE
    277 	{ "xcase",	0,	XCASE,	0,	0102,	M_LFLAG },
    278 #endif
    279 #ifndef	UCB
    280 	{ "echo",	0,	ECHO,	ECHO,	01,	M_LFLAG },
    281 	{ "echoe",	0,	ECHOE,	ECHOE,	01,	M_LFLAG },
    282 	{ "echok",	0,	ECHOK,	ECHOK,	01,	M_LFLAG },
    283 #else	/* UCB */
    284 	{ "echo",	0,	ECHO,	ECHO,	0,	M_LFLAG },
    285 	{ "echoe",	0,	ECHOE,	ECHOE,	04,	M_LFLAG },
    286 	{ "crterase",	0,	ECHOE,	0,	040,	M_LFLAG },
    287 	{ "echok",	0,	ECHOK,	ECHOK,	0,	M_LFLAG },
    288 	{ "lfkc",	0,	ECHOK,	0,	040,	M_LFLAG },
    289 	{ "echoe",	0,ECHOE|ECHOKE,	ECHOE,	0122,	M_LFLAG },
    290 	{ "-echoke",	0,ECHOE|ECHOKE,	ECHOE,	0122,	M_LFLAG },
    291 	{ "echoprt",	0,ECHOE|ECHOPRT,0,	0122,	M_LFLAG },
    292 	{ "crt",	0,ECHOE|ECHOKE,ECHOE|ECHOKE,0302,M_LFLAG },
    293 #endif	/* UCB */
    294 	{ "lfkc",	0,	ECHOK,	0,	040,	M_LFLAG },
    295 	{ "echonl",	0,	ECHONL,	0,	0,	M_LFLAG },
    296 	{ "noflsh",	0,	NOFLSH,	0,	0,	M_LFLAG },
    297 	{ "\n",		0,	0,	0,	04,	M_NSEPAR },
    298 	{ "tostop",	0,	TOSTOP,	0,	0,	M_LFLAG },
    299 #ifndef	UCB
    300 	{ "echoctl",	0,	ECHOCTL,0,	0,	M_LFLAG },
    301 #else	/* UCB */
    302 	{ "echoctl",	0,	ECHOCTL,ECHOCTL,0,	M_LFLAG },
    303 	{ "ctlecho",	0,	ECHOCTL,0,	040,	M_LFLAG },
    304 	{ "prterase",	0,	ECHOPRT,0,	040,	M_LFLAG },
    305 #endif	/* UCB */
    306 	{ "echoprt",	0,	ECHOPRT,0,	04,	M_LFLAG },
    307 #ifndef	UCB
    308 	{ "echoke",	0,	ECHOKE,	0,	0,	M_LFLAG },
    309 #else	/* UCB */
    310 	{ "echoke",	0,	ECHOKE,	0,	04,	M_LFLAG },
    311 	{ "crtkill",	0,	ECHOKE,	0,	040,	M_LFLAG },
    312 #endif	/* UCB */
    313 	{ "defecho",	0,	0,	0,	0,	M_INVAL },
    314 	{ "flusho",	0,	FLUSHO,	0,	0,	M_LFLAG },
    315 	{ "pendin",	0,	PENDIN,	0,	0,	M_LFLAG },
    316 	{ "iexten",	0,	IEXTEN,	0,	0,	M_LFLAG },
    317 	{ "\n",		0,	0,	0,	04,	M_SEPAR },
    318 	{ "opost",	0,	OPOST,	OPOST,	04,	M_OFLAG },
    319 #ifdef	OLCUC
    320 	{ "olcuc",	0,	OLCUC,	0,	04,	M_OFLAG },
    321 #endif
    322 	{ "onlcr",	0,	ONLCR,	0,	04,	M_OFLAG },
    323 	{ "ocrnl",	0,	OCRNL,	0,	04,	M_OFLAG },
    324 	{ "onocr",	0,	ONOCR,	0,	04,	M_OFLAG },
    325 	{ "onlret",	0,	ONLRET,	0,	04,	M_OFLAG },
    326 #ifdef	OFILL
    327 	{ "ofill",	0,	OFILL,	0,	04,	M_OFLAG },
    328 #endif
    329 #ifdef	OFDEL
    330 	{ "ofdel",	0,	OFDEL,	0,	04,	M_OFLAG },
    331 #endif
    332 #ifdef	TAB1
    333 	{ "tab1",	0,	TAB1,	TABDLY,	0704,	M_OFLAG },
    334 #endif
    335 #ifdef	TAB2
    336 	{ "tab2",	0,	TAB2,	TABDLY,	0704,	M_OFLAG },
    337 #endif
    338 #ifdef	TAB3
    339 	{ "tab3",	0,	TAB3,	TABDLY,	0704,	M_OFLAG },
    340 #endif
    341 	{ "\n",		0,	0,	0,	04,	M_SEPAR },
    342 #ifdef	NL0
    343 	{ "nl0",	0,	NL0,	NLDLY,	0240,	M_OFLAG },
    344 #endif
    345 #ifdef	NL1
    346 	{ "nl1",	0,	NL1,	NLDLY,	0240,	M_OFLAG },
    347 #endif
    348 #ifdef	CR0
    349 	{ "cr0",	0,	CR0,	CRDLY,	0240,	M_OFLAG },
    350 #endif
    351 #ifdef	CR1
    352 	{ "cr1",	0,	CR1,	CRDLY,	0240,	M_OFLAG },
    353 #endif
    354 #ifdef	CR2
    355 	{ "cr2",	0,	CR2,	CRDLY,	0240,	M_OFLAG },
    356 #endif
    357 #ifdef	CR3
    358 	{ "cr3",	0,	CR3,	CRDLY,	0240,	M_OFLAG },
    359 #endif
    360 #ifdef	TAB0
    361 	{ "tab0",	0,	TAB0,	TABDLY,	0240,	M_OFLAG },
    362 #endif
    363 #ifdef	TAB1
    364 	{ "tab1",	0,	TAB1,	TABDLY,	0240,	M_OFLAG },
    365 #endif
    366 #ifdef	TAB2
    367 	{ "tab2",	0,	TAB2,	TABDLY,	0240,	M_OFLAG },
    368 #endif
    369 #ifdef	TAB3
    370 	{ "tab3",	0,	TAB3,	TABDLY,	0240,	M_OFLAG },
    371 #endif
    372 #ifdef	TABDLY
    373 	{ "tabs",	tabs,	0,	0,	0240,	M_FUNCT },
    374 #endif
    375 #ifdef	BS0
    376 	{ "bs0",	0,	BS0,	BSDLY,	0240,	M_OFLAG },
    377 #endif
    378 #ifdef	BS1
    379 	{ "bs1",	0,	BS1,	BSDLY,	0240,	M_OFLAG },
    380 #endif
    381 #ifdef	FF0
    382 	{ "ff0",	0,	FF0,	FFDLY,	0240,	M_OFLAG },
    383 #endif
    384 #ifdef	FF1
    385 	{ "ff1",	0,	FF1,	FFDLY,	0240,	M_OFLAG },
    386 #endif
    387 #ifdef	VT0
    388 	{ "vt0",	0,	VT0,	VTDLY,	0240,	M_OFLAG },
    389 #endif
    390 #ifdef	VT1
    391 	{ "vt1",	0,	VT1,	VTDLY,	0240,	M_OFLAG },
    392 #endif
    393 #ifdef	CRTSCTS
    394 	{ "ctsxon",	0,	CRTSCTS,0,	040,	M_OFLAG },
    395 #endif	/* CRTSCTS */
    396 	{ "evenp",	evenp,	0,	0,	040,	M_FUNCT },
    397 	{ "parity",	evenp,	0,	0,	040,	M_FUNCT },
    398 	{ "oddp",	oddp,	0,	0,	040,	M_FUNCT },
    399 	{ "spacep",	spacep,	0,	0,	040,	M_FUNCT },
    400 	{ "markp",	markp,	0,	0,	040,	M_FUNCT },
    401 	{ "raw",	raw,	0,	0,	040,	M_FUNCT },
    402 	{ "cooked",	cooked,	0,	0,	040,	M_FUNCT },
    403 	{ "nl",		nl,	0,	0,	040,	M_FUNCT },
    404 #ifdef	XCASE
    405 	{ "lcase",	lcase,	0,	0,	040,	M_FUNCT },
    406 	{ "LCASE",	lcase,	0,	0,	040,	M_FUNCT },
    407 #endif
    408 	{ "ek",		ek,	0,	0,	040,	M_FUNCT },
    409 	{ "sane",	sane,	0,	0,	040,	M_FUNCT },
    410 #ifdef	OFDEL
    411 	{ "fill",	fill,	0,	0,	040,	M_FUNCT },
    412 #endif
    413 #ifdef	TABDLY
    414 	{ "tty33",	tty33,	0,	0,	040,	M_FUNCT },
    415 	{ "tty37",	tty37,	0,	0,	040,	M_FUNCT },
    416 	{ "vt05",	vt05,	0,	0,	040,	M_FUNCT },
    417 	{ "tn300",	tn300,	0,	0,	040,	M_FUNCT },
    418 	{ "ti700",	ti700,	0,	0,	040,	M_FUNCT },
    419 	{ "tek",	tek,	0,	0,	040,	M_FUNCT },
    420 #endif
    421 	{ "rows",	rows,	0,	0,	040,	M_FUNCT },
    422 	{ "columns",	columns,0,	0,	040,	M_FUNCT },
    423 #ifdef	UCB
    424 	{ "cols",	columns,0,	0,	040,	M_FUNCT },
    425 #endif	/* UCB */
    426 	{ "ypixels",	ypixels,0,	0,	040,	M_FUNCT },
    427 	{ "xpixels",	xpixels,0,	0,	040,	M_FUNCT },
    428 	{ "min",	vmin,	0,	0,	040,	M_FUNCT },
    429 	{ "time",	vtime,	0,	0,	040,	M_FUNCT },
    430 	{ "line",	line,	0,	0,	040,	M_FUNCT },
    431 #ifdef	UCB
    432 	{ "litout",	litout,	0,	0,	040,	M_FUNCT },
    433 	{ "pass8",	pass8,	0,	0,	040,	M_FUNCT },
    434 	{ "crt",	crt,	0,	0,	040,	M_FUNCT },
    435 	{ "dec",	dec,	0,	0,	040,	M_FUNCT },
    436 #endif	/* UCB */
    437 	{ 0,		0,	0,	0,	0,	M_INVAL }
    438 };
    439 
    440 static const struct {
    441 	const char	*s_str;
    442 	speed_t	s_val;
    443 } speeds[] = {
    444 	{ "0",		B0 },
    445 	{ "50",		B50 },
    446 	{ "75",		B75 },
    447 	{ "110",	B110 },
    448 	{ "134",	B134 },
    449 	{ "134.5",	B134 },
    450 	{ "150",	B150 },
    451 	{ "200",	B200 },
    452 	{ "300",	B300 },
    453 	{ "600",	B600 },
    454 	{ "1200",	B1200 },
    455 	{ "1800",	B1800 },
    456 	{ "2400",	B2400 },
    457 	{ "4800",	B4800 },
    458 	{ "9600",	B9600 },
    459 	{ "19200",	B19200 },
    460 	{ "19.2",	B19200 },
    461 	{ "38400",	B38400 },
    462 	{ "38.4",	B38400 },
    463 #ifdef	B57600
    464 	{ "57600",	B57600 },
    465 #endif	/* B57600 */
    466 #ifdef	B115200
    467 	{ "115200",	B115200 },
    468 #endif	/* B115200 */
    469 #ifdef	B230400
    470 	{ "230400",	B230400 },
    471 #endif	/* B230400 */
    472 #ifdef	B460800
    473 	{ "460800",	B460800 },
    474 #endif	/* B460800 */
    475 #ifdef	B500000
    476 	{ "500000",	B500000 },
    477 #endif	/* B500000 */
    478 #ifdef	B576000
    479 	{ "576000",	B576000 },
    480 #endif	/* B576000 */
    481 #ifdef	B921600
    482 	{ "921600",	B921600 },
    483 #endif	/* B921600 */
    484 #ifdef	B1000000
    485 	{ "1000000",	B1000000 },
    486 #endif	/* B1000000 */
    487 #ifdef	B1152000
    488 	{ "1152000",	B1152000 },
    489 #endif	/* B1152000 */
    490 #ifdef	B1500000
    491 	{ "1500000",	B1500000 },
    492 #endif	/* B1500000 */
    493 #ifdef	B2000000
    494 	{ "2000000",	B2000000 },
    495 #endif	/* B2000000 */
    496 #ifdef	B2500000
    497 	{ "2500000",	B2500000 },
    498 #endif	/* B2500000 */
    499 #ifdef	B3000000
    500 	{ "3000000",	B3000000 },
    501 #endif	/* B3000000 */
    502 #ifdef	B3500000
    503 	{ "3500000",	B3500000 },
    504 #endif	/* B3500000 */
    505 #ifdef	B4000000
    506 	{ "4000000",	B4000000 },
    507 #endif	/* B4000000 */
    508 #ifdef	EXTA
    509 	{ "exta",	EXTA },
    510 #endif	/* EXTA */
    511 #ifdef	EXTB
    512 	{ "extb",	EXTB },
    513 #endif	/* EXTB */
    514 	{ 0,		0 }
    515 };
    516 
    517 static const char	*progname;
    518 static const char	**args;
    519 static struct termios	ts;
    520 static struct winsize	ws;
    521 static int		wschange;	/* ws was changed */
    522 static long		vdis;		/* VDISABLE character */
    523 extern int		sysv3;
    524 
    525 static void	usage(void);
    526 static void	getattr(int);
    527 static void	list(int, int);
    528 static int	listmode(tcflag_t, struct mode, int, int);
    529 static int	listchar(cc_t *, struct mode, int, int);
    530 static const char	*baudrate(speed_t c);
    531 static void	set(void);
    532 static void	setmod(tcflag_t *, struct mode, int);
    533 static void	setchr(cc_t *, struct mode);
    534 static void	inval(void);
    535 static void	glist(void);
    536 static void	gset(void);
    537 #ifdef	UCB
    538 static void	hlist(int);
    539 static void	speed(void);
    540 static void	size(void);
    541 #endif	/* UCB */
    542 
    543 #ifndef	UCB
    544 #define	STTYFD	0
    545 #else	/* UCB */
    546 #define	STTYFD	1
    547 #endif	/* UCB */
    548 
    549 int
    550 main(int argc, char **argv)
    551 {
    552 	int	dds;
    553 
    554 	progname = basename(argv[0]);
    555 	setlocale(LC_CTYPE, "");
    556 #ifndef	UCB
    557 	if (getenv("SYSV3") != NULL)
    558 		sysv3 = 1;
    559 	getattr(STTYFD);
    560 #endif	/* !UCB */
    561 	if (argc >= 2 && strcmp(argv[1], "--") == 0) {
    562 		argc--, argv++;
    563 		dds = 1;
    564 	} else
    565 		dds = 0;
    566 	args = argc ? (const char **)&argv[1] : (const char **)&argv[0];
    567 	if(!dds && argc == 2 && argv[1][0] == '-' && argv[1][1] &&
    568 			argv[1][2] == '\0') {
    569 		switch (argv[1][1]) {
    570 		case 'a':
    571 #ifdef	UCB
    572 		getattr(STTYFD);
    573 #endif	/* UCB */
    574 			list(1, 0);
    575 			break;
    576 		case 'g':
    577 #ifdef	UCB
    578 		getattr(-1);
    579 #endif	/* UCB */
    580 			glist();
    581 			break;
    582 #ifdef	UCB
    583 		case 'h':
    584 		getattr(STTYFD);
    585 			hlist(1);
    586 			break;
    587 #endif	/* UCB */
    588 		default:
    589 			usage();
    590 		}
    591 	} else if (argc == 1) {
    592 #ifdef	UCB
    593 		getattr(STTYFD);
    594 #endif	/* UCB */
    595 		list(0, 0);
    596 #ifdef	UCB
    597 	} else if (argc == 2 && strcmp(argv[1], "all") == 0) {
    598 		getattr(STTYFD);
    599 		hlist(0);
    600 	} else if (argc == 2 && strcmp(argv[1], "everything") == 0) {
    601 		getattr(STTYFD);
    602 		hlist(1);
    603 	} else if (argc == 2 && strcmp(argv[1], "speed") == 0) {
    604 		getattr(-1);
    605 		speed();
    606 	} else if (argc == 2 && strcmp(argv[1], "size") == 0) {
    607 		getattr(-1);
    608 		size();
    609 #endif	/* UCB */
    610 	} else {
    611 #ifdef	UCB
    612 		getattr(STTYFD);
    613 #endif	/* UCB */
    614 		set();
    615 		if (tcsetattr(STTYFD, TCSADRAIN, &ts) < 0 ||
    616 				wschange && ioctl(STTYFD, TIOCSWINSZ, &ws) < 0)
    617 			perror(progname);
    618 	}
    619 	return 0;
    620 }
    621 
    622 static void
    623 usage(void)
    624 {
    625 	fprintf(stderr, "usage: %s [-ag] [modes]\n", progname);
    626 	exit(2);
    627 }
    628 
    629 static void
    630 getattr(int fd)
    631 {
    632 #ifdef	UCB
    633 	const char	devtty[] = "/dev/tty";
    634 
    635 	if (fd < 0 && (fd = open(devtty, O_RDONLY)) < 0) {
    636 		fprintf(stderr, "%s: Cannot open %s: %s\n",
    637 				progname, devtty, strerror(errno));
    638 		exit(2);
    639 	}
    640 #endif	/* UCB */
    641 	if (tcgetattr(fd, &ts) < 0) {
    642 		perror(progname);
    643 		exit(2);
    644 	}
    645 	if (ioctl(fd, TIOCGWINSZ, &ws) < 0) {
    646 		ws.ws_row = 0;
    647 		ws.ws_col = 0;
    648 		ws.ws_xpixel = 0;
    649 		ws.ws_ypixel = 0;
    650 	}
    651 #if !defined (__FreeBSD__) && !defined (__DragonFly__) && !defined (__APPLE__)
    652 	vdis = fpathconf(fd, _PC_VDISABLE) & 0377;
    653 #else
    654 	vdis = '\377' & 0377;
    655 #endif
    656 }
    657 
    658 static void
    659 list(int aflag, int hflag)
    660 {
    661 	int	i, d = 0;
    662 	speed_t	is, os;
    663 
    664 	is = cfgetispeed(&ts);
    665 	os = cfgetospeed(&ts);
    666 	if (is == os)
    667 		printf("speed %s baud;", baudrate(is));
    668 	else
    669 		printf("ispeed %s baud; ospeed %s baud;",
    670 				baudrate(is), baudrate(os));
    671 	if (aflag == 0) {
    672 		for (i = 0; modes[i].m_name; i++) {
    673 			if (modes[i].m_type == M_PCFLAG)
    674 				d += listmode(ts.c_cflag, modes[i], aflag, 1);
    675 		}
    676 		d = 0;
    677 	}
    678 	if (sysv3 && aflag == 0) {
    679 		putchar('\n');
    680 	} else {
    681 		putchar(sysv3 ? ' ' : '\n');
    682 		printf("rows = %d%s columns = %d; "
    683 				"ypixels = %d%s xpixels = %d%s\n",
    684 			(int)ws.ws_row,
    685 			aflag&&hflag ? "" : ";",
    686 			(int)ws.ws_col,
    687 			(int)ws.ws_ypixel,
    688 			aflag&&hflag ? "" : ";",
    689 			(int)ws.ws_xpixel,
    690 			aflag&&hflag ? "" : ";");
    691 	}
    692 	if ((ts.c_lflag&ICANON) == 0)
    693 		printf("min = %d; time = %d;\n",
    694 				(int)ts.c_cc[VMIN], (int)ts.c_cc[VTIME]);
    695 	for (i = 0; modes[i].m_name; i++) {
    696 		if (modes[i].m_flg&040)
    697 			continue;
    698 		switch (modes[i].m_type) {
    699 		case M_NSEPAR:
    700 			if (sysv3)
    701 				break;
    702 		case M_SEPAR:
    703 			if (d && (modes[i].m_flg&8 ||
    704 					(modes[i].m_flg&(aflag?2:4)) == 0)) {
    705 				fputs(modes[i].m_name, stdout);
    706 				d = 0;
    707 			}
    708 			break;
    709 		case M_IFLAG:
    710 			d += listmode(ts.c_iflag, modes[i], aflag, d);
    711 			break;
    712 		case M_OFLAG:
    713 			d += listmode(ts.c_oflag, modes[i], aflag, d);
    714 			break;
    715 		case M_CFLAG:
    716 			d += listmode(ts.c_cflag, modes[i], aflag, d);
    717 			break;
    718 		case M_LFLAG:
    719 			d += listmode(ts.c_lflag, modes[i], aflag, d);
    720 			break;
    721 		case M_CC:
    722 			if (hflag == 0)
    723 				d += listchar(ts.c_cc, modes[i], aflag, d);
    724 			break;
    725 		}
    726 		if (d >= 72 && aflag == 0) {
    727 			putchar('\n');
    728 			d = 0;
    729 		}
    730 	}
    731 	if (d && aflag == 0)
    732 		putchar('\n');
    733 }
    734 
    735 static int
    736 listmode(tcflag_t flag, struct mode m, int aflag, int space)
    737 {
    738 	int	n = 0;
    739 
    740 	if (m.m_flg&010 || (m.m_flg & (aflag?2:4)) == 0 &&
    741 			(m.m_flg&0200 ? (flag&m.m_dfl) == m.m_val :
    742 			 m.m_flg&020 ? (flag&m.m_val) == m.m_dfl :
    743 				(flag&m.m_val) != m.m_dfl)
    744 			| m.m_flg&1 |
    745 			(aflag != 0) ^ ((m.m_flg&(aflag?0400:0)) != 0)) {
    746 		if (space) {
    747 			putchar(' ');
    748 			n++;
    749 		}
    750 		if ((flag&m.m_val) == 0) {
    751 			putchar('-');
    752 			n++;
    753 		}
    754 		n += printf("%s", m.m_name);
    755 	}
    756 	return n;
    757 }
    758 
    759 static int
    760 listchar(cc_t *cc, struct mode m, int aflag, int space)
    761 {
    762 	int	n = 0;
    763 	char	c = m.m_val >= 0 ? cc[m.m_val] : vdis;
    764 
    765 	if (m.m_flg&8 || (m.m_flg & (aflag?2:4)) == 0 &&
    766 			c != (m.m_dfl?m.m_dfl:vdis) | m.m_flg&1 |
    767 			(aflag != 0) ^ ((m.m_flg&(aflag?0400:0)) != 0)) {
    768 		if (space) {
    769 			putchar(' ');
    770 			n++;
    771 		}
    772 		n += printf("%s ", m.m_name);
    773 		if ((c&0377) == vdis)
    774 			n += printf(sysv3 ? "<undef>" : "= <undef>");
    775 		else {
    776 			printf("= ");
    777 			if (c & 0200) {
    778 				c &= 0177;
    779 				putchar('-');
    780 				n++;
    781 			}
    782 			if ((c&037) == c)
    783 				n += printf("^%c", c | (sysv3 ? 0100 : 0140));
    784 			else if (c == '\177')
    785 				n += printf("DEL");
    786 			else {
    787 				putchar(c & 0377);
    788 				n++;
    789 			}
    790 		}
    791 		putchar(';');
    792 		n++;
    793 	}
    794 	return n;
    795 }
    796 
    797 static const char *
    798 baudrate(speed_t c)
    799 {
    800 	int	i;
    801 
    802 	for (i = 0; speeds[i].s_str; i++)
    803 		if (speeds[i].s_val == c)
    804 			return speeds[i].s_str;
    805 	return "-1";
    806 }
    807 
    808 static void
    809 set(void)
    810 {
    811 	int	i, gotcha, not, sspeed = 0;
    812 	speed_t	ispeed0, ospeed0, ispeed1, ospeed1;
    813 	const char	*ap;
    814 	struct termios	tc;
    815 
    816 	ispeed0 = ispeed1 = cfgetispeed(&ts);
    817 	ospeed0 = ospeed1 = cfgetospeed(&ts);
    818 	while (*args) {
    819 		for (i = 0; speeds[i].s_str; i++)
    820 			if (strcmp(speeds[i].s_str, *args) == 0) {
    821 				ispeed1 = ospeed1 = speeds[i].s_val;
    822 				sspeed |= 3;
    823 				goto next;
    824 			}
    825 		gotcha = 0;
    826 		if (**args == '-') {
    827 			not = 1;
    828 			ap = &args[0][1];
    829 		} else {
    830 			not = 0;
    831 			ap = *args;
    832 		}
    833 		for (i = 0; modes[i].m_name; i++) {
    834 			if (modes[i].m_type == M_SEPAR || modes[i].m_flg&0100)
    835 				continue;
    836 			if (strcmp(modes[i].m_name, ap) == 0) {
    837 				gotcha++;
    838 				switch (modes[i].m_type) {
    839 				case M_IFLAG:
    840 					setmod(&ts.c_iflag, modes[i], not);
    841 					break;
    842 				case M_OFLAG:
    843 					setmod(&ts.c_oflag, modes[i], not);
    844 					break;
    845 				case M_CFLAG:
    846 				case M_PCFLAG:
    847 					setmod(&ts.c_cflag, modes[i], not);
    848 					break;
    849 				case M_LFLAG:
    850 					setmod(&ts.c_lflag, modes[i], not);
    851 					break;
    852 				case M_CC:
    853 					if (not)
    854 						inval();
    855 					setchr(ts.c_cc, modes[i]);
    856 					break;
    857 				case M_FUNCT:
    858 					modes[i].m_func(not);
    859 					break;
    860 				}
    861 			}
    862 		}
    863 		if (gotcha)
    864 			goto next;
    865 		if (strcmp(*args, "ispeed") == 0) {
    866 			if (*++args == NULL)
    867 				break;
    868 			if (atol(*args) == 0) {
    869 				ispeed1 = ospeed1;
    870 				sspeed |= 1;
    871 				goto next;
    872 			} else for (i = 0; speeds[i].s_str; i++)
    873 				if (strcmp(speeds[i].s_str, *args) == 0) {
    874 					ispeed1 = speeds[i].s_val;
    875 					sspeed |= 1;
    876 					goto next;
    877 				}
    878 			inval();
    879 		}
    880 		if (strcmp(*args, "ospeed") == 0) {
    881 			if (*++args == NULL)
    882 				break;
    883 			for (i = 0; speeds[i].s_str; i++)
    884 				if (strcmp(speeds[i].s_str, *args) == 0) {
    885 					ospeed1 = speeds[i].s_val;
    886 					sspeed |= 2;
    887 					goto next;
    888 				}
    889 			inval();
    890 		}
    891 		gset();
    892 	next:	args++;
    893 	}
    894 	if (sspeed) {
    895 		if (sspeed == 3 && ispeed1 != ospeed1 && ospeed1 != B0) {
    896 			tc = ts;
    897 			cfsetispeed(&tc, ispeed1);
    898 			if (cfgetospeed(&tc) == cfgetospeed(&ts)) {
    899 				tc = ts;
    900 				cfsetospeed(&tc, ospeed1);
    901 				if (cfgetispeed(&tc) == cfgetispeed(&ts)) {
    902 					cfsetispeed(&ts, ispeed1);
    903 					cfsetospeed(&ts, ospeed1);
    904 				}
    905 			}
    906 		} else {
    907 			if (ispeed0 != ispeed1)
    908 				cfsetispeed(&ts, ispeed1);
    909 			if (ospeed0 != ospeed1)
    910 				cfsetospeed(&ts, ospeed1);
    911 		}
    912 	}
    913 }
    914 
    915 static void
    916 setmod(tcflag_t *t, struct mode m, int not)
    917 {
    918 	if (m.m_flg&0200) {
    919 		if (not)
    920 			inval();
    921 		*t = *t&~(tcflag_t)m.m_dfl | m.m_val;
    922 	} else {
    923 		if (not ^ (m.m_flg&01000) != 0)
    924 			*t &= ~(tcflag_t)m.m_val;
    925 		else
    926 			*t |= m.m_val;
    927 	}
    928 }
    929 
    930 static void
    931 setchr(cc_t *cc, struct mode m)
    932 {
    933 	if (args[1] == NULL)
    934 		return;
    935 	args++;
    936 	if (m.m_val < 0)
    937 		return;
    938 	if (**args == '^') {
    939 		if (args[0][1] == '-')
    940 			cc[m.m_val] = vdis;
    941 		else if (args[0][1] == '?')
    942 			cc[m.m_val] = '\177';
    943 		else
    944 			cc[m.m_val] = args[0][1] & 037;
    945 	} else if (strcmp(*args, "undef") == 0)
    946 		cc[m.m_val] = vdis;
    947 	else
    948 		cc[m.m_val] = **args;
    949 }
    950 
    951 static void
    952 inval(void)
    953 {
    954 	fprintf(stderr, "unknown mode: %s\n", *args);
    955 	exit(2);
    956 }
    957 
    958 #ifdef	TABDLY
    959 static void
    960 tabs(int not)
    961 {
    962 	ts.c_oflag &= ~(tcflag_t)TABDLY;
    963 	ts.c_oflag |= not ? TAB3 : TAB0;
    964 }
    965 #endif
    966 
    967 static void
    968 evenp(int not)
    969 {
    970 	if (not) {
    971 		ts.c_cflag &= ~(tcflag_t)PARENB;
    972 		ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS8;
    973 	} else {
    974 		ts.c_cflag |= PARENB;
    975 		ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS7;
    976 	}
    977 }
    978 
    979 static void
    980 oddp(int not)
    981 {
    982 	if (not) {
    983 		ts.c_cflag &= ~(tcflag_t)(PARENB|PARODD);
    984 		ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS8;
    985 	} else {
    986 		ts.c_cflag |= PARENB|PARODD;
    987 		ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS7;
    988 	}
    989 }
    990 
    991 static void
    992 spacep(int not)
    993 {
    994 	evenp(not);
    995 }
    996 
    997 static void
    998 markp(int not)
    999 {
   1000 	oddp(not);
   1001 }
   1002 
   1003 static void
   1004 raw(int not)
   1005 {
   1006 	if (not) {
   1007 		ts.c_cc[VEOF] = ts.c_cc[VMIN] = '\4';
   1008 		ts.c_cc[VEOL] = ts.c_cc[VTIME] = vdis;
   1009 		ts.c_oflag |= OPOST;
   1010 		ts.c_lflag |= ISIG|ICANON;
   1011 	} else {
   1012 		ts.c_cc[VEOF] = ts.c_cc[VMIN] = 1;
   1013 		ts.c_cc[VEOL] = ts.c_cc[VTIME] = 1;
   1014 		ts.c_oflag &= ~(tcflag_t)OPOST;
   1015 		ts.c_lflag &= ~(tcflag_t)(ISIG|ICANON);
   1016 	}
   1017 }
   1018 
   1019 static void
   1020 cooked(int not)
   1021 {
   1022 	if (not)
   1023 		inval();
   1024 	raw(1);
   1025 }
   1026 
   1027 static void
   1028 nl(int not)
   1029 {
   1030 	if (not) {
   1031 		ts.c_iflag |= ICRNL;
   1032 		ts.c_oflag |= ONLCR;
   1033 		ts.c_iflag &= ~(tcflag_t)(INLCR|IGNCR);
   1034 		ts.c_oflag &= ~(tcflag_t)(OCRNL|ONLRET);
   1035 	} else {
   1036 		ts.c_iflag &= ~(tcflag_t)ICRNL;
   1037 		ts.c_oflag &= ~(tcflag_t)ONLCR;
   1038 	}
   1039 }
   1040 
   1041 static void
   1042 sane(int not)
   1043 {
   1044 	speed_t	ispeed, ospeed;
   1045 
   1046 	if (not)
   1047 		inval();
   1048 	ispeed = cfgetispeed(&ts);
   1049 	ospeed = cfgetospeed(&ts);
   1050 	ts.c_cc[VINTR] = '\3';
   1051 	ts.c_cc[VQUIT] = '\34';
   1052 	ts.c_cc[VERASE] = '\10';
   1053 	ts.c_cc[VKILL] = '\25';
   1054 	ts.c_cc[VEOF] = '\4';
   1055 	ts.c_cc[VEOL] = vdis;
   1056 	ts.c_cc[VEOL2] = vdis;
   1057 #ifdef	VSWTCH
   1058 	ts.c_cc[VSWTCH] = vdis;
   1059 #endif
   1060 	ts.c_cc[VSTART] = '\21';
   1061 	ts.c_cc[VSTOP] = '\23';
   1062 	ts.c_cc[VSUSP] = '\32';
   1063 #ifdef	VREPRINT
   1064 	ts.c_cc[VREPRINT] = '\22';
   1065 #endif
   1066 #ifdef	VDISCARD
   1067 	ts.c_cc[VDISCARD] = '\17';
   1068 #endif
   1069 #ifdef	VWERASE
   1070 	ts.c_cc[VWERASE] = '\27';
   1071 #endif
   1072 	ts.c_cc[VLNEXT] = '\26';
   1073 	ts.c_cflag = CS8|CREAD;
   1074 	ts.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOKE|IEXTEN;
   1075 	ts.c_iflag = BRKINT|IGNPAR|ICRNL|IXON|IMAXBEL;
   1076 #ifdef	IUTF8
   1077 	if (MB_CUR_MAX > 1) {
   1078 		wchar_t	wc;
   1079 		if (mbtowc(&wc, "\303\266", 2) == 2 && wc == 0xF6 &&
   1080 				mbtowc(&wc, "\342\202\254", 3) == 3 &&
   1081 				wc == 0x20AC)
   1082 			ts.c_iflag |= IUTF8;
   1083 	}
   1084 #endif	/* IUTF8 */
   1085 	ts.c_oflag = OPOST|ONLCR;
   1086 	cfsetispeed(&ts, ispeed);
   1087 	cfsetospeed(&ts, ospeed);
   1088 }
   1089 
   1090 #ifdef	OFDEL
   1091 static void
   1092 fill(int not)
   1093 {
   1094 	if (not)
   1095 		ts.c_oflag &= ~(tcflag_t)(OFILL|OFDEL);
   1096 	else {
   1097 		ts.c_oflag |= OFILL;
   1098 		ts.c_oflag &= ~(tcflag_t)OFDEL;
   1099 	}
   1100 }
   1101 #endif
   1102 
   1103 #ifdef	XCASE
   1104 static void
   1105 lcase(int not)
   1106 {
   1107 	if (not) {
   1108 		ts.c_lflag &= ~(tcflag_t)XCASE;
   1109 		ts.c_iflag &= ~(tcflag_t)IUCLC;
   1110 		ts.c_oflag &= ~(tcflag_t)OLCUC;
   1111 	} else {
   1112 		ts.c_lflag |= XCASE;
   1113 		ts.c_iflag |= IUCLC;
   1114 		ts.c_oflag |= OLCUC;
   1115 	}
   1116 }
   1117 #endif
   1118 
   1119 static void
   1120 ek(int not)
   1121 {
   1122 	if (not)
   1123 		inval();
   1124 	ts.c_cc[VERASE] = '\10';
   1125 	ts.c_cc[VKILL] = '\25';
   1126 }
   1127 
   1128 #ifdef	TABDLY
   1129 static void
   1130 tty33(int not)
   1131 {
   1132 	if (not)
   1133 		inval();
   1134 	ts.c_oflag &= ~(tcflag_t)(NLDLY|CRDLY|TABDLY|BSDLY|FFDLY|VTDLY);
   1135 	ts.c_oflag |= CR1;
   1136 }
   1137 
   1138 static void
   1139 tty37(int not)
   1140 {
   1141 	if (not)
   1142 		inval();
   1143 	ts.c_oflag &= ~(tcflag_t)(NLDLY|CRDLY|TABDLY|BSDLY|FFDLY|VTDLY);
   1144 	ts.c_oflag |= NL1|CR2|TAB1|FF1|VT1;
   1145 }
   1146 
   1147 static void
   1148 vt05(int not)
   1149 {
   1150 	if (not)
   1151 		inval();
   1152 	ts.c_oflag &= ~(tcflag_t)(NLDLY|CRDLY|TABDLY|BSDLY|FFDLY|VTDLY);
   1153 	ts.c_oflag |= NL1;
   1154 }
   1155 
   1156 static void
   1157 tn300(int not)
   1158 {
   1159 	if (not)
   1160 		inval();
   1161 	ts.c_oflag &= ~(tcflag_t)(NLDLY|CRDLY|TABDLY|BSDLY|FFDLY|VTDLY);
   1162 	ts.c_oflag |= CR1;
   1163 }
   1164 
   1165 static void
   1166 ti700(int not)
   1167 {
   1168 	if (not)
   1169 		inval();
   1170 	ts.c_oflag &= ~(tcflag_t)(NLDLY|CRDLY|TABDLY|BSDLY|FFDLY|VTDLY);
   1171 	ts.c_oflag |= CR2;
   1172 }
   1173 
   1174 static void
   1175 tek(int not)
   1176 {
   1177 	if (not)
   1178 		inval();
   1179 	ts.c_oflag &= ~(tcflag_t)(NLDLY|CRDLY|TABDLY|BSDLY|FFDLY|VTDLY);
   1180 	ts.c_oflag |= FF1;
   1181 }
   1182 #endif
   1183 
   1184 static void
   1185 rows(int not)
   1186 {
   1187 	if (not)
   1188 		inval();
   1189 	if (args[1] == NULL)
   1190 		return;
   1191 	wschange = 1;
   1192 	ws.ws_row = atoi(*++args);
   1193 }
   1194 
   1195 static void
   1196 columns(int not)
   1197 {
   1198 	if (not)
   1199 		inval();
   1200 	if (args[1] == NULL)
   1201 		return;
   1202 	wschange = 1;
   1203 	ws.ws_col = atoi(*++args);
   1204 }
   1205 
   1206 static void
   1207 ypixels(int not)
   1208 {
   1209 	if (not)
   1210 		inval();
   1211 	if (args[1] == NULL)
   1212 		return;
   1213 	wschange = 1;
   1214 	ws.ws_ypixel = atoi(*++args);
   1215 }
   1216 
   1217 static void
   1218 xpixels(int not)
   1219 {
   1220 	if (not)
   1221 		inval();
   1222 	if (args[1] == NULL)
   1223 		return;
   1224 	wschange = 1;
   1225 	ws.ws_xpixel = atoi(*++args);
   1226 }
   1227 
   1228 static void
   1229 vmin(int not)
   1230 {
   1231 	if (not)
   1232 		inval();
   1233 	if (args[1] == NULL)
   1234 		return;
   1235 	ts.c_cc[VMIN] = atoi(*++args);
   1236 }
   1237 
   1238 static void
   1239 vtime(int not)
   1240 {
   1241 	if (not)
   1242 		inval();
   1243 	if (args[1] == NULL)
   1244 		return;
   1245 	ts.c_cc[VTIME] = atoi(*++args);
   1246 }
   1247 
   1248 
   1249 static void
   1250 line(int not)
   1251 {
   1252 	if (not)
   1253 		inval();
   1254 	if (args[1] == NULL)
   1255 		return;
   1256 #ifdef	__linux__
   1257 	ts.c_line = atoi(*++args);
   1258 #endif
   1259 }
   1260 
   1261 static const char gfmt[] ="%lx:%lx:%lx:%lx:"
   1262 		"%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x";
   1263 
   1264 static void
   1265 glist(void)
   1266 {
   1267 	printf(gfmt,	(long)ts.c_iflag,
   1268 			(long)ts.c_oflag,
   1269 			(long)ts.c_cflag,
   1270 			(long)ts.c_lflag,
   1271 			(int)ts.c_cc[VINTR],
   1272 			(int)ts.c_cc[VQUIT],
   1273 			(int)ts.c_cc[VERASE],
   1274 			(int)ts.c_cc[VKILL],
   1275 			(int)ts.c_cc[VEOF],
   1276 			(int)ts.c_cc[VEOL],
   1277 			(int)ts.c_cc[VEOL2],
   1278 #ifdef	VSWTCH
   1279 			(int)ts.c_cc[VSWTCH],
   1280 #else
   1281 			(int)vdis,
   1282 #endif
   1283 			(int)ts.c_cc[VSTART],
   1284 			(int)ts.c_cc[VSTOP],
   1285 			(int)ts.c_cc[VSUSP],
   1286 #ifdef	VDSUSP
   1287 			(int)ts.c_cc[VDSUSP],
   1288 #else
   1289 			(int)vdis,
   1290 #endif
   1291 #ifdef	VREPRINT
   1292 			(int)ts.c_cc[VREPRINT],
   1293 #else
   1294 			(int)vdis,
   1295 #endif
   1296 #ifdef	VDISCARD
   1297 			(int)ts.c_cc[VDISCARD],
   1298 #else
   1299 			(int)vdis,
   1300 #endif
   1301 #ifdef	VWERASE
   1302 			(int)ts.c_cc[VWERASE],
   1303 #else
   1304 			(int)vdis,
   1305 #endif
   1306 			(int)ts.c_cc[VLNEXT],
   1307 			(int)ts.c_cc[VMIN],
   1308 			(int)ts.c_cc[VTIME]);
   1309 	putchar('\n');
   1310 }
   1311 
   1312 static void
   1313 gset(void)
   1314 {
   1315 	long	iflag, oflag, cflag, lflag;
   1316 	int	vintr, vquit, verase, vkill,
   1317 		veof, veol, veol2, vswtch,
   1318 		vstart, vstop, vsusp, vdsusp,
   1319 		vrprnt, vflush, vwerase, vlnext,
   1320 		vmin, vtime;
   1321 
   1322 	if (sscanf(*args, gfmt,
   1323 			&iflag, &oflag, &cflag, &lflag,
   1324 			&vintr, &vquit, &verase, &vkill,
   1325 			&veof, &veol, &veol2, &vswtch,
   1326 			&vstart, &vstop, &vsusp, &vdsusp,
   1327 			&vrprnt, &vflush, &vwerase, &vlnext,
   1328 			&vmin, &vtime) != 22)
   1329 		inval();
   1330 	ts.c_iflag = iflag;
   1331 	ts.c_oflag = oflag;
   1332 	ts.c_cflag = cflag;
   1333 	ts.c_lflag = lflag;
   1334 	ts.c_cc[VINTR] = vintr;
   1335 	ts.c_cc[VQUIT] = vquit;
   1336 	ts.c_cc[VKILL] = vkill;
   1337 	ts.c_cc[VEOF] = veof;
   1338 	ts.c_cc[VEOL] = veol;
   1339 	ts.c_cc[VEOL2] = veol2;
   1340 #ifdef	VSWTCH
   1341 	ts.c_cc[VSWTCH] = vswtch;
   1342 #endif
   1343 	ts.c_cc[VSTART] = vstart;
   1344 	ts.c_cc[VSTOP] = vstop;
   1345 	ts.c_cc[VSUSP] = vsusp;
   1346 #ifdef	VDSUSP
   1347 	ts.c_cc[VDSUSP] = vdsusp;
   1348 #endif
   1349 #ifdef	VREPRINT
   1350 	ts.c_cc[VREPRINT] = vrprnt;
   1351 #endif
   1352 #ifdef	VDISCARD
   1353 	ts.c_cc[VDISCARD] = vflush;
   1354 #endif
   1355 #ifdef	VWERASE
   1356 	ts.c_cc[VWERASE] = vwerase;
   1357 #endif
   1358 	ts.c_cc[VLNEXT] = vlnext;
   1359 	ts.c_cc[VMIN] = vmin;
   1360 	ts.c_cc[VTIME] = vtime;
   1361 }
   1362 
   1363 #ifdef	UCB
   1364 static void
   1365 hchar(int c, int c2, int spc)
   1366 {
   1367 	int	n = 0;
   1368 
   1369 chr:	if (c != vdis) {
   1370 		if (c & 0200) {
   1371 			c &= 0177;
   1372 			n += printf("M-");
   1373 		}
   1374 		if ((c&037) == c)
   1375 			n += printf("^%c", c | 0100);
   1376 		else if (c == '\177')
   1377 			n += printf("^?");
   1378 		else {
   1379 			putchar(c);
   1380 			n++;
   1381 		}
   1382 	}
   1383 	if (c2 != EOF) {
   1384 		putchar('/');
   1385 		n++;
   1386 		c = c2;
   1387 		c2 = EOF;
   1388 		goto chr;
   1389 	}
   1390 	if (spc)
   1391 		while (n++ < 7)
   1392 			putchar(' ');
   1393 }
   1394 
   1395 static void
   1396 hlist(int aflag)
   1397 {
   1398 	list(aflag, 1);
   1399 	printf("erase  kill   werase rprnt  flush  lnext  "
   1400 			"susp   intr   quit   stop   eof\n");
   1401 	hchar(ts.c_cc[VERASE]&0377, EOF, 1);
   1402 	hchar(ts.c_cc[VKILL]&0377, EOF, 1);
   1403 #ifdef	VWERASE
   1404 	hchar(ts.c_cc[VWERASE]&0377, EOF, 1);
   1405 #else
   1406 	hchar(vdis, EOF, 1);
   1407 #endif
   1408 #ifdef	VREPRINT
   1409 	hchar(ts.c_cc[VREPRINT]&0377, EOF, 1);
   1410 #else
   1411 	hchar(vdis, EOF, 1);
   1412 #endif
   1413 #ifdef	VDISCARD
   1414 	hchar(ts.c_cc[VDISCARD]&0377, EOF, 1);
   1415 #else
   1416 	hchar(vdis, EOF, 1);
   1417 #endif
   1418 	hchar(ts.c_cc[VLNEXT]&0377, EOF, 1);
   1419 	hchar(ts.c_cc[VSUSP]&0377, EOF, 1);
   1420 	hchar(ts.c_cc[VINTR]&0377, EOF, 1);
   1421 	hchar(ts.c_cc[VQUIT]&0377, EOF, 1);
   1422 	hchar(ts.c_cc[VSTOP]&0377, ts.c_cc[VSTART]&0377, 1);
   1423 	hchar(ts.c_cc[VEOF]&0377, EOF, 1);
   1424 	putchar('\n');
   1425 }
   1426 
   1427 static void
   1428 speed(void)
   1429 {
   1430 	printf("%s\n", baudrate(cfgetospeed(&ts)));
   1431 }
   1432 
   1433 static void
   1434 size(void)
   1435 {
   1436 	printf("%d %d\n", (int)ws.ws_row, (int)ws.ws_col);
   1437 }
   1438 
   1439 static void
   1440 litout(int not)
   1441 {
   1442 	if (not) {
   1443 		ts.c_cflag |= PARENB;
   1444 		ts.c_iflag |= ISTRIP;
   1445 		ts.c_oflag |= OPOST;
   1446 		ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS7;
   1447 	} else {
   1448 		ts.c_cflag &= ~(tcflag_t)PARENB;
   1449 		ts.c_iflag &= ~(tcflag_t)ISTRIP;
   1450 		ts.c_oflag &= ~(tcflag_t)OPOST;
   1451 		ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS8;
   1452 	}
   1453 }
   1454 
   1455 static void
   1456 pass8(int not)
   1457 {
   1458 	if (not) {
   1459 		ts.c_cflag |= PARENB;
   1460 		ts.c_iflag |= ISTRIP;
   1461 		ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS7;
   1462 	} else {
   1463 		ts.c_cflag &= ~(tcflag_t)PARENB;
   1464 		ts.c_iflag &= ~(tcflag_t)ISTRIP;
   1465 		ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS8;
   1466 	}
   1467 }
   1468 
   1469 static void
   1470 crt(int not)
   1471 {
   1472 	if (not)
   1473 		inval();
   1474 	ts.c_lflag |= ECHOE|ECHOCTL;
   1475 	if (cfgetospeed(&ts) >= B1200)
   1476 		ts.c_lflag |= ECHOKE;
   1477 }
   1478 
   1479 static void
   1480 dec(int not)
   1481 {
   1482 	if (not)
   1483 		inval();
   1484 	ts.c_cc[VERASE] = '\177';
   1485 	ts.c_cc[VKILL] = '\25';
   1486 	ts.c_cc[VINTR] = '\3';
   1487 	ts.c_iflag &= ~(tcflag_t)IXANY;
   1488 	crt(not);
   1489 }
   1490 #endif	/* UCB */