1139743Simp/*- 239212Sgibbs * Copyright (c) 1991, 1993, 1994 339212Sgibbs * The Regents of the University of California. All rights reserved. 442651Sgibbs * 542823Sken * Redistribution and use in source and binary forms, with or without 639212Sgibbs * modification, are permitted provided that the following conditions 739212Sgibbs * are met: 839212Sgibbs * 1. Redistributions of source code must retain the above copyright 939212Sgibbs * notice, this list of conditions and the following disclaimer. 1039212Sgibbs * 2. Redistributions in binary form must reproduce the above copyright 1139212Sgibbs * notice, this list of conditions and the following disclaimer in the 1239212Sgibbs * documentation and/or other materials provided with the distribution. 1339212Sgibbs * 4. Neither the name of the University nor the names of its contributors 1439212Sgibbs * may be used to endorse or promote products derived from this software 1539212Sgibbs * without specific prior written permission. 1639212Sgibbs * 1739212Sgibbs * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1839212Sgibbs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1939212Sgibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2039212Sgibbs * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2139212Sgibbs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2239212Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2339212Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2439212Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2539212Sgibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2639212Sgibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2739212Sgibbs * SUCH DAMAGE. 2839212Sgibbs */ 29116161Sobrien 30116161Sobrien#ifndef lint 31116161Sobrien#if 0 32116161Sobrienstatic char sccsid[] = "@(#)cchar.c 8.5 (Berkeley) 4/2/94"; 3339212Sgibbs#endif 3465822Sjhb#endif /* not lint */ 3539212Sgibbs#include <sys/cdefs.h> 3639212Sgibbs__FBSDID("$FreeBSD$"); 3739212Sgibbs 3839212Sgibbs#include <sys/types.h> 3947412Sgibbs 4039212Sgibbs#include <err.h> 4139212Sgibbs#include <limits.h> 4242038Smjacob#include <stddef.h> 4374840Sken#include <stdlib.h> 44168752Sscottl#include <string.h> 4539212Sgibbs 46141566Sscottl#include "stty.h" 47141566Sscottl#include "extern.h" 48150201Smjacob 49166896Smjacobstatic int c_cchar(const void *, const void *); 50141566Sscottl 5139212Sgibbs/* 5239212Sgibbs * Special control characters. 5339212Sgibbs * 54195534Sscottl * Cchars1 are the standard names, cchars2 are the old aliases. 5539212Sgibbs * The first are displayed, but both are recognized on the 5639212Sgibbs * command line. 5739212Sgibbs */ 5839212Sgibbsstruct cchar cchars1[] = { 59195534Sscottl { "discard", VDISCARD, CDISCARD }, 6039212Sgibbs { "dsusp", VDSUSP, CDSUSP }, 6139212Sgibbs { "eof", VEOF, CEOF }, 6239212Sgibbs { "eol", VEOL, CEOL }, 6339212Sgibbs { "eol2", VEOL2, CEOL }, 6439212Sgibbs { "erase", VERASE, CERASE }, 65230665Smarius { "erase2", VERASE2, CERASE2 }, 66230665Smarius { "intr", VINTR, CINTR }, 67164906Smjacob { "kill", VKILL, CKILL }, 68230665Smarius { "lnext", VLNEXT, CLNEXT }, 6939212Sgibbs { "min", VMIN, CMIN }, 7039212Sgibbs { "quit", VQUIT, CQUIT }, 7139212Sgibbs { "reprint", VREPRINT, CREPRINT }, 7239212Sgibbs { "start", VSTART, CSTART }, 7339212Sgibbs { "status", VSTATUS, CSTATUS }, 7439212Sgibbs { "stop", VSTOP, CSTOP }, 7539212Sgibbs { "susp", VSUSP, CSUSP }, 7639212Sgibbs { "time", VTIME, CTIME }, 7739212Sgibbs { "werase", VWERASE, CWERASE }, 7839212Sgibbs { NULL, 0, 0}, 79195534Sscottl}; 80195534Sscottl 81241941Smavstruct cchar cchars2[] = { 82241941Smav { "brk", VEOL, CEOL }, 83241941Smav { "flush", VDISCARD, CDISCARD }, 8439212Sgibbs { "rprnt", VREPRINT, CREPRINT }, 85195534Sscottl { NULL, 0, 0 }, 86195534Sscottl}; 87195534Sscottl 88195534Sscottlstatic int 89195534Sscottlc_cchar(const void *a, const void *b) 9039212Sgibbs{ 9139212Sgibbs 9239212Sgibbs return (strcmp(((const struct cchar *)a)->name, ((const struct cchar *)b)->name)); 9339212Sgibbs} 9439212Sgibbs 9539212Sgibbsint 9639212Sgibbscsearch(char ***argvp, struct info *ip) 97168752Sscottl{ 98168752Sscottl struct cchar *cp, tmp; 99168752Sscottl long val; 100168752Sscottl char *arg, *ep, *name; 101168752Sscottl 102168752Sscottl name = **argvp; 103168752Sscottl 104168752Sscottl tmp.name = name; 105168752Sscottl if (!(cp = (struct cchar *)bsearch(&tmp, cchars1, 106203108Smav sizeof(cchars1)/sizeof(struct cchar) - 1, sizeof(struct cchar), 107203108Smav c_cchar)) && !(cp = (struct cchar *)bsearch(&tmp, cchars2, 108168752Sscottl sizeof(cchars2)/sizeof(struct cchar) - 1, sizeof(struct cchar), 109168752Sscottl c_cchar))) 110168752Sscottl return (0); 111168752Sscottl 112168752Sscottl arg = *++*argvp; 113168752Sscottl if (!arg) { 114168752Sscottl warnx("option requires an argument -- %s", name); 115203108Smav usage(); 116203108Smav } 117203108Smav 118168752Sscottl#define CHK(s) (*arg == s[0] && !strcmp(arg, s)) 119168752Sscottl if (CHK("undef") || CHK("<undef>")) 12039212Sgibbs ip->t.c_cc[cp->sub] = _POSIX_VDISABLE; 12139212Sgibbs else if (cp->sub == VMIN || cp->sub == VTIME) { 12239212Sgibbs val = strtol(arg, &ep, 10); 12339212Sgibbs if (val > UCHAR_MAX) { 12439212Sgibbs warnx("maximum option value is %d -- %s", 12539212Sgibbs UCHAR_MAX, name); 12639212Sgibbs usage(); 12739212Sgibbs } 12839212Sgibbs if (*ep != '\0') { 12939212Sgibbs warnx("option requires a numeric argument -- %s", name); 13039212Sgibbs usage(); 13139212Sgibbs } 13239212Sgibbs ip->t.c_cc[cp->sub] = val; 13339212Sgibbs } else if (arg[0] == '^') 13439212Sgibbs ip->t.c_cc[cp->sub] = (arg[1] == '?') ? 0177 : 13539212Sgibbs (arg[1] == '-') ? _POSIX_VDISABLE : arg[1] & 037; 13639212Sgibbs else 13739212Sgibbs ip->t.c_cc[cp->sub] = arg[0]; 13839212Sgibbs ip->set = 1; 13939212Sgibbs return (1); 14039212Sgibbs} 14139212Sgibbs