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