xref: /csrg-svn/bin/stty/stty.c (revision 50007)
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*50007Sbostic static char sccsid[] = "@(#)stty.c	5.27 (Berkeley) 06/05/91";
1647843Sbostic #endif /* not lint */
1719907Sdist 
1838674Smarc #include <sys/types.h>
1948945Sbostic #include <fcntl.h>
2038674Smarc #include <errno.h>
2148945Sbostic #include <unistd.h>
2248945Sbostic #include <stdio.h>
2338674Smarc #include <ctype.h>
2448945Sbostic #include <stdlib.h>
2548945Sbostic #include <string.h>
2648945Sbostic #include "stty.h"
2748945Sbostic #include "extern.h"
281179Sbill 
29*50007Sbostic static char usage[] = "usage: stty: [-eg] [-f file] [options]";
3038674Smarc 
3138674Smarc main(argc, argv)
3248945Sbostic 	int argc;
3348945Sbostic 	char **argv;
341179Sbill {
3548945Sbostic 	register struct modes *mp;
3648945Sbostic 	register struct cchar *cp;
37*50007Sbostic 	struct info i;
38*50007Sbostic 	struct key *kp;
3948945Sbostic 	enum FMT fmt;
40*50007Sbostic 	int ch;
411179Sbill 
4248945Sbostic 	fmt = NOTSET;
43*50007Sbostic 	i.fd = STDIN_FILENO;
44*50007Sbostic 
4548974Sbostic 	opterr = 0;
4649974Sbostic 	while (strspn(argv[optind], "-aefg") == strlen(argv[optind]) &&
4749974Sbostic 	    (ch = getopt(argc, argv, "aef:g")) != EOF)
4848945Sbostic 		switch(ch) {
4948945Sbostic 		case 'a':		/* undocumented: POSIX compatibility */
5048945Sbostic 			fmt = POSIX;
5148945Sbostic 			break;
5248945Sbostic 		case 'e':
5348945Sbostic 			fmt = BSD;
5448945Sbostic 			break;
5548945Sbostic 		case 'f':
56*50007Sbostic 			if ((i.fd = open(optarg, O_RDONLY | O_NONBLOCK)) < 0)
5749974Sbostic 				err("%s: %s", optarg, strerror(errno));
5848945Sbostic 			break;
5948945Sbostic 		case 'g':
6048945Sbostic 			fmt = GFLAG;
6148945Sbostic 			break;
6248945Sbostic 		case '?':
6348945Sbostic 		default:
6448945Sbostic 			goto args;
6548945Sbostic 		}
6648945Sbostic 
6748945Sbostic args:	argc -= optind;
6848945Sbostic 	argv += optind;
6948945Sbostic 
70*50007Sbostic 	if (ioctl(i.fd, TIOCGETD, &i.ldisc) < 0)
7148945Sbostic 		err("TIOCGETD: %s", strerror(errno));
72*50007Sbostic 	if (tcgetattr(i.fd, &i.t) < 0)
7348945Sbostic 		err("tcgetattr: %s", strerror(errno));
74*50007Sbostic 	if (ioctl(i.fd, TIOCGWINSZ, &i.win) < 0)
7548945Sbostic 		warn("TIOCGWINSZ: %s\n", strerror(errno));
7638674Smarc 
7748945Sbostic 	checkredirect();			/* conversion aid */
7848945Sbostic 
7948945Sbostic 	switch(fmt) {
8048945Sbostic 	case NOTSET:
8148945Sbostic 		if (*argv)
8248945Sbostic 			break;
8348945Sbostic 		/* FALLTHROUGH */
8448945Sbostic 	case BSD:
8548945Sbostic 	case POSIX:
86*50007Sbostic 		print(&i.t, &i.win, i.ldisc, fmt);
8748945Sbostic 		break;
8848945Sbostic 	case GFLAG:
89*50007Sbostic 		gprint(&i.t, &i.win, i.ldisc);
9048945Sbostic 		break;
911179Sbill 	}
9238674Smarc 
93*50007Sbostic 	for (i.set = i.wset = 0; *argv; ++argv) {
94*50007Sbostic 		i.off = **argv == '-';
95*50007Sbostic 		if (kp = ksearch(i.off ? *argv + 1 : *argv)) {
96*50007Sbostic 			if (!(kp->flags & F_OFFOK) && i.off)
97*50007Sbostic 				err("illegal option -- %s\n%s", *argv, usage);
98*50007Sbostic 			if (kp->flags & F_NEEDARG && !(i.arg = *++argv))
99*50007Sbostic 				err("option requires an argument -- %s\n%s",
100*50007Sbostic 				    kp->name, usage);
101*50007Sbostic 			kp->f(&i);
10248945Sbostic 			continue;
1031179Sbill 		}
10448945Sbostic 
105*50007Sbostic 
106*50007Sbostic #define	CHK(s)	(**argv == s[0] && !strcmp(*argv, s))
10748945Sbostic 		for (mp = cmodes; mp->name; ++mp)
10848945Sbostic 			if (CHK(mp->name)) {
109*50007Sbostic 				i.t.c_cflag &= ~mp->unset;
110*50007Sbostic 				i.t.c_cflag |= mp->set;
111*50007Sbostic 				i.set = 1;
11238674Smarc 				goto next;
1131179Sbill 			}
11448945Sbostic 		for (mp = imodes; mp->name; ++mp)
11548945Sbostic 			if (CHK(mp->name)) {
116*50007Sbostic 				i.t.c_iflag &= ~mp->unset;
117*50007Sbostic 				i.t.c_iflag |= mp->set;
118*50007Sbostic 				i.set = 1;
11938674Smarc 				goto next;
12038674Smarc 			}
12148945Sbostic 		for (mp = lmodes; mp->name; ++mp)
12248945Sbostic 			if (CHK(mp->name)) {
123*50007Sbostic 				i.t.c_lflag &= ~mp->unset;
124*50007Sbostic 				i.t.c_lflag |= mp->set;
125*50007Sbostic 				i.set = 1;
12638674Smarc 				goto next;
12738674Smarc 			}
12848945Sbostic 		for (mp = omodes; mp->name; ++mp)
12948945Sbostic 			if (CHK(mp->name)) {
130*50007Sbostic 				i.t.c_oflag &= ~mp->unset;
131*50007Sbostic 				i.t.c_oflag |= mp->set;
132*50007Sbostic 				i.set = 1;
13338674Smarc 				goto next;
13438674Smarc 			}
135*50007Sbostic 
136*50007Sbostic 		for (cp = cchars1; cp->name; ++cp)
137*50007Sbostic 			if (CHK(cp->name))
138*50007Sbostic 				goto ccfound;
13948945Sbostic 		for (cp = cchars2; cp->name; ++cp) {
14048945Sbostic 			if (!CHK(cp->name))
14148945Sbostic 				continue;
14248945Sbostic ccfound:		if (!*++argv)
143*50007Sbostic 				err("option requires an argument -- %s\n%s",
144*50007Sbostic 				    cp->name, usage);
14549847Sbostic 			if (CHK("undef") || CHK("<undef>"))
146*50007Sbostic 				i.t.c_cc[cp->sub] = _POSIX_VDISABLE;
14748945Sbostic 			else if (**argv == '^')
148*50007Sbostic 				i.t.c_cc[cp->sub] =
14948945Sbostic 				    ((*argv)[1] == '?') ? 0177 :
15048945Sbostic 				    ((*argv)[1] == '-') ? _POSIX_VDISABLE :
15148945Sbostic 				    (*argv)[1] & 037;
15248945Sbostic 			else
153*50007Sbostic 				i.t.c_cc[cp->sub] = **argv;
154*50007Sbostic 			i.set = 1;
155*50007Sbostic 			continue;
15648945Sbostic 		}
15748945Sbostic 
15838674Smarc 		if (isdigit(**argv)) {
159*50007Sbostic 			cfsetospeed(&i.t, atoi(*argv));
160*50007Sbostic 			cfsetispeed(&i.t, atoi(*argv));
161*50007Sbostic 			continue;
16238674Smarc 		}
16348945Sbostic 		if (!strncmp(*argv, "gfmt1", sizeof("gfmt1") - 1)) {
164*50007Sbostic 			gread(&i.t, *argv + sizeof("gfmt1") - 1);
165*50007Sbostic 			continue;
16643323Smarc 		}
16748945Sbostic 
168*50007Sbostic 		err("illegal option -- %s\n%s", *argv, usage);
16948945Sbostic next:		continue;
1701179Sbill 	}
17148945Sbostic 
172*50007Sbostic 	if (i.set && tcsetattr(i.fd, 0, &i.t) < 0)
17348945Sbostic 		err("tcsetattr: %s", strerror(errno));
174*50007Sbostic 	if (i.wset && ioctl(i.fd, TIOCSWINSZ, &i.win) < 0)
17548945Sbostic 		warn("TIOCSWINSZ: %s", strerror(errno));
17638674Smarc 	exit(0);
1771179Sbill }
178