xref: /openbsd/usr.sbin/lpr/lpq/lpq.c (revision e5dd7070)
1 /*	$OpenBSD: lpq.c,v 1.23 2016/02/29 17:26:02 jca 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
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 postive 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 		case '?':
108 		default:
109 			usage();
110 		}
111 	}
112 
113 	if (!aflag && printer == NULL && (printer = getenv("PRINTER")) == NULL)
114 		printer = DEFLP;
115 
116 	for (argc -= optind, argv += optind; argc; --argc, ++argv)
117 		if (isdigit((unsigned char)argv[0][0])) {
118 			if (requests >= MAXREQUESTS)
119 				fatal("too many requests");
120 			requ[requests++] = atoi(*argv);
121 		}
122 		else {
123 			if (users >= MAXUSERS)
124 				fatal("too many users");
125 			user[users++] = *argv;
126 		}
127 
128 	if (aflag) {
129 		while (cgetnext(&buf, printcapdb) > 0) {
130 			if (ckqueue(buf) <= 0) {
131 				free(buf);
132 				continue;	/* no jobs */
133 			}
134 			for (cp = buf; *cp; cp++)
135 				if (*cp == '|' || *cp == ':') {
136 					*cp = '\0';
137 					break;
138 				}
139 			printer = buf;
140 			printf("%s:\n", printer);
141 			displayq(lflag);
142 			free(buf);
143 			printf("\n");
144 		}
145 	} else
146 		displayq(lflag);
147 	exit(0);
148 }
149 
150 static __dead void
151 usage(void)
152 {
153 	extern char *__progname;
154 
155 	fprintf(stderr,
156 	    "usage: %s [-al] [-Pprinter] [job# ...] [user ...]\n",
157 	    __progname);
158 	exit(1);
159 }
160