1 /* 2 * Copyright (c) 1983 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE 34 * -------------------- ----- ---------------------- 35 * CURRENT PATCH LEVEL: 1 00150 36 * -------------------- ----- ---------------------- 37 * 38 * 22 Apr 93 Rodney W. Grimes support for 57600 and 115200 baud 39 * 40 */ 41 42 #ifndef lint 43 static char sccsid[] = "@(#)subr.c 5.10 (Berkeley) 2/26/91"; 44 #endif /* not lint */ 45 46 /* 47 * Melbourne getty. 48 */ 49 #include <sys/param.h> 50 #define USE_OLD_TTY 51 #include <sgtty.h> 52 #include <unistd.h> 53 #include <string.h> 54 #include "gettytab.h" 55 56 extern struct sgttyb tmode; 57 extern struct tchars tc; 58 extern struct ltchars ltc; 59 60 /* 61 * Get a table entry. 62 */ 63 gettable(name, buf, area) 64 char *name, *buf, *area; 65 { 66 register struct gettystrs *sp; 67 register struct gettynums *np; 68 register struct gettyflags *fp; 69 register n; 70 71 hopcount = 0; /* new lookup, start fresh */ 72 if (getent(buf, name) != 1) 73 return; 74 75 for (sp = gettystrs; sp->field; sp++) 76 sp->value = getstr(sp->field, &area); 77 for (np = gettynums; np->field; np++) { 78 n = getnum(np->field); 79 if (n == -1) 80 np->set = 0; 81 else { 82 np->set = 1; 83 np->value = n; 84 } 85 } 86 for (fp = gettyflags; fp->field; fp++) { 87 n = getflag(fp->field); 88 if (n == -1) 89 fp->set = 0; 90 else { 91 fp->set = 1; 92 fp->value = n ^ fp->invrt; 93 } 94 } 95 } 96 97 gendefaults() 98 { 99 register struct gettystrs *sp; 100 register struct gettynums *np; 101 register struct gettyflags *fp; 102 103 for (sp = gettystrs; sp->field; sp++) 104 if (sp->value) 105 sp->defalt = sp->value; 106 for (np = gettynums; np->field; np++) 107 if (np->set) 108 np->defalt = np->value; 109 for (fp = gettyflags; fp->field; fp++) 110 if (fp->set) 111 fp->defalt = fp->value; 112 else 113 fp->defalt = fp->invrt; 114 } 115 116 setdefaults() 117 { 118 register struct gettystrs *sp; 119 register struct gettynums *np; 120 register struct gettyflags *fp; 121 122 for (sp = gettystrs; sp->field; sp++) 123 if (!sp->value) 124 sp->value = sp->defalt; 125 for (np = gettynums; np->field; np++) 126 if (!np->set) 127 np->value = np->defalt; 128 for (fp = gettyflags; fp->field; fp++) 129 if (!fp->set) 130 fp->value = fp->defalt; 131 } 132 133 static char ** 134 charnames[] = { 135 &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK, 136 &SU, &DS, &RP, &FL, &WE, &LN, 0 137 }; 138 139 static char * 140 charvars[] = { 141 &tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc, 142 &tc.t_quitc, &tc.t_startc, &tc.t_stopc, 143 &tc.t_eofc, &tc.t_brkc, <c.t_suspc, 144 <c.t_dsuspc, <c.t_rprntc, <c.t_flushc, 145 <c.t_werasc, <c.t_lnextc, 0 146 }; 147 148 setchars() 149 { 150 register int i; 151 register char *p; 152 153 for (i = 0; charnames[i]; i++) { 154 p = *charnames[i]; 155 if (p && *p) 156 *charvars[i] = *p; 157 else 158 *charvars[i] = '\377'; 159 } 160 } 161 162 long 163 setflags(n) 164 { 165 register long f; 166 167 switch (n) { 168 case 0: 169 if (F0set) 170 return(F0); 171 break; 172 case 1: 173 if (F1set) 174 return(F1); 175 break; 176 default: 177 if (F2set) 178 return(F2); 179 break; 180 } 181 182 f = 0; 183 184 if (AP) 185 f |= ANYP; 186 else if (OP) 187 f |= ODDP; 188 else if (EP) 189 f |= EVENP; 190 if (NP) 191 f |= PASS8; 192 193 if (UC) 194 f |= LCASE; 195 196 if (NL) 197 f |= CRMOD; 198 199 f |= delaybits(); 200 201 if (n == 1) { /* read mode flags */ 202 if (RW) 203 f |= RAW; 204 else 205 f |= CBREAK; 206 return (f); 207 } 208 209 if (!HT) 210 f |= XTABS; 211 212 if (n == 0) 213 return (f); 214 215 if (CB) 216 f |= CRTBS; 217 218 if (CE) 219 f |= CRTERA; 220 221 if (CK) 222 f |= CRTKIL; 223 224 if (PE) 225 f |= PRTERA; 226 227 if (EC) 228 f |= ECHO; 229 230 if (XC) 231 f |= CTLECH; 232 233 if (DX) 234 f |= DECCTQ; 235 236 return (f); 237 } 238 239 struct delayval { 240 unsigned delay; /* delay in ms */ 241 int bits; 242 }; 243 244 /* 245 * below are random guesses, I can't be bothered checking 246 */ 247 248 struct delayval crdelay[] = { 249 1, CR1, 250 2, CR2, 251 3, CR3, 252 83, CR1, 253 166, CR2, 254 0, CR3, 255 }; 256 257 struct delayval nldelay[] = { 258 1, NL1, /* special, calculated */ 259 2, NL2, 260 3, NL3, 261 100, NL2, 262 0, NL3, 263 }; 264 265 struct delayval bsdelay[] = { 266 1, BS1, 267 0, 0, 268 }; 269 270 struct delayval ffdelay[] = { 271 1, FF1, 272 1750, FF1, 273 0, FF1, 274 }; 275 276 struct delayval tbdelay[] = { 277 1, TAB1, 278 2, TAB2, 279 3, XTABS, /* this is expand tabs */ 280 100, TAB1, 281 0, TAB2, 282 }; 283 284 delaybits() 285 { 286 register f; 287 288 f = adelay(CD, crdelay); 289 f |= adelay(ND, nldelay); 290 f |= adelay(FD, ffdelay); 291 f |= adelay(TD, tbdelay); 292 f |= adelay(BD, bsdelay); 293 return (f); 294 } 295 296 adelay(ms, dp) 297 register ms; 298 register struct delayval *dp; 299 { 300 if (ms == 0) 301 return (0); 302 while (dp->delay && ms > dp->delay) 303 dp++; 304 return (dp->bits); 305 } 306 307 char editedhost[MAXHOSTNAMELEN]; 308 309 edithost(pat) 310 register char *pat; 311 { 312 register char *host = HN; 313 register char *res = editedhost; 314 315 if (!pat) 316 pat = ""; 317 while (*pat) { 318 switch (*pat) { 319 320 case '#': 321 if (*host) 322 host++; 323 break; 324 325 case '@': 326 if (*host) 327 *res++ = *host++; 328 break; 329 330 default: 331 *res++ = *pat; 332 break; 333 334 } 335 if (res == &editedhost[sizeof editedhost - 1]) { 336 *res = '\0'; 337 return; 338 } 339 pat++; 340 } 341 if (*host) 342 strncpy(res, host, sizeof editedhost - (res - editedhost) - 1); 343 else 344 *res = '\0'; 345 editedhost[sizeof editedhost - 1] = '\0'; 346 } 347 348 struct speedtab { 349 int speed; 350 int uxname; 351 } speedtab[] = { 352 50, B50, 353 75, B75, 354 110, B110, 355 134, B134, 356 150, B150, 357 200, B200, 358 300, B300, 359 600, B600, 360 1200, B1200, 361 1800, B1800, 362 2400, B2400, 363 4800, B4800, 364 9600, B9600, 365 19200, EXTA, 366 19, EXTA, /* for people who say 19.2K */ 367 38400, EXTB, 368 38, EXTB, 369 7200, EXTB, /* alternative */ 370 57600, B57600, 371 115200, B115200, 372 0 373 }; 374 375 speed(val) 376 { 377 register struct speedtab *sp; 378 379 if (val <= 15) 380 return (val); 381 382 for (sp = speedtab; sp->speed; sp++) 383 if (sp->speed == val) 384 return (sp->uxname); 385 386 return (B300); /* default in impossible cases */ 387 } 388 389 makeenv(env) 390 char *env[]; 391 { 392 static char termbuf[128] = "TERM="; 393 register char *p, *q; 394 register char **ep; 395 char *index(); 396 397 ep = env; 398 if (TT && *TT) { 399 strcat(termbuf, TT); 400 *ep++ = termbuf; 401 } 402 if (p = EV) { 403 q = p; 404 while (q = index(q, ',')) { 405 *q++ = '\0'; 406 *ep++ = p; 407 p = q; 408 } 409 if (*p) 410 *ep++ = p; 411 } 412 *ep = (char *)0; 413 } 414 415 /* 416 * This speed select mechanism is written for the Develcon DATASWITCH. 417 * The Develcon sends a string of the form "B{speed}\n" at a predefined 418 * baud rate. This string indicates the user's actual speed. 419 * The routine below returns the terminal type mapped from derived speed. 420 */ 421 struct portselect { 422 char *ps_baud; 423 char *ps_type; 424 } portspeeds[] = { 425 { "B110", "std.110" }, 426 { "B134", "std.134" }, 427 { "B150", "std.150" }, 428 { "B300", "std.300" }, 429 { "B600", "std.600" }, 430 { "B1200", "std.1200" }, 431 { "B2400", "std.2400" }, 432 { "B4800", "std.4800" }, 433 { "B9600", "std.9600" }, 434 { "B19200", "std.19200" }, 435 { 0 } 436 }; 437 438 char * 439 portselector() 440 { 441 char c, baud[20], *type = "default"; 442 register struct portselect *ps; 443 int len; 444 445 alarm(5*60); 446 for (len = 0; len < sizeof (baud) - 1; len++) { 447 if (read(STDIN_FILENO, &c, 1) <= 0) 448 break; 449 c &= 0177; 450 if (c == '\n' || c == '\r') 451 break; 452 if (c == 'B') 453 len = 0; /* in case of leading garbage */ 454 baud[len] = c; 455 } 456 baud[len] = '\0'; 457 for (ps = portspeeds; ps->ps_baud; ps++) 458 if (strcmp(ps->ps_baud, baud) == 0) { 459 type = ps->ps_type; 460 break; 461 } 462 sleep(2); /* wait for connection to complete */ 463 return (type); 464 } 465 466 /* 467 * This auto-baud speed select mechanism is written for the Micom 600 468 * portselector. Selection is done by looking at how the character '\r' 469 * is garbled at the different speeds. 470 */ 471 #include <sys/time.h> 472 473 char * 474 autobaud() 475 { 476 int rfds; 477 struct timeval timeout; 478 char c, *type = "9600-baud"; 479 int null = 0; 480 481 ioctl(0, TIOCFLUSH, &null); 482 rfds = 1 << 0; 483 timeout.tv_sec = 5; 484 timeout.tv_usec = 0; 485 if (select(32, (fd_set *)&rfds, (fd_set *)NULL, 486 (fd_set *)NULL, &timeout) <= 0) 487 return (type); 488 if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char)) 489 return (type); 490 timeout.tv_sec = 0; 491 timeout.tv_usec = 20; 492 (void) select(32, (fd_set *)NULL, (fd_set *)NULL, 493 (fd_set *)NULL, &timeout); 494 ioctl(0, TIOCFLUSH, &null); 495 switch (c & 0377) { 496 497 case 0200: /* 300-baud */ 498 type = "300-baud"; 499 break; 500 501 case 0346: /* 1200-baud */ 502 type = "1200-baud"; 503 break; 504 505 case 015: /* 2400-baud */ 506 case 0215: 507 type = "2400-baud"; 508 break; 509 510 default: /* 4800-baud */ 511 type = "4800-baud"; 512 break; 513 514 case 0377: /* 9600-baud */ 515 type = "9600-baud"; 516 break; 517 } 518 return (type); 519 } 520