1 /* 2 * Copyright (c) 1988,1989,1999 by Sun Microsystems, Inc. 3 * All rights reserved. 4 */ 5 6 /* 7 * Copyright (c) 1983 Regents of the University of California. 8 * All rights reserved. The Berkeley software License Agreement 9 * specifies the terms and conditions for redistribution. 10 */ 11 12 #pragma ident "%Z%%M% %I% %E% SMI" 13 14 /* 15 * Stolen from ucb/lpr/printjob.c 16 */ 17 18 #include <string.h> 19 #include "uucp.h" 20 21 static struct termios termios_set; 22 static struct termios termios_clear; 23 24 setmode(modes, fd) 25 char *modes; 26 int fd; 27 { 28 if (parse_modes(modes)) 29 setty(fd); 30 } 31 32 struct mds { 33 char *string; 34 unsigned long set; 35 unsigned long reset; 36 }; 37 /* Control Modes */ 38 static struct mds cmodes[] = { 39 "-parity", CS8, PARENB|CSIZE, 40 "-evenp", CS8, PARENB|CSIZE, 41 "-oddp", CS8, PARENB|PARODD|CSIZE, 42 "parity", PARENB|CS7, PARODD|CSIZE, 43 "evenp", PARENB|CS7, PARODD|CSIZE, 44 "oddp", PARENB|PARODD|CS7, CSIZE, 45 "parenb", PARENB, 0, 46 "-parenb", 0, PARENB, 47 "parodd", PARODD, 0, 48 "-parodd", 0, PARODD, 49 "cs8", CS8, CSIZE, 50 "cs7", CS7, CSIZE, 51 "cs6", CS6, CSIZE, 52 "cs5", CS5, CSIZE, 53 "cstopb", CSTOPB, 0, 54 "-cstopb", 0, CSTOPB, 55 "stopb", CSTOPB, 0, 56 "-stopb", 0, CSTOPB, 57 "hupcl", HUPCL, 0, 58 "hup", HUPCL, 0, 59 "-hupcl", 0, HUPCL, 60 "-hup", 0, HUPCL, 61 "clocal", CLOCAL, 0, 62 "-clocal", 0, CLOCAL, 63 "nohang", CLOCAL, 0, 64 "-nohang", 0, CLOCAL, 65 #if 0 /* this bit isn't supported */ 66 "loblk", LOBLK, 0, 67 "-loblk", 0, LOBLK, 68 #endif 69 "cread", CREAD, 0, 70 "-cread", 0, CREAD, 71 #ifndef CRTSCTS 72 #define CRTSCTS 0x80000000 73 #endif 74 "crtscts", CRTSCTS, 0, 75 "-crtscts", 0, CRTSCTS, 76 #ifndef CRTSXOFF 77 #define CRTSXOFF 0x40000000 78 #endif 79 "crtsxoff", CRTSXOFF, 0, 80 "-crtsxoff", 0, CRTSXOFF, 81 "litout", CS8, (CSIZE|PARENB), 82 "-litout", (CS7|PARENB), CSIZE, 83 "pass8", CS8, (CSIZE|PARENB), 84 "-pass8", (CS7|PARENB), CSIZE, 85 "raw", CS8, (CSIZE|PARENB), 86 "-raw", (CS7|PARENB), CSIZE, 87 "cooked", (CS7|PARENB), CSIZE, 88 "sane", (CS7|PARENB|CREAD), (CSIZE|PARODD|CLOCAL), 89 0 90 }; 91 /* Input Modes */ 92 static struct mds imodes[] = { 93 "ignbrk", IGNBRK, 0, 94 "-ignbrk", 0, IGNBRK, 95 "brkint", BRKINT, 0, 96 "-brkint", 0, BRKINT, 97 "ignpar", IGNPAR, 0, 98 "-ignpar", 0, IGNPAR, 99 "parmrk", PARMRK, 0, 100 "-parmrk", 0, PARMRK, 101 "inpck", INPCK, 0, 102 "-inpck", 0, INPCK, 103 "istrip", ISTRIP, 0, 104 "-istrip", 0, ISTRIP, 105 "inlcr", INLCR, 0, 106 "-inlcr", 0, INLCR, 107 "igncr", IGNCR, 0, 108 "-igncr", 0, IGNCR, 109 "icrnl", ICRNL, 0, 110 "-icrnl", 0, ICRNL, 111 "-nl", ICRNL, (INLCR|IGNCR), 112 "nl", 0, ICRNL, 113 "iuclc", IUCLC, 0, 114 "-iuclc", 0, IUCLC, 115 "lcase", IUCLC, 0, 116 "-lcase", 0, IUCLC, 117 "LCASE", IUCLC, 0, 118 "-LCASE", 0, IUCLC, 119 "ixon", IXON, 0, 120 "-ixon", 0, IXON, 121 "ixany", IXANY, 0, 122 "-ixany", 0, IXANY, 123 "decctlq", 0, IXANY, 124 "-decctlq", IXANY, 0, 125 "ixoff", IXOFF, 0, 126 "-ixoff", 0, IXOFF, 127 "tandem", IXOFF, 0, 128 "-tandem", 0, IXOFF, 129 "imaxbel", IMAXBEL, 0, 130 "-imaxbel", 0, IMAXBEL, 131 "pass8", 0, ISTRIP, 132 "-pass8", ISTRIP, 0, 133 "raw", 0, (unsigned long)-1, 134 "-raw", (BRKINT|IGNPAR|ISTRIP|ICRNL|IXON|IMAXBEL), 0, 135 "cooked", (BRKINT|IGNPAR|ISTRIP|ICRNL|IXON), 0, 136 "sane", (BRKINT|IGNPAR|ISTRIP|ICRNL|IXON|IMAXBEL), 137 (IGNBRK|PARMRK|INPCK|INLCR|IGNCR|IUCLC|IXOFF), 138 0 139 }; 140 /* Local Modes */ 141 static struct mds lmodes[] = { 142 "isig", ISIG, 0, 143 "-isig", 0, ISIG, 144 "noisig", 0, ISIG, 145 "-noisig", ISIG, 0, 146 "iexten", IEXTEN, 0, 147 "-iexten", 0, IEXTEN, 148 "icanon", ICANON, 0, 149 "-icanon", 0, ICANON, 150 "cbreak", 0, ICANON, 151 "-cbreak", ICANON, 0, 152 "xcase", XCASE, 0, 153 "-xcase", 0, XCASE, 154 "lcase", XCASE, 0, 155 "-lcase", 0, XCASE, 156 "LCASE", XCASE, 0, 157 "-LCASE", 0, XCASE, 158 "echo", ECHO, 0, 159 "-echo", 0, ECHO, 160 "echoe", ECHOE, 0, 161 "-echoe", 0, ECHOE, 162 "crterase", ECHOE, 0, 163 "-crterase", 0, ECHOE, 164 "echok", ECHOK, 0, 165 "-echok", 0, ECHOK, 166 "lfkc", ECHOK, 0, 167 "-lfkc", 0, ECHOK, 168 "echonl", ECHONL, 0, 169 "-echonl", 0, ECHONL, 170 "noflsh", NOFLSH, 0, 171 "-noflsh", 0, NOFLSH, 172 "tostop", TOSTOP, 0, 173 "-tostop", 0, TOSTOP, 174 "echoctl", ECHOCTL, 0, 175 "-echoctl", 0, ECHOCTL, 176 "ctlecho", ECHOCTL, 0, 177 "-ctlecho", 0, ECHOCTL, 178 "echoprt", ECHOPRT, 0, 179 "-echoprt", 0, ECHOPRT, 180 "prterase", ECHOPRT, 0, 181 "-prterase", 0, ECHOPRT, 182 "echoke", ECHOKE, 0, 183 "-echoke", 0, ECHOKE, 184 "crtkill", ECHOKE, 0, 185 "-crtkill", 0, ECHOKE, 186 #if 0 /* this bit isn't supported yet */ 187 "defecho", DEFECHO, 0, 188 "-defecho", 0, DEFECHO, 189 #endif 190 "raw", 0, (ISIG|ICANON|XCASE|IEXTEN), 191 "-raw", (ISIG|ICANON|IEXTEN), 0, 192 "cooked", (ISIG|ICANON), 0, 193 "sane", (ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE), 194 (XCASE|ECHOPRT|ECHONL|NOFLSH), 195 0, 196 }; 197 /* Output Modes */ 198 static struct mds omodes[] = { 199 "opost", OPOST, 0, 200 "-opost", 0, OPOST, 201 "nopost", 0, OPOST, 202 "-nopost", OPOST, 0, 203 "olcuc", OLCUC, 0, 204 "-olcuc", 0, OLCUC, 205 "lcase", OLCUC, 0, 206 "-lcase", 0, OLCUC, 207 "LCASE", OLCUC, 0, 208 "-LCASE", 0, OLCUC, 209 "onlcr", ONLCR, 0, 210 "-onlcr", 0, ONLCR, 211 "-nl", ONLCR, (OCRNL|ONLRET), 212 "nl", 0, ONLCR, 213 "ocrnl", OCRNL, 0, 214 "-ocrnl", 0, OCRNL, 215 "onocr", ONOCR, 0, 216 "-onocr", 0, ONOCR, 217 "onlret", ONLRET, 0, 218 "-onlret", 0, ONLRET, 219 "fill", OFILL, OFDEL, 220 "-fill", 0, OFILL|OFDEL, 221 "nul-fill", OFILL, OFDEL, 222 "del-fill", OFILL|OFDEL, 0, 223 "ofill", OFILL, 0, 224 "-ofill", 0, OFILL, 225 "ofdel", OFDEL, 0, 226 "-ofdel", 0, OFDEL, 227 "cr0", CR0, CRDLY, 228 "cr1", CR1, CRDLY, 229 "cr2", CR2, CRDLY, 230 "cr3", CR3, CRDLY, 231 "tab0", TAB0, TABDLY, 232 "tabs", TAB0, TABDLY, 233 "tab1", TAB1, TABDLY, 234 "tab2", TAB2, TABDLY, 235 "-tabs", XTABS, TABDLY, 236 "tab3", XTABS, TABDLY, 237 "nl0", NL0, NLDLY, 238 "nl1", NL1, NLDLY, 239 "ff0", FF0, FFDLY, 240 "ff1", FF1, FFDLY, 241 "vt0", VT0, VTDLY, 242 "vt1", VT1, VTDLY, 243 "bs0", BS0, BSDLY, 244 "bs1", BS1, BSDLY, 245 #if 0 /* these bits aren't supported yet */ 246 "pageout", PAGEOUT, 0, 247 "-pageout", 0, PAGEOUT, 248 "wrap", WRAP, 0, 249 "-wrap", 0, WRAP, 250 #endif 251 "litout", 0, OPOST, 252 "-litout", OPOST, 0, 253 "raw", 0, OPOST, 254 "-raw", OPOST, 0, 255 "cooked", OPOST, 0, 256 "33", CR1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY), 257 "tty33", CR1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY), 258 "tn", CR1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY), 259 "tn300", CR1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY), 260 "ti", CR2, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY), 261 "ti700", CR2, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY), 262 "05", NL1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY), 263 "vt05", NL1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY), 264 "tek", FF1, (CRDLY|TABDLY|NLDLY|FFDLY|VTDLY|BSDLY), 265 "37", (FF1|VT1|CR2|TAB1|NL1), (NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY), 266 "tty37", (FF1|VT1|CR2|TAB1|NL1), (NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY), 267 "sane", (OPOST|ONLCR), (OLCUC|OCRNL|ONOCR|ONLRET|OFILL|OFDEL| 268 NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY), 269 0, 270 }; 271 272 /* 273 * Parse a set of modes. 274 */ 275 static int 276 parse_modes(modes) 277 char *modes; 278 { 279 register char *curtoken; 280 register int match; 281 register int i; 282 283 termios_clear.c_iflag = 0; 284 termios_clear.c_oflag = 0; 285 termios_clear.c_cflag = 0; 286 termios_clear.c_lflag = 0; 287 termios_set.c_iflag = 0; 288 termios_set.c_oflag = 0; 289 termios_set.c_cflag = 0; 290 termios_set.c_lflag = 0; 291 292 curtoken = strtok(modes, ","); 293 while (curtoken != NULL) { 294 match = 0; 295 for (i = 0; imodes[i].string != NULL; i++) { 296 if (strcmp(curtoken, imodes[i].string) == 0) { 297 match++; 298 termios_clear.c_iflag |= imodes[i].reset; 299 termios_set.c_iflag |= imodes[i].set; 300 } 301 } 302 for (i = 0; omodes[i].string != NULL; i++) { 303 if (strcmp(curtoken, omodes[i].string) == 0) { 304 match++; 305 termios_clear.c_oflag |= omodes[i].reset; 306 termios_set.c_oflag |= omodes[i].set; 307 } 308 } 309 for (i = 0; cmodes[i].string != NULL; i++) { 310 if (strcmp(curtoken, cmodes[i].string) == 0) { 311 match++; 312 termios_clear.c_cflag |= cmodes[i].reset; 313 termios_set.c_cflag |= cmodes[i].set; 314 } 315 } 316 for (i = 0; lmodes[i].string != NULL; i++) { 317 if (strcmp(curtoken, lmodes[i].string) == 0) { 318 match++; 319 termios_clear.c_lflag |= lmodes[i].reset; 320 termios_set.c_lflag |= lmodes[i].set; 321 } 322 } 323 if (!match) { 324 CDEBUG(5, "unknown mode %s in STTY= string", curtoken); 325 return (0); 326 } 327 curtoken = strtok((char *)NULL, ","); 328 } 329 return (1); 330 } 331 332 /* 333 * setup tty lines. 334 */ 335 static 336 setty(fd) 337 { 338 struct termios termios; 339 340 if ((*Ioctl)(fd, TCGETS, &termios) < 0) { 341 CDEBUG(5, "ioctl(TCGETS): %d", errno); 342 return; 343 } 344 345 termios.c_iflag &= ~termios_clear.c_iflag; 346 termios.c_iflag |= termios_set.c_iflag; 347 termios.c_oflag &= ~termios_clear.c_oflag; 348 termios.c_oflag |= termios_set.c_oflag; 349 termios.c_cflag &= ~termios_clear.c_cflag; 350 termios.c_cflag |= termios_set.c_cflag; 351 termios.c_lflag &= ~termios_clear.c_lflag; 352 termios.c_lflag |= termios_set.c_lflag; 353 354 if ((*Ioctl)(fd, TCSETSF, &termios) < 0) { 355 CDEBUG(5, "ioctl(TCSETSF): %d", errno); 356 return; 357 } 358 } 359