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