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