119061Sdist /*
2*61431Sbostic * Copyright (c) 1983, 1993
3*61431Sbostic * The Regents of the University of California. All rights reserved.
436930Sbostic *
542670Sbostic * %sccs.include.redist.c%
619061Sdist */
719061Sdist
813796Ssam #ifndef lint
9*61431Sbostic static char sccsid[] = "@(#)subr.c 8.1 (Berkeley) 06/04/93";
1036930Sbostic #endif /* not lint */
1113796Ssam
1213796Ssam /*
1313796Ssam * Melbourne getty.
1413796Ssam */
1542668Smarc #define USE_OLD_TTY
1660499Selan #include <stdlib.h>
1713796Ssam #include <sgtty.h>
1860091Sbostic #include <string.h>
1946671Sbostic #include <unistd.h>
2060091Sbostic
2113796Ssam #include "gettytab.h"
2260091Sbostic #include "extern.h"
2360499Selan #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
gettable(name,buf)3360499Selan gettable(name, buf)
3460499Selan char *name, *buf;
3513796Ssam {
3613796Ssam register struct gettystrs *sp;
3713796Ssam register struct gettynums *np;
3813796Ssam register struct gettyflags *fp;
3960499Selan long n;
4060499Selan char *dba[2];
4160499Selan dba[0] = _PATH_GETTYTAB;
4260499Selan dba[1] = 0;
4313796Ssam
4460499Selan if (cgetent(&buf, dba, name) != 0)
4513796Ssam return;
4613796Ssam
4760499Selan for (sp = gettystrs; sp->field; sp++)
4860499Selan cgetstr(buf, sp->field, &sp->value);
4913796Ssam for (np = gettynums; np->field; np++) {
5060499Selan 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++) {
5860499Selan if (cgetcap(buf, fp->field, ':') == NULL)
5913796Ssam fp->set = 0;
6013796Ssam else {
6113796Ssam fp->set = 1;
6260499Selan fp->value = 1 ^ fp->invrt;
6313796Ssam }
6413796Ssam }
6560499Selan #ifdef DEBUG
6660499Selan printf("name=\"%s\", buf=\"%s\"\n", name, buf);
6760499Selan for (sp = gettystrs; sp->field; sp++)
6860499Selan printf("cgetstr: %s=%s\n", sp->field, sp->value);
6960499Selan for (np = gettynums; np->field; np++)
7060499Selan printf("cgetnum: %s=%d\n", np->field, np->value);
7160499Selan for (fp = gettyflags; fp->field; fp++)
7260499Selan printf("cgetflags: %s='%c' set='%c'\n", fp->field,
7360499Selan fp->value + '0', fp->set + '0');
7460499Selan exit(1);
7560499Selan #endif /* DEBUG */
7613796Ssam }
7713796Ssam
7860091Sbostic void
gendefaults()7913796Ssam gendefaults()
8013796Ssam {
8113796Ssam register struct gettystrs *sp;
8213796Ssam register struct gettynums *np;
8313796Ssam register struct gettyflags *fp;
8413796Ssam
8513796Ssam for (sp = gettystrs; sp->field; sp++)
8613796Ssam if (sp->value)
8713796Ssam sp->defalt = sp->value;
8813796Ssam for (np = gettynums; np->field; np++)
8913796Ssam if (np->set)
9013796Ssam np->defalt = np->value;
9113796Ssam for (fp = gettyflags; fp->field; fp++)
9213796Ssam if (fp->set)
9313796Ssam fp->defalt = fp->value;
9413796Ssam else
9513796Ssam fp->defalt = fp->invrt;
9613796Ssam }
9713796Ssam
9860091Sbostic void
setdefaults()9913796Ssam setdefaults()
10013796Ssam {
10113796Ssam register struct gettystrs *sp;
10213796Ssam register struct gettynums *np;
10313796Ssam register struct gettyflags *fp;
10413796Ssam
10513796Ssam for (sp = gettystrs; sp->field; sp++)
10613796Ssam if (!sp->value)
10713796Ssam sp->value = sp->defalt;
10813796Ssam for (np = gettynums; np->field; np++)
10913796Ssam if (!np->set)
11013796Ssam np->value = np->defalt;
11113796Ssam for (fp = gettyflags; fp->field; fp++)
11213796Ssam if (!fp->set)
11313796Ssam fp->value = fp->defalt;
11413796Ssam }
11513796Ssam
11613796Ssam static char **
11713796Ssam charnames[] = {
11813796Ssam &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
11913796Ssam &SU, &DS, &RP, &FL, &WE, &LN, 0
12013796Ssam };
12113796Ssam
12213796Ssam static char *
12313796Ssam charvars[] = {
12413796Ssam &tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc,
12513796Ssam &tc.t_quitc, &tc.t_startc, &tc.t_stopc,
12613796Ssam &tc.t_eofc, &tc.t_brkc, <c.t_suspc,
12713796Ssam <c.t_dsuspc, <c.t_rprntc, <c.t_flushc,
12813796Ssam <c.t_werasc, <c.t_lnextc, 0
12913796Ssam };
13013796Ssam
13160091Sbostic void
setchars()13213796Ssam setchars()
13313796Ssam {
13413796Ssam register int i;
13513796Ssam register char *p;
13613796Ssam
13713796Ssam for (i = 0; charnames[i]; i++) {
13813796Ssam p = *charnames[i];
13913796Ssam if (p && *p)
14013796Ssam *charvars[i] = *p;
14113796Ssam else
14219946Sedward *charvars[i] = '\377';
14313796Ssam }
14413796Ssam }
14513796Ssam
14613796Ssam long
setflags(n)14713796Ssam setflags(n)
14860091Sbostic int n;
14913796Ssam {
15013796Ssam register long f;
15113796Ssam
15213796Ssam switch (n) {
15313796Ssam case 0:
15413796Ssam if (F0set)
15513796Ssam return(F0);
15613796Ssam break;
15713796Ssam case 1:
15813796Ssam if (F1set)
15913796Ssam return(F1);
16013796Ssam break;
16113796Ssam default:
16213796Ssam if (F2set)
16313796Ssam return(F2);
16413796Ssam break;
16513796Ssam }
16613796Ssam
16713796Ssam f = 0;
16813796Ssam
16913796Ssam if (AP)
17013796Ssam f |= ANYP;
17113796Ssam else if (OP)
17213796Ssam f |= ODDP;
17313796Ssam else if (EP)
17413796Ssam f |= EVENP;
17513796Ssam
17613796Ssam if (UC)
17713796Ssam f |= LCASE;
17813796Ssam
17913796Ssam if (NL)
18013796Ssam f |= CRMOD;
18113796Ssam
18213796Ssam f |= delaybits();
18313796Ssam
18413796Ssam if (n == 1) { /* read mode flags */
18513796Ssam if (RW)
18613796Ssam f |= RAW;
18713796Ssam else
18813796Ssam f |= CBREAK;
18913796Ssam return (f);
19013796Ssam }
19113796Ssam
19213796Ssam if (!HT)
19313796Ssam f |= XTABS;
19413796Ssam
19513796Ssam if (n == 0)
19613796Ssam return (f);
19713796Ssam
19813796Ssam if (CB)
19913796Ssam f |= CRTBS;
20013796Ssam
20113796Ssam if (CE)
20213796Ssam f |= CRTERA;
20313796Ssam
20416565Sralph if (CK)
20516565Sralph f |= CRTKIL;
20616565Sralph
20713796Ssam if (PE)
20813796Ssam f |= PRTERA;
20913796Ssam
21013796Ssam if (EC)
21113796Ssam f |= ECHO;
21213796Ssam
21313796Ssam if (XC)
21413796Ssam f |= CTLECH;
21513796Ssam
21625730Smckusick if (DX)
21725730Smckusick f |= DECCTQ;
21825730Smckusick
21913796Ssam return (f);
22013796Ssam }
22113796Ssam
22213796Ssam struct delayval {
22313796Ssam unsigned delay; /* delay in ms */
22413796Ssam int bits;
22513796Ssam };
22613796Ssam
22713796Ssam /*
22813796Ssam * below are random guesses, I can't be bothered checking
22913796Ssam */
23013796Ssam
23113796Ssam struct delayval crdelay[] = {
23260091Sbostic { 1, CR1 },
23360091Sbostic { 2, CR2 },
23460091Sbostic { 3, CR3 },
23560091Sbostic { 83, CR1 },
23660091Sbostic { 166, CR2 },
23760091Sbostic { 0, CR3 },
23813796Ssam };
23913796Ssam
24013796Ssam struct delayval nldelay[] = {
24160091Sbostic { 1, NL1 }, /* special, calculated */
24260091Sbostic { 2, NL2 },
24360091Sbostic { 3, NL3 },
24460091Sbostic { 100, NL2 },
24560091Sbostic { 0, NL3 },
24613796Ssam };
24713796Ssam
24813796Ssam struct delayval bsdelay[] = {
24960091Sbostic { 1, BS1 },
25060091Sbostic { 0, 0 },
25113796Ssam };
25213796Ssam
25313796Ssam struct delayval ffdelay[] = {
25460091Sbostic { 1, FF1 },
25560091Sbostic { 1750, FF1 },
25660091Sbostic { 0, FF1 },
25713796Ssam };
25813796Ssam
25913796Ssam struct delayval tbdelay[] = {
26060091Sbostic { 1, TAB1 },
26160091Sbostic { 2, TAB2 },
26260091Sbostic { 3, XTABS }, /* this is expand tabs */
26360091Sbostic { 100, TAB1 },
26460091Sbostic { 0, TAB2 },
26513796Ssam };
26613796Ssam
26760091Sbostic int
delaybits()26813796Ssam delaybits()
26913796Ssam {
27060091Sbostic register int f;
27113796Ssam
27213796Ssam f = adelay(CD, crdelay);
27313796Ssam f |= adelay(ND, nldelay);
27413796Ssam f |= adelay(FD, ffdelay);
27513796Ssam f |= adelay(TD, tbdelay);
27613796Ssam f |= adelay(BD, bsdelay);
27713796Ssam return (f);
27813796Ssam }
27913796Ssam
28060091Sbostic int
adelay(ms,dp)28113796Ssam adelay(ms, dp)
28213796Ssam register ms;
28313796Ssam register struct delayval *dp;
28413796Ssam {
28513796Ssam if (ms == 0)
28613796Ssam return (0);
28713796Ssam while (dp->delay && ms > dp->delay)
28813796Ssam dp++;
28913796Ssam return (dp->bits);
29013796Ssam }
29113796Ssam
29213796Ssam char editedhost[32];
29313796Ssam
29460091Sbostic void
edithost(pat)29513796Ssam edithost(pat)
29613796Ssam register char *pat;
29713796Ssam {
29813796Ssam register char *host = HN;
29913796Ssam register char *res = editedhost;
30013796Ssam
30113796Ssam if (!pat)
30213796Ssam pat = "";
30313796Ssam while (*pat) {
30413796Ssam switch (*pat) {
30513796Ssam
30613796Ssam case '#':
30713796Ssam if (*host)
30813796Ssam host++;
30913796Ssam break;
31013796Ssam
31113796Ssam case '@':
31213796Ssam if (*host)
31313796Ssam *res++ = *host++;
31413796Ssam break;
31513796Ssam
31613796Ssam default:
31713796Ssam *res++ = *pat;
31813796Ssam break;
31913796Ssam
32013796Ssam }
32113796Ssam if (res == &editedhost[sizeof editedhost - 1]) {
32213796Ssam *res = '\0';
32313796Ssam return;
32413796Ssam }
32513796Ssam pat++;
32613796Ssam }
32713796Ssam if (*host)
32813796Ssam strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
32913796Ssam else
33013796Ssam *res = '\0';
33113796Ssam editedhost[sizeof editedhost - 1] = '\0';
33213796Ssam }
33313796Ssam
33413796Ssam struct speedtab {
33513796Ssam int speed;
33613796Ssam int uxname;
33713796Ssam } speedtab[] = {
33860091Sbostic { 50, B50 },
33960091Sbostic { 75, B75 },
34060091Sbostic { 110, B110 },
34160091Sbostic { 134, B134 },
34260091Sbostic { 150, B150 },
34360091Sbostic { 200, B200 },
34460091Sbostic { 300, B300 },
34560091Sbostic { 600, B600 },
34660091Sbostic { 1200, B1200 },
34760091Sbostic { 1800, B1800 },
34860091Sbostic { 2400, B2400 },
34960091Sbostic { 4800, B4800 },
35060091Sbostic { 9600, B9600 },
35160091Sbostic { 19200, EXTA },
35260091Sbostic { 19, EXTA }, /* for people who say 19.2K */
35360091Sbostic { 38400, EXTB },
35460091Sbostic { 38, EXTB },
35560091Sbostic { 7200, EXTB }, /* alternative */
35660091Sbostic { 0 }
35713796Ssam };
35813796Ssam
35960091Sbostic int
speed(val)36013796Ssam speed(val)
36160091Sbostic int val;
36213796Ssam {
36313796Ssam register struct speedtab *sp;
36413796Ssam
36513796Ssam if (val <= 15)
36617925Sralph return (val);
36713796Ssam
36813796Ssam for (sp = speedtab; sp->speed; sp++)
36913796Ssam if (sp->speed == val)
37013796Ssam return (sp->uxname);
37113796Ssam
37213796Ssam return (B300); /* default in impossible cases */
37313796Ssam }
37413796Ssam
37560091Sbostic void
makeenv(env)37613796Ssam makeenv(env)
37713796Ssam char *env[];
37813796Ssam {
37913796Ssam static char termbuf[128] = "TERM=";
38013796Ssam register char *p, *q;
38113796Ssam register char **ep;
38213796Ssam
38313796Ssam ep = env;
38413796Ssam if (TT && *TT) {
38513796Ssam strcat(termbuf, TT);
38613796Ssam *ep++ = termbuf;
38713796Ssam }
38813796Ssam if (p = EV) {
38913796Ssam q = p;
39060091Sbostic while (q = strchr(q, ',')) {
39113796Ssam *q++ = '\0';
39213796Ssam *ep++ = p;
39313796Ssam p = q;
39413796Ssam }
39513796Ssam if (*p)
39613796Ssam *ep++ = p;
39713796Ssam }
39813796Ssam *ep = (char *)0;
39913796Ssam }
40013796Ssam
40113796Ssam /*
40213796Ssam * This speed select mechanism is written for the Develcon DATASWITCH.
40313796Ssam * The Develcon sends a string of the form "B{speed}\n" at a predefined
40413796Ssam * baud rate. This string indicates the user's actual speed.
40513796Ssam * The routine below returns the terminal type mapped from derived speed.
40613796Ssam */
40713796Ssam struct portselect {
40813796Ssam char *ps_baud;
40913796Ssam char *ps_type;
41013796Ssam } portspeeds[] = {
41113796Ssam { "B110", "std.110" },
41213796Ssam { "B134", "std.134" },
41313796Ssam { "B150", "std.150" },
41413796Ssam { "B300", "std.300" },
41513796Ssam { "B600", "std.600" },
41613796Ssam { "B1200", "std.1200" },
41713796Ssam { "B2400", "std.2400" },
41813796Ssam { "B4800", "std.4800" },
41913796Ssam { "B9600", "std.9600" },
42025233Smckusick { "B19200", "std.19200" },
42113796Ssam { 0 }
42213796Ssam };
42313796Ssam
42413796Ssam char *
portselector()42513796Ssam portselector()
42613796Ssam {
42713796Ssam char c, baud[20], *type = "default";
42813796Ssam register struct portselect *ps;
42913796Ssam int len;
43013796Ssam
43113796Ssam alarm(5*60);
43213796Ssam for (len = 0; len < sizeof (baud) - 1; len++) {
43346690Sbostic if (read(STDIN_FILENO, &c, 1) <= 0)
43413796Ssam break;
43513796Ssam c &= 0177;
43613796Ssam if (c == '\n' || c == '\r')
43713796Ssam break;
43813796Ssam if (c == 'B')
43913796Ssam len = 0; /* in case of leading garbage */
44013796Ssam baud[len] = c;
44113796Ssam }
44213796Ssam baud[len] = '\0';
44313796Ssam for (ps = portspeeds; ps->ps_baud; ps++)
44413796Ssam if (strcmp(ps->ps_baud, baud) == 0) {
44513796Ssam type = ps->ps_type;
44613796Ssam break;
44713796Ssam }
44813796Ssam sleep(2); /* wait for connection to complete */
44913796Ssam return (type);
45013796Ssam }
45117925Sralph
45217925Sralph /*
45317925Sralph * This auto-baud speed select mechanism is written for the Micom 600
45417925Sralph * portselector. Selection is done by looking at how the character '\r'
45517925Sralph * is garbled at the different speeds.
45617925Sralph */
45717925Sralph #include <sys/time.h>
45817925Sralph
45917925Sralph char *
autobaud()46017925Sralph autobaud()
46117925Sralph {
46217925Sralph int rfds;
46317925Sralph struct timeval timeout;
46417925Sralph char c, *type = "9600-baud";
46517925Sralph int null = 0;
46617925Sralph
46717925Sralph ioctl(0, TIOCFLUSH, &null);
46817925Sralph rfds = 1 << 0;
46917925Sralph timeout.tv_sec = 5;
47017925Sralph timeout.tv_usec = 0;
47146689Sbostic if (select(32, (fd_set *)&rfds, (fd_set *)NULL,
47246689Sbostic (fd_set *)NULL, &timeout) <= 0)
47317925Sralph return (type);
47446690Sbostic if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char))
47517925Sralph return (type);
47617925Sralph timeout.tv_sec = 0;
47717925Sralph timeout.tv_usec = 20;
47846689Sbostic (void) select(32, (fd_set *)NULL, (fd_set *)NULL,
47946689Sbostic (fd_set *)NULL, &timeout);
48017925Sralph ioctl(0, TIOCFLUSH, &null);
48117925Sralph switch (c & 0377) {
48217925Sralph
48317925Sralph case 0200: /* 300-baud */
48417925Sralph type = "300-baud";
48517925Sralph break;
48617925Sralph
48717925Sralph case 0346: /* 1200-baud */
48817925Sralph type = "1200-baud";
48917925Sralph break;
49017925Sralph
49117925Sralph case 015: /* 2400-baud */
49217925Sralph case 0215:
49317925Sralph type = "2400-baud";
49417925Sralph break;
49517925Sralph
49617925Sralph default: /* 4800-baud */
49717925Sralph type = "4800-baud";
49817925Sralph break;
49917925Sralph
50017925Sralph case 0377: /* 9600-baud */
50117925Sralph type = "9600-baud";
50217925Sralph break;
50317925Sralph }
50417925Sralph return (type);
50517925Sralph }
506