use C library err/warn routines, index->strchr, etc.
[unix-history] / usr / src / bin / stty / key.c
CommitLineData
b21d5003
KB
1/*-
2 * Copyright (c) 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8#ifndef lint
f2e315b0 9static char sccsid[] = "@(#)key.c 5.5 (Berkeley) %G%";
b21d5003
KB
10#endif /* not lint */
11
12#include <sys/types.h>
f2e315b0
KB
13
14#include <err.h>
b21d5003
KB
15#include <errno.h>
16#include <stdlib.h>
17#include <stdio.h>
18#include <string.h>
f2e315b0 19
b21d5003
KB
20#include "stty.h"
21#include "extern.h"
22
23__BEGIN_DECLS
b21d5003
KB
24void f_all __P((struct info *));
25void f_cbreak __P((struct info *));
26void f_columns __P((struct info *));
27void f_dec __P((struct info *));
28void f_everything __P((struct info *));
29void f_extproc __P((struct info *));
30void f_ispeed __P((struct info *));
31void f_nl __P((struct info *));
32void f_ospeed __P((struct info *));
33void f_raw __P((struct info *));
34void f_rows __P((struct info *));
35void f_sane __P((struct info *));
36void f_size __P((struct info *));
37void f_speed __P((struct info *));
38void f_tty __P((struct info *));
39__END_DECLS
40
3ac03562
KB
41static 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[] = {
f2e315b0
KB
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 },
b21d5003
KB
67};
68
f2e315b0 69int
14cc5c1c
KB
70ksearch(argvp, ip)
71 char ***argvp;
72 struct info *ip;
b21d5003 73{
14cc5c1c
KB
74 register struct key *kp;
75 register char *name;
b21d5003 76 struct key tmp;
14cc5c1c
KB
77 static int c_key __P((const void *, const void *));
78
79 name = **argvp;
80 if (*name == '-') {
81 ip->off = 1;
82 ++name;
83 } else
84 ip->off = 0;
b21d5003
KB
85
86 tmp.name = name;
14cc5c1c
KB
87 if (!(kp = (struct key *)bsearch(&tmp, keys,
88 sizeof(keys)/sizeof(struct key), sizeof(struct key), c_key)))
f2e315b0
KB
89 return (0);
90 if (!(kp->flags & F_OFFOK) && ip->off) {
91 errx(1, "illegal option -- %s", name);
92 usage();
93 }
94 if (kp->flags & F_NEEDARG && !(ip->arg = *++*argvp)) {
95 errx(1, "option requires an argument -- %s", name);
96 usage();
97 }
14cc5c1c 98 kp->f(ip);
f2e315b0 99 return (1);
b21d5003
KB
100}
101
f2e315b0 102static int
b21d5003
KB
103c_key(a, b)
104 const void *a, *b;
105{
f2e315b0 106 return (strcmp(((struct key *)a)->name, ((struct key *)b)->name));
b21d5003
KB
107}
108
109void
110f_all(ip)
111 struct info *ip;
112{
113 print(&ip->t, &ip->win, ip->ldisc, BSD);
114}
115
116void
117f_cbreak(ip)
118 struct info *ip;
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
131void
132f_columns(ip)
133 struct info *ip;
134{
135 ip->win.ws_col = atoi(ip->arg);
136 ip->wset = 1;
137}
138
139void
140f_dec(ip)
141 struct info *ip;
142{
143 ip->t.c_cc[VERASE] = (u_char)0177;
144 ip->t.c_cc[VKILL] = CTRL('u');
145 ip->t.c_cc[VINTR] = CTRL('c');
146 ip->t.c_lflag &= ~ECHOPRT;
147 ip->t.c_lflag |= ECHOE|ECHOKE|ECHOCTL;
148 ip->t.c_iflag &= ~IXANY;
149 ip->set = 1;
150}
151
152void
153f_everything(ip)
154 struct info *ip;
155{
156 print(&ip->t, &ip->win, ip->ldisc, BSD);
157}
158
159void
160f_extproc(ip)
161 struct info *ip;
162{
163 int tmp;
164
165 if (ip->set) {
166 tmp = 1;
167 (void)ioctl(ip->fd, TIOCEXT, &tmp);
168 } else {
169 tmp = 0;
170 (void)ioctl(ip->fd, TIOCEXT, &tmp);
171 }
172}
173
174void
175f_ispeed(ip)
176 struct info *ip;
177{
178 cfsetispeed(&ip->t, atoi(ip->arg));
179 ip->set = 1;
180}
181
182void
183f_nl(ip)
184 struct info *ip;
185{
186 if (ip->off) {
187 ip->t.c_iflag |= ICRNL;
188 ip->t.c_oflag |= ONLCR;
189 } else {
190 ip->t.c_iflag &= ~ICRNL;
191 ip->t.c_oflag &= ~ONLCR;
192 }
193 ip->set = 1;
194}
195
196void
197f_ospeed(ip)
198 struct info *ip;
199{
200 cfsetospeed(&ip->t, atoi(ip->arg));
201 ip->set = 1;
202}
203
204void
205f_raw(ip)
206 struct info *ip;
207{
208 if (ip->off)
209 f_sane(ip);
210 else {
211 cfmakeraw(&ip->t);
212 ip->t.c_cflag &= ~(CSIZE|PARENB);
213 ip->t.c_cflag |= CS8;
214 ip->set = 1;
215 }
216}
217
218void
219f_rows(ip)
220 struct info *ip;
221{
222 ip->win.ws_row = atoi(ip->arg);
223 ip->wset = 1;
224}
225
226void
227f_sane(ip)
228 struct info *ip;
229{
230 ip->t.c_cflag = TTYDEF_CFLAG | (ip->t.c_cflag & CLOCAL);
231 ip->t.c_iflag = TTYDEF_IFLAG;
232 ip->t.c_iflag |= ICRNL;
233 /* preserve user-preference flags in lflag */
234#define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH)
235 ip->t.c_lflag = TTYDEF_LFLAG | (ip->t.c_lflag & LKEEP);
236 ip->t.c_oflag = TTYDEF_OFLAG;
237 ip->set = 1;
238}
239
240void
241f_size(ip)
242 struct info *ip;
243{
244 (void)printf("%d %d\n", ip->win.ws_row, ip->win.ws_col);
245}
246
247void
248f_speed(ip)
249 struct info *ip;
250{
251 (void)printf("%d\n", cfgetospeed(&ip->t));
252}
253
254void
255f_tty(ip)
256 struct info *ip;
257{
258 int tmp;
259
260 tmp = TTYDISC;
261 if (ioctl(0, TIOCSETD, &tmp) < 0)
f2e315b0 262 err(1, "TIOCSETD");
b21d5003 263}