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.4 (Berkeley) 01/07/86"; 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 if (DX) 193 f |= DECCTQ; 194 195 return (f); 196 } 197 198 struct delayval { 199 unsigned delay; /* delay in ms */ 200 int bits; 201 }; 202 203 /* 204 * below are random guesses, I can't be bothered checking 205 */ 206 207 struct delayval crdelay[] = { 208 1, CR1, 209 2, CR2, 210 3, CR3, 211 83, CR1, 212 166, CR2, 213 0, CR3, 214 }; 215 216 struct delayval nldelay[] = { 217 1, NL1, /* special, calculated */ 218 2, NL2, 219 3, NL3, 220 100, NL2, 221 0, NL3, 222 }; 223 224 struct delayval bsdelay[] = { 225 1, BS1, 226 0, 0, 227 }; 228 229 struct delayval ffdelay[] = { 230 1, FF1, 231 1750, FF1, 232 0, FF1, 233 }; 234 235 struct delayval tbdelay[] = { 236 1, TAB1, 237 2, TAB2, 238 3, XTABS, /* this is expand tabs */ 239 100, TAB1, 240 0, TAB2, 241 }; 242 243 delaybits() 244 { 245 register f; 246 247 f = adelay(CD, crdelay); 248 f |= adelay(ND, nldelay); 249 f |= adelay(FD, ffdelay); 250 f |= adelay(TD, tbdelay); 251 f |= adelay(BD, bsdelay); 252 return (f); 253 } 254 255 adelay(ms, dp) 256 register ms; 257 register struct delayval *dp; 258 { 259 if (ms == 0) 260 return (0); 261 while (dp->delay && ms > dp->delay) 262 dp++; 263 return (dp->bits); 264 } 265 266 char editedhost[32]; 267 268 edithost(pat) 269 register char *pat; 270 { 271 register char *host = HN; 272 register char *res = editedhost; 273 274 if (!pat) 275 pat = ""; 276 while (*pat) { 277 switch (*pat) { 278 279 case '#': 280 if (*host) 281 host++; 282 break; 283 284 case '@': 285 if (*host) 286 *res++ = *host++; 287 break; 288 289 default: 290 *res++ = *pat; 291 break; 292 293 } 294 if (res == &editedhost[sizeof editedhost - 1]) { 295 *res = '\0'; 296 return; 297 } 298 pat++; 299 } 300 if (*host) 301 strncpy(res, host, sizeof editedhost - (res - editedhost) - 1); 302 else 303 *res = '\0'; 304 editedhost[sizeof editedhost - 1] = '\0'; 305 } 306 307 struct speedtab { 308 int speed; 309 int uxname; 310 } speedtab[] = { 311 50, B50, 312 75, B75, 313 110, B110, 314 134, B134, 315 150, B150, 316 200, B200, 317 300, B300, 318 600, B600, 319 1200, B1200, 320 1800, B1800, 321 2400, B2400, 322 4800, B4800, 323 9600, B9600, 324 19200, EXTA, 325 19, EXTA, /* for people who say 19.2K */ 326 38400, EXTB, 327 38, EXTB, 328 7200, EXTB, /* alternative */ 329 0 330 }; 331 332 speed(val) 333 { 334 register struct speedtab *sp; 335 336 if (val <= 15) 337 return (val); 338 339 for (sp = speedtab; sp->speed; sp++) 340 if (sp->speed == val) 341 return (sp->uxname); 342 343 return (B300); /* default in impossible cases */ 344 } 345 346 makeenv(env) 347 char *env[]; 348 { 349 static char termbuf[128] = "TERM="; 350 register char *p, *q; 351 register char **ep; 352 char *index(); 353 354 ep = env; 355 if (TT && *TT) { 356 strcat(termbuf, TT); 357 *ep++ = termbuf; 358 } 359 if (p = EV) { 360 q = p; 361 while (q = index(q, ',')) { 362 *q++ = '\0'; 363 *ep++ = p; 364 p = q; 365 } 366 if (*p) 367 *ep++ = p; 368 } 369 *ep = (char *)0; 370 } 371 372 /* 373 * This speed select mechanism is written for the Develcon DATASWITCH. 374 * The Develcon sends a string of the form "B{speed}\n" at a predefined 375 * baud rate. This string indicates the user's actual speed. 376 * The routine below returns the terminal type mapped from derived speed. 377 */ 378 struct portselect { 379 char *ps_baud; 380 char *ps_type; 381 } portspeeds[] = { 382 { "B110", "std.110" }, 383 { "B134", "std.134" }, 384 { "B150", "std.150" }, 385 { "B300", "std.300" }, 386 { "B600", "std.600" }, 387 { "B1200", "std.1200" }, 388 { "B2400", "std.2400" }, 389 { "B4800", "std.4800" }, 390 { "B9600", "std.9600" }, 391 { "B19200", "std.19200" }, 392 { 0 } 393 }; 394 395 char * 396 portselector() 397 { 398 char c, baud[20], *type = "default"; 399 register struct portselect *ps; 400 int len; 401 402 alarm(5*60); 403 for (len = 0; len < sizeof (baud) - 1; len++) { 404 if (read(0, &c, 1) <= 0) 405 break; 406 c &= 0177; 407 if (c == '\n' || c == '\r') 408 break; 409 if (c == 'B') 410 len = 0; /* in case of leading garbage */ 411 baud[len] = c; 412 } 413 baud[len] = '\0'; 414 for (ps = portspeeds; ps->ps_baud; ps++) 415 if (strcmp(ps->ps_baud, baud) == 0) { 416 type = ps->ps_type; 417 break; 418 } 419 sleep(2); /* wait for connection to complete */ 420 return (type); 421 } 422 423 /* 424 * This auto-baud speed select mechanism is written for the Micom 600 425 * portselector. Selection is done by looking at how the character '\r' 426 * is garbled at the different speeds. 427 */ 428 #include <sys/time.h> 429 430 char * 431 autobaud() 432 { 433 int rfds; 434 struct timeval timeout; 435 char c, *type = "9600-baud"; 436 int null = 0; 437 438 ioctl(0, TIOCFLUSH, &null); 439 rfds = 1 << 0; 440 timeout.tv_sec = 5; 441 timeout.tv_usec = 0; 442 if (select(32, &rfds, (int *)0, (int *)0, &timeout) <= 0) 443 return (type); 444 if (read(0, &c, sizeof(char)) != sizeof(char)) 445 return (type); 446 timeout.tv_sec = 0; 447 timeout.tv_usec = 20; 448 (void) select(32, (int *)0, (int *)0, (int *)0, &timeout); 449 ioctl(0, TIOCFLUSH, &null); 450 switch (c & 0377) { 451 452 case 0200: /* 300-baud */ 453 type = "300-baud"; 454 break; 455 456 case 0346: /* 1200-baud */ 457 type = "1200-baud"; 458 break; 459 460 case 015: /* 2400-baud */ 461 case 0215: 462 type = "2400-baud"; 463 break; 464 465 default: /* 4800-baud */ 466 type = "4800-baud"; 467 break; 468 469 case 0377: /* 9600-baud */ 470 type = "9600-baud"; 471 break; 472 } 473 return (type); 474 } 475