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