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