11556Srgrimes/*- 21556Srgrimes * Copyright (c) 1991, 1993, 1994 31556Srgrimes * The Regents of the University of California. All rights reserved. 41556Srgrimes * 51556Srgrimes * Redistribution and use in source and binary forms, with or without 61556Srgrimes * modification, are permitted provided that the following conditions 71556Srgrimes * are met: 81556Srgrimes * 1. Redistributions of source code must retain the above copyright 91556Srgrimes * notice, this list of conditions and the following disclaimer. 101556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111556Srgrimes * notice, this list of conditions and the following disclaimer in the 121556Srgrimes * documentation and/or other materials provided with the distribution. 131556Srgrimes * 4. Neither the name of the University nor the names of its contributors 141556Srgrimes * may be used to endorse or promote products derived from this software 151556Srgrimes * without specific prior written permission. 161556Srgrimes * 171556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201556Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271556Srgrimes * SUCH DAMAGE. 281556Srgrimes */ 291556Srgrimes 301556Srgrimes#ifndef lint 3128642Ssteve#if 0 3228642Sstevestatic char sccsid[] = "@(#)key.c 8.3 (Berkeley) 4/2/94"; 3328642Ssteve#endif 341556Srgrimes#endif /* not lint */ 3599110Sobrien#include <sys/cdefs.h> 3699110Sobrien__FBSDID("$FreeBSD$"); 371556Srgrimes 381556Srgrimes#include <sys/types.h> 391556Srgrimes 401556Srgrimes#include <err.h> 411556Srgrimes#include <errno.h> 421556Srgrimes#include <stdlib.h> 431556Srgrimes#include <stdio.h> 441556Srgrimes#include <string.h> 451556Srgrimes 461556Srgrimes#include "stty.h" 471556Srgrimes#include "extern.h" 481556Srgrimes 491556Srgrimes__BEGIN_DECLS 5090111Simpstatic int c_key(const void *, const void *); 5190111Simpvoid f_all(struct info *); 5290111Simpvoid f_cbreak(struct info *); 5390111Simpvoid f_columns(struct info *); 5490111Simpvoid f_dec(struct info *); 5590111Simpvoid f_ek(struct info *); 5690111Simpvoid f_everything(struct info *); 5790111Simpvoid f_extproc(struct info *); 5890111Simpvoid f_ispeed(struct info *); 5990111Simpvoid f_nl(struct info *); 6090111Simpvoid f_ospeed(struct info *); 6190111Simpvoid f_raw(struct info *); 6290111Simpvoid f_rows(struct info *); 6390111Simpvoid f_sane(struct info *); 6490111Simpvoid f_size(struct info *); 6590111Simpvoid f_speed(struct info *); 6690111Simpvoid f_tty(struct info *); 671556Srgrimes__END_DECLS 681556Srgrimes 691556Srgrimesstatic struct key { 7076810Skris const char *name; /* name */ 7190111Simp void (*f)(struct info *); /* function */ 721556Srgrimes#define F_NEEDARG 0x01 /* needs an argument */ 731556Srgrimes#define F_OFFOK 0x02 /* can turn off */ 741556Srgrimes int flags; 751556Srgrimes} keys[] = { 761556Srgrimes { "all", f_all, 0 }, 771556Srgrimes { "cbreak", f_cbreak, F_OFFOK }, 781556Srgrimes { "cols", f_columns, F_NEEDARG }, 791556Srgrimes { "columns", f_columns, F_NEEDARG }, 801556Srgrimes { "cooked", f_sane, 0 }, 811556Srgrimes { "dec", f_dec, 0 }, 8282237Sdd { "ek", f_ek, 0 }, 831556Srgrimes { "everything", f_everything, 0 }, 841556Srgrimes { "extproc", f_extproc, F_OFFOK }, 851556Srgrimes { "ispeed", f_ispeed, F_NEEDARG }, 861556Srgrimes { "new", f_tty, 0 }, 871556Srgrimes { "nl", f_nl, F_OFFOK }, 881556Srgrimes { "old", f_tty, 0 }, 891556Srgrimes { "ospeed", f_ospeed, F_NEEDARG }, 901556Srgrimes { "raw", f_raw, F_OFFOK }, 911556Srgrimes { "rows", f_rows, F_NEEDARG }, 921556Srgrimes { "sane", f_sane, 0 }, 931556Srgrimes { "size", f_size, 0 }, 941556Srgrimes { "speed", f_speed, 0 }, 951556Srgrimes { "tty", f_tty, 0 }, 961556Srgrimes}; 971556Srgrimes 981556Srgrimesstatic int 9990111Simpc_key(const void *a, const void *b) 1001556Srgrimes{ 1011556Srgrimes 10276810Skris return (strcmp(((const struct key *)a)->name, ((const struct key *)b)->name)); 1031556Srgrimes} 1041556Srgrimes 1051556Srgrimesint 10690111Simpksearch(char ***argvp, struct info *ip) 1071556Srgrimes{ 1081556Srgrimes char *name; 1091556Srgrimes struct key *kp, tmp; 1101556Srgrimes 1111556Srgrimes name = **argvp; 1121556Srgrimes if (*name == '-') { 1131556Srgrimes ip->off = 1; 1141556Srgrimes ++name; 1151556Srgrimes } else 1161556Srgrimes ip->off = 0; 1171556Srgrimes 1181556Srgrimes tmp.name = name; 1191556Srgrimes if (!(kp = (struct key *)bsearch(&tmp, keys, 1201556Srgrimes sizeof(keys)/sizeof(struct key), sizeof(struct key), c_key))) 1211556Srgrimes return (0); 1221556Srgrimes if (!(kp->flags & F_OFFOK) && ip->off) { 12328642Ssteve warnx("illegal option -- -%s", name); 1241556Srgrimes usage(); 1251556Srgrimes } 1261556Srgrimes if (kp->flags & F_NEEDARG && !(ip->arg = *++*argvp)) { 12728642Ssteve warnx("option requires an argument -- %s", name); 1281556Srgrimes usage(); 1291556Srgrimes } 1301556Srgrimes kp->f(ip); 1311556Srgrimes return (1); 1321556Srgrimes} 1331556Srgrimes 1341556Srgrimesvoid 13590111Simpf_all(struct info *ip) 1361556Srgrimes{ 13759788Sache print(&ip->t, &ip->win, ip->ldisc, BSD); 1381556Srgrimes} 1391556Srgrimes 1401556Srgrimesvoid 14190111Simpf_cbreak(struct info *ip) 1421556Srgrimes{ 1431556Srgrimes 1441556Srgrimes if (ip->off) 1451556Srgrimes f_sane(ip); 1461556Srgrimes else { 1471556Srgrimes ip->t.c_iflag |= BRKINT|IXON|IMAXBEL; 1481556Srgrimes ip->t.c_oflag |= OPOST; 1491556Srgrimes ip->t.c_lflag |= ISIG|IEXTEN; 1501556Srgrimes ip->t.c_lflag &= ~ICANON; 1511556Srgrimes ip->set = 1; 1521556Srgrimes } 1531556Srgrimes} 1541556Srgrimes 1551556Srgrimesvoid 15690111Simpf_columns(struct info *ip) 1571556Srgrimes{ 1581556Srgrimes 1591556Srgrimes ip->win.ws_col = atoi(ip->arg); 1601556Srgrimes ip->wset = 1; 1611556Srgrimes} 1621556Srgrimes 1631556Srgrimesvoid 16490111Simpf_dec(struct info *ip) 1651556Srgrimes{ 1661556Srgrimes 1671556Srgrimes ip->t.c_cc[VERASE] = (u_char)0177; 1681556Srgrimes ip->t.c_cc[VKILL] = CTRL('u'); 1691556Srgrimes ip->t.c_cc[VINTR] = CTRL('c'); 1701556Srgrimes ip->t.c_lflag &= ~ECHOPRT; 1711556Srgrimes ip->t.c_lflag |= ECHOE|ECHOKE|ECHOCTL; 1721556Srgrimes ip->t.c_iflag &= ~IXANY; 1731556Srgrimes ip->set = 1; 1741556Srgrimes} 1751556Srgrimes 1761556Srgrimesvoid 17790111Simpf_ek(struct info *ip) 17882237Sdd{ 17982237Sdd 18082237Sdd ip->t.c_cc[VERASE] = CERASE; 18182237Sdd ip->t.c_cc[VKILL] = CKILL; 18282237Sdd ip->set = 1; 18382237Sdd} 18482237Sdd 18582237Sddvoid 18690111Simpf_everything(struct info *ip) 1871556Srgrimes{ 1881556Srgrimes 18959788Sache print(&ip->t, &ip->win, ip->ldisc, BSD); 1901556Srgrimes} 1911556Srgrimes 1921556Srgrimesvoid 19390111Simpf_extproc(struct info *ip) 1941556Srgrimes{ 1951556Srgrimes 19620424Ssteve if (ip->off) { 19720424Ssteve int tmp = 0; 1981556Srgrimes (void)ioctl(ip->fd, TIOCEXT, &tmp); 1991556Srgrimes } else { 20020424Ssteve int tmp = 1; 2011556Srgrimes (void)ioctl(ip->fd, TIOCEXT, &tmp); 2021556Srgrimes } 2031556Srgrimes} 2041556Srgrimes 2051556Srgrimesvoid 20690111Simpf_ispeed(struct info *ip) 2071556Srgrimes{ 2081556Srgrimes 20976810Skris cfsetispeed(&ip->t, (speed_t)atoi(ip->arg)); 2101556Srgrimes ip->set = 1; 2111556Srgrimes} 2121556Srgrimes 2131556Srgrimesvoid 21490111Simpf_nl(struct info *ip) 2151556Srgrimes{ 2161556Srgrimes 2171556Srgrimes if (ip->off) { 2181556Srgrimes ip->t.c_iflag |= ICRNL; 2191556Srgrimes ip->t.c_oflag |= ONLCR; 2201556Srgrimes } else { 2211556Srgrimes ip->t.c_iflag &= ~ICRNL; 2221556Srgrimes ip->t.c_oflag &= ~ONLCR; 2231556Srgrimes } 2241556Srgrimes ip->set = 1; 2251556Srgrimes} 2261556Srgrimes 2271556Srgrimesvoid 22890111Simpf_ospeed(struct info *ip) 2291556Srgrimes{ 2301556Srgrimes 23176810Skris cfsetospeed(&ip->t, (speed_t)atoi(ip->arg)); 2321556Srgrimes ip->set = 1; 2331556Srgrimes} 2341556Srgrimes 2351556Srgrimesvoid 23690111Simpf_raw(struct info *ip) 2371556Srgrimes{ 2381556Srgrimes 2391556Srgrimes if (ip->off) 2401556Srgrimes f_sane(ip); 2411556Srgrimes else { 2421556Srgrimes cfmakeraw(&ip->t); 2431556Srgrimes ip->t.c_cflag &= ~(CSIZE|PARENB); 2441556Srgrimes ip->t.c_cflag |= CS8; 2451556Srgrimes ip->set = 1; 2461556Srgrimes } 2471556Srgrimes} 2481556Srgrimes 2491556Srgrimesvoid 25090111Simpf_rows(struct info *ip) 2511556Srgrimes{ 2521556Srgrimes 2531556Srgrimes ip->win.ws_row = atoi(ip->arg); 2541556Srgrimes ip->wset = 1; 2551556Srgrimes} 2561556Srgrimes 2571556Srgrimesvoid 25890111Simpf_sane(struct info *ip) 2591556Srgrimes{ 260214680Sed struct termios def; 2611556Srgrimes 262214680Sed cfmakesane(&def); 263214680Sed ip->t.c_cflag = def.c_cflag | (ip->t.c_cflag & CLOCAL); 264214680Sed ip->t.c_iflag = def.c_iflag; 2651556Srgrimes /* preserve user-preference flags in lflag */ 2661556Srgrimes#define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH) 267214680Sed ip->t.c_lflag = def.c_lflag | (ip->t.c_lflag & LKEEP); 268214680Sed ip->t.c_oflag = def.c_oflag; 2691556Srgrimes ip->set = 1; 2701556Srgrimes} 2711556Srgrimes 2721556Srgrimesvoid 27390111Simpf_size(struct info *ip) 2741556Srgrimes{ 2751556Srgrimes 2761556Srgrimes (void)printf("%d %d\n", ip->win.ws_row, ip->win.ws_col); 2771556Srgrimes} 2781556Srgrimes 2791556Srgrimesvoid 28090111Simpf_speed(struct info *ip) 2811556Srgrimes{ 2821556Srgrimes 28337230Sbde (void)printf("%lu\n", (u_long)cfgetospeed(&ip->t)); 2841556Srgrimes} 2851556Srgrimes 2861556Srgrimesvoid 28790111Simpf_tty(struct info *ip) 2881556Srgrimes{ 2891556Srgrimes int tmp; 2901556Srgrimes 2911556Srgrimes tmp = TTYDISC; 2928148Sache if (ioctl(ip->fd, TIOCSETD, &tmp) < 0) 2931556Srgrimes err(1, "TIOCSETD"); 2941556Srgrimes} 295