xref: /netbsd-src/bin/stty/modes.c (revision 78d721faf95756f01ebf5690c6f226f7b60bdc3a)
1*78d721faSchristos /* $NetBSD: modes.c,v 1.18 2015/05/01 17:01:08 christos Exp $ */
249f0ad86Scgd 
361f28255Scgd /*-
4fe5a9095Smycroft  * Copyright (c) 1991, 1993, 1994
5fe5a9095Smycroft  *	The Regents of the University of California.  All rights reserved.
661f28255Scgd  *
761f28255Scgd  * Redistribution and use in source and binary forms, with or without
861f28255Scgd  * modification, are permitted provided that the following conditions
961f28255Scgd  * are met:
1061f28255Scgd  * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd  *    notice, this list of conditions and the following disclaimer.
1261f28255Scgd  * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd  *    notice, this list of conditions and the following disclaimer in the
1461f28255Scgd  *    documentation and/or other materials provided with the distribution.
15b5b29542Sagc  * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd  *    may be used to endorse or promote products derived from this software
1761f28255Scgd  *    without specific prior written permission.
1861f28255Scgd  *
1961f28255Scgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd  * SUCH DAMAGE.
3061f28255Scgd  */
3161f28255Scgd 
32e028842eSchristos #include <sys/cdefs.h>
3361f28255Scgd #ifndef lint
3449f0ad86Scgd #if 0
3549f0ad86Scgd static char sccsid[] = "@(#)modes.c	8.3 (Berkeley) 4/2/94";
3649f0ad86Scgd #else
37*78d721faSchristos __RCSID("$NetBSD: modes.c,v 1.18 2015/05/01 17:01:08 christos Exp $");
3849f0ad86Scgd #endif
3961f28255Scgd #endif /* not lint */
4061f28255Scgd 
4161f28255Scgd #include <sys/types.h>
4230b25d1cSperry 
4361f28255Scgd #include <stddef.h>
4461f28255Scgd #include <string.h>
45*78d721faSchristos #include <stdbool.h>
4630b25d1cSperry 
4761f28255Scgd #include "stty.h"
48e028842eSchristos #include "extern.h"
4961f28255Scgd 
5061f28255Scgd struct modes {
514f6f2f00Sjtc 	const char *name;
52*78d721faSchristos 	tcflag_t flag;
53*78d721faSchristos };
54*78d721faSchristos 
55*78d721faSchristos struct specialmodes {
56*78d721faSchristos 	const char *name;
57301199f5Smycroft 	tcflag_t set;
58301199f5Smycroft 	tcflag_t unset;
5961f28255Scgd };
6061f28255Scgd 
6161f28255Scgd /*
6261f28255Scgd  * The code in optlist() depends on minus options following regular
6361f28255Scgd  * options, i.e. "foo" must immediately precede "-foo".
6461f28255Scgd  */
654f6f2f00Sjtc const struct modes cmodes[] = {
66*78d721faSchristos 	{ "cstopb",	CSTOPB },
67*78d721faSchristos 	{ "cread",	CREAD },
68*78d721faSchristos 	{ "parenb",	PARENB },
69*78d721faSchristos 	{ "parodd",	PARODD },
70*78d721faSchristos 	{ "hupcl",	HUPCL },
71*78d721faSchristos 	{ "hup",	HUPCL },
72*78d721faSchristos 	{ "clocal",	CLOCAL },
73*78d721faSchristos 	{ "crtscts",	CRTSCTS },
74*78d721faSchristos 	{ "mdmbuf",	MDMBUF },
75*78d721faSchristos 	{ "cdtrcts",	CDTRCTS },
76*78d721faSchristos 	{ .name = NULL },
77*78d721faSchristos };
78*78d721faSchristos 
79*78d721faSchristos const struct specialmodes cspecialmodes[] = {
80fe5a9095Smycroft 	{ "cs5",	CS5, CSIZE },
81fe5a9095Smycroft 	{ "cs6",	CS6, CSIZE },
82fe5a9095Smycroft 	{ "cs7",	CS7, CSIZE },
83fe5a9095Smycroft 	{ "cs8",	CS8, CSIZE },
84fe5a9095Smycroft 	{ "parity",	PARENB | CS7, PARODD | CSIZE },
85fe5a9095Smycroft 	{ "-parity",	CS8, PARODD | PARENB | CSIZE },
86fe5a9095Smycroft 	{ "evenp",	PARENB | CS7, PARODD | CSIZE },
87fe5a9095Smycroft 	{ "-evenp",	CS8, PARODD | PARENB | CSIZE },
88fe5a9095Smycroft 	{ "oddp",	PARENB | CS7 | PARODD, CSIZE },
89fe5a9095Smycroft 	{ "-oddp",	CS8, PARODD | PARENB | CSIZE },
90fe5a9095Smycroft 	{ "pass8",	CS8, PARODD | PARENB | CSIZE },
91fe5a9095Smycroft 	{ "-pass8",	PARENB | CS7, PARODD | CSIZE },
9218243309Schristos 	{ .name = NULL },
9361f28255Scgd };
9461f28255Scgd 
954f6f2f00Sjtc const struct modes imodes[] = {
96*78d721faSchristos 	{ "ignbrk",	IGNBRK },
97*78d721faSchristos 	{ "brkint",	BRKINT },
98*78d721faSchristos 	{ "ignpar",	IGNPAR },
99*78d721faSchristos 	{ "parmrk",	PARMRK },
100*78d721faSchristos 	{ "inpck",	INPCK },
101*78d721faSchristos 	{ "istrip",	ISTRIP },
102*78d721faSchristos 	{ "inlcr",	INLCR },
103*78d721faSchristos 	{ "igncr",	IGNCR },
104*78d721faSchristos 	{ "icrnl",	ICRNL },
105*78d721faSchristos 	{ "ixon",	IXON },
106*78d721faSchristos 	{ "flow",	IXON },
107*78d721faSchristos 	{ "ixoff",	IXOFF },
108*78d721faSchristos 	{ "tandem",	IXOFF },
109*78d721faSchristos 	{ "ixany",	IXANY },
110*78d721faSchristos 	{ "imaxbel",	IMAXBEL },
111*78d721faSchristos 	{ .name = NULL },
112*78d721faSchristos };
113*78d721faSchristos 
114*78d721faSchristos const struct specialmodes ispecialmodes[] = {
115fe5a9095Smycroft 	{ "decctlq",	0, IXANY },
116fe5a9095Smycroft 	{ "-decctlq",	IXANY, 0 },
11718243309Schristos 	{ .name = NULL },
11861f28255Scgd };
11961f28255Scgd 
1204f6f2f00Sjtc const struct modes lmodes[] = {
121*78d721faSchristos 	{ "echo",	ECHO },
122*78d721faSchristos 	{ "echoe",	ECHOE },
123*78d721faSchristos 	{ "crterase",	ECHOE },
124*78d721faSchristos 	{ "crtbs",	ECHOE },	/* crtbs not supported, close enough */
125*78d721faSchristos 	{ "echok",	ECHOK },
126*78d721faSchristos 	{ "echoke",	ECHOKE },
127*78d721faSchristos 	{ "crtkill",	ECHOKE },
128*78d721faSchristos 	{ "altwerase",	ALTWERASE },
129*78d721faSchristos 	{ "iexten",	IEXTEN },
130*78d721faSchristos 	{ "echonl",	ECHONL },
131*78d721faSchristos 	{ "echoctl",	ECHOCTL },
132*78d721faSchristos 	{ "ctlecho",	ECHOCTL },
133*78d721faSchristos 	{ "echoprt",	ECHOPRT },
134*78d721faSchristos 	{ "prterase",	ECHOPRT },
135*78d721faSchristos 	{ "isig",	ISIG },
136*78d721faSchristos 	{ "icanon",	ICANON },
137*78d721faSchristos 	{ "noflsh",	NOFLSH },
138*78d721faSchristos 	{ "tostop",	TOSTOP },
139*78d721faSchristos 	{ "flusho",	FLUSHO },
140*78d721faSchristos 	{ "pendin",	PENDIN },
141*78d721faSchristos 	{ "nokerninfo",	NOKERNINFO },
142*78d721faSchristos 	{ .name = NULL },
143*78d721faSchristos };
144*78d721faSchristos 
145*78d721faSchristos const struct specialmodes lspecialmodes[] = {
146fe5a9095Smycroft 	{ "crt",	ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT },
147fe5a9095Smycroft 	{ "-crt",	ECHOK, ECHOE|ECHOKE|ECHOCTL },
148fe5a9095Smycroft 	{ "newcrt",	ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT },
149fe5a9095Smycroft 	{ "-newcrt",	ECHOK, ECHOE|ECHOKE|ECHOCTL },
150fe5a9095Smycroft 	{ "kerninfo",	0, NOKERNINFO },
151fe5a9095Smycroft 	{ "-kerninfo",	NOKERNINFO, 0 },
15218243309Schristos 	{ .name = NULL },
15361f28255Scgd };
15461f28255Scgd 
1554f6f2f00Sjtc const struct modes omodes[] = {
156*78d721faSchristos 	{ "opost",	OPOST },
157*78d721faSchristos 	{ "onlcr",	ONLCR },
158*78d721faSchristos 	{ "ocrnl",	OCRNL },
159*78d721faSchristos 	{ "oxtabs",	OXTABS },
160*78d721faSchristos 	{ "onocr",	ONOCR },
161*78d721faSchristos 	{ "onlret",	ONLRET },
162*78d721faSchristos 	{ .name = NULL },
163*78d721faSchristos };
164*78d721faSchristos 
165*78d721faSchristos const struct specialmodes ospecialmodes[] = {
166fe5a9095Smycroft 	{ "litout",	0, OPOST },
167fe5a9095Smycroft 	{ "-litout",	OPOST, 0 },
168fe5a9095Smycroft 	{ "tabs",	0, OXTABS },		/* "preserve" tabs */
169fe5a9095Smycroft 	{ "-tabs",	OXTABS, 0 },
17018243309Schristos 	{ .name = NULL },
17161f28255Scgd };
17261f28255Scgd 
1734f6f2f00Sjtc #define	CHK(s)	(!strcmp(name, s))
17461f28255Scgd 
175*78d721faSchristos static int
modeset(const char * name,const struct modes * mp,const struct specialmodes * smp,tcflag_t * f)176*78d721faSchristos modeset(const char *name, const struct modes *mp,
177*78d721faSchristos     const struct specialmodes *smp, tcflag_t *f)
178*78d721faSchristos {
179*78d721faSchristos 	bool neg;
180*78d721faSchristos 
181*78d721faSchristos 	for (; smp->name; ++smp)
182*78d721faSchristos 		if (CHK(smp->name)) {
183*78d721faSchristos 			*f &= ~smp->unset;
184*78d721faSchristos 			*f |= smp->set;
185*78d721faSchristos 			return 1;
186*78d721faSchristos 		}
187*78d721faSchristos 
188*78d721faSchristos 	if ((neg = (*name == '-')))
189*78d721faSchristos 		name++;
190*78d721faSchristos 
191*78d721faSchristos 	for (; mp->name; ++mp)
192*78d721faSchristos 		if (CHK(mp->name)) {
193*78d721faSchristos 			if (neg)
194*78d721faSchristos 				*f &= ~mp->flag;
195*78d721faSchristos 			else
196*78d721faSchristos 				*f |= mp->flag;
197*78d721faSchristos 			return 1;
198*78d721faSchristos 		}
199*78d721faSchristos 
200*78d721faSchristos 	return 0;
201*78d721faSchristos }
202*78d721faSchristos 
203fe5a9095Smycroft int
msearch(char *** argvp,struct info * ip)20430b25d1cSperry msearch(char ***argvp, struct info *ip)
20561f28255Scgd {
206*78d721faSchristos 	const char *name = **argvp;
20761f28255Scgd 
208*78d721faSchristos 	if (modeset(name, cmodes, cspecialmodes, &ip->t.c_cflag))
209*78d721faSchristos 		goto out;
21061f28255Scgd 
211*78d721faSchristos 	if (modeset(name, imodes, ispecialmodes, &ip->t.c_iflag))
212*78d721faSchristos 		goto out;
213*78d721faSchristos 
214*78d721faSchristos 	if (modeset(name, lmodes, lspecialmodes, &ip->t.c_lflag))
215*78d721faSchristos 		goto out;
216*78d721faSchristos 
217*78d721faSchristos 	if (modeset(name, omodes, ospecialmodes, &ip->t.c_oflag))
218*78d721faSchristos 		goto out;
219*78d721faSchristos 
220*78d721faSchristos 	return 0;
221*78d721faSchristos out:
22261f28255Scgd 	ip->set = 1;
223*78d721faSchristos 	return 1;
22461f28255Scgd }
225