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: #if !defined(lint) && defined(DOSCCS) 8: static char sccsid[] = "@(#)subr.c 5.4.2 (2.11BSD GTE) 1997/3/28"; 9: #endif 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: if (HF) 152: f |= RTSCTS; 153: if (NL) 154: f |= CRMOD; 155: 156: if (n == 1) { /* read mode flags */ 157: if (RW) 158: f |= RAW; 159: else 160: f |= CBREAK; 161: return (f); 162: } 163: 164: if (!HT) 165: f |= XTABS; 166: if (n == 0) 167: return (f); 168: if (CB) 169: f |= CRTBS; 170: if (CE) 171: f |= CRTERA; 172: if (CK) 173: f |= CRTKIL; 174: if (PE) 175: f |= PRTERA; 176: if (EC) 177: f |= ECHO; 178: if (XC) 179: f |= CTLECH; 180: if (DX) 181: f |= DECCTQ; 182: return (f); 183: } 184: 185: char editedhost[32]; 186: 187: edithost(pat) 188: register char *pat; 189: { 190: register char *host = HN; 191: register char *res = editedhost; 192: 193: if (!pat) 194: pat = ""; 195: while (*pat) { 196: switch (*pat) { 197: 198: case '#': 199: if (*host) 200: host++; 201: break; 202: 203: case '@': 204: if (*host) 205: *res++ = *host++; 206: break; 207: 208: default: 209: *res++ = *pat; 210: break; 211: 212: } 213: if (res == &editedhost[sizeof editedhost - 1]) { 214: *res = '\0'; 215: return; 216: } 217: pat++; 218: } 219: if (*host) 220: strncpy(res, host, sizeof editedhost - (res - editedhost) - 1); 221: else 222: *res = '\0'; 223: editedhost[sizeof editedhost - 1] = '\0'; 224: } 225: 226: struct speedtab { 227: int speed; 228: int uxname; 229: } speedtab[] = { 230: 50, B50, 231: 75, B75, 232: 110, B110, 233: 134, B134, 234: 150, B150, 235: 200, B200, 236: 300, B300, 237: 600, B600, 238: 1200, B1200, 239: 1800, B1800, 240: 2400, B2400, 241: 4800, B4800, 242: 9600, B9600, 243: 19200, EXTA, 244: 19, EXTA, /* for people who say 19.2K */ 245: 38400, EXTB, 246: 38, EXTB, 247: 7200, EXTB, /* alternative */ 248: 0 249: }; 250: 251: speed(val) 252: long val; 253: { 254: register struct speedtab *sp; 255: 256: if (val <= 15) 257: return (val); 258: 259: for (sp = speedtab; sp->speed; sp++) 260: if (sp->speed == val) 261: return (sp->uxname); 262: 263: return (B300); /* default in impossible cases */ 264: } 265: 266: makeenv(env) 267: char *env[]; 268: { 269: static char termbuf[128] = "TERM="; 270: register char *p, *q; 271: register char **ep; 272: char *index(); 273: 274: ep = env; 275: if (TT && *TT) { 276: strcat(termbuf, TT); 277: *ep++ = termbuf; 278: } 279: if (p = EV) { 280: q = p; 281: while (q = index(q, ',')) { 282: *q++ = '\0'; 283: *ep++ = p; 284: p = q; 285: } 286: if (*p) 287: *ep++ = p; 288: } 289: *ep = (char *)0; 290: } 291: 292: /* 293: * This speed select mechanism is written for the Develcon DATASWITCH. 294: * The Develcon sends a string of the form "B{speed}\n" at a predefined 295: * baud rate. This string indicates the user's actual speed. 296: * The routine below returns the terminal type mapped from derived speed. 297: */ 298: struct portselect { 299: char *ps_baud; 300: char *ps_type; 301: } portspeeds[] = { 302: { "B110", "std.110" }, 303: { "B134", "std.134" }, 304: { "B150", "std.150" }, 305: { "B300", "std.300" }, 306: { "B600", "std.600" }, 307: { "B1200", "std.1200" }, 308: { "B2400", "std.2400" }, 309: { "B4800", "std.4800" }, 310: { "B9600", "std.9600" }, 311: { "B19200", "std.19200" }, 312: { 0 } 313: }; 314: 315: char * 316: portselector() 317: { 318: char c, baud[20], *type = "default"; 319: register struct portselect *ps; 320: int len; 321: 322: alarm(5*60); 323: for (len = 0; len < sizeof (baud) - 1; len++) { 324: if (read(0, &c, 1) <= 0) 325: break; 326: c &= 0177; 327: if (c == '\n' || c == '\r') 328: break; 329: if (c == 'B') 330: len = 0; /* in case of leading garbage */ 331: baud[len] = c; 332: } 333: baud[len] = '\0'; 334: for (ps = portspeeds; ps->ps_baud; ps++) 335: if (strcmp(ps->ps_baud, baud) == 0) { 336: type = ps->ps_type; 337: break; 338: } 339: sleep(2); /* wait for connection to complete */ 340: return (type); 341: } 342: 343: /* 344: * This auto-baud speed select mechanism is written for the Micom 600 345: * portselector. Selection is done by looking at how the character '\r' 346: * is garbled at the different speeds. 347: */ 348: #include <sys/time.h> 349: 350: char * 351: autobaud() 352: { 353: long rfds; 354: struct timeval timeout; 355: char c, *type = "1200-baud"; 356: int null = 0; 357: 358: ioctl(0, TIOCFLUSH, &null); 359: rfds = 1 << 0; 360: timeout.tv_sec = 30; 361: timeout.tv_usec = 0; 362: if (select(32, &rfds, (int *)0, (int *)0, &timeout) <= 0) 363: return (type); 364: if (read(0, &c, sizeof(char)) != sizeof(char)) 365: return (type); 366: timeout.tv_sec = 0; 367: timeout.tv_usec = 20; 368: (void) select(32, (int *)0, (int *)0, (int *)0, &timeout); 369: ioctl(0, TIOCFLUSH, &null); 370: switch (c & 0377) { 371: 372: case 0200: /* 300-baud */ 373: type = "300-baud"; 374: break; 375: 376: case 0346: /* 1200-baud */ 377: type = "1200-baud"; 378: break; 379: 380: case 015: /* 2400-baud */ 381: case 0215: 382: type = "2400-baud"; 383: break; 384: 385: default: /* 4800-baud */ 386: type = "4800-baud"; 387: break; 388: 389: case 0377: /* 9600-baud */ 390: type = "9600-baud"; 391: break; 392: } 393: return (type); 394: }