key.c revision 272461
1219820Sjeff/*- 2219820Sjeff * Copyright (c) 1991, 1993, 1994 3219820Sjeff * The Regents of the University of California. All rights reserved. 4219820Sjeff * 5219820Sjeff * Redistribution and use in source and binary forms, with or without 6219820Sjeff * modification, are permitted provided that the following conditions 7219820Sjeff * are met: 8219820Sjeff * 1. Redistributions of source code must retain the above copyright 9219820Sjeff * notice, this list of conditions and the following disclaimer. 10219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright 11219820Sjeff * notice, this list of conditions and the following disclaimer in the 12219820Sjeff * documentation and/or other materials provided with the distribution. 13219820Sjeff * 4. Neither the name of the University nor the names of its contributors 14219820Sjeff * may be used to endorse or promote products derived from this software 15219820Sjeff * without specific prior written permission. 16219820Sjeff * 17219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18219820Sjeff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19219820Sjeff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20219820Sjeff * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21219820Sjeff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22219820Sjeff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23219820Sjeff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24219820Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25219820Sjeff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26219820Sjeff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27219820Sjeff * SUCH DAMAGE. 28219820Sjeff */ 29219820Sjeff 30219820Sjeff#ifndef lint 31219820Sjeff#if 0 32219820Sjeffstatic char sccsid[] = "@(#)key.c 8.3 (Berkeley) 4/2/94"; 33219820Sjeff#endif 34219820Sjeff#endif /* not lint */ 35219820Sjeff#include <sys/cdefs.h> 36219820Sjeff__FBSDID("$FreeBSD: releng/10.1/bin/stty/key.c 214680 2010-11-02 17:00:56Z ed $"); 37219820Sjeff 38219820Sjeff#include <sys/types.h> 39219820Sjeff 40219820Sjeff#include <err.h> 41219820Sjeff#include <errno.h> 42219820Sjeff#include <stdlib.h> 43219820Sjeff#include <stdio.h> 44219820Sjeff#include <string.h> 45219820Sjeff 46219820Sjeff#include "stty.h" 47219820Sjeff#include "extern.h" 48219820Sjeff 49219820Sjeff__BEGIN_DECLS 50219820Sjeffstatic int c_key(const void *, const void *); 51219820Sjeffvoid f_all(struct info *); 52219820Sjeffvoid f_cbreak(struct info *); 53219820Sjeffvoid f_columns(struct info *); 54219820Sjeffvoid f_dec(struct info *); 55219820Sjeffvoid f_ek(struct info *); 56219820Sjeffvoid f_everything(struct info *); 57219820Sjeffvoid f_extproc(struct info *); 58219820Sjeffvoid f_ispeed(struct info *); 59219820Sjeffvoid f_nl(struct info *); 60219820Sjeffvoid f_ospeed(struct info *); 61219820Sjeffvoid f_raw(struct info *); 62219820Sjeffvoid f_rows(struct info *); 63219820Sjeffvoid f_sane(struct info *); 64219820Sjeffvoid f_size(struct info *); 65219820Sjeffvoid f_speed(struct info *); 66219820Sjeffvoid f_tty(struct info *); 67219820Sjeff__END_DECLS 68219820Sjeff 69219820Sjeffstatic struct key { 70219820Sjeff const char *name; /* name */ 71219820Sjeff void (*f)(struct info *); /* function */ 72219820Sjeff#define F_NEEDARG 0x01 /* needs an argument */ 73219820Sjeff#define F_OFFOK 0x02 /* can turn off */ 74219820Sjeff int flags; 75219820Sjeff} keys[] = { 76219820Sjeff { "all", f_all, 0 }, 77219820Sjeff { "cbreak", f_cbreak, F_OFFOK }, 78219820Sjeff { "cols", f_columns, F_NEEDARG }, 79219820Sjeff { "columns", f_columns, F_NEEDARG }, 80219820Sjeff { "cooked", f_sane, 0 }, 81219820Sjeff { "dec", f_dec, 0 }, 82219820Sjeff { "ek", f_ek, 0 }, 83219820Sjeff { "everything", f_everything, 0 }, 84219820Sjeff { "extproc", f_extproc, F_OFFOK }, 85219820Sjeff { "ispeed", f_ispeed, F_NEEDARG }, 86219820Sjeff { "new", f_tty, 0 }, 87219820Sjeff { "nl", f_nl, F_OFFOK }, 88219820Sjeff { "old", f_tty, 0 }, 89219820Sjeff { "ospeed", f_ospeed, F_NEEDARG }, 90219820Sjeff { "raw", f_raw, F_OFFOK }, 91219820Sjeff { "rows", f_rows, F_NEEDARG }, 92219820Sjeff { "sane", f_sane, 0 }, 93219820Sjeff { "size", f_size, 0 }, 94219820Sjeff { "speed", f_speed, 0 }, 95219820Sjeff { "tty", f_tty, 0 }, 96219820Sjeff}; 97219820Sjeff 98219820Sjeffstatic int 99219820Sjeffc_key(const void *a, const void *b) 100219820Sjeff{ 101219820Sjeff 102219820Sjeff return (strcmp(((const struct key *)a)->name, ((const struct key *)b)->name)); 103219820Sjeff} 104219820Sjeff 105219820Sjeffint 106219820Sjeffksearch(char ***argvp, struct info *ip) 107219820Sjeff{ 108219820Sjeff char *name; 109219820Sjeff struct key *kp, tmp; 110219820Sjeff 111219820Sjeff name = **argvp; 112219820Sjeff if (*name == '-') { 113219820Sjeff ip->off = 1; 114219820Sjeff ++name; 115219820Sjeff } else 116219820Sjeff ip->off = 0; 117219820Sjeff 118219820Sjeff tmp.name = name; 119219820Sjeff if (!(kp = (struct key *)bsearch(&tmp, keys, 120219820Sjeff sizeof(keys)/sizeof(struct key), sizeof(struct key), c_key))) 121219820Sjeff return (0); 122219820Sjeff if (!(kp->flags & F_OFFOK) && ip->off) { 123219820Sjeff warnx("illegal option -- -%s", name); 124219820Sjeff usage(); 125219820Sjeff } 126219820Sjeff if (kp->flags & F_NEEDARG && !(ip->arg = *++*argvp)) { 127219820Sjeff warnx("option requires an argument -- %s", name); 128219820Sjeff usage(); 129219820Sjeff } 130219820Sjeff kp->f(ip); 131219820Sjeff return (1); 132219820Sjeff} 133219820Sjeff 134219820Sjeffvoid 135219820Sjefff_all(struct info *ip) 136219820Sjeff{ 137219820Sjeff print(&ip->t, &ip->win, ip->ldisc, BSD); 138219820Sjeff} 139219820Sjeff 140219820Sjeffvoid 141219820Sjefff_cbreak(struct info *ip) 142219820Sjeff{ 143219820Sjeff 144219820Sjeff if (ip->off) 145219820Sjeff f_sane(ip); 146219820Sjeff else { 147219820Sjeff ip->t.c_iflag |= BRKINT|IXON|IMAXBEL; 148219820Sjeff ip->t.c_oflag |= OPOST; 149219820Sjeff ip->t.c_lflag |= ISIG|IEXTEN; 150219820Sjeff ip->t.c_lflag &= ~ICANON; 151219820Sjeff ip->set = 1; 152219820Sjeff } 153219820Sjeff} 154219820Sjeff 155219820Sjeffvoid 156219820Sjefff_columns(struct info *ip) 157219820Sjeff{ 158219820Sjeff 159219820Sjeff ip->win.ws_col = atoi(ip->arg); 160219820Sjeff ip->wset = 1; 161219820Sjeff} 162219820Sjeff 163219820Sjeffvoid 164219820Sjefff_dec(struct info *ip) 165219820Sjeff{ 166219820Sjeff 167219820Sjeff ip->t.c_cc[VERASE] = (u_char)0177; 168219820Sjeff ip->t.c_cc[VKILL] = CTRL('u'); 169219820Sjeff ip->t.c_cc[VINTR] = CTRL('c'); 170219820Sjeff ip->t.c_lflag &= ~ECHOPRT; 171219820Sjeff ip->t.c_lflag |= ECHOE|ECHOKE|ECHOCTL; 172219820Sjeff ip->t.c_iflag &= ~IXANY; 173219820Sjeff ip->set = 1; 174219820Sjeff} 175219820Sjeff 176219820Sjeffvoid 177219820Sjefff_ek(struct info *ip) 178219820Sjeff{ 179219820Sjeff 180219820Sjeff ip->t.c_cc[VERASE] = CERASE; 181219820Sjeff ip->t.c_cc[VKILL] = CKILL; 182219820Sjeff ip->set = 1; 183219820Sjeff} 184219820Sjeff 185219820Sjeffvoid 186219820Sjefff_everything(struct info *ip) 187219820Sjeff{ 188219820Sjeff 189219820Sjeff print(&ip->t, &ip->win, ip->ldisc, BSD); 190219820Sjeff} 191219820Sjeff 192219820Sjeffvoid 193219820Sjefff_extproc(struct info *ip) 194219820Sjeff{ 195219820Sjeff 196219820Sjeff if (ip->off) { 197219820Sjeff int tmp = 0; 198219820Sjeff (void)ioctl(ip->fd, TIOCEXT, &tmp); 199219820Sjeff } else { 200219820Sjeff int tmp = 1; 201219820Sjeff (void)ioctl(ip->fd, TIOCEXT, &tmp); 202219820Sjeff } 203219820Sjeff} 204219820Sjeff 205219820Sjeffvoid 206219820Sjefff_ispeed(struct info *ip) 207219820Sjeff{ 208219820Sjeff 209219820Sjeff cfsetispeed(&ip->t, (speed_t)atoi(ip->arg)); 210219820Sjeff ip->set = 1; 211219820Sjeff} 212219820Sjeff 213219820Sjeffvoid 214219820Sjefff_nl(struct info *ip) 215219820Sjeff{ 216219820Sjeff 217219820Sjeff if (ip->off) { 218219820Sjeff ip->t.c_iflag |= ICRNL; 219219820Sjeff ip->t.c_oflag |= ONLCR; 220219820Sjeff } else { 221219820Sjeff ip->t.c_iflag &= ~ICRNL; 222219820Sjeff ip->t.c_oflag &= ~ONLCR; 223219820Sjeff } 224219820Sjeff ip->set = 1; 225219820Sjeff} 226219820Sjeff 227219820Sjeffvoid 228219820Sjefff_ospeed(struct info *ip) 229219820Sjeff{ 230219820Sjeff 231219820Sjeff cfsetospeed(&ip->t, (speed_t)atoi(ip->arg)); 232219820Sjeff ip->set = 1; 233219820Sjeff} 234219820Sjeff 235219820Sjeffvoid 236219820Sjefff_raw(struct info *ip) 237219820Sjeff{ 238219820Sjeff 239219820Sjeff if (ip->off) 240219820Sjeff f_sane(ip); 241219820Sjeff else { 242219820Sjeff cfmakeraw(&ip->t); 243219820Sjeff ip->t.c_cflag &= ~(CSIZE|PARENB); 244219820Sjeff ip->t.c_cflag |= CS8; 245219820Sjeff ip->set = 1; 246219820Sjeff } 247219820Sjeff} 248219820Sjeff 249219820Sjeffvoid 250219820Sjefff_rows(struct info *ip) 251219820Sjeff{ 252219820Sjeff 253219820Sjeff ip->win.ws_row = atoi(ip->arg); 254219820Sjeff ip->wset = 1; 255219820Sjeff} 256219820Sjeff 257219820Sjeffvoid 258219820Sjefff_sane(struct info *ip) 259219820Sjeff{ 260219820Sjeff struct termios def; 261219820Sjeff 262219820Sjeff cfmakesane(&def); 263219820Sjeff ip->t.c_cflag = def.c_cflag | (ip->t.c_cflag & CLOCAL); 264219820Sjeff ip->t.c_iflag = def.c_iflag; 265219820Sjeff /* preserve user-preference flags in lflag */ 266219820Sjeff#define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH) 267219820Sjeff ip->t.c_lflag = def.c_lflag | (ip->t.c_lflag & LKEEP); 268219820Sjeff ip->t.c_oflag = def.c_oflag; 269219820Sjeff ip->set = 1; 270219820Sjeff} 271219820Sjeff 272219820Sjeffvoid 273219820Sjefff_size(struct info *ip) 274219820Sjeff{ 275219820Sjeff 276219820Sjeff (void)printf("%d %d\n", ip->win.ws_row, ip->win.ws_col); 277219820Sjeff} 278219820Sjeff 279219820Sjeffvoid 280219820Sjefff_speed(struct info *ip) 281219820Sjeff{ 282219820Sjeff 283219820Sjeff (void)printf("%lu\n", (u_long)cfgetospeed(&ip->t)); 284219820Sjeff} 285219820Sjeff 286219820Sjeffvoid 287219820Sjefff_tty(struct info *ip) 288219820Sjeff{ 289219820Sjeff int tmp; 290219820Sjeff 291219820Sjeff tmp = TTYDISC; 292219820Sjeff if (ioctl(ip->fd, TIOCSETD, &tmp) < 0) 293219820Sjeff err(1, "TIOCSETD"); 294219820Sjeff} 295219820Sjeff