1 /*- 2 * Copyright (c) 1991, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)key.c 8.3 (Berkeley) 04/02/94"; 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 static int 70 c_key(a, b) 71 const void *a, *b; 72 { 73 74 return (strcmp(((struct key *)a)->name, ((struct key *)b)->name)); 75 } 76 77 int 78 ksearch(argvp, ip) 79 char ***argvp; 80 struct info *ip; 81 { 82 char *name; 83 struct key *kp, tmp; 84 85 name = **argvp; 86 if (*name == '-') { 87 ip->off = 1; 88 ++name; 89 } else 90 ip->off = 0; 91 92 tmp.name = name; 93 if (!(kp = (struct key *)bsearch(&tmp, keys, 94 sizeof(keys)/sizeof(struct key), sizeof(struct key), c_key))) 95 return (0); 96 if (!(kp->flags & F_OFFOK) && ip->off) { 97 errx(1, "illegal option -- %s", name); 98 usage(); 99 } 100 if (kp->flags & F_NEEDARG && !(ip->arg = *++*argvp)) { 101 errx(1, "option requires an argument -- %s", name); 102 usage(); 103 } 104 kp->f(ip); 105 return (1); 106 } 107 108 void 109 f_all(ip) 110 struct info *ip; 111 { 112 print(&ip->t, &ip->win, ip->ldisc, BSD); 113 } 114 115 void 116 f_cbreak(ip) 117 struct info *ip; 118 { 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 136 ip->win.ws_col = atoi(ip->arg); 137 ip->wset = 1; 138 } 139 140 void 141 f_dec(ip) 142 struct info *ip; 143 { 144 145 ip->t.c_cc[VERASE] = (u_char)0177; 146 ip->t.c_cc[VKILL] = CTRL('u'); 147 ip->t.c_cc[VINTR] = CTRL('c'); 148 ip->t.c_lflag &= ~ECHOPRT; 149 ip->t.c_lflag |= ECHOE|ECHOKE|ECHOCTL; 150 ip->t.c_iflag &= ~IXANY; 151 ip->set = 1; 152 } 153 154 void 155 f_everything(ip) 156 struct info *ip; 157 { 158 159 print(&ip->t, &ip->win, ip->ldisc, BSD); 160 } 161 162 void 163 f_extproc(ip) 164 struct info *ip; 165 { 166 167 if (ip->set) { 168 int tmp = 1; 169 (void)ioctl(ip->fd, TIOCEXT, &tmp); 170 } else { 171 int tmp = 0; 172 (void)ioctl(ip->fd, TIOCEXT, &tmp); 173 } 174 } 175 176 void 177 f_ispeed(ip) 178 struct info *ip; 179 { 180 181 cfsetispeed(&ip->t, atoi(ip->arg)); 182 ip->set = 1; 183 } 184 185 void 186 f_nl(ip) 187 struct info *ip; 188 { 189 190 if (ip->off) { 191 ip->t.c_iflag |= ICRNL; 192 ip->t.c_oflag |= ONLCR; 193 } else { 194 ip->t.c_iflag &= ~ICRNL; 195 ip->t.c_oflag &= ~ONLCR; 196 } 197 ip->set = 1; 198 } 199 200 void 201 f_ospeed(ip) 202 struct info *ip; 203 { 204 205 cfsetospeed(&ip->t, atoi(ip->arg)); 206 ip->set = 1; 207 } 208 209 void 210 f_raw(ip) 211 struct info *ip; 212 { 213 214 if (ip->off) 215 f_sane(ip); 216 else { 217 cfmakeraw(&ip->t); 218 ip->t.c_cflag &= ~(CSIZE|PARENB); 219 ip->t.c_cflag |= CS8; 220 ip->set = 1; 221 } 222 } 223 224 void 225 f_rows(ip) 226 struct info *ip; 227 { 228 229 ip->win.ws_row = atoi(ip->arg); 230 ip->wset = 1; 231 } 232 233 void 234 f_sane(ip) 235 struct info *ip; 236 { 237 238 ip->t.c_cflag = TTYDEF_CFLAG | (ip->t.c_cflag & CLOCAL); 239 ip->t.c_iflag = TTYDEF_IFLAG; 240 ip->t.c_iflag |= ICRNL; 241 /* preserve user-preference flags in lflag */ 242 #define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH) 243 ip->t.c_lflag = TTYDEF_LFLAG | (ip->t.c_lflag & LKEEP); 244 ip->t.c_oflag = TTYDEF_OFLAG; 245 ip->set = 1; 246 } 247 248 void 249 f_size(ip) 250 struct info *ip; 251 { 252 253 (void)printf("%d %d\n", ip->win.ws_row, ip->win.ws_col); 254 } 255 256 void 257 f_speed(ip) 258 struct info *ip; 259 { 260 261 (void)printf("%d\n", cfgetospeed(&ip->t)); 262 } 263 264 void 265 f_tty(ip) 266 struct info *ip; 267 { 268 int tmp; 269 270 tmp = TTYDISC; 271 if (ioctl(0, TIOCSETD, &tmp) < 0) 272 err(1, "TIOCSETD"); 273 } 274