xref: /freebsd/usr.sbin/lpr/lpq/lpq.c (revision 0b8224d1)
18a16b7a1SPedro F. Giffuni /*-
28a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
38a16b7a1SPedro F. Giffuni  *
40b561052SJoerg Wunsch  * Copyright (c) 1983, 1993
50b561052SJoerg Wunsch  *	The Regents of the University of California.  All rights reserved.
60b561052SJoerg Wunsch  *
70b561052SJoerg Wunsch  *
80b561052SJoerg Wunsch  * Redistribution and use in source and binary forms, with or without
90b561052SJoerg Wunsch  * modification, are permitted provided that the following conditions
100b561052SJoerg Wunsch  * are met:
110b561052SJoerg Wunsch  * 1. Redistributions of source code must retain the above copyright
120b561052SJoerg Wunsch  *    notice, this list of conditions and the following disclaimer.
130b561052SJoerg Wunsch  * 2. Redistributions in binary form must reproduce the above copyright
140b561052SJoerg Wunsch  *    notice, this list of conditions and the following disclaimer in the
150b561052SJoerg Wunsch  *    documentation and/or other materials provided with the distribution.
16fbbd9655SWarner Losh  * 3. Neither the name of the University nor the names of its contributors
170b561052SJoerg Wunsch  *    may be used to endorse or promote products derived from this software
180b561052SJoerg Wunsch  *    without specific prior written permission.
190b561052SJoerg Wunsch  *
200b561052SJoerg Wunsch  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
210b561052SJoerg Wunsch  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
220b561052SJoerg Wunsch  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
230b561052SJoerg Wunsch  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
240b561052SJoerg Wunsch  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
250b561052SJoerg Wunsch  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
260b561052SJoerg Wunsch  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
270b561052SJoerg Wunsch  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
280b561052SJoerg Wunsch  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
290b561052SJoerg Wunsch  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
300b561052SJoerg Wunsch  * SUCH DAMAGE.
310b561052SJoerg Wunsch  */
320b561052SJoerg Wunsch 
338e36ed92SGarance A Drosehn #include "lp.cdefs.h"		/* A cross-platform version of <sys/cdefs.h> */
340b561052SJoerg Wunsch /*
350b561052SJoerg Wunsch  * Spool Queue examination program
360b561052SJoerg Wunsch  *
370b561052SJoerg Wunsch  * lpq [-a] [-l] [-Pprinter] [user...] [job...]
380b561052SJoerg Wunsch  *
390b561052SJoerg Wunsch  * -a show all non-null queues on the local machine
400b561052SJoerg Wunsch  * -l long output
410b561052SJoerg Wunsch  * -P used to identify printer as per lpr/lprm
420b561052SJoerg Wunsch  */
430b561052SJoerg Wunsch 
440b561052SJoerg Wunsch #include <sys/param.h>
450b561052SJoerg Wunsch 
460b561052SJoerg Wunsch #include <ctype.h>
474a1a0dbeSGarrett Wollman #include <dirent.h>
484a1a0dbeSGarrett Wollman #include <err.h>
494a1a0dbeSGarrett Wollman #include <stdio.h>
504a1a0dbeSGarrett Wollman #include <stdlib.h>
514a1a0dbeSGarrett Wollman #include <syslog.h>
524a1a0dbeSGarrett Wollman #include <unistd.h>
534a1a0dbeSGarrett Wollman 
540b561052SJoerg Wunsch #include "lp.h"
550b561052SJoerg Wunsch #include "lp.local.h"
560b561052SJoerg Wunsch #include "pathnames.h"
570b561052SJoerg Wunsch 
580b561052SJoerg Wunsch int	 requ[MAXREQUESTS];	/* job number of spool entries */
590b561052SJoerg Wunsch int	 requests;		/* # of spool requests */
600b561052SJoerg Wunsch char	*user[MAXUSERS];	/* users to process */
610b561052SJoerg Wunsch int	 users;			/* # of users in user array */
620b561052SJoerg Wunsch 
63360d4ad5SWarner Losh uid_t	uid, euid;
64360d4ad5SWarner Losh 
65ba7a1ad7SGarance A Drosehn static int	 ckqueue(const struct printer *_pp);
66ba7a1ad7SGarance A Drosehn static void	 usage(void);
67ba7a1ad7SGarance A Drosehn int 		 main(int _argc, char **_argv);
680b561052SJoerg Wunsch 
690b561052SJoerg Wunsch int
main(int argc,char ** argv)70ba7a1ad7SGarance A Drosehn main(int argc, char **argv)
710b561052SJoerg Wunsch {
720b561052SJoerg Wunsch 	int ch, aflag, lflag;
73ba7a1ad7SGarance A Drosehn 	const char *printer;
744a1a0dbeSGarrett Wollman 	struct printer myprinter, *pp = &myprinter;
750b561052SJoerg Wunsch 
764a1a0dbeSGarrett Wollman 	printer = NULL;
77360d4ad5SWarner Losh 	euid = geteuid();
78360d4ad5SWarner Losh 	uid = getuid();
791d1d4a47SEitan Adler 	PRIV_END
8031058a75SGarance A Drosehn 	progname = *argv;
81cc3fd56fSGarance A Drosehn 	if (gethostname(local_host, sizeof(local_host)))
829b3fe531SPhilippe Charnier 		err(1, "gethostname");
830b561052SJoerg Wunsch 	openlog("lpd", 0, LOG_LPR);
840b561052SJoerg Wunsch 
850b561052SJoerg Wunsch 	aflag = lflag = 0;
866c3f552aSWarner Losh 	while ((ch = getopt(argc, argv, "alP:")) != -1)
870b561052SJoerg Wunsch 		switch((char)ch) {
880b561052SJoerg Wunsch 		case 'a':
890b561052SJoerg Wunsch 			++aflag;
900b561052SJoerg Wunsch 			break;
910b561052SJoerg Wunsch 		case 'l':			/* long output */
920b561052SJoerg Wunsch 			++lflag;
930b561052SJoerg Wunsch 			break;
940b561052SJoerg Wunsch 		case 'P':		/* printer name */
950b561052SJoerg Wunsch 			printer = optarg;
960b561052SJoerg Wunsch 			break;
970b561052SJoerg Wunsch 		case '?':
980b561052SJoerg Wunsch 		default:
990b561052SJoerg Wunsch 			usage();
1000b561052SJoerg Wunsch 		}
1010b561052SJoerg Wunsch 
1020b561052SJoerg Wunsch 	if (!aflag && printer == NULL && (printer = getenv("PRINTER")) == NULL)
1030b561052SJoerg Wunsch 		printer = DEFLP;
1040b561052SJoerg Wunsch 
1050b561052SJoerg Wunsch 	for (argc -= optind, argv += optind; argc; --argc, ++argv)
1060b561052SJoerg Wunsch 		if (isdigit(argv[0][0])) {
1070b561052SJoerg Wunsch 			if (requests >= MAXREQUESTS)
1084a1a0dbeSGarrett Wollman 				fatal(0, "too many requests");
1090b561052SJoerg Wunsch 			requ[requests++] = atoi(*argv);
1100b561052SJoerg Wunsch 		}
1110b561052SJoerg Wunsch 		else {
1120b561052SJoerg Wunsch 			if (users >= MAXUSERS)
1134a1a0dbeSGarrett Wollman 				fatal(0, "too many users");
1140b561052SJoerg Wunsch 			user[users++] = *argv;
1150b561052SJoerg Wunsch 		}
1160b561052SJoerg Wunsch 
1170b561052SJoerg Wunsch 	if (aflag) {
1184a1a0dbeSGarrett Wollman 		int more, status;
1194a1a0dbeSGarrett Wollman 
1204a1a0dbeSGarrett Wollman 		more = firstprinter(pp, &status);
1214a1a0dbeSGarrett Wollman 		if (status)
1224a1a0dbeSGarrett Wollman 			goto looperr;
1234a1a0dbeSGarrett Wollman 		while (more) {
1244a1a0dbeSGarrett Wollman 			if (ckqueue(pp) > 0) {
1254a1a0dbeSGarrett Wollman 				printf("%s:\n", pp->printer);
1264a1a0dbeSGarrett Wollman 				displayq(pp, lflag);
1270b561052SJoerg Wunsch 				printf("\n");
1280b561052SJoerg Wunsch 			}
1294a1a0dbeSGarrett Wollman 			do {
1304a1a0dbeSGarrett Wollman 				more = nextprinter(pp, &status);
1314a1a0dbeSGarrett Wollman looperr:
1324a1a0dbeSGarrett Wollman 				switch (status) {
1334a1a0dbeSGarrett Wollman 				case PCAPERR_TCOPEN:
1344a1a0dbeSGarrett Wollman 					printf("warning: %s: unresolved "
1354a1a0dbeSGarrett Wollman 					       "tc= reference(s) ",
1364a1a0dbeSGarrett Wollman 					       pp->printer);
1374a1a0dbeSGarrett Wollman 				case PCAPERR_SUCCESS:
1384a1a0dbeSGarrett Wollman 					break;
1394a1a0dbeSGarrett Wollman 				default:
1406d39e1b7SGarance A Drosehn 					fatal(pp, "%s", pcaperr(status));
1414a1a0dbeSGarrett Wollman 				}
1424a1a0dbeSGarrett Wollman 			} while (more && status);
1434a1a0dbeSGarrett Wollman 		}
1444a1a0dbeSGarrett Wollman 	} else {
1454a1a0dbeSGarrett Wollman 		int status;
1464a1a0dbeSGarrett Wollman 
1474a1a0dbeSGarrett Wollman 		init_printer(pp);
1484a1a0dbeSGarrett Wollman 		status = getprintcap(printer, pp);
1494a1a0dbeSGarrett Wollman 		if (status < 0)
1506d39e1b7SGarance A Drosehn 			fatal(pp, "%s", pcaperr(status));
1514a1a0dbeSGarrett Wollman 
1524a1a0dbeSGarrett Wollman 		displayq(pp, lflag);
1534a1a0dbeSGarrett Wollman 	}
1540b561052SJoerg Wunsch 	exit(0);
1550b561052SJoerg Wunsch }
1560b561052SJoerg Wunsch 
1570b561052SJoerg Wunsch static int
ckqueue(const struct printer * pp)158ba7a1ad7SGarance A Drosehn ckqueue(const struct printer *pp)
1590b561052SJoerg Wunsch {
1600b561052SJoerg Wunsch 	register struct dirent *d;
1610b561052SJoerg Wunsch 	DIR *dirp;
1620b561052SJoerg Wunsch 	char *spooldir;
1630b561052SJoerg Wunsch 
1644a1a0dbeSGarrett Wollman 	spooldir = pp->spool_dir;
1650b561052SJoerg Wunsch 	if ((dirp = opendir(spooldir)) == NULL)
1660b561052SJoerg Wunsch 		return (-1);
1670b561052SJoerg Wunsch 	while ((d = readdir(dirp)) != NULL) {
1680b561052SJoerg Wunsch 		if (d->d_name[0] != 'c' || d->d_name[1] != 'f')
1690b561052SJoerg Wunsch 			continue;	/* daemon control files only */
1700b561052SJoerg Wunsch 		closedir(dirp);
1710b561052SJoerg Wunsch 		return (1);		/* found something */
1720b561052SJoerg Wunsch 	}
1730b561052SJoerg Wunsch 	closedir(dirp);
1740b561052SJoerg Wunsch 	return (0);
1750b561052SJoerg Wunsch }
1760b561052SJoerg Wunsch 
1779b3fe531SPhilippe Charnier static void
usage(void)178ba7a1ad7SGarance A Drosehn usage(void)
1790b561052SJoerg Wunsch {
1809b3fe531SPhilippe Charnier 	fprintf(stderr,
1819b3fe531SPhilippe Charnier 	"usage: lpq [-a] [-l] [-Pprinter] [user ...] [job ...]\n");
1820b561052SJoerg Wunsch 	exit(1);
1830b561052SJoerg Wunsch }
184