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