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