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