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*60499Selan static char sccsid[] = "@(#)subr.c 5.12 (Berkeley) 05/27/93"; 1036930Sbostic #endif /* not lint */ 1113796Ssam 1213796Ssam /* 1313796Ssam * Melbourne getty. 1413796Ssam */ 1542668Smarc #define USE_OLD_TTY 16*60499Selan #include <stdlib.h> 1713796Ssam #include <sgtty.h> 1860091Sbostic #include <string.h> 1946671Sbostic #include <unistd.h> 2060091Sbostic 2113796Ssam #include "gettytab.h" 2260091Sbostic #include "extern.h" 23*60499Selan #include "pathnames.h" 2413796Ssam 2513796Ssam extern struct sgttyb tmode; 2613796Ssam extern struct tchars tc; 2713796Ssam extern struct ltchars ltc; 2813796Ssam 2913796Ssam /* 3013796Ssam * Get a table entry. 3113796Ssam */ 3260091Sbostic void 33*60499Selan gettable(name, buf) 34*60499Selan char *name, *buf; 3513796Ssam { 3613796Ssam register struct gettystrs *sp; 3713796Ssam register struct gettynums *np; 3813796Ssam register struct gettyflags *fp; 39*60499Selan long n; 40*60499Selan char *dba[2]; 41*60499Selan dba[0] = _PATH_GETTYTAB; 42*60499Selan dba[1] = 0; 4313796Ssam 44*60499Selan if (cgetent(&buf, dba, name) != 0) 4513796Ssam return; 4613796Ssam 47*60499Selan for (sp = gettystrs; sp->field; sp++) 48*60499Selan cgetstr(buf, sp->field, &sp->value); 4913796Ssam for (np = gettynums; np->field; np++) { 50*60499Selan if (cgetnum(buf, np->field, &n) == -1) 5113796Ssam np->set = 0; 5213796Ssam else { 5313796Ssam np->set = 1; 5413796Ssam np->value = n; 5513796Ssam } 5613796Ssam } 5713796Ssam for (fp = gettyflags; fp->field; fp++) { 58*60499Selan if (cgetcap(buf, fp->field, ':') == NULL) 5913796Ssam fp->set = 0; 6013796Ssam else { 6113796Ssam fp->set = 1; 62*60499Selan fp->value = 1 ^ fp->invrt; 6313796Ssam } 6413796Ssam } 65*60499Selan #define DEBUG 66*60499Selan #ifdef DEBUG 67*60499Selan printf("name=\"%s\", buf=\"%s\"\n", name, buf); 68*60499Selan for (sp = gettystrs; sp->field; sp++) 69*60499Selan printf("cgetstr: %s=%s\n", sp->field, sp->value); 70*60499Selan for (np = gettynums; np->field; np++) 71*60499Selan printf("cgetnum: %s=%d\n", np->field, np->value); 72*60499Selan for (fp = gettyflags; fp->field; fp++) 73*60499Selan printf("cgetflags: %s='%c' set='%c'\n", fp->field, 74*60499Selan fp->value + '0', fp->set + '0'); 75*60499Selan exit(1); 76*60499Selan #endif /* DEBUG */ 7713796Ssam } 7813796Ssam 7960091Sbostic void 8013796Ssam gendefaults() 8113796Ssam { 8213796Ssam register struct gettystrs *sp; 8313796Ssam register struct gettynums *np; 8413796Ssam register struct gettyflags *fp; 8513796Ssam 8613796Ssam for (sp = gettystrs; sp->field; sp++) 8713796Ssam if (sp->value) 8813796Ssam sp->defalt = sp->value; 8913796Ssam for (np = gettynums; np->field; np++) 9013796Ssam if (np->set) 9113796Ssam np->defalt = np->value; 9213796Ssam for (fp = gettyflags; fp->field; fp++) 9313796Ssam if (fp->set) 9413796Ssam fp->defalt = fp->value; 9513796Ssam else 9613796Ssam fp->defalt = fp->invrt; 9713796Ssam } 9813796Ssam 9960091Sbostic void 10013796Ssam setdefaults() 10113796Ssam { 10213796Ssam register struct gettystrs *sp; 10313796Ssam register struct gettynums *np; 10413796Ssam register struct gettyflags *fp; 10513796Ssam 10613796Ssam for (sp = gettystrs; sp->field; sp++) 10713796Ssam if (!sp->value) 10813796Ssam sp->value = sp->defalt; 10913796Ssam for (np = gettynums; np->field; np++) 11013796Ssam if (!np->set) 11113796Ssam np->value = np->defalt; 11213796Ssam for (fp = gettyflags; fp->field; fp++) 11313796Ssam if (!fp->set) 11413796Ssam fp->value = fp->defalt; 11513796Ssam } 11613796Ssam 11713796Ssam static char ** 11813796Ssam charnames[] = { 11913796Ssam &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK, 12013796Ssam &SU, &DS, &RP, &FL, &WE, &LN, 0 12113796Ssam }; 12213796Ssam 12313796Ssam static char * 12413796Ssam charvars[] = { 12513796Ssam &tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc, 12613796Ssam &tc.t_quitc, &tc.t_startc, &tc.t_stopc, 12713796Ssam &tc.t_eofc, &tc.t_brkc, <c.t_suspc, 12813796Ssam <c.t_dsuspc, <c.t_rprntc, <c.t_flushc, 12913796Ssam <c.t_werasc, <c.t_lnextc, 0 13013796Ssam }; 13113796Ssam 13260091Sbostic void 13313796Ssam setchars() 13413796Ssam { 13513796Ssam register int i; 13613796Ssam register char *p; 13713796Ssam 13813796Ssam for (i = 0; charnames[i]; i++) { 13913796Ssam p = *charnames[i]; 14013796Ssam if (p && *p) 14113796Ssam *charvars[i] = *p; 14213796Ssam else 14319946Sedward *charvars[i] = '\377'; 14413796Ssam } 14513796Ssam } 14613796Ssam 14713796Ssam long 14813796Ssam setflags(n) 14960091Sbostic int n; 15013796Ssam { 15113796Ssam register long f; 15213796Ssam 15313796Ssam switch (n) { 15413796Ssam case 0: 15513796Ssam if (F0set) 15613796Ssam return(F0); 15713796Ssam break; 15813796Ssam case 1: 15913796Ssam if (F1set) 16013796Ssam return(F1); 16113796Ssam break; 16213796Ssam default: 16313796Ssam if (F2set) 16413796Ssam return(F2); 16513796Ssam break; 16613796Ssam } 16713796Ssam 16813796Ssam f = 0; 16913796Ssam 17013796Ssam if (AP) 17113796Ssam f |= ANYP; 17213796Ssam else if (OP) 17313796Ssam f |= ODDP; 17413796Ssam else if (EP) 17513796Ssam f |= EVENP; 17613796Ssam 17713796Ssam if (UC) 17813796Ssam f |= LCASE; 17913796Ssam 18013796Ssam if (NL) 18113796Ssam f |= CRMOD; 18213796Ssam 18313796Ssam f |= delaybits(); 18413796Ssam 18513796Ssam if (n == 1) { /* read mode flags */ 18613796Ssam if (RW) 18713796Ssam f |= RAW; 18813796Ssam else 18913796Ssam f |= CBREAK; 19013796Ssam return (f); 19113796Ssam } 19213796Ssam 19313796Ssam if (!HT) 19413796Ssam f |= XTABS; 19513796Ssam 19613796Ssam if (n == 0) 19713796Ssam return (f); 19813796Ssam 19913796Ssam if (CB) 20013796Ssam f |= CRTBS; 20113796Ssam 20213796Ssam if (CE) 20313796Ssam f |= CRTERA; 20413796Ssam 20516565Sralph if (CK) 20616565Sralph f |= CRTKIL; 20716565Sralph 20813796Ssam if (PE) 20913796Ssam f |= PRTERA; 21013796Ssam 21113796Ssam if (EC) 21213796Ssam f |= ECHO; 21313796Ssam 21413796Ssam if (XC) 21513796Ssam f |= CTLECH; 21613796Ssam 21725730Smckusick if (DX) 21825730Smckusick f |= DECCTQ; 21925730Smckusick 22013796Ssam return (f); 22113796Ssam } 22213796Ssam 22313796Ssam struct delayval { 22413796Ssam unsigned delay; /* delay in ms */ 22513796Ssam int bits; 22613796Ssam }; 22713796Ssam 22813796Ssam /* 22913796Ssam * below are random guesses, I can't be bothered checking 23013796Ssam */ 23113796Ssam 23213796Ssam struct delayval crdelay[] = { 23360091Sbostic { 1, CR1 }, 23460091Sbostic { 2, CR2 }, 23560091Sbostic { 3, CR3 }, 23660091Sbostic { 83, CR1 }, 23760091Sbostic { 166, CR2 }, 23860091Sbostic { 0, CR3 }, 23913796Ssam }; 24013796Ssam 24113796Ssam struct delayval nldelay[] = { 24260091Sbostic { 1, NL1 }, /* special, calculated */ 24360091Sbostic { 2, NL2 }, 24460091Sbostic { 3, NL3 }, 24560091Sbostic { 100, NL2 }, 24660091Sbostic { 0, NL3 }, 24713796Ssam }; 24813796Ssam 24913796Ssam struct delayval bsdelay[] = { 25060091Sbostic { 1, BS1 }, 25160091Sbostic { 0, 0 }, 25213796Ssam }; 25313796Ssam 25413796Ssam struct delayval ffdelay[] = { 25560091Sbostic { 1, FF1 }, 25660091Sbostic { 1750, FF1 }, 25760091Sbostic { 0, FF1 }, 25813796Ssam }; 25913796Ssam 26013796Ssam struct delayval tbdelay[] = { 26160091Sbostic { 1, TAB1 }, 26260091Sbostic { 2, TAB2 }, 26360091Sbostic { 3, XTABS }, /* this is expand tabs */ 26460091Sbostic { 100, TAB1 }, 26560091Sbostic { 0, TAB2 }, 26613796Ssam }; 26713796Ssam 26860091Sbostic int 26913796Ssam delaybits() 27013796Ssam { 27160091Sbostic register int f; 27213796Ssam 27313796Ssam f = adelay(CD, crdelay); 27413796Ssam f |= adelay(ND, nldelay); 27513796Ssam f |= adelay(FD, ffdelay); 27613796Ssam f |= adelay(TD, tbdelay); 27713796Ssam f |= adelay(BD, bsdelay); 27813796Ssam return (f); 27913796Ssam } 28013796Ssam 28160091Sbostic int 28213796Ssam adelay(ms, dp) 28313796Ssam register ms; 28413796Ssam register struct delayval *dp; 28513796Ssam { 28613796Ssam if (ms == 0) 28713796Ssam return (0); 28813796Ssam while (dp->delay && ms > dp->delay) 28913796Ssam dp++; 29013796Ssam return (dp->bits); 29113796Ssam } 29213796Ssam 29313796Ssam char editedhost[32]; 29413796Ssam 29560091Sbostic void 29613796Ssam edithost(pat) 29713796Ssam register char *pat; 29813796Ssam { 29913796Ssam register char *host = HN; 30013796Ssam register char *res = editedhost; 30113796Ssam 30213796Ssam if (!pat) 30313796Ssam pat = ""; 30413796Ssam while (*pat) { 30513796Ssam switch (*pat) { 30613796Ssam 30713796Ssam case '#': 30813796Ssam if (*host) 30913796Ssam host++; 31013796Ssam break; 31113796Ssam 31213796Ssam case '@': 31313796Ssam if (*host) 31413796Ssam *res++ = *host++; 31513796Ssam break; 31613796Ssam 31713796Ssam default: 31813796Ssam *res++ = *pat; 31913796Ssam break; 32013796Ssam 32113796Ssam } 32213796Ssam if (res == &editedhost[sizeof editedhost - 1]) { 32313796Ssam *res = '\0'; 32413796Ssam return; 32513796Ssam } 32613796Ssam pat++; 32713796Ssam } 32813796Ssam if (*host) 32913796Ssam strncpy(res, host, sizeof editedhost - (res - editedhost) - 1); 33013796Ssam else 33113796Ssam *res = '\0'; 33213796Ssam editedhost[sizeof editedhost - 1] = '\0'; 33313796Ssam } 33413796Ssam 33513796Ssam struct speedtab { 33613796Ssam int speed; 33713796Ssam int uxname; 33813796Ssam } speedtab[] = { 33960091Sbostic { 50, B50 }, 34060091Sbostic { 75, B75 }, 34160091Sbostic { 110, B110 }, 34260091Sbostic { 134, B134 }, 34360091Sbostic { 150, B150 }, 34460091Sbostic { 200, B200 }, 34560091Sbostic { 300, B300 }, 34660091Sbostic { 600, B600 }, 34760091Sbostic { 1200, B1200 }, 34860091Sbostic { 1800, B1800 }, 34960091Sbostic { 2400, B2400 }, 35060091Sbostic { 4800, B4800 }, 35160091Sbostic { 9600, B9600 }, 35260091Sbostic { 19200, EXTA }, 35360091Sbostic { 19, EXTA }, /* for people who say 19.2K */ 35460091Sbostic { 38400, EXTB }, 35560091Sbostic { 38, EXTB }, 35660091Sbostic { 7200, EXTB }, /* alternative */ 35760091Sbostic { 0 } 35813796Ssam }; 35913796Ssam 36060091Sbostic int 36113796Ssam speed(val) 36260091Sbostic int val; 36313796Ssam { 36413796Ssam register struct speedtab *sp; 36513796Ssam 36613796Ssam if (val <= 15) 36717925Sralph return (val); 36813796Ssam 36913796Ssam for (sp = speedtab; sp->speed; sp++) 37013796Ssam if (sp->speed == val) 37113796Ssam return (sp->uxname); 37213796Ssam 37313796Ssam return (B300); /* default in impossible cases */ 37413796Ssam } 37513796Ssam 37660091Sbostic void 37713796Ssam makeenv(env) 37813796Ssam char *env[]; 37913796Ssam { 38013796Ssam static char termbuf[128] = "TERM="; 38113796Ssam register char *p, *q; 38213796Ssam register char **ep; 38313796Ssam 38413796Ssam ep = env; 38513796Ssam if (TT && *TT) { 38613796Ssam strcat(termbuf, TT); 38713796Ssam *ep++ = termbuf; 38813796Ssam } 38913796Ssam if (p = EV) { 39013796Ssam q = p; 39160091Sbostic while (q = strchr(q, ',')) { 39213796Ssam *q++ = '\0'; 39313796Ssam *ep++ = p; 39413796Ssam p = q; 39513796Ssam } 39613796Ssam if (*p) 39713796Ssam *ep++ = p; 39813796Ssam } 39913796Ssam *ep = (char *)0; 40013796Ssam } 40113796Ssam 40213796Ssam /* 40313796Ssam * This speed select mechanism is written for the Develcon DATASWITCH. 40413796Ssam * The Develcon sends a string of the form "B{speed}\n" at a predefined 40513796Ssam * baud rate. This string indicates the user's actual speed. 40613796Ssam * The routine below returns the terminal type mapped from derived speed. 40713796Ssam */ 40813796Ssam struct portselect { 40913796Ssam char *ps_baud; 41013796Ssam char *ps_type; 41113796Ssam } portspeeds[] = { 41213796Ssam { "B110", "std.110" }, 41313796Ssam { "B134", "std.134" }, 41413796Ssam { "B150", "std.150" }, 41513796Ssam { "B300", "std.300" }, 41613796Ssam { "B600", "std.600" }, 41713796Ssam { "B1200", "std.1200" }, 41813796Ssam { "B2400", "std.2400" }, 41913796Ssam { "B4800", "std.4800" }, 42013796Ssam { "B9600", "std.9600" }, 42125233Smckusick { "B19200", "std.19200" }, 42213796Ssam { 0 } 42313796Ssam }; 42413796Ssam 42513796Ssam char * 42613796Ssam portselector() 42713796Ssam { 42813796Ssam char c, baud[20], *type = "default"; 42913796Ssam register struct portselect *ps; 43013796Ssam int len; 43113796Ssam 43213796Ssam alarm(5*60); 43313796Ssam for (len = 0; len < sizeof (baud) - 1; len++) { 43446690Sbostic if (read(STDIN_FILENO, &c, 1) <= 0) 43513796Ssam break; 43613796Ssam c &= 0177; 43713796Ssam if (c == '\n' || c == '\r') 43813796Ssam break; 43913796Ssam if (c == 'B') 44013796Ssam len = 0; /* in case of leading garbage */ 44113796Ssam baud[len] = c; 44213796Ssam } 44313796Ssam baud[len] = '\0'; 44413796Ssam for (ps = portspeeds; ps->ps_baud; ps++) 44513796Ssam if (strcmp(ps->ps_baud, baud) == 0) { 44613796Ssam type = ps->ps_type; 44713796Ssam break; 44813796Ssam } 44913796Ssam sleep(2); /* wait for connection to complete */ 45013796Ssam return (type); 45113796Ssam } 45217925Sralph 45317925Sralph /* 45417925Sralph * This auto-baud speed select mechanism is written for the Micom 600 45517925Sralph * portselector. Selection is done by looking at how the character '\r' 45617925Sralph * is garbled at the different speeds. 45717925Sralph */ 45817925Sralph #include <sys/time.h> 45917925Sralph 46017925Sralph char * 46117925Sralph autobaud() 46217925Sralph { 46317925Sralph int rfds; 46417925Sralph struct timeval timeout; 46517925Sralph char c, *type = "9600-baud"; 46617925Sralph int null = 0; 46717925Sralph 46817925Sralph ioctl(0, TIOCFLUSH, &null); 46917925Sralph rfds = 1 << 0; 47017925Sralph timeout.tv_sec = 5; 47117925Sralph timeout.tv_usec = 0; 47246689Sbostic if (select(32, (fd_set *)&rfds, (fd_set *)NULL, 47346689Sbostic (fd_set *)NULL, &timeout) <= 0) 47417925Sralph return (type); 47546690Sbostic if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char)) 47617925Sralph return (type); 47717925Sralph timeout.tv_sec = 0; 47817925Sralph timeout.tv_usec = 20; 47946689Sbostic (void) select(32, (fd_set *)NULL, (fd_set *)NULL, 48046689Sbostic (fd_set *)NULL, &timeout); 48117925Sralph ioctl(0, TIOCFLUSH, &null); 48217925Sralph switch (c & 0377) { 48317925Sralph 48417925Sralph case 0200: /* 300-baud */ 48517925Sralph type = "300-baud"; 48617925Sralph break; 48717925Sralph 48817925Sralph case 0346: /* 1200-baud */ 48917925Sralph type = "1200-baud"; 49017925Sralph break; 49117925Sralph 49217925Sralph case 015: /* 2400-baud */ 49317925Sralph case 0215: 49417925Sralph type = "2400-baud"; 49517925Sralph break; 49617925Sralph 49717925Sralph default: /* 4800-baud */ 49817925Sralph type = "4800-baud"; 49917925Sralph break; 50017925Sralph 50117925Sralph case 0377: /* 9600-baud */ 50217925Sralph type = "9600-baud"; 50317925Sralph break; 50417925Sralph } 50517925Sralph return (type); 50617925Sralph } 507