1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1980, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
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.
18 *
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.
30 */
31
32#include <sys/param.h>
33#include <sys/ioctl.h>
34#include <sys/time.h>
35#include <sys/resource.h>
36#include <sys/stat.h>
37#include <sys/ttydefaults.h>
38#include <sys/utsname.h>
39
40#include <ctype.h>
41#include <errno.h>
42#include <fcntl.h>
43#include <locale.h>
44#include <libutil.h>
45#include <setjmp.h>
46#include <signal.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <string.h>
50#include <syslog.h>
51#include <termios.h>
52#include <time.h>
53#include <unistd.h>
54
55#include "gettytab.h"
56#include "extern.h"
57#include "pathnames.h"
58
59/*
60 * Set the amount of running time that getty should accumulate
61 * before deciding that something is wrong and exit.
62 */
63#define GETTY_TIMEOUT	60 /* seconds */
64
65#undef CTRL
66#define CTRL(x)  (x&037)
67
68/* defines for auto detection of incoming PPP calls (->PAP/CHAP) */
69
70#define PPP_FRAME           0x7e  /* PPP Framing character */
71#define PPP_STATION         0xff  /* "All Station" character */
72#define PPP_ESCAPE          0x7d  /* Escape Character */
73#define PPP_CONTROL         0x03  /* PPP Control Field */
74#define PPP_CONTROL_ESCAPED 0x23  /* PPP Control Field, escaped */
75#define PPP_LCP_HI          0xc0  /* LCP protocol - high byte */
76#define PPP_LCP_LOW         0x21  /* LCP protocol - low byte */
77
78/* original mode; flags've been reset using values from <sys/ttydefaults.h> */
79struct termios omode;
80/* current mode */
81struct termios tmode;
82
83static int crmod, digit, lower, upper;
84
85char	hostname[MAXHOSTNAMELEN];
86static char	name[MAXLOGNAME*3];
87static char	ttyn[32];
88
89#define	OBUFSIZ		128
90
91static const char	*tname;
92
93static char	*env[128];
94
95static char partab[] = {
96	0001,0201,0201,0001,0201,0001,0001,0201,
97	0202,0004,0003,0205,0005,0206,0201,0001,
98	0201,0001,0001,0201,0001,0201,0201,0001,
99	0001,0201,0201,0001,0201,0001,0001,0201,
100	0200,0000,0000,0200,0000,0200,0200,0000,
101	0000,0200,0200,0000,0200,0000,0000,0200,
102	0000,0200,0200,0000,0200,0000,0000,0200,
103	0200,0000,0000,0200,0000,0200,0200,0000,
104	0200,0000,0000,0200,0000,0200,0200,0000,
105	0000,0200,0200,0000,0200,0000,0000,0200,
106	0000,0200,0200,0000,0200,0000,0000,0200,
107	0200,0000,0000,0200,0000,0200,0200,0000,
108	0000,0200,0200,0000,0200,0000,0000,0200,
109	0200,0000,0000,0200,0000,0200,0200,0000,
110	0200,0000,0000,0200,0000,0200,0200,0000,
111	0000,0200,0200,0000,0200,0000,0000,0201
112};
113
114#define	ERASE	tmode.c_cc[VERASE]
115#define	KILL	tmode.c_cc[VKILL]
116#define	EOT	tmode.c_cc[VEOF]
117
118#define	puts	Gputs
119
120static void	defttymode(void);
121static void	dingdong(int);
122static void	dogettytab(void);
123static int	getname(void);
124static void	interrupt(int);
125static void	oflush(void);
126static void	prompt(void);
127static void	putchr(int);
128static void	putf(const char *);
129static void	putpad(const char *);
130static void	puts(const char *);
131static void	timeoverrun(int);
132static char	*get_line(int);
133static void	setttymode(int);
134static int	opentty(const char *, int);
135
136static jmp_buf timeout;
137
138static void
139dingdong(int signo __unused)
140{
141	alarm(0);
142	longjmp(timeout, 1);
143}
144
145static jmp_buf	intrupt;
146
147static void
148interrupt(int signo __unused)
149{
150	longjmp(intrupt, 1);
151}
152
153/*
154 * Action to take when getty is running too long.
155 */
156static void
157timeoverrun(int signo __unused)
158{
159
160	syslog(LOG_ERR, "getty exiting due to excessive running time");
161	exit(1);
162}
163
164int
165main(int argc, char *argv[])
166{
167	int first_sleep = 1, first_time = 1;
168	struct rlimit limit;
169	int rval;
170
171	signal(SIGINT, SIG_IGN);
172	signal(SIGQUIT, SIG_IGN);
173
174	openlog("getty", LOG_CONS|LOG_PID, LOG_AUTH);
175	gethostname(hostname, sizeof(hostname) - 1);
176	hostname[sizeof(hostname) - 1] = '\0';
177	if (hostname[0] == '\0')
178		snprintf(hostname, sizeof(hostname), "Amnesiac");
179
180	/*
181	 * Limit running time to deal with broken or dead lines.
182	 */
183	(void)signal(SIGXCPU, timeoverrun);
184	limit.rlim_max = RLIM_INFINITY;
185	limit.rlim_cur = GETTY_TIMEOUT;
186	(void)setrlimit(RLIMIT_CPU, &limit);
187
188	gettable("default");
189	gendefaults();
190	tname = "default";
191	if (argc > 1)
192		tname = argv[1];
193
194	/*
195	 * The following is a work around for vhangup interactions
196	 * which cause great problems getting window systems started.
197	 * If the tty line is "-", we do the old style getty presuming
198	 * that the file descriptors are already set up for us.
199	 * J. Gettys - MIT Project Athena.
200	 */
201	if (argc <= 2 || strcmp(argv[2], "-") == 0) {
202		char *n = ttyname(STDIN_FILENO);
203		if (n == NULL) {
204			syslog(LOG_ERR, "ttyname: %m");
205			exit(1);
206		}
207		snprintf(ttyn, sizeof(ttyn), "%s", n);
208	} else {
209		snprintf(ttyn, sizeof(ttyn), "%s%s", _PATH_DEV, argv[2]);
210		if (strcmp(argv[0], "+") != 0) {
211			chown(ttyn, 0, 0);
212			chmod(ttyn, 0600);
213			revoke(ttyn);
214
215			/*
216			 * Do the first scan through gettytab.
217			 * Terminal mode parameters will be wrong until
218			 * defttymode() called, but they're irrelevant for
219			 * the initial setup of the terminal device.
220			 */
221			dogettytab();
222
223			/*
224			 * Init or answer modem sequence has been specified.
225			 */
226			if (IC || AC) {
227				if (!opentty(ttyn, O_RDWR|O_NONBLOCK))
228					exit(1);
229				defttymode();
230				setttymode(1);
231			}
232
233			if (IC) {
234				if (getty_chat(IC, CT, DC) > 0) {
235					syslog(LOG_ERR, "modem init problem on %s", ttyn);
236					(void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
237					exit(1);
238				}
239			}
240
241			if (AC) {
242				fd_set rfds;
243				struct timeval to;
244				int i;
245
246				FD_ZERO(&rfds);
247				FD_SET(0, &rfds);
248				to.tv_sec = RT;
249				to.tv_usec = 0;
250				i = select(32, &rfds, NULL, NULL, RT ? &to : NULL);
251				if (i < 0) {
252					syslog(LOG_ERR, "select %s: %m", ttyn);
253				} else if (i == 0) {
254					syslog(LOG_NOTICE, "recycle tty %s", ttyn);
255					(void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
256					exit(0);  /* recycle for init */
257				}
258				i = getty_chat(AC, CT, DC);
259				if (i > 0) {
260					syslog(LOG_ERR, "modem answer problem on %s", ttyn);
261					(void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
262					exit(1);
263				}
264			} else { /* maybe blocking open */
265				if (!opentty(ttyn, O_RDWR | (NC ? O_NONBLOCK : 0 )))
266					exit(1);
267			}
268		}
269	}
270
271	defttymode();
272	for (;;) {
273
274		/*
275		 * if a delay was specified then sleep for that
276		 * number of seconds before writing the initial prompt
277		 */
278		if (first_sleep && DE) {
279			sleep(DE);
280			/* remove any noise */
281			(void)tcflush(STDIN_FILENO, TCIOFLUSH);
282		}
283		first_sleep = 0;
284
285		setttymode(0);
286		if (AB) {
287			tname = autobaud();
288			dogettytab();
289			continue;
290		}
291		if (PS) {
292			tname = portselector();
293			dogettytab();
294			continue;
295		}
296		if (CL && *CL)
297			putpad(CL);
298		edithost(HE);
299
300		/* if this is the first time through this, and an
301		   issue file has been given, then send it */
302		if (first_time && IF) {
303			int fd;
304
305			if ((fd = open(IF, O_RDONLY)) != -1) {
306				char * cp;
307
308				while ((cp = get_line(fd)) != NULL) {
309					putf(cp);
310				}
311				close(fd);
312			}
313		}
314		first_time = 0;
315
316		if (IMP && *IMP && !(PL && PP))
317			system(IMP);
318		if (IM && *IM && !(PL && PP))
319			putf(IM);
320		if (setjmp(timeout)) {
321			cfsetispeed(&tmode, B0);
322			cfsetospeed(&tmode, B0);
323			(void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
324			exit(1);
325		}
326		if (TO) {
327			signal(SIGALRM, dingdong);
328			alarm(TO);
329		}
330
331		rval = 0;
332		if (AL) {
333			const char *p = AL;
334			char *q = name;
335
336			while (*p && q < &name[sizeof name - 1]) {
337				if (isupper(*p))
338					upper = 1;
339				else if (islower(*p))
340					lower = 1;
341				else if (isdigit(*p))
342					digit = 1;
343				*q++ = *p++;
344			}
345		} else if (!(PL && PP))
346			rval = getname();
347		if (rval == 2 || (PL && PP)) {
348			oflush();
349			alarm(0);
350			limit.rlim_max = RLIM_INFINITY;
351			limit.rlim_cur = RLIM_INFINITY;
352			(void)setrlimit(RLIMIT_CPU, &limit);
353			execle(PP, "ppplogin", ttyn, (char *) 0, env);
354			syslog(LOG_ERR, "%s: %m", PP);
355			exit(1);
356		} else if (rval || AL) {
357			int i;
358
359			oflush();
360			alarm(0);
361			signal(SIGALRM, SIG_DFL);
362			if (name[0] == '\0')
363				continue;
364			if (name[0] == '-') {
365				puts("user names may not start with '-'.");
366				continue;
367			}
368			if (!(upper || lower || digit)) {
369				if (AL) {
370					syslog(LOG_ERR,
371					    "invalid auto-login name: %s", AL);
372					exit(1);
373				} else
374					continue;
375			}
376			set_flags(2);
377			if (crmod) {
378				tmode.c_iflag |= ICRNL;
379				tmode.c_oflag |= ONLCR;
380			}
381#if REALLY_OLD_TTYS
382			if (upper || UC)
383				tmode.sg_flags |= LCASE;
384			if (lower || LC)
385				tmode.sg_flags &= ~LCASE;
386#endif
387			if (tcsetattr(STDIN_FILENO, TCSANOW, &tmode) < 0) {
388				syslog(LOG_ERR, "tcsetattr %s: %m", ttyn);
389				exit(1);
390			}
391			signal(SIGINT, SIG_DFL);
392			for (i = 0; environ[i] != (char *)0; i++)
393				env[i] = environ[i];
394			makeenv(&env[i]);
395
396			limit.rlim_max = RLIM_INFINITY;
397			limit.rlim_cur = RLIM_INFINITY;
398			(void)setrlimit(RLIMIT_CPU, &limit);
399			execle(LO, "login", AL ? "-fp" : "-p", name,
400			    (char *) 0, env);
401			syslog(LOG_ERR, "%s: %m", LO);
402			exit(1);
403		}
404		alarm(0);
405		signal(SIGALRM, SIG_DFL);
406		signal(SIGINT, SIG_IGN);
407		if (NX && *NX) {
408			tname = NX;
409			dogettytab();
410		}
411	}
412}
413
414static int
415opentty(const char *tty, int flags)
416{
417	int failopenlogged = 0, i, saved_errno;
418
419	while ((i = open(tty, flags)) == -1)
420	{
421		saved_errno = errno;
422		if (!failopenlogged) {
423			syslog(LOG_ERR, "open %s: %m", tty);
424			failopenlogged = 1;
425		}
426		if (saved_errno == ENOENT)
427			return 0;
428		sleep(60);
429	}
430	if (login_tty(i) < 0) {
431		if (daemon(0,0) < 0) {
432			syslog(LOG_ERR,"daemon: %m");
433			close(i);
434			return 0;
435		}
436		if (login_tty(i) < 0) {
437			syslog(LOG_ERR, "login_tty %s: %m", tty);
438			close(i);
439			return 0;
440		}
441	}
442	return 1;
443}
444
445static void
446defttymode(void)
447{
448	struct termios def;
449
450	/* Start with default tty settings. */
451	if (tcgetattr(STDIN_FILENO, &tmode) < 0) {
452		syslog(LOG_ERR, "tcgetattr %s: %m", ttyn);
453		exit(1);
454	}
455	omode = tmode; /* fill c_cc for dogettytab() */
456	dogettytab();
457	/*
458	 * Don't rely on the driver too much, and initialize crucial
459	 * things according to <sys/ttydefaults.h>.  Avoid clobbering
460	 * the c_cc[] settings however, the console drivers might wish
461	 * to leave their idea of the preferred VERASE key value
462	 * there.
463	 */
464	cfmakesane(&def);
465	tmode.c_iflag = def.c_iflag;
466	tmode.c_oflag = def.c_oflag;
467	tmode.c_lflag = def.c_lflag;
468	tmode.c_cflag = def.c_cflag;
469	if (NC)
470		tmode.c_cflag |= CLOCAL;
471	omode = tmode;
472}
473
474static void
475setttymode(int raw)
476{
477	int off = 0;
478
479	(void)tcflush(STDIN_FILENO, TCIOFLUSH);	/* clear out the crap */
480	ioctl(STDIN_FILENO, FIONBIO, &off);	/* turn off non-blocking mode */
481	ioctl(STDIN_FILENO, FIOASYNC, &off);	/* ditto for async mode */
482
483	if (IS)
484		cfsetispeed(&tmode, speed(IS));
485	else if (SP)
486		cfsetispeed(&tmode, speed(SP));
487	if (OS)
488		cfsetospeed(&tmode, speed(OS));
489	else if (SP)
490		cfsetospeed(&tmode, speed(SP));
491	set_flags(0);
492	setchars();
493	if (raw)
494		cfmakeraw(&tmode);
495	if (tcsetattr(STDIN_FILENO, TCSANOW, &tmode) < 0) {
496		syslog(LOG_ERR, "tcsetattr %s: %m", ttyn);
497		exit(1);
498	}
499}
500
501
502static int
503getname(void)
504{
505	int c;
506	char *np;
507	unsigned char cs;
508	int ppp_state = 0;
509	int ppp_connection = 0;
510
511	/*
512	 * Interrupt may happen if we use CBREAK mode
513	 */
514	if (setjmp(intrupt)) {
515		signal(SIGINT, SIG_IGN);
516		return (0);
517	}
518	signal(SIGINT, interrupt);
519	set_flags(1);
520	prompt();
521	oflush();
522	if (PF > 0) {
523		sleep(PF);
524		PF = 0;
525	}
526	if (tcsetattr(STDIN_FILENO, TCSANOW, &tmode) < 0) {
527		syslog(LOG_ERR, "%s: %m", ttyn);
528		exit(1);
529	}
530	crmod = digit = lower = upper = 0;
531	np = name;
532	for (;;) {
533		oflush();
534		if (read(STDIN_FILENO, &cs, 1) <= 0)
535			exit(0);
536		if ((c = cs&0177) == 0)
537			return (0);
538
539		/* PPP detection state machine..
540		   Look for sequences:
541		   PPP_FRAME, PPP_STATION, PPP_ESCAPE, PPP_CONTROL_ESCAPED or
542		   PPP_FRAME, PPP_STATION, PPP_CONTROL (deviant from RFC)
543		   See RFC1662.
544		   Derived from code from Michael Hancock, <michaelh@cet.co.jp>
545		   and Erik 'PPP' Olson, <eriko@wrq.com>
546		*/
547
548		if (PP && (cs == PPP_FRAME)) {
549			ppp_state = 1;
550		} else if (ppp_state == 1 && cs == PPP_STATION) {
551			ppp_state = 2;
552		} else if (ppp_state == 2 && cs == PPP_ESCAPE) {
553			ppp_state = 3;
554		} else if ((ppp_state == 2 && cs == PPP_CONTROL)
555		    || (ppp_state == 3 && cs == PPP_CONTROL_ESCAPED)) {
556			ppp_state = 4;
557		} else if (ppp_state == 4 && cs == PPP_LCP_HI) {
558			ppp_state = 5;
559		} else if (ppp_state == 5 && cs == PPP_LCP_LOW) {
560			ppp_connection = 1;
561			break;
562		} else {
563			ppp_state = 0;
564		}
565
566		if (c == EOT || c == CTRL('d'))
567			exit(0);
568		if (c == '\r' || c == '\n' || np >= &name[sizeof name-1]) {
569			putf("\r\n");
570			break;
571		}
572		if (islower(c))
573			lower = 1;
574		else if (isupper(c))
575			upper = 1;
576		else if (c == ERASE || c == '\b' || c == 0177) {
577			if (np > name) {
578				np--;
579				if (cfgetospeed(&tmode) >= 1200)
580					puts("\b \b");
581				else
582					putchr(cs);
583			}
584			continue;
585		} else if (c == KILL || c == CTRL('u')) {
586			putchr('\r');
587			if (cfgetospeed(&tmode) < 1200)
588				putchr('\n');
589			/* this is the way they do it down under ... */
590			else if (np > name)
591				puts("                                     \r");
592			prompt();
593			digit = lower = upper = 0;
594			np = name;
595			continue;
596		} else if (isdigit(c))
597			digit = 1;
598		if (IG && (c <= ' ' || c > 0176))
599			continue;
600		*np++ = c;
601		putchr(cs);
602	}
603	signal(SIGINT, SIG_IGN);
604	*np = 0;
605	if (c == '\r')
606		crmod = 1;
607	if ((upper && !lower && !LC) || UC)
608		for (np = name; *np; np++)
609			if (isupper(*np))
610				*np = tolower(*np);
611	return (1 + ppp_connection);
612}
613
614static void
615putpad(const char *s)
616{
617	int pad = 0;
618	speed_t ospeed = cfgetospeed(&tmode);
619
620	if (isdigit(*s)) {
621		while (isdigit(*s)) {
622			pad *= 10;
623			pad += *s++ - '0';
624		}
625		pad *= 10;
626		if (*s == '.' && isdigit(s[1])) {
627			pad += s[1] - '0';
628			s += 2;
629		}
630	}
631
632	puts(s);
633	/*
634	 * If no delay needed, or output speed is
635	 * not comprehensible, then don't try to delay.
636	 */
637	if (pad == 0 || ospeed <= 0)
638		return;
639
640	/*
641	 * Round up by a half a character frame, and then do the delay.
642	 * Too bad there are no user program accessible programmed delays.
643	 * Transmitting pad characters slows many terminals down and also
644	 * loads the system.
645	 */
646	pad = (pad * ospeed + 50000) / 100000;
647	while (pad--)
648		putchr(*PC);
649}
650
651static void
652puts(const char *s)
653{
654	while (*s)
655		putchr(*s++);
656}
657
658static char	outbuf[OBUFSIZ];
659static int	obufcnt = 0;
660
661static void
662putchr(int cc)
663{
664	char c;
665
666	c = cc;
667	if (!NP) {
668		c |= partab[c&0177] & 0200;
669		if (OP)
670			c ^= 0200;
671	}
672	if (!UB) {
673		outbuf[obufcnt++] = c;
674		if (obufcnt >= OBUFSIZ)
675			oflush();
676	} else
677		write(STDOUT_FILENO, &c, 1);
678}
679
680static void
681oflush(void)
682{
683	if (obufcnt)
684		write(STDOUT_FILENO, outbuf, obufcnt);
685	obufcnt = 0;
686}
687
688static void
689prompt(void)
690{
691
692	putf(LM);
693	if (CO)
694		putchr('\n');
695}
696
697
698static char *
699get_line(int fd)
700{
701	size_t i = 0;
702	static char linebuf[512];
703
704	/*
705	 * This is certainly slow, but it avoids having to include
706	 * stdio.h unnecessarily. Issue files should be small anyway.
707	 */
708	while (i < (sizeof linebuf - 3) && read(fd, linebuf+i, 1)==1) {
709		if (linebuf[i] == '\n') {
710			/* Don't rely on newline mode, assume raw */
711			linebuf[i++] = '\r';
712			linebuf[i++] = '\n';
713			linebuf[i] = '\0';
714			return linebuf;
715		}
716		++i;
717	}
718	linebuf[i] = '\0';
719	return i ? linebuf : 0;
720}
721
722static void
723putf(const char *cp)
724{
725	time_t t;
726	char db[100];
727	const char *slash;
728
729	static struct utsname kerninfo;
730
731	if (!*kerninfo.sysname)
732		uname(&kerninfo);
733
734	while (*cp) {
735		if (*cp != '%') {
736			putchr(*cp++);
737			continue;
738		}
739		switch (*++cp) {
740
741		case 't':
742			slash = strrchr(ttyn, '/');
743			if (slash == (char *) 0)
744				puts(ttyn);
745			else
746				puts(&slash[1]);
747			break;
748
749		case 'h':
750			puts(editedhost);
751			break;
752
753		case 'd':
754			t = (time_t)0;
755			(void)time(&t);
756			if (Lo)
757				(void)setlocale(LC_TIME, Lo);
758			(void)strftime(db, sizeof(db), DF, localtime(&t));
759			puts(db);
760			break;
761
762		case 's':
763			puts(kerninfo.sysname);
764			break;
765
766		case 'm':
767			puts(kerninfo.machine);
768			break;
769
770		case 'r':
771			puts(kerninfo.release);
772			break;
773
774		case 'v':
775			puts(kerninfo.version);
776			break;
777
778		case '%':
779			putchr('%');
780			break;
781		}
782		cp++;
783	}
784}
785
786/*
787 * Read a gettytab database entry and perform necessary quirks.
788 */
789static void
790dogettytab(void)
791{
792
793	/* Read the database entry. */
794	gettable(tname);
795
796	/*
797	 * Avoid inheriting the parity values from the default entry
798	 * if any of them is set in the current entry.
799	 * Mixing different parity settings is unreasonable.
800	 */
801	if (OPset || EPset || APset || NPset)
802		OPset = EPset = APset = NPset = 1;
803
804	/* Fill in default values for unset capabilities. */
805	setdefaults();
806}
807