xref: /freebsd/bin/stty/key.c (revision e043f37205ffbde5627ff299ad25cd532f2956f0)
14b88c807SRodney W. Grimes /*-
24b88c807SRodney W. Grimes  * Copyright (c) 1991, 1993, 1994
34b88c807SRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
44b88c807SRodney W. Grimes  *
54b88c807SRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
64b88c807SRodney W. Grimes  * modification, are permitted provided that the following conditions
74b88c807SRodney W. Grimes  * are met:
84b88c807SRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
94b88c807SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
104b88c807SRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
114b88c807SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
124b88c807SRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
13*fbbd9655SWarner Losh  * 3. Neither the name of the University nor the names of its contributors
144b88c807SRodney W. Grimes  *    may be used to endorse or promote products derived from this software
154b88c807SRodney W. Grimes  *    without specific prior written permission.
164b88c807SRodney W. Grimes  *
174b88c807SRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
184b88c807SRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
194b88c807SRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
204b88c807SRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
214b88c807SRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
224b88c807SRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
234b88c807SRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
244b88c807SRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
254b88c807SRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
264b88c807SRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
274b88c807SRodney W. Grimes  * SUCH DAMAGE.
284b88c807SRodney W. Grimes  */
294b88c807SRodney W. Grimes 
304b88c807SRodney W. Grimes #include <sys/types.h>
314b88c807SRodney W. Grimes 
324b88c807SRodney W. Grimes #include <err.h>
334b88c807SRodney W. Grimes #include <stdlib.h>
344b88c807SRodney W. Grimes #include <stdio.h>
354b88c807SRodney W. Grimes #include <string.h>
364b88c807SRodney W. Grimes 
374b88c807SRodney W. Grimes #include "stty.h"
384b88c807SRodney W. Grimes #include "extern.h"
394b88c807SRodney W. Grimes 
404b88c807SRodney W. Grimes __BEGIN_DECLS
415134c3f7SWarner Losh static int c_key(const void *, const void *);
425134c3f7SWarner Losh void	f_all(struct info *);
435134c3f7SWarner Losh void	f_cbreak(struct info *);
445134c3f7SWarner Losh void	f_columns(struct info *);
455134c3f7SWarner Losh void	f_dec(struct info *);
465134c3f7SWarner Losh void	f_ek(struct info *);
475134c3f7SWarner Losh void	f_everything(struct info *);
485134c3f7SWarner Losh void	f_extproc(struct info *);
495134c3f7SWarner Losh void	f_ispeed(struct info *);
505134c3f7SWarner Losh void	f_nl(struct info *);
515134c3f7SWarner Losh void	f_ospeed(struct info *);
525134c3f7SWarner Losh void	f_raw(struct info *);
535134c3f7SWarner Losh void	f_rows(struct info *);
545134c3f7SWarner Losh void	f_sane(struct info *);
555134c3f7SWarner Losh void	f_size(struct info *);
565134c3f7SWarner Losh void	f_speed(struct info *);
575134c3f7SWarner Losh void	f_tty(struct info *);
584b88c807SRodney W. Grimes __END_DECLS
594b88c807SRodney W. Grimes 
604b88c807SRodney W. Grimes static struct key {
615e5a5667SKris Kennaway 	const char *name;			/* name */
625134c3f7SWarner Losh 	void (*f)(struct info *);		/* function */
634b88c807SRodney W. Grimes #define	F_NEEDARG	0x01			/* needs an argument */
644b88c807SRodney W. Grimes #define	F_OFFOK		0x02			/* can turn off */
654b88c807SRodney W. Grimes 	int flags;
664b88c807SRodney W. Grimes } keys[] = {
674b88c807SRodney W. Grimes 	{ "all",	f_all,		0 },
684b88c807SRodney W. Grimes 	{ "cbreak",	f_cbreak,	F_OFFOK },
694b88c807SRodney W. Grimes 	{ "cols",	f_columns,	F_NEEDARG },
704b88c807SRodney W. Grimes 	{ "columns",	f_columns,	F_NEEDARG },
714b88c807SRodney W. Grimes 	{ "cooked", 	f_sane,		0 },
724b88c807SRodney W. Grimes 	{ "dec",	f_dec,		0 },
73d736886aSDima Dorfman 	{ "ek",		f_ek,		0 },
744b88c807SRodney W. Grimes 	{ "everything",	f_everything,	0 },
754b88c807SRodney W. Grimes 	{ "extproc",	f_extproc,	F_OFFOK },
764b88c807SRodney W. Grimes 	{ "ispeed",	f_ispeed,	F_NEEDARG },
774b88c807SRodney W. Grimes 	{ "new",	f_tty,		0 },
784b88c807SRodney W. Grimes 	{ "nl",		f_nl,		F_OFFOK },
794b88c807SRodney W. Grimes 	{ "old",	f_tty,		0 },
804b88c807SRodney W. Grimes 	{ "ospeed",	f_ospeed,	F_NEEDARG },
814b88c807SRodney W. Grimes 	{ "raw",	f_raw,		F_OFFOK },
824b88c807SRodney W. Grimes 	{ "rows",	f_rows,		F_NEEDARG },
834b88c807SRodney W. Grimes 	{ "sane",	f_sane,		0 },
844b88c807SRodney W. Grimes 	{ "size",	f_size,		0 },
854b88c807SRodney W. Grimes 	{ "speed",	f_speed,	0 },
864b88c807SRodney W. Grimes 	{ "tty",	f_tty,		0 },
874b88c807SRodney W. Grimes };
884b88c807SRodney W. Grimes 
894b88c807SRodney W. Grimes static int
c_key(const void * a,const void * b)905134c3f7SWarner Losh c_key(const void *a, const void *b)
914b88c807SRodney W. Grimes {
924b88c807SRodney W. Grimes 
935e5a5667SKris Kennaway         return (strcmp(((const struct key *)a)->name, ((const struct key *)b)->name));
944b88c807SRodney W. Grimes }
954b88c807SRodney W. Grimes 
964b88c807SRodney W. Grimes int
ksearch(char *** argvp,struct info * ip)975134c3f7SWarner Losh ksearch(char ***argvp, struct info *ip)
984b88c807SRodney W. Grimes {
994b88c807SRodney W. Grimes 	char *name;
1004b88c807SRodney W. Grimes 	struct key *kp, tmp;
1014b88c807SRodney W. Grimes 
1024b88c807SRodney W. Grimes 	name = **argvp;
1034b88c807SRodney W. Grimes 	if (*name == '-') {
1044b88c807SRodney W. Grimes 		ip->off = 1;
1054b88c807SRodney W. Grimes 		++name;
1064b88c807SRodney W. Grimes 	} else
1074b88c807SRodney W. Grimes 		ip->off = 0;
1084b88c807SRodney W. Grimes 
1094b88c807SRodney W. Grimes 	tmp.name = name;
1104b88c807SRodney W. Grimes 	if (!(kp = (struct key *)bsearch(&tmp, keys,
1114b88c807SRodney W. Grimes 	    sizeof(keys)/sizeof(struct key), sizeof(struct key), c_key)))
1124b88c807SRodney W. Grimes 		return (0);
1134b88c807SRodney W. Grimes 	if (!(kp->flags & F_OFFOK) && ip->off) {
114b74ad526SSteve Price 		warnx("illegal option -- -%s", name);
1154b88c807SRodney W. Grimes 		usage();
1164b88c807SRodney W. Grimes 	}
1174b88c807SRodney W. Grimes 	if (kp->flags & F_NEEDARG && !(ip->arg = *++*argvp)) {
118b74ad526SSteve Price 		warnx("option requires an argument -- %s", name);
1194b88c807SRodney W. Grimes 		usage();
1204b88c807SRodney W. Grimes 	}
1214b88c807SRodney W. Grimes 	kp->f(ip);
1224b88c807SRodney W. Grimes 	return (1);
1234b88c807SRodney W. Grimes }
1244b88c807SRodney W. Grimes 
1254b88c807SRodney W. Grimes void
f_all(struct info * ip)1265134c3f7SWarner Losh f_all(struct info *ip)
1274b88c807SRodney W. Grimes {
128df41cfeeSAndrey A. Chernov 	print(&ip->t, &ip->win, ip->ldisc, BSD);
1294b88c807SRodney W. Grimes }
1304b88c807SRodney W. Grimes 
1314b88c807SRodney W. Grimes void
f_cbreak(struct info * ip)1325134c3f7SWarner Losh f_cbreak(struct info *ip)
1334b88c807SRodney W. Grimes {
1344b88c807SRodney W. Grimes 
1354b88c807SRodney W. Grimes 	if (ip->off)
1364b88c807SRodney W. Grimes 		f_sane(ip);
1374b88c807SRodney W. Grimes 	else {
1384b88c807SRodney W. Grimes 		ip->t.c_iflag |= BRKINT|IXON|IMAXBEL;
1394b88c807SRodney W. Grimes 		ip->t.c_oflag |= OPOST;
1404b88c807SRodney W. Grimes 		ip->t.c_lflag |= ISIG|IEXTEN;
1414b88c807SRodney W. Grimes 		ip->t.c_lflag &= ~ICANON;
1424b88c807SRodney W. Grimes 		ip->set = 1;
1434b88c807SRodney W. Grimes 	}
1444b88c807SRodney W. Grimes }
1454b88c807SRodney W. Grimes 
1464b88c807SRodney W. Grimes void
f_columns(struct info * ip)1475134c3f7SWarner Losh f_columns(struct info *ip)
1484b88c807SRodney W. Grimes {
1494b88c807SRodney W. Grimes 
1504b88c807SRodney W. Grimes 	ip->win.ws_col = atoi(ip->arg);
1514b88c807SRodney W. Grimes 	ip->wset = 1;
1524b88c807SRodney W. Grimes }
1534b88c807SRodney W. Grimes 
1544b88c807SRodney W. Grimes void
f_dec(struct info * ip)1555134c3f7SWarner Losh f_dec(struct info *ip)
1564b88c807SRodney W. Grimes {
1574b88c807SRodney W. Grimes 
1584b88c807SRodney W. Grimes 	ip->t.c_cc[VERASE] = (u_char)0177;
1594b88c807SRodney W. Grimes 	ip->t.c_cc[VKILL] = CTRL('u');
1604b88c807SRodney W. Grimes 	ip->t.c_cc[VINTR] = CTRL('c');
1614b88c807SRodney W. Grimes 	ip->t.c_lflag &= ~ECHOPRT;
1624b88c807SRodney W. Grimes 	ip->t.c_lflag |= ECHOE|ECHOKE|ECHOCTL;
1634b88c807SRodney W. Grimes 	ip->t.c_iflag &= ~IXANY;
1644b88c807SRodney W. Grimes 	ip->set = 1;
1654b88c807SRodney W. Grimes }
1664b88c807SRodney W. Grimes 
1674b88c807SRodney W. Grimes void
f_ek(struct info * ip)1685134c3f7SWarner Losh f_ek(struct info *ip)
169d736886aSDima Dorfman {
170d736886aSDima Dorfman 
171d736886aSDima Dorfman 	ip->t.c_cc[VERASE] = CERASE;
172d736886aSDima Dorfman 	ip->t.c_cc[VKILL] = CKILL;
173d736886aSDima Dorfman 	ip->set = 1;
174d736886aSDima Dorfman }
175d736886aSDima Dorfman 
176d736886aSDima Dorfman void
f_everything(struct info * ip)1775134c3f7SWarner Losh f_everything(struct info *ip)
1784b88c807SRodney W. Grimes {
1794b88c807SRodney W. Grimes 
180df41cfeeSAndrey A. Chernov 	print(&ip->t, &ip->win, ip->ldisc, BSD);
1814b88c807SRodney W. Grimes }
1824b88c807SRodney W. Grimes 
1834b88c807SRodney W. Grimes void
f_extproc(struct info * ip)1845134c3f7SWarner Losh f_extproc(struct info *ip)
1854b88c807SRodney W. Grimes {
1864b88c807SRodney W. Grimes 
1874507dafdSSteve Price 	if (ip->off) {
1884507dafdSSteve Price 		int tmp = 0;
1894b88c807SRodney W. Grimes 		(void)ioctl(ip->fd, TIOCEXT, &tmp);
1904b88c807SRodney W. Grimes 	} else {
1914507dafdSSteve Price 		int tmp = 1;
1924b88c807SRodney W. Grimes 		(void)ioctl(ip->fd, TIOCEXT, &tmp);
1934b88c807SRodney W. Grimes 	}
1944b88c807SRodney W. Grimes }
1954b88c807SRodney W. Grimes 
1964b88c807SRodney W. Grimes void
f_ispeed(struct info * ip)1975134c3f7SWarner Losh f_ispeed(struct info *ip)
1984b88c807SRodney W. Grimes {
1994b88c807SRodney W. Grimes 
2005e5a5667SKris Kennaway 	cfsetispeed(&ip->t, (speed_t)atoi(ip->arg));
2014b88c807SRodney W. Grimes 	ip->set = 1;
2024b88c807SRodney W. Grimes }
2034b88c807SRodney W. Grimes 
2044b88c807SRodney W. Grimes void
f_nl(struct info * ip)2055134c3f7SWarner Losh f_nl(struct info *ip)
2064b88c807SRodney W. Grimes {
2074b88c807SRodney W. Grimes 
2084b88c807SRodney W. Grimes 	if (ip->off) {
2094b88c807SRodney W. Grimes 		ip->t.c_iflag |= ICRNL;
2104b88c807SRodney W. Grimes 		ip->t.c_oflag |= ONLCR;
2114b88c807SRodney W. Grimes 	} else {
2124b88c807SRodney W. Grimes 		ip->t.c_iflag &= ~ICRNL;
2134b88c807SRodney W. Grimes 		ip->t.c_oflag &= ~ONLCR;
2144b88c807SRodney W. Grimes 	}
2154b88c807SRodney W. Grimes 	ip->set = 1;
2164b88c807SRodney W. Grimes }
2174b88c807SRodney W. Grimes 
2184b88c807SRodney W. Grimes void
f_ospeed(struct info * ip)2195134c3f7SWarner Losh f_ospeed(struct info *ip)
2204b88c807SRodney W. Grimes {
2214b88c807SRodney W. Grimes 
2225e5a5667SKris Kennaway 	cfsetospeed(&ip->t, (speed_t)atoi(ip->arg));
2234b88c807SRodney W. Grimes 	ip->set = 1;
2244b88c807SRodney W. Grimes }
2254b88c807SRodney W. Grimes 
2264b88c807SRodney W. Grimes void
f_raw(struct info * ip)2275134c3f7SWarner Losh f_raw(struct info *ip)
2284b88c807SRodney W. Grimes {
2294b88c807SRodney W. Grimes 
2304b88c807SRodney W. Grimes 	if (ip->off)
2314b88c807SRodney W. Grimes 		f_sane(ip);
2324b88c807SRodney W. Grimes 	else {
2334b88c807SRodney W. Grimes 		cfmakeraw(&ip->t);
2344b88c807SRodney W. Grimes 		ip->t.c_cflag &= ~(CSIZE|PARENB);
2354b88c807SRodney W. Grimes 		ip->t.c_cflag |= CS8;
2364b88c807SRodney W. Grimes 		ip->set = 1;
2374b88c807SRodney W. Grimes 	}
2384b88c807SRodney W. Grimes }
2394b88c807SRodney W. Grimes 
2404b88c807SRodney W. Grimes void
f_rows(struct info * ip)2415134c3f7SWarner Losh f_rows(struct info *ip)
2424b88c807SRodney W. Grimes {
2434b88c807SRodney W. Grimes 
2444b88c807SRodney W. Grimes 	ip->win.ws_row = atoi(ip->arg);
2454b88c807SRodney W. Grimes 	ip->wset = 1;
2464b88c807SRodney W. Grimes }
2474b88c807SRodney W. Grimes 
2484b88c807SRodney W. Grimes void
f_sane(struct info * ip)2495134c3f7SWarner Losh f_sane(struct info *ip)
2504b88c807SRodney W. Grimes {
251736fc286SEd Schouten 	struct termios def;
2524b88c807SRodney W. Grimes 
253736fc286SEd Schouten 	cfmakesane(&def);
254736fc286SEd Schouten 	ip->t.c_cflag = def.c_cflag | (ip->t.c_cflag & CLOCAL);
255736fc286SEd Schouten 	ip->t.c_iflag = def.c_iflag;
2564b88c807SRodney W. Grimes 	/* preserve user-preference flags in lflag */
2574b88c807SRodney W. Grimes #define	LKEEP	(ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH)
258736fc286SEd Schouten 	ip->t.c_lflag = def.c_lflag | (ip->t.c_lflag & LKEEP);
259736fc286SEd Schouten 	ip->t.c_oflag = def.c_oflag;
2604b88c807SRodney W. Grimes 	ip->set = 1;
2614b88c807SRodney W. Grimes }
2624b88c807SRodney W. Grimes 
2634b88c807SRodney W. Grimes void
f_size(struct info * ip)2645134c3f7SWarner Losh f_size(struct info *ip)
2654b88c807SRodney W. Grimes {
2664b88c807SRodney W. Grimes 
2674b88c807SRodney W. Grimes 	(void)printf("%d %d\n", ip->win.ws_row, ip->win.ws_col);
2684b88c807SRodney W. Grimes }
2694b88c807SRodney W. Grimes 
2704b88c807SRodney W. Grimes void
f_speed(struct info * ip)2715134c3f7SWarner Losh f_speed(struct info *ip)
2724b88c807SRodney W. Grimes {
2734b88c807SRodney W. Grimes 
2740eb7b1caSBruce Evans 	(void)printf("%lu\n", (u_long)cfgetospeed(&ip->t));
2754b88c807SRodney W. Grimes }
2764b88c807SRodney W. Grimes 
2774b88c807SRodney W. Grimes void
f_tty(struct info * ip)2785134c3f7SWarner Losh f_tty(struct info *ip)
2794b88c807SRodney W. Grimes {
2804b88c807SRodney W. Grimes 	int tmp;
2814b88c807SRodney W. Grimes 
2824b88c807SRodney W. Grimes 	tmp = TTYDISC;
2830b51c95dSAndrey A. Chernov 	if (ioctl(ip->fd, TIOCSETD, &tmp) < 0)
2844b88c807SRodney W. Grimes 		err(1, "TIOCSETD");
2854b88c807SRodney W. Grimes }
286