1 /* $OpenBSD: key.c,v 1.8 2015/01/16 06:40:18 deraadt Exp $ */ 2 /* $NetBSD: key.c,v 1.3 1997/10/20 08:08:28 scottr Exp $ */ 3 4 /*- 5 * Copyright (c) 1991, 1993, 1994 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <sys/types.h> 34 35 #include <errno.h> 36 #include <signal.h> 37 #include <stdlib.h> 38 #include <stdio.h> 39 #include <string.h> 40 #include <syslog.h> 41 #include <dirent.h> 42 #include <limits.h> 43 #include <termios.h> 44 45 #include "lp.h" 46 #include "extern.h" 47 48 __BEGIN_DECLS 49 static int 50 c_key(const void *, const void *); 51 void f_cbreak(struct info *); 52 void f_columns(struct info *); 53 void f_dec(struct info *); 54 void f_extproc(struct info *); 55 void f_ispeed(struct info *); 56 void f_nl(struct info *); 57 void f_ospeed(struct info *); 58 void f_raw(struct info *); 59 void f_rows(struct info *); 60 void f_sane(struct info *); 61 void f_tty(struct info *); 62 __END_DECLS 63 64 static struct key { 65 char *name; /* name */ 66 void (*f)(struct info *); /* function */ 67 #define F_NEEDARG 0x01 /* needs an argument */ 68 #define F_OFFOK 0x02 /* can turn off */ 69 int flags; 70 } const keys[] = { 71 { "cbreak", f_cbreak, F_OFFOK }, 72 { "cols", f_columns, F_NEEDARG }, 73 { "columns", f_columns, F_NEEDARG }, 74 { "cooked", f_sane, 0 }, 75 { "dec", f_dec, 0 }, 76 { "extproc", f_extproc, F_OFFOK }, 77 { "ispeed", f_ispeed, F_NEEDARG }, 78 { "new", f_tty, 0 }, 79 { "nl", f_nl, F_OFFOK }, 80 { "old", f_tty, 0 }, 81 { "ospeed", f_ospeed, F_NEEDARG }, 82 { "raw", f_raw, F_OFFOK }, 83 { "rows", f_rows, F_NEEDARG }, 84 { "sane", f_sane, 0 }, 85 { "tty", f_tty, 0 }, 86 }; 87 88 static int 89 c_key(const void *a, const void *b) 90 { 91 92 return (strcmp(((struct key *)a)->name, ((struct key *)b)->name)); 93 } 94 95 int 96 ksearch(char ***argvp, struct info *ip) 97 { 98 char *name; 99 struct key *kp, tmp; 100 101 name = **argvp; 102 if (*name == '-') { 103 ip->off = 1; 104 ++name; 105 } else 106 ip->off = 0; 107 108 tmp.name = name; 109 if (!(kp = (struct key *)bsearch(&tmp, keys, 110 sizeof(keys)/sizeof(struct key), sizeof(struct key), c_key))) 111 return (0); 112 if (!(kp->flags & F_OFFOK) && ip->off) { 113 syslog(LOG_INFO, "%s: illegal option: %s", printer, name); 114 return (1); 115 } 116 if (kp->flags & F_NEEDARG && !(ip->arg = *++*argvp)) { 117 syslog(LOG_INFO, "%s: option requires an argument: %s", 118 printer, name); 119 return (1); 120 } 121 kp->f(ip); 122 return (1); 123 } 124 125 void 126 f_cbreak(struct info *ip) 127 { 128 129 if (ip->off) 130 f_sane(ip); 131 else { 132 ip->t.c_iflag |= BRKINT|IXON|IMAXBEL; 133 ip->t.c_oflag |= OPOST; 134 ip->t.c_lflag |= ISIG|IEXTEN; 135 ip->t.c_lflag &= ~ICANON; 136 ip->set = 1; 137 } 138 } 139 140 void 141 f_columns(struct info *ip) 142 { 143 144 ip->win.ws_col = atoi(ip->arg); 145 ip->wset = 1; 146 } 147 148 void 149 f_dec(struct info *ip) 150 { 151 152 ip->t.c_cc[VERASE] = (u_char)0177; 153 ip->t.c_cc[VKILL] = CTRL('u'); 154 ip->t.c_cc[VINTR] = CTRL('c'); 155 ip->t.c_lflag &= ~ECHOPRT; 156 ip->t.c_lflag |= ECHOE|ECHOKE|ECHOCTL; 157 ip->t.c_iflag &= ~IXANY; 158 ip->set = 1; 159 } 160 161 void 162 f_extproc(struct info *ip) 163 { 164 165 if (ip->set) { 166 int tmp = 1; 167 (void)ioctl(ip->fd, TIOCEXT, &tmp); 168 } else { 169 int tmp = 0; 170 (void)ioctl(ip->fd, TIOCEXT, &tmp); 171 } 172 } 173 174 void 175 f_ispeed(struct info *ip) 176 { 177 178 cfsetispeed(&ip->t, atoi(ip->arg)); 179 ip->set = 1; 180 } 181 182 void 183 f_nl(struct info *ip) 184 { 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(struct info *ip) 198 { 199 200 cfsetospeed(&ip->t, atoi(ip->arg)); 201 ip->set = 1; 202 } 203 204 void 205 f_raw(struct info *ip) 206 { 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(struct info *ip) 220 { 221 222 ip->win.ws_row = atoi(ip->arg); 223 ip->wset = 1; 224 } 225 226 void 227 f_sane(struct info *ip) 228 { 229 230 ip->t.c_cflag = TTYDEF_CFLAG | (ip->t.c_cflag & (CLOCAL|CRTSCTS)); 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_tty(struct info *ip) 242 { 243 int tmp; 244 245 tmp = TTYDISC; 246 if (ioctl(0, TIOCSETD, &tmp) < 0) 247 syslog(LOG_ERR, "%s: ioctl(TIOCSETD): %m", printer); 248 } 249