1*2264Sjacobs /*
2*2264Sjacobs  * CDDL HEADER START
3*2264Sjacobs  *
4*2264Sjacobs  * The contents of this file are subject to the terms of the
5*2264Sjacobs  * Common Development and Distribution License (the "License").
6*2264Sjacobs  * You may not use this file except in compliance with the License.
7*2264Sjacobs  *
8*2264Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*2264Sjacobs  * or http://www.opensolaris.org/os/licensing.
10*2264Sjacobs  * See the License for the specific language governing permissions
11*2264Sjacobs  * and limitations under the License.
12*2264Sjacobs  *
13*2264Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
14*2264Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*2264Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
16*2264Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
17*2264Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
18*2264Sjacobs  *
19*2264Sjacobs  * CDDL HEADER END
20*2264Sjacobs  */
21*2264Sjacobs 
22*2264Sjacobs /*
23*2264Sjacobs  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24*2264Sjacobs  * Use is subject to license terms.
25*2264Sjacobs  *
26*2264Sjacobs  */
27*2264Sjacobs 
28*2264Sjacobs /* $Id: lpstat.c 173 2006-05-25 04:52:06Z njacobs $ */
29*2264Sjacobs 
30*2264Sjacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*2264Sjacobs 
32*2264Sjacobs #include <stdio.h>
33*2264Sjacobs #include <stdlib.h>
34*2264Sjacobs #include <unistd.h>
35*2264Sjacobs #include <string.h>
36*2264Sjacobs #include <locale.h>
37*2264Sjacobs #include <libintl.h>
38*2264Sjacobs #include <pwd.h>
39*2264Sjacobs #include <papi.h>
40*2264Sjacobs #include <uri.h>
41*2264Sjacobs #include "common.h"
42*2264Sjacobs 
43*2264Sjacobs static void
44*2264Sjacobs usage(char *program)
45*2264Sjacobs {
46*2264Sjacobs 	char *name;
47*2264Sjacobs 
48*2264Sjacobs 	if ((name = strrchr(program, '/')) == NULL)
49*2264Sjacobs 		name = program;
50*2264Sjacobs 	else
51*2264Sjacobs 		name++;
52*2264Sjacobs 
53*2264Sjacobs 	fprintf(stdout, gettext("Usage: %s [-d] [-r] [-s] [-t] [-a [list]] "
54*2264Sjacobs 		"[-c [list]] [-o [list] [-l]] [-R [list] [-l]] "
55*2264Sjacobs 		"[-p [list] [-D] [-l]] [-v [list]] [-S [list] [-l]] "
56*2264Sjacobs 		"[-f [list] [-l]] [-u list]\n"),
57*2264Sjacobs 		name);
58*2264Sjacobs 	exit(1);
59*2264Sjacobs }
60*2264Sjacobs 
61*2264Sjacobs static char *
62*2264Sjacobs nctime(time_t *t)
63*2264Sjacobs {
64*2264Sjacobs 	static char buf[64];
65*2264Sjacobs 	struct tm *tm = localtime(t);
66*2264Sjacobs 
67*2264Sjacobs 	(void) strftime(buf, sizeof (buf), "%c", tm);
68*2264Sjacobs 
69*2264Sjacobs 	return (buf);
70*2264Sjacobs }
71*2264Sjacobs 
72*2264Sjacobs static char *
73*2264Sjacobs printer_name(papi_printer_t printer)
74*2264Sjacobs {
75*2264Sjacobs 	papi_attribute_t **attributes = papiPrinterGetAttributeList(printer);
76*2264Sjacobs 	char *result = NULL;
77*2264Sjacobs 
78*2264Sjacobs 	if (attributes != NULL)
79*2264Sjacobs 		papiAttributeListGetString(attributes, NULL,
80*2264Sjacobs 				"printer-name", &result);
81*2264Sjacobs 
82*2264Sjacobs 	return (result);
83*2264Sjacobs }
84*2264Sjacobs 
85*2264Sjacobs static int
86*2264Sjacobs lpstat_default_printer(papi_encryption_t encryption)
87*2264Sjacobs {
88*2264Sjacobs 	papi_status_t status;
89*2264Sjacobs 	papi_service_t svc = NULL;
90*2264Sjacobs 	papi_printer_t p = NULL;
91*2264Sjacobs 	char *name = NULL;
92*2264Sjacobs 
93*2264Sjacobs 	status = papiServiceCreate(&svc, NULL, NULL, NULL, cli_auth_callback,
94*2264Sjacobs 					encryption, NULL);
95*2264Sjacobs 	if (status == PAPI_OK) {
96*2264Sjacobs 		char *req[] = { "printer-name", NULL };
97*2264Sjacobs 
98*2264Sjacobs 		status = papiPrinterQuery(svc, DEFAULT_DEST, req, NULL, &p);
99*2264Sjacobs 		if (p != NULL)
100*2264Sjacobs 			name = printer_name(p);
101*2264Sjacobs 	}
102*2264Sjacobs 	if (name != NULL)
103*2264Sjacobs 		printf(gettext("system default printer: %s\n"), name);
104*2264Sjacobs 	else
105*2264Sjacobs 		printf(gettext("no system default destination\n"));
106*2264Sjacobs 	papiPrinterFree(p);
107*2264Sjacobs 	papiServiceDestroy(svc);
108*2264Sjacobs 
109*2264Sjacobs 	return (0);
110*2264Sjacobs }
111*2264Sjacobs 
112*2264Sjacobs static int
113*2264Sjacobs lpstat_service_status(papi_encryption_t encryption)
114*2264Sjacobs {
115*2264Sjacobs 	int result = 0;
116*2264Sjacobs 	papi_status_t status;
117*2264Sjacobs 	papi_service_t svc = NULL;
118*2264Sjacobs 	char *name = NULL;
119*2264Sjacobs 
120*2264Sjacobs 	if (((name = getenv("PAPI_SERVICE_URI")) == NULL) &&
121*2264Sjacobs 	    ((name = getenv("IPP_SERVER")) == NULL) &&
122*2264Sjacobs 	    ((name = getenv("CUPS_SERVER")) == NULL))
123*2264Sjacobs 		name = DEFAULT_SERVICE_URI;
124*2264Sjacobs 
125*2264Sjacobs 	status = papiServiceCreate(&svc, name, NULL, NULL, cli_auth_callback,
126*2264Sjacobs 					encryption, NULL);
127*2264Sjacobs 	if (status != PAPI_OK) {
128*2264Sjacobs 		printf(gettext("scheduler is not running\n"));
129*2264Sjacobs 		result = -1;
130*2264Sjacobs 	} else
131*2264Sjacobs 		printf(gettext("scheduler is running\n"));
132*2264Sjacobs 	papiServiceDestroy(svc);
133*2264Sjacobs 
134*2264Sjacobs 	return (result);
135*2264Sjacobs }
136*2264Sjacobs 
137*2264Sjacobs static char *
138*2264Sjacobs get_device_uri(papi_service_t svc, char *name)
139*2264Sjacobs {
140*2264Sjacobs 	papi_status_t status;
141*2264Sjacobs 	papi_printer_t p = NULL;
142*2264Sjacobs 	char *keys[] = { "device-uri", NULL };
143*2264Sjacobs 	char *result = NULL;
144*2264Sjacobs 
145*2264Sjacobs 	status = papiPrinterQuery(svc, name, keys, NULL, &p);
146*2264Sjacobs 	if ((status == PAPI_OK) && (p != NULL)) {
147*2264Sjacobs 		papi_attribute_t **attrs = papiPrinterGetAttributeList(p);
148*2264Sjacobs 
149*2264Sjacobs 		(void) papiAttributeListGetString(attrs, NULL,
150*2264Sjacobs 					"device-uri", &result);
151*2264Sjacobs 		if (result != NULL)
152*2264Sjacobs 			result = strdup(result);
153*2264Sjacobs 
154*2264Sjacobs 		papiPrinterFree(p);
155*2264Sjacobs 	}
156*2264Sjacobs 
157*2264Sjacobs 	return (result);
158*2264Sjacobs }
159*2264Sjacobs 
160*2264Sjacobs static char *report_device_keys[] = { "printer-name", "printer-uri-supported",
161*2264Sjacobs 					NULL };
162*2264Sjacobs /* ARGSUSED2 */
163*2264Sjacobs static int
164*2264Sjacobs report_device(papi_service_t svc, char *name, papi_printer_t printer,
165*2264Sjacobs 		int verbose, int description)
166*2264Sjacobs {
167*2264Sjacobs 	papi_status_t status;
168*2264Sjacobs 	papi_attribute_t **attrs = papiPrinterGetAttributeList(printer);
169*2264Sjacobs 	char *uri = NULL;
170*2264Sjacobs 	char *device = NULL;
171*2264Sjacobs 	uri_t *u = NULL;
172*2264Sjacobs 
173*2264Sjacobs 	if (name == NULL) {
174*2264Sjacobs 		status = papiAttributeListGetString(attrs, NULL,
175*2264Sjacobs 					"printer-name", &name);
176*2264Sjacobs 		if (status != PAPI_OK)
177*2264Sjacobs 			status = papiAttributeListGetString(attrs, NULL,
178*2264Sjacobs 					"printer-uri-supported", &name);
179*2264Sjacobs 	}
180*2264Sjacobs 
181*2264Sjacobs 	if (name == NULL)
182*2264Sjacobs 		return (-1);
183*2264Sjacobs 
184*2264Sjacobs 	(void) papiAttributeListGetString(attrs, NULL,
185*2264Sjacobs 					"printer-uri-supported", &uri);
186*2264Sjacobs 
187*2264Sjacobs 	if ((uri != NULL) && (uri_from_string(uri, &u) == 0)) {
188*2264Sjacobs 		char *nodename = localhostname();
189*2264Sjacobs 
190*2264Sjacobs 		if ((u->host == NULL) ||
191*2264Sjacobs 		    (strcasecmp(u->host, "localhost") == 0) ||
192*2264Sjacobs 		    (strcasecmp(u->host, nodename) == 0))
193*2264Sjacobs 			device = get_device_uri(svc, name);
194*2264Sjacobs 
195*2264Sjacobs 		if (device != NULL) {
196*2264Sjacobs 			printf(gettext("device for %s: %s\n"), name, device);
197*2264Sjacobs 			return (0);
198*2264Sjacobs 		} else if (uri != NULL) {
199*2264Sjacobs 			printf(gettext("system for %s: %s (as %s)\n"), name,
200*2264Sjacobs 				u->host, uri);
201*2264Sjacobs 			return (0);
202*2264Sjacobs 		}
203*2264Sjacobs 
204*2264Sjacobs 		uri_free(u);
205*2264Sjacobs 	}
206*2264Sjacobs 
207*2264Sjacobs 	return (0);
208*2264Sjacobs }
209*2264Sjacobs 
210*2264Sjacobs static char *report_accepting_keys[] = { "printer-name",
211*2264Sjacobs 			"printer-uri-supported", "printer-is-accepting-jobs",
212*2264Sjacobs 			"printer-up-time", "printer-state-time",
213*2264Sjacobs 			"lpsched-reject-date", "lpsched-reject-reason", NULL };
214*2264Sjacobs /* ARGSUSED2 */
215*2264Sjacobs static int
216*2264Sjacobs report_accepting(papi_service_t svc, char *name, papi_printer_t printer,
217*2264Sjacobs 		int verbose, int description)
218*2264Sjacobs {
219*2264Sjacobs 	papi_status_t status;
220*2264Sjacobs 	papi_attribute_t **attrs = papiPrinterGetAttributeList(printer);
221*2264Sjacobs 	time_t curr;
222*2264Sjacobs 	char boolean = PAPI_FALSE;
223*2264Sjacobs 
224*2264Sjacobs 	if (name == NULL) {
225*2264Sjacobs 		status = papiAttributeListGetString(attrs, NULL,
226*2264Sjacobs 					"printer-name", &name);
227*2264Sjacobs 		if (status != PAPI_OK)
228*2264Sjacobs 			status = papiAttributeListGetString(attrs, NULL,
229*2264Sjacobs 					"printer-uri-supported", &name);
230*2264Sjacobs 	}
231*2264Sjacobs 	if (name == NULL)
232*2264Sjacobs 		return (-1);
233*2264Sjacobs 
234*2264Sjacobs 	(void) papiAttributeListGetBoolean(attrs, NULL,
235*2264Sjacobs 				"printer-is-accepting-jobs", &boolean);
236*2264Sjacobs 	(void) time(&curr);
237*2264Sjacobs 	(void) papiAttributeListGetDatetime(attrs, NULL,
238*2264Sjacobs 					"printer-up-time", &curr);
239*2264Sjacobs 	(void) papiAttributeListGetDatetime(attrs, NULL,
240*2264Sjacobs 					"printer-state-time", &curr);
241*2264Sjacobs 	(void) papiAttributeListGetDatetime(attrs, NULL,
242*2264Sjacobs 					"lpsched-reject-date", &curr);
243*2264Sjacobs 
244*2264Sjacobs 	if (boolean == PAPI_TRUE) {
245*2264Sjacobs 		printf(gettext("%s accepting requests since %s\n"),
246*2264Sjacobs 			name, nctime(&curr));
247*2264Sjacobs 	} else {
248*2264Sjacobs 		char *reason = "unknown reason";
249*2264Sjacobs 
250*2264Sjacobs 		(void) papiAttributeListGetString(attrs, NULL,
251*2264Sjacobs 					"lpsched-reject-reason", &reason);
252*2264Sjacobs 
253*2264Sjacobs 		printf(gettext("%s not accepting requests since %s\n\t%s\n"),
254*2264Sjacobs 			name, nctime(&curr), reason);
255*2264Sjacobs 	}
256*2264Sjacobs 
257*2264Sjacobs 	return (0);
258*2264Sjacobs }
259*2264Sjacobs 
260*2264Sjacobs static char *report_class_keys[] = { "printer-name", "printer-uri-supported",
261*2264Sjacobs 					"member-names", NULL };
262*2264Sjacobs /* ARGSUSED2 */
263*2264Sjacobs static int
264*2264Sjacobs report_class(papi_service_t svc, char *name, papi_printer_t printer,
265*2264Sjacobs 		int verbose, int description)
266*2264Sjacobs {
267*2264Sjacobs 	papi_status_t status;
268*2264Sjacobs 	papi_attribute_t **attrs = papiPrinterGetAttributeList(printer);
269*2264Sjacobs 	char *member = NULL;
270*2264Sjacobs 	void *iter = NULL;
271*2264Sjacobs 
272*2264Sjacobs 	status = papiAttributeListGetString(attrs, &iter,
273*2264Sjacobs 				"member-names", &member);
274*2264Sjacobs 	if (status == PAPI_NOT_FOUND)	/* it's not a class */
275*2264Sjacobs 		return (0);
276*2264Sjacobs 
277*2264Sjacobs 	if (name == NULL) {
278*2264Sjacobs 		status = papiAttributeListGetString(attrs, NULL,
279*2264Sjacobs 					"printer-name", &name);
280*2264Sjacobs 		if (status != PAPI_OK)
281*2264Sjacobs 			status = papiAttributeListGetString(attrs, NULL,
282*2264Sjacobs 					"printer-uri-supported", &name);
283*2264Sjacobs 	}
284*2264Sjacobs 	if (name == NULL)
285*2264Sjacobs 		return (-1);
286*2264Sjacobs 
287*2264Sjacobs 	printf(gettext("members of class %s:\n\t%s\n"), name, member);
288*2264Sjacobs 	while (papiAttributeListGetString(attrs, &iter, NULL, &member)
289*2264Sjacobs 			== PAPI_OK)
290*2264Sjacobs 		printf("\t%s\n", member);
291*2264Sjacobs 
292*2264Sjacobs 	return (0);
293*2264Sjacobs }
294*2264Sjacobs 
295*2264Sjacobs static char *report_printer_keys[] = { "printer-name",
296*2264Sjacobs 			"printer-uri-supported", "printer-state",
297*2264Sjacobs 			"printer-up-time", "printer-state-time",
298*2264Sjacobs 			"lpsched-disable-date", "printer-state-reasons",
299*2264Sjacobs 			"lpsched-disable-reason", NULL };
300*2264Sjacobs /* ARGSUSED2 */
301*2264Sjacobs static int
302*2264Sjacobs report_printer(papi_service_t svc, char *name, papi_printer_t printer,
303*2264Sjacobs 		int verbose, int description)
304*2264Sjacobs {
305*2264Sjacobs 	papi_status_t status;
306*2264Sjacobs 	papi_attribute_t **attrs = papiPrinterGetAttributeList(printer);
307*2264Sjacobs 	time_t curr;
308*2264Sjacobs 	int32_t pstat = 0;
309*2264Sjacobs 	char *member = NULL;
310*2264Sjacobs 
311*2264Sjacobs 	status = papiAttributeListGetString(attrs, NULL,
312*2264Sjacobs 				"member-names", &member);
313*2264Sjacobs 	if (status == PAPI_OK)	/* it's a class */
314*2264Sjacobs 		return (0);
315*2264Sjacobs 
316*2264Sjacobs 	if (name == NULL) {
317*2264Sjacobs 		status = papiAttributeListGetString(attrs, NULL,
318*2264Sjacobs 					"printer-name", &name);
319*2264Sjacobs 		if (status != PAPI_OK)
320*2264Sjacobs 			status = papiAttributeListGetString(attrs, NULL,
321*2264Sjacobs 					"printer-uri-supported", &name);
322*2264Sjacobs 	}
323*2264Sjacobs 	if (name == NULL)
324*2264Sjacobs 		return (-1);
325*2264Sjacobs 
326*2264Sjacobs 	printf(gettext("printer %s "), name);
327*2264Sjacobs 
328*2264Sjacobs 	status = papiAttributeListGetInteger(attrs, NULL,
329*2264Sjacobs 					"printer-state", &pstat);
330*2264Sjacobs 
331*2264Sjacobs 	switch (pstat) {
332*2264Sjacobs 	case 0x03:	/* idle */
333*2264Sjacobs 		printf(gettext("idle. enabled"));
334*2264Sjacobs 		break;
335*2264Sjacobs 	case 0x04: {	/* processing */
336*2264Sjacobs 		char *requested[] = { "job-id", NULL };
337*2264Sjacobs 		papi_job_t *j = NULL;
338*2264Sjacobs 		int32_t jobid = 0;
339*2264Sjacobs 
340*2264Sjacobs 		(void) papiPrinterListJobs(svc, name, requested, 0, 1, &j);
341*2264Sjacobs 		if ((j != NULL) && (j[0] != NULL))
342*2264Sjacobs 			jobid = papiJobGetId(j[0]);
343*2264Sjacobs 		papiJobListFree(j);
344*2264Sjacobs 
345*2264Sjacobs 		printf(gettext("now printing %s-%d. enabled"), name, jobid);
346*2264Sjacobs 		}
347*2264Sjacobs 		break;
348*2264Sjacobs 	case 0x05:	/* stopped */
349*2264Sjacobs 		printf(gettext("disabled"));
350*2264Sjacobs 		break;
351*2264Sjacobs 	default:
352*2264Sjacobs 		printf(gettext("unknown state(0x%x)."), pstat);
353*2264Sjacobs 		break;
354*2264Sjacobs 	}
355*2264Sjacobs 
356*2264Sjacobs 	(void) time(&curr);
357*2264Sjacobs 	(void) papiAttributeListGetDatetime(attrs, NULL,
358*2264Sjacobs 					"printer-up-time", &curr);
359*2264Sjacobs 	(void) papiAttributeListGetDatetime(attrs, NULL,
360*2264Sjacobs 					"printer-state-time", &curr);
361*2264Sjacobs 	(void) papiAttributeListGetDatetime(attrs, NULL,
362*2264Sjacobs 					"lpsched-disable-date", &curr);
363*2264Sjacobs 	printf(gettext(" since %s. available.\n"), nctime(&curr));
364*2264Sjacobs 
365*2264Sjacobs 	if (pstat == 0x05) {
366*2264Sjacobs 		char *reason = "unknown reason";
367*2264Sjacobs 
368*2264Sjacobs 		(void) papiAttributeListGetString(attrs, NULL,
369*2264Sjacobs 					"printer-state-reasons", &reason);
370*2264Sjacobs 		(void) papiAttributeListGetString(attrs, NULL,
371*2264Sjacobs 					"lpsched-disable-reason", &reason);
372*2264Sjacobs 		printf(gettext("\t%s\n"), reason);
373*2264Sjacobs 	}
374*2264Sjacobs 
375*2264Sjacobs 	if (verbose == 1) {
376*2264Sjacobs 		void *iter;
377*2264Sjacobs 		char *str;
378*2264Sjacobs 
379*2264Sjacobs 		str = "";
380*2264Sjacobs 		(void) papiAttributeListGetString(attrs, NULL,
381*2264Sjacobs 					"form-ready", &str);
382*2264Sjacobs 		printf(gettext("\tForm mounted: %s\n"), str);
383*2264Sjacobs 
384*2264Sjacobs 		str = "";
385*2264Sjacobs 		iter = NULL;
386*2264Sjacobs 		(void) papiAttributeListGetString(attrs, &iter,
387*2264Sjacobs 					"document-format-supported", &str);
388*2264Sjacobs 		printf(gettext("\tContent types: %s"), str);
389*2264Sjacobs 		while (papiAttributeListGetString(attrs, &iter, NULL, &str)
390*2264Sjacobs 				== PAPI_OK)
391*2264Sjacobs 			printf(", %s", str);
392*2264Sjacobs 		printf("\n");
393*2264Sjacobs 
394*2264Sjacobs 		str = "";
395*2264Sjacobs 		(void) papiAttributeListGetString(attrs, NULL,
396*2264Sjacobs 					"printer-info", &str);
397*2264Sjacobs 		printf(gettext("\tDescription: %s\n"), str);
398*2264Sjacobs 
399*2264Sjacobs 		str = "";
400*2264Sjacobs 		(void) papiAttributeListGetString(attrs, NULL,
401*2264Sjacobs 					"lpsched-dial-info", &str);
402*2264Sjacobs 		printf(gettext("\tConnection: %s\n"),
403*2264Sjacobs 			((str[0] != '\0') ? gettext("direct") : str));
404*2264Sjacobs 
405*2264Sjacobs 		str = "";
406*2264Sjacobs 		(void) papiAttributeListGetString(attrs, NULL,
407*2264Sjacobs 					"lpsched-interface-script", &str);
408*2264Sjacobs 		printf(gettext("\tInterface: %s\n"), str);
409*2264Sjacobs 
410*2264Sjacobs 		str = NULL;
411*2264Sjacobs 		(void) papiAttributeListGetString(attrs, NULL,
412*2264Sjacobs 					"ppd-file-uri", &str);
413*2264Sjacobs 		(void) papiAttributeListGetString(attrs, NULL,
414*2264Sjacobs 					"lpsched-ppd-source-path", &str);
415*2264Sjacobs 		if (str != NULL)
416*2264Sjacobs 			printf(gettext("\tPPD: %s\n"), str);
417*2264Sjacobs 
418*2264Sjacobs 		str = NULL;
419*2264Sjacobs 		(void) papiAttributeListGetString(attrs, NULL,
420*2264Sjacobs 					"lpsched-fault-alert-command", &str);
421*2264Sjacobs 		if (str != NULL)
422*2264Sjacobs 			printf(gettext("\tOn fault: %s\n"), str);
423*2264Sjacobs 
424*2264Sjacobs 		str = "";
425*2264Sjacobs 		(void) papiAttributeListGetString(attrs, NULL,
426*2264Sjacobs 					"lpsched-fault-recovery", &str);
427*2264Sjacobs 		printf(gettext("\tAfter fault: %s\n"),
428*2264Sjacobs 			((str[0] == '\0') ? gettext("continue") : str));
429*2264Sjacobs 
430*2264Sjacobs 		str = "(all)";
431*2264Sjacobs 		iter = NULL;
432*2264Sjacobs 		(void) papiAttributeListGetString(attrs, &iter,
433*2264Sjacobs 					"requesting-user-name-allowed", &str);
434*2264Sjacobs 		printf(gettext("\tUsers allowed:\n\t\t%s\n"),
435*2264Sjacobs 			((str[0] == '\0') ? gettext("(none)") : str));
436*2264Sjacobs 		if ((str != NULL) && (str[0] != '\0'))
437*2264Sjacobs 			while (papiAttributeListGetString(attrs, &iter, NULL,
438*2264Sjacobs 					&str) == PAPI_OK)
439*2264Sjacobs 				printf("\t\t%s\n", str);
440*2264Sjacobs 
441*2264Sjacobs 		str = NULL;
442*2264Sjacobs 		iter = NULL;
443*2264Sjacobs 		(void) papiAttributeListGetString(attrs, &iter,
444*2264Sjacobs 					"requesting-user-name-denied", &str);
445*2264Sjacobs 		if (str != NULL) {
446*2264Sjacobs 			printf(gettext("\tUsers denied:\n\t\t%s\n"),
447*2264Sjacobs 				((str[0] == '\0') ? gettext("(none)") : str));
448*2264Sjacobs 			if ((str != NULL) && (str[0] != '\0'))
449*2264Sjacobs 				while (papiAttributeListGetString(attrs, &iter,
450*2264Sjacobs 						NULL, &str) == PAPI_OK)
451*2264Sjacobs 					printf("\t\t%s\n", str);
452*2264Sjacobs 		}
453*2264Sjacobs 
454*2264Sjacobs 		str = "(none)";
455*2264Sjacobs 		iter = NULL;
456*2264Sjacobs 		(void) papiAttributeListGetString(attrs, &iter,
457*2264Sjacobs 					"form-supported", &str);
458*2264Sjacobs 		printf(gettext("\tForms allowed:\n\t\t%s\n"),
459*2264Sjacobs 			((str[0] == '\0') ? gettext("(none)") : str));
460*2264Sjacobs 		if ((str != NULL) && (str[0] != '\0'))
461*2264Sjacobs 			while (papiAttributeListGetString(attrs, &iter, NULL,
462*2264Sjacobs 					&str) == PAPI_OK)
463*2264Sjacobs 				printf("\t\t%s\n", str);
464*2264Sjacobs 
465*2264Sjacobs 		str = "";
466*2264Sjacobs 		iter = NULL;
467*2264Sjacobs 		(void) papiAttributeListGetString(attrs, &iter,
468*2264Sjacobs 					"media-supported", &str);
469*2264Sjacobs 		printf(gettext("\tMedia supported:\n\t\t%s\n"),
470*2264Sjacobs 			((str[0] == '\0') ? gettext("(none)") : str));
471*2264Sjacobs 		if ((str != NULL) && (str[0] != '\0'))
472*2264Sjacobs 			while (papiAttributeListGetString(attrs, &iter, NULL,
473*2264Sjacobs 					&str) == PAPI_OK)
474*2264Sjacobs 				printf("\t\t%s\n", str);
475*2264Sjacobs 
476*2264Sjacobs 		str = "";
477*2264Sjacobs 		(void) papiAttributeListGetString(attrs, NULL,
478*2264Sjacobs 					"job-sheets-supported", &str);
479*2264Sjacobs 		printf(gettext("\tBanner %s\n"),
480*2264Sjacobs 			(strcasecmp(str, "none") == 0 ?
481*2264Sjacobs 				gettext("not required") : gettext("required")));
482*2264Sjacobs 
483*2264Sjacobs 		str = "";
484*2264Sjacobs 		iter = NULL;
485*2264Sjacobs 		(void) papiAttributeListGetString(attrs, &iter,
486*2264Sjacobs 					"lpsched-print-wheels", &str);
487*2264Sjacobs 		printf(gettext("\tCharacter sets:\n\t\t%s\n"),
488*2264Sjacobs 			((str[0] == '\0') ? gettext("(none)") : str));
489*2264Sjacobs 		if ((str != NULL) && (str[0] != '\0'))
490*2264Sjacobs 			while (papiAttributeListGetString(attrs, &iter, NULL,
491*2264Sjacobs 					&str) == PAPI_OK)
492*2264Sjacobs 				printf("\t\t%s\n", str);
493*2264Sjacobs 
494*2264Sjacobs 		printf(gettext("\tDefault pitch:\n"));
495*2264Sjacobs 		printf(gettext("\tDefault page size:\n"));
496*2264Sjacobs 		printf(gettext("\tDefault port setting:\n"));
497*2264Sjacobs 
498*2264Sjacobs 		str = "";
499*2264Sjacobs 		iter = NULL;
500*2264Sjacobs 		(void) papiAttributeListGetString(attrs, &iter,
501*2264Sjacobs 					"lpsched-options", &str);
502*2264Sjacobs 		if (str != NULL) {
503*2264Sjacobs 			printf(gettext("\tOptions: %s"), str);
504*2264Sjacobs 			while (papiAttributeListGetString(attrs, &iter, NULL,
505*2264Sjacobs 						&str) == PAPI_OK)
506*2264Sjacobs 				printf(", %s", str);
507*2264Sjacobs 			printf("\n");
508*2264Sjacobs 		}
509*2264Sjacobs 
510*2264Sjacobs 	} else if (description == 1) {
511*2264Sjacobs 		char *str = "";
512*2264Sjacobs 		(void) papiAttributeListGetString(attrs, NULL,
513*2264Sjacobs 					"printer-description", &str);
514*2264Sjacobs 		printf(gettext("\tDescription: %s\n"), str);
515*2264Sjacobs 	} else if (verbose > 1)
516*2264Sjacobs 		papiAttributeListPrint(stdout, attrs, "\t");
517*2264Sjacobs 
518*2264Sjacobs 	if (verbose > 0)
519*2264Sjacobs 		printf("\n");
520*2264Sjacobs 
521*2264Sjacobs 	return (0);
522*2264Sjacobs }
523*2264Sjacobs 
524*2264Sjacobs static int
525*2264Sjacobs printer_query(char *name, int (*report)(papi_service_t, char *, papi_printer_t,
526*2264Sjacobs 					int, int), papi_encryption_t encryption,
527*2264Sjacobs 		int verbose, int description)
528*2264Sjacobs {
529*2264Sjacobs 	int result = 0;
530*2264Sjacobs 	papi_status_t status;
531*2264Sjacobs 	papi_service_t svc = NULL;
532*2264Sjacobs 
533*2264Sjacobs 	status = papiServiceCreate(&svc, name, NULL, NULL, cli_auth_callback,
534*2264Sjacobs 					encryption, NULL);
535*2264Sjacobs 	if (status != PAPI_OK) {
536*2264Sjacobs 		fprintf(stderr, gettext(
537*2264Sjacobs 			"Failed to contact service for %s: %s\n"),
538*2264Sjacobs 			name ? name : "(NULL)",
539*2264Sjacobs 			verbose_papi_message(svc, status));
540*2264Sjacobs 		papiServiceDestroy(svc);
541*2264Sjacobs 		return (-1);
542*2264Sjacobs 	}
543*2264Sjacobs 
544*2264Sjacobs 	if (name == NULL) { /* all */
545*2264Sjacobs 		char **interest = interest_list(svc);
546*2264Sjacobs 
547*2264Sjacobs 		if (interest != NULL) {
548*2264Sjacobs 			int i;
549*2264Sjacobs 
550*2264Sjacobs 			for (i = 0; interest[i] != NULL; i++)
551*2264Sjacobs 				result += printer_query(interest[i], report,
552*2264Sjacobs 							encryption, verbose,
553*2264Sjacobs 							description);
554*2264Sjacobs 		}
555*2264Sjacobs 	} else {
556*2264Sjacobs 		papi_printer_t printer = NULL;
557*2264Sjacobs 		char **keys = NULL;
558*2264Sjacobs 
559*2264Sjacobs 		/*
560*2264Sjacobs 		 * Limit the query to only required data to reduce the need
561*2264Sjacobs 		 * to go remote for information.
562*2264Sjacobs 		 */
563*2264Sjacobs 		if (report == report_device)
564*2264Sjacobs 			keys = report_device_keys;
565*2264Sjacobs 		else if (report == report_class)
566*2264Sjacobs 			keys = report_class_keys;
567*2264Sjacobs 		else if (report == report_accepting)
568*2264Sjacobs 			keys = report_accepting_keys;
569*2264Sjacobs 		else if ((report == report_printer) && (verbose == 0))
570*2264Sjacobs 			keys = report_printer_keys;
571*2264Sjacobs 
572*2264Sjacobs 		status = papiPrinterQuery(svc, name, keys, NULL, &printer);
573*2264Sjacobs 		if (status != PAPI_OK) {
574*2264Sjacobs 			fprintf(stderr, gettext(
575*2264Sjacobs 				"Failed to get printer info for %s: %s\n"),
576*2264Sjacobs 				name, verbose_papi_message(svc, status));
577*2264Sjacobs 			papiServiceDestroy(svc);
578*2264Sjacobs 			return (-1);
579*2264Sjacobs 		}
580*2264Sjacobs 
581*2264Sjacobs 		if (printer != NULL)
582*2264Sjacobs 			result = report(svc, name, printer, verbose,
583*2264Sjacobs 					description);
584*2264Sjacobs 
585*2264Sjacobs 		papiPrinterFree(printer);
586*2264Sjacobs 	}
587*2264Sjacobs 
588*2264Sjacobs 	papiServiceDestroy(svc);
589*2264Sjacobs 
590*2264Sjacobs 	return (result);
591*2264Sjacobs }
592*2264Sjacobs 
593*2264Sjacobs static int
594*2264Sjacobs match_user(char *user, char **list)
595*2264Sjacobs {
596*2264Sjacobs 	int i;
597*2264Sjacobs 
598*2264Sjacobs 	for (i = 0; list[i] != NULL; i++) {
599*2264Sjacobs 		if (strcmp(user, list[i]) == 0)
600*2264Sjacobs 			return (0);
601*2264Sjacobs 	}
602*2264Sjacobs 
603*2264Sjacobs 	return (-1);
604*2264Sjacobs }
605*2264Sjacobs 
606*2264Sjacobs static char **users = NULL;
607*2264Sjacobs 
608*2264Sjacobs static int
609*2264Sjacobs report_job(papi_job_t job, int show_rank, int verbose)
610*2264Sjacobs {
611*2264Sjacobs 	papi_attribute_t **attrs = papiJobGetAttributeList(job);
612*2264Sjacobs 	time_t clock = 0;
613*2264Sjacobs 	char date[24];
614*2264Sjacobs 	char request[26];
615*2264Sjacobs 	char *user = "unknown";
616*2264Sjacobs 	int32_t size = 0;
617*2264Sjacobs 	int32_t jstate = 0;
618*2264Sjacobs 
619*2264Sjacobs 	char *destination = "unknown";
620*2264Sjacobs 	int32_t id = -1;
621*2264Sjacobs 
622*2264Sjacobs 	(void) papiAttributeListGetString(attrs, NULL,
623*2264Sjacobs 				"job-originating-user-name", &user);
624*2264Sjacobs 
625*2264Sjacobs 	if ((users != NULL) && (match_user(user, users) < 0))
626*2264Sjacobs 		return (0);
627*2264Sjacobs 
628*2264Sjacobs 	(void) papiAttributeListGetInteger(attrs, NULL, "job-k-octets", &size);
629*2264Sjacobs 	size *= 1024;	/* for the approximate byte size */
630*2264Sjacobs 	(void) papiAttributeListGetInteger(attrs, NULL, "job-octets", &size);
631*2264Sjacobs 
632*2264Sjacobs 	(void) time(&clock);
633*2264Sjacobs 	(void) papiAttributeListGetInteger(attrs, NULL,
634*2264Sjacobs 				"time-at-creation", (int32_t *)&clock);
635*2264Sjacobs 	(void) strftime(date, sizeof (date), "%b %d %R", localtime(&clock));
636*2264Sjacobs 
637*2264Sjacobs 	(void) papiAttributeListGetString(attrs, NULL,
638*2264Sjacobs 				"job-printer-uri", &destination);
639*2264Sjacobs 	(void) papiAttributeListGetString(attrs, NULL,
640*2264Sjacobs 				"printer-name", &destination);
641*2264Sjacobs 	(void) papiAttributeListGetInteger(attrs, NULL,
642*2264Sjacobs 				"job-id", &id);
643*2264Sjacobs 	snprintf(request, sizeof (request), "%s-%d", destination, id);
644*2264Sjacobs 
645*2264Sjacobs 	if (show_rank != 0) {
646*2264Sjacobs 		int32_t rank = -1;
647*2264Sjacobs 
648*2264Sjacobs 		(void) papiAttributeListGetInteger(attrs, NULL,
649*2264Sjacobs 				"number-of-intervening-jobs", &rank);
650*2264Sjacobs 		rank++;
651*2264Sjacobs 
652*2264Sjacobs 		printf("%3d %-21s %-14s %7ld %s",
653*2264Sjacobs 			rank, request, user, size, date);
654*2264Sjacobs 	} else
655*2264Sjacobs 		printf("%-23s %-14s %7ld   %s", request, user, size, date);
656*2264Sjacobs 
657*2264Sjacobs 	(void) papiAttributeListGetInteger(attrs, NULL,
658*2264Sjacobs 				"job-state", &jstate);
659*2264Sjacobs 	if (jstate == 0x04)
660*2264Sjacobs 		printf(gettext(", being held"));
661*2264Sjacobs 	else if (jstate == 0x07)
662*2264Sjacobs 		printf(gettext(", cancelled"));
663*2264Sjacobs 	else if (jstate == 0x09)
664*2264Sjacobs 		printf(gettext(", complete"));
665*2264Sjacobs 
666*2264Sjacobs 	if (verbose == 1) {
667*2264Sjacobs 		(void) papiAttributeListGetString(attrs, NULL,
668*2264Sjacobs 				"output-device-assigned", &destination);
669*2264Sjacobs 		printf("\n\t assigned %s", destination);
670*2264Sjacobs 	} else if (verbose > 1) {
671*2264Sjacobs 		printf("\n");
672*2264Sjacobs 		papiAttributeListPrint(stdout, attrs, "\t");
673*2264Sjacobs 	}
674*2264Sjacobs 
675*2264Sjacobs 	printf("\n");
676*2264Sjacobs 
677*2264Sjacobs 	return (0);
678*2264Sjacobs }
679*2264Sjacobs 
680*2264Sjacobs static int
681*2264Sjacobs job_query(char *request, int (*report)(papi_job_t, int, int),
682*2264Sjacobs 		papi_encryption_t encryption, int show_rank, int verbose)
683*2264Sjacobs {
684*2264Sjacobs 	int result = 0;
685*2264Sjacobs 	papi_status_t status;
686*2264Sjacobs 	papi_service_t svc = NULL;
687*2264Sjacobs 	char *printer = NULL;
688*2264Sjacobs 	int32_t id = -1;
689*2264Sjacobs 
690*2264Sjacobs 	get_printer_id(request, &printer, &id);
691*2264Sjacobs 
692*2264Sjacobs 	status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback,
693*2264Sjacobs 					encryption, NULL);
694*2264Sjacobs 	if (status != PAPI_OK) {
695*2264Sjacobs 		fprintf(stderr, gettext(
696*2264Sjacobs 			"Failed to contact service for %s: %s\n"),
697*2264Sjacobs 			(printer ? printer : "all"),
698*2264Sjacobs 			verbose_papi_message(svc, status));
699*2264Sjacobs 		return (-1);
700*2264Sjacobs 	}
701*2264Sjacobs 
702*2264Sjacobs 	if (printer == NULL) { /* all */
703*2264Sjacobs 		char **interest = interest_list(svc);
704*2264Sjacobs 
705*2264Sjacobs 		if (interest != NULL) {
706*2264Sjacobs 			int i;
707*2264Sjacobs 
708*2264Sjacobs 			for (i = 0; interest[i] != NULL; i++)
709*2264Sjacobs 				result += job_query(interest[i], report,
710*2264Sjacobs 						encryption, show_rank, verbose);
711*2264Sjacobs 		}
712*2264Sjacobs 	} else if (id == -1) { /* a printer */
713*2264Sjacobs 		papi_job_t *jobs = NULL;
714*2264Sjacobs 
715*2264Sjacobs 		status = papiPrinterListJobs(svc, printer, NULL, 0, 0, &jobs);
716*2264Sjacobs 		if (status != PAPI_OK) {
717*2264Sjacobs 			fprintf(stderr, gettext(
718*2264Sjacobs 				"Failed to get job list: %s\n"),
719*2264Sjacobs 				verbose_papi_message(svc, status));
720*2264Sjacobs 			papiServiceDestroy(svc);
721*2264Sjacobs 			return (-1);
722*2264Sjacobs 		}
723*2264Sjacobs 
724*2264Sjacobs 		if (jobs != NULL) {
725*2264Sjacobs 			int i;
726*2264Sjacobs 
727*2264Sjacobs 			for (i = 0; jobs[i] != NULL; i++)
728*2264Sjacobs 				result += report(jobs[i], show_rank, verbose);
729*2264Sjacobs 		}
730*2264Sjacobs 
731*2264Sjacobs 		papiJobListFree(jobs);
732*2264Sjacobs 	} else {	/* a job */
733*2264Sjacobs 		papi_job_t job = NULL;
734*2264Sjacobs 
735*2264Sjacobs 		status = papiJobQuery(svc, printer, id, NULL, &job);
736*2264Sjacobs 		if (status != PAPI_OK) {
737*2264Sjacobs 			fprintf(stderr, gettext(
738*2264Sjacobs 				"Failed to get job info for %s: %s\n"),
739*2264Sjacobs 				request, verbose_papi_message(svc, status));
740*2264Sjacobs 			papiServiceDestroy(svc);
741*2264Sjacobs 			return (-1);
742*2264Sjacobs 		}
743*2264Sjacobs 
744*2264Sjacobs 		if (job != NULL)
745*2264Sjacobs 			result = report(job, show_rank, verbose);
746*2264Sjacobs 
747*2264Sjacobs 		papiJobFree(job);
748*2264Sjacobs 	}
749*2264Sjacobs 
750*2264Sjacobs 	papiServiceDestroy(svc);
751*2264Sjacobs 
752*2264Sjacobs 	return (result);
753*2264Sjacobs }
754*2264Sjacobs 
755*2264Sjacobs static int
756*2264Sjacobs report_form(char *name, papi_attribute_t **attrs, int verbose)
757*2264Sjacobs {
758*2264Sjacobs 	papi_status_t status;
759*2264Sjacobs 	char *form = NULL;
760*2264Sjacobs 	void *iter = NULL;
761*2264Sjacobs 
762*2264Sjacobs 	for (status = papiAttributeListGetString(attrs, &iter,
763*2264Sjacobs 					"form-supported", &form);
764*2264Sjacobs 		status == PAPI_OK;
765*2264Sjacobs 		status = papiAttributeListGetString(attrs, &iter,
766*2264Sjacobs 							NULL, &form)) {
767*2264Sjacobs 		if ((name == NULL) || (strcmp(name, form) == 0)) {
768*2264Sjacobs 			printf(gettext("form %s is available to you\n"), form);
769*2264Sjacobs 			if (verbose != 0) {
770*2264Sjacobs 				char *detail = NULL;
771*2264Sjacobs 				status = papiAttributeListGetString(attrs, NULL,
772*2264Sjacobs 						"form-supported-detail",
773*2264Sjacobs 						&detail);
774*2264Sjacobs 				if (status == PAPI_OK)
775*2264Sjacobs 					printf("%s\n", detail);
776*2264Sjacobs 			}
777*2264Sjacobs 		}
778*2264Sjacobs 	}
779*2264Sjacobs 
780*2264Sjacobs 	return (0);
781*2264Sjacobs }
782*2264Sjacobs 
783*2264Sjacobs static int
784*2264Sjacobs report_print_wheels(char *name, papi_attribute_t **attrs, int verbose)
785*2264Sjacobs {
786*2264Sjacobs 	papi_status_t status;
787*2264Sjacobs 	char *pw = NULL;
788*2264Sjacobs 	void *iter = NULL;
789*2264Sjacobs 
790*2264Sjacobs 	for (status = papiAttributeListGetString(attrs, &iter,
791*2264Sjacobs 					"pw-supported", &pw);
792*2264Sjacobs 		status == PAPI_OK;
793*2264Sjacobs 		status = papiAttributeListGetString(attrs, &iter, NULL, &pw)) {
794*2264Sjacobs 		if ((name == NULL) || (strcmp(name, pw) == 0)) {
795*2264Sjacobs 			printf(gettext("charset %s is available\n"), pw);
796*2264Sjacobs 			if (verbose != 0) {
797*2264Sjacobs 				char *info = NULL;
798*2264Sjacobs 				status = papiAttributeListGetString(attrs, NULL,
799*2264Sjacobs 						"pw-supported-extra", &info);
800*2264Sjacobs 				if (status == PAPI_OK)
801*2264Sjacobs 					printf("%s\n", info);
802*2264Sjacobs 			}
803*2264Sjacobs 		}
804*2264Sjacobs 	}
805*2264Sjacobs 
806*2264Sjacobs 	return (0);
807*2264Sjacobs }
808*2264Sjacobs 
809*2264Sjacobs static int
810*2264Sjacobs service_query(char *name, int (*report)(char *, papi_attribute_t **, int),
811*2264Sjacobs 		papi_encryption_t encryption, int verbose)
812*2264Sjacobs {
813*2264Sjacobs 	int result = 0;
814*2264Sjacobs 	papi_status_t status;
815*2264Sjacobs 	papi_service_t svc = NULL;
816*2264Sjacobs 	papi_attribute_t **attrs = NULL;
817*2264Sjacobs 
818*2264Sjacobs 	status = papiServiceCreate(&svc, name, NULL, NULL, cli_auth_callback,
819*2264Sjacobs 					encryption, NULL);
820*2264Sjacobs 	if (status != PAPI_OK) {
821*2264Sjacobs 		papiServiceDestroy(svc);
822*2264Sjacobs 		return (-1);
823*2264Sjacobs 	}
824*2264Sjacobs 
825*2264Sjacobs 	attrs = papiServiceGetAttributeList(svc);
826*2264Sjacobs 	if (attrs != NULL) {
827*2264Sjacobs 		result = report(name, attrs, verbose);
828*2264Sjacobs 
829*2264Sjacobs 		if (verbose > 1) {
830*2264Sjacobs 			printf("\n");
831*2264Sjacobs 			papiAttributeListPrint(stdout, attrs, "\t");
832*2264Sjacobs 			printf("\n");
833*2264Sjacobs 		}
834*2264Sjacobs 	}
835*2264Sjacobs 
836*2264Sjacobs 	papiServiceDestroy(svc);
837*2264Sjacobs 
838*2264Sjacobs 	return (result);
839*2264Sjacobs }
840*2264Sjacobs 
841*2264Sjacobs int
842*2264Sjacobs main(int ac, char *av[])
843*2264Sjacobs {
844*2264Sjacobs 	int exit_code = 0;
845*2264Sjacobs 	papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
846*2264Sjacobs 	int rank = 0;
847*2264Sjacobs 	int verbose = 0;
848*2264Sjacobs 	int description = 0;
849*2264Sjacobs 	int c;
850*2264Sjacobs 	char **argv;
851*2264Sjacobs 
852*2264Sjacobs 	(void) setlocale(LC_ALL, "");
853*2264Sjacobs 	(void) textdomain("SUNW_OST_OSCMD");
854*2264Sjacobs 
855*2264Sjacobs 	argv = (char **)calloc((ac + 1), sizeof (char *));
856*2264Sjacobs 	for (c = 0; c < ac; c++)
857*2264Sjacobs 		argv[c] = av[c];
858*2264Sjacobs 	argv[c++] = "--";
859*2264Sjacobs 	ac = c;
860*2264Sjacobs 
861*2264Sjacobs 	/* preprocess argument list looking for '-l' or '-R' so it can trail */
862*2264Sjacobs 	while ((c = getopt(ac, argv, "LEDf:S:stc:p:a:drs:v:l:o:R:u:")) != EOF)
863*2264Sjacobs 		switch (c) {
864*2264Sjacobs 		case 'l':
865*2264Sjacobs 			if ((optarg == NULL) || (optarg[0] == '-'))
866*2264Sjacobs 				optarg = "1";
867*2264Sjacobs 			verbose = atoi(optarg);
868*2264Sjacobs 			break;
869*2264Sjacobs 		case 'D':
870*2264Sjacobs 			description = 1;
871*2264Sjacobs 			break;
872*2264Sjacobs 		case 'R':
873*2264Sjacobs 			rank = 1;
874*2264Sjacobs 			break;
875*2264Sjacobs 		case 'E':
876*2264Sjacobs 			encryption = PAPI_ENCRYPT_REQUIRED;
877*2264Sjacobs 			break;
878*2264Sjacobs 		default:
879*2264Sjacobs 			break;
880*2264Sjacobs 		}
881*2264Sjacobs 	optind = 1;
882*2264Sjacobs 
883*2264Sjacobs 	/* process command line arguments */
884*2264Sjacobs 	while ((c = getopt(ac, argv, "LEDf:S:stc:p:a:drs:v:l:o:R:u:")) != EOF) {
885*2264Sjacobs 		switch (c) {	/* these may or may not have an option */
886*2264Sjacobs 		case 'a':
887*2264Sjacobs 		case 'c':
888*2264Sjacobs 		case 'p':
889*2264Sjacobs 		case 'o':
890*2264Sjacobs 		case 'R':
891*2264Sjacobs 		case 'u':
892*2264Sjacobs 		case 'v':
893*2264Sjacobs 		case 'l':
894*2264Sjacobs 		case 'f':
895*2264Sjacobs 		case 'S':
896*2264Sjacobs 			if (optarg[0] == '-') {
897*2264Sjacobs 				/* this check stop a possible infinite loop */
898*2264Sjacobs 				if ((optind > 1) && (argv[optind-1][1] != c))
899*2264Sjacobs 					optind--;
900*2264Sjacobs 				optarg = NULL;
901*2264Sjacobs 			} else if (strcmp(optarg, "all") == 0)
902*2264Sjacobs 				optarg = NULL;
903*2264Sjacobs 		}
904*2264Sjacobs 
905*2264Sjacobs 		switch (c) {
906*2264Sjacobs 		case 'a':
907*2264Sjacobs 			exit_code += printer_query(optarg, report_accepting,
908*2264Sjacobs 						encryption, verbose, 0);
909*2264Sjacobs 			break;
910*2264Sjacobs 		case 'c':
911*2264Sjacobs 			exit_code += printer_query(optarg, report_class,
912*2264Sjacobs 						encryption, verbose, 0);
913*2264Sjacobs 			break;
914*2264Sjacobs 		case 'p':
915*2264Sjacobs 			exit_code += printer_query(optarg, report_printer,
916*2264Sjacobs 						encryption, verbose,
917*2264Sjacobs 						description);
918*2264Sjacobs 			break;
919*2264Sjacobs 		case 'd':
920*2264Sjacobs 			exit_code += lpstat_default_printer(encryption);
921*2264Sjacobs 			break;
922*2264Sjacobs 		case 'r':
923*2264Sjacobs 			exit_code += lpstat_service_status(encryption);
924*2264Sjacobs 			break;
925*2264Sjacobs 		case 'u':
926*2264Sjacobs 			if (optarg != NULL)
927*2264Sjacobs 				users = strsplit(optarg, ", \n");
928*2264Sjacobs 			exit_code += job_query(NULL, report_job,
929*2264Sjacobs 						encryption, rank, verbose);
930*2264Sjacobs 			if (users != NULL) {
931*2264Sjacobs 				free(users);
932*2264Sjacobs 				users = NULL;
933*2264Sjacobs 			}
934*2264Sjacobs 			break;
935*2264Sjacobs 		case 'v':
936*2264Sjacobs 			exit_code += printer_query(optarg, report_device,
937*2264Sjacobs 						encryption, verbose, 0);
938*2264Sjacobs 			break;
939*2264Sjacobs 		case 'o':
940*2264Sjacobs 			exit_code += job_query(optarg, report_job,
941*2264Sjacobs 						encryption, rank, verbose);
942*2264Sjacobs 			break;
943*2264Sjacobs 		case 'f':
944*2264Sjacobs 			exit_code += service_query(optarg, report_form,
945*2264Sjacobs 						encryption, verbose);
946*2264Sjacobs 			break;
947*2264Sjacobs 		case 'S':
948*2264Sjacobs 			exit_code += service_query(optarg, report_print_wheels,
949*2264Sjacobs 						encryption, verbose);
950*2264Sjacobs 			break;
951*2264Sjacobs 		case 's':
952*2264Sjacobs 			exit_code += lpstat_service_status(encryption);
953*2264Sjacobs 			exit_code += lpstat_default_printer(encryption);
954*2264Sjacobs 			exit_code += printer_query(NULL, report_class,
955*2264Sjacobs 						encryption, verbose, 0);
956*2264Sjacobs 			exit_code += printer_query(NULL, report_device,
957*2264Sjacobs 						encryption, verbose, 0);
958*2264Sjacobs 			exit_code += service_query(optarg, report_form,
959*2264Sjacobs 						encryption, verbose);
960*2264Sjacobs 			exit_code += service_query(optarg, report_print_wheels,
961*2264Sjacobs 						encryption, verbose);
962*2264Sjacobs 			break;
963*2264Sjacobs 		case 't':
964*2264Sjacobs 			exit_code += lpstat_service_status(encryption);
965*2264Sjacobs 			exit_code += lpstat_default_printer(encryption);
966*2264Sjacobs 			exit_code += printer_query(NULL, report_class,
967*2264Sjacobs 						encryption, verbose, 0);
968*2264Sjacobs 			exit_code += printer_query(NULL, report_device,
969*2264Sjacobs 						encryption, verbose, 0);
970*2264Sjacobs 			exit_code += printer_query(NULL, report_accepting,
971*2264Sjacobs 						encryption, verbose, 0);
972*2264Sjacobs 			exit_code += printer_query(NULL, report_printer,
973*2264Sjacobs 						encryption, verbose, 0);
974*2264Sjacobs 			exit_code += service_query(optarg, report_form,
975*2264Sjacobs 						encryption, verbose);
976*2264Sjacobs 			exit_code += service_query(optarg, report_print_wheels,
977*2264Sjacobs 						encryption, verbose);
978*2264Sjacobs 			exit_code += job_query(NULL, report_job,
979*2264Sjacobs 						encryption, rank, verbose);
980*2264Sjacobs 			break;
981*2264Sjacobs 		case 'L':	/* local-only, ignored */
982*2264Sjacobs 		case 'l':	/* increased verbose level in first pass */
983*2264Sjacobs 		case 'D':	/* set "description" flag in first pass */
984*2264Sjacobs 		case 'R':	/* set "rank" flag in first pass */
985*2264Sjacobs 		case 'E':	/* set encryption in the first pass */
986*2264Sjacobs 			break;
987*2264Sjacobs 		default:
988*2264Sjacobs 			usage(av[0]);
989*2264Sjacobs 		}
990*2264Sjacobs 	}
991*2264Sjacobs 	ac--;
992*2264Sjacobs 
993*2264Sjacobs 	if (ac == 1) {	/* report on my jobs */
994*2264Sjacobs 		struct passwd *pw = getpwuid(getuid());
995*2264Sjacobs 
996*2264Sjacobs 		if (pw != NULL)
997*2264Sjacobs 			users = strsplit(pw->pw_name, "");
998*2264Sjacobs 		exit_code += job_query(NULL, report_job, encryption,
999*2264Sjacobs 					rank, verbose);
1000*2264Sjacobs 		if (users != NULL) {
1001*2264Sjacobs 			free(users);
1002*2264Sjacobs 			users = NULL;
1003*2264Sjacobs 		}
1004*2264Sjacobs 	} else {
1005*2264Sjacobs 		for (c = optind; c < ac; c++)
1006*2264Sjacobs 			exit_code += job_query(argv[c], report_job, encryption,
1007*2264Sjacobs 					rank, verbose);
1008*2264Sjacobs 	}
1009*2264Sjacobs 
1010*2264Sjacobs 
1011*2264Sjacobs 	if (exit_code != 0)
1012*2264Sjacobs 		exit_code = 1;
1013*2264Sjacobs 
1014*2264Sjacobs 	return (exit_code);
1015*2264Sjacobs }
1016