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