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 int 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 { 19200, B19200 }, 56 { 38400, B38400 }, 57 { 57600, B57600 }, 58 { 76800, B76800 }, 59 { 115200, B115200 }, 60 { 153600, B153600 }, 61 { 230400, B230400 }, 62 { 307200, B307200 }, 63 { 460800, B460800 }, 64 { 921600, B921600 }, 65 { 1000000, B1000000 }, 66 { 1152000, B1152000 }, 67 { 1500000, B1500000 }, 68 { 2000000, B2000000 }, 69 { 2500000, B2500000 }, 70 { 3000000, B3000000 }, 71 { 3500000, B3500000 }, 72 { 4000000, B4000000 }, 73 { 0, 0} 74 }; 75 76 #define HEADERSIZE 6 77 78 static int Saved_line; /* was savline() successful? */ 79 static int Saved_termios; /* was termios saved? */ 80 static int 81 Oddflag, /* Default is no parity */ 82 Evenflag, /* Default is no parity */ 83 Duplex = 1, /* Default is full duplex */ 84 Terminal, /* Default is no terminal */ 85 line_8bit = -1; /* Default is same as terminal */ 86 87 static const char P_PARITY[] = "Parity option error\r\n"; 88 89 static struct termio Savettyb; 90 static struct termios Savettybs; 91 /* 92 * set speed/echo/mode... 93 * tty -> terminal name 94 * spwant -> speed 95 * type -> type 96 * 97 * if spwant == 0, speed is untouched 98 * type is unused, but needed for compatibility 99 * 100 * return: 101 * none 102 */ 103 /*ARGSUSED*/ 104 static void 105 fixline(int tty, int spwant, int type) 106 { 107 register const struct sg_spds *ps; 108 struct termio ttbuf; 109 struct termios ttbufs; 110 int speed = -1; 111 int i, istermios, ospeed; 112 113 DEBUG(6, "fixline(%d, ", tty); 114 DEBUG(6, "%d)\n", spwant); 115 if ((istermios = (*Ioctl)(tty, TCGETS, &ttbufs)) < 0) { 116 if ((*Ioctl)(tty, TCGETA, &ttbuf) != 0) 117 return; 118 ttbufs.c_lflag = ttbuf.c_lflag; 119 ttbufs.c_oflag = ttbuf.c_oflag; 120 ttbufs.c_iflag = ttbuf.c_iflag; 121 ttbufs.c_cflag = ttbuf.c_cflag; 122 for (i = 0; i < NCC; i++) 123 ttbufs.c_cc[i] = ttbuf.c_cc[i]; 124 } 125 if (spwant > 0) { 126 for (ps = spds; ps->sp_val != 0; ps++) 127 if (ps->sp_val == spwant) { 128 speed = ps->sp_name; 129 break; 130 } 131 if (speed < 0) { 132 /*EMPTY*/ 133 DEBUG(5, "speed (%d) not supported\n", spwant); 134 } 135 ASSERT(speed >= 0, "BAD SPEED", "", spwant); 136 ttbufs.c_cflag &= 0xffff0000; 137 (void) cfsetospeed(&ttbufs, speed); 138 } else { /* determine the current speed setting */ 139 ospeed = cfgetospeed(&ttbufs); 140 ttbufs.c_cflag &= 0xffff0000; 141 (void) cfsetospeed(&ttbufs, ospeed); 142 for (ps = spds; ps->sp_val != 0; ps++) 143 if (ps->sp_name == ospeed) { 144 spwant = ps->sp_val; 145 break; 146 } 147 } 148 ttbufs.c_iflag &= 0xffff0000; 149 ttbufs.c_oflag &= 0xffff0000; 150 ttbufs.c_lflag &= 0xffff0000; 151 152 ttbufs.c_cflag &= ~CLOCAL; 153 154 if (EQUALS(Progname, "cu")) { 155 156 /* set attributes associated with -h, -t, -e, and -o options */ 157 158 ttbufs.c_iflag = (IGNPAR | IGNBRK | IXON | IXOFF); 159 if (line_8bit) { 160 ttbufs.c_cflag |= CS8; 161 ttbufs.c_iflag &= ~ISTRIP; 162 } else { 163 ttbufs.c_cflag |= CS7; 164 ttbufs.c_iflag |= ISTRIP; 165 } 166 167 ttbufs.c_cc[VEOF] = '\1'; 168 ttbufs.c_cflag |= (CREAD | (speed ? HUPCL : 0)); 169 170 if (Evenflag) { /* even parity -e */ 171 if (ttbufs.c_cflag & PARENB) { 172 VERBOSE(P_PARITY, 0); 173 exit(1); 174 } 175 ttbufs.c_cflag |= PARENB; 176 } else if (Oddflag) { /* odd parity -o */ 177 if (ttbufs.c_cflag & PARENB) { 178 VERBOSE(P_PARITY, 0); 179 exit(1); 180 } 181 ttbufs.c_cflag |= PARODD; 182 ttbufs.c_cflag |= PARENB; 183 } 184 185 if (!Duplex) /* half duplex -h */ 186 ttbufs.c_iflag &= ~(IXON | IXOFF); 187 if (Terminal) /* -t */ 188 ttbufs.c_oflag |= (OPOST | ONLCR); 189 190 } else { /* non-cu */ 191 ttbufs.c_cflag |= (CS8 | CREAD | (speed ? HUPCL : 0)); 192 ttbufs.c_cc[VMIN] = HEADERSIZE; 193 ttbufs.c_cc[VTIME] = 1; 194 } 195 196 if (istermios < 0) { 197 ttbuf.c_lflag = ttbufs.c_lflag; 198 ttbuf.c_oflag = ttbufs.c_oflag; 199 ttbuf.c_iflag = ttbufs.c_iflag; 200 ttbuf.c_cflag = ttbufs.c_cflag; 201 for (i = 0; i < NCC; i++) 202 ttbuf.c_cc[i] = ttbufs.c_cc[i]; 203 ASSERT((*Ioctl)(tty, TCSETAW, &ttbuf) >= 0, 204 "RETURN FROM fixline ioctl", "", errno); 205 } else { 206 ASSERT((*Ioctl)(tty, TCSETSW, &ttbufs) >= 0, 207 "RETURN FROM fixline ioctl", "", errno); 208 } 209 } 210 211 static void 212 sethup(int dcf) 213 { 214 struct termio ttbuf; 215 216 if ((*Ioctl)(dcf, TCGETA, &ttbuf) != 0) 217 return; 218 if (!(ttbuf.c_cflag & HUPCL)) { 219 ttbuf.c_cflag |= HUPCL; 220 (void) (*Ioctl)(dcf, TCSETAW, &ttbuf); 221 } 222 } 223 224 static void 225 ttygenbrk(int fn) 226 { 227 if (isatty(fn)) 228 (void) (*Ioctl)(fn, TCSBRK, 0); 229 } 230 231 static int 232 savline(void) 233 { 234 if ((Saved_termios = (*Ioctl)(0, TCGETS, &Savettybs)) < 0) { 235 if ((*Ioctl)(0, TCGETA, &Savettyb) != 0) { 236 Saved_line = FALSE; 237 } else { 238 Saved_line = TRUE; 239 Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7; 240 Savettyb.c_oflag |= OPOST; 241 Savettyb.c_lflag |= (ISIG|ICANON|ECHO); 242 } 243 } else { 244 Saved_line = TRUE; 245 Savettybs.c_cflag = (Savettybs.c_cflag & ~CS8) | CS7; 246 Savettybs.c_oflag |= OPOST; 247 Savettybs.c_lflag |= (ISIG|ICANON|ECHO); 248 } 249 return (0); 250 } 251 252 static int 253 restline(void) 254 { 255 if (Saved_line == TRUE) { 256 if (Saved_termios < 0) 257 return ((*Ioctl)(0, TCSETAW, &Savettyb)); 258 else 259 return ((*Ioctl)(0, TCSETSW, &Savettybs)); 260 } 261 return (0); 262 } 263