xref: /openbsd-src/usr.sbin/lpr/lpq/lpq.c (revision 3a50f0a93a2072911d0ba6ababa815fb04bf9a71)
1 /*	$OpenBSD: lpq.c,v 1.25 2022/12/28 21:30:17 jmc Exp $	*/
2 /*	$NetBSD: lpq.c,v 1.9 1999/12/07 14:54:47 mrg Exp $	*/
3 
4 /*
5  * Copyright (c) 1983, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 /*
35  * Spool Queue examination program
36  *
37  * lpq [-a] [-l] [-Pprinter] [user...] [job...]
38  *
39  * -a show all non-null queues on the local machine
40  * -l long output
41  * -P used to identify printer as per lpr/lprm
42  */
43 
44 
45 #include <ctype.h>
46 #include <signal.h>
47 #include <dirent.h>
48 #include <err.h>
49 #include <errno.h>
50 #include <unistd.h>
51 #include <stdlib.h>
52 #include <stdio.h>
53 #include <limits.h>
54 #include <syslog.h>
55 
56 #include "lp.h"
57 #include "lp.local.h"
58 #include "pathnames.h"
59 
60 int	 requ[MAXREQUESTS];	/* job number of spool entries */
61 int	 requests;		/* # of spool requests */
62 char	*user[MAXUSERS];	/* users to process */
63 int	 users;			/* # of users in user array */
64 
65 volatile sig_atomic_t gotintr;
66 
67 static __dead void usage(void);
68 
69 int
main(int argc,char ** argv)70 main(int argc, char **argv)
71 {
72 	int	ch, aflag, lflag;
73 	char	*buf, *cp;
74 	long	l;
75 
76 	effective_uid = geteuid();
77 	real_uid = getuid();
78 	effective_gid = getegid();
79 	real_gid = getgid();
80 	PRIV_END;	/* be safe */
81 
82 	if (gethostname(host, sizeof(host)) != 0)
83 		err(1, "gethostname");
84 	openlog("lpq", 0, LOG_LPR);
85 
86 	aflag = lflag = 0;
87 	while ((ch = getopt(argc, argv, "alP:w:")) != -1) {
88 		switch(ch) {
89 		case 'a':
90 			aflag = 1;
91 			break;
92 		case 'l':			/* long output */
93 			lflag = 1;
94 			break;
95 		case 'P':		/* printer name */
96 			printer = optarg;
97 			break;
98 		case 'w':
99 			l = strtol(optarg, &cp, 10);
100 			if (*cp != '\0' || l < 0 || l >= INT_MAX)
101 				errx(1, "wait time must be positive integer: %s",
102 				    optarg);
103 			wait_time = (u_int)l;
104 			if (wait_time < 30)
105 				warnx("warning: wait time less than 30 seconds");
106 			break;
107 		default:
108 			usage();
109 		}
110 	}
111 
112 	if (!aflag && printer == NULL && (printer = getenv("PRINTER")) == NULL)
113 		printer = DEFLP;
114 
115 	for (argc -= optind, argv += optind; argc; --argc, ++argv)
116 		if (isdigit((unsigned char)argv[0][0])) {
117 			if (requests >= MAXREQUESTS)
118 				fatal("too many requests");
119 			requ[requests++] = atoi(*argv);
120 		}
121 		else {
122 			if (users >= MAXUSERS)
123 				fatal("too many users");
124 			user[users++] = *argv;
125 		}
126 
127 	if (aflag) {
128 		while (cgetnext(&buf, printcapdb) > 0) {
129 			if (ckqueue(buf) <= 0) {
130 				free(buf);
131 				continue;	/* no jobs */
132 			}
133 			for (cp = buf; *cp; cp++)
134 				if (*cp == '|' || *cp == ':') {
135 					*cp = '\0';
136 					break;
137 				}
138 			printer = buf;
139 			printf("%s:\n", printer);
140 			displayq(lflag);
141 			free(buf);
142 			printf("\n");
143 		}
144 	} else
145 		displayq(lflag);
146 	exit(0);
147 }
148 
149 static __dead void
usage(void)150 usage(void)
151 {
152 	extern char *__progname;
153 
154 	fprintf(stderr,
155 	    "usage: %s [-al] [-Pprinter] [job# ...] [user ...]\n",
156 	    __progname);
157 	exit(1);
158 }
159