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.3 (Berkeley) 10/18/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 { "B19200", "std.19200" }, 389 { 0 } 390 }; 391 392 char * 393 portselector() 394 { 395 char c, baud[20], *type = "default"; 396 register struct portselect *ps; 397 int len; 398 399 alarm(5*60); 400 for (len = 0; len < sizeof (baud) - 1; len++) { 401 if (read(0, &c, 1) <= 0) 402 break; 403 c &= 0177; 404 if (c == '\n' || c == '\r') 405 break; 406 if (c == 'B') 407 len = 0; /* in case of leading garbage */ 408 baud[len] = c; 409 } 410 baud[len] = '\0'; 411 for (ps = portspeeds; ps->ps_baud; ps++) 412 if (strcmp(ps->ps_baud, baud) == 0) { 413 type = ps->ps_type; 414 break; 415 } 416 sleep(2); /* wait for connection to complete */ 417 return (type); 418 } 419 420 /* 421 * This auto-baud speed select mechanism is written for the Micom 600 422 * portselector. Selection is done by looking at how the character '\r' 423 * is garbled at the different speeds. 424 */ 425 #include <sys/time.h> 426 427 char * 428 autobaud() 429 { 430 int rfds; 431 struct timeval timeout; 432 char c, *type = "9600-baud"; 433 int null = 0; 434 435 ioctl(0, TIOCFLUSH, &null); 436 rfds = 1 << 0; 437 timeout.tv_sec = 5; 438 timeout.tv_usec = 0; 439 if (select(32, &rfds, (int *)0, (int *)0, &timeout) <= 0) 440 return (type); 441 if (read(0, &c, sizeof(char)) != sizeof(char)) 442 return (type); 443 timeout.tv_sec = 0; 444 timeout.tv_usec = 20; 445 (void) select(32, (int *)0, (int *)0, (int *)0, &timeout); 446 ioctl(0, TIOCFLUSH, &null); 447 switch (c & 0377) { 448 449 case 0200: /* 300-baud */ 450 type = "300-baud"; 451 break; 452 453 case 0346: /* 1200-baud */ 454 type = "1200-baud"; 455 break; 456 457 case 015: /* 2400-baud */ 458 case 0215: 459 type = "2400-baud"; 460 break; 461 462 default: /* 4800-baud */ 463 type = "4800-baud"; 464 break; 465 466 case 0377: /* 9600-baud */ 467 type = "9600-baud"; 468 break; 469 } 470 return (type); 471 } 472