xref: /illumos-gate/usr/src/ucbcmd/stty/sttyparse.c (revision 8c0b080c8ed055a259d8cd26b9f005211c6a9753)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright 1997 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
287c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <stdio.h>
317c478bd9Sstevel@tonic-gate #include <stdlib.h>
327c478bd9Sstevel@tonic-gate #include <sys/types.h>
337c478bd9Sstevel@tonic-gate #include <termio.h>
347c478bd9Sstevel@tonic-gate #include <sys/stermio.h>
357c478bd9Sstevel@tonic-gate #include <sys/termiox.h>
367c478bd9Sstevel@tonic-gate #include "stty.h"
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate static char	*s_arg;			/* s_arg: ptr to mode to be set */
397c478bd9Sstevel@tonic-gate static int	match;
407c478bd9Sstevel@tonic-gate static int gct(), eq(), encode();
41*cc6c5292Schin static int eqarg(char *, int);
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate /* set terminal modes for supplied options */
447c478bd9Sstevel@tonic-gate char *
sttyparse(argc,argv,term,ocb,cb,termiox,winsize)457c478bd9Sstevel@tonic-gate sttyparse(argc, argv, term, ocb, cb, termiox, winsize)
467c478bd9Sstevel@tonic-gate int	argc;
477c478bd9Sstevel@tonic-gate char	*argv[];
487c478bd9Sstevel@tonic-gate int	term; /* type of tty device, -1 means allow all options,
497c478bd9Sstevel@tonic-gate 	       * no sanity check
507c478bd9Sstevel@tonic-gate 	       */
517c478bd9Sstevel@tonic-gate struct	termio	*ocb;
527c478bd9Sstevel@tonic-gate struct	termios	*cb;
537c478bd9Sstevel@tonic-gate struct	termiox	*termiox;
547c478bd9Sstevel@tonic-gate struct	winsize	*winsize;
557c478bd9Sstevel@tonic-gate {
56*cc6c5292Schin 	int i;
577c478bd9Sstevel@tonic-gate 	extern	const struct	speeds	speeds[];
587c478bd9Sstevel@tonic-gate 	extern	const struct	mds	lmodes[];
597c478bd9Sstevel@tonic-gate 	extern	const struct	mds	nlmodes[];
607c478bd9Sstevel@tonic-gate 	extern	const struct	mds	cmodes[];
617c478bd9Sstevel@tonic-gate 	extern	const struct	mds	ncmodes[];
627c478bd9Sstevel@tonic-gate 	extern	const struct	mds	imodes[];
637c478bd9Sstevel@tonic-gate 	extern	const struct	mds	nimodes[];
647c478bd9Sstevel@tonic-gate 	extern	const struct	mds	omodes[];
657c478bd9Sstevel@tonic-gate 	extern	const struct	mds	hmodes[];
667c478bd9Sstevel@tonic-gate 	extern	const struct	mds	clkmodes[];
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate 	while(--argc > 0) {
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate 		s_arg = *++argv;
717c478bd9Sstevel@tonic-gate 		match = 0;
727c478bd9Sstevel@tonic-gate 		if ((term & ASYNC) || term == -1) {
737c478bd9Sstevel@tonic-gate 			if (eqarg("erase", argc) && --argc)
747c478bd9Sstevel@tonic-gate 				cb->c_cc[VERASE] = gct(*++argv, term);
757c478bd9Sstevel@tonic-gate 			else if (eqarg("intr", argc) && --argc)
767c478bd9Sstevel@tonic-gate 				cb->c_cc[VINTR] = gct(*++argv, term);
777c478bd9Sstevel@tonic-gate 			else if (eqarg("quit", argc) && --argc)
787c478bd9Sstevel@tonic-gate 				cb->c_cc[VQUIT] = gct(*++argv, term);
797c478bd9Sstevel@tonic-gate 			else if (eqarg("eof", argc) && --argc)
807c478bd9Sstevel@tonic-gate 				cb->c_cc[VEOF] = gct(*++argv, term);
817c478bd9Sstevel@tonic-gate 			else if (eqarg("min", argc) && --argc)
827c478bd9Sstevel@tonic-gate 				cb->c_cc[VMIN] = atoi(*++argv);
837c478bd9Sstevel@tonic-gate 			else if (eqarg("eol", argc) && --argc)
847c478bd9Sstevel@tonic-gate 				cb->c_cc[VEOL] = gct(*++argv, term);
857c478bd9Sstevel@tonic-gate 			else if (eqarg("brk", argc) && --argc)
867c478bd9Sstevel@tonic-gate 				cb->c_cc[VEOL] = gct(*++argv, term);
877c478bd9Sstevel@tonic-gate 			else if (eqarg("eol2", argc) && --argc)
887c478bd9Sstevel@tonic-gate 				cb->c_cc[VEOL2] = gct(*++argv, term);
897c478bd9Sstevel@tonic-gate 			else if (eqarg("time", argc) && --argc)
907c478bd9Sstevel@tonic-gate 				cb->c_cc[VTIME] = atoi(*++argv);
917c478bd9Sstevel@tonic-gate 			else if (eqarg("kill", argc) && --argc)
927c478bd9Sstevel@tonic-gate 				cb->c_cc[VKILL] = gct(*++argv, term);
937c478bd9Sstevel@tonic-gate 			else if (eqarg("swtch", argc) && --argc)
947c478bd9Sstevel@tonic-gate 				cb->c_cc[VSWTCH] = gct(*++argv, term);
957c478bd9Sstevel@tonic-gate 			if(match)
967c478bd9Sstevel@tonic-gate 				continue;
977c478bd9Sstevel@tonic-gate 			if((term & TERMIOS) || term == -1) {
987c478bd9Sstevel@tonic-gate 				if (eqarg("start", argc) && --argc)
997c478bd9Sstevel@tonic-gate 					cb->c_cc[VSTART] = gct(*++argv, term);
1007c478bd9Sstevel@tonic-gate 				else if (eqarg("stop", argc) && --argc)
1017c478bd9Sstevel@tonic-gate 					cb->c_cc[VSTOP] = gct(*++argv, term);
1027c478bd9Sstevel@tonic-gate 				else if (eqarg("susp", argc) && --argc)
1037c478bd9Sstevel@tonic-gate 					cb->c_cc[VSUSP] = gct(*++argv, term);
1047c478bd9Sstevel@tonic-gate 				else if (eqarg("dsusp", argc) && --argc)
1057c478bd9Sstevel@tonic-gate 					cb->c_cc[VDSUSP] = gct(*++argv, term);
1067c478bd9Sstevel@tonic-gate 				else if (eqarg("rprnt", argc) && --argc)
1077c478bd9Sstevel@tonic-gate 					cb->c_cc[VREPRINT] = gct(*++argv, term);
1087c478bd9Sstevel@tonic-gate 				else if (eqarg("flush", argc) && --argc)
1097c478bd9Sstevel@tonic-gate 					cb->c_cc[VDISCARD] = gct(*++argv, term);
1107c478bd9Sstevel@tonic-gate 				else if (eqarg("werase", argc) && --argc)
1117c478bd9Sstevel@tonic-gate 					cb->c_cc[VWERASE] = gct(*++argv, term);
1127c478bd9Sstevel@tonic-gate 				else if (eqarg("lnext", argc) && --argc)
1137c478bd9Sstevel@tonic-gate 					cb->c_cc[VLNEXT] = gct(*++argv, term);
1147c478bd9Sstevel@tonic-gate 			}
1157c478bd9Sstevel@tonic-gate 			if(match)
1167c478bd9Sstevel@tonic-gate 				continue;
1177c478bd9Sstevel@tonic-gate 			if (eq("ek")) {
1187c478bd9Sstevel@tonic-gate 				cb->c_cc[VERASE] = CERASE;
1197c478bd9Sstevel@tonic-gate 				cb->c_cc[VKILL] = CKILL;
1207c478bd9Sstevel@tonic-gate 			}
1217c478bd9Sstevel@tonic-gate 			else if (eq("crt") || eq("newcrt")) {
1227c478bd9Sstevel@tonic-gate 				cb->c_lflag &= ~ECHOPRT;
1237c478bd9Sstevel@tonic-gate 				cb->c_lflag |= ECHOE|ECHOCTL;
1247c478bd9Sstevel@tonic-gate 				if (cfgetospeed(cb) >= B1200)
1257c478bd9Sstevel@tonic-gate 					cb->c_lflag |= ECHOKE;
1267c478bd9Sstevel@tonic-gate 			}
1277c478bd9Sstevel@tonic-gate 			else if (eq("dec")) {
1287c478bd9Sstevel@tonic-gate 				cb->c_cc[VERASE] = 0177;
1297c478bd9Sstevel@tonic-gate 				cb->c_cc[VKILL] = CTRL('u');
1307c478bd9Sstevel@tonic-gate 				cb->c_cc[VINTR] = CTRL('c');
1317c478bd9Sstevel@tonic-gate 				cb->c_lflag &= ~ECHOPRT;
1327c478bd9Sstevel@tonic-gate 				cb->c_lflag |= ECHOE|ECHOCTL|IEXTEN;
1337c478bd9Sstevel@tonic-gate 				if (cfgetospeed(cb) >= B1200)
1347c478bd9Sstevel@tonic-gate 					cb->c_lflag |= ECHOKE;
1357c478bd9Sstevel@tonic-gate 			}
1367c478bd9Sstevel@tonic-gate 			else if (eqarg("line", argc) && (!(term & TERMIOS) || term == -1) && --argc) {
1377c478bd9Sstevel@tonic-gate 				ocb->c_line = atoi(*++argv);
1387c478bd9Sstevel@tonic-gate 				continue;
1397c478bd9Sstevel@tonic-gate 			}
1407c478bd9Sstevel@tonic-gate 			else if (eq("raw") || eq("cbreak")) {
1417c478bd9Sstevel@tonic-gate 				cb->c_cc[VMIN] = 1;
1427c478bd9Sstevel@tonic-gate 				cb->c_cc[VTIME] = 0;
1437c478bd9Sstevel@tonic-gate 			}
1447c478bd9Sstevel@tonic-gate 			else if (eq("-raw") || eq("-cbreak") || eq("cooked")) {
1457c478bd9Sstevel@tonic-gate 				cb->c_cc[VEOF] = CEOF;
1467c478bd9Sstevel@tonic-gate 				cb->c_cc[VEOL] = CNUL;
1477c478bd9Sstevel@tonic-gate 			}
1487c478bd9Sstevel@tonic-gate 			else if(eq("sane")) {
1497c478bd9Sstevel@tonic-gate 				cb->c_cc[VERASE] = CERASE;
1507c478bd9Sstevel@tonic-gate 				cb->c_cc[VKILL] = CKILL;
1517c478bd9Sstevel@tonic-gate 				cb->c_cc[VQUIT] = CQUIT;
1527c478bd9Sstevel@tonic-gate 				cb->c_cc[VINTR] = CINTR;
1537c478bd9Sstevel@tonic-gate 				cb->c_cc[VEOF] = CEOF;
1547c478bd9Sstevel@tonic-gate 				cb->c_cc[VEOL] = CNUL;
1557c478bd9Sstevel@tonic-gate 							   /* SWTCH purposely not set */
1567c478bd9Sstevel@tonic-gate 			}
1577c478bd9Sstevel@tonic-gate 			else if((term & TERMIOS) && eqarg("ospeed", argc) && --argc) {
1587c478bd9Sstevel@tonic-gate 				s_arg = *++argv;
1597c478bd9Sstevel@tonic-gate 				match = 0;
1607c478bd9Sstevel@tonic-gate 				for(i=0; speeds[i].string; i++)
1617c478bd9Sstevel@tonic-gate 					if(eq(speeds[i].string))
1627c478bd9Sstevel@tonic-gate 					    cfsetospeed(cb, speeds[i].speed);
1637c478bd9Sstevel@tonic-gate 				if(!match)
1647c478bd9Sstevel@tonic-gate 					return s_arg;
1657c478bd9Sstevel@tonic-gate 				continue;
1667c478bd9Sstevel@tonic-gate 			}
1677c478bd9Sstevel@tonic-gate 			else if((term & TERMIOS) && eqarg("ispeed", argc) && --argc) {
1687c478bd9Sstevel@tonic-gate 				s_arg = *++argv;
1697c478bd9Sstevel@tonic-gate 				match = 0;
1707c478bd9Sstevel@tonic-gate 				for(i=0; speeds[i].string; i++)
1717c478bd9Sstevel@tonic-gate 					if(eq(speeds[i].string))
1727c478bd9Sstevel@tonic-gate 					    cfsetispeed(cb, speeds[i].speed);
1737c478bd9Sstevel@tonic-gate 				if(!match)
1747c478bd9Sstevel@tonic-gate 					return s_arg;
1757c478bd9Sstevel@tonic-gate 				continue;
1767c478bd9Sstevel@tonic-gate 			}
1777c478bd9Sstevel@tonic-gate 			else if (argc == 0) {
1787c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, "stty: No argument for \"%s\"\n", s_arg);
1797c478bd9Sstevel@tonic-gate 				exit(1);
1807c478bd9Sstevel@tonic-gate 			}
1817c478bd9Sstevel@tonic-gate 			for(i=0; speeds[i].string; i++)
1827c478bd9Sstevel@tonic-gate 				if(eq(speeds[i].string)) {
1837c478bd9Sstevel@tonic-gate 					cfsetospeed(cb, B0);
1847c478bd9Sstevel@tonic-gate 					cfsetispeed(cb, B0);
1857c478bd9Sstevel@tonic-gate 					cfsetospeed(cb, speeds[i].speed);
1867c478bd9Sstevel@tonic-gate 				}
1877c478bd9Sstevel@tonic-gate 		}
1887c478bd9Sstevel@tonic-gate 		if ((!(term & ASYNC) || term == -1) && eqarg("ctab", argc) && --argc) {
1897c478bd9Sstevel@tonic-gate 			cb->c_cc[7] = gct(*++argv, term);
1907c478bd9Sstevel@tonic-gate 			continue;
1917c478bd9Sstevel@tonic-gate 		}
1927c478bd9Sstevel@tonic-gate 		else if (argc == 0) {
1937c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "stty: No argument for \"%s\"\n", s_arg);
1947c478bd9Sstevel@tonic-gate 			exit(1);
1957c478bd9Sstevel@tonic-gate 		}
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 		for(i=0; imodes[i].string; i++)
1987c478bd9Sstevel@tonic-gate 			if(eq(imodes[i].string)) {
1997c478bd9Sstevel@tonic-gate 				cb->c_iflag &= ~imodes[i].reset;
2007c478bd9Sstevel@tonic-gate 				cb->c_iflag |= imodes[i].set;
2017c478bd9Sstevel@tonic-gate 			}
2027c478bd9Sstevel@tonic-gate 		if((term & TERMIOS) || term == -1) {
2037c478bd9Sstevel@tonic-gate 			for(i=0; nimodes[i].string; i++)
2047c478bd9Sstevel@tonic-gate 				if(eq(nimodes[i].string)) {
2057c478bd9Sstevel@tonic-gate 					cb->c_iflag &= ~nimodes[i].reset;
2067c478bd9Sstevel@tonic-gate 					cb->c_iflag |= nimodes[i].set;
2077c478bd9Sstevel@tonic-gate 				}
2087c478bd9Sstevel@tonic-gate 		}
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 		for(i=0; omodes[i].string; i++)
2117c478bd9Sstevel@tonic-gate 			if(eq(omodes[i].string)) {
2127c478bd9Sstevel@tonic-gate 				cb->c_oflag &= ~omodes[i].reset;
2137c478bd9Sstevel@tonic-gate 				cb->c_oflag |= omodes[i].set;
2147c478bd9Sstevel@tonic-gate 			}
2157c478bd9Sstevel@tonic-gate 		if((!(term & ASYNC) || term == -1) && eq("sane")) {
2167c478bd9Sstevel@tonic-gate 			cb->c_oflag |= TAB3;
2177c478bd9Sstevel@tonic-gate 			continue;
2187c478bd9Sstevel@tonic-gate 		}
2197c478bd9Sstevel@tonic-gate 		for(i=0; cmodes[i].string; i++)
2207c478bd9Sstevel@tonic-gate 			if(eq(cmodes[i].string)) {
2217c478bd9Sstevel@tonic-gate 				cb->c_cflag &= ~cmodes[i].reset;
2227c478bd9Sstevel@tonic-gate 				cb->c_cflag |= cmodes[i].set;
2237c478bd9Sstevel@tonic-gate 			}
2247c478bd9Sstevel@tonic-gate 		if((term & TERMIOS) || term == -1)
2257c478bd9Sstevel@tonic-gate 			for(i=0; ncmodes[i].string; i++)
2267c478bd9Sstevel@tonic-gate 				if(eq(ncmodes[i].string)) {
2277c478bd9Sstevel@tonic-gate 					cb->c_cflag &= ~ncmodes[i].reset;
2287c478bd9Sstevel@tonic-gate 					cb->c_cflag |= ncmodes[i].set;
2297c478bd9Sstevel@tonic-gate 				}
2307c478bd9Sstevel@tonic-gate 		for(i=0; lmodes[i].string; i++)
2317c478bd9Sstevel@tonic-gate 			if(eq(lmodes[i].string)) {
2327c478bd9Sstevel@tonic-gate 				cb->c_lflag &= ~lmodes[i].reset;
2337c478bd9Sstevel@tonic-gate 				cb->c_lflag |= lmodes[i].set;
2347c478bd9Sstevel@tonic-gate 			}
2357c478bd9Sstevel@tonic-gate 		if((term & TERMIOS) || term == -1)
2367c478bd9Sstevel@tonic-gate 			for(i=0; nlmodes[i].string; i++)
2377c478bd9Sstevel@tonic-gate 				if(eq(nlmodes[i].string)) {
2387c478bd9Sstevel@tonic-gate 					cb->c_lflag &= ~nlmodes[i].reset;
2397c478bd9Sstevel@tonic-gate 					cb->c_lflag |= nlmodes[i].set;
2407c478bd9Sstevel@tonic-gate 				}
2417c478bd9Sstevel@tonic-gate 		if((term & FLOW) || term == -1) {
2427c478bd9Sstevel@tonic-gate 			for(i=0; hmodes[i].string; i++)
2437c478bd9Sstevel@tonic-gate 				if(eq(hmodes[i].string)) {
2447c478bd9Sstevel@tonic-gate 					termiox->x_hflag &= ~hmodes[i].reset;
2457c478bd9Sstevel@tonic-gate 					termiox->x_hflag |= hmodes[i].set;
2467c478bd9Sstevel@tonic-gate 				}
2477c478bd9Sstevel@tonic-gate 			for(i=0; clkmodes[i].string; i++)
2487c478bd9Sstevel@tonic-gate 				if(eq(clkmodes[i].string)) {
2497c478bd9Sstevel@tonic-gate 					termiox->x_cflag &= ~clkmodes[i].reset;
2507c478bd9Sstevel@tonic-gate 					termiox->x_cflag |= clkmodes[i].set;
2517c478bd9Sstevel@tonic-gate 				}
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 		}
2547c478bd9Sstevel@tonic-gate 		if(eqarg("rows", argc) && --argc)
2557c478bd9Sstevel@tonic-gate 			winsize->ws_row = atoi(*++argv);
2567c478bd9Sstevel@tonic-gate 		else if((eqarg("columns", argc) || eqarg("cols", argc)) && --argc)
2577c478bd9Sstevel@tonic-gate 			winsize->ws_col = atoi(*++argv);
2587c478bd9Sstevel@tonic-gate 		else if(eqarg("xpixels", argc) && --argc)
2597c478bd9Sstevel@tonic-gate 			winsize->ws_xpixel = atoi(*++argv);
2607c478bd9Sstevel@tonic-gate 		else if(eqarg("ypixels", argc) && --argc)
2617c478bd9Sstevel@tonic-gate 			winsize->ws_ypixel = atoi(*++argv);
2627c478bd9Sstevel@tonic-gate 		else if (argc == 0) {
2637c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "stty: No argument for \"%s\"\n", s_arg);
2647c478bd9Sstevel@tonic-gate 			exit(1);
2657c478bd9Sstevel@tonic-gate 		}
2667c478bd9Sstevel@tonic-gate 		if(!match)
2677c478bd9Sstevel@tonic-gate 			if(!encode(cb, term)) {
2687c478bd9Sstevel@tonic-gate 				return(s_arg); /* parsing failed */
2697c478bd9Sstevel@tonic-gate 			}
2707c478bd9Sstevel@tonic-gate 	}
2717c478bd9Sstevel@tonic-gate 	return((char *)0);
2727c478bd9Sstevel@tonic-gate }
2737c478bd9Sstevel@tonic-gate 
eq(string)2747c478bd9Sstevel@tonic-gate static int eq(string)
2757c478bd9Sstevel@tonic-gate char *string;
2767c478bd9Sstevel@tonic-gate {
277*cc6c5292Schin 	int i;
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate 	if(!s_arg)
2807c478bd9Sstevel@tonic-gate 		return(0);
2817c478bd9Sstevel@tonic-gate 	i = 0;
2827c478bd9Sstevel@tonic-gate loop:
2837c478bd9Sstevel@tonic-gate 	if(s_arg[i] != string[i])
2847c478bd9Sstevel@tonic-gate 		return(0);
2857c478bd9Sstevel@tonic-gate 	if(s_arg[i++] != '\0')
2867c478bd9Sstevel@tonic-gate 		goto loop;
2877c478bd9Sstevel@tonic-gate 	match++;
2887c478bd9Sstevel@tonic-gate 	return(1);
2897c478bd9Sstevel@tonic-gate }
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate /* Checks for options that require an argument */
2927c478bd9Sstevel@tonic-gate static int
eqarg(char * string,int argc)293*cc6c5292Schin eqarg(char *string, int argc)
2947c478bd9Sstevel@tonic-gate {
2957c478bd9Sstevel@tonic-gate 	int status;
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate 	if ((status = eq(string)) == 1) {
2987c478bd9Sstevel@tonic-gate 		if (argc <= 1) {
2997c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "stty: No argument for \"%s\"\n",
3007c478bd9Sstevel@tonic-gate 					 	s_arg);
3017c478bd9Sstevel@tonic-gate 			exit(1);
3027c478bd9Sstevel@tonic-gate 		}
3037c478bd9Sstevel@tonic-gate 	}
3047c478bd9Sstevel@tonic-gate 	return(status);
3057c478bd9Sstevel@tonic-gate }
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate /* get pseudo control characters from terminal */
3087c478bd9Sstevel@tonic-gate /* and convert to internal representation      */
gct(cp,term)3097c478bd9Sstevel@tonic-gate static int gct(cp, term)
310*cc6c5292Schin char *cp;
3117c478bd9Sstevel@tonic-gate int term;
3127c478bd9Sstevel@tonic-gate {
313*cc6c5292Schin 	int c;
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	c = *cp++;
3167c478bd9Sstevel@tonic-gate 	if (c == '^') {
3177c478bd9Sstevel@tonic-gate 		c = *cp;
3187c478bd9Sstevel@tonic-gate 		if (c == '?')
3197c478bd9Sstevel@tonic-gate 			c = 0177;		/* map '^?' to DEL */
3207c478bd9Sstevel@tonic-gate 		else if (c == '-')
3217c478bd9Sstevel@tonic-gate 			c = (term & TERMIOS) ? _POSIX_VDISABLE : 0200;		/* map '^-' to undefined */
3227c478bd9Sstevel@tonic-gate 		else
3237c478bd9Sstevel@tonic-gate 			c &= 037;
3247c478bd9Sstevel@tonic-gate 	}
3257c478bd9Sstevel@tonic-gate 	return(c);
3267c478bd9Sstevel@tonic-gate }
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate /* get modes of tty device and fill in applicable structures */
3297c478bd9Sstevel@tonic-gate int
get_ttymode(fd,termio,termios,stermio,termiox,winsize)3307c478bd9Sstevel@tonic-gate get_ttymode(fd, termio, termios, stermio, termiox, winsize)
3317c478bd9Sstevel@tonic-gate int fd;
3327c478bd9Sstevel@tonic-gate struct termio *termio;
3337c478bd9Sstevel@tonic-gate struct termios *termios;
3347c478bd9Sstevel@tonic-gate struct stio *stermio;
3357c478bd9Sstevel@tonic-gate struct termiox *termiox;
3367c478bd9Sstevel@tonic-gate struct winsize *winsize;
3377c478bd9Sstevel@tonic-gate {
3387c478bd9Sstevel@tonic-gate 	int i;
3397c478bd9Sstevel@tonic-gate 	int term = 0;
3407c478bd9Sstevel@tonic-gate 	if(ioctl(fd, STGET, stermio) == -1) {
3417c478bd9Sstevel@tonic-gate 		term |= ASYNC;
3427c478bd9Sstevel@tonic-gate 		if(ioctl(fd, TCGETS, termios) == -1) {
3437c478bd9Sstevel@tonic-gate 			if(ioctl(fd, TCGETA, termio) == -1)
3447c478bd9Sstevel@tonic-gate 				return -1;
3457c478bd9Sstevel@tonic-gate 			termios->c_lflag = termio->c_lflag;
3467c478bd9Sstevel@tonic-gate 			termios->c_oflag = termio->c_oflag;
3477c478bd9Sstevel@tonic-gate 			termios->c_iflag = termio->c_iflag;
3487c478bd9Sstevel@tonic-gate 			termios->c_cflag = termio->c_cflag;
3497c478bd9Sstevel@tonic-gate 			for(i = 0; i < NCC; i++)
3507c478bd9Sstevel@tonic-gate 				termios->c_cc[i] = termio->c_cc[i];
3517c478bd9Sstevel@tonic-gate 		} else
3527c478bd9Sstevel@tonic-gate 			term |= TERMIOS;
3537c478bd9Sstevel@tonic-gate 	}
3547c478bd9Sstevel@tonic-gate 	else {
3557c478bd9Sstevel@tonic-gate 		termios->c_cc[7] = (unsigned)stermio->tab;
3567c478bd9Sstevel@tonic-gate 		termios->c_lflag = stermio->lmode;
3577c478bd9Sstevel@tonic-gate 		termios->c_oflag = stermio->omode;
3587c478bd9Sstevel@tonic-gate 		termios->c_iflag = stermio->imode;
3597c478bd9Sstevel@tonic-gate 	}
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate 	if(ioctl(fd, TCGETX, termiox) == 0)
3627c478bd9Sstevel@tonic-gate 		term |= FLOW;
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 	if(ioctl(fd, TIOCGWINSZ, winsize) == 0)
3657c478bd9Sstevel@tonic-gate 		term |= WINDOW;
3667c478bd9Sstevel@tonic-gate 	return term;
3677c478bd9Sstevel@tonic-gate }
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate /* set tty modes */
3707c478bd9Sstevel@tonic-gate int
set_ttymode(fd,term,termio,termios,stermio,termiox,winsize,owinsize)3717c478bd9Sstevel@tonic-gate set_ttymode(fd, term, termio, termios, stermio, termiox, winsize, owinsize)
3727c478bd9Sstevel@tonic-gate int fd, term;
3737c478bd9Sstevel@tonic-gate struct termio *termio;
3747c478bd9Sstevel@tonic-gate struct termios *termios;
3757c478bd9Sstevel@tonic-gate struct stio *stermio;
3767c478bd9Sstevel@tonic-gate struct termiox *termiox;
3777c478bd9Sstevel@tonic-gate struct winsize *winsize, *owinsize;
3787c478bd9Sstevel@tonic-gate {
3797c478bd9Sstevel@tonic-gate 	int i;
3807c478bd9Sstevel@tonic-gate 	if (term & ASYNC) {
3817c478bd9Sstevel@tonic-gate 		if(term & TERMIOS) {
3827c478bd9Sstevel@tonic-gate 			if(ioctl(fd, TCSETSW, termios) == -1)
3837c478bd9Sstevel@tonic-gate 				return -1;
3847c478bd9Sstevel@tonic-gate 		} else {
3857c478bd9Sstevel@tonic-gate 			termio->c_lflag = termios->c_lflag;
3867c478bd9Sstevel@tonic-gate 			termio->c_oflag = termios->c_oflag;
3877c478bd9Sstevel@tonic-gate 			termio->c_iflag = termios->c_iflag;
3887c478bd9Sstevel@tonic-gate 			termio->c_cflag = termios->c_cflag;
3897c478bd9Sstevel@tonic-gate 			for(i = 0; i < NCC; i++)
3907c478bd9Sstevel@tonic-gate 				termio->c_cc[i] = termios->c_cc[i];
3917c478bd9Sstevel@tonic-gate 			if(ioctl(fd, TCSETAW, termio) == -1)
3927c478bd9Sstevel@tonic-gate 				return -1;
3937c478bd9Sstevel@tonic-gate 		}
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate 	} else {
3967c478bd9Sstevel@tonic-gate 		stermio->imode = termios->c_iflag;
3977c478bd9Sstevel@tonic-gate 		stermio->omode = termios->c_oflag;
3987c478bd9Sstevel@tonic-gate 		stermio->lmode = termios->c_lflag;
3997c478bd9Sstevel@tonic-gate 		stermio->tab = termios->c_cc[7];
4007c478bd9Sstevel@tonic-gate 		if (ioctl(fd, STSET, stermio) == -1)
4017c478bd9Sstevel@tonic-gate 			return -1;
4027c478bd9Sstevel@tonic-gate 	}
4037c478bd9Sstevel@tonic-gate 	if(term & FLOW) {
4047c478bd9Sstevel@tonic-gate 		if(ioctl(fd, TCSETXW, termiox) == -1)
4057c478bd9Sstevel@tonic-gate 			return -1;
4067c478bd9Sstevel@tonic-gate 	}
4077c478bd9Sstevel@tonic-gate 	if((owinsize->ws_col != winsize->ws_col
4087c478bd9Sstevel@tonic-gate 	   || owinsize->ws_row != winsize->ws_row)
4097c478bd9Sstevel@tonic-gate 	   && ioctl(0, TIOCSWINSZ, winsize) != 0)
4107c478bd9Sstevel@tonic-gate 		return -1;
4117c478bd9Sstevel@tonic-gate 	return 0;
4127c478bd9Sstevel@tonic-gate }
4137c478bd9Sstevel@tonic-gate 
encode(cb,term)4147c478bd9Sstevel@tonic-gate static int encode(cb, term)
4157c478bd9Sstevel@tonic-gate struct	termios	*cb;
4167c478bd9Sstevel@tonic-gate int term;
4177c478bd9Sstevel@tonic-gate {
4187c478bd9Sstevel@tonic-gate 	unsigned long grab[20], i;
4197c478bd9Sstevel@tonic-gate 	int last;
4207c478bd9Sstevel@tonic-gate 	i = sscanf(s_arg,
4217c478bd9Sstevel@tonic-gate 	"%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx",
4227c478bd9Sstevel@tonic-gate 	&grab[0],&grab[1],&grab[2],&grab[3],&grab[4],&grab[5],&grab[6],
4237c478bd9Sstevel@tonic-gate 	&grab[7],&grab[8],&grab[9],&grab[10],&grab[11],
4247c478bd9Sstevel@tonic-gate 	&grab[12], &grab[13], &grab[14], &grab[15],
4257c478bd9Sstevel@tonic-gate 	&grab[16], &grab[17], &grab[18], &grab[19]);
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate 	if((term & TERMIOS) && i < 20 && term != -1 || i < 12)
4287c478bd9Sstevel@tonic-gate 		return(0);
4297c478bd9Sstevel@tonic-gate 	cb->c_iflag = grab[0];
4307c478bd9Sstevel@tonic-gate 	cb->c_oflag = grab[1];
4317c478bd9Sstevel@tonic-gate 	cb->c_cflag = grab[2];
4327c478bd9Sstevel@tonic-gate 	cb->c_lflag = grab[3];
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate 	if(term & TERMIOS)
4357c478bd9Sstevel@tonic-gate 		last = NCCS - 1;
4367c478bd9Sstevel@tonic-gate 	else
4377c478bd9Sstevel@tonic-gate 		last = NCC;
4387c478bd9Sstevel@tonic-gate 	for(i=0; i<last; i++)
4397c478bd9Sstevel@tonic-gate 		cb->c_cc[i] = (unsigned char) grab[i+4];
4407c478bd9Sstevel@tonic-gate 	return(1);
4417c478bd9Sstevel@tonic-gate }
4427c478bd9Sstevel@tonic-gate 
443