xref: /onnv-gate/usr/src/lib/libnsl/dial/line.c (revision 9354:9559ac454e7e)
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
5*9354STim.Marsland@Sun.COM  * Common Development and Distribution License (the "License").
6*9354STim.Marsland@Sun.COM  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21132Srobinson 
22132Srobinson /*
23*9354STim.Marsland@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24132Srobinson  * Use is subject to license terms.
25132Srobinson  */
26132Srobinson 
270Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
280Sstevel@tonic-gate /*	  All Rights Reserved  	*/
290Sstevel@tonic-gate 
30132Srobinson /*
31132Srobinson  * This is a new line.c, which consists of line.c and culine.c
320Sstevel@tonic-gate  * merged together.
330Sstevel@tonic-gate  */
340Sstevel@tonic-gate 
351219Sraf #include "mt.h"
360Sstevel@tonic-gate #include "uucp.h"
370Sstevel@tonic-gate 
380Sstevel@tonic-gate static const struct sg_spds {
390Sstevel@tonic-gate 	int	sp_val,
400Sstevel@tonic-gate 		sp_name;
410Sstevel@tonic-gate } spds[] = {
420Sstevel@tonic-gate 	{  50,   B50},
430Sstevel@tonic-gate 	{  75,   B75},
440Sstevel@tonic-gate 	{ 110,  B110},
450Sstevel@tonic-gate 	{ 134,  B134},
460Sstevel@tonic-gate 	{ 150,  B150},
470Sstevel@tonic-gate 	{ 200,  B200},
480Sstevel@tonic-gate 	{ 300,  B300},
490Sstevel@tonic-gate 	{ 600,  B600},
500Sstevel@tonic-gate 	{1200, B1200},
510Sstevel@tonic-gate 	{1800, B1800},
520Sstevel@tonic-gate 	{2400, B2400},
530Sstevel@tonic-gate 	{4800, B4800},
540Sstevel@tonic-gate 	{9600, B9600},
550Sstevel@tonic-gate #ifdef EXTA
560Sstevel@tonic-gate 	{19200,	EXTA},
570Sstevel@tonic-gate #endif
580Sstevel@tonic-gate #ifdef B19200
590Sstevel@tonic-gate 	{19200,	B19200},
600Sstevel@tonic-gate #endif
610Sstevel@tonic-gate #ifdef B38400
620Sstevel@tonic-gate 	{38400,	B38400},
630Sstevel@tonic-gate #endif
640Sstevel@tonic-gate 	{57600, B57600},
650Sstevel@tonic-gate 	{76800, B76800},
660Sstevel@tonic-gate 	{115200, B115200},
670Sstevel@tonic-gate 	{153600, B153600},
680Sstevel@tonic-gate 	{230400, B230400},
690Sstevel@tonic-gate 	{307200, B307200},
700Sstevel@tonic-gate 	{460800, B460800},
71*9354STim.Marsland@Sun.COM 	{921600, B921600},
720Sstevel@tonic-gate 	{0,    0}
730Sstevel@tonic-gate };
740Sstevel@tonic-gate 
75132Srobinson #define	PACKSIZE	64
76132Srobinson #define	HEADERSIZE	6
770Sstevel@tonic-gate 
78132Srobinson #define	SNDFILE	'S'
79132Srobinson #define	RCVFILE 'R'
80132Srobinson #define	RESET	'X'
810Sstevel@tonic-gate 
820Sstevel@tonic-gate static int Saved_line;		/* was savline() successful?	*/
830Sstevel@tonic-gate static int Saved_termios;	/* was termios saved?	*/
84132Srobinson static int
850Sstevel@tonic-gate 	Oddflag,	/* Default is no parity */
860Sstevel@tonic-gate 	Evenflag,	/* Default is no parity */
870Sstevel@tonic-gate 	Duplex = 1,	/* Default is full duplex */
880Sstevel@tonic-gate 	Terminal,	/* Default is no terminal */
890Sstevel@tonic-gate 	line_8bit = -1;	/* Default is same as terminal */
900Sstevel@tonic-gate 
910Sstevel@tonic-gate static const char P_PARITY[] = "Parity option error\r\n";
920Sstevel@tonic-gate 
930Sstevel@tonic-gate static struct termio Savettyb;
940Sstevel@tonic-gate static struct termios Savettybs;
950Sstevel@tonic-gate /*
960Sstevel@tonic-gate  * set speed/echo/mode...
970Sstevel@tonic-gate  *	tty 	-> terminal name
980Sstevel@tonic-gate  *	spwant 	-> speed
990Sstevel@tonic-gate  *	type	-> type
1000Sstevel@tonic-gate  *
1010Sstevel@tonic-gate  *	if spwant == 0, speed is untouched
1020Sstevel@tonic-gate  *	type is unused, but needed for compatibility
1030Sstevel@tonic-gate  *
104132Srobinson  * return:
1050Sstevel@tonic-gate  *	none
1060Sstevel@tonic-gate  */
1070Sstevel@tonic-gate /*ARGSUSED*/
108132Srobinson static void
fixline(int tty,int spwant,int type)109132Srobinson fixline(int tty, int spwant, int type)
1100Sstevel@tonic-gate {
1110Sstevel@tonic-gate 	register const struct sg_spds	*ps;
1120Sstevel@tonic-gate 	struct termio		ttbuf;
1130Sstevel@tonic-gate 	struct termios		ttbufs;
1140Sstevel@tonic-gate 	int			speed = -1;
1150Sstevel@tonic-gate 	int			i, istermios, ospeed;
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate 	DEBUG(6, "fixline(%d, ", tty);
1180Sstevel@tonic-gate 	DEBUG(6, "%d)\n", spwant);
1190Sstevel@tonic-gate 	if ((istermios = (*Ioctl)(tty, TCGETS, &ttbufs)) < 0) {
120132Srobinson 		if ((*Ioctl)(tty, TCGETA, &ttbuf) != 0)
121132Srobinson 			return;
1220Sstevel@tonic-gate 		ttbufs.c_lflag = ttbuf.c_lflag;
1230Sstevel@tonic-gate 		ttbufs.c_oflag = ttbuf.c_oflag;
1240Sstevel@tonic-gate 		ttbufs.c_iflag = ttbuf.c_iflag;
1250Sstevel@tonic-gate 		ttbufs.c_cflag = ttbuf.c_cflag;
126132Srobinson 		for (i = 0; i < NCC; i++)
1270Sstevel@tonic-gate 			ttbufs.c_cc[i] = ttbuf.c_cc[i];
1280Sstevel@tonic-gate 	}
1290Sstevel@tonic-gate 	if (spwant > 0) {
1300Sstevel@tonic-gate 		for (ps = spds; ps->sp_val; ps++)
1310Sstevel@tonic-gate 			if (ps->sp_val == spwant) {
1320Sstevel@tonic-gate 				speed = ps->sp_name;
1330Sstevel@tonic-gate 				break;
1340Sstevel@tonic-gate 			}
1350Sstevel@tonic-gate 		if (speed < 0) {
1360Sstevel@tonic-gate 			/*EMPTY*/
137132Srobinson 			DEBUG(5, "speed (%d) not supported\n", spwant);
1380Sstevel@tonic-gate 		}
1390Sstevel@tonic-gate 		ASSERT(speed >= 0, "BAD SPEED", "", spwant);
1400Sstevel@tonic-gate 		ttbufs.c_cflag &= 0xffff0000;
141132Srobinson 		(void) cfsetospeed(&ttbufs, speed);
1420Sstevel@tonic-gate 	} else { /* determine the current speed setting */
1430Sstevel@tonic-gate 		ospeed = cfgetospeed(&ttbufs);
1440Sstevel@tonic-gate 		ttbufs.c_cflag &= 0xffff0000;
145132Srobinson 		(void) cfsetospeed(&ttbufs, ospeed);
1460Sstevel@tonic-gate 		for (ps = spds; ps->sp_val; ps++)
1470Sstevel@tonic-gate 			if (ps->sp_name == ospeed) {
1480Sstevel@tonic-gate 				spwant = ps->sp_val;
1490Sstevel@tonic-gate 				break;
1500Sstevel@tonic-gate 			}
1510Sstevel@tonic-gate 	}
1520Sstevel@tonic-gate 	ttbufs.c_iflag &= 0xffff0000;
1530Sstevel@tonic-gate 	ttbufs.c_oflag &= 0xffff0000;
1540Sstevel@tonic-gate 	ttbufs.c_lflag &= 0xffff0000;
1550Sstevel@tonic-gate 
156132Srobinson 	ttbufs.c_cflag &= ~CLOCAL;
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate 	if (EQUALS(Progname, "cu")) {
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate 		/* set attributes associated with -h, -t, -e, and -o options */
1610Sstevel@tonic-gate 
1620Sstevel@tonic-gate 		ttbufs.c_iflag = (IGNPAR | IGNBRK | IXON | IXOFF);
1630Sstevel@tonic-gate 		if (line_8bit) {
164132Srobinson 			ttbufs.c_cflag |= CS8;
165132Srobinson 			ttbufs.c_iflag &= ~ISTRIP;
1660Sstevel@tonic-gate 		} else {
167132Srobinson 			ttbufs.c_cflag |= CS7;
168132Srobinson 			ttbufs.c_iflag |= ISTRIP;
1690Sstevel@tonic-gate 		}
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate 		ttbufs.c_cc[VEOF] = '\1';
1720Sstevel@tonic-gate 		ttbufs.c_cflag |= (CREAD | (speed ? HUPCL : 0));
1730Sstevel@tonic-gate 
174132Srobinson 		if (Evenflag) {				/* even parity -e */
175132Srobinson 			if (ttbufs.c_cflag & PARENB) {
1760Sstevel@tonic-gate 				VERBOSE(P_PARITY, 0);
177132Srobinson 				exit(1);
178132Srobinson 			}
179132Srobinson 			ttbufs.c_cflag |= PARENB;
180132Srobinson 		} else if (Oddflag) {			/* odd parity -o */
181132Srobinson 			if (ttbufs.c_cflag & PARENB) {
1820Sstevel@tonic-gate 				VERBOSE(P_PARITY, 0);
183132Srobinson 				exit(1);
184132Srobinson 			}
185132Srobinson 			ttbufs.c_cflag |= PARODD;
186132Srobinson 			ttbufs.c_cflag |= PARENB;
1870Sstevel@tonic-gate 		}
1880Sstevel@tonic-gate 
189132Srobinson 		if (!Duplex)				/* half duplex -h */
190132Srobinson 			ttbufs.c_iflag &= ~(IXON | IXOFF);
1910Sstevel@tonic-gate 		if (Terminal)				/* -t */
192132Srobinson 			ttbufs.c_oflag |= (OPOST | ONLCR);
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate 	} else { /* non-cu */
1950Sstevel@tonic-gate 		ttbufs.c_cflag |= (CS8 | CREAD | (speed ? HUPCL : 0));
1960Sstevel@tonic-gate 		ttbufs.c_cc[VMIN] = HEADERSIZE;
1970Sstevel@tonic-gate 		ttbufs.c_cc[VTIME] = 1;
1980Sstevel@tonic-gate 	}
1990Sstevel@tonic-gate 
2000Sstevel@tonic-gate 	if (istermios < 0) {
2010Sstevel@tonic-gate 		ttbuf.c_lflag = ttbufs.c_lflag;
2020Sstevel@tonic-gate 		ttbuf.c_oflag = ttbufs.c_oflag;
2030Sstevel@tonic-gate 		ttbuf.c_iflag = ttbufs.c_iflag;
2040Sstevel@tonic-gate 		ttbuf.c_cflag = ttbufs.c_cflag;
205132Srobinson 		for (i = 0; i < NCC; i++)
2060Sstevel@tonic-gate 			ttbuf.c_cc[i] = ttbufs.c_cc[i];
2070Sstevel@tonic-gate 		ASSERT((*Ioctl)(tty, TCSETAW, &ttbuf) >= 0,
208*9354STim.Marsland@Sun.COM 		    "RETURN FROM fixline ioctl", "", errno);
2090Sstevel@tonic-gate 	} else {
2100Sstevel@tonic-gate 		ASSERT((*Ioctl)(tty, TCSETSW, &ttbufs) >= 0,
211*9354STim.Marsland@Sun.COM 		    "RETURN FROM fixline ioctl", "", errno);
2120Sstevel@tonic-gate 	}
2130Sstevel@tonic-gate }
2140Sstevel@tonic-gate 
215132Srobinson static void
sethup(int dcf)216132Srobinson sethup(int dcf)
2170Sstevel@tonic-gate {
2180Sstevel@tonic-gate 	struct termio ttbuf;
2190Sstevel@tonic-gate 
220132Srobinson 	if ((*Ioctl)(dcf, TCGETA, &ttbuf) != 0)
2210Sstevel@tonic-gate 		return;
2220Sstevel@tonic-gate 	if (!(ttbuf.c_cflag & HUPCL)) {
2230Sstevel@tonic-gate 		ttbuf.c_cflag |= HUPCL;
2240Sstevel@tonic-gate 		(void) (*Ioctl)(dcf, TCSETAW, &ttbuf);
2250Sstevel@tonic-gate 	}
2260Sstevel@tonic-gate }
2270Sstevel@tonic-gate 
228132Srobinson static void
ttygenbrk(int fn)229132Srobinson ttygenbrk(int fn)
2300Sstevel@tonic-gate {
231132Srobinson 	if (isatty(fn))
2320Sstevel@tonic-gate 		(void) (*Ioctl)(fn, TCSBRK, 0);
2330Sstevel@tonic-gate }
2340Sstevel@tonic-gate 
235132Srobinson static int
savline(void)236132Srobinson savline(void)
2370Sstevel@tonic-gate {
238132Srobinson 	if ((Saved_termios = (*Ioctl)(0, TCGETS, &Savettybs)) < 0) {
239132Srobinson 		if ((*Ioctl)(0, TCGETA, &Savettyb) != 0) {
240132Srobinson 			Saved_line = FALSE;
2410Sstevel@tonic-gate 		} else {
242132Srobinson 			Saved_line = TRUE;
243132Srobinson 			Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7;
244132Srobinson 			Savettyb.c_oflag |= OPOST;
245132Srobinson 			Savettyb.c_lflag |= (ISIG|ICANON|ECHO);
2460Sstevel@tonic-gate 		}
2470Sstevel@tonic-gate 	} else {
2480Sstevel@tonic-gate 		Saved_line = TRUE;
2490Sstevel@tonic-gate 		Savettybs.c_cflag = (Savettybs.c_cflag & ~CS8) | CS7;
2500Sstevel@tonic-gate 		Savettybs.c_oflag |= OPOST;
2510Sstevel@tonic-gate 		Savettybs.c_lflag |= (ISIG|ICANON|ECHO);
2520Sstevel@tonic-gate 	}
2530Sstevel@tonic-gate 	return (0);
2540Sstevel@tonic-gate }
2550Sstevel@tonic-gate 
256132Srobinson static int
restline(void)257132Srobinson restline(void)
2580Sstevel@tonic-gate {
2590Sstevel@tonic-gate 	if (Saved_line == TRUE) {
2600Sstevel@tonic-gate 		if (Saved_termios < 0)
2610Sstevel@tonic-gate 			return ((*Ioctl)(0, TCSETAW, &Savettyb));
2620Sstevel@tonic-gate 		else
2630Sstevel@tonic-gate 			return ((*Ioctl)(0, TCSETSW, &Savettybs));
2640Sstevel@tonic-gate 	}
2650Sstevel@tonic-gate 	return (0);
2660Sstevel@tonic-gate }
267