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*46690Sbostic static char sccsid[] = "@(#)subr.c 5.10 (Berkeley) 02/26/91"; 1036930Sbostic #endif /* not lint */ 1113796Ssam 1213796Ssam /* 1313796Ssam * Melbourne getty. 1413796Ssam */ 1542668Smarc #define USE_OLD_TTY 1613796Ssam #include <sgtty.h> 1746671Sbostic #include <unistd.h> 1846671Sbostic #include <string.h> 1913796Ssam #include "gettytab.h" 2013796Ssam 2113796Ssam extern struct sgttyb tmode; 2213796Ssam extern struct tchars tc; 2313796Ssam extern struct ltchars ltc; 2413796Ssam 2513796Ssam /* 2613796Ssam * Get a table entry. 2713796Ssam */ 2813796Ssam gettable(name, buf, area) 2913796Ssam char *name, *buf, *area; 3013796Ssam { 3113796Ssam register struct gettystrs *sp; 3213796Ssam register struct gettynums *np; 3313796Ssam register struct gettyflags *fp; 3413796Ssam register n; 3513796Ssam 3613796Ssam hopcount = 0; /* new lookup, start fresh */ 3713796Ssam if (getent(buf, name) != 1) 3813796Ssam return; 3913796Ssam 4013796Ssam for (sp = gettystrs; sp->field; sp++) 4113796Ssam sp->value = getstr(sp->field, &area); 4213796Ssam for (np = gettynums; np->field; np++) { 4313796Ssam n = getnum(np->field); 4413796Ssam if (n == -1) 4513796Ssam np->set = 0; 4613796Ssam else { 4713796Ssam np->set = 1; 4813796Ssam np->value = n; 4913796Ssam } 5013796Ssam } 5113796Ssam for (fp = gettyflags; fp->field; fp++) { 5213796Ssam n = getflag(fp->field); 5313796Ssam if (n == -1) 5413796Ssam fp->set = 0; 5513796Ssam else { 5613796Ssam fp->set = 1; 5713796Ssam fp->value = n ^ fp->invrt; 5813796Ssam } 5913796Ssam } 6013796Ssam } 6113796Ssam 6213796Ssam gendefaults() 6313796Ssam { 6413796Ssam register struct gettystrs *sp; 6513796Ssam register struct gettynums *np; 6613796Ssam register struct gettyflags *fp; 6713796Ssam 6813796Ssam for (sp = gettystrs; sp->field; sp++) 6913796Ssam if (sp->value) 7013796Ssam sp->defalt = sp->value; 7113796Ssam for (np = gettynums; np->field; np++) 7213796Ssam if (np->set) 7313796Ssam np->defalt = np->value; 7413796Ssam for (fp = gettyflags; fp->field; fp++) 7513796Ssam if (fp->set) 7613796Ssam fp->defalt = fp->value; 7713796Ssam else 7813796Ssam fp->defalt = fp->invrt; 7913796Ssam } 8013796Ssam 8113796Ssam setdefaults() 8213796Ssam { 8313796Ssam register struct gettystrs *sp; 8413796Ssam register struct gettynums *np; 8513796Ssam register struct gettyflags *fp; 8613796Ssam 8713796Ssam for (sp = gettystrs; sp->field; sp++) 8813796Ssam if (!sp->value) 8913796Ssam sp->value = sp->defalt; 9013796Ssam for (np = gettynums; np->field; np++) 9113796Ssam if (!np->set) 9213796Ssam np->value = np->defalt; 9313796Ssam for (fp = gettyflags; fp->field; fp++) 9413796Ssam if (!fp->set) 9513796Ssam fp->value = fp->defalt; 9613796Ssam } 9713796Ssam 9813796Ssam static char ** 9913796Ssam charnames[] = { 10013796Ssam &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK, 10113796Ssam &SU, &DS, &RP, &FL, &WE, &LN, 0 10213796Ssam }; 10313796Ssam 10413796Ssam static char * 10513796Ssam charvars[] = { 10613796Ssam &tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc, 10713796Ssam &tc.t_quitc, &tc.t_startc, &tc.t_stopc, 10813796Ssam &tc.t_eofc, &tc.t_brkc, <c.t_suspc, 10913796Ssam <c.t_dsuspc, <c.t_rprntc, <c.t_flushc, 11013796Ssam <c.t_werasc, <c.t_lnextc, 0 11113796Ssam }; 11213796Ssam 11313796Ssam setchars() 11413796Ssam { 11513796Ssam register int i; 11613796Ssam register char *p; 11713796Ssam 11813796Ssam for (i = 0; charnames[i]; i++) { 11913796Ssam p = *charnames[i]; 12013796Ssam if (p && *p) 12113796Ssam *charvars[i] = *p; 12213796Ssam else 12319946Sedward *charvars[i] = '\377'; 12413796Ssam } 12513796Ssam } 12613796Ssam 12713796Ssam long 12813796Ssam setflags(n) 12913796Ssam { 13013796Ssam register long f; 13113796Ssam 13213796Ssam switch (n) { 13313796Ssam case 0: 13413796Ssam if (F0set) 13513796Ssam return(F0); 13613796Ssam break; 13713796Ssam case 1: 13813796Ssam if (F1set) 13913796Ssam return(F1); 14013796Ssam break; 14113796Ssam default: 14213796Ssam if (F2set) 14313796Ssam return(F2); 14413796Ssam break; 14513796Ssam } 14613796Ssam 14713796Ssam f = 0; 14813796Ssam 14913796Ssam if (AP) 15013796Ssam f |= ANYP; 15113796Ssam else if (OP) 15213796Ssam f |= ODDP; 15313796Ssam else if (EP) 15413796Ssam f |= EVENP; 15513796Ssam 15613796Ssam if (UC) 15713796Ssam f |= LCASE; 15813796Ssam 15913796Ssam if (NL) 16013796Ssam f |= CRMOD; 16113796Ssam 16213796Ssam f |= delaybits(); 16313796Ssam 16413796Ssam if (n == 1) { /* read mode flags */ 16513796Ssam if (RW) 16613796Ssam f |= RAW; 16713796Ssam else 16813796Ssam f |= CBREAK; 16913796Ssam return (f); 17013796Ssam } 17113796Ssam 17213796Ssam if (!HT) 17313796Ssam f |= XTABS; 17413796Ssam 17513796Ssam if (n == 0) 17613796Ssam return (f); 17713796Ssam 17813796Ssam if (CB) 17913796Ssam f |= CRTBS; 18013796Ssam 18113796Ssam if (CE) 18213796Ssam f |= CRTERA; 18313796Ssam 18416565Sralph if (CK) 18516565Sralph f |= CRTKIL; 18616565Sralph 18713796Ssam if (PE) 18813796Ssam f |= PRTERA; 18913796Ssam 19013796Ssam if (EC) 19113796Ssam f |= ECHO; 19213796Ssam 19313796Ssam if (XC) 19413796Ssam f |= CTLECH; 19513796Ssam 19625730Smckusick if (DX) 19725730Smckusick f |= DECCTQ; 19825730Smckusick 19913796Ssam return (f); 20013796Ssam } 20113796Ssam 20213796Ssam struct delayval { 20313796Ssam unsigned delay; /* delay in ms */ 20413796Ssam int bits; 20513796Ssam }; 20613796Ssam 20713796Ssam /* 20813796Ssam * below are random guesses, I can't be bothered checking 20913796Ssam */ 21013796Ssam 21113796Ssam struct delayval crdelay[] = { 21213827Skre 1, CR1, 21313827Skre 2, CR2, 21413827Skre 3, CR3, 21513827Skre 83, CR1, 21613827Skre 166, CR2, 21713796Ssam 0, CR3, 21813796Ssam }; 21913796Ssam 22013796Ssam struct delayval nldelay[] = { 22113796Ssam 1, NL1, /* special, calculated */ 22213827Skre 2, NL2, 22313827Skre 3, NL3, 22413827Skre 100, NL2, 22513796Ssam 0, NL3, 22613796Ssam }; 22713796Ssam 22813796Ssam struct delayval bsdelay[] = { 22913827Skre 1, BS1, 23013796Ssam 0, 0, 23113796Ssam }; 23213796Ssam 23313796Ssam struct delayval ffdelay[] = { 23413827Skre 1, FF1, 23513796Ssam 1750, FF1, 23613796Ssam 0, FF1, 23713796Ssam }; 23813796Ssam 23913796Ssam struct delayval tbdelay[] = { 24013827Skre 1, TAB1, 24113827Skre 2, TAB2, 24213827Skre 3, XTABS, /* this is expand tabs */ 24313827Skre 100, TAB1, 24413796Ssam 0, TAB2, 24513796Ssam }; 24613796Ssam 24713796Ssam delaybits() 24813796Ssam { 24913796Ssam register f; 25013796Ssam 25113796Ssam f = adelay(CD, crdelay); 25213796Ssam f |= adelay(ND, nldelay); 25313796Ssam f |= adelay(FD, ffdelay); 25413796Ssam f |= adelay(TD, tbdelay); 25513796Ssam f |= adelay(BD, bsdelay); 25613796Ssam return (f); 25713796Ssam } 25813796Ssam 25913796Ssam adelay(ms, dp) 26013796Ssam register ms; 26113796Ssam register struct delayval *dp; 26213796Ssam { 26313796Ssam if (ms == 0) 26413796Ssam return (0); 26513796Ssam while (dp->delay && ms > dp->delay) 26613796Ssam dp++; 26713796Ssam return (dp->bits); 26813796Ssam } 26913796Ssam 27013796Ssam char editedhost[32]; 27113796Ssam 27213796Ssam edithost(pat) 27313796Ssam register char *pat; 27413796Ssam { 27513796Ssam register char *host = HN; 27613796Ssam register char *res = editedhost; 27713796Ssam 27813796Ssam if (!pat) 27913796Ssam pat = ""; 28013796Ssam while (*pat) { 28113796Ssam switch (*pat) { 28213796Ssam 28313796Ssam case '#': 28413796Ssam if (*host) 28513796Ssam host++; 28613796Ssam break; 28713796Ssam 28813796Ssam case '@': 28913796Ssam if (*host) 29013796Ssam *res++ = *host++; 29113796Ssam break; 29213796Ssam 29313796Ssam default: 29413796Ssam *res++ = *pat; 29513796Ssam break; 29613796Ssam 29713796Ssam } 29813796Ssam if (res == &editedhost[sizeof editedhost - 1]) { 29913796Ssam *res = '\0'; 30013796Ssam return; 30113796Ssam } 30213796Ssam pat++; 30313796Ssam } 30413796Ssam if (*host) 30513796Ssam strncpy(res, host, sizeof editedhost - (res - editedhost) - 1); 30613796Ssam else 30713796Ssam *res = '\0'; 30813796Ssam editedhost[sizeof editedhost - 1] = '\0'; 30913796Ssam } 31013796Ssam 31113796Ssam struct speedtab { 31213796Ssam int speed; 31313796Ssam int uxname; 31413796Ssam } speedtab[] = { 31513796Ssam 50, B50, 31613796Ssam 75, B75, 31713796Ssam 110, B110, 31813796Ssam 134, B134, 31913796Ssam 150, B150, 32013796Ssam 200, B200, 32113796Ssam 300, B300, 32213796Ssam 600, B600, 32313796Ssam 1200, B1200, 32413796Ssam 1800, B1800, 32513796Ssam 2400, B2400, 32613796Ssam 4800, B4800, 32713796Ssam 9600, B9600, 32813796Ssam 19200, EXTA, 32913796Ssam 19, EXTA, /* for people who say 19.2K */ 33013796Ssam 38400, EXTB, 33113796Ssam 38, EXTB, 33213796Ssam 7200, EXTB, /* alternative */ 33313796Ssam 0 33413796Ssam }; 33513796Ssam 33613796Ssam speed(val) 33713796Ssam { 33813796Ssam register struct speedtab *sp; 33913796Ssam 34013796Ssam if (val <= 15) 34117925Sralph return (val); 34213796Ssam 34313796Ssam for (sp = speedtab; sp->speed; sp++) 34413796Ssam if (sp->speed == val) 34513796Ssam return (sp->uxname); 34613796Ssam 34713796Ssam return (B300); /* default in impossible cases */ 34813796Ssam } 34913796Ssam 35013796Ssam makeenv(env) 35113796Ssam char *env[]; 35213796Ssam { 35313796Ssam static char termbuf[128] = "TERM="; 35413796Ssam register char *p, *q; 35513796Ssam register char **ep; 35613796Ssam char *index(); 35713796Ssam 35813796Ssam ep = env; 35913796Ssam if (TT && *TT) { 36013796Ssam strcat(termbuf, TT); 36113796Ssam *ep++ = termbuf; 36213796Ssam } 36313796Ssam if (p = EV) { 36413796Ssam q = p; 36513796Ssam while (q = index(q, ',')) { 36613796Ssam *q++ = '\0'; 36713796Ssam *ep++ = p; 36813796Ssam p = q; 36913796Ssam } 37013796Ssam if (*p) 37113796Ssam *ep++ = p; 37213796Ssam } 37313796Ssam *ep = (char *)0; 37413796Ssam } 37513796Ssam 37613796Ssam /* 37713796Ssam * This speed select mechanism is written for the Develcon DATASWITCH. 37813796Ssam * The Develcon sends a string of the form "B{speed}\n" at a predefined 37913796Ssam * baud rate. This string indicates the user's actual speed. 38013796Ssam * The routine below returns the terminal type mapped from derived speed. 38113796Ssam */ 38213796Ssam struct portselect { 38313796Ssam char *ps_baud; 38413796Ssam char *ps_type; 38513796Ssam } portspeeds[] = { 38613796Ssam { "B110", "std.110" }, 38713796Ssam { "B134", "std.134" }, 38813796Ssam { "B150", "std.150" }, 38913796Ssam { "B300", "std.300" }, 39013796Ssam { "B600", "std.600" }, 39113796Ssam { "B1200", "std.1200" }, 39213796Ssam { "B2400", "std.2400" }, 39313796Ssam { "B4800", "std.4800" }, 39413796Ssam { "B9600", "std.9600" }, 39525233Smckusick { "B19200", "std.19200" }, 39613796Ssam { 0 } 39713796Ssam }; 39813796Ssam 39913796Ssam char * 40013796Ssam portselector() 40113796Ssam { 40213796Ssam char c, baud[20], *type = "default"; 40313796Ssam register struct portselect *ps; 40413796Ssam int len; 40513796Ssam 40613796Ssam alarm(5*60); 40713796Ssam for (len = 0; len < sizeof (baud) - 1; len++) { 408*46690Sbostic if (read(STDIN_FILENO, &c, 1) <= 0) 40913796Ssam break; 41013796Ssam c &= 0177; 41113796Ssam if (c == '\n' || c == '\r') 41213796Ssam break; 41313796Ssam if (c == 'B') 41413796Ssam len = 0; /* in case of leading garbage */ 41513796Ssam baud[len] = c; 41613796Ssam } 41713796Ssam baud[len] = '\0'; 41813796Ssam for (ps = portspeeds; ps->ps_baud; ps++) 41913796Ssam if (strcmp(ps->ps_baud, baud) == 0) { 42013796Ssam type = ps->ps_type; 42113796Ssam break; 42213796Ssam } 42313796Ssam sleep(2); /* wait for connection to complete */ 42413796Ssam return (type); 42513796Ssam } 42617925Sralph 42717925Sralph /* 42817925Sralph * This auto-baud speed select mechanism is written for the Micom 600 42917925Sralph * portselector. Selection is done by looking at how the character '\r' 43017925Sralph * is garbled at the different speeds. 43117925Sralph */ 43217925Sralph #include <sys/time.h> 43317925Sralph 43417925Sralph char * 43517925Sralph autobaud() 43617925Sralph { 43717925Sralph int rfds; 43817925Sralph struct timeval timeout; 43917925Sralph char c, *type = "9600-baud"; 44017925Sralph int null = 0; 44117925Sralph 44217925Sralph ioctl(0, TIOCFLUSH, &null); 44317925Sralph rfds = 1 << 0; 44417925Sralph timeout.tv_sec = 5; 44517925Sralph timeout.tv_usec = 0; 44646689Sbostic if (select(32, (fd_set *)&rfds, (fd_set *)NULL, 44746689Sbostic (fd_set *)NULL, &timeout) <= 0) 44817925Sralph return (type); 449*46690Sbostic if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char)) 45017925Sralph return (type); 45117925Sralph timeout.tv_sec = 0; 45217925Sralph timeout.tv_usec = 20; 45346689Sbostic (void) select(32, (fd_set *)NULL, (fd_set *)NULL, 45446689Sbostic (fd_set *)NULL, &timeout); 45517925Sralph ioctl(0, TIOCFLUSH, &null); 45617925Sralph switch (c & 0377) { 45717925Sralph 45817925Sralph case 0200: /* 300-baud */ 45917925Sralph type = "300-baud"; 46017925Sralph break; 46117925Sralph 46217925Sralph case 0346: /* 1200-baud */ 46317925Sralph type = "1200-baud"; 46417925Sralph break; 46517925Sralph 46617925Sralph case 015: /* 2400-baud */ 46717925Sralph case 0215: 46817925Sralph type = "2400-baud"; 46917925Sralph break; 47017925Sralph 47117925Sralph default: /* 4800-baud */ 47217925Sralph type = "4800-baud"; 47317925Sralph break; 47417925Sralph 47517925Sralph case 0377: /* 9600-baud */ 47617925Sralph type = "9600-baud"; 47717925Sralph break; 47817925Sralph } 47917925Sralph return (type); 48017925Sralph } 481