1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 29 /* All Rights Reserved */ 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /* 34 * This is a new line.c, which consists of line.c and culine.c 35 * merged together. 36 */ 37 38 #include "mt.h" 39 #include "uucp.h" 40 41 static const struct sg_spds { 42 int sp_val, 43 sp_name; 44 } spds[] = { 45 { 50, B50}, 46 { 75, B75}, 47 { 110, B110}, 48 { 134, B134}, 49 { 150, B150}, 50 { 200, B200}, 51 { 300, B300}, 52 { 600, B600}, 53 {1200, B1200}, 54 {1800, B1800}, 55 {2400, B2400}, 56 {4800, B4800}, 57 {9600, B9600}, 58 #ifdef EXTA 59 {19200, EXTA}, 60 #endif 61 #ifdef B19200 62 {19200, B19200}, 63 #endif 64 #ifdef B38400 65 {38400, B38400}, 66 #endif 67 {57600, B57600}, 68 {76800, B76800}, 69 {115200, B115200}, 70 {153600, B153600}, 71 {230400, B230400}, 72 {307200, B307200}, 73 {460800, B460800}, 74 {0, 0} 75 }; 76 77 #define PACKSIZE 64 78 #define HEADERSIZE 6 79 80 #define SNDFILE 'S' 81 #define RCVFILE 'R' 82 #define RESET 'X' 83 84 static int Saved_line; /* was savline() successful? */ 85 static int Saved_termios; /* was termios saved? */ 86 static int 87 Oddflag, /* Default is no parity */ 88 Evenflag, /* Default is no parity */ 89 Duplex = 1, /* Default is full duplex */ 90 Terminal, /* Default is no terminal */ 91 line_8bit = -1; /* Default is same as terminal */ 92 93 static const char P_PARITY[] = "Parity option error\r\n"; 94 95 static struct termio Savettyb; 96 static struct termios Savettybs; 97 /* 98 * set speed/echo/mode... 99 * tty -> terminal name 100 * spwant -> speed 101 * type -> type 102 * 103 * if spwant == 0, speed is untouched 104 * type is unused, but needed for compatibility 105 * 106 * return: 107 * none 108 */ 109 /*ARGSUSED*/ 110 static void 111 fixline(int tty, int spwant, int type) 112 { 113 register const struct sg_spds *ps; 114 struct termio ttbuf; 115 struct termios ttbufs; 116 int speed = -1; 117 int i, istermios, ospeed; 118 119 DEBUG(6, "fixline(%d, ", tty); 120 DEBUG(6, "%d)\n", spwant); 121 if ((istermios = (*Ioctl)(tty, TCGETS, &ttbufs)) < 0) { 122 if ((*Ioctl)(tty, TCGETA, &ttbuf) != 0) 123 return; 124 ttbufs.c_lflag = ttbuf.c_lflag; 125 ttbufs.c_oflag = ttbuf.c_oflag; 126 ttbufs.c_iflag = ttbuf.c_iflag; 127 ttbufs.c_cflag = ttbuf.c_cflag; 128 for (i = 0; i < NCC; i++) 129 ttbufs.c_cc[i] = ttbuf.c_cc[i]; 130 } 131 if (spwant > 0) { 132 for (ps = spds; ps->sp_val; ps++) 133 if (ps->sp_val == spwant) { 134 speed = ps->sp_name; 135 break; 136 } 137 if (speed < 0) { 138 /*EMPTY*/ 139 DEBUG(5, "speed (%d) not supported\n", spwant); 140 } 141 ASSERT(speed >= 0, "BAD SPEED", "", spwant); 142 ttbufs.c_cflag &= 0xffff0000; 143 (void) cfsetospeed(&ttbufs, speed); 144 } else { /* determine the current speed setting */ 145 ospeed = cfgetospeed(&ttbufs); 146 ttbufs.c_cflag &= 0xffff0000; 147 (void) cfsetospeed(&ttbufs, ospeed); 148 for (ps = spds; ps->sp_val; ps++) 149 if (ps->sp_name == ospeed) { 150 spwant = ps->sp_val; 151 break; 152 } 153 } 154 ttbufs.c_iflag &= 0xffff0000; 155 ttbufs.c_oflag &= 0xffff0000; 156 ttbufs.c_lflag &= 0xffff0000; 157 158 ttbufs.c_cflag &= ~CLOCAL; 159 160 if (EQUALS(Progname, "cu")) { 161 162 /* set attributes associated with -h, -t, -e, and -o options */ 163 164 ttbufs.c_iflag = (IGNPAR | IGNBRK | IXON | IXOFF); 165 if (line_8bit) { 166 ttbufs.c_cflag |= CS8; 167 ttbufs.c_iflag &= ~ISTRIP; 168 } else { 169 ttbufs.c_cflag |= CS7; 170 ttbufs.c_iflag |= ISTRIP; 171 } 172 173 ttbufs.c_cc[VEOF] = '\1'; 174 ttbufs.c_cflag |= (CREAD | (speed ? HUPCL : 0)); 175 176 if (Evenflag) { /* even parity -e */ 177 if (ttbufs.c_cflag & PARENB) { 178 VERBOSE(P_PARITY, 0); 179 exit(1); 180 } 181 ttbufs.c_cflag |= PARENB; 182 } else if (Oddflag) { /* odd parity -o */ 183 if (ttbufs.c_cflag & PARENB) { 184 VERBOSE(P_PARITY, 0); 185 exit(1); 186 } 187 ttbufs.c_cflag |= PARODD; 188 ttbufs.c_cflag |= PARENB; 189 } 190 191 if (!Duplex) /* half duplex -h */ 192 ttbufs.c_iflag &= ~(IXON | IXOFF); 193 if (Terminal) /* -t */ 194 ttbufs.c_oflag |= (OPOST | ONLCR); 195 196 } else { /* non-cu */ 197 ttbufs.c_cflag |= (CS8 | CREAD | (speed ? HUPCL : 0)); 198 ttbufs.c_cc[VMIN] = HEADERSIZE; 199 ttbufs.c_cc[VTIME] = 1; 200 } 201 202 if (istermios < 0) { 203 ttbuf.c_lflag = ttbufs.c_lflag; 204 ttbuf.c_oflag = ttbufs.c_oflag; 205 ttbuf.c_iflag = ttbufs.c_iflag; 206 ttbuf.c_cflag = ttbufs.c_cflag; 207 for (i = 0; i < NCC; i++) 208 ttbuf.c_cc[i] = ttbufs.c_cc[i]; 209 ASSERT((*Ioctl)(tty, TCSETAW, &ttbuf) >= 0, 210 "RETURN FROM fixline ioctl", "", errno); 211 } else { 212 ASSERT((*Ioctl)(tty, TCSETSW, &ttbufs) >= 0, 213 "RETURN FROM fixline ioctl", "", errno); 214 } 215 } 216 217 static void 218 sethup(int dcf) 219 { 220 struct termio ttbuf; 221 222 if ((*Ioctl)(dcf, TCGETA, &ttbuf) != 0) 223 return; 224 if (!(ttbuf.c_cflag & HUPCL)) { 225 ttbuf.c_cflag |= HUPCL; 226 (void) (*Ioctl)(dcf, TCSETAW, &ttbuf); 227 } 228 } 229 230 static void 231 ttygenbrk(int fn) 232 { 233 if (isatty(fn)) 234 (void) (*Ioctl)(fn, TCSBRK, 0); 235 } 236 237 static int 238 savline(void) 239 { 240 if ((Saved_termios = (*Ioctl)(0, TCGETS, &Savettybs)) < 0) { 241 if ((*Ioctl)(0, TCGETA, &Savettyb) != 0) { 242 Saved_line = FALSE; 243 } else { 244 Saved_line = TRUE; 245 Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7; 246 Savettyb.c_oflag |= OPOST; 247 Savettyb.c_lflag |= (ISIG|ICANON|ECHO); 248 } 249 } else { 250 Saved_line = TRUE; 251 Savettybs.c_cflag = (Savettybs.c_cflag & ~CS8) | CS7; 252 Savettybs.c_oflag |= OPOST; 253 Savettybs.c_lflag |= (ISIG|ICANON|ECHO); 254 } 255 return (0); 256 } 257 258 static int 259 restline(void) 260 { 261 if (Saved_line == TRUE) { 262 if (Saved_termios < 0) 263 return ((*Ioctl)(0, TCSETAW, &Savettyb)); 264 else 265 return ((*Ioctl)(0, TCSETSW, &Savettybs)); 266 } 267 return (0); 268 } 269