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