119061Sdist /* 236930Sbostic * Copyright (c) 1983 The Regents of the University of California. 336930Sbostic * All rights reserved. 436930Sbostic * 536930Sbostic * Redistribution and use in source and binary forms are permitted 636930Sbostic * provided that the above copyright notice and this paragraph are 736930Sbostic * duplicated in all such forms and that any documentation, 836930Sbostic * advertising materials, and other materials related to such 936930Sbostic * distribution and use acknowledge that the software was developed 1036930Sbostic * by the University of California, Berkeley. The name of the 1136930Sbostic * University may not be used to endorse or promote products derived 1236930Sbostic * from this software without specific prior written permission. 1336930Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1436930Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1536930Sbostic * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1619061Sdist */ 1719061Sdist 1813796Ssam #ifndef lint 19*42668Smarc static char sccsid[] = "@(#)subr.c 5.6 (Berkeley) 06/01/90"; 2036930Sbostic #endif /* not lint */ 2113796Ssam 2213796Ssam /* 2313796Ssam * Melbourne getty. 2413796Ssam */ 25*42668Smarc #define USE_OLD_TTY 2613796Ssam #include <sgtty.h> 2713796Ssam #include "gettytab.h" 2813796Ssam 2913796Ssam extern struct sgttyb tmode; 3013796Ssam extern struct tchars tc; 3113796Ssam extern struct ltchars ltc; 3213796Ssam 3313796Ssam /* 3413796Ssam * Get a table entry. 3513796Ssam */ 3613796Ssam gettable(name, buf, area) 3713796Ssam char *name, *buf, *area; 3813796Ssam { 3913796Ssam register struct gettystrs *sp; 4013796Ssam register struct gettynums *np; 4113796Ssam register struct gettyflags *fp; 4213796Ssam register n; 4313796Ssam 4413796Ssam hopcount = 0; /* new lookup, start fresh */ 4513796Ssam if (getent(buf, name) != 1) 4613796Ssam return; 4713796Ssam 4813796Ssam for (sp = gettystrs; sp->field; sp++) 4913796Ssam sp->value = getstr(sp->field, &area); 5013796Ssam for (np = gettynums; np->field; np++) { 5113796Ssam n = getnum(np->field); 5213796Ssam if (n == -1) 5313796Ssam np->set = 0; 5413796Ssam else { 5513796Ssam np->set = 1; 5613796Ssam np->value = n; 5713796Ssam } 5813796Ssam } 5913796Ssam for (fp = gettyflags; fp->field; fp++) { 6013796Ssam n = getflag(fp->field); 6113796Ssam if (n == -1) 6213796Ssam fp->set = 0; 6313796Ssam else { 6413796Ssam fp->set = 1; 6513796Ssam fp->value = n ^ fp->invrt; 6613796Ssam } 6713796Ssam } 6813796Ssam } 6913796Ssam 7013796Ssam gendefaults() 7113796Ssam { 7213796Ssam register struct gettystrs *sp; 7313796Ssam register struct gettynums *np; 7413796Ssam register struct gettyflags *fp; 7513796Ssam 7613796Ssam for (sp = gettystrs; sp->field; sp++) 7713796Ssam if (sp->value) 7813796Ssam sp->defalt = sp->value; 7913796Ssam for (np = gettynums; np->field; np++) 8013796Ssam if (np->set) 8113796Ssam np->defalt = np->value; 8213796Ssam for (fp = gettyflags; fp->field; fp++) 8313796Ssam if (fp->set) 8413796Ssam fp->defalt = fp->value; 8513796Ssam else 8613796Ssam fp->defalt = fp->invrt; 8713796Ssam } 8813796Ssam 8913796Ssam setdefaults() 9013796Ssam { 9113796Ssam register struct gettystrs *sp; 9213796Ssam register struct gettynums *np; 9313796Ssam register struct gettyflags *fp; 9413796Ssam 9513796Ssam for (sp = gettystrs; sp->field; sp++) 9613796Ssam if (!sp->value) 9713796Ssam sp->value = sp->defalt; 9813796Ssam for (np = gettynums; np->field; np++) 9913796Ssam if (!np->set) 10013796Ssam np->value = np->defalt; 10113796Ssam for (fp = gettyflags; fp->field; fp++) 10213796Ssam if (!fp->set) 10313796Ssam fp->value = fp->defalt; 10413796Ssam } 10513796Ssam 10613796Ssam static char ** 10713796Ssam charnames[] = { 10813796Ssam &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK, 10913796Ssam &SU, &DS, &RP, &FL, &WE, &LN, 0 11013796Ssam }; 11113796Ssam 11213796Ssam static char * 11313796Ssam charvars[] = { 11413796Ssam &tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc, 11513796Ssam &tc.t_quitc, &tc.t_startc, &tc.t_stopc, 11613796Ssam &tc.t_eofc, &tc.t_brkc, <c.t_suspc, 11713796Ssam <c.t_dsuspc, <c.t_rprntc, <c.t_flushc, 11813796Ssam <c.t_werasc, <c.t_lnextc, 0 11913796Ssam }; 12013796Ssam 12113796Ssam setchars() 12213796Ssam { 12313796Ssam register int i; 12413796Ssam register char *p; 12513796Ssam 12613796Ssam for (i = 0; charnames[i]; i++) { 12713796Ssam p = *charnames[i]; 12813796Ssam if (p && *p) 12913796Ssam *charvars[i] = *p; 13013796Ssam else 13119946Sedward *charvars[i] = '\377'; 13213796Ssam } 13313796Ssam } 13413796Ssam 13513796Ssam long 13613796Ssam setflags(n) 13713796Ssam { 13813796Ssam register long f; 13913796Ssam 14013796Ssam switch (n) { 14113796Ssam case 0: 14213796Ssam if (F0set) 14313796Ssam return(F0); 14413796Ssam break; 14513796Ssam case 1: 14613796Ssam if (F1set) 14713796Ssam return(F1); 14813796Ssam break; 14913796Ssam default: 15013796Ssam if (F2set) 15113796Ssam return(F2); 15213796Ssam break; 15313796Ssam } 15413796Ssam 15513796Ssam f = 0; 15613796Ssam 15713796Ssam if (AP) 15813796Ssam f |= ANYP; 15913796Ssam else if (OP) 16013796Ssam f |= ODDP; 16113796Ssam else if (EP) 16213796Ssam f |= EVENP; 16313796Ssam 16413796Ssam if (UC) 16513796Ssam f |= LCASE; 16613796Ssam 16713796Ssam if (NL) 16813796Ssam f |= CRMOD; 16913796Ssam 17013796Ssam f |= delaybits(); 17113796Ssam 17213796Ssam if (n == 1) { /* read mode flags */ 17313796Ssam if (RW) 17413796Ssam f |= RAW; 17513796Ssam else 17613796Ssam f |= CBREAK; 17713796Ssam return (f); 17813796Ssam } 17913796Ssam 18013796Ssam if (!HT) 18113796Ssam f |= XTABS; 18213796Ssam 18313796Ssam if (n == 0) 18413796Ssam return (f); 18513796Ssam 18613796Ssam if (CB) 18713796Ssam f |= CRTBS; 18813796Ssam 18913796Ssam if (CE) 19013796Ssam f |= CRTERA; 19113796Ssam 19216565Sralph if (CK) 19316565Sralph f |= CRTKIL; 19416565Sralph 19513796Ssam if (PE) 19613796Ssam f |= PRTERA; 19713796Ssam 19813796Ssam if (EC) 19913796Ssam f |= ECHO; 20013796Ssam 20113796Ssam if (XC) 20213796Ssam f |= CTLECH; 20313796Ssam 20425730Smckusick if (DX) 20525730Smckusick f |= DECCTQ; 20625730Smckusick 20713796Ssam return (f); 20813796Ssam } 20913796Ssam 21013796Ssam struct delayval { 21113796Ssam unsigned delay; /* delay in ms */ 21213796Ssam int bits; 21313796Ssam }; 21413796Ssam 21513796Ssam /* 21613796Ssam * below are random guesses, I can't be bothered checking 21713796Ssam */ 21813796Ssam 21913796Ssam struct delayval crdelay[] = { 22013827Skre 1, CR1, 22113827Skre 2, CR2, 22213827Skre 3, CR3, 22313827Skre 83, CR1, 22413827Skre 166, CR2, 22513796Ssam 0, CR3, 22613796Ssam }; 22713796Ssam 22813796Ssam struct delayval nldelay[] = { 22913796Ssam 1, NL1, /* special, calculated */ 23013827Skre 2, NL2, 23113827Skre 3, NL3, 23213827Skre 100, NL2, 23313796Ssam 0, NL3, 23413796Ssam }; 23513796Ssam 23613796Ssam struct delayval bsdelay[] = { 23713827Skre 1, BS1, 23813796Ssam 0, 0, 23913796Ssam }; 24013796Ssam 24113796Ssam struct delayval ffdelay[] = { 24213827Skre 1, FF1, 24313796Ssam 1750, FF1, 24413796Ssam 0, FF1, 24513796Ssam }; 24613796Ssam 24713796Ssam struct delayval tbdelay[] = { 24813827Skre 1, TAB1, 24913827Skre 2, TAB2, 25013827Skre 3, XTABS, /* this is expand tabs */ 25113827Skre 100, TAB1, 25213796Ssam 0, TAB2, 25313796Ssam }; 25413796Ssam 25513796Ssam delaybits() 25613796Ssam { 25713796Ssam register 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 26713796Ssam adelay(ms, dp) 26813796Ssam register ms; 26913796Ssam register struct delayval *dp; 27013796Ssam { 27113796Ssam if (ms == 0) 27213796Ssam return (0); 27313796Ssam while (dp->delay && ms > dp->delay) 27413796Ssam dp++; 27513796Ssam return (dp->bits); 27613796Ssam } 27713796Ssam 27813796Ssam char editedhost[32]; 27913796Ssam 28013796Ssam edithost(pat) 28113796Ssam register char *pat; 28213796Ssam { 28313796Ssam register char *host = HN; 28413796Ssam register char *res = editedhost; 28513796Ssam 28613796Ssam if (!pat) 28713796Ssam pat = ""; 28813796Ssam while (*pat) { 28913796Ssam switch (*pat) { 29013796Ssam 29113796Ssam case '#': 29213796Ssam if (*host) 29313796Ssam host++; 29413796Ssam break; 29513796Ssam 29613796Ssam case '@': 29713796Ssam if (*host) 29813796Ssam *res++ = *host++; 29913796Ssam break; 30013796Ssam 30113796Ssam default: 30213796Ssam *res++ = *pat; 30313796Ssam break; 30413796Ssam 30513796Ssam } 30613796Ssam if (res == &editedhost[sizeof editedhost - 1]) { 30713796Ssam *res = '\0'; 30813796Ssam return; 30913796Ssam } 31013796Ssam pat++; 31113796Ssam } 31213796Ssam if (*host) 31313796Ssam strncpy(res, host, sizeof editedhost - (res - editedhost) - 1); 31413796Ssam else 31513796Ssam *res = '\0'; 31613796Ssam editedhost[sizeof editedhost - 1] = '\0'; 31713796Ssam } 31813796Ssam 31913796Ssam struct speedtab { 32013796Ssam int speed; 32113796Ssam int uxname; 32213796Ssam } speedtab[] = { 32313796Ssam 50, B50, 32413796Ssam 75, B75, 32513796Ssam 110, B110, 32613796Ssam 134, B134, 32713796Ssam 150, B150, 32813796Ssam 200, B200, 32913796Ssam 300, B300, 33013796Ssam 600, B600, 33113796Ssam 1200, B1200, 33213796Ssam 1800, B1800, 33313796Ssam 2400, B2400, 33413796Ssam 4800, B4800, 33513796Ssam 9600, B9600, 33613796Ssam 19200, EXTA, 33713796Ssam 19, EXTA, /* for people who say 19.2K */ 33813796Ssam 38400, EXTB, 33913796Ssam 38, EXTB, 34013796Ssam 7200, EXTB, /* alternative */ 34113796Ssam 0 34213796Ssam }; 34313796Ssam 34413796Ssam speed(val) 34513796Ssam { 34613796Ssam register struct speedtab *sp; 34713796Ssam 34813796Ssam if (val <= 15) 34917925Sralph return (val); 35013796Ssam 35113796Ssam for (sp = speedtab; sp->speed; sp++) 35213796Ssam if (sp->speed == val) 35313796Ssam return (sp->uxname); 35413796Ssam 35513796Ssam return (B300); /* default in impossible cases */ 35613796Ssam } 35713796Ssam 35813796Ssam makeenv(env) 35913796Ssam char *env[]; 36013796Ssam { 36113796Ssam static char termbuf[128] = "TERM="; 36213796Ssam register char *p, *q; 36313796Ssam register char **ep; 36413796Ssam char *index(); 36513796Ssam 36613796Ssam ep = env; 36713796Ssam if (TT && *TT) { 36813796Ssam strcat(termbuf, TT); 36913796Ssam *ep++ = termbuf; 37013796Ssam } 37113796Ssam if (p = EV) { 37213796Ssam q = p; 37313796Ssam while (q = index(q, ',')) { 37413796Ssam *q++ = '\0'; 37513796Ssam *ep++ = p; 37613796Ssam p = q; 37713796Ssam } 37813796Ssam if (*p) 37913796Ssam *ep++ = p; 38013796Ssam } 38113796Ssam *ep = (char *)0; 38213796Ssam } 38313796Ssam 38413796Ssam /* 38513796Ssam * This speed select mechanism is written for the Develcon DATASWITCH. 38613796Ssam * The Develcon sends a string of the form "B{speed}\n" at a predefined 38713796Ssam * baud rate. This string indicates the user's actual speed. 38813796Ssam * The routine below returns the terminal type mapped from derived speed. 38913796Ssam */ 39013796Ssam struct portselect { 39113796Ssam char *ps_baud; 39213796Ssam char *ps_type; 39313796Ssam } portspeeds[] = { 39413796Ssam { "B110", "std.110" }, 39513796Ssam { "B134", "std.134" }, 39613796Ssam { "B150", "std.150" }, 39713796Ssam { "B300", "std.300" }, 39813796Ssam { "B600", "std.600" }, 39913796Ssam { "B1200", "std.1200" }, 40013796Ssam { "B2400", "std.2400" }, 40113796Ssam { "B4800", "std.4800" }, 40213796Ssam { "B9600", "std.9600" }, 40325233Smckusick { "B19200", "std.19200" }, 40413796Ssam { 0 } 40513796Ssam }; 40613796Ssam 40713796Ssam char * 40813796Ssam portselector() 40913796Ssam { 41013796Ssam char c, baud[20], *type = "default"; 41113796Ssam register struct portselect *ps; 41213796Ssam int len; 41313796Ssam 41413796Ssam alarm(5*60); 41513796Ssam for (len = 0; len < sizeof (baud) - 1; len++) { 41613796Ssam if (read(0, &c, 1) <= 0) 41713796Ssam break; 41813796Ssam c &= 0177; 41913796Ssam if (c == '\n' || c == '\r') 42013796Ssam break; 42113796Ssam if (c == 'B') 42213796Ssam len = 0; /* in case of leading garbage */ 42313796Ssam baud[len] = c; 42413796Ssam } 42513796Ssam baud[len] = '\0'; 42613796Ssam for (ps = portspeeds; ps->ps_baud; ps++) 42713796Ssam if (strcmp(ps->ps_baud, baud) == 0) { 42813796Ssam type = ps->ps_type; 42913796Ssam break; 43013796Ssam } 43113796Ssam sleep(2); /* wait for connection to complete */ 43213796Ssam return (type); 43313796Ssam } 43417925Sralph 43517925Sralph /* 43617925Sralph * This auto-baud speed select mechanism is written for the Micom 600 43717925Sralph * portselector. Selection is done by looking at how the character '\r' 43817925Sralph * is garbled at the different speeds. 43917925Sralph */ 44017925Sralph #include <sys/time.h> 44117925Sralph 44217925Sralph char * 44317925Sralph autobaud() 44417925Sralph { 44517925Sralph int rfds; 44617925Sralph struct timeval timeout; 44717925Sralph char c, *type = "9600-baud"; 44817925Sralph int null = 0; 44917925Sralph 45017925Sralph ioctl(0, TIOCFLUSH, &null); 45117925Sralph rfds = 1 << 0; 45217925Sralph timeout.tv_sec = 5; 45317925Sralph timeout.tv_usec = 0; 45417925Sralph if (select(32, &rfds, (int *)0, (int *)0, &timeout) <= 0) 45517925Sralph return (type); 45617925Sralph if (read(0, &c, sizeof(char)) != sizeof(char)) 45717925Sralph return (type); 45817925Sralph timeout.tv_sec = 0; 45917925Sralph timeout.tv_usec = 20; 46017925Sralph (void) select(32, (int *)0, (int *)0, (int *)0, &timeout); 46117925Sralph ioctl(0, TIOCFLUSH, &null); 46217925Sralph switch (c & 0377) { 46317925Sralph 46417925Sralph case 0200: /* 300-baud */ 46517925Sralph type = "300-baud"; 46617925Sralph break; 46717925Sralph 46817925Sralph case 0346: /* 1200-baud */ 46917925Sralph type = "1200-baud"; 47017925Sralph break; 47117925Sralph 47217925Sralph case 015: /* 2400-baud */ 47317925Sralph case 0215: 47417925Sralph type = "2400-baud"; 47517925Sralph break; 47617925Sralph 47717925Sralph default: /* 4800-baud */ 47817925Sralph type = "4800-baud"; 47917925Sralph break; 48017925Sralph 48117925Sralph case 0377: /* 9600-baud */ 48217925Sralph type = "9600-baud"; 48317925Sralph break; 48417925Sralph } 48517925Sralph return (type); 48617925Sralph } 487