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.4 (Berkeley) 02/20/95"; 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->off) { 168 int tmp = 0; 169 (void)ioctl(ip->fd, TIOCEXT, &tmp); 170 } else { 171 int tmp = 1; 172 (void)ioctl(ip->fd, TIOCEXT, &tmp); 173 } 174 ip->set = 1; 175 } 176 177 void 178 f_ispeed(ip) 179 struct info *ip; 180 { 181 182 cfsetispeed(&ip->t, atoi(ip->arg)); 183 ip->set = 1; 184 } 185 186 void 187 f_nl(ip) 188 struct info *ip; 189 { 190 191 if (ip->off) { 192 ip->t.c_iflag |= ICRNL; 193 ip->t.c_oflag |= ONLCR; 194 } else { 195 ip->t.c_iflag &= ~ICRNL; 196 ip->t.c_oflag &= ~ONLCR; 197 } 198 ip->set = 1; 199 } 200 201 void 202 f_ospeed(ip) 203 struct info *ip; 204 { 205 206 cfsetospeed(&ip->t, atoi(ip->arg)); 207 ip->set = 1; 208 } 209 210 void 211 f_raw(ip) 212 struct info *ip; 213 { 214 215 if (ip->off) 216 f_sane(ip); 217 else { 218 cfmakeraw(&ip->t); 219 ip->t.c_cflag &= ~(CSIZE|PARENB); 220 ip->t.c_cflag |= CS8; 221 ip->set = 1; 222 } 223 } 224 225 void 226 f_rows(ip) 227 struct info *ip; 228 { 229 230 ip->win.ws_row = atoi(ip->arg); 231 ip->wset = 1; 232 } 233 234 void 235 f_sane(ip) 236 struct info *ip; 237 { 238 239 ip->t.c_cflag = TTYDEF_CFLAG | (ip->t.c_cflag & CLOCAL); 240 ip->t.c_iflag = TTYDEF_IFLAG; 241 ip->t.c_iflag |= ICRNL; 242 /* preserve user-preference flags in lflag */ 243 #define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH) 244 ip->t.c_lflag = TTYDEF_LFLAG | (ip->t.c_lflag & LKEEP); 245 ip->t.c_oflag = TTYDEF_OFLAG; 246 ip->set = 1; 247 } 248 249 void 250 f_size(ip) 251 struct info *ip; 252 { 253 254 (void)printf("%d %d\n", ip->win.ws_row, ip->win.ws_col); 255 } 256 257 void 258 f_speed(ip) 259 struct info *ip; 260 { 261 262 (void)printf("%d\n", cfgetospeed(&ip->t)); 263 } 264 265 void 266 f_tty(ip) 267 struct info *ip; 268 { 269 int tmp; 270 271 tmp = TTYDISC; 272 if (ioctl(0, TIOCSETD, &tmp) < 0) 273 err(1, "TIOCSETD"); 274 } 275