1 1.18 christos /* $NetBSD: modes.c,v 1.18 2015/05/01 17:01:08 christos Exp $ */ 2 1.8 cgd 3 1.1 cgd /*- 4 1.7 mycroft * Copyright (c) 1991, 1993, 1994 5 1.7 mycroft * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * Redistribution and use in source and binary forms, with or without 8 1.1 cgd * modification, are permitted provided that the following conditions 9 1.1 cgd * are met: 10 1.1 cgd * 1. Redistributions of source code must retain the above copyright 11 1.1 cgd * notice, this list of conditions and the following disclaimer. 12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cgd * notice, this list of conditions and the following disclaimer in the 14 1.1 cgd * documentation and/or other materials provided with the distribution. 15 1.16 agc * 3. Neither the name of the University nor the names of its contributors 16 1.1 cgd * may be used to endorse or promote products derived from this software 17 1.1 cgd * without specific prior written permission. 18 1.1 cgd * 19 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 cgd * SUCH DAMAGE. 30 1.1 cgd */ 31 1.1 cgd 32 1.11 christos #include <sys/cdefs.h> 33 1.1 cgd #ifndef lint 34 1.8 cgd #if 0 35 1.8 cgd static char sccsid[] = "@(#)modes.c 8.3 (Berkeley) 4/2/94"; 36 1.8 cgd #else 37 1.18 christos __RCSID("$NetBSD: modes.c,v 1.18 2015/05/01 17:01:08 christos Exp $"); 38 1.8 cgd #endif 39 1.1 cgd #endif /* not lint */ 40 1.1 cgd 41 1.1 cgd #include <sys/types.h> 42 1.15 perry 43 1.1 cgd #include <stddef.h> 44 1.1 cgd #include <string.h> 45 1.18 christos #include <stdbool.h> 46 1.15 perry 47 1.1 cgd #include "stty.h" 48 1.11 christos #include "extern.h" 49 1.1 cgd 50 1.1 cgd struct modes { 51 1.9 jtc const char *name; 52 1.18 christos tcflag_t flag; 53 1.18 christos }; 54 1.18 christos 55 1.18 christos struct specialmodes { 56 1.18 christos const char *name; 57 1.14 mycroft tcflag_t set; 58 1.14 mycroft tcflag_t unset; 59 1.1 cgd }; 60 1.1 cgd 61 1.1 cgd /* 62 1.1 cgd * The code in optlist() depends on minus options following regular 63 1.1 cgd * options, i.e. "foo" must immediately precede "-foo". 64 1.1 cgd */ 65 1.9 jtc const struct modes cmodes[] = { 66 1.18 christos { "cstopb", CSTOPB }, 67 1.18 christos { "cread", CREAD }, 68 1.18 christos { "parenb", PARENB }, 69 1.18 christos { "parodd", PARODD }, 70 1.18 christos { "hupcl", HUPCL }, 71 1.18 christos { "hup", HUPCL }, 72 1.18 christos { "clocal", CLOCAL }, 73 1.18 christos { "crtscts", CRTSCTS }, 74 1.18 christos { "mdmbuf", MDMBUF }, 75 1.18 christos { "cdtrcts", CDTRCTS }, 76 1.18 christos { .name = NULL }, 77 1.18 christos }; 78 1.18 christos 79 1.18 christos const struct specialmodes cspecialmodes[] = { 80 1.7 mycroft { "cs5", CS5, CSIZE }, 81 1.7 mycroft { "cs6", CS6, CSIZE }, 82 1.7 mycroft { "cs7", CS7, CSIZE }, 83 1.7 mycroft { "cs8", CS8, CSIZE }, 84 1.7 mycroft { "parity", PARENB | CS7, PARODD | CSIZE }, 85 1.7 mycroft { "-parity", CS8, PARODD | PARENB | CSIZE }, 86 1.7 mycroft { "evenp", PARENB | CS7, PARODD | CSIZE }, 87 1.7 mycroft { "-evenp", CS8, PARODD | PARENB | CSIZE }, 88 1.7 mycroft { "oddp", PARENB | CS7 | PARODD, CSIZE }, 89 1.7 mycroft { "-oddp", CS8, PARODD | PARENB | CSIZE }, 90 1.7 mycroft { "pass8", CS8, PARODD | PARENB | CSIZE }, 91 1.7 mycroft { "-pass8", PARENB | CS7, PARODD | CSIZE }, 92 1.17 christos { .name = NULL }, 93 1.1 cgd }; 94 1.1 cgd 95 1.9 jtc const struct modes imodes[] = { 96 1.18 christos { "ignbrk", IGNBRK }, 97 1.18 christos { "brkint", BRKINT }, 98 1.18 christos { "ignpar", IGNPAR }, 99 1.18 christos { "parmrk", PARMRK }, 100 1.18 christos { "inpck", INPCK }, 101 1.18 christos { "istrip", ISTRIP }, 102 1.18 christos { "inlcr", INLCR }, 103 1.18 christos { "igncr", IGNCR }, 104 1.18 christos { "icrnl", ICRNL }, 105 1.18 christos { "ixon", IXON }, 106 1.18 christos { "flow", IXON }, 107 1.18 christos { "ixoff", IXOFF }, 108 1.18 christos { "tandem", IXOFF }, 109 1.18 christos { "ixany", IXANY }, 110 1.18 christos { "imaxbel", IMAXBEL }, 111 1.18 christos { .name = NULL }, 112 1.18 christos }; 113 1.18 christos 114 1.18 christos const struct specialmodes ispecialmodes[] = { 115 1.7 mycroft { "decctlq", 0, IXANY }, 116 1.7 mycroft { "-decctlq", IXANY, 0 }, 117 1.17 christos { .name = NULL }, 118 1.1 cgd }; 119 1.1 cgd 120 1.9 jtc const struct modes lmodes[] = { 121 1.18 christos { "echo", ECHO }, 122 1.18 christos { "echoe", ECHOE }, 123 1.18 christos { "crterase", ECHOE }, 124 1.18 christos { "crtbs", ECHOE }, /* crtbs not supported, close enough */ 125 1.18 christos { "echok", ECHOK }, 126 1.18 christos { "echoke", ECHOKE }, 127 1.18 christos { "crtkill", ECHOKE }, 128 1.18 christos { "altwerase", ALTWERASE }, 129 1.18 christos { "iexten", IEXTEN }, 130 1.18 christos { "echonl", ECHONL }, 131 1.18 christos { "echoctl", ECHOCTL }, 132 1.18 christos { "ctlecho", ECHOCTL }, 133 1.18 christos { "echoprt", ECHOPRT }, 134 1.18 christos { "prterase", ECHOPRT }, 135 1.18 christos { "isig", ISIG }, 136 1.18 christos { "icanon", ICANON }, 137 1.18 christos { "noflsh", NOFLSH }, 138 1.18 christos { "tostop", TOSTOP }, 139 1.18 christos { "flusho", FLUSHO }, 140 1.18 christos { "pendin", PENDIN }, 141 1.18 christos { "nokerninfo", NOKERNINFO }, 142 1.18 christos { .name = NULL }, 143 1.18 christos }; 144 1.18 christos 145 1.18 christos const struct specialmodes lspecialmodes[] = { 146 1.7 mycroft { "crt", ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT }, 147 1.7 mycroft { "-crt", ECHOK, ECHOE|ECHOKE|ECHOCTL }, 148 1.7 mycroft { "newcrt", ECHOE|ECHOKE|ECHOCTL, ECHOK|ECHOPRT }, 149 1.7 mycroft { "-newcrt", ECHOK, ECHOE|ECHOKE|ECHOCTL }, 150 1.7 mycroft { "kerninfo", 0, NOKERNINFO }, 151 1.7 mycroft { "-kerninfo", NOKERNINFO, 0 }, 152 1.17 christos { .name = NULL }, 153 1.1 cgd }; 154 1.1 cgd 155 1.9 jtc const struct modes omodes[] = { 156 1.18 christos { "opost", OPOST }, 157 1.18 christos { "onlcr", ONLCR }, 158 1.18 christos { "ocrnl", OCRNL }, 159 1.18 christos { "oxtabs", OXTABS }, 160 1.18 christos { "onocr", ONOCR }, 161 1.18 christos { "onlret", ONLRET }, 162 1.18 christos { .name = NULL }, 163 1.18 christos }; 164 1.18 christos 165 1.18 christos const struct specialmodes ospecialmodes[] = { 166 1.7 mycroft { "litout", 0, OPOST }, 167 1.7 mycroft { "-litout", OPOST, 0 }, 168 1.7 mycroft { "tabs", 0, OXTABS }, /* "preserve" tabs */ 169 1.7 mycroft { "-tabs", OXTABS, 0 }, 170 1.17 christos { .name = NULL }, 171 1.1 cgd }; 172 1.1 cgd 173 1.9 jtc #define CHK(s) (!strcmp(name, s)) 174 1.1 cgd 175 1.18 christos static int 176 1.18 christos modeset(const char *name, const struct modes *mp, 177 1.18 christos const struct specialmodes *smp, tcflag_t *f) 178 1.1 cgd { 179 1.18 christos bool neg; 180 1.18 christos 181 1.18 christos for (; smp->name; ++smp) 182 1.18 christos if (CHK(smp->name)) { 183 1.18 christos *f &= ~smp->unset; 184 1.18 christos *f |= smp->set; 185 1.18 christos return 1; 186 1.18 christos } 187 1.1 cgd 188 1.18 christos if ((neg = (*name == '-'))) 189 1.18 christos name++; 190 1.1 cgd 191 1.18 christos for (; mp->name; ++mp) 192 1.1 cgd if (CHK(mp->name)) { 193 1.18 christos if (neg) 194 1.18 christos *f &= ~mp->flag; 195 1.18 christos else 196 1.18 christos *f |= mp->flag; 197 1.18 christos return 1; 198 1.1 cgd } 199 1.18 christos 200 1.18 christos return 0; 201 1.18 christos } 202 1.18 christos 203 1.18 christos int 204 1.18 christos msearch(char ***argvp, struct info *ip) 205 1.18 christos { 206 1.18 christos const char *name = **argvp; 207 1.18 christos 208 1.18 christos if (modeset(name, cmodes, cspecialmodes, &ip->t.c_cflag)) 209 1.18 christos goto out; 210 1.18 christos 211 1.18 christos if (modeset(name, imodes, ispecialmodes, &ip->t.c_iflag)) 212 1.18 christos goto out; 213 1.18 christos 214 1.18 christos if (modeset(name, lmodes, lspecialmodes, &ip->t.c_lflag)) 215 1.18 christos goto out; 216 1.18 christos 217 1.18 christos if (modeset(name, omodes, ospecialmodes, &ip->t.c_oflag)) 218 1.18 christos goto out; 219 1.18 christos 220 1.18 christos return 0; 221 1.18 christos out: 222 1.18 christos ip->set = 1; 223 1.18 christos return 1; 224 1.1 cgd } 225