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