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