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