1 /*-
2 * Copyright (c) 1991, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)cchar.c 8.5 (Berkeley) 04/02/94";
10 #endif /* not lint */
11
12 #include <sys/types.h>
13
14 #include <err.h>
15 #include <limits.h>
16 #include <stddef.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 #include "stty.h"
21 #include "extern.h"
22
23 /*
24 * Special control characters.
25 *
26 * Cchars1 are the standard names, cchars2 are the old aliases.
27 * The first are displayed, but both are recognized on the
28 * command line.
29 */
30 struct cchar cchars1[] = {
31 { "discard", VDISCARD, CDISCARD },
32 { "dsusp", VDSUSP, CDSUSP },
33 { "eof", VEOF, CEOF },
34 { "eol", VEOL, CEOL },
35 { "eol2", VEOL2, CEOL },
36 { "erase", VERASE, CERASE },
37 { "intr", VINTR, CINTR },
38 { "kill", VKILL, CKILL },
39 { "lnext", VLNEXT, CLNEXT },
40 { "min", VMIN, CMIN },
41 { "quit", VQUIT, CQUIT },
42 { "reprint", VREPRINT, CREPRINT },
43 { "start", VSTART, CSTART },
44 { "status", VSTATUS, CSTATUS },
45 { "stop", VSTOP, CSTOP },
46 { "susp", VSUSP, CSUSP },
47 { "time", VTIME, CTIME },
48 { "werase", VWERASE, CWERASE },
49 { NULL },
50 };
51
52 struct cchar cchars2[] = {
53 { "brk", VEOL, CEOL },
54 { "flush", VDISCARD, CDISCARD },
55 { "rprnt", VREPRINT, CREPRINT },
56 { NULL },
57 };
58
59 static int
c_cchar(a,b)60 c_cchar(a, b)
61 const void *a, *b;
62 {
63
64 return (strcmp(((struct cchar *)a)->name, ((struct cchar *)b)->name));
65 }
66
67 int
csearch(argvp,ip)68 csearch(argvp, ip)
69 char ***argvp;
70 struct info *ip;
71 {
72 struct cchar *cp, tmp;
73 long val;
74 char *arg, *ep, *name;
75
76 name = **argvp;
77
78 tmp.name = name;
79 if (!(cp = (struct cchar *)bsearch(&tmp, cchars1,
80 sizeof(cchars1)/sizeof(struct cchar) - 1, sizeof(struct cchar),
81 c_cchar)) && !(cp = (struct cchar *)bsearch(&tmp, cchars1,
82 sizeof(cchars1)/sizeof(struct cchar) - 1, sizeof(struct cchar),
83 c_cchar)))
84 return (0);
85
86 arg = *++*argvp;
87 if (!arg) {
88 warnx("option requires an argument -- %s", name);
89 usage();
90 }
91
92 #define CHK(s) (*arg == s[0] && !strcmp(arg, s))
93 if (CHK("undef") || CHK("<undef>"))
94 ip->t.c_cc[cp->sub] = _POSIX_VDISABLE;
95 else if (cp->sub == VMIN || cp->sub == VTIME) {
96 val = strtol(arg, &ep, 10);
97 if (val == _POSIX_VDISABLE) {
98 warnx("value of %ld would disable the option -- %s",
99 val, name);
100 usage();
101 }
102 if (val > UCHAR_MAX) {
103 warnx("maximum option value is %d -- %s",
104 UCHAR_MAX, name);
105 usage();
106 }
107 if (*ep != '\0') {
108 warnx("option requires a numeric argument -- %s", name);
109 usage();
110 }
111 ip->t.c_cc[cp->sub] = val;
112 } else if (arg[0] == '^')
113 ip->t.c_cc[cp->sub] = (arg[1] == '?') ? 0177 :
114 (arg[1] == '-') ? _POSIX_VDISABLE : arg[1] & 037;
115 else
116 ip->t.c_cc[cp->sub] = arg[0];
117 ip->set = 1;
118 return (1);
119 }
120