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