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) 1/7/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: }