Home | History | Annotate | Line # | Download | only in stty
      1 /* $NetBSD: modes.c,v 1.18 2015/05/01 17:01:08 christos Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 1991, 1993, 1994
      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/cdefs.h>
     33 #ifndef lint
     34 #if 0
     35 static char sccsid[] = "@(#)modes.c	8.3 (Berkeley) 4/2/94";
     36 #else
     37 __RCSID("$NetBSD: modes.c,v 1.18 2015/05/01 17:01:08 christos Exp $");
     38 #endif
     39 #endif /* not lint */
     40 
     41 #include <sys/types.h>
     42 
     43 #include <stddef.h>
     44 #include <string.h>
     45 #include <stdbool.h>
     46 
     47 #include "stty.h"
     48 #include "extern.h"
     49 
     50 struct modes {
     51 	const char *name;
     52 	tcflag_t flag;
     53 };
     54 
     55 struct specialmodes {
     56 	const char *name;
     57 	tcflag_t set;
     58 	tcflag_t unset;
     59 };
     60 
     61 /*
     62  * The code in optlist() depends on minus options following regular
     63  * options, i.e. "foo" must immediately precede "-foo".
     64  */
     65 const struct modes cmodes[] = {
     66 	{ "cstopb",	CSTOPB },
     67 	{ "cread",	CREAD },
     68 	{ "parenb",	PARENB },
     69 	{ "parodd",	PARODD },
     70 	{ "hupcl",	HUPCL },
     71 	{ "hup",	HUPCL },
     72 	{ "clocal",	CLOCAL },
     73 	{ "crtscts",	CRTSCTS },
     74 	{ "mdmbuf",	MDMBUF },
     75 	{ "cdtrcts",	CDTRCTS },
     76 	{ .name = NULL },
     77 };
     78 
     79 const struct specialmodes cspecialmodes[] = {
     80 	{ "cs5",	CS5, CSIZE },
     81 	{ "cs6",	CS6, CSIZE },
     82 	{ "cs7",	CS7, CSIZE },
     83 	{ "cs8",	CS8, CSIZE },
     84 	{ "parity",	PARENB | CS7, PARODD | CSIZE },
     85 	{ "-parity",	CS8, PARODD | PARENB | CSIZE },
     86 	{ "evenp",	PARENB | CS7, PARODD | CSIZE },
     87 	{ "-evenp",	CS8, PARODD | PARENB | CSIZE },
     88 	{ "oddp",	PARENB | CS7 | PARODD, CSIZE },
     89 	{ "-oddp",	CS8, PARODD | PARENB | CSIZE },
     90 	{ "pass8",	CS8, PARODD | PARENB | CSIZE },
     91 	{ "-pass8",	PARENB | CS7, PARODD | CSIZE },
     92 	{ .name = NULL },
     93 };
     94 
     95 const struct modes imodes[] = {
     96 	{ "ignbrk",	IGNBRK },
     97 	{ "brkint",	BRKINT },
     98 	{ "ignpar",	IGNPAR },
     99 	{ "parmrk",	PARMRK },
    100 	{ "inpck",	INPCK },
    101 	{ "istrip",	ISTRIP },
    102 	{ "inlcr",	INLCR },
    103 	{ "igncr",	IGNCR },
    104 	{ "icrnl",	ICRNL },
    105 	{ "ixon",	IXON },
    106 	{ "flow",	IXON },
    107 	{ "ixoff",	IXOFF },
    108 	{ "tandem",	IXOFF },
    109 	{ "ixany",	IXANY },
    110 	{ "imaxbel",	IMAXBEL },
    111 	{ .name = NULL },
    112 };
    113 
    114 const struct specialmodes ispecialmodes[] = {
    115 	{ "decctlq",	0, IXANY },
    116 	{ "-decctlq",	IXANY, 0 },
    117 	{ .name = NULL },
    118 };
    119 
    120 const struct modes lmodes[] = {
    121 	{ "echo",	ECHO },
    122 	{ "echoe",	ECHOE },
    123 	{ "crterase",	ECHOE },
    124 	{ "crtbs",	ECHOE },	/* crtbs not supported, close enough */
    125 	{ "echok",	ECHOK },
    126 	{ "echoke",	ECHOKE },
    127 	{ "crtkill",	ECHOKE },
    128 	{ "altwerase",	ALTWERASE },
    129 	{ "iexten",	IEXTEN },
    130 	{ "echonl",	ECHONL },
    131 	{ "echoctl",	ECHOCTL },
    132 	{ "ctlecho",	ECHOCTL },
    133 	{ "echoprt",	ECHOPRT },
    134 	{ "prterase",	ECHOPRT },
    135 	{ "isig",	ISIG },
    136 	{ "icanon",	ICANON },
    137 	{ "noflsh",	NOFLSH },
    138 	{ "tostop",	TOSTOP },
    139 	{ "flusho",	FLUSHO },
    140 	{ "pendin",	PENDIN },
    141 	{ "nokerninfo",	NOKERNINFO },
    142 	{ .name = NULL },
    143 };
    144 
    145 const struct specialmodes lspecialmodes[] = {
    146 	{ "crt",	ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT },
    147 	{ "-crt",	ECHOK, ECHOE|ECHOKE|ECHOCTL },
    148 	{ "newcrt",	ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT },
    149 	{ "-newcrt",	ECHOK, ECHOE|ECHOKE|ECHOCTL },
    150 	{ "kerninfo",	0, NOKERNINFO },
    151 	{ "-kerninfo",	NOKERNINFO, 0 },
    152 	{ .name = NULL },
    153 };
    154 
    155 const struct modes omodes[] = {
    156 	{ "opost",	OPOST },
    157 	{ "onlcr",	ONLCR },
    158 	{ "ocrnl",	OCRNL },
    159 	{ "oxtabs",	OXTABS },
    160 	{ "onocr",	ONOCR },
    161 	{ "onlret",	ONLRET },
    162 	{ .name = NULL },
    163 };
    164 
    165 const struct specialmodes ospecialmodes[] = {
    166 	{ "litout",	0, OPOST },
    167 	{ "-litout",	OPOST, 0 },
    168 	{ "tabs",	0, OXTABS },		/* "preserve" tabs */
    169 	{ "-tabs",	OXTABS, 0 },
    170 	{ .name = NULL },
    171 };
    172 
    173 #define	CHK(s)	(!strcmp(name, s))
    174 
    175 static int
    176 modeset(const char *name, const struct modes *mp,
    177     const struct specialmodes *smp, tcflag_t *f)
    178 {
    179 	bool neg;
    180 
    181 	for (; smp->name; ++smp)
    182 		if (CHK(smp->name)) {
    183 			*f &= ~smp->unset;
    184 			*f |= smp->set;
    185 			return 1;
    186 		}
    187 
    188 	if ((neg = (*name == '-')))
    189 		name++;
    190 
    191 	for (; mp->name; ++mp)
    192 		if (CHK(mp->name)) {
    193 			if (neg)
    194 				*f &= ~mp->flag;
    195 			else
    196 				*f |= mp->flag;
    197 			return 1;
    198 		}
    199 
    200 	return 0;
    201 }
    202 
    203 int
    204 msearch(char ***argvp, struct info *ip)
    205 {
    206 	const char *name = **argvp;
    207 
    208 	if (modeset(name, cmodes, cspecialmodes, &ip->t.c_cflag))
    209 		goto out;
    210 
    211 	if (modeset(name, imodes, ispecialmodes, &ip->t.c_iflag))
    212 		goto out;
    213 
    214 	if (modeset(name, lmodes, lspecialmodes, &ip->t.c_lflag))
    215 		goto out;
    216 
    217 	if (modeset(name, omodes, ospecialmodes, &ip->t.c_oflag))
    218 		goto out;
    219 
    220 	return 0;
    221 out:
    222 	ip->set = 1;
    223 	return 1;
    224 }
    225