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