1/*
2 * Copyright (c) 1983, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 4. Neither the name of the University nor the names of its contributors
15 *    may be used to endorse or promote products derived from this software
16 *    without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#ifndef lint
32static const char copyright[] =
33"@(#) Copyright (c) 1983, 1993\n\
34	The Regents of the University of California.  All rights reserved.\n";
35#endif /* not lint */
36
37#if 0
38#ifndef lint
39static char sccsid[] = "@(#)lpq.c	8.3 (Berkeley) 5/10/95";
40#endif /* not lint */
41#endif
42
43#include "lp.cdefs.h"		/* A cross-platform version of <sys/cdefs.h> */
44__FBSDID("$FreeBSD$");
45
46/*
47 * Spool Queue examination program
48 *
49 * lpq [-a] [-l] [-Pprinter] [user...] [job...]
50 *
51 * -a show all non-null queues on the local machine
52 * -l long output
53 * -P used to identify printer as per lpr/lprm
54 */
55
56#include <sys/param.h>
57
58#include <ctype.h>
59#include <dirent.h>
60#include <err.h>
61#include <stdio.h>
62#include <stdlib.h>
63#include <syslog.h>
64#include <unistd.h>
65
66#include "lp.h"
67#include "lp.local.h"
68#include "pathnames.h"
69
70int	 requ[MAXREQUESTS];	/* job number of spool entries */
71int	 requests;		/* # of spool requests */
72char	*user[MAXUSERS];	/* users to process */
73int	 users;			/* # of users in user array */
74
75uid_t	uid, euid;
76
77static int	 ckqueue(const struct printer *_pp);
78static void	 usage(void);
79int 		 main(int _argc, char **_argv);
80
81int
82main(int argc, char **argv)
83{
84	int ch, aflag, lflag;
85	const char *printer;
86	struct printer myprinter, *pp = &myprinter;
87
88	printer = NULL;
89	euid = geteuid();
90	uid = getuid();
91	PRIV_END
92	progname = *argv;
93	if (gethostname(local_host, sizeof(local_host)))
94		err(1, "gethostname");
95	openlog("lpd", 0, LOG_LPR);
96
97	aflag = lflag = 0;
98	while ((ch = getopt(argc, argv, "alP:")) != -1)
99		switch((char)ch) {
100		case 'a':
101			++aflag;
102			break;
103		case 'l':			/* long output */
104			++lflag;
105			break;
106		case 'P':		/* printer name */
107			printer = optarg;
108			break;
109		case '?':
110		default:
111			usage();
112		}
113
114	if (!aflag && printer == NULL && (printer = getenv("PRINTER")) == NULL)
115		printer = DEFLP;
116
117	for (argc -= optind, argv += optind; argc; --argc, ++argv)
118		if (isdigit(argv[0][0])) {
119			if (requests >= MAXREQUESTS)
120				fatal(0, "too many requests");
121			requ[requests++] = atoi(*argv);
122		}
123		else {
124			if (users >= MAXUSERS)
125				fatal(0, "too many users");
126			user[users++] = *argv;
127		}
128
129	if (aflag) {
130		int more, status;
131
132		more = firstprinter(pp, &status);
133		if (status)
134			goto looperr;
135		while (more) {
136			if (ckqueue(pp) > 0) {
137				printf("%s:\n", pp->printer);
138				displayq(pp, lflag);
139				printf("\n");
140			}
141			do {
142				more = nextprinter(pp, &status);
143looperr:
144				switch (status) {
145				case PCAPERR_TCOPEN:
146					printf("warning: %s: unresolved "
147					       "tc= reference(s) ",
148					       pp->printer);
149				case PCAPERR_SUCCESS:
150					break;
151				default:
152					fatal(pp, "%s", pcaperr(status));
153				}
154			} while (more && status);
155		}
156	} else {
157		int status;
158
159		init_printer(pp);
160		status = getprintcap(printer, pp);
161		if (status < 0)
162			fatal(pp, "%s", pcaperr(status));
163
164		displayq(pp, lflag);
165	}
166	exit(0);
167}
168
169static int
170ckqueue(const struct printer *pp)
171{
172	register struct dirent *d;
173	DIR *dirp;
174	char *spooldir;
175
176	spooldir = pp->spool_dir;
177	if ((dirp = opendir(spooldir)) == NULL)
178		return (-1);
179	while ((d = readdir(dirp)) != NULL) {
180		if (d->d_name[0] != 'c' || d->d_name[1] != 'f')
181			continue;	/* daemon control files only */
182		closedir(dirp);
183		return (1);		/* found something */
184	}
185	closedir(dirp);
186	return (0);
187}
188
189static void
190usage(void)
191{
192	fprintf(stderr,
193	"usage: lpq [-a] [-l] [-Pprinter] [user ...] [job ...]\n");
194	exit(1);
195}
196