xref: /openbsd-src/usr.sbin/lpr/lpq/lpq.c (revision 2b0358df1d88d06ef4139321dd05bd5e05d91eaf)
1 /*	$OpenBSD: lpq.c,v 1.18 2008/05/26 06:30:36 otto 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 #ifndef lint
35 static const char copyright[] =
36 "@(#) Copyright (c) 1983, 1993\n\
37 	The Regents of the University of California.  All rights reserved.\n";
38 #endif /* not lint */
39 
40 #ifndef lint
41 #if 0
42 static const char sccsid[] = "@(#)lpq.c	8.3 (Berkeley) 5/10/95";
43 #else
44 static const char rcsid[] = "$OpenBSD: lpq.c,v 1.18 2008/05/26 06:30:36 otto Exp $";
45 #endif
46 #endif /* not lint */
47 
48 /*
49  * Spool Queue examination program
50  *
51  * lpq [-a] [-l] [-Pprinter] [user...] [job...]
52  *
53  * -a show all non-null queues on the local machine
54  * -l long output
55  * -P used to identify printer as per lpr/lprm
56  */
57 
58 #include <sys/param.h>
59 
60 #include <ctype.h>
61 #include <dirent.h>
62 #include <err.h>
63 #include <errno.h>
64 #include <unistd.h>
65 #include <stdlib.h>
66 #include <stdio.h>
67 #include <syslog.h>
68 
69 #include "lp.h"
70 #include "lp.local.h"
71 #include "pathnames.h"
72 
73 int	 requ[MAXREQUESTS];	/* job number of spool entries */
74 int	 requests;		/* # of spool requests */
75 char	*user[MAXUSERS];	/* users to process */
76 int	 users;			/* # of users in user array */
77 
78 volatile sig_atomic_t gotintr;
79 
80 static int ckqueue(char *);
81 static __dead void usage(void);
82 
83 int
84 main(int argc, char **argv)
85 {
86 	int	ch, aflag, lflag;
87 	char	*buf, *cp;
88 	long	l;
89 
90 	effective_uid = geteuid();
91 	real_uid = getuid();
92 	effective_gid = getegid();
93 	real_gid = getgid();
94 	PRIV_END;	/* be safe */
95 
96 	if (gethostname(host, sizeof(host)) != 0)
97 		err(1, "gethostname");
98 	openlog("lpq", 0, LOG_LPR);
99 
100 	aflag = lflag = 0;
101 	while ((ch = getopt(argc, argv, "alP:w:")) != -1) {
102 		switch(ch) {
103 		case 'a':
104 			++aflag;
105 			break;
106 		case 'l':			/* long output */
107 			++lflag;
108 			break;
109 		case 'P':		/* printer name */
110 			printer = optarg;
111 			break;
112 		case 'w':
113 			l = strtol(optarg, &cp, 10);
114 			if (*cp != '\0' || l < 0 || l >= INT_MAX)
115 				errx(1, "wait time must be postive integer: %s",
116 				    optarg);
117 			wait_time = (u_int)l;
118 			if (wait_time < 30)
119 				warnx("warning: wait time less than 30 seconds");
120 			break;
121 		case '?':
122 		default:
123 			usage();
124 		}
125 	}
126 
127 	if (!aflag && printer == NULL && (printer = getenv("PRINTER")) == NULL)
128 		printer = DEFLP;
129 
130 	for (argc -= optind, argv += optind; argc; --argc, ++argv)
131 		if (isdigit(argv[0][0])) {
132 			if (requests >= MAXREQUESTS)
133 				fatal("too many requests");
134 			requ[requests++] = atoi(*argv);
135 		}
136 		else {
137 			if (users >= MAXUSERS)
138 				fatal("too many users");
139 			user[users++] = *argv;
140 		}
141 
142 	if (aflag) {
143 		while (cgetnext(&buf, printcapdb) > 0) {
144 			if (ckqueue(buf) <= 0) {
145 				free(buf);
146 				continue;	/* no jobs */
147 			}
148 			for (cp = buf; *cp; cp++)
149 				if (*cp == '|' || *cp == ':') {
150 					*cp = '\0';
151 					break;
152 				}
153 			printer = buf;
154 			printf("%s:\n", printer);
155 			displayq(lflag);
156 			free(buf);
157 			printf("\n");
158 		}
159 	} else
160 		displayq(lflag);
161 	exit(0);
162 }
163 
164 /* XXX - could be common w/ lpd */
165 static int
166 ckqueue(char *cap)
167 {
168 	struct dirent *d;
169 	DIR *dirp;
170 	char *spooldir;
171 
172 	if (cgetstr(cap, "sd", &spooldir) >= 0) {
173 		dirp = opendir(spooldir);
174 		free(spooldir);
175 	} else
176 		dirp = opendir(_PATH_DEFSPOOL);
177 
178 	if (dirp == NULL)
179 		return (-1);
180 	while ((d = readdir(dirp)) != NULL) {
181 		if (d->d_name[0] != 'c' || d->d_name[1] != 'f')
182 			continue;	/* daemon control files only */
183 		closedir(dirp);
184 		return (1);		/* found something */
185 	}
186 	closedir(dirp);
187 	return (0);
188 }
189 
190 static __dead void
191 usage(void)
192 {
193 	extern char *__progname;
194 
195 	fprintf(stderr,
196 	    "usage: %s [-al] [-Pprinter] [job# ...] [user ...]\n",
197 	    __progname);
198 	exit(1);
199 }
200