1*04723c3fSchristos /* $NetBSD: key.c,v 1.7 2005/11/28 03:26:06 christos Exp $ */
28e41ca80Shpeyerl
38e41ca80Shpeyerl /*-
48e41ca80Shpeyerl * Copyright (c) 1991, 1993, 1994
58e41ca80Shpeyerl * The Regents of the University of California. All rights reserved.
68e41ca80Shpeyerl *
78e41ca80Shpeyerl * Redistribution and use in source and binary forms, with or without
88e41ca80Shpeyerl * modification, are permitted provided that the following conditions
98e41ca80Shpeyerl * are met:
108e41ca80Shpeyerl * 1. Redistributions of source code must retain the above copyright
118e41ca80Shpeyerl * notice, this list of conditions and the following disclaimer.
128e41ca80Shpeyerl * 2. Redistributions in binary form must reproduce the above copyright
138e41ca80Shpeyerl * notice, this list of conditions and the following disclaimer in the
148e41ca80Shpeyerl * documentation and/or other materials provided with the distribution.
15326b2259Sagc * 3. Neither the name of the University nor the names of its contributors
168e41ca80Shpeyerl * may be used to endorse or promote products derived from this software
178e41ca80Shpeyerl * without specific prior written permission.
188e41ca80Shpeyerl *
198e41ca80Shpeyerl * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
208e41ca80Shpeyerl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
218e41ca80Shpeyerl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
228e41ca80Shpeyerl * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
238e41ca80Shpeyerl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
248e41ca80Shpeyerl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
258e41ca80Shpeyerl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
268e41ca80Shpeyerl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
278e41ca80Shpeyerl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
288e41ca80Shpeyerl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
298e41ca80Shpeyerl * SUCH DAMAGE.
308e41ca80Shpeyerl */
318e41ca80Shpeyerl
3295abafa1Smikel #include <sys/cdefs.h>
338e41ca80Shpeyerl #ifndef lint
348e41ca80Shpeyerl #if 0
358e41ca80Shpeyerl static char sccsid[] = "@(#)key.c 8.3 (Berkeley) 4/2/94";
368e41ca80Shpeyerl #else
37*04723c3fSchristos __RCSID("$NetBSD: key.c,v 1.7 2005/11/28 03:26:06 christos Exp $");
388e41ca80Shpeyerl #endif
398e41ca80Shpeyerl #endif /* not lint */
408e41ca80Shpeyerl
418e41ca80Shpeyerl #include <sys/param.h>
428e41ca80Shpeyerl #include <sys/types.h>
438e41ca80Shpeyerl
448e41ca80Shpeyerl #include <errno.h>
458e41ca80Shpeyerl #include <stdlib.h>
468e41ca80Shpeyerl #include <stdio.h>
478e41ca80Shpeyerl #include <string.h>
488e41ca80Shpeyerl #include <syslog.h>
498e41ca80Shpeyerl #include <dirent.h>
508e41ca80Shpeyerl #include <termios.h>
518e41ca80Shpeyerl
528e41ca80Shpeyerl #include "lp.h"
538e41ca80Shpeyerl #include "extern.h"
548e41ca80Shpeyerl
558e41ca80Shpeyerl __BEGIN_DECLS
5695abafa1Smikel static int
57895dc72aSwiz c_key(const void *, const void *);
58895dc72aSwiz void f_cbreak(struct info *);
59895dc72aSwiz void f_columns(struct info *);
60895dc72aSwiz void f_dec(struct info *);
61895dc72aSwiz void f_extproc(struct info *);
62895dc72aSwiz void f_ispeed(struct info *);
63895dc72aSwiz void f_nl(struct info *);
64895dc72aSwiz void f_ospeed(struct info *);
65895dc72aSwiz void f_raw(struct info *);
66895dc72aSwiz void f_rows(struct info *);
67895dc72aSwiz void f_sane(struct info *);
68895dc72aSwiz void f_tty(struct info *);
698e41ca80Shpeyerl __END_DECLS
708e41ca80Shpeyerl
718e41ca80Shpeyerl static struct key {
72*04723c3fSchristos const char *name; /* name */
73895dc72aSwiz void (*f)(struct info *); /* function */
748e41ca80Shpeyerl #define F_NEEDARG 0x01 /* needs an argument */
758e41ca80Shpeyerl #define F_OFFOK 0x02 /* can turn off */
768e41ca80Shpeyerl int flags;
77c903850dSmjl } const keys[] = {
788e41ca80Shpeyerl { "cbreak", f_cbreak, F_OFFOK },
798e41ca80Shpeyerl { "cols", f_columns, F_NEEDARG },
808e41ca80Shpeyerl { "columns", f_columns, F_NEEDARG },
818e41ca80Shpeyerl { "cooked", f_sane, 0 },
828e41ca80Shpeyerl { "dec", f_dec, 0 },
838e41ca80Shpeyerl { "extproc", f_extproc, F_OFFOK },
848e41ca80Shpeyerl { "ispeed", f_ispeed, F_NEEDARG },
858e41ca80Shpeyerl { "new", f_tty, 0 },
868e41ca80Shpeyerl { "nl", f_nl, F_OFFOK },
878e41ca80Shpeyerl { "old", f_tty, 0 },
888e41ca80Shpeyerl { "ospeed", f_ospeed, F_NEEDARG },
898e41ca80Shpeyerl { "raw", f_raw, F_OFFOK },
908e41ca80Shpeyerl { "rows", f_rows, F_NEEDARG },
918e41ca80Shpeyerl { "sane", f_sane, 0 },
928e41ca80Shpeyerl { "tty", f_tty, 0 },
938e41ca80Shpeyerl };
948e41ca80Shpeyerl
958e41ca80Shpeyerl static int
c_key(const void * a,const void * b)96c903850dSmjl c_key(const void *a, const void *b)
978e41ca80Shpeyerl {
988e41ca80Shpeyerl
99*04723c3fSchristos return (strcmp(((const struct key *)a)->name,
100*04723c3fSchristos ((const struct key *)b)->name));
1018e41ca80Shpeyerl }
1028e41ca80Shpeyerl
1038e41ca80Shpeyerl int
ksearch(char *** argvp,struct info * ip)104c903850dSmjl ksearch(char ***argvp, struct info *ip)
1058e41ca80Shpeyerl {
1068e41ca80Shpeyerl char *name;
1078e41ca80Shpeyerl struct key *kp, tmp;
1088e41ca80Shpeyerl
1098e41ca80Shpeyerl name = **argvp;
1108e41ca80Shpeyerl if (*name == '-') {
1118e41ca80Shpeyerl ip->off = 1;
1128e41ca80Shpeyerl ++name;
1138e41ca80Shpeyerl } else
1148e41ca80Shpeyerl ip->off = 0;
1158e41ca80Shpeyerl
1168e41ca80Shpeyerl tmp.name = name;
1178e41ca80Shpeyerl if (!(kp = (struct key *)bsearch(&tmp, keys,
1188e41ca80Shpeyerl sizeof(keys)/sizeof(struct key), sizeof(struct key), c_key)))
1198e41ca80Shpeyerl return (0);
1208e41ca80Shpeyerl if (!(kp->flags & F_OFFOK) && ip->off) {
1218e41ca80Shpeyerl syslog(LOG_INFO, "%s: illegal option: %s", printer, name);
1228e41ca80Shpeyerl return (1);
1238e41ca80Shpeyerl }
1248e41ca80Shpeyerl if (kp->flags & F_NEEDARG && !(ip->arg = *++*argvp)) {
1258e41ca80Shpeyerl syslog(LOG_INFO, "%s: option requires an argument: %s",
1268e41ca80Shpeyerl printer, name);
1278e41ca80Shpeyerl return (1);
1288e41ca80Shpeyerl }
1298e41ca80Shpeyerl kp->f(ip);
1308e41ca80Shpeyerl return (1);
1318e41ca80Shpeyerl }
1328e41ca80Shpeyerl
1338e41ca80Shpeyerl void
f_cbreak(struct info * ip)134c903850dSmjl f_cbreak(struct info *ip)
1358e41ca80Shpeyerl {
1368e41ca80Shpeyerl
1378e41ca80Shpeyerl if (ip->off)
1388e41ca80Shpeyerl f_sane(ip);
1398e41ca80Shpeyerl else {
1408e41ca80Shpeyerl ip->t.c_iflag |= BRKINT|IXON|IMAXBEL;
1418e41ca80Shpeyerl ip->t.c_oflag |= OPOST;
1428e41ca80Shpeyerl ip->t.c_lflag |= ISIG|IEXTEN;
1438e41ca80Shpeyerl ip->t.c_lflag &= ~ICANON;
1448e41ca80Shpeyerl ip->set = 1;
1458e41ca80Shpeyerl }
1468e41ca80Shpeyerl }
1478e41ca80Shpeyerl
1488e41ca80Shpeyerl void
f_columns(struct info * ip)149c903850dSmjl f_columns(struct info *ip)
1508e41ca80Shpeyerl {
1518e41ca80Shpeyerl
1528e41ca80Shpeyerl ip->win.ws_col = atoi(ip->arg);
1538e41ca80Shpeyerl ip->wset = 1;
1548e41ca80Shpeyerl }
1558e41ca80Shpeyerl
1568e41ca80Shpeyerl void
f_dec(struct info * ip)157c903850dSmjl f_dec(struct info *ip)
1588e41ca80Shpeyerl {
1598e41ca80Shpeyerl
1608e41ca80Shpeyerl ip->t.c_cc[VERASE] = (u_char)0177;
1618e41ca80Shpeyerl ip->t.c_cc[VKILL] = CTRL('u');
1628e41ca80Shpeyerl ip->t.c_cc[VINTR] = CTRL('c');
1638e41ca80Shpeyerl ip->t.c_lflag &= ~ECHOPRT;
1648e41ca80Shpeyerl ip->t.c_lflag |= ECHOE|ECHOKE|ECHOCTL;
1658e41ca80Shpeyerl ip->t.c_iflag &= ~IXANY;
1668e41ca80Shpeyerl ip->set = 1;
1678e41ca80Shpeyerl }
1688e41ca80Shpeyerl
1698e41ca80Shpeyerl void
f_extproc(struct info * ip)170c903850dSmjl f_extproc(struct info *ip)
1718e41ca80Shpeyerl {
1728e41ca80Shpeyerl
1738e41ca80Shpeyerl if (ip->set) {
1748e41ca80Shpeyerl int tmp = 1;
1758e41ca80Shpeyerl (void)ioctl(ip->fd, TIOCEXT, &tmp);
1768e41ca80Shpeyerl } else {
1778e41ca80Shpeyerl int tmp = 0;
1788e41ca80Shpeyerl (void)ioctl(ip->fd, TIOCEXT, &tmp);
1798e41ca80Shpeyerl }
1808e41ca80Shpeyerl }
1818e41ca80Shpeyerl
1828e41ca80Shpeyerl void
f_ispeed(struct info * ip)183c903850dSmjl f_ispeed(struct info *ip)
1848e41ca80Shpeyerl {
1858e41ca80Shpeyerl
1868e41ca80Shpeyerl cfsetispeed(&ip->t, atoi(ip->arg));
1878e41ca80Shpeyerl ip->set = 1;
1888e41ca80Shpeyerl }
1898e41ca80Shpeyerl
1908e41ca80Shpeyerl void
f_nl(struct info * ip)191c903850dSmjl f_nl(struct info *ip)
1928e41ca80Shpeyerl {
1938e41ca80Shpeyerl
1948e41ca80Shpeyerl if (ip->off) {
1958e41ca80Shpeyerl ip->t.c_iflag |= ICRNL;
1968e41ca80Shpeyerl ip->t.c_oflag |= ONLCR;
1978e41ca80Shpeyerl } else {
1988e41ca80Shpeyerl ip->t.c_iflag &= ~ICRNL;
1998e41ca80Shpeyerl ip->t.c_oflag &= ~ONLCR;
2008e41ca80Shpeyerl }
2018e41ca80Shpeyerl ip->set = 1;
2028e41ca80Shpeyerl }
2038e41ca80Shpeyerl
2048e41ca80Shpeyerl void
f_ospeed(struct info * ip)205c903850dSmjl f_ospeed(struct info *ip)
2068e41ca80Shpeyerl {
2078e41ca80Shpeyerl
2088e41ca80Shpeyerl cfsetospeed(&ip->t, atoi(ip->arg));
2098e41ca80Shpeyerl ip->set = 1;
2108e41ca80Shpeyerl }
2118e41ca80Shpeyerl
2128e41ca80Shpeyerl void
f_raw(struct info * ip)213c903850dSmjl f_raw(struct info *ip)
2148e41ca80Shpeyerl {
2158e41ca80Shpeyerl
2168e41ca80Shpeyerl if (ip->off)
2178e41ca80Shpeyerl f_sane(ip);
2188e41ca80Shpeyerl else {
2198e41ca80Shpeyerl cfmakeraw(&ip->t);
2208e41ca80Shpeyerl ip->t.c_cflag &= ~(CSIZE|PARENB);
2218e41ca80Shpeyerl ip->t.c_cflag |= CS8;
2228e41ca80Shpeyerl ip->set = 1;
2238e41ca80Shpeyerl }
2248e41ca80Shpeyerl }
2258e41ca80Shpeyerl
2268e41ca80Shpeyerl void
f_rows(struct info * ip)227c903850dSmjl f_rows(struct info *ip)
2288e41ca80Shpeyerl {
2298e41ca80Shpeyerl
2308e41ca80Shpeyerl ip->win.ws_row = atoi(ip->arg);
2318e41ca80Shpeyerl ip->wset = 1;
2328e41ca80Shpeyerl }
2338e41ca80Shpeyerl
2348e41ca80Shpeyerl void
f_sane(struct info * ip)235c903850dSmjl f_sane(struct info *ip)
2368e41ca80Shpeyerl {
2378e41ca80Shpeyerl
23894cf4332Sscottr ip->t.c_cflag = TTYDEF_CFLAG | (ip->t.c_cflag & (CLOCAL|CRTSCTS|CDTRCTS));
2398e41ca80Shpeyerl ip->t.c_iflag = TTYDEF_IFLAG;
2408e41ca80Shpeyerl ip->t.c_iflag |= ICRNL;
2418e41ca80Shpeyerl /* preserve user-preference flags in lflag */
2428e41ca80Shpeyerl #define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH)
2438e41ca80Shpeyerl ip->t.c_lflag = TTYDEF_LFLAG | (ip->t.c_lflag & LKEEP);
2448e41ca80Shpeyerl ip->t.c_oflag = TTYDEF_OFLAG;
2458e41ca80Shpeyerl ip->set = 1;
2468e41ca80Shpeyerl }
2478e41ca80Shpeyerl
2488e41ca80Shpeyerl void
f_tty(struct info * ip)249c903850dSmjl f_tty(struct info *ip)
2508e41ca80Shpeyerl {
2518e41ca80Shpeyerl int tmp;
2528e41ca80Shpeyerl
2538e41ca80Shpeyerl tmp = TTYDISC;
2548e41ca80Shpeyerl if (ioctl(0, TIOCSETD, &tmp) < 0)
2558e41ca80Shpeyerl syslog(LOG_ERR, "%s: ioctl(TIOCSETD): %m", printer);
2568e41ca80Shpeyerl }
257