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