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