xref: /onnv-gate/usr/src/ucbcmd/stty/sttyparse.c (revision 669:3cf64fd04122)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate  * Copyright 1997 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
280Sstevel@tonic-gate /*	  All Rights Reserved  	*/
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
310Sstevel@tonic-gate 
320Sstevel@tonic-gate 
330Sstevel@tonic-gate #include <stdio.h>
340Sstevel@tonic-gate #include <stdlib.h>
350Sstevel@tonic-gate #include <sys/types.h>
360Sstevel@tonic-gate #include <termio.h>
370Sstevel@tonic-gate #include <sys/stermio.h>
380Sstevel@tonic-gate #include <sys/termiox.h>
390Sstevel@tonic-gate #include "stty.h"
400Sstevel@tonic-gate 
410Sstevel@tonic-gate static char	*s_arg;			/* s_arg: ptr to mode to be set */
420Sstevel@tonic-gate static int	match;
430Sstevel@tonic-gate static int gct(), eq(), encode();
44*669Schin static int eqarg(char *, int);
450Sstevel@tonic-gate 
460Sstevel@tonic-gate /* set terminal modes for supplied options */
470Sstevel@tonic-gate char *
sttyparse(argc,argv,term,ocb,cb,termiox,winsize)480Sstevel@tonic-gate sttyparse(argc, argv, term, ocb, cb, termiox, winsize)
490Sstevel@tonic-gate int	argc;
500Sstevel@tonic-gate char	*argv[];
510Sstevel@tonic-gate int	term; /* type of tty device, -1 means allow all options,
520Sstevel@tonic-gate 	       * no sanity check
530Sstevel@tonic-gate 	       */
540Sstevel@tonic-gate struct	termio	*ocb;
550Sstevel@tonic-gate struct	termios	*cb;
560Sstevel@tonic-gate struct	termiox	*termiox;
570Sstevel@tonic-gate struct	winsize	*winsize;
580Sstevel@tonic-gate {
59*669Schin 	int i;
600Sstevel@tonic-gate 	extern	const struct	speeds	speeds[];
610Sstevel@tonic-gate 	extern	const struct	mds	lmodes[];
620Sstevel@tonic-gate 	extern	const struct	mds	nlmodes[];
630Sstevel@tonic-gate 	extern	const struct	mds	cmodes[];
640Sstevel@tonic-gate 	extern	const struct	mds	ncmodes[];
650Sstevel@tonic-gate 	extern	const struct	mds	imodes[];
660Sstevel@tonic-gate 	extern	const struct	mds	nimodes[];
670Sstevel@tonic-gate 	extern	const struct	mds	omodes[];
680Sstevel@tonic-gate 	extern	const struct	mds	hmodes[];
690Sstevel@tonic-gate 	extern	const struct	mds	clkmodes[];
700Sstevel@tonic-gate 
710Sstevel@tonic-gate 	while(--argc > 0) {
720Sstevel@tonic-gate 
730Sstevel@tonic-gate 		s_arg = *++argv;
740Sstevel@tonic-gate 		match = 0;
750Sstevel@tonic-gate 		if ((term & ASYNC) || term == -1) {
760Sstevel@tonic-gate 			if (eqarg("erase", argc) && --argc)
770Sstevel@tonic-gate 				cb->c_cc[VERASE] = gct(*++argv, term);
780Sstevel@tonic-gate 			else if (eqarg("intr", argc) && --argc)
790Sstevel@tonic-gate 				cb->c_cc[VINTR] = gct(*++argv, term);
800Sstevel@tonic-gate 			else if (eqarg("quit", argc) && --argc)
810Sstevel@tonic-gate 				cb->c_cc[VQUIT] = gct(*++argv, term);
820Sstevel@tonic-gate 			else if (eqarg("eof", argc) && --argc)
830Sstevel@tonic-gate 				cb->c_cc[VEOF] = gct(*++argv, term);
840Sstevel@tonic-gate 			else if (eqarg("min", argc) && --argc)
850Sstevel@tonic-gate 				cb->c_cc[VMIN] = atoi(*++argv);
860Sstevel@tonic-gate 			else if (eqarg("eol", argc) && --argc)
870Sstevel@tonic-gate 				cb->c_cc[VEOL] = gct(*++argv, term);
880Sstevel@tonic-gate 			else if (eqarg("brk", argc) && --argc)
890Sstevel@tonic-gate 				cb->c_cc[VEOL] = gct(*++argv, term);
900Sstevel@tonic-gate 			else if (eqarg("eol2", argc) && --argc)
910Sstevel@tonic-gate 				cb->c_cc[VEOL2] = gct(*++argv, term);
920Sstevel@tonic-gate 			else if (eqarg("time", argc) && --argc)
930Sstevel@tonic-gate 				cb->c_cc[VTIME] = atoi(*++argv);
940Sstevel@tonic-gate 			else if (eqarg("kill", argc) && --argc)
950Sstevel@tonic-gate 				cb->c_cc[VKILL] = gct(*++argv, term);
960Sstevel@tonic-gate 			else if (eqarg("swtch", argc) && --argc)
970Sstevel@tonic-gate 				cb->c_cc[VSWTCH] = gct(*++argv, term);
980Sstevel@tonic-gate 			if(match)
990Sstevel@tonic-gate 				continue;
1000Sstevel@tonic-gate 			if((term & TERMIOS) || term == -1) {
1010Sstevel@tonic-gate 				if (eqarg("start", argc) && --argc)
1020Sstevel@tonic-gate 					cb->c_cc[VSTART] = gct(*++argv, term);
1030Sstevel@tonic-gate 				else if (eqarg("stop", argc) && --argc)
1040Sstevel@tonic-gate 					cb->c_cc[VSTOP] = gct(*++argv, term);
1050Sstevel@tonic-gate 				else if (eqarg("susp", argc) && --argc)
1060Sstevel@tonic-gate 					cb->c_cc[VSUSP] = gct(*++argv, term);
1070Sstevel@tonic-gate 				else if (eqarg("dsusp", argc) && --argc)
1080Sstevel@tonic-gate 					cb->c_cc[VDSUSP] = gct(*++argv, term);
1090Sstevel@tonic-gate 				else if (eqarg("rprnt", argc) && --argc)
1100Sstevel@tonic-gate 					cb->c_cc[VREPRINT] = gct(*++argv, term);
1110Sstevel@tonic-gate 				else if (eqarg("flush", argc) && --argc)
1120Sstevel@tonic-gate 					cb->c_cc[VDISCARD] = gct(*++argv, term);
1130Sstevel@tonic-gate 				else if (eqarg("werase", argc) && --argc)
1140Sstevel@tonic-gate 					cb->c_cc[VWERASE] = gct(*++argv, term);
1150Sstevel@tonic-gate 				else if (eqarg("lnext", argc) && --argc)
1160Sstevel@tonic-gate 					cb->c_cc[VLNEXT] = gct(*++argv, term);
1170Sstevel@tonic-gate 			}
1180Sstevel@tonic-gate 			if(match)
1190Sstevel@tonic-gate 				continue;
1200Sstevel@tonic-gate 			if (eq("ek")) {
1210Sstevel@tonic-gate 				cb->c_cc[VERASE] = CERASE;
1220Sstevel@tonic-gate 				cb->c_cc[VKILL] = CKILL;
1230Sstevel@tonic-gate 			}
1240Sstevel@tonic-gate 			else if (eq("crt") || eq("newcrt")) {
1250Sstevel@tonic-gate 				cb->c_lflag &= ~ECHOPRT;
1260Sstevel@tonic-gate 				cb->c_lflag |= ECHOE|ECHOCTL;
1270Sstevel@tonic-gate 				if (cfgetospeed(cb) >= B1200)
1280Sstevel@tonic-gate 					cb->c_lflag |= ECHOKE;
1290Sstevel@tonic-gate 			}
1300Sstevel@tonic-gate 			else if (eq("dec")) {
1310Sstevel@tonic-gate 				cb->c_cc[VERASE] = 0177;
1320Sstevel@tonic-gate 				cb->c_cc[VKILL] = CTRL('u');
1330Sstevel@tonic-gate 				cb->c_cc[VINTR] = CTRL('c');
1340Sstevel@tonic-gate 				cb->c_lflag &= ~ECHOPRT;
1350Sstevel@tonic-gate 				cb->c_lflag |= ECHOE|ECHOCTL|IEXTEN;
1360Sstevel@tonic-gate 				if (cfgetospeed(cb) >= B1200)
1370Sstevel@tonic-gate 					cb->c_lflag |= ECHOKE;
1380Sstevel@tonic-gate 			}
1390Sstevel@tonic-gate 			else if (eqarg("line", argc) && (!(term & TERMIOS) || term == -1) && --argc) {
1400Sstevel@tonic-gate 				ocb->c_line = atoi(*++argv);
1410Sstevel@tonic-gate 				continue;
1420Sstevel@tonic-gate 			}
1430Sstevel@tonic-gate 			else if (eq("raw") || eq("cbreak")) {
1440Sstevel@tonic-gate 				cb->c_cc[VMIN] = 1;
1450Sstevel@tonic-gate 				cb->c_cc[VTIME] = 0;
1460Sstevel@tonic-gate 			}
1470Sstevel@tonic-gate 			else if (eq("-raw") || eq("-cbreak") || eq("cooked")) {
1480Sstevel@tonic-gate 				cb->c_cc[VEOF] = CEOF;
1490Sstevel@tonic-gate 				cb->c_cc[VEOL] = CNUL;
1500Sstevel@tonic-gate 			}
1510Sstevel@tonic-gate 			else if(eq("sane")) {
1520Sstevel@tonic-gate 				cb->c_cc[VERASE] = CERASE;
1530Sstevel@tonic-gate 				cb->c_cc[VKILL] = CKILL;
1540Sstevel@tonic-gate 				cb->c_cc[VQUIT] = CQUIT;
1550Sstevel@tonic-gate 				cb->c_cc[VINTR] = CINTR;
1560Sstevel@tonic-gate 				cb->c_cc[VEOF] = CEOF;
1570Sstevel@tonic-gate 				cb->c_cc[VEOL] = CNUL;
1580Sstevel@tonic-gate 							   /* SWTCH purposely not set */
1590Sstevel@tonic-gate 			}
1600Sstevel@tonic-gate 			else if((term & TERMIOS) && eqarg("ospeed", argc) && --argc) {
1610Sstevel@tonic-gate 				s_arg = *++argv;
1620Sstevel@tonic-gate 				match = 0;
1630Sstevel@tonic-gate 				for(i=0; speeds[i].string; i++)
1640Sstevel@tonic-gate 					if(eq(speeds[i].string))
1650Sstevel@tonic-gate 					    cfsetospeed(cb, speeds[i].speed);
1660Sstevel@tonic-gate 				if(!match)
1670Sstevel@tonic-gate 					return s_arg;
1680Sstevel@tonic-gate 				continue;
1690Sstevel@tonic-gate 			}
1700Sstevel@tonic-gate 			else if((term & TERMIOS) && eqarg("ispeed", argc) && --argc) {
1710Sstevel@tonic-gate 				s_arg = *++argv;
1720Sstevel@tonic-gate 				match = 0;
1730Sstevel@tonic-gate 				for(i=0; speeds[i].string; i++)
1740Sstevel@tonic-gate 					if(eq(speeds[i].string))
1750Sstevel@tonic-gate 					    cfsetispeed(cb, speeds[i].speed);
1760Sstevel@tonic-gate 				if(!match)
1770Sstevel@tonic-gate 					return s_arg;
1780Sstevel@tonic-gate 				continue;
1790Sstevel@tonic-gate 			}
1800Sstevel@tonic-gate 			else if (argc == 0) {
1810Sstevel@tonic-gate 				(void) fprintf(stderr, "stty: No argument for \"%s\"\n", s_arg);
1820Sstevel@tonic-gate 				exit(1);
1830Sstevel@tonic-gate 			}
1840Sstevel@tonic-gate 			for(i=0; speeds[i].string; i++)
1850Sstevel@tonic-gate 				if(eq(speeds[i].string)) {
1860Sstevel@tonic-gate 					cfsetospeed(cb, B0);
1870Sstevel@tonic-gate 					cfsetispeed(cb, B0);
1880Sstevel@tonic-gate 					cfsetospeed(cb, speeds[i].speed);
1890Sstevel@tonic-gate 				}
1900Sstevel@tonic-gate 		}
1910Sstevel@tonic-gate 		if ((!(term & ASYNC) || term == -1) && eqarg("ctab", argc) && --argc) {
1920Sstevel@tonic-gate 			cb->c_cc[7] = gct(*++argv, term);
1930Sstevel@tonic-gate 			continue;
1940Sstevel@tonic-gate 		}
1950Sstevel@tonic-gate 		else if (argc == 0) {
1960Sstevel@tonic-gate 			(void) fprintf(stderr, "stty: No argument for \"%s\"\n", s_arg);
1970Sstevel@tonic-gate 			exit(1);
1980Sstevel@tonic-gate 		}
1990Sstevel@tonic-gate 
2000Sstevel@tonic-gate 		for(i=0; imodes[i].string; i++)
2010Sstevel@tonic-gate 			if(eq(imodes[i].string)) {
2020Sstevel@tonic-gate 				cb->c_iflag &= ~imodes[i].reset;
2030Sstevel@tonic-gate 				cb->c_iflag |= imodes[i].set;
2040Sstevel@tonic-gate 			}
2050Sstevel@tonic-gate 		if((term & TERMIOS) || term == -1) {
2060Sstevel@tonic-gate 			for(i=0; nimodes[i].string; i++)
2070Sstevel@tonic-gate 				if(eq(nimodes[i].string)) {
2080Sstevel@tonic-gate 					cb->c_iflag &= ~nimodes[i].reset;
2090Sstevel@tonic-gate 					cb->c_iflag |= nimodes[i].set;
2100Sstevel@tonic-gate 				}
2110Sstevel@tonic-gate 		}
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate 		for(i=0; omodes[i].string; i++)
2140Sstevel@tonic-gate 			if(eq(omodes[i].string)) {
2150Sstevel@tonic-gate 				cb->c_oflag &= ~omodes[i].reset;
2160Sstevel@tonic-gate 				cb->c_oflag |= omodes[i].set;
2170Sstevel@tonic-gate 			}
2180Sstevel@tonic-gate 		if((!(term & ASYNC) || term == -1) && eq("sane")) {
2190Sstevel@tonic-gate 			cb->c_oflag |= TAB3;
2200Sstevel@tonic-gate 			continue;
2210Sstevel@tonic-gate 		}
2220Sstevel@tonic-gate 		for(i=0; cmodes[i].string; i++)
2230Sstevel@tonic-gate 			if(eq(cmodes[i].string)) {
2240Sstevel@tonic-gate 				cb->c_cflag &= ~cmodes[i].reset;
2250Sstevel@tonic-gate 				cb->c_cflag |= cmodes[i].set;
2260Sstevel@tonic-gate 			}
2270Sstevel@tonic-gate 		if((term & TERMIOS) || term == -1)
2280Sstevel@tonic-gate 			for(i=0; ncmodes[i].string; i++)
2290Sstevel@tonic-gate 				if(eq(ncmodes[i].string)) {
2300Sstevel@tonic-gate 					cb->c_cflag &= ~ncmodes[i].reset;
2310Sstevel@tonic-gate 					cb->c_cflag |= ncmodes[i].set;
2320Sstevel@tonic-gate 				}
2330Sstevel@tonic-gate 		for(i=0; lmodes[i].string; i++)
2340Sstevel@tonic-gate 			if(eq(lmodes[i].string)) {
2350Sstevel@tonic-gate 				cb->c_lflag &= ~lmodes[i].reset;
2360Sstevel@tonic-gate 				cb->c_lflag |= lmodes[i].set;
2370Sstevel@tonic-gate 			}
2380Sstevel@tonic-gate 		if((term & TERMIOS) || term == -1)
2390Sstevel@tonic-gate 			for(i=0; nlmodes[i].string; i++)
2400Sstevel@tonic-gate 				if(eq(nlmodes[i].string)) {
2410Sstevel@tonic-gate 					cb->c_lflag &= ~nlmodes[i].reset;
2420Sstevel@tonic-gate 					cb->c_lflag |= nlmodes[i].set;
2430Sstevel@tonic-gate 				}
2440Sstevel@tonic-gate 		if((term & FLOW) || term == -1) {
2450Sstevel@tonic-gate 			for(i=0; hmodes[i].string; i++)
2460Sstevel@tonic-gate 				if(eq(hmodes[i].string)) {
2470Sstevel@tonic-gate 					termiox->x_hflag &= ~hmodes[i].reset;
2480Sstevel@tonic-gate 					termiox->x_hflag |= hmodes[i].set;
2490Sstevel@tonic-gate 				}
2500Sstevel@tonic-gate 			for(i=0; clkmodes[i].string; i++)
2510Sstevel@tonic-gate 				if(eq(clkmodes[i].string)) {
2520Sstevel@tonic-gate 					termiox->x_cflag &= ~clkmodes[i].reset;
2530Sstevel@tonic-gate 					termiox->x_cflag |= clkmodes[i].set;
2540Sstevel@tonic-gate 				}
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate 		}
2570Sstevel@tonic-gate 		if(eqarg("rows", argc) && --argc)
2580Sstevel@tonic-gate 			winsize->ws_row = atoi(*++argv);
2590Sstevel@tonic-gate 		else if((eqarg("columns", argc) || eqarg("cols", argc)) && --argc)
2600Sstevel@tonic-gate 			winsize->ws_col = atoi(*++argv);
2610Sstevel@tonic-gate 		else if(eqarg("xpixels", argc) && --argc)
2620Sstevel@tonic-gate 			winsize->ws_xpixel = atoi(*++argv);
2630Sstevel@tonic-gate 		else if(eqarg("ypixels", argc) && --argc)
2640Sstevel@tonic-gate 			winsize->ws_ypixel = atoi(*++argv);
2650Sstevel@tonic-gate 		else if (argc == 0) {
2660Sstevel@tonic-gate 			(void) fprintf(stderr, "stty: No argument for \"%s\"\n", s_arg);
2670Sstevel@tonic-gate 			exit(1);
2680Sstevel@tonic-gate 		}
2690Sstevel@tonic-gate 		if(!match)
2700Sstevel@tonic-gate 			if(!encode(cb, term)) {
2710Sstevel@tonic-gate 				return(s_arg); /* parsing failed */
2720Sstevel@tonic-gate 			}
2730Sstevel@tonic-gate 	}
2740Sstevel@tonic-gate 	return((char *)0);
2750Sstevel@tonic-gate }
2760Sstevel@tonic-gate 
eq(string)2770Sstevel@tonic-gate static int eq(string)
2780Sstevel@tonic-gate char *string;
2790Sstevel@tonic-gate {
280*669Schin 	int i;
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate 	if(!s_arg)
2830Sstevel@tonic-gate 		return(0);
2840Sstevel@tonic-gate 	i = 0;
2850Sstevel@tonic-gate loop:
2860Sstevel@tonic-gate 	if(s_arg[i] != string[i])
2870Sstevel@tonic-gate 		return(0);
2880Sstevel@tonic-gate 	if(s_arg[i++] != '\0')
2890Sstevel@tonic-gate 		goto loop;
2900Sstevel@tonic-gate 	match++;
2910Sstevel@tonic-gate 	return(1);
2920Sstevel@tonic-gate }
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate /* Checks for options that require an argument */
2950Sstevel@tonic-gate static int
eqarg(char * string,int argc)296*669Schin eqarg(char *string, int argc)
2970Sstevel@tonic-gate {
2980Sstevel@tonic-gate 	int status;
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate 	if ((status = eq(string)) == 1) {
3010Sstevel@tonic-gate 		if (argc <= 1) {
3020Sstevel@tonic-gate 			(void) fprintf(stderr, "stty: No argument for \"%s\"\n",
3030Sstevel@tonic-gate 					 	s_arg);
3040Sstevel@tonic-gate 			exit(1);
3050Sstevel@tonic-gate 		}
3060Sstevel@tonic-gate 	}
3070Sstevel@tonic-gate 	return(status);
3080Sstevel@tonic-gate }
3090Sstevel@tonic-gate 
3100Sstevel@tonic-gate /* get pseudo control characters from terminal */
3110Sstevel@tonic-gate /* and convert to internal representation      */
gct(cp,term)3120Sstevel@tonic-gate static int gct(cp, term)
313*669Schin char *cp;
3140Sstevel@tonic-gate int term;
3150Sstevel@tonic-gate {
316*669Schin 	int c;
3170Sstevel@tonic-gate 
3180Sstevel@tonic-gate 	c = *cp++;
3190Sstevel@tonic-gate 	if (c == '^') {
3200Sstevel@tonic-gate 		c = *cp;
3210Sstevel@tonic-gate 		if (c == '?')
3220Sstevel@tonic-gate 			c = 0177;		/* map '^?' to DEL */
3230Sstevel@tonic-gate 		else if (c == '-')
3240Sstevel@tonic-gate 			c = (term & TERMIOS) ? _POSIX_VDISABLE : 0200;		/* map '^-' to undefined */
3250Sstevel@tonic-gate 		else
3260Sstevel@tonic-gate 			c &= 037;
3270Sstevel@tonic-gate 	}
3280Sstevel@tonic-gate 	return(c);
3290Sstevel@tonic-gate }
3300Sstevel@tonic-gate 
3310Sstevel@tonic-gate /* get modes of tty device and fill in applicable structures */
3320Sstevel@tonic-gate int
get_ttymode(fd,termio,termios,stermio,termiox,winsize)3330Sstevel@tonic-gate get_ttymode(fd, termio, termios, stermio, termiox, winsize)
3340Sstevel@tonic-gate int fd;
3350Sstevel@tonic-gate struct termio *termio;
3360Sstevel@tonic-gate struct termios *termios;
3370Sstevel@tonic-gate struct stio *stermio;
3380Sstevel@tonic-gate struct termiox *termiox;
3390Sstevel@tonic-gate struct winsize *winsize;
3400Sstevel@tonic-gate {
3410Sstevel@tonic-gate 	int i;
3420Sstevel@tonic-gate 	int term = 0;
3430Sstevel@tonic-gate 	if(ioctl(fd, STGET, stermio) == -1) {
3440Sstevel@tonic-gate 		term |= ASYNC;
3450Sstevel@tonic-gate 		if(ioctl(fd, TCGETS, termios) == -1) {
3460Sstevel@tonic-gate 			if(ioctl(fd, TCGETA, termio) == -1)
3470Sstevel@tonic-gate 				return -1;
3480Sstevel@tonic-gate 			termios->c_lflag = termio->c_lflag;
3490Sstevel@tonic-gate 			termios->c_oflag = termio->c_oflag;
3500Sstevel@tonic-gate 			termios->c_iflag = termio->c_iflag;
3510Sstevel@tonic-gate 			termios->c_cflag = termio->c_cflag;
3520Sstevel@tonic-gate 			for(i = 0; i < NCC; i++)
3530Sstevel@tonic-gate 				termios->c_cc[i] = termio->c_cc[i];
3540Sstevel@tonic-gate 		} else
3550Sstevel@tonic-gate 			term |= TERMIOS;
3560Sstevel@tonic-gate 	}
3570Sstevel@tonic-gate 	else {
3580Sstevel@tonic-gate 		termios->c_cc[7] = (unsigned)stermio->tab;
3590Sstevel@tonic-gate 		termios->c_lflag = stermio->lmode;
3600Sstevel@tonic-gate 		termios->c_oflag = stermio->omode;
3610Sstevel@tonic-gate 		termios->c_iflag = stermio->imode;
3620Sstevel@tonic-gate 	}
3630Sstevel@tonic-gate 
3640Sstevel@tonic-gate 	if(ioctl(fd, TCGETX, termiox) == 0)
3650Sstevel@tonic-gate 		term |= FLOW;
3660Sstevel@tonic-gate 
3670Sstevel@tonic-gate 	if(ioctl(fd, TIOCGWINSZ, winsize) == 0)
3680Sstevel@tonic-gate 		term |= WINDOW;
3690Sstevel@tonic-gate 	return term;
3700Sstevel@tonic-gate }
3710Sstevel@tonic-gate 
3720Sstevel@tonic-gate /* set tty modes */
3730Sstevel@tonic-gate int
set_ttymode(fd,term,termio,termios,stermio,termiox,winsize,owinsize)3740Sstevel@tonic-gate set_ttymode(fd, term, termio, termios, stermio, termiox, winsize, owinsize)
3750Sstevel@tonic-gate int fd, term;
3760Sstevel@tonic-gate struct termio *termio;
3770Sstevel@tonic-gate struct termios *termios;
3780Sstevel@tonic-gate struct stio *stermio;
3790Sstevel@tonic-gate struct termiox *termiox;
3800Sstevel@tonic-gate struct winsize *winsize, *owinsize;
3810Sstevel@tonic-gate {
3820Sstevel@tonic-gate 	int i;
3830Sstevel@tonic-gate 	if (term & ASYNC) {
3840Sstevel@tonic-gate 		if(term & TERMIOS) {
3850Sstevel@tonic-gate 			if(ioctl(fd, TCSETSW, termios) == -1)
3860Sstevel@tonic-gate 				return -1;
3870Sstevel@tonic-gate 		} else {
3880Sstevel@tonic-gate 			termio->c_lflag = termios->c_lflag;
3890Sstevel@tonic-gate 			termio->c_oflag = termios->c_oflag;
3900Sstevel@tonic-gate 			termio->c_iflag = termios->c_iflag;
3910Sstevel@tonic-gate 			termio->c_cflag = termios->c_cflag;
3920Sstevel@tonic-gate 			for(i = 0; i < NCC; i++)
3930Sstevel@tonic-gate 				termio->c_cc[i] = termios->c_cc[i];
3940Sstevel@tonic-gate 			if(ioctl(fd, TCSETAW, termio) == -1)
3950Sstevel@tonic-gate 				return -1;
3960Sstevel@tonic-gate 		}
3970Sstevel@tonic-gate 
3980Sstevel@tonic-gate 	} else {
3990Sstevel@tonic-gate 		stermio->imode = termios->c_iflag;
4000Sstevel@tonic-gate 		stermio->omode = termios->c_oflag;
4010Sstevel@tonic-gate 		stermio->lmode = termios->c_lflag;
4020Sstevel@tonic-gate 		stermio->tab = termios->c_cc[7];
4030Sstevel@tonic-gate 		if (ioctl(fd, STSET, stermio) == -1)
4040Sstevel@tonic-gate 			return -1;
4050Sstevel@tonic-gate 	}
4060Sstevel@tonic-gate 	if(term & FLOW) {
4070Sstevel@tonic-gate 		if(ioctl(fd, TCSETXW, termiox) == -1)
4080Sstevel@tonic-gate 			return -1;
4090Sstevel@tonic-gate 	}
4100Sstevel@tonic-gate 	if((owinsize->ws_col != winsize->ws_col
4110Sstevel@tonic-gate 	   || owinsize->ws_row != winsize->ws_row)
4120Sstevel@tonic-gate 	   && ioctl(0, TIOCSWINSZ, winsize) != 0)
4130Sstevel@tonic-gate 		return -1;
4140Sstevel@tonic-gate 	return 0;
4150Sstevel@tonic-gate }
4160Sstevel@tonic-gate 
encode(cb,term)4170Sstevel@tonic-gate static int encode(cb, term)
4180Sstevel@tonic-gate struct	termios	*cb;
4190Sstevel@tonic-gate int term;
4200Sstevel@tonic-gate {
4210Sstevel@tonic-gate 	unsigned long grab[20], i;
4220Sstevel@tonic-gate 	int last;
4230Sstevel@tonic-gate 	i = sscanf(s_arg,
4240Sstevel@tonic-gate 	"%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx",
4250Sstevel@tonic-gate 	&grab[0],&grab[1],&grab[2],&grab[3],&grab[4],&grab[5],&grab[6],
4260Sstevel@tonic-gate 	&grab[7],&grab[8],&grab[9],&grab[10],&grab[11],
4270Sstevel@tonic-gate 	&grab[12], &grab[13], &grab[14], &grab[15],
4280Sstevel@tonic-gate 	&grab[16], &grab[17], &grab[18], &grab[19]);
4290Sstevel@tonic-gate 
4300Sstevel@tonic-gate 	if((term & TERMIOS) && i < 20 && term != -1 || i < 12)
4310Sstevel@tonic-gate 		return(0);
4320Sstevel@tonic-gate 	cb->c_iflag = grab[0];
4330Sstevel@tonic-gate 	cb->c_oflag = grab[1];
4340Sstevel@tonic-gate 	cb->c_cflag = grab[2];
4350Sstevel@tonic-gate 	cb->c_lflag = grab[3];
4360Sstevel@tonic-gate 
4370Sstevel@tonic-gate 	if(term & TERMIOS)
4380Sstevel@tonic-gate 		last = NCCS - 1;
4390Sstevel@tonic-gate 	else
4400Sstevel@tonic-gate 		last = NCC;
4410Sstevel@tonic-gate 	for(i=0; i<last; i++)
4420Sstevel@tonic-gate 		cb->c_cc[i] = (unsigned char) grab[i+4];
4430Sstevel@tonic-gate 	return(1);
4440Sstevel@tonic-gate }
4450Sstevel@tonic-gate 
446