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