xref: /csrg-svn/bin/stty/stty.c (revision 49847)
147843Sbostic /*-
248945Sbostic  * Copyright (c) 1989, 1991 The Regents of the University of California.
347843Sbostic  * All rights reserved.
447843Sbostic  *
549269Sbostic  * %sccs.include.redist.c%
619907Sdist  */
719907Sdist 
813073Ssam #ifndef lint
919907Sdist char copyright[] =
1048945Sbostic "@(#) Copyright (c) 1989, 1991 The Regents of the University of California.\n\
1119907Sdist  All rights reserved.\n";
1247843Sbostic #endif /* not lint */
1319907Sdist 
1419907Sdist #ifndef lint
15*49847Sbostic static char sccsid[] = "@(#)stty.c	5.24 (Berkeley) 05/22/91";
1647843Sbostic #endif /* not lint */
1719907Sdist 
1838674Smarc #include <sys/types.h>
1937609Sbostic #include <sys/ioctl.h>
2048945Sbostic #include <termios.h>
2148945Sbostic #include <fcntl.h>
2238674Smarc #include <errno.h>
2348945Sbostic #include <unistd.h>
2448945Sbostic #include <stdio.h>
2538674Smarc #include <ctype.h>
2648945Sbostic #include <stdlib.h>
2748945Sbostic #include <string.h>
2848945Sbostic #include "stty.h"
2948945Sbostic #include "extern.h"
301179Sbill 
3148945Sbostic static void usage __P((void));
3238674Smarc 
3338674Smarc main(argc, argv)
3448945Sbostic 	int argc;
3548945Sbostic 	char **argv;
361179Sbill {
3738674Smarc 	extern char *optarg;
3848974Sbostic 	extern int opterr, optind;
3948945Sbostic 	extern struct cchar cchars1[], cchars2[];
4048945Sbostic 	extern struct modes cmodes[], imodes[], lmodes[], omodes[];
4148945Sbostic 	register struct modes *mp;
4248945Sbostic 	register struct cchar *cp;
4348945Sbostic 	struct winsize win;
4448945Sbostic 	struct termios t;
4548945Sbostic 	enum FMT fmt;
4648945Sbostic 	int ch, ctl, ldisc, tmp;
471179Sbill 
4848945Sbostic 	ctl = STDIN_FILENO;
4948945Sbostic 	fmt = NOTSET;
5048974Sbostic 	opterr = 0;
5148945Sbostic 	while ((ch = getopt(argc, argv, "aef:g")) != EOF)
5248945Sbostic 		switch(ch) {
5348945Sbostic 		case 'a':		/* undocumented: POSIX compatibility */
5448945Sbostic 			fmt = POSIX;
5548945Sbostic 			break;
5648945Sbostic 		case 'e':
5748945Sbostic 			fmt = BSD;
5848945Sbostic 			break;
5948945Sbostic 		case 'f':
6048945Sbostic 			if ((ctl = open(optarg, O_RDONLY | O_NONBLOCK)) < 0)
6148945Sbostic 				err(optarg);
6248945Sbostic 			break;
6348945Sbostic 		case 'g':
6448945Sbostic 			fmt = GFLAG;
6548945Sbostic 			break;
6648945Sbostic 		case '?':
6748945Sbostic 		default:
6848945Sbostic 			goto args;
6948945Sbostic 		}
7048945Sbostic 
7148945Sbostic args:	argc -= optind;
7248945Sbostic 	argv += optind;
7348945Sbostic 
7438674Smarc 	if (ioctl(ctl, TIOCGETD, &ldisc) < 0)
7548945Sbostic 		err("TIOCGETD: %s", strerror(errno));
7638674Smarc 	if (tcgetattr(ctl, &t) < 0)
7748945Sbostic 		err("tcgetattr: %s", strerror(errno));
7838674Smarc 	if (ioctl(ctl, TIOCGWINSZ, &win) < 0)
7948945Sbostic 		warn("TIOCGWINSZ: %s\n", strerror(errno));
8038674Smarc 
8148945Sbostic 	checkredirect();			/* conversion aid */
8248945Sbostic 
8348945Sbostic 	switch(fmt) {
8448945Sbostic 	case NOTSET:
8548945Sbostic 		if (*argv)
8648945Sbostic 			break;
8748945Sbostic 		/* FALLTHROUGH */
8848945Sbostic 	case BSD:
8948945Sbostic 	case POSIX:
9048945Sbostic 		print(&t, &win, ldisc, fmt);
9148945Sbostic 		break;
9248945Sbostic 	case GFLAG:
9348945Sbostic 		gprint(&t, &win, ldisc);
9448945Sbostic 		break;
951179Sbill 	}
9638674Smarc 
9748945Sbostic #define	CHK(s)	(**argv == s[0] && !strcmp(*argv, s))
9848945Sbostic 
9948945Sbostic 	for (; *argv; ++argv) {
10048945Sbostic 		if (CHK("-nl")) {
10148945Sbostic 			t.c_iflag |= ICRNL;
10248945Sbostic 			t.c_oflag |= ONLCR;
10348945Sbostic 			continue;
1041179Sbill 		}
10548945Sbostic 		if (CHK("all")) {
10648945Sbostic 			print(&t, &win, ldisc, BSD);
10748945Sbostic 			continue;
1081179Sbill 		}
10948945Sbostic 		if (CHK("-cbreak"))
11048945Sbostic 			goto reset;
11148945Sbostic 		if (CHK("cbreak")) {
11248945Sbostic 			t.c_iflag | BRKINT|IXON|IMAXBEL;
11348945Sbostic 			t.c_oflag |= OPOST;
11448945Sbostic 			t.c_lflag |= ISIG|IEXTEN;
11548945Sbostic 			t.c_lflag &= ~ICANON;
11648945Sbostic 			continue;
1171179Sbill 		}
11848945Sbostic 		if (CHK("cols")) {
11948945Sbostic 			if (!*++argv)
12048945Sbostic 				err("option requires an argument -- cols");
12148945Sbostic 			goto columns;
1221179Sbill 		}
12348945Sbostic 		if (CHK("columns")) {
12448945Sbostic 			if (!*++argv)
12548945Sbostic 				err("option requires an argument -- columns");
12648945Sbostic columns:		win.ws_col = atoi(*argv);
12748945Sbostic 			continue;
1283797Sroot 		}
12948945Sbostic 		if (CHK("cooked"))
13048945Sbostic 			goto reset;
13148945Sbostic 		if (CHK("dec")) {
13238674Smarc 			t.c_cc[VERASE] = (u_char)0177;
13338674Smarc 			t.c_cc[VKILL] = CTRL('u');
13438674Smarc 			t.c_cc[VINTR] = CTRL('c');
13538674Smarc 			t.c_lflag &= ~ECHOPRT;
13638674Smarc 			t.c_lflag |= ECHOE|ECHOKE|ECHOCTL;
13738674Smarc 			t.c_iflag &= ~IXANY;
13848945Sbostic 			continue;
1391179Sbill 		}
14048945Sbostic 		if (CHK("everything")) {
14148945Sbostic 			print(&t, &win, ldisc, BSD);
14248945Sbostic 			continue;
14348945Sbostic 		}
14448945Sbostic 		if (CHK("-extproc")) {
14548945Sbostic 			tmp = 0;
14648945Sbostic 			ioctl(ctl, TIOCEXT, &tmp);
14748945Sbostic 			continue;
14848945Sbostic 		}
14948945Sbostic 		if (CHK("extrpc")) {
15048945Sbostic 			tmp = 1;
15148945Sbostic 			ioctl(ctl, TIOCEXT, &tmp);
15248945Sbostic 			continue;
15348945Sbostic 		}
15448945Sbostic 		if (CHK("ispeed")) {
15548945Sbostic 			if (!*++argv)
15648945Sbostic 				err("option requires an argument -- ispeed");
15748945Sbostic 			cfsetispeed(&t, atoi(*argv));
15848945Sbostic 			continue;
15948945Sbostic 		}
16048945Sbostic 		if (CHK("new"))
16148945Sbostic 			goto tty;
16248945Sbostic 		if (CHK("nl")) {
16348945Sbostic 			t.c_iflag &= ~ICRNL;
16448945Sbostic 			t.c_oflag &= ~ONLCR;
16548945Sbostic 			continue;
16648945Sbostic 		}
16748945Sbostic 		if (CHK("old"))
16848945Sbostic 			goto tty;
16948945Sbostic 		if (CHK("ospeed")) {
17048945Sbostic 			if (!*++argv)
17148945Sbostic 				err("option requires an argument -- ospeed");
17248945Sbostic 			cfsetospeed(&t, atoi(*argv));
17348945Sbostic 			continue;
17448945Sbostic 		}
17548945Sbostic 		if (CHK("-raw"))
17648945Sbostic 			goto reset;
17748945Sbostic 		if (CHK("raw")) {
17840169Skarels 			cfmakeraw(&t);
17940169Skarels 			t.c_cflag &= ~(CSIZE|PARENB);
18040169Skarels 			t.c_cflag |= CS8;
18148945Sbostic 			continue;
18240169Skarels 		}
18348945Sbostic 		if (CHK("rows")) {
18448945Sbostic 			if (!*++argv)
18548945Sbostic 				err("option requires an argument -- rows");
18648945Sbostic 			win.ws_row = atoi(*argv);
18748945Sbostic 			continue;
18845029Smarc 		}
18948945Sbostic 		if (CHK("sane")) {
19048945Sbostic reset:			t.c_cflag = TTYDEF_CFLAG | (t.c_cflag & CLOCAL);
19140169Skarels 			t.c_iflag = TTYDEF_IFLAG;
19240169Skarels 			t.c_iflag |= ICRNL;
19340169Skarels 			/* preserve user-preference flags in lflag */
19440169Skarels #define	LKEEP	(ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH)
19540169Skarels 			t.c_lflag = TTYDEF_LFLAG | (t.c_lflag & LKEEP);
19640169Skarels 			t.c_oflag = TTYDEF_OFLAG;
19748945Sbostic 			continue;
19840169Skarels 		}
19948945Sbostic 		if (CHK("size")) {
20048945Sbostic 			(void)printf("%d %d\n", win.ws_row, win.ws_col);
20148945Sbostic 			continue;
20218023Sbloom 		}
20348945Sbostic 		if (CHK("speed")) {
20448945Sbostic 			(void)printf("%d\n", cfgetospeed(&t));
20548945Sbostic 			continue;
20638674Smarc 		}
20748945Sbostic 		if (CHK("tty")) {
20848945Sbostic tty:			tmp = TTYDISC;
20948945Sbostic 			if (ioctl(0, TIOCSETD, &tmp) < 0)
21048945Sbostic 				err("TIOCSETD: %s", strerror(errno));
21148945Sbostic 			continue;
21238674Smarc 		}
21348945Sbostic 
21448945Sbostic 		for (mp = cmodes; mp->name; ++mp)
21548945Sbostic 			if (CHK(mp->name)) {
21648945Sbostic 				t.c_cflag &= ~mp->unset;
21748945Sbostic 				t.c_cflag |= mp->set;
21838674Smarc 				goto next;
2191179Sbill 			}
22048945Sbostic 		for (mp = imodes; mp->name; ++mp)
22148945Sbostic 			if (CHK(mp->name)) {
22248945Sbostic 				t.c_iflag &= ~mp->unset;
22348945Sbostic 				t.c_iflag |= mp->set;
22438674Smarc 				goto next;
22538674Smarc 			}
22648945Sbostic 		for (mp = lmodes; mp->name; ++mp)
22748945Sbostic 			if (CHK(mp->name)) {
22848945Sbostic 				t.c_lflag &= ~mp->unset;
22948945Sbostic 				t.c_lflag |= mp->set;
23038674Smarc 				goto next;
23138674Smarc 			}
23248945Sbostic 		for (mp = omodes; mp->name; ++mp)
23348945Sbostic 			if (CHK(mp->name)) {
23448945Sbostic 				t.c_oflag &= ~mp->unset;
23548945Sbostic 				t.c_oflag |= mp->set;
23638674Smarc 				goto next;
23738674Smarc 			}
23848945Sbostic 		for (cp = cchars1; cp->name; ++cp) {
23948945Sbostic 			if (!CHK(cp->name))
24048945Sbostic 				continue;
24148945Sbostic 			goto ccfound;
2421179Sbill 		}
24348945Sbostic 		for (cp = cchars2; cp->name; ++cp) {
24448945Sbostic 			if (!CHK(cp->name))
24548945Sbostic 				continue;
24648945Sbostic ccfound:		if (!*++argv)
24748945Sbostic 				err("option requires an argument -- %s",
24848945Sbostic 				    cp->name);
249*49847Sbostic 			if (CHK("undef") || CHK("<undef>"))
25048945Sbostic 				t.c_cc[cp->sub] = _POSIX_VDISABLE;
25148945Sbostic 			else if (**argv == '^')
25248945Sbostic 				t.c_cc[cp->sub] =
25348945Sbostic 				    ((*argv)[1] == '?') ? 0177 :
25448945Sbostic 				    ((*argv)[1] == '-') ? _POSIX_VDISABLE :
25548945Sbostic 				    (*argv)[1] & 037;
25648945Sbostic 			else
25748945Sbostic 				t.c_cc[cp->sub] = **argv;
25848945Sbostic 			goto next;
25948945Sbostic 		}
26048945Sbostic 
26138674Smarc 		if (isdigit(**argv)) {
26238674Smarc 			cfsetospeed(&t, atoi(*argv));
26338674Smarc 			cfsetispeed(&t, atoi(*argv));
26438674Smarc 			goto next;
26538674Smarc 		}
26648945Sbostic 		if (!strncmp(*argv, "gfmt1", sizeof("gfmt1") - 1)) {
26748945Sbostic 			gread(&t, *argv + sizeof("gfmt1") - 1);
26843323Smarc 			goto next;
26943323Smarc 		}
27048945Sbostic 
27148945Sbostic 		err("illegal option -- %s", *argv);
27248945Sbostic next:		continue;
2731179Sbill 	}
27448945Sbostic 
27538674Smarc 	if (tcsetattr(ctl, 0, &t) < 0)
27648945Sbostic 		err("tcsetattr: %s", strerror(errno));
27738674Smarc 	if (ioctl(ctl, TIOCSWINSZ, &win) < 0)
27848945Sbostic 		warn("TIOCSWINSZ: %s", strerror(errno));
27938674Smarc 	exit(0);
2801179Sbill }
2811179Sbill 
28248945Sbostic static void
28348945Sbostic usage()
28443323Smarc {
28548945Sbostic 	(void)fprintf(stderr, "usage: stty: [-eg] [-f file] [options]\n");
28638674Smarc 	exit(1);
28738674Smarc }
288