Remove building with NOCRYPTO option
[minix3.git] / libexec / getty / subr.c
blobc46695cc7dfa212affec755652648039f2e19a12
1 /* $NetBSD: subr.c,v 1.35 2013/08/11 16:36:30 dholland Exp $ */
3 /*
4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "from: @(#)subr.c 8.1 (Berkeley) 6/4/93";
36 #else
37 __RCSID("$NetBSD: subr.c,v 1.35 2013/08/11 16:36:30 dholland Exp $");
38 #endif
39 #endif /* not lint */
42 * Melbourne getty.
44 #if !defined(__minix)
45 #define COMPAT_43
46 #endif /* !defined(__minix) */
47 #include <sys/param.h>
48 #include <sys/ioctl.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <termios.h>
53 #include <unistd.h>
54 #include <poll.h>
55 #include <util.h>
57 #include "extern.h"
58 #include "gettytab.h"
59 #include "pathnames.h"
61 extern struct termios tmode, omode;
63 #if !defined(__minix)
64 static void compatflags(long);
65 #endif /* !defined(__minix) */
68 * Get a table entry.
70 void
71 gettable(const char *name, char *buf)
73 struct gettystrs *sp;
74 struct gettynums *np;
75 struct gettyflags *fp;
76 long n;
77 const char *dba[2];
78 dba[0] = _PATH_GETTYTAB;
79 dba[1] = NULL;
81 if (cgetent(&buf, dba, name) != 0)
82 return;
84 for (sp = gettystrs; sp->field; sp++)
85 (void)cgetstr(buf, sp->field, &sp->value);
86 for (np = gettynums; np->field; np++) {
87 if (cgetnum(buf, np->field, &n) == -1)
88 np->set = 0;
89 else {
90 np->set = 1;
91 np->value = n;
94 for (fp = gettyflags; fp->field; fp++) {
95 if (cgetcap(buf, fp->field, ':') == NULL)
96 fp->set = 0;
97 else {
98 fp->set = 1;
99 fp->value = 1 ^ fp->invrt;
102 #ifdef DEBUG
103 printf("name=\"%s\", buf=\"%s\"\n", name, buf);
104 for (sp = gettystrs; sp->field; sp++)
105 printf("cgetstr: %s=%s\n", sp->field, sp->value);
106 for (np = gettynums; np->field; np++)
107 printf("cgetnum: %s=%d\n", np->field, np->value);
108 for (fp = gettyflags; fp->field; fp++)
109 printf("cgetflags: %s='%c' set='%c'\n", fp->field,
110 fp->value + '0', fp->set + '0');
111 exit(1);
112 #endif /* DEBUG */
115 void
116 gendefaults(void)
118 struct gettystrs *sp;
119 struct gettynums *np;
120 struct gettyflags *fp;
122 for (sp = gettystrs; sp->field; sp++)
123 if (sp->value)
124 sp->defalt = sp->value;
125 for (np = gettynums; np->field; np++)
126 if (np->set)
127 np->defalt = np->value;
128 for (fp = gettyflags; fp->field; fp++)
129 if (fp->set)
130 fp->defalt = fp->value;
131 else
132 fp->defalt = fp->invrt;
135 void
136 setdefaults(void)
138 struct gettystrs *sp;
139 struct gettynums *np;
140 struct gettyflags *fp;
142 for (sp = gettystrs; sp->field; sp++)
143 if (!sp->value)
144 sp->value = sp->defalt ? estrdup(sp->defalt) : NULL;
145 for (np = gettynums; np->field; np++)
146 if (!np->set)
147 np->value = np->defalt;
148 for (fp = gettyflags; fp->field; fp++)
149 if (!fp->set)
150 fp->value = fp->defalt;
153 static char **
154 charnames[] = {
155 &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
156 &SU, &DS, &RP, &FL, &WE, &LN, &ST, &B2, 0
159 static cc_t *
160 charvars[] = {
161 &tmode.c_cc[VERASE], &tmode.c_cc[VKILL], &tmode.c_cc[VINTR],
162 &tmode.c_cc[VQUIT], &tmode.c_cc[VSTART], &tmode.c_cc[VSTOP],
163 &tmode.c_cc[VEOF], &tmode.c_cc[VEOL], &tmode.c_cc[VSUSP],
164 &tmode.c_cc[VDSUSP], &tmode.c_cc[VREPRINT], &tmode.c_cc[VDISCARD],
165 &tmode.c_cc[VWERASE], &tmode.c_cc[VLNEXT], &tmode.c_cc[VSTATUS],
166 &tmode.c_cc[VEOL2], 0
169 void
170 setchars(void)
172 int i;
173 char *p;
175 for (i = 0; charnames[i]; i++) {
176 p = *charnames[i];
177 if (p && *p)
178 *charvars[i] = *p;
179 else
180 *charvars[i] = _POSIX_VDISABLE;
184 /* Macros to clear/set/test flags. */
185 #define SET(t, f) (t) |= (f)
186 #define CLR(t, f) (t) &= ~(f)
187 #define ISSET(t, f) ((t) & (f))
189 void
190 setflags(int n)
192 tcflag_t iflag, oflag, cflag, lflag;
194 #ifdef COMPAT_43
195 switch (n) {
196 case 0:
197 if (F0set) {
198 compatflags(F0);
199 return;
201 break;
202 case 1:
203 if (F1set) {
204 compatflags(F1);
205 return;
207 break;
208 default:
209 if (F2set) {
210 compatflags(F2);
211 return;
213 break;
215 #endif
217 switch (n) {
218 case 0:
219 if (C0set && I0set && L0set && O0set) {
220 tmode.c_cflag = C0;
221 tmode.c_iflag = I0;
222 tmode.c_lflag = L0;
223 tmode.c_oflag = O0;
224 return;
226 break;
227 case 1:
228 if (C1set && I1set && L1set && O1set) {
229 tmode.c_cflag = C1;
230 tmode.c_iflag = I1;
231 tmode.c_lflag = L1;
232 tmode.c_oflag = O1;
233 return;
235 break;
236 default:
237 if (C2set && I2set && L2set && O2set) {
238 tmode.c_cflag = C2;
239 tmode.c_iflag = I2;
240 tmode.c_lflag = L2;
241 tmode.c_oflag = O2;
242 return;
244 break;
247 iflag = omode.c_iflag;
248 oflag = omode.c_oflag;
249 cflag = omode.c_cflag;
250 lflag = omode.c_lflag;
252 if (NP) {
253 CLR(cflag, CSIZE|PARENB);
254 SET(cflag, CS8);
255 CLR(iflag, ISTRIP|INPCK|IGNPAR);
256 } else if (AP || EP || OP) {
257 CLR(cflag, CSIZE);
258 SET(cflag, CS7|PARENB);
259 SET(iflag, ISTRIP);
260 if (OP && !EP) {
261 SET(iflag, INPCK|IGNPAR);
262 SET(cflag, PARODD);
263 if (AP)
264 CLR(iflag, INPCK);
265 } else if (EP && !OP) {
266 SET(iflag, INPCK|IGNPAR);
267 CLR(cflag, PARODD);
268 if (AP)
269 CLR(iflag, INPCK);
270 } else if (AP || (EP && OP)) {
271 CLR(iflag, INPCK|IGNPAR);
272 CLR(cflag, PARODD);
274 } /* else, leave as is */
276 #if 0
277 if (UC)
278 f |= LCASE;
279 #endif
281 if (HC)
282 SET(cflag, HUPCL);
283 else
284 CLR(cflag, HUPCL);
286 #if !defined(__minix)
287 if (MB)
288 SET(cflag, MDMBUF);
289 else
290 CLR(cflag, MDMBUF);
291 #endif /* !defined(__minix) */
293 if (NL) {
294 SET(iflag, ICRNL);
295 SET(oflag, ONLCR|OPOST);
296 } else {
297 CLR(iflag, ICRNL);
298 CLR(oflag, ONLCR);
301 #if !defined(__minix)
302 if (!HT)
303 SET(oflag, OXTABS|OPOST);
304 else
305 CLR(oflag, OXTABS);
306 #endif /* !defined(__minix) */
308 #ifdef XXX_DELAY
309 SET(f, delaybits());
310 #endif
312 if (n == 1) { /* read mode flags */
313 if (RW) {
314 iflag = 0;
315 CLR(oflag, OPOST);
316 CLR(cflag, CSIZE|PARENB);
317 SET(cflag, CS8);
318 lflag = 0;
319 } else {
320 CLR(lflag, ICANON);
322 goto out;
325 if (n == 0)
326 goto out;
328 #if 0
329 if (CB)
330 SET(f, CRTBS);
331 #endif
333 if (CE)
334 SET(lflag, ECHOE);
335 else
336 CLR(lflag, ECHOE);
338 #if !defined(__minix)
339 if (CK)
340 SET(lflag, ECHOKE);
341 else
342 CLR(lflag, ECHOKE);
344 if (PE)
345 SET(lflag, ECHOPRT);
346 else
347 CLR(lflag, ECHOPRT);
348 #endif /* !defined(__minix) */
350 if (EC)
351 SET(lflag, ECHO);
352 else
353 CLR(lflag, ECHO);
355 #if !defined(__minix)
356 if (XC)
357 SET(lflag, ECHOCTL);
358 else
359 CLR(lflag, ECHOCTL);
360 #endif /* !defined(__minix) */
362 if (DX)
363 SET(lflag, IXANY);
364 else
365 CLR(lflag, IXANY);
367 out:
368 tmode.c_iflag = iflag;
369 tmode.c_oflag = oflag;
370 tmode.c_cflag = cflag;
371 tmode.c_lflag = lflag;
374 #ifdef COMPAT_43
376 * Old TTY => termios, snatched from <sys/kern/tty_compat.c>
378 void
379 compatflags(long flags)
381 tcflag_t iflag, oflag, cflag, lflag;
383 iflag = BRKINT|ICRNL|IMAXBEL|IXON|IXANY;
384 oflag = OPOST|ONLCR|OXTABS;
385 cflag = CREAD;
386 lflag = ICANON|ISIG|IEXTEN;
388 if (ISSET(flags, TANDEM))
389 SET(iflag, IXOFF);
390 else
391 CLR(iflag, IXOFF);
392 if (ISSET(flags, ECHO))
393 SET(lflag, ECHO);
394 else
395 CLR(lflag, ECHO);
396 if (ISSET(flags, CRMOD)) {
397 SET(iflag, ICRNL);
398 SET(oflag, ONLCR);
399 } else {
400 CLR(iflag, ICRNL);
401 CLR(oflag, ONLCR);
403 if (ISSET(flags, XTABS))
404 SET(oflag, OXTABS);
405 else
406 CLR(oflag, OXTABS);
409 if (ISSET(flags, RAW)) {
410 iflag &= IXOFF;
411 CLR(lflag, ISIG|ICANON|IEXTEN);
412 CLR(cflag, PARENB);
413 } else {
414 SET(iflag, BRKINT|IXON|IMAXBEL);
415 SET(lflag, ISIG|IEXTEN);
416 if (ISSET(flags, CBREAK))
417 CLR(lflag, ICANON);
418 else
419 SET(lflag, ICANON);
420 switch (ISSET(flags, ANYP)) {
421 case 0:
422 CLR(cflag, PARENB);
423 break;
424 case ANYP:
425 SET(cflag, PARENB);
426 CLR(iflag, INPCK);
427 break;
428 case EVENP:
429 SET(cflag, PARENB);
430 SET(iflag, INPCK);
431 CLR(cflag, PARODD);
432 break;
433 case ODDP:
434 SET(cflag, PARENB);
435 SET(iflag, INPCK);
436 SET(cflag, PARODD);
437 break;
441 /* Nothing we can do with CRTBS. */
442 if (ISSET(flags, PRTERA))
443 SET(lflag, ECHOPRT);
444 else
445 CLR(lflag, ECHOPRT);
446 if (ISSET(flags, CRTERA))
447 SET(lflag, ECHOE);
448 else
449 CLR(lflag, ECHOE);
450 #if !defined(__minix)
451 /* Nothing we can do with TILDE. */
452 if (ISSET(flags, MDMBUF))
453 SET(cflag, MDMBUF);
454 else
455 CLR(cflag, MDMBUF);
456 #endif /* !defined(__minix) */
457 if (ISSET(flags, NOHANG))
458 CLR(cflag, HUPCL);
459 else
460 SET(cflag, HUPCL);
461 #if !defined(__minix)
462 if (ISSET(flags, CRTKIL))
463 SET(lflag, ECHOKE);
464 else
465 CLR(lflag, ECHOKE);
466 #endif /* !defined(__minix) */
467 if (ISSET(flags, CTLECH))
468 SET(lflag, ECHOCTL);
469 else
470 CLR(lflag, ECHOCTL);
471 if (!ISSET(flags, DECCTQ))
472 SET(iflag, IXANY);
473 else
474 CLR(iflag, IXANY);
475 CLR(lflag, TOSTOP|FLUSHO|PENDIN|NOFLSH);
476 SET(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH));
478 if (ISSET(flags, RAW|LITOUT|PASS8)) {
479 CLR(cflag, CSIZE);
480 SET(cflag, CS8);
481 if (!ISSET(flags, RAW|PASS8))
482 SET(iflag, ISTRIP);
483 else
484 CLR(iflag, ISTRIP);
485 if (!ISSET(flags, RAW|LITOUT))
486 SET(oflag, OPOST);
487 else
488 CLR(oflag, OPOST);
489 } else {
490 CLR(cflag, CSIZE);
491 SET(cflag, CS7);
492 SET(iflag, ISTRIP);
493 SET(oflag, OPOST);
496 tmode.c_iflag = iflag;
497 tmode.c_oflag = oflag;
498 tmode.c_cflag = cflag;
499 tmode.c_lflag = lflag;
501 #endif
503 #ifdef XXX_DELAY
504 struct delayval {
505 unsigned delay; /* delay in ms */
506 int bits;
510 * below are random guesses, I can't be bothered checking
513 struct delayval crdelay[] = {
514 { 1, CR1 },
515 { 2, CR2 },
516 { 3, CR3 },
517 { 83, CR1 },
518 { 166, CR2 },
519 { 0, CR3 },
522 struct delayval nldelay[] = {
523 { 1, NL1 }, /* special, calculated */
524 { 2, NL2 },
525 { 3, NL3 },
526 { 100, NL2 },
527 { 0, NL3 },
530 struct delayval bsdelay[] = {
531 { 1, BS1 },
532 { 0, 0 },
535 struct delayval ffdelay[] = {
536 { 1, FF1 },
537 { 1750, FF1 },
538 { 0, FF1 },
541 struct delayval tbdelay[] = {
542 { 1, TAB1 },
543 { 2, TAB2 },
544 { 3, XTABS }, /* this is expand tabs */
545 { 100, TAB1 },
546 { 0, TAB2 },
550 delaybits(void)
552 int f;
554 f = adelay(CD, crdelay);
555 f |= adelay(ND, nldelay);
556 f |= adelay(FD, ffdelay);
557 f |= adelay(TD, tbdelay);
558 f |= adelay(BD, bsdelay);
559 return (f);
563 adelay(int ms, struct delayval *dp)
565 if (ms == 0)
566 return (0);
567 while (dp->delay && ms > dp->delay)
568 dp++;
569 return (dp->bits);
571 #endif
573 char editedhost[MAXHOSTNAMELEN];
575 void
576 edithost(const char *pat)
578 char *host = HN;
579 char *res = editedhost;
581 if (!pat)
582 pat = "";
583 while (*pat) {
584 switch (*pat) {
586 case '#':
587 if (*host)
588 host++;
589 break;
591 case '@':
592 if (*host)
593 *res++ = *host++;
594 break;
596 default:
597 *res++ = *pat;
598 break;
601 if (res == &editedhost[sizeof editedhost - 1]) {
602 *res = '\0';
603 return;
605 pat++;
607 if (*host)
608 (void)strncpy(res, host,
609 sizeof editedhost - (res - editedhost) - 1);
610 else
611 *res = '\0';
612 editedhost[sizeof editedhost - 1] = '\0';
615 void
616 makeenv(char *env[])
618 static char termbuf[128] = "TERM=";
619 char *p, *q;
620 char **ep;
622 ep = env;
623 if (TT && *TT) {
624 (void)strlcat(termbuf, TT, sizeof(termbuf));
625 *ep++ = termbuf;
627 if ((p = EV) != NULL) {
628 q = p;
629 while ((q = strchr(q, ',')) != NULL) {
630 *q++ = '\0';
631 *ep++ = p;
632 p = q;
634 if (*p)
635 *ep++ = p;
637 *ep = (char *)0;
641 * This speed select mechanism is written for the Develcon DATASWITCH.
642 * The Develcon sends a string of the form "B{speed}\n" at a predefined
643 * baud rate. This string indicates the user's actual speed.
644 * The routine below returns the terminal type mapped from derived speed.
646 struct portselect {
647 const char *ps_baud;
648 const char *ps_type;
649 } portspeeds[] = {
650 { "B110", "std.110" },
651 { "B134", "std.134" },
652 { "B150", "std.150" },
653 { "B300", "std.300" },
654 { "B600", "std.600" },
655 { "B1200", "std.1200" },
656 { "B2400", "std.2400" },
657 { "B4800", "std.4800" },
658 { "B9600", "std.9600" },
659 { "B19200", "std.19200" },
660 { NULL, NULL }
663 const char *
664 portselector(void)
666 char c, baud[20];
667 const char *type = "default";
668 struct portselect *ps;
669 size_t len;
671 (void)alarm(5*60);
672 for (len = 0; len < sizeof (baud) - 1; len++) {
673 if (read(STDIN_FILENO, &c, 1) <= 0)
674 break;
675 c &= 0177;
676 if (c == '\n' || c == '\r')
677 break;
678 if (c == 'B')
679 len = 0; /* in case of leading garbage */
680 baud[len] = c;
682 baud[len] = '\0';
683 for (ps = portspeeds; ps->ps_baud; ps++)
684 if (strcmp(ps->ps_baud, baud) == 0) {
685 type = ps->ps_type;
686 break;
688 (void)sleep(2); /* wait for connection to complete */
689 return (type);
693 * This auto-baud speed select mechanism is written for the Micom 600
694 * portselector. Selection is done by looking at how the character '\r'
695 * is garbled at the different speeds.
697 #include <sys/time.h>
699 const char *
700 autobaud(void)
702 struct pollfd set[1];
703 struct timespec timeout;
704 char c;
705 const char *type = "9600-baud";
707 (void)tcflush(0, TCIOFLUSH);
708 set[0].fd = STDIN_FILENO;
709 set[0].events = POLLIN;
710 if (poll(set, 1, 5000) <= 0)
711 return (type);
712 if (read(STDIN_FILENO, &c, 1) != 1)
713 return (type);
714 timeout.tv_sec = 0;
715 timeout.tv_nsec = 20000;
716 (void)nanosleep(&timeout, NULL);
717 (void)tcflush(0, TCIOFLUSH);
718 switch (c & 0377) {
720 case 0200: /* 300-baud */
721 type = "300-baud";
722 break;
724 case 0346: /* 1200-baud */
725 type = "1200-baud";
726 break;
728 case 015: /* 2400-baud */
729 case 0215:
730 type = "2400-baud";
731 break;
733 default: /* 4800-baud */
734 type = "4800-baud";
735 break;
737 case 0377: /* 9600-baud */
738 type = "9600-baud";
739 break;
741 return (type);