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