xref: /netbsd-src/usr.sbin/lpr/lpd/key.c (revision 04723c3ffc6d548c80a76c0a326a379e13ae6929)
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