lpq.c revision 1.13
1/*	$OpenBSD: lpq.c,v 1.13 2002/06/08 01:53:43 millert 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. All advertising materials mentioning features or use of this software
18 *    must display the following acknowledgement:
19 *	This product includes software developed by the University of
20 *	California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 *    may be used to endorse or promote products derived from this software
23 *    without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 */
37
38#ifndef lint
39static const char copyright[] =
40"@(#) Copyright (c) 1983, 1993\n\
41	The Regents of the University of California.  All rights reserved.\n";
42#endif /* not lint */
43
44#ifndef lint
45#if 0
46static const char sccsid[] = "@(#)lpq.c	8.3 (Berkeley) 5/10/95";
47#else
48static const char rcsid[] = "$OpenBSD: lpq.c,v 1.13 2002/06/08 01:53:43 millert Exp $";
49#endif
50#endif /* not lint */
51
52/*
53 * Spool Queue examination program
54 *
55 * lpq [-a] [-l] [-Pprinter] [user...] [job...]
56 *
57 * -a show all non-null queues on the local machine
58 * -l long output
59 * -P used to identify printer as per lpr/lprm
60 */
61
62#include <sys/param.h>
63
64#include <ctype.h>
65#include <dirent.h>
66#include <err.h>
67#include <errno.h>
68#include <unistd.h>
69#include <stdlib.h>
70#include <stdio.h>
71#include <syslog.h>
72
73#include "lp.h"
74#include "lp.local.h"
75#include "pathnames.h"
76
77int	 requ[MAXREQUESTS];	/* job number of spool entries */
78int	 requests;		/* # of spool requests */
79char	*user[MAXUSERS];	/* users to process */
80int	 users;			/* # of users in user array */
81
82volatile sig_atomic_t gotintr;
83
84static int ckqueue(char *);
85static __dead void usage(void);
86
87int
88main(int argc, char **argv)
89{
90	int	ch, aflag, lflag;
91	char	*buf, *cp;
92	long	l;
93
94	effective_uid = geteuid();
95	real_uid = getuid();
96	effective_gid = getegid();
97	real_gid = getgid();
98	PRIV_END;	/* be safe */
99
100	if (gethostname(host, sizeof(host)) != 0)
101		err(1, "gethostname");
102	openlog("lpq", 0, LOG_LPR);
103
104	aflag = lflag = 0;
105	while ((ch = getopt(argc, argv, "alP:w:")) != -1) {
106		switch(ch) {
107		case 'a':
108			++aflag;
109			break;
110		case 'l':			/* long output */
111			++lflag;
112			break;
113		case 'P':		/* printer name */
114			printer = optarg;
115			break;
116		case 'w':
117			l = strtol(optarg, &cp, 10);
118			if (*cp != '\0' || l < 0 || l >= INT_MAX)
119				errx(1, "wait time must be postive integer: %s",
120				    optarg);
121			wait_time = (u_int)l;
122			if (wait_time < 30)
123				warnx("warning: wait time less than 30 seconds");
124			break;
125		case '?':
126		default:
127			usage();
128		}
129	}
130
131	if (!aflag && printer == NULL && (printer = getenv("PRINTER")) == NULL)
132		printer = DEFLP;
133
134	for (argc -= optind, argv += optind; argc; --argc, ++argv)
135		if (isdigit(argv[0][0])) {
136			if (requests >= MAXREQUESTS)
137				fatal("too many requests");
138			requ[requests++] = atoi(*argv);
139		}
140		else {
141			if (users >= MAXUSERS)
142				fatal("too many users");
143			user[users++] = *argv;
144		}
145
146	if (aflag) {
147		while (cgetnext(&buf, printcapdb) > 0) {
148			if (ckqueue(buf) <= 0) {
149				free(buf);
150				continue;	/* no jobs */
151			}
152			for (cp = buf; *cp; cp++)
153				if (*cp == '|' || *cp == ':') {
154					*cp = '\0';
155					break;
156				}
157			printer = buf;
158			printf("%s:\n", printer);
159			displayq(lflag);
160			free(buf);
161			printf("\n");
162		}
163	} else
164		displayq(lflag);
165	exit(0);
166}
167
168/* XXX - could be common w/ lpd */
169static int
170ckqueue(char *cap)
171{
172	struct dirent *d;
173	DIR *dirp;
174	char *spooldir;
175
176	if (cgetstr(cap, "sd", &spooldir) == -1)
177		spooldir = _PATH_DEFSPOOL;
178	if ((dirp = opendir(spooldir)) == 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
190static __dead void
191usage(void)
192{
193	extern char *__progname;
194
195	fprintf(stderr,
196	    "usage: %s [-a] [-l] [-Pprinter] [user ...] [job ...]\n",
197	    __progname);
198	exit(1);
199}
200