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