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[] = "@(#)key.c 8.4 (Berkeley) 02/20/95";
10 #endif /* not lint */
11
12 #include <sys/types.h>
13
14 #include <err.h>
15 #include <errno.h>
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19
20 #include "stty.h"
21 #include "extern.h"
22
23 __BEGIN_DECLS
24 void f_all __P((struct info *));
25 void f_cbreak __P((struct info *));
26 void f_columns __P((struct info *));
27 void f_dec __P((struct info *));
28 void f_everything __P((struct info *));
29 void f_extproc __P((struct info *));
30 void f_ispeed __P((struct info *));
31 void f_nl __P((struct info *));
32 void f_ospeed __P((struct info *));
33 void f_raw __P((struct info *));
34 void f_rows __P((struct info *));
35 void f_sane __P((struct info *));
36 void f_size __P((struct info *));
37 void f_speed __P((struct info *));
38 void f_tty __P((struct info *));
39 __END_DECLS
40
41 static struct key {
42 char *name; /* name */
43 void (*f) __P((struct info *)); /* function */
44 #define F_NEEDARG 0x01 /* needs an argument */
45 #define F_OFFOK 0x02 /* can turn off */
46 int flags;
47 } keys[] = {
48 { "all", f_all, 0 },
49 { "cbreak", f_cbreak, F_OFFOK },
50 { "cols", f_columns, F_NEEDARG },
51 { "columns", f_columns, F_NEEDARG },
52 { "cooked", f_sane, 0 },
53 { "dec", f_dec, 0 },
54 { "everything", f_everything, 0 },
55 { "extproc", f_extproc, F_OFFOK },
56 { "ispeed", f_ispeed, F_NEEDARG },
57 { "new", f_tty, 0 },
58 { "nl", f_nl, F_OFFOK },
59 { "old", f_tty, 0 },
60 { "ospeed", f_ospeed, F_NEEDARG },
61 { "raw", f_raw, F_OFFOK },
62 { "rows", f_rows, F_NEEDARG },
63 { "sane", f_sane, 0 },
64 { "size", f_size, 0 },
65 { "speed", f_speed, 0 },
66 { "tty", f_tty, 0 },
67 };
68
69 static int
c_key(a,b)70 c_key(a, b)
71 const void *a, *b;
72 {
73
74 return (strcmp(((struct key *)a)->name, ((struct key *)b)->name));
75 }
76
77 int
ksearch(argvp,ip)78 ksearch(argvp, ip)
79 char ***argvp;
80 struct info *ip;
81 {
82 char *name;
83 struct key *kp, tmp;
84
85 name = **argvp;
86 if (*name == '-') {
87 ip->off = 1;
88 ++name;
89 } else
90 ip->off = 0;
91
92 tmp.name = name;
93 if (!(kp = (struct key *)bsearch(&tmp, keys,
94 sizeof(keys)/sizeof(struct key), sizeof(struct key), c_key)))
95 return (0);
96 if (!(kp->flags & F_OFFOK) && ip->off) {
97 errx(1, "illegal option -- %s", name);
98 usage();
99 }
100 if (kp->flags & F_NEEDARG && !(ip->arg = *++*argvp)) {
101 errx(1, "option requires an argument -- %s", name);
102 usage();
103 }
104 kp->f(ip);
105 return (1);
106 }
107
108 void
f_all(ip)109 f_all(ip)
110 struct info *ip;
111 {
112 print(&ip->t, &ip->win, ip->ldisc, BSD);
113 }
114
115 void
f_cbreak(ip)116 f_cbreak(ip)
117 struct info *ip;
118 {
119
120 if (ip->off)
121 f_sane(ip);
122 else {
123 ip->t.c_iflag |= BRKINT|IXON|IMAXBEL;
124 ip->t.c_oflag |= OPOST;
125 ip->t.c_lflag |= ISIG|IEXTEN;
126 ip->t.c_lflag &= ~ICANON;
127 ip->set = 1;
128 }
129 }
130
131 void
f_columns(ip)132 f_columns(ip)
133 struct info *ip;
134 {
135
136 ip->win.ws_col = atoi(ip->arg);
137 ip->wset = 1;
138 }
139
140 void
f_dec(ip)141 f_dec(ip)
142 struct info *ip;
143 {
144
145 ip->t.c_cc[VERASE] = (u_char)0177;
146 ip->t.c_cc[VKILL] = CTRL('u');
147 ip->t.c_cc[VINTR] = CTRL('c');
148 ip->t.c_lflag &= ~ECHOPRT;
149 ip->t.c_lflag |= ECHOE|ECHOKE|ECHOCTL;
150 ip->t.c_iflag &= ~IXANY;
151 ip->set = 1;
152 }
153
154 void
f_everything(ip)155 f_everything(ip)
156 struct info *ip;
157 {
158
159 print(&ip->t, &ip->win, ip->ldisc, BSD);
160 }
161
162 void
f_extproc(ip)163 f_extproc(ip)
164 struct info *ip;
165 {
166
167 if (ip->off) {
168 int tmp = 0;
169 (void)ioctl(ip->fd, TIOCEXT, &tmp);
170 } else {
171 int tmp = 1;
172 (void)ioctl(ip->fd, TIOCEXT, &tmp);
173 }
174 ip->set = 1;
175 }
176
177 void
f_ispeed(ip)178 f_ispeed(ip)
179 struct info *ip;
180 {
181
182 cfsetispeed(&ip->t, atoi(ip->arg));
183 ip->set = 1;
184 }
185
186 void
f_nl(ip)187 f_nl(ip)
188 struct info *ip;
189 {
190
191 if (ip->off) {
192 ip->t.c_iflag |= ICRNL;
193 ip->t.c_oflag |= ONLCR;
194 } else {
195 ip->t.c_iflag &= ~ICRNL;
196 ip->t.c_oflag &= ~ONLCR;
197 }
198 ip->set = 1;
199 }
200
201 void
f_ospeed(ip)202 f_ospeed(ip)
203 struct info *ip;
204 {
205
206 cfsetospeed(&ip->t, atoi(ip->arg));
207 ip->set = 1;
208 }
209
210 void
f_raw(ip)211 f_raw(ip)
212 struct info *ip;
213 {
214
215 if (ip->off)
216 f_sane(ip);
217 else {
218 cfmakeraw(&ip->t);
219 ip->t.c_cflag &= ~(CSIZE|PARENB);
220 ip->t.c_cflag |= CS8;
221 ip->set = 1;
222 }
223 }
224
225 void
f_rows(ip)226 f_rows(ip)
227 struct info *ip;
228 {
229
230 ip->win.ws_row = atoi(ip->arg);
231 ip->wset = 1;
232 }
233
234 void
f_sane(ip)235 f_sane(ip)
236 struct info *ip;
237 {
238
239 ip->t.c_cflag = TTYDEF_CFLAG | (ip->t.c_cflag & CLOCAL);
240 ip->t.c_iflag = TTYDEF_IFLAG;
241 ip->t.c_iflag |= ICRNL;
242 /* preserve user-preference flags in lflag */
243 #define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH)
244 ip->t.c_lflag = TTYDEF_LFLAG | (ip->t.c_lflag & LKEEP);
245 ip->t.c_oflag = TTYDEF_OFLAG;
246 ip->set = 1;
247 }
248
249 void
f_size(ip)250 f_size(ip)
251 struct info *ip;
252 {
253
254 (void)printf("%d %d\n", ip->win.ws_row, ip->win.ws_col);
255 }
256
257 void
f_speed(ip)258 f_speed(ip)
259 struct info *ip;
260 {
261
262 (void)printf("%d\n", cfgetospeed(&ip->t));
263 }
264
265 void
f_tty(ip)266 f_tty(ip)
267 struct info *ip;
268 {
269 int tmp;
270
271 tmp = TTYDISC;
272 if (ioctl(0, TIOCSETD, &tmp) < 0)
273 err(1, "TIOCSETD");
274 }
275