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