119061Sdist /* 236930Sbostic * Copyright (c) 1983 The Regents of the University of California. 336930Sbostic * All rights reserved. 436930Sbostic * 542670Sbostic * %sccs.include.redist.c% 619061Sdist */ 719061Sdist 813796Ssam #ifndef lint 9*60091Sbostic static char sccsid[] = "@(#)subr.c 5.11 (Berkeley) 05/17/93"; 1036930Sbostic #endif /* not lint */ 1113796Ssam 1213796Ssam /* 1313796Ssam * Melbourne getty. 1413796Ssam */ 1542668Smarc #define USE_OLD_TTY 1613796Ssam #include <sgtty.h> 17*60091Sbostic #include <string.h> 1846671Sbostic #include <unistd.h> 19*60091Sbostic 2013796Ssam #include "gettytab.h" 21*60091Sbostic #include "extern.h" 2213796Ssam 2313796Ssam extern struct sgttyb tmode; 2413796Ssam extern struct tchars tc; 2513796Ssam extern struct ltchars ltc; 2613796Ssam 2713796Ssam /* 2813796Ssam * Get a table entry. 2913796Ssam */ 30*60091Sbostic void 3113796Ssam gettable(name, buf, area) 3213796Ssam char *name, *buf, *area; 3313796Ssam { 3413796Ssam register struct gettystrs *sp; 3513796Ssam register struct gettynums *np; 3613796Ssam register struct gettyflags *fp; 3713796Ssam register n; 3813796Ssam 3913796Ssam hopcount = 0; /* new lookup, start fresh */ 4013796Ssam if (getent(buf, name) != 1) 4113796Ssam return; 4213796Ssam 4313796Ssam for (sp = gettystrs; sp->field; sp++) 4413796Ssam sp->value = getstr(sp->field, &area); 4513796Ssam for (np = gettynums; np->field; np++) { 4613796Ssam n = getnum(np->field); 4713796Ssam if (n == -1) 4813796Ssam np->set = 0; 4913796Ssam else { 5013796Ssam np->set = 1; 5113796Ssam np->value = n; 5213796Ssam } 5313796Ssam } 5413796Ssam for (fp = gettyflags; fp->field; fp++) { 5513796Ssam n = getflag(fp->field); 5613796Ssam if (n == -1) 5713796Ssam fp->set = 0; 5813796Ssam else { 5913796Ssam fp->set = 1; 6013796Ssam fp->value = n ^ fp->invrt; 6113796Ssam } 6213796Ssam } 6313796Ssam } 6413796Ssam 65*60091Sbostic void 6613796Ssam gendefaults() 6713796Ssam { 6813796Ssam register struct gettystrs *sp; 6913796Ssam register struct gettynums *np; 7013796Ssam register struct gettyflags *fp; 7113796Ssam 7213796Ssam for (sp = gettystrs; sp->field; sp++) 7313796Ssam if (sp->value) 7413796Ssam sp->defalt = sp->value; 7513796Ssam for (np = gettynums; np->field; np++) 7613796Ssam if (np->set) 7713796Ssam np->defalt = np->value; 7813796Ssam for (fp = gettyflags; fp->field; fp++) 7913796Ssam if (fp->set) 8013796Ssam fp->defalt = fp->value; 8113796Ssam else 8213796Ssam fp->defalt = fp->invrt; 8313796Ssam } 8413796Ssam 85*60091Sbostic void 8613796Ssam setdefaults() 8713796Ssam { 8813796Ssam register struct gettystrs *sp; 8913796Ssam register struct gettynums *np; 9013796Ssam register struct gettyflags *fp; 9113796Ssam 9213796Ssam for (sp = gettystrs; sp->field; sp++) 9313796Ssam if (!sp->value) 9413796Ssam sp->value = sp->defalt; 9513796Ssam for (np = gettynums; np->field; np++) 9613796Ssam if (!np->set) 9713796Ssam np->value = np->defalt; 9813796Ssam for (fp = gettyflags; fp->field; fp++) 9913796Ssam if (!fp->set) 10013796Ssam fp->value = fp->defalt; 10113796Ssam } 10213796Ssam 10313796Ssam static char ** 10413796Ssam charnames[] = { 10513796Ssam &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK, 10613796Ssam &SU, &DS, &RP, &FL, &WE, &LN, 0 10713796Ssam }; 10813796Ssam 10913796Ssam static char * 11013796Ssam charvars[] = { 11113796Ssam &tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc, 11213796Ssam &tc.t_quitc, &tc.t_startc, &tc.t_stopc, 11313796Ssam &tc.t_eofc, &tc.t_brkc, <c.t_suspc, 11413796Ssam <c.t_dsuspc, <c.t_rprntc, <c.t_flushc, 11513796Ssam <c.t_werasc, <c.t_lnextc, 0 11613796Ssam }; 11713796Ssam 118*60091Sbostic void 11913796Ssam setchars() 12013796Ssam { 12113796Ssam register int i; 12213796Ssam register char *p; 12313796Ssam 12413796Ssam for (i = 0; charnames[i]; i++) { 12513796Ssam p = *charnames[i]; 12613796Ssam if (p && *p) 12713796Ssam *charvars[i] = *p; 12813796Ssam else 12919946Sedward *charvars[i] = '\377'; 13013796Ssam } 13113796Ssam } 13213796Ssam 13313796Ssam long 13413796Ssam setflags(n) 135*60091Sbostic int n; 13613796Ssam { 13713796Ssam register long f; 13813796Ssam 13913796Ssam switch (n) { 14013796Ssam case 0: 14113796Ssam if (F0set) 14213796Ssam return(F0); 14313796Ssam break; 14413796Ssam case 1: 14513796Ssam if (F1set) 14613796Ssam return(F1); 14713796Ssam break; 14813796Ssam default: 14913796Ssam if (F2set) 15013796Ssam return(F2); 15113796Ssam break; 15213796Ssam } 15313796Ssam 15413796Ssam f = 0; 15513796Ssam 15613796Ssam if (AP) 15713796Ssam f |= ANYP; 15813796Ssam else if (OP) 15913796Ssam f |= ODDP; 16013796Ssam else if (EP) 16113796Ssam f |= EVENP; 16213796Ssam 16313796Ssam if (UC) 16413796Ssam f |= LCASE; 16513796Ssam 16613796Ssam if (NL) 16713796Ssam f |= CRMOD; 16813796Ssam 16913796Ssam f |= delaybits(); 17013796Ssam 17113796Ssam if (n == 1) { /* read mode flags */ 17213796Ssam if (RW) 17313796Ssam f |= RAW; 17413796Ssam else 17513796Ssam f |= CBREAK; 17613796Ssam return (f); 17713796Ssam } 17813796Ssam 17913796Ssam if (!HT) 18013796Ssam f |= XTABS; 18113796Ssam 18213796Ssam if (n == 0) 18313796Ssam return (f); 18413796Ssam 18513796Ssam if (CB) 18613796Ssam f |= CRTBS; 18713796Ssam 18813796Ssam if (CE) 18913796Ssam f |= CRTERA; 19013796Ssam 19116565Sralph if (CK) 19216565Sralph f |= CRTKIL; 19316565Sralph 19413796Ssam if (PE) 19513796Ssam f |= PRTERA; 19613796Ssam 19713796Ssam if (EC) 19813796Ssam f |= ECHO; 19913796Ssam 20013796Ssam if (XC) 20113796Ssam f |= CTLECH; 20213796Ssam 20325730Smckusick if (DX) 20425730Smckusick f |= DECCTQ; 20525730Smckusick 20613796Ssam return (f); 20713796Ssam } 20813796Ssam 20913796Ssam struct delayval { 21013796Ssam unsigned delay; /* delay in ms */ 21113796Ssam int bits; 21213796Ssam }; 21313796Ssam 21413796Ssam /* 21513796Ssam * below are random guesses, I can't be bothered checking 21613796Ssam */ 21713796Ssam 21813796Ssam struct delayval crdelay[] = { 219*60091Sbostic { 1, CR1 }, 220*60091Sbostic { 2, CR2 }, 221*60091Sbostic { 3, CR3 }, 222*60091Sbostic { 83, CR1 }, 223*60091Sbostic { 166, CR2 }, 224*60091Sbostic { 0, CR3 }, 22513796Ssam }; 22613796Ssam 22713796Ssam struct delayval nldelay[] = { 228*60091Sbostic { 1, NL1 }, /* special, calculated */ 229*60091Sbostic { 2, NL2 }, 230*60091Sbostic { 3, NL3 }, 231*60091Sbostic { 100, NL2 }, 232*60091Sbostic { 0, NL3 }, 23313796Ssam }; 23413796Ssam 23513796Ssam struct delayval bsdelay[] = { 236*60091Sbostic { 1, BS1 }, 237*60091Sbostic { 0, 0 }, 23813796Ssam }; 23913796Ssam 24013796Ssam struct delayval ffdelay[] = { 241*60091Sbostic { 1, FF1 }, 242*60091Sbostic { 1750, FF1 }, 243*60091Sbostic { 0, FF1 }, 24413796Ssam }; 24513796Ssam 24613796Ssam struct delayval tbdelay[] = { 247*60091Sbostic { 1, TAB1 }, 248*60091Sbostic { 2, TAB2 }, 249*60091Sbostic { 3, XTABS }, /* this is expand tabs */ 250*60091Sbostic { 100, TAB1 }, 251*60091Sbostic { 0, TAB2 }, 25213796Ssam }; 25313796Ssam 254*60091Sbostic int 25513796Ssam delaybits() 25613796Ssam { 257*60091Sbostic register int f; 25813796Ssam 25913796Ssam f = adelay(CD, crdelay); 26013796Ssam f |= adelay(ND, nldelay); 26113796Ssam f |= adelay(FD, ffdelay); 26213796Ssam f |= adelay(TD, tbdelay); 26313796Ssam f |= adelay(BD, bsdelay); 26413796Ssam return (f); 26513796Ssam } 26613796Ssam 267*60091Sbostic int 26813796Ssam adelay(ms, dp) 26913796Ssam register ms; 27013796Ssam register struct delayval *dp; 27113796Ssam { 27213796Ssam if (ms == 0) 27313796Ssam return (0); 27413796Ssam while (dp->delay && ms > dp->delay) 27513796Ssam dp++; 27613796Ssam return (dp->bits); 27713796Ssam } 27813796Ssam 27913796Ssam char editedhost[32]; 28013796Ssam 281*60091Sbostic void 28213796Ssam edithost(pat) 28313796Ssam register char *pat; 28413796Ssam { 28513796Ssam register char *host = HN; 28613796Ssam register char *res = editedhost; 28713796Ssam 28813796Ssam if (!pat) 28913796Ssam pat = ""; 29013796Ssam while (*pat) { 29113796Ssam switch (*pat) { 29213796Ssam 29313796Ssam case '#': 29413796Ssam if (*host) 29513796Ssam host++; 29613796Ssam break; 29713796Ssam 29813796Ssam case '@': 29913796Ssam if (*host) 30013796Ssam *res++ = *host++; 30113796Ssam break; 30213796Ssam 30313796Ssam default: 30413796Ssam *res++ = *pat; 30513796Ssam break; 30613796Ssam 30713796Ssam } 30813796Ssam if (res == &editedhost[sizeof editedhost - 1]) { 30913796Ssam *res = '\0'; 31013796Ssam return; 31113796Ssam } 31213796Ssam pat++; 31313796Ssam } 31413796Ssam if (*host) 31513796Ssam strncpy(res, host, sizeof editedhost - (res - editedhost) - 1); 31613796Ssam else 31713796Ssam *res = '\0'; 31813796Ssam editedhost[sizeof editedhost - 1] = '\0'; 31913796Ssam } 32013796Ssam 32113796Ssam struct speedtab { 32213796Ssam int speed; 32313796Ssam int uxname; 32413796Ssam } speedtab[] = { 325*60091Sbostic { 50, B50 }, 326*60091Sbostic { 75, B75 }, 327*60091Sbostic { 110, B110 }, 328*60091Sbostic { 134, B134 }, 329*60091Sbostic { 150, B150 }, 330*60091Sbostic { 200, B200 }, 331*60091Sbostic { 300, B300 }, 332*60091Sbostic { 600, B600 }, 333*60091Sbostic { 1200, B1200 }, 334*60091Sbostic { 1800, B1800 }, 335*60091Sbostic { 2400, B2400 }, 336*60091Sbostic { 4800, B4800 }, 337*60091Sbostic { 9600, B9600 }, 338*60091Sbostic { 19200, EXTA }, 339*60091Sbostic { 19, EXTA }, /* for people who say 19.2K */ 340*60091Sbostic { 38400, EXTB }, 341*60091Sbostic { 38, EXTB }, 342*60091Sbostic { 7200, EXTB }, /* alternative */ 343*60091Sbostic { 0 } 34413796Ssam }; 34513796Ssam 346*60091Sbostic int 34713796Ssam speed(val) 348*60091Sbostic int val; 34913796Ssam { 35013796Ssam register struct speedtab *sp; 35113796Ssam 35213796Ssam if (val <= 15) 35317925Sralph return (val); 35413796Ssam 35513796Ssam for (sp = speedtab; sp->speed; sp++) 35613796Ssam if (sp->speed == val) 35713796Ssam return (sp->uxname); 35813796Ssam 35913796Ssam return (B300); /* default in impossible cases */ 36013796Ssam } 36113796Ssam 362*60091Sbostic void 36313796Ssam makeenv(env) 36413796Ssam char *env[]; 36513796Ssam { 36613796Ssam static char termbuf[128] = "TERM="; 36713796Ssam register char *p, *q; 36813796Ssam register char **ep; 36913796Ssam 37013796Ssam ep = env; 37113796Ssam if (TT && *TT) { 37213796Ssam strcat(termbuf, TT); 37313796Ssam *ep++ = termbuf; 37413796Ssam } 37513796Ssam if (p = EV) { 37613796Ssam q = p; 377*60091Sbostic while (q = strchr(q, ',')) { 37813796Ssam *q++ = '\0'; 37913796Ssam *ep++ = p; 38013796Ssam p = q; 38113796Ssam } 38213796Ssam if (*p) 38313796Ssam *ep++ = p; 38413796Ssam } 38513796Ssam *ep = (char *)0; 38613796Ssam } 38713796Ssam 38813796Ssam /* 38913796Ssam * This speed select mechanism is written for the Develcon DATASWITCH. 39013796Ssam * The Develcon sends a string of the form "B{speed}\n" at a predefined 39113796Ssam * baud rate. This string indicates the user's actual speed. 39213796Ssam * The routine below returns the terminal type mapped from derived speed. 39313796Ssam */ 39413796Ssam struct portselect { 39513796Ssam char *ps_baud; 39613796Ssam char *ps_type; 39713796Ssam } portspeeds[] = { 39813796Ssam { "B110", "std.110" }, 39913796Ssam { "B134", "std.134" }, 40013796Ssam { "B150", "std.150" }, 40113796Ssam { "B300", "std.300" }, 40213796Ssam { "B600", "std.600" }, 40313796Ssam { "B1200", "std.1200" }, 40413796Ssam { "B2400", "std.2400" }, 40513796Ssam { "B4800", "std.4800" }, 40613796Ssam { "B9600", "std.9600" }, 40725233Smckusick { "B19200", "std.19200" }, 40813796Ssam { 0 } 40913796Ssam }; 41013796Ssam 41113796Ssam char * 41213796Ssam portselector() 41313796Ssam { 41413796Ssam char c, baud[20], *type = "default"; 41513796Ssam register struct portselect *ps; 41613796Ssam int len; 41713796Ssam 41813796Ssam alarm(5*60); 41913796Ssam for (len = 0; len < sizeof (baud) - 1; len++) { 42046690Sbostic if (read(STDIN_FILENO, &c, 1) <= 0) 42113796Ssam break; 42213796Ssam c &= 0177; 42313796Ssam if (c == '\n' || c == '\r') 42413796Ssam break; 42513796Ssam if (c == 'B') 42613796Ssam len = 0; /* in case of leading garbage */ 42713796Ssam baud[len] = c; 42813796Ssam } 42913796Ssam baud[len] = '\0'; 43013796Ssam for (ps = portspeeds; ps->ps_baud; ps++) 43113796Ssam if (strcmp(ps->ps_baud, baud) == 0) { 43213796Ssam type = ps->ps_type; 43313796Ssam break; 43413796Ssam } 43513796Ssam sleep(2); /* wait for connection to complete */ 43613796Ssam return (type); 43713796Ssam } 43817925Sralph 43917925Sralph /* 44017925Sralph * This auto-baud speed select mechanism is written for the Micom 600 44117925Sralph * portselector. Selection is done by looking at how the character '\r' 44217925Sralph * is garbled at the different speeds. 44317925Sralph */ 44417925Sralph #include <sys/time.h> 44517925Sralph 44617925Sralph char * 44717925Sralph autobaud() 44817925Sralph { 44917925Sralph int rfds; 45017925Sralph struct timeval timeout; 45117925Sralph char c, *type = "9600-baud"; 45217925Sralph int null = 0; 45317925Sralph 45417925Sralph ioctl(0, TIOCFLUSH, &null); 45517925Sralph rfds = 1 << 0; 45617925Sralph timeout.tv_sec = 5; 45717925Sralph timeout.tv_usec = 0; 45846689Sbostic if (select(32, (fd_set *)&rfds, (fd_set *)NULL, 45946689Sbostic (fd_set *)NULL, &timeout) <= 0) 46017925Sralph return (type); 46146690Sbostic if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char)) 46217925Sralph return (type); 46317925Sralph timeout.tv_sec = 0; 46417925Sralph timeout.tv_usec = 20; 46546689Sbostic (void) select(32, (fd_set *)NULL, (fd_set *)NULL, 46646689Sbostic (fd_set *)NULL, &timeout); 46717925Sralph ioctl(0, TIOCFLUSH, &null); 46817925Sralph switch (c & 0377) { 46917925Sralph 47017925Sralph case 0200: /* 300-baud */ 47117925Sralph type = "300-baud"; 47217925Sralph break; 47317925Sralph 47417925Sralph case 0346: /* 1200-baud */ 47517925Sralph type = "1200-baud"; 47617925Sralph break; 47717925Sralph 47817925Sralph case 015: /* 2400-baud */ 47917925Sralph case 0215: 48017925Sralph type = "2400-baud"; 48117925Sralph break; 48217925Sralph 48317925Sralph default: /* 4800-baud */ 48417925Sralph type = "4800-baud"; 48517925Sralph break; 48617925Sralph 48717925Sralph case 0377: /* 9600-baud */ 48817925Sralph type = "9600-baud"; 48917925Sralph break; 49017925Sralph } 49117925Sralph return (type); 49217925Sralph } 493