1 |
|
|
/* $OpenBSD: cchar.c,v 1.12 2016/03/23 14:52:42 mmcc Exp $ */ |
2 |
|
|
/* $NetBSD: cchar.c,v 1.10 1996/05/07 18:20:05 jtc Exp $ */ |
3 |
|
|
|
4 |
|
|
/*- |
5 |
|
|
* Copyright (c) 1991, 1993, 1994 |
6 |
|
|
* The Regents of the University of California. All rights reserved. |
7 |
|
|
* |
8 |
|
|
* Redistribution and use in source and binary forms, with or without |
9 |
|
|
* modification, are permitted provided that the following conditions |
10 |
|
|
* are met: |
11 |
|
|
* 1. Redistributions of source code must retain the above copyright |
12 |
|
|
* notice, this list of conditions and the following disclaimer. |
13 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
14 |
|
|
* notice, this list of conditions and the following disclaimer in the |
15 |
|
|
* documentation and/or other materials provided with the distribution. |
16 |
|
|
* 3. Neither the name of the University nor the names of its contributors |
17 |
|
|
* may be used to endorse or promote products derived from this software |
18 |
|
|
* without specific prior written permission. |
19 |
|
|
* |
20 |
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
21 |
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
22 |
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
23 |
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
24 |
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
25 |
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
26 |
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
27 |
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
28 |
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
29 |
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
30 |
|
|
* SUCH DAMAGE. |
31 |
|
|
*/ |
32 |
|
|
|
33 |
|
|
#include <sys/types.h> |
34 |
|
|
#include <sys/ioctl.h> |
35 |
|
|
|
36 |
|
|
#include <err.h> |
37 |
|
|
#include <limits.h> |
38 |
|
|
#include <stddef.h> |
39 |
|
|
#include <stdlib.h> |
40 |
|
|
#include <string.h> |
41 |
|
|
#include <termios.h> |
42 |
|
|
|
43 |
|
|
#include "stty.h" |
44 |
|
|
#include "extern.h" |
45 |
|
|
|
46 |
|
|
/* |
47 |
|
|
* Special control characters. |
48 |
|
|
* |
49 |
|
|
* Cchars1 are the standard names, cchars2 are the old aliases. |
50 |
|
|
* The first are displayed, but both are recognized on the |
51 |
|
|
* command line. |
52 |
|
|
*/ |
53 |
|
|
const struct cchar cchars1[] = { |
54 |
|
|
{ "discard", VDISCARD, CDISCARD }, |
55 |
|
|
{ "dsusp", VDSUSP, CDSUSP }, |
56 |
|
|
{ "eof", VEOF, CEOF }, |
57 |
|
|
{ "eol", VEOL, CEOL }, |
58 |
|
|
{ "eol2", VEOL2, CEOL }, |
59 |
|
|
{ "erase", VERASE, CERASE }, |
60 |
|
|
{ "intr", VINTR, CINTR }, |
61 |
|
|
{ "kill", VKILL, CKILL }, |
62 |
|
|
{ "lnext", VLNEXT, CLNEXT }, |
63 |
|
|
{ "min", VMIN, CMIN }, |
64 |
|
|
{ "quit", VQUIT, CQUIT }, |
65 |
|
|
{ "reprint", VREPRINT, CREPRINT }, |
66 |
|
|
{ "start", VSTART, CSTART }, |
67 |
|
|
{ "status", VSTATUS, CSTATUS }, |
68 |
|
|
{ "stop", VSTOP, CSTOP }, |
69 |
|
|
{ "susp", VSUSP, CSUSP }, |
70 |
|
|
{ "time", VTIME, CTIME }, |
71 |
|
|
{ "werase", VWERASE, CWERASE }, |
72 |
|
|
{ NULL }, |
73 |
|
|
}; |
74 |
|
|
|
75 |
|
|
const struct cchar cchars2[] = { |
76 |
|
|
{ "brk", VEOL, CEOL }, |
77 |
|
|
{ "flush", VDISCARD, CDISCARD }, |
78 |
|
|
{ "rprnt", VREPRINT, CREPRINT }, |
79 |
|
|
{ NULL }, |
80 |
|
|
}; |
81 |
|
|
|
82 |
|
|
static int |
83 |
|
|
c_cchar(const void *a, const void *b) |
84 |
|
|
{ |
85 |
|
252 |
return (strcmp(((struct cchar *)a)->name, ((struct cchar *)b)->name)); |
86 |
|
|
} |
87 |
|
|
|
88 |
|
|
int |
89 |
|
|
csearch(char ***argvp, struct info *ip) |
90 |
|
|
{ |
91 |
|
36 |
struct cchar *cp, tmp; |
92 |
|
|
long val; |
93 |
|
18 |
char *arg, *ep, *name; |
94 |
|
|
|
95 |
|
18 |
name = **argvp; |
96 |
|
|
|
97 |
|
18 |
tmp.name = name; |
98 |
✓✗ |
36 |
if (!(cp = (struct cchar *)bsearch(&tmp, cchars1, |
99 |
|
|
sizeof(cchars1)/sizeof(struct cchar) - 1, sizeof(struct cchar), |
100 |
✓✗ |
36 |
c_cchar)) && !(cp = (struct cchar *)bsearch(&tmp, cchars2, |
101 |
|
|
sizeof(cchars2)/sizeof(struct cchar) - 1, sizeof(struct cchar), |
102 |
|
|
c_cchar))) |
103 |
|
18 |
return (0); |
104 |
|
|
|
105 |
|
|
arg = *++*argvp; |
106 |
|
|
if (!arg) { |
107 |
|
|
warnx("option requires an argument -- %s", name); |
108 |
|
|
usage(); |
109 |
|
|
} |
110 |
|
|
|
111 |
|
|
#define CHK(s) (*arg == s[0] && !strcmp(arg, s)) |
112 |
|
|
if (CHK("undef") || CHK("<undef>")) |
113 |
|
|
ip->t.c_cc[cp->sub] = _POSIX_VDISABLE; |
114 |
|
|
else if (cp->sub == VMIN || cp->sub == VTIME) { |
115 |
|
|
val = strtol(arg, &ep, 10); |
116 |
|
|
if (val > UCHAR_MAX || val < 0) { |
117 |
|
|
warnx("maximum option value is %d -- %s", |
118 |
|
|
UCHAR_MAX, name); |
119 |
|
|
usage(); |
120 |
|
|
} |
121 |
|
|
if (*ep != '\0') { |
122 |
|
|
warnx("option requires a numeric argument -- %s", name); |
123 |
|
|
usage(); |
124 |
|
|
} |
125 |
|
|
ip->t.c_cc[cp->sub] = val; |
126 |
|
|
} else if (arg[0] == '^') |
127 |
|
|
ip->t.c_cc[cp->sub] = (arg[1] == '?') ? 0177 : |
128 |
|
|
(arg[1] == '-') ? _POSIX_VDISABLE : arg[1] & 037; |
129 |
|
|
else |
130 |
|
|
ip->t.c_cc[cp->sub] = arg[0]; |
131 |
|
|
ip->set = 1; |
132 |
|
|
return (1); |
133 |
|
18 |
} |