Commit | Line | Data |
---|---|---|
984263bc MD |
1 | /*- |
2 | * Copyright (c) 1991, 1993, 1994 | |
3 | * The Regents of the University of California. All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
dc71b7ab | 13 | * 3. Neither the name of the University nor the names of its contributors |
984263bc MD |
14 | * may be used to endorse or promote products derived from this software |
15 | * without specific prior written permission. | |
16 | * | |
17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
27 | * SUCH DAMAGE. | |
1de703da MD |
28 | * |
29 | * @(#)key.c 8.3 (Berkeley) 4/2/94 | |
30 | * $FreeBSD: src/bin/stty/key.c,v 1.11.2.2 2001/10/15 13:45:05 dd Exp $ | |
57fed2af | 31 | * $DragonFly: src/bin/stty/key.c,v 1.5 2004/11/07 20:54:52 eirikn Exp $ |
984263bc MD |
32 | */ |
33 | ||
984263bc MD |
34 | #include <sys/types.h> |
35 | ||
36 | #include <err.h> | |
37 | #include <errno.h> | |
38 | #include <stdlib.h> | |
39 | #include <stdio.h> | |
40 | #include <string.h> | |
41 | ||
42 | #include "stty.h" | |
43 | #include "extern.h" | |
44 | ||
45 | __BEGIN_DECLS | |
9dbf638f DR |
46 | static int c_key (const void *, const void *); |
47 | void f_all (struct info *); | |
48 | void f_cbreak (struct info *); | |
49 | void f_columns (struct info *); | |
50 | void f_dec (struct info *); | |
51 | void f_ek (struct info *); | |
52 | void f_everything (struct info *); | |
53 | void f_extproc (struct info *); | |
54 | void f_ispeed (struct info *); | |
55 | void f_nl (struct info *); | |
56 | void f_ospeed (struct info *); | |
57 | void f_raw (struct info *); | |
58 | void f_rows (struct info *); | |
59 | void f_sane (struct info *); | |
60 | void f_size (struct info *); | |
61 | void f_speed (struct info *); | |
62 | void f_tty (struct info *); | |
984263bc MD |
63 | __END_DECLS |
64 | ||
65 | static struct key { | |
66 | const char *name; /* name */ | |
9dbf638f | 67 | void (*f) (struct info *); /* function */ |
984263bc MD |
68 | #define F_NEEDARG 0x01 /* needs an argument */ |
69 | #define F_OFFOK 0x02 /* can turn off */ | |
70 | int flags; | |
71 | } keys[] = { | |
72 | { "all", f_all, 0 }, | |
73 | { "cbreak", f_cbreak, F_OFFOK }, | |
74 | { "cols", f_columns, F_NEEDARG }, | |
75 | { "columns", f_columns, F_NEEDARG }, | |
76 | { "cooked", f_sane, 0 }, | |
77 | { "dec", f_dec, 0 }, | |
78 | { "ek", f_ek, 0 }, | |
79 | { "everything", f_everything, 0 }, | |
80 | { "extproc", f_extproc, F_OFFOK }, | |
81 | { "ispeed", f_ispeed, F_NEEDARG }, | |
82 | { "new", f_tty, 0 }, | |
83 | { "nl", f_nl, F_OFFOK }, | |
84 | { "old", f_tty, 0 }, | |
85 | { "ospeed", f_ospeed, F_NEEDARG }, | |
86 | { "raw", f_raw, F_OFFOK }, | |
87 | { "rows", f_rows, F_NEEDARG }, | |
88 | { "sane", f_sane, 0 }, | |
89 | { "size", f_size, 0 }, | |
90 | { "speed", f_speed, 0 }, | |
91 | { "tty", f_tty, 0 }, | |
92 | }; | |
93 | ||
94 | static int | |
b5744197 | 95 | c_key(const void *a, const void *b) |
984263bc MD |
96 | { |
97 | ||
98 | return (strcmp(((const struct key *)a)->name, ((const struct key *)b)->name)); | |
99 | } | |
100 | ||
101 | int | |
b5744197 | 102 | ksearch(char ***argvp, struct info *ip) |
984263bc MD |
103 | { |
104 | char *name; | |
105 | struct key *kp, tmp; | |
106 | ||
107 | name = **argvp; | |
108 | if (*name == '-') { | |
109 | ip->off = 1; | |
110 | ++name; | |
111 | } else | |
112 | ip->off = 0; | |
113 | ||
114 | tmp.name = name; | |
115 | if (!(kp = (struct key *)bsearch(&tmp, keys, | |
116 | sizeof(keys)/sizeof(struct key), sizeof(struct key), c_key))) | |
117 | return (0); | |
118 | if (!(kp->flags & F_OFFOK) && ip->off) { | |
119 | warnx("illegal option -- -%s", name); | |
120 | usage(); | |
121 | } | |
122 | if (kp->flags & F_NEEDARG && !(ip->arg = *++*argvp)) { | |
123 | warnx("option requires an argument -- %s", name); | |
124 | usage(); | |
125 | } | |
126 | kp->f(ip); | |
127 | return (1); | |
128 | } | |
129 | ||
130 | void | |
b5744197 | 131 | f_all(struct info *ip) |
984263bc MD |
132 | { |
133 | print(&ip->t, &ip->win, ip->ldisc, BSD); | |
134 | } | |
135 | ||
136 | void | |
b5744197 | 137 | f_cbreak(struct info *ip) |
984263bc MD |
138 | { |
139 | ||
140 | if (ip->off) | |
141 | f_sane(ip); | |
142 | else { | |
143 | ip->t.c_iflag |= BRKINT|IXON|IMAXBEL; | |
144 | ip->t.c_oflag |= OPOST; | |
145 | ip->t.c_lflag |= ISIG|IEXTEN; | |
146 | ip->t.c_lflag &= ~ICANON; | |
147 | ip->set = 1; | |
148 | } | |
149 | } | |
150 | ||
151 | void | |
b5744197 | 152 | f_columns(struct info *ip) |
984263bc MD |
153 | { |
154 | ||
155 | ip->win.ws_col = atoi(ip->arg); | |
156 | ip->wset = 1; | |
157 | } | |
158 | ||
159 | void | |
b5744197 | 160 | f_dec(struct info *ip) |
984263bc MD |
161 | { |
162 | ||
163 | ip->t.c_cc[VERASE] = (u_char)0177; | |
164 | ip->t.c_cc[VKILL] = CTRL('u'); | |
165 | ip->t.c_cc[VINTR] = CTRL('c'); | |
166 | ip->t.c_lflag &= ~ECHOPRT; | |
167 | ip->t.c_lflag |= ECHOE|ECHOKE|ECHOCTL; | |
168 | ip->t.c_iflag &= ~IXANY; | |
169 | ip->set = 1; | |
170 | } | |
171 | ||
172 | void | |
b5744197 | 173 | f_ek(struct info *ip) |
984263bc MD |
174 | { |
175 | ||
176 | ip->t.c_cc[VERASE] = CERASE; | |
177 | ip->t.c_cc[VKILL] = CKILL; | |
178 | ip->set = 1; | |
179 | } | |
180 | ||
181 | void | |
b5744197 | 182 | f_everything(struct info *ip) |
984263bc MD |
183 | { |
184 | ||
185 | print(&ip->t, &ip->win, ip->ldisc, BSD); | |
186 | } | |
187 | ||
188 | void | |
b5744197 | 189 | f_extproc(struct info *ip) |
984263bc MD |
190 | { |
191 | ||
192 | if (ip->off) { | |
193 | int tmp = 0; | |
57fed2af | 194 | ioctl(ip->fd, TIOCEXT, &tmp); |
984263bc MD |
195 | } else { |
196 | int tmp = 1; | |
57fed2af | 197 | ioctl(ip->fd, TIOCEXT, &tmp); |
984263bc MD |
198 | } |
199 | } | |
200 | ||
201 | void | |
b5744197 | 202 | f_ispeed(struct info *ip) |
984263bc MD |
203 | { |
204 | ||
205 | cfsetispeed(&ip->t, (speed_t)atoi(ip->arg)); | |
206 | ip->set = 1; | |
207 | } | |
208 | ||
209 | void | |
b5744197 | 210 | f_nl(struct info *ip) |
984263bc MD |
211 | { |
212 | ||
213 | if (ip->off) { | |
214 | ip->t.c_iflag |= ICRNL; | |
215 | ip->t.c_oflag |= ONLCR; | |
216 | } else { | |
217 | ip->t.c_iflag &= ~ICRNL; | |
218 | ip->t.c_oflag &= ~ONLCR; | |
219 | } | |
220 | ip->set = 1; | |
221 | } | |
222 | ||
223 | void | |
b5744197 | 224 | f_ospeed(struct info *ip) |
984263bc MD |
225 | { |
226 | ||
227 | cfsetospeed(&ip->t, (speed_t)atoi(ip->arg)); | |
228 | ip->set = 1; | |
229 | } | |
230 | ||
231 | void | |
b5744197 | 232 | f_raw(struct info *ip) |
984263bc MD |
233 | { |
234 | ||
235 | if (ip->off) | |
236 | f_sane(ip); | |
237 | else { | |
238 | cfmakeraw(&ip->t); | |
239 | ip->t.c_cflag &= ~(CSIZE|PARENB); | |
240 | ip->t.c_cflag |= CS8; | |
241 | ip->set = 1; | |
242 | } | |
243 | } | |
244 | ||
245 | void | |
b5744197 | 246 | f_rows(struct info *ip) |
984263bc MD |
247 | { |
248 | ||
249 | ip->win.ws_row = atoi(ip->arg); | |
250 | ip->wset = 1; | |
251 | } | |
252 | ||
253 | void | |
b5744197 | 254 | f_sane(struct info *ip) |
984263bc MD |
255 | { |
256 | ||
257 | ip->t.c_cflag = TTYDEF_CFLAG | (ip->t.c_cflag & CLOCAL); | |
258 | ip->t.c_iflag = TTYDEF_IFLAG; | |
259 | ip->t.c_iflag |= ICRNL; | |
260 | /* preserve user-preference flags in lflag */ | |
261 | #define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH) | |
262 | ip->t.c_lflag = TTYDEF_LFLAG | (ip->t.c_lflag & LKEEP); | |
263 | ip->t.c_oflag = TTYDEF_OFLAG; | |
264 | ip->set = 1; | |
265 | } | |
266 | ||
267 | void | |
b5744197 | 268 | f_size(struct info *ip) |
984263bc MD |
269 | { |
270 | ||
57fed2af | 271 | printf("%d %d\n", ip->win.ws_row, ip->win.ws_col); |
984263bc MD |
272 | } |
273 | ||
274 | void | |
b5744197 | 275 | f_speed(struct info *ip) |
984263bc MD |
276 | { |
277 | ||
57fed2af | 278 | printf("%lu\n", (u_long)cfgetospeed(&ip->t)); |
984263bc MD |
279 | } |
280 | ||
281 | void | |
b5744197 | 282 | f_tty(struct info *ip) |
984263bc MD |
283 | { |
284 | int tmp; | |
285 | ||
286 | tmp = TTYDISC; | |
287 | if (ioctl(ip->fd, TIOCSETD, &tmp) < 0) | |
288 | err(1, "TIOCSETD"); | |
289 | } |