1 /*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)key.c 5.5 (Berkeley) 04/29/93"; 10 #endif /* not lint */ 11 12 #include <sys/types.h> 13 14 #include <err.h> 15 #include <errno.h> 16 #include <stdlib.h> 17 #include <stdio.h> 18 #include <string.h> 19 20 #include "stty.h" 21 #include "extern.h" 22 23 __BEGIN_DECLS 24 void f_all __P((struct info *)); 25 void f_cbreak __P((struct info *)); 26 void f_columns __P((struct info *)); 27 void f_dec __P((struct info *)); 28 void f_everything __P((struct info *)); 29 void f_extproc __P((struct info *)); 30 void f_ispeed __P((struct info *)); 31 void f_nl __P((struct info *)); 32 void f_ospeed __P((struct info *)); 33 void f_raw __P((struct info *)); 34 void f_rows __P((struct info *)); 35 void f_sane __P((struct info *)); 36 void f_size __P((struct info *)); 37 void f_speed __P((struct info *)); 38 void f_tty __P((struct info *)); 39 __END_DECLS 40 41 static struct key { 42 char *name; /* name */ 43 void (*f) __P((struct info *)); /* function */ 44 #define F_NEEDARG 0x01 /* needs an argument */ 45 #define F_OFFOK 0x02 /* can turn off */ 46 int flags; 47 } keys[] = { 48 { "all", f_all, 0 }, 49 { "cbreak", f_cbreak, F_OFFOK }, 50 { "cols", f_columns, F_NEEDARG }, 51 { "columns", f_columns, F_NEEDARG }, 52 { "cooked", f_sane, 0 }, 53 { "dec", f_dec, 0 }, 54 { "everything", f_everything, 0 }, 55 { "extproc", f_extproc, F_OFFOK }, 56 { "ispeed", f_ispeed, F_NEEDARG }, 57 { "new", f_tty, 0 }, 58 { "nl", f_nl, F_OFFOK }, 59 { "old", f_tty, 0 }, 60 { "ospeed", f_ospeed, F_NEEDARG }, 61 { "raw", f_raw, F_OFFOK }, 62 { "rows", f_rows, F_NEEDARG }, 63 { "sane", f_sane, 0 }, 64 { "size", f_size, 0 }, 65 { "speed", f_speed, 0 }, 66 { "tty", f_tty, 0 }, 67 }; 68 69 int 70 ksearch(argvp, ip) 71 char ***argvp; 72 struct info *ip; 73 { 74 register struct key *kp; 75 register char *name; 76 struct key tmp; 77 static int c_key __P((const void *, const void *)); 78 79 name = **argvp; 80 if (*name == '-') { 81 ip->off = 1; 82 ++name; 83 } else 84 ip->off = 0; 85 86 tmp.name = name; 87 if (!(kp = (struct key *)bsearch(&tmp, keys, 88 sizeof(keys)/sizeof(struct key), sizeof(struct key), c_key))) 89 return (0); 90 if (!(kp->flags & F_OFFOK) && ip->off) { 91 errx(1, "illegal option -- %s", name); 92 usage(); 93 } 94 if (kp->flags & F_NEEDARG && !(ip->arg = *++*argvp)) { 95 errx(1, "option requires an argument -- %s", name); 96 usage(); 97 } 98 kp->f(ip); 99 return (1); 100 } 101 102 static int 103 c_key(a, b) 104 const void *a, *b; 105 { 106 return (strcmp(((struct key *)a)->name, ((struct key *)b)->name)); 107 } 108 109 void 110 f_all(ip) 111 struct info *ip; 112 { 113 print(&ip->t, &ip->win, ip->ldisc, BSD); 114 } 115 116 void 117 f_cbreak(ip) 118 struct info *ip; 119 { 120 if (ip->off) 121 f_sane(ip); 122 else { 123 ip->t.c_iflag |= BRKINT|IXON|IMAXBEL; 124 ip->t.c_oflag |= OPOST; 125 ip->t.c_lflag |= ISIG|IEXTEN; 126 ip->t.c_lflag &= ~ICANON; 127 ip->set = 1; 128 } 129 } 130 131 void 132 f_columns(ip) 133 struct info *ip; 134 { 135 ip->win.ws_col = atoi(ip->arg); 136 ip->wset = 1; 137 } 138 139 void 140 f_dec(ip) 141 struct info *ip; 142 { 143 ip->t.c_cc[VERASE] = (u_char)0177; 144 ip->t.c_cc[VKILL] = CTRL('u'); 145 ip->t.c_cc[VINTR] = CTRL('c'); 146 ip->t.c_lflag &= ~ECHOPRT; 147 ip->t.c_lflag |= ECHOE|ECHOKE|ECHOCTL; 148 ip->t.c_iflag &= ~IXANY; 149 ip->set = 1; 150 } 151 152 void 153 f_everything(ip) 154 struct info *ip; 155 { 156 print(&ip->t, &ip->win, ip->ldisc, BSD); 157 } 158 159 void 160 f_extproc(ip) 161 struct info *ip; 162 { 163 int tmp; 164 165 if (ip->set) { 166 tmp = 1; 167 (void)ioctl(ip->fd, TIOCEXT, &tmp); 168 } else { 169 tmp = 0; 170 (void)ioctl(ip->fd, TIOCEXT, &tmp); 171 } 172 } 173 174 void 175 f_ispeed(ip) 176 struct info *ip; 177 { 178 cfsetispeed(&ip->t, atoi(ip->arg)); 179 ip->set = 1; 180 } 181 182 void 183 f_nl(ip) 184 struct info *ip; 185 { 186 if (ip->off) { 187 ip->t.c_iflag |= ICRNL; 188 ip->t.c_oflag |= ONLCR; 189 } else { 190 ip->t.c_iflag &= ~ICRNL; 191 ip->t.c_oflag &= ~ONLCR; 192 } 193 ip->set = 1; 194 } 195 196 void 197 f_ospeed(ip) 198 struct info *ip; 199 { 200 cfsetospeed(&ip->t, atoi(ip->arg)); 201 ip->set = 1; 202 } 203 204 void 205 f_raw(ip) 206 struct info *ip; 207 { 208 if (ip->off) 209 f_sane(ip); 210 else { 211 cfmakeraw(&ip->t); 212 ip->t.c_cflag &= ~(CSIZE|PARENB); 213 ip->t.c_cflag |= CS8; 214 ip->set = 1; 215 } 216 } 217 218 void 219 f_rows(ip) 220 struct info *ip; 221 { 222 ip->win.ws_row = atoi(ip->arg); 223 ip->wset = 1; 224 } 225 226 void 227 f_sane(ip) 228 struct info *ip; 229 { 230 ip->t.c_cflag = TTYDEF_CFLAG | (ip->t.c_cflag & CLOCAL); 231 ip->t.c_iflag = TTYDEF_IFLAG; 232 ip->t.c_iflag |= ICRNL; 233 /* preserve user-preference flags in lflag */ 234 #define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH) 235 ip->t.c_lflag = TTYDEF_LFLAG | (ip->t.c_lflag & LKEEP); 236 ip->t.c_oflag = TTYDEF_OFLAG; 237 ip->set = 1; 238 } 239 240 void 241 f_size(ip) 242 struct info *ip; 243 { 244 (void)printf("%d %d\n", ip->win.ws_row, ip->win.ws_col); 245 } 246 247 void 248 f_speed(ip) 249 struct info *ip; 250 { 251 (void)printf("%d\n", cfgetospeed(&ip->t)); 252 } 253 254 void 255 f_tty(ip) 256 struct info *ip; 257 { 258 int tmp; 259 260 tmp = TTYDISC; 261 if (ioctl(0, TIOCSETD, &tmp) < 0) 262 err(1, "TIOCSETD"); 263 } 264