added "ub" to force unbuffered output
[unix-history] / usr / src / libexec / getty / subr.c
CommitLineData
3eea9327
SL
1#ifndef lint
2static char sccsid[] = "@(#)subr.c 4.1 (Berkeley) 83/07/06";
3#endif
4
5/*
6 * Melbourne getty.
7 */
8#include <sgtty.h>
9#include "gettytab.h"
10
11extern struct sgttyb tmode;
12extern struct tchars tc;
13extern struct ltchars ltc;
14
15/*
16 * Get a table entry.
17 */
18gettable(name, buf, area)
19 char *name, *buf, *area;
20{
21 register struct gettystrs *sp;
22 register struct gettynums *np;
23 register struct gettyflags *fp;
24 register n;
25
26 hopcount = 0; /* new lookup, start fresh */
27 if (getent(buf, name) != 1)
28 return;
29
30 for (sp = gettystrs; sp->field; sp++)
31 sp->value = getstr(sp->field, &area);
32 for (np = gettynums; np->field; np++) {
33 n = getnum(np->field);
34 if (n == -1)
35 np->set = 0;
36 else {
37 np->set = 1;
38 np->value = n;
39 }
40 }
41 for (fp = gettyflags; fp->field; fp++) {
42 n = getflag(fp->field);
43 if (n == -1)
44 fp->set = 0;
45 else {
46 fp->set = 1;
47 fp->value = n ^ fp->invrt;
48 }
49 }
50}
51
52gendefaults()
53{
54 register struct gettystrs *sp;
55 register struct gettynums *np;
56 register struct gettyflags *fp;
57
58 for (sp = gettystrs; sp->field; sp++)
59 if (sp->value)
60 sp->defalt = sp->value;
61 for (np = gettynums; np->field; np++)
62 if (np->set)
63 np->defalt = np->value;
64 for (fp = gettyflags; fp->field; fp++)
65 if (fp->set)
66 fp->defalt = fp->value;
67 else
68 fp->defalt = fp->invrt;
69}
70
71setdefaults()
72{
73 register struct gettystrs *sp;
74 register struct gettynums *np;
75 register struct gettyflags *fp;
76
77 for (sp = gettystrs; sp->field; sp++)
78 if (!sp->value)
79 sp->value = sp->defalt;
80 for (np = gettynums; np->field; np++)
81 if (!np->set)
82 np->value = np->defalt;
83 for (fp = gettyflags; fp->field; fp++)
84 if (!fp->set)
85 fp->value = fp->defalt;
86}
87
88static char **
89charnames[] = {
90 &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
91 &SU, &DS, &RP, &FL, &WE, &LN, 0
92};
93
94static char *
95charvars[] = {
96 &tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc,
97 &tc.t_quitc, &tc.t_startc, &tc.t_stopc,
98 &tc.t_eofc, &tc.t_brkc, &ltc.t_suspc,
99 &ltc.t_dsuspc, &ltc.t_rprntc, &ltc.t_flushc,
100 &ltc.t_werasc, &ltc.t_lnextc, 0
101};
102
103setchars()
104{
105 register int i;
106 register char *p;
107
108 for (i = 0; charnames[i]; i++) {
109 p = *charnames[i];
110 if (p && *p)
111 *charvars[i] = *p;
112 else
113 *charvars[i] = '\0377';
114 }
115}
116
117long
118setflags(n)
119{
120 register long f;
121
122 switch (n) {
123 case 0:
124 if (F0set)
125 return(F0);
126 break;
127 case 1:
128 if (F1set)
129 return(F1);
130 break;
131 default:
132 if (F2set)
133 return(F2);
134 break;
135 }
136
137 f = 0;
138
139 if (AP)
140 f |= ANYP;
141 else if (OP)
142 f |= ODDP;
143 else if (EP)
144 f |= EVENP;
145
146 if (UC)
147 f |= LCASE;
148
149 if (NL)
150 f |= CRMOD;
151
152 f |= delaybits();
153
154 if (n == 1) { /* read mode flags */
155 if (RW)
156 f |= RAW;
157 else
158 f |= CBREAK;
159 return (f);
160 }
161
162 if (!HT)
163 f |= XTABS;
164
165 if (n == 0)
166 return (f);
167
168 if (CB)
169 f |= CRTBS;
170
171 if (CE)
172 f |= CRTERA;
173
174 if (PE)
175 f |= PRTERA;
176
177 if (EC)
178 f |= ECHO;
179
180 if (XC)
181 f |= CTLECH;
182
183 return (f);
184}
185
186struct delayval {
187 unsigned delay; /* delay in ms */
188 int bits;
189};
190
191/*
192 * below are random guesses, I can't be bothered checking
193 */
194
195struct delayval crdelay[] = {
196 20, CR1,
197 30, CR2,
198 40, CR3,
199 0, CR3,
200};
201
202struct delayval nldelay[] = {
203 1, NL1, /* special, calculated */
204 16, NL2,
205 30, NL3,
206 0, NL3,
207};
208
209struct delayval bsdelay[] = {
210 0, 0,
211};
212
213struct delayval ffdelay[] = {
214 1750, FF1,
215 0, FF1,
216};
217
218struct delayval tbdelay[] = {
219 10, TAB1,
220 20, TAB2,
221 0, TAB2,
222};
223
224delaybits()
225{
226 register f;
227
228 f = adelay(CD, crdelay);
229 f |= adelay(ND, nldelay);
230 f |= adelay(FD, ffdelay);
231 f |= adelay(TD, tbdelay);
232 f |= adelay(BD, bsdelay);
233 return (f);
234}
235
236adelay(ms, dp)
237 register ms;
238 register struct delayval *dp;
239{
240 if (ms == 0)
241 return (0);
242 while (dp->delay && ms > dp->delay)
243 dp++;
244 return (dp->bits);
245}
246
247char editedhost[32];
248
249edithost(pat)
250 register char *pat;
251{
252 register char *host = HN;
253 register char *res = editedhost;
254
255 if (!pat)
256 pat = "";
257 while (*pat) {
258 switch (*pat) {
259
260 case '#':
261 if (*host)
262 host++;
263 break;
264
265 case '@':
266 if (*host)
267 *res++ = *host++;
268 break;
269
270 default:
271 *res++ = *pat;
272 break;
273
274 }
275 if (res == &editedhost[sizeof editedhost - 1]) {
276 *res = '\0';
277 return;
278 }
279 pat++;
280 }
281 if (*host)
282 strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
283 else
284 *res = '\0';
285 editedhost[sizeof editedhost - 1] = '\0';
286}
287
288struct speedtab {
289 int speed;
290 int uxname;
291} speedtab[] = {
292 50, B50,
293 75, B75,
294 110, B110,
295 134, B134,
296 150, B150,
297 200, B200,
298 300, B300,
299 600, B600,
300 1200, B1200,
301 1800, B1800,
302 2400, B2400,
303 4800, B4800,
304 9600, B9600,
305 19200, EXTA,
306 19, EXTA, /* for people who say 19.2K */
307 38400, EXTB,
308 38, EXTB,
309 7200, EXTB, /* alternative */
310 0
311};
312
313speed(val)
314{
315 register struct speedtab *sp;
316
317 if (val <= 15)
318 return(val);
319
320 for (sp = speedtab; sp->speed; sp++)
321 if (sp->speed == val)
322 return (sp->uxname);
323
324 return (B300); /* default in impossible cases */
325}
326
327makeenv(env)
328 char *env[];
329{
330 static char termbuf[128] = "TERM=";
331 register char *p, *q;
332 register char **ep;
333 char *index();
334
335 ep = env;
336 if (TT && *TT) {
337 strcat(termbuf, TT);
338 *ep++ = termbuf;
339 }
340 if (p = EV) {
341 q = p;
342 while (q = index(q, ',')) {
343 *q++ = '\0';
344 *ep++ = p;
345 p = q;
346 }
347 if (*p)
348 *ep++ = p;
349 }
350 *ep = (char *)0;
351}
352
353/*
354 * This speed select mechanism is written for the Develcon DATASWITCH.
355 * The Develcon sends a string of the form "B{speed}\n" at a predefined
356 * baud rate. This string indicates the user's actual speed.
357 * The routine below returns the terminal type mapped from derived speed.
358 */
359struct portselect {
360 char *ps_baud;
361 char *ps_type;
362} portspeeds[] = {
363 { "B110", "std.110" },
364 { "B134", "std.134" },
365 { "B150", "std.150" },
366 { "B300", "std.300" },
367 { "B600", "std.600" },
368 { "B1200", "std.1200" },
369 { "B2400", "std.2400" },
370 { "B4800", "std.4800" },
371 { "B9600", "std.9600" },
372 { 0 }
373};
374
375char *
376portselector()
377{
378 char c, baud[20], *type = "default";
379 register struct portselect *ps;
380 int len;
381
382 alarm(5*60);
383 for (len = 0; len < sizeof (baud) - 1; len++) {
384 if (read(0, &c, 1) <= 0)
385 break;
386 c &= 0177;
387 if (c == '\n' || c == '\r')
388 break;
389 if (c == 'B')
390 len = 0; /* in case of leading garbage */
391 baud[len] = c;
392 }
393 baud[len] = '\0';
394 for (ps = portspeeds; ps->ps_baud; ps++)
395 if (strcmp(ps->ps_baud, baud) == 0) {
396 type = ps->ps_type;
397 break;
398 }
399 sleep(2); /* wait for connection to complete */
400 return (type);
401}