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