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