Home | History | Annotate | Download | only in bsd-sysv-commands
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  *
     26  */
     27 
     28 /* $Id: lpstat.c 173 2006-05-25 04:52:06Z njacobs $ */
     29 
     30 
     31 #include <stdio.h>
     32 #include <stdlib.h>
     33 #include <unistd.h>
     34 #include <string.h>
     35 #include <locale.h>
     36 #include <libintl.h>
     37 #include <ctype.h>
     38 #include <pwd.h>
     39 #include <papi.h>
     40 #include <uri.h>
     41 #include "common.h"
     42 #include "lp.h"
     43 
     44 static void
     45 usage(char *program)
     46 {
     47 	char *name;
     48 
     49 	if ((name = strrchr(program, '/')) == NULL)
     50 		name = program;
     51 	else
     52 		name++;
     53 
     54 	fprintf(stdout, gettext("Usage: %s [-d] [-r] [-s] [-t] [-a [list]] "
     55 	    "[-c [list]] [-o [list] [-l]] [-R [list] [-l]] "
     56 	    "[-p [list] [-D] [-l]] [-v [list]] [-S [list] [-l]] "
     57 	    "[-f [list] [-l]] [-u list]\n"),
     58 	    name);
     59 	exit(1);
     60 }
     61 
     62 static char *
     63 nctime(time_t *t)
     64 {
     65 	static char buf[64];
     66 	struct tm *tm = localtime(t);
     67 
     68 	(void) strftime(buf, sizeof (buf), "%c", tm);
     69 
     70 	return (buf);
     71 }
     72 
     73 static char *
     74 printer_name(papi_printer_t printer)
     75 {
     76 	papi_attribute_t **attributes = papiPrinterGetAttributeList(printer);
     77 	char *result = NULL;
     78 
     79 	if (attributes != NULL)
     80 		papiAttributeListGetString(attributes, NULL,
     81 		    "printer-name", &result);
     82 
     83 	return (result);
     84 }
     85 
     86 static int
     87 lpstat_default_printer(papi_encryption_t encryption)
     88 {
     89 	papi_status_t status;
     90 	papi_service_t svc = NULL;
     91 	papi_printer_t p = NULL;
     92 	char *name = NULL;
     93 
     94 	status = papiServiceCreate(&svc, NULL, NULL, NULL, cli_auth_callback,
     95 	    encryption, NULL);
     96 	if (status == PAPI_OK) {
     97 		char *req[] = { "printer-name", NULL };
     98 
     99 		status = papiPrinterQuery(svc, DEFAULT_DEST, req, NULL, &p);
    100 		if (p != NULL)
    101 			name = printer_name(p);
    102 	}
    103 	if (name != NULL)
    104 		printf(gettext("system default printer: %s\n"), name);
    105 	else
    106 		printf(gettext("no system default destination\n"));
    107 	papiPrinterFree(p);
    108 	papiServiceDestroy(svc);
    109 
    110 	return (0);
    111 }
    112 
    113 static int
    114 lpstat_service_status(papi_encryption_t encryption)
    115 {
    116 	papi_status_t status;
    117 	papi_service_t svc = NULL;
    118 	char *name = NULL;
    119 
    120 	if (((name = getenv("PAPI_SERVICE_URI")) == NULL) &&
    121 	    ((name = getenv("IPP_SERVER")) == NULL) &&
    122 	    ((name = getenv("CUPS_SERVER")) == NULL))
    123 		name = DEFAULT_SERVICE_URI;
    124 
    125 	status = papiServiceCreate(&svc, name, NULL, NULL, cli_auth_callback,
    126 	    encryption, NULL);
    127 	if (status != PAPI_OK) {
    128 		printf(gettext("scheduler is not running\n"));
    129 	} else
    130 		printf(gettext("scheduler is running\n"));
    131 	papiServiceDestroy(svc);
    132 
    133 	return (0);
    134 }
    135 
    136 static char *
    137 get_device_uri(papi_service_t svc, char *name)
    138 {
    139 	papi_status_t status;
    140 	papi_printer_t p = NULL;
    141 	char *keys[] = { "device-uri", NULL };
    142 	char *result = NULL;
    143 
    144 	status = papiPrinterQuery(svc, name, keys, NULL, &p);
    145 	if ((status == PAPI_OK) && (p != NULL)) {
    146 		papi_attribute_t **attrs = papiPrinterGetAttributeList(p);
    147 
    148 		(void) papiAttributeListGetString(attrs, NULL,
    149 		    "device-uri", &result);
    150 		if (result != NULL)
    151 			result = strdup(result);
    152 
    153 		papiPrinterFree(p);
    154 	}
    155 
    156 	return (result);
    157 }
    158 
    159 static void
    160 print_description(papi_attribute_t **list, char *printer_name)
    161 {
    162 	char *str = "";
    163 
    164 	(void) papiAttributeListGetString(list, NULL,
    165 	    "printer-info", &str);
    166 
    167 	/*
    168 	 * If no printer-info is read then
    169 	 * by default the printer-info is <printer-name>@<server>
    170 	 */
    171 	if (str[0] == '\0') {
    172 		char *uri = NULL;
    173 		uri_t *u = NULL;
    174 
    175 		(void) papiAttributeListGetString(list, NULL,
    176 		    "printer-uri-supported", &uri);
    177 
    178 		if ((uri != NULL) && (uri_from_string(uri, &u) == 0)) {
    179 			char *nodename = localhostname();
    180 
    181 			if ((u->host == NULL) ||
    182 			    (strcasecmp(u->host, "localhost") == 0) ||
    183 			    (strcasecmp(u->host, nodename) == 0))
    184 				printf(gettext("\tDescription:\n"));
    185 			else
    186 				printf(gettext("\tDescription: %s@%s\n"),
    187 				    printer_name, u->host);
    188 
    189 			uri_free(u);
    190 		} else
    191 			printf(gettext("\tDescription:\n"));
    192 	} else
    193 		printf(gettext("\tDescription: %s\n"), str);
    194 }
    195 
    196 static char *report_device_keys[] = { "printer-name", "printer-uri-supported",
    197 					NULL };
    198 /* ARGSUSED2 */
    199 static int
    200 report_device(papi_service_t svc, char *name, papi_printer_t printer,
    201 		int verbose, int description)
    202 {
    203 	papi_status_t status;
    204 	papi_attribute_t **attrs = papiPrinterGetAttributeList(printer);
    205 	char *uri = NULL;
    206 	char *device = NULL;
    207 	uri_t *u = NULL;
    208 
    209 	if (name == NULL) {
    210 		status = papiAttributeListGetString(attrs, NULL,
    211 		    "printer-name", &name);
    212 		if (status != PAPI_OK)
    213 			status = papiAttributeListGetString(attrs, NULL,
    214 			    "printer-uri-supported", &name);
    215 	}
    216 
    217 	if (name == NULL)
    218 		return (-1);
    219 
    220 	(void) papiAttributeListGetString(attrs, NULL,
    221 	    "printer-uri-supported", &uri);
    222 
    223 	if ((uri != NULL) && (uri_from_string(uri, &u) == 0)) {
    224 		char *nodename = localhostname();
    225 
    226 		if ((u->host == NULL) ||
    227 		    (strcasecmp(u->host, "localhost") == 0) ||
    228 		    (strcasecmp(u->host, nodename) == 0))
    229 			device = get_device_uri(svc, name);
    230 
    231 		if (device != NULL) {
    232 			printf(gettext("device for %s: %s\n"), name, device);
    233 			return (0);
    234 		} else if (uri != NULL) {
    235 			printf(gettext("system for %s: %s (as %s)\n"), name,
    236 			    u->host?u->host:"localhost", uri);
    237 			return (0);
    238 		}
    239 
    240 		uri_free(u);
    241 	}
    242 
    243 	return (0);
    244 }
    245 
    246 static char *report_accepting_keys[] = { "printer-name",
    247 			"printer-uri-supported", "printer-is-accepting-jobs",
    248 			"printer-up-time", "printer-state-time",
    249 			"lpsched-reject-date", "lpsched-reject-reason", NULL };
    250 /* ARGSUSED2 */
    251 static int
    252 report_accepting(papi_service_t svc, char *name, papi_printer_t printer,
    253 		int verbose, int description)
    254 {
    255 	papi_status_t status;
    256 	papi_attribute_t **attrs = papiPrinterGetAttributeList(printer);
    257 	time_t curr;
    258 	char boolean = PAPI_FALSE;
    259 
    260 	if (name == NULL) {
    261 		status = papiAttributeListGetString(attrs, NULL,
    262 		    "printer-name", &name);
    263 		if (status != PAPI_OK)
    264 			status = papiAttributeListGetString(attrs, NULL,
    265 			    "printer-uri-supported", &name);
    266 	}
    267 	if (name == NULL)
    268 		return (-1);
    269 
    270 	(void) papiAttributeListGetBoolean(attrs, NULL,
    271 	    "printer-is-accepting-jobs", &boolean);
    272 	(void) time(&curr);
    273 	(void) papiAttributeListGetDatetime(attrs, NULL,
    274 	    "printer-up-time", &curr);
    275 	(void) papiAttributeListGetDatetime(attrs, NULL,
    276 	    "printer-state-time", &curr);
    277 	(void) papiAttributeListGetDatetime(attrs, NULL,
    278 	    "lpsched-reject-date", &curr);
    279 
    280 	if (boolean == PAPI_TRUE) {
    281 		printf(gettext("%s accepting requests since %s\n"),
    282 		    name, nctime(&curr));
    283 	} else {
    284 		char *reason = "unknown reason";
    285 
    286 		(void) papiAttributeListGetString(attrs, NULL,
    287 		    "lpsched-reject-reason", &reason);
    288 
    289 		printf(gettext("%s not accepting requests since %s\n\t%s\n"),
    290 		    name, nctime(&curr), reason);
    291 	}
    292 
    293 	return (0);
    294 }
    295 
    296 static char *report_class_keys[] = { "printer-name", "printer-uri-supported",
    297 					"member-names", NULL };
    298 /* ARGSUSED2 */
    299 static int
    300 report_class(papi_service_t svc, char *name, papi_printer_t printer,
    301 		int verbose, int description)
    302 {
    303 	papi_status_t status;
    304 	papi_attribute_t **attrs = papiPrinterGetAttributeList(printer);
    305 	char *member = NULL;
    306 	void *iter = NULL;
    307 
    308 	status = papiAttributeListGetString(attrs, &iter,
    309 	    "member-names", &member);
    310 	if (status == PAPI_NOT_FOUND)	/* it's not a class */
    311 		return (0);
    312 
    313 	if (name == NULL) {
    314 		status = papiAttributeListGetString(attrs, NULL,
    315 		    "printer-name", &name);
    316 		if (status != PAPI_OK)
    317 			status = papiAttributeListGetString(attrs, NULL,
    318 			    "printer-uri-supported", &name);
    319 	}
    320 	if (name == NULL)
    321 		return (-1);
    322 
    323 	printf(gettext("members of class %s:\n\t%s\n"), name, member);
    324 	while (papiAttributeListGetString(attrs, &iter, NULL, &member)
    325 	    == PAPI_OK)
    326 		printf("\t%s\n", member);
    327 
    328 	return (0);
    329 }
    330 
    331 static int
    332 get_remote_hostname(papi_attribute_t **attrs, char **host)
    333 {
    334 	char *uri = NULL;
    335 	uri_t *u;
    336 	char *nodename;
    337 
    338 	*host = NULL;
    339 	(void) papiAttributeListGetString(attrs, NULL,
    340 	    "job-originating-host-name", host);
    341 	(void) papiAttributeListGetString(attrs, NULL,
    342 	    "printer-uri-supported", &uri);
    343 	if (*host == NULL) {
    344 		if (uri != NULL) {
    345 			if (uri_from_string(uri, &u) == 0) {
    346 				if (u->host == NULL) {
    347 					uri_free(u);
    348 					return (0);
    349 				}
    350 				*host = strdup(u->host);
    351 				uri_free(u);
    352 			} else {
    353 				return (0);
    354 			}
    355 		} else {
    356 			return (0);
    357 		}
    358 	}
    359 	nodename = localhostname();
    360 	if ((strcasecmp(*host, "localhost") == 0) ||
    361 	    (strcasecmp(*host, nodename) == 0)) {
    362 		return (0);
    363 	}
    364 	return (1);
    365 }
    366 
    367 static char *report_printer_keys[] = { "printer-name",
    368 			"printer-uri-supported", "printer-state",
    369 			"printer-up-time", "printer-state-time",
    370 			"lpsched-disable-date", "printer-state-reasons",
    371 			"lpsched-disable-reason", NULL };
    372 /* ARGSUSED2 */
    373 static int
    374 report_printer(papi_service_t svc, char *name, papi_printer_t printer,
    375 		int verbose, int description)
    376 {
    377 	papi_status_t status;
    378 	papi_attribute_t **attrs = papiPrinterGetAttributeList(printer);
    379 	time_t curr;
    380 	int32_t pstat = 0;
    381 	char *member = NULL;
    382 	papi_job_t *j = NULL;
    383 
    384 	status = papiAttributeListGetString(attrs, NULL,
    385 	    "member-names", &member);
    386 	if (status == PAPI_OK)	/* it's a class */
    387 		return (0);
    388 
    389 	if (name == NULL) {
    390 		status = papiAttributeListGetString(attrs, NULL,
    391 		    "printer-name", &name);
    392 		if (status != PAPI_OK)
    393 			status = papiAttributeListGetString(attrs, NULL,
    394 			    "printer-uri-supported", &name);
    395 	}
    396 	if (name == NULL)
    397 		return (-1);
    398 
    399 	printf(gettext("printer %s "), name);
    400 
    401 	status = papiAttributeListGetInteger(attrs, NULL,
    402 	    "printer-state", &pstat);
    403 
    404 	switch (pstat) {
    405 	case 0x03:	/* idle */
    406 		printf(gettext("is idle. enabled"));
    407 		break;
    408 	case 0x04: /* processing */
    409 		status = papiPrinterListJobs(svc, name, NULL,
    410 		    0, 0, &j);
    411 
    412 		if (status == PAPI_OK) {
    413 			if (j != NULL) {
    414 				int i = 0;
    415 				int32_t jobid = 0;
    416 				int32_t jstate = 0;
    417 
    418 				for (i = 0; j[i] != NULL; ++i) {
    419 					papi_attribute_t **attr =
    420 					    papiJobGetAttributeList(j[i]);
    421 
    422 					papiAttributeListGetInteger(attr,
    423 					    NULL, "job-state", &jstate);
    424 					papiAttributeListGetInteger(attr,
    425 					    NULL, "job-id", &jobid);
    426 					/*
    427 					 * For lpd protocol "job-id-requested"
    428 					 * should be read.
    429 					 */
    430 					papiAttributeListGetInteger(attr,
    431 					    NULL, "job-id-requested", &jobid);
    432 
    433 					/*
    434 					 * When lpd protocol is used job-state
    435 					 * cannot be retrieved, therefore
    436 					 * job-state will be 0.
    437 					 * When ipp protocol is used, the
    438 					 * active/printing job-state will be
    439 					 * RS_PRINTING (0x0008) post s10u5.
    440 					 * For pre-s10u5 job-state will be
    441 					 * RS_ACTIVE (0x05). So print only when
    442 					 * the job-state is RS_PRINTING (0x0008)
    443 					 * or RS_ACTIVE (0x05) or 0
    444 					 */
    445 					if ((jstate == 0x0008) ||
    446 					    (jstate == 0x05) ||
    447 					    (jstate == 0)) {
    448 						printf(gettext
    449 						    ("now printing"\
    450 						    " %s-%d. enabled"),
    451 						    name, jobid);
    452 						break;
    453 					}
    454 				}
    455 				papiJobListFree(j);
    456 			}
    457 		}
    458 		break;
    459 	case 0x05:	/* stopped */
    460 		printf(gettext("disabled"));
    461 		break;
    462 	default:
    463 		printf(gettext("unknown state(0x%x)."), pstat);
    464 		break;
    465 	}
    466 
    467 	(void) time(&curr);
    468 	(void) papiAttributeListGetDatetime(attrs, NULL,
    469 	    "printer-up-time", &curr);
    470 	(void) papiAttributeListGetDatetime(attrs, NULL,
    471 	    "printer-state-time", &curr);
    472 	(void) papiAttributeListGetDatetime(attrs, NULL,
    473 	    "lpsched-disable-date", &curr);
    474 	printf(gettext(" since %s. available.\n"), nctime(&curr));
    475 
    476 	if (pstat == 0x05) {
    477 		char *reason = "unknown reason";
    478 
    479 		(void) papiAttributeListGetString(attrs, NULL,
    480 		    "printer-state-reasons", &reason);
    481 		(void) papiAttributeListGetString(attrs, NULL,
    482 		    "lpsched-disable-reason", &reason);
    483 		printf(gettext("\t%s\n"), reason);
    484 	}
    485 
    486 	if (verbose == 1) {
    487 		void *iter;
    488 		char *str;
    489 		char *host = NULL;
    490 
    491 		if ((get_remote_hostname(attrs, &host)) != 0) {
    492 			(void) printf(
    493 			    gettext("\tRemote Name: %s\n\tRemote Server: "
    494 			    "%s\n"), name, host);
    495 			free(host);
    496 			return (0);
    497 		}
    498 		str = "";
    499 		(void) papiAttributeListGetString(attrs, NULL,
    500 		    "form-ready", &str);
    501 		printf(gettext("\tForm mounted: %s\n"), str);
    502 
    503 		str = "";
    504 		iter = NULL;
    505 		(void) papiAttributeListGetString(attrs, &iter,
    506 		    "document-format-supported", &str);
    507 		printf(gettext("\tContent types: %s"), str);
    508 		while (papiAttributeListGetString(attrs, &iter, NULL, &str)
    509 		    == PAPI_OK)
    510 			printf(", %s", str);
    511 		printf("\n");
    512 
    513 		/* Display the printer description */
    514 		print_description(attrs, name);
    515 
    516 		str = "";
    517 		iter = NULL;
    518 		(void) papiAttributeListGetString(attrs, &iter,
    519 		    "lpsched-printer-type", &str);
    520 		printf(gettext("\tPrinter types: %s"), str);
    521 		while (papiAttributeListGetString(attrs, &iter, NULL, &str)
    522 		    == PAPI_OK)
    523 			printf(", %s", str);
    524 		printf("\n");
    525 
    526 		str = "";
    527 		(void) papiAttributeListGetString(attrs, NULL,
    528 		    "lpsched-dial-info", &str);
    529 		printf(gettext("\tConnection: %s\n"),
    530 		    ((str[0] == '\0') ? gettext("direct") : str));
    531 
    532 		str = "";
    533 		(void) papiAttributeListGetString(attrs, NULL,
    534 		    "lpsched-interface-script", &str);
    535 		printf(gettext("\tInterface: %s\n"), str);
    536 
    537 		str = NULL;
    538 		(void) papiAttributeListGetString(attrs, NULL,
    539 		    "ppd-file-uri", &str);
    540 		(void) papiAttributeListGetString(attrs, NULL,
    541 		    "lpsched-ppd-source-path", &str);
    542 		if (str != NULL)
    543 			printf(gettext("\tPPD: %s\n"), str);
    544 
    545 		str = NULL;
    546 		(void) papiAttributeListGetString(attrs, NULL,
    547 		    "lpsched-fault-alert-command", &str);
    548 		if (str != NULL)
    549 			printf(gettext("\tOn fault: %s\n"), str);
    550 
    551 		str = "";
    552 		(void) papiAttributeListGetString(attrs, NULL,
    553 		    "lpsched-fault-recovery", &str);
    554 		printf(gettext("\tAfter fault: %s\n"),
    555 		    ((str[0] == '\0') ? gettext("continue") : str));
    556 
    557 		str = "(all)";
    558 		iter = NULL;
    559 		(void) papiAttributeListGetString(attrs, &iter,
    560 		    "requesting-user-name-allowed", &str);
    561 		printf(gettext("\tUsers allowed:\n\t\t%s\n"),
    562 		    ((str[0] == '\0') ? gettext("(none)") : str));
    563 		if ((str != NULL) && (str[0] != '\0'))
    564 			while (papiAttributeListGetString(attrs, &iter, NULL,
    565 			    &str) == PAPI_OK)
    566 				printf("\t\t%s\n", str);
    567 
    568 		str = NULL;
    569 		iter = NULL;
    570 		(void) papiAttributeListGetString(attrs, &iter,
    571 		    "requesting-user-name-denied", &str);
    572 		if (str != NULL) {
    573 			printf(gettext("\tUsers denied:\n\t\t%s\n"),
    574 			    ((str[0] == '\0') ? gettext("(none)") : str));
    575 			if ((str != NULL) && (str[0] != '\0'))
    576 				while (papiAttributeListGetString(attrs, &iter,
    577 				    NULL, &str) == PAPI_OK)
    578 					printf("\t\t%s\n", str);
    579 		}
    580 
    581 		str = "none";
    582 		iter = NULL;
    583 		(void) papiAttributeListGetString(attrs, &iter,
    584 		    "form-supported", &str);
    585 		printf(gettext("\tForms allowed:\n\t\t(%s)\n"),
    586 		    ((str[0] == '\0') ? gettext("none") : str));
    587 		if ((str != NULL) && (str[0] != '\0'))
    588 			while (papiAttributeListGetString(attrs, &iter, NULL,
    589 			    &str) == PAPI_OK)
    590 				printf("\t\t(%s)\n", str);
    591 
    592 		str = "";
    593 		iter = NULL;
    594 		(void) papiAttributeListGetString(attrs, &iter,
    595 		    "media-supported", &str);
    596 		printf(gettext("\tMedia supported:\n\t\t%s\n"),
    597 		    ((str[0] == '\0') ? gettext("(none)") : str));
    598 		if ((str != NULL) && (str[0] != '\0'))
    599 			while (papiAttributeListGetString(attrs, &iter, NULL,
    600 			    &str) == PAPI_OK)
    601 				printf("\t\t%s\n", str);
    602 
    603 		str = "";
    604 		(void) papiAttributeListGetString(attrs, NULL,
    605 		    "job-sheets-supported", &str);
    606 		if ((strcasecmp(str, "none")) == 0)
    607 			str = gettext("page never printed");
    608 		else if (strcasecmp(str, "optional") == 0)
    609 			str = gettext("not required");
    610 		else
    611 			str = gettext("required");
    612 
    613 		printf(gettext("\tBanner %s\n"), str);
    614 
    615 
    616 		str = "";
    617 		iter = NULL;
    618 		(void) papiAttributeListGetString(attrs, &iter,
    619 		    "lpsched-print-wheels", &str);
    620 		printf(gettext("\tCharacter sets:\n\t\t%s\n"),
    621 		    ((str[0] == '\0') ? gettext("(none)") : str));
    622 		if ((str != NULL) && (str[0] != '\0'))
    623 			while (papiAttributeListGetString(attrs, &iter, NULL,
    624 			    &str) == PAPI_OK)
    625 				printf("\t\t%s\n", str);
    626 
    627 		printf(gettext("\tDefault pitch:\n"));
    628 		printf(gettext("\tDefault page size:\n"));
    629 		printf(gettext("\tDefault port setting:\n"));
    630 
    631 		str = "";
    632 		iter = NULL;
    633 		(void) papiAttributeListGetString(attrs, &iter,
    634 		    "lpsched-options", &str);
    635 		if (str != NULL) {
    636 			printf(gettext("\tOptions: %s"), str);
    637 			while (papiAttributeListGetString(attrs, &iter, NULL,
    638 			    &str) == PAPI_OK)
    639 				printf(", %s", str);
    640 			printf("\n");
    641 		}
    642 
    643 	} else if (description == 1)
    644 		/* Display printer description */
    645 		print_description(attrs, name);
    646 	else if (verbose > 1)
    647 		papiAttributeListPrint(stdout, attrs, "\t");
    648 
    649 	if (verbose > 0)
    650 		printf("\n");
    651 
    652 	return (0);
    653 }
    654 
    655 static int
    656 printer_query(char *name, int (*report)(papi_service_t, char *, papi_printer_t,
    657 					int, int), papi_encryption_t encryption,
    658 		int verbose, int description)
    659 {
    660 	int result = 0, i = 0;
    661 	papi_status_t status;
    662 	papi_service_t svc = NULL;
    663 	char **list = getlist(name, LP_WS, LP_SEP);
    664 
    665 	if (list == NULL) {
    666 		list = (char **)malloc(sizeof (char *));
    667 		list[0] = name;
    668 	}
    669 
    670 	/*
    671 	 * The for loop executes once for every printer
    672 	 * entry in list. If list is NULL that implies
    673 	 * name is also NULL, the loop runs only one time.
    674 	 */
    675 
    676 	for (i = 0; name == NULL || list[i] != NULL; i++) {
    677 		name = list[i];
    678 
    679 		status = papiServiceCreate(&svc, name, NULL, NULL,
    680 		    cli_auth_callback, encryption, NULL);
    681 		if (status != PAPI_OK) {
    682 			if (status == PAPI_NOT_FOUND)
    683 				fprintf(stderr,
    684 				    gettext("%s: unknown printer\n"),
    685 				    name ? name : "(NULL)");
    686 			else
    687 				fprintf(stderr, gettext(
    688 				    "Failed to contact service for %s: %s\n"),
    689 				    name ? name : "(NULL)",
    690 				    verbose_papi_message(svc, status));
    691 			papiServiceDestroy(svc);
    692 			result--;
    693 			continue;
    694 		}
    695 
    696 		if (name == NULL) { /* all */
    697 			char **interest = interest_list(svc);
    698 
    699 			if (interest != NULL) {
    700 				int i;
    701 
    702 				for (i = 0; interest[i] != NULL; i++)
    703 					result += printer_query(interest[i],
    704 					    report, encryption, verbose,
    705 					    description);
    706 			}
    707 		} else {
    708 			papi_printer_t printer = NULL;
    709 			char **keys = NULL;
    710 
    711 			/*
    712 			 * Limit the query to only required data
    713 			 * to reduce the need to go remote for
    714 			 * information.
    715 			 */
    716 			if (report == report_device)
    717 				keys = report_device_keys;
    718 			else if (report == report_class)
    719 				keys = report_class_keys;
    720 			else if (report == report_accepting)
    721 				keys = report_accepting_keys;
    722 			else if ((report == report_printer) && (verbose == 0))
    723 				keys = report_printer_keys;
    724 
    725 			status = papiPrinterQuery(svc, name, keys,
    726 			    NULL, &printer);
    727 			if (status != PAPI_OK) {
    728 				fprintf(stderr, gettext(
    729 				    "Failed to get printer info for %s: %s\n"),
    730 				    name, verbose_papi_message(svc, status));
    731 				papiServiceDestroy(svc);
    732 				result--;
    733 				continue;
    734 			}
    735 
    736 			if (printer != NULL)
    737 				result += report(svc, name, printer, verbose,
    738 				    description);
    739 
    740 			papiPrinterFree(printer);
    741 		}
    742 
    743 		papiServiceDestroy(svc);
    744 
    745 		if (name == NULL)
    746 			break;
    747 	}
    748 
    749 	freelist(list);
    750 
    751 	return (result);
    752 }
    753 
    754 static int
    755 match_user(char *user, char **list)
    756 {
    757 	int i;
    758 
    759 	for (i = 0; list[i] != NULL; i++) {
    760 		if (strcmp(user, list[i]) == 0)
    761 			return (0);
    762 	}
    763 
    764 	return (-1);
    765 }
    766 
    767 static char **users = NULL;
    768 
    769 static int
    770 report_job(char *printer, papi_job_t job, int show_rank, int verbose)
    771 {
    772 	papi_attribute_t **attrs = papiJobGetAttributeList(job);
    773 	time_t clock = 0;
    774 	char date[24];
    775 	char request[26];
    776 	char *user = "unknown";
    777 	char *host = NULL;
    778 	int32_t size = 0;
    779 	int32_t jstate = 0;
    780 	char User[50];
    781 
    782 	char *destination = "unknown";
    783 	int32_t id = -1;
    784 	static int check = 0;
    785 	static char *uri = NULL;
    786 	static char *puri = NULL;	/* printer-uri */
    787 	static char *pname = NULL;	/* printer-name */
    788 
    789 	(void) papiAttributeListGetString(attrs, NULL,
    790 	    "job-originating-user-name", &user);
    791 
    792 	if ((users != NULL) && (match_user(user, users) < 0))
    793 		return (0);
    794 
    795 	(void) papiAttributeListGetString(attrs, NULL,
    796 	    "job-originating-host-name", &host);
    797 
    798 	/*
    799 	 * When lpstat is called for multiple printers
    800 	 * internally the function 'report_job' gets
    801 	 * called multiple times with different printer-names.
    802 	 * The following block of code handles the case when lpstat is
    803 	 * executed for multiple printers. In other words when 'report_job'
    804 	 * is called multiple times for different printers for
    805 	 * one lpstat command
    806 	 * For e.g: lpstat printer1 printer2 printer3
    807 	 */
    808 	if (pname == NULL) {
    809 		/*
    810 		 * When lpstat is queried for the first time
    811 		 * pname is NULL so this part of the code gets executed.
    812 		 * Read the attribute "job-printer-uri"
    813 		 * first time
    814 		 */
    815 		(void) papiAttributeListGetString(attrs, NULL,
    816 		    "job-printer-uri", &uri);
    817 
    818 		if (printer != NULL) {
    819 			/*
    820 			 * Set pname to the printer that is being
    821 			 * queried so that this can be used later
    822 			 * if 'report_job' is called multiple times for
    823 			 * different printers for one lpstat command
    824 			 */
    825 			pname = printer;
    826 		}
    827 
    828 		if (uri != NULL) {
    829 			/*
    830 			 * Set puri so that "job-printer-uri" corresponding
    831 			 * to a particular printer can be used later when
    832 			 * lpstat is queried for the same printer as
    833 			 * "job-printer-uri" for a printer is read just once.
    834 			 */
    835 			puri = strdup(uri);
    836 		}
    837 	} else {
    838 		/*
    839 		 * This part of the code will get executed when
    840 		 * 'report_job' is called more than once for the same
    841 		 * lpstat command
    842 		 */
    843 		if (printer != NULL) {
    844 			if (strcasecmp(pname, printer) != 0) {
    845 				/*
    846 				 * Read the job-printer-uri as
    847 				 * it will be different for
    848 				 * different printers
    849 				 */
    850 				uri = NULL;
    851 				(void) papiAttributeListGetString(attrs,
    852 				    NULL, "job-printer-uri", &uri);
    853 				pname = printer;
    854 				if (uri != NULL)
    855 					puri = strdup(uri);
    856 				else
    857 					puri = NULL;
    858 			} else {
    859 				/*
    860 				 * Same printer queried twice
    861 				 * uri should be the same as
    862 				 * already read in the previous call
    863 				 * to 'report_job'.
    864 				 * For the same printer 'job-printer-uri'
    865 				 * is read just once because only in the
    866 				 * first call it contains the host information
    867 				 */
    868 				uri = puri;
    869 			}
    870 		}
    871 	}
    872 
    873 	if (host) {
    874 		/* Check if it is local printer or remote printer */
    875 		uri_t *u = NULL;
    876 
    877 		if ((uri != NULL) && (uri_from_string(uri, &u) == 0)) {
    878 			char *nodename = localhostname();
    879 
    880 			if ((u->host == NULL) ||
    881 			    (strcasecmp(u->host, "localhost") == 0) ||
    882 			    (strcasecmp(u->host, nodename) == 0)) {
    883 
    884 				if (strcasecmp(host, nodename) == 0) {
    885 					/*
    886 					 * Request submitted locally
    887 					 * for the local queue.
    888 					 * Hostname will not be displayed
    889 					 */
    890 					snprintf(User, sizeof (User), "%s",
    891 					    user);
    892 				}
    893 				else
    894 					snprintf(User, sizeof (User), "%s@%s",
    895 					    user, host);
    896 			} else if (uri != NULL) {
    897 				/*
    898 				 * It's a remote printer.
    899 				 * In case of remote printers hostname is
    900 				 * always displayed.
    901 				 */
    902 				snprintf(User, sizeof (User), "%s@%s",
    903 				    user, host);
    904 			}
    905 			uri_free(u);
    906 		} else {
    907 			/*
    908 			 * If attribute "job-printer-uri"
    909 			 * cannot be read
    910 			 * by default append the hostname
    911 			 */
    912 			snprintf(User, sizeof (User), "%s@%s", user, host);
    913 		}
    914 	} else {
    915 		/*
    916 		 * When print server is s10u4 and ipp service is used
    917 		 * "job-originating-hostname" attribute is not set
    918 		 * So get the host information from the uri
    919 		 */
    920 		uri_t *u = NULL;
    921 		if ((uri != NULL) && (uri_from_string(uri, &u) == 0)) {
    922 			if ((u != NULL) && (u->host != NULL))
    923 				snprintf(User, sizeof (User), "%s@%s",
    924 				    user, u->host);
    925 			else
    926 				snprintf(User, sizeof (User), "%s", user);
    927 
    928 			uri_free(u);
    929 		} else
    930 			snprintf(User, sizeof (User), "%s", user);
    931 	}
    932 	(void) papiAttributeListGetInteger(attrs, NULL, "job-k-octets", &size);
    933 	size *= 1024;	/* for the approximate byte size */
    934 	(void) papiAttributeListGetInteger(attrs, NULL, "job-octets", &size);
    935 
    936 	(void) time(&clock);
    937 	(void) papiAttributeListGetInteger(attrs, NULL,
    938 	    "time-at-creation", (int32_t *)&clock);
    939 	(void) strftime(date, sizeof (date), "%b %d %R", localtime(&clock));
    940 
    941 	(void) papiAttributeListGetString(attrs, NULL,
    942 	    "job-printer-uri", &destination);
    943 	(void) papiAttributeListGetString(attrs, NULL,
    944 	    "printer-name", &destination);
    945 	(void) papiAttributeListGetInteger(attrs, NULL,
    946 	    "job-id", &id);
    947 	(void) papiAttributeListGetInteger(attrs, NULL,
    948 	    "job-id-requested", &id);
    949 
    950 
    951 	snprintf(request, sizeof (request), "%s-%d", printer, id);
    952 
    953 	if (show_rank != 0) {
    954 		int32_t rank = -1;
    955 
    956 		(void) papiAttributeListGetInteger(attrs, NULL,
    957 		    "number-of-intervening-jobs", &rank);
    958 		rank++;
    959 
    960 		printf("%3d %-21s %-14s %7ld %s",
    961 		    rank, request, User, size, date);
    962 	} else
    963 		printf("%-23s %-14s %7ld   %s", request, User, size, date);
    964 
    965 	(void) papiAttributeListGetInteger(attrs, NULL,
    966 	    "job-state", &jstate);
    967 
    968 	if (jstate == 0x0001)
    969 		printf(gettext(" being held"));
    970 	else if (jstate == 0x0800)
    971 		printf(gettext(" notifying user"));
    972 	else if (jstate == 0x0040)
    973 		printf(gettext(" cancelled"));
    974 	else if (jstate == 0x0010)
    975 		printf(gettext(" finished printing"));
    976 	else if (jstate == 0x0008)
    977 		printf(gettext(" on %s"), destination);
    978 	else if (jstate == 0x2000)
    979 		printf(gettext(" held by admin"));
    980 	else if (jstate == 0x0002)
    981 		printf(gettext(" being filtered"));
    982 	else if (jstate == 0x0004)
    983 		printf(gettext(" filtered"));
    984 	else if (jstate == 0x0020)
    985 		printf(gettext(" held for change"));
    986 
    987 	if (verbose == 1) {
    988 		char *form = NULL;
    989 
    990 		(void) papiAttributeListGetString(attrs, NULL,
    991 		    "output-device-assigned", &destination);
    992 		printf("\n\t assigned %s", destination);
    993 
    994 		(void) papiAttributeListGetString(attrs, NULL, "form", &form);
    995 		if (form != NULL)
    996 			printf(", form %s", form);
    997 	} else if (verbose > 1) {
    998 		printf("\n");
    999 		papiAttributeListPrint(stdout, attrs, "\t");
   1000 	}
   1001 
   1002 	printf("\n");
   1003 
   1004 	return (0);
   1005 }
   1006 
   1007 static int
   1008 job_query(char *request, int (*report)(char *, papi_job_t, int, int),
   1009 		papi_encryption_t encryption, int show_rank, int verbose)
   1010 {
   1011 	int result = 0;
   1012 	papi_status_t status;
   1013 	papi_service_t svc = NULL;
   1014 	char *printer = request;
   1015 	int32_t id = -1;
   1016 	int flag1 = 0;
   1017 	int flag = 1;
   1018 	int print_flag = 0;
   1019 
   1020 	do {
   1021 		status = papiServiceCreate(&svc, printer, NULL, NULL,
   1022 		    cli_auth_callback, encryption, NULL);
   1023 
   1024 		if ((status == PAPI_OK) && (printer != NULL))
   1025 			print_flag = 1;
   1026 
   1027 		/* <name>-# printer name does not exist */
   1028 		if (status != PAPI_OK) {
   1029 			/*
   1030 			 * Check if <name>-# is a request-id
   1031 			 * Once this check is done flag1 is set
   1032 			 */
   1033 			if (flag1 == 1)
   1034 				break;
   1035 
   1036 			get_printer_id(printer, &printer, &id);
   1037 
   1038 			status = papiServiceCreate(&svc, printer, NULL, NULL,
   1039 			    cli_auth_callback, encryption, NULL);
   1040 
   1041 			if (status != PAPI_OK) {
   1042 				fprintf(stderr, gettext(
   1043 				    "Failed to contact service for %s: %s\n"),
   1044 				    (printer ? printer : "all"),
   1045 				    verbose_papi_message(svc, status));
   1046 				return (-1);
   1047 			}
   1048 		}
   1049 
   1050 		if (printer == NULL) { /* all */
   1051 			char **interest = interest_list(svc);
   1052 
   1053 			if (interest != NULL) {
   1054 				int i;
   1055 
   1056 				for (i = 0; interest[i] != NULL; i++)
   1057 					result += job_query(interest[i], report,
   1058 					    encryption, show_rank, verbose);
   1059 			}
   1060 		} else if (id == -1) { /* a printer */
   1061 			papi_job_t *jobs = NULL;
   1062 
   1063 			status = papiPrinterListJobs(svc, printer, NULL,
   1064 			    0, 0, &jobs);
   1065 			if (status != PAPI_OK) {
   1066 				fprintf(stderr, gettext(
   1067 				    "Failed to get job list: %s\n"),
   1068 				    verbose_papi_message(svc, status));
   1069 				papiServiceDestroy(svc);
   1070 				return (-1);
   1071 			}
   1072 
   1073 			if (jobs != NULL) {
   1074 				int i;
   1075 
   1076 				for (i = 0; jobs[i] != NULL; i++)
   1077 					result += report(printer,
   1078 					    jobs[i], show_rank,
   1079 					    verbose);
   1080 			}
   1081 
   1082 			papiJobListFree(jobs);
   1083 		} else {	/* a job */
   1084 			papi_job_t job = NULL;
   1085 
   1086 			/* Once a job has been found stop processing */
   1087 			flag = 0;
   1088 
   1089 			/*
   1090 			 * Job-id could be the job-id requested
   1091 			 * Check if it is job-id or job-id-requested
   1092 			 */
   1093 			id = job_to_be_queried(svc, printer, id);
   1094 
   1095 			if (id >= 0)
   1096 				status = papiJobQuery(svc, printer, id,
   1097 				    NULL, &job);
   1098 			else
   1099 				/* id not found */
   1100 				status = PAPI_NOT_FOUND;
   1101 
   1102 			if (status != PAPI_OK) {
   1103 				if (!print_flag)
   1104 					fprintf(stderr, gettext(
   1105 					    "Failed to get job"\
   1106 					    " info for %s: %s\n"),
   1107 					    request,
   1108 					    verbose_papi_message(svc, status));
   1109 				papiServiceDestroy(svc);
   1110 				return (-1);
   1111 			}
   1112 
   1113 			if (job != NULL)
   1114 				result = report(printer, job,
   1115 				    show_rank, verbose);
   1116 
   1117 			papiJobFree(job);
   1118 		}
   1119 
   1120 		if (flag) {
   1121 			id = -1;
   1122 			get_printer_id(printer, &printer, &id);
   1123 			if (id == -1)
   1124 				flag = 0;
   1125 			else
   1126 				flag1 = 1;
   1127 		}
   1128 	} while (flag);
   1129 
   1130 	papiServiceDestroy(svc);
   1131 
   1132 	return (result);
   1133 }
   1134 
   1135 static int
   1136 report_form(char *name, papi_attribute_t **attrs, int verbose)
   1137 {
   1138 	papi_status_t status;
   1139 	char *form = NULL;
   1140 	void *iter = NULL;
   1141 
   1142 	for (status = papiAttributeListGetString(attrs, &iter,
   1143 	    "form-supported", &form);
   1144 	    status == PAPI_OK;
   1145 	    status = papiAttributeListGetString(attrs, &iter,
   1146 	    NULL, &form)) {
   1147 		if ((name == NULL) || (strcmp(name, form) == 0)) {
   1148 			printf(gettext("form %s is available to you\n"), form);
   1149 			if (verbose != 0) {
   1150 				char *detail = NULL;
   1151 				status = papiAttributeListGetString(attrs, NULL,
   1152 				    "form-supported-detail", &detail);
   1153 				if (status == PAPI_OK)
   1154 					printf("%s\n", detail);
   1155 			}
   1156 		}
   1157 	}
   1158 
   1159 	return (0);
   1160 }
   1161 
   1162 static int
   1163 report_print_wheels(char *name, papi_attribute_t **attrs, int verbose)
   1164 {
   1165 	papi_status_t status;
   1166 	char *pw = NULL;
   1167 	void *iter = NULL;
   1168 
   1169 	for (status = papiAttributeListGetString(attrs, &iter,
   1170 	    "pw-supported", &pw);
   1171 	    status == PAPI_OK;
   1172 	    status = papiAttributeListGetString(attrs, &iter, NULL, &pw)) {
   1173 		if ((name == NULL) || (strcmp(name, pw) == 0)) {
   1174 			printf(gettext("charset %s is available\n"), pw);
   1175 			if (verbose != 0) {
   1176 				char *info = NULL;
   1177 				status = papiAttributeListGetString(attrs, NULL,
   1178 				    "pw-supported-extra", &info);
   1179 				if (status == PAPI_OK)
   1180 					printf("%s\n", info);
   1181 			}
   1182 		}
   1183 	}
   1184 
   1185 	return (0);
   1186 }
   1187 
   1188 static int
   1189 service_query(char *name, int (*report)(char *, papi_attribute_t **, int),
   1190 		papi_encryption_t encryption, int verbose)
   1191 {
   1192 	int result = 0;
   1193 	papi_status_t status;
   1194 	papi_service_t svc = NULL;
   1195 	papi_attribute_t **attrs = NULL;
   1196 
   1197 	status = papiServiceCreate(&svc, name, NULL, NULL, cli_auth_callback,
   1198 	    encryption, NULL);
   1199 	if (status != PAPI_OK) {
   1200 		papiServiceDestroy(svc);
   1201 		return (-1);
   1202 	}
   1203 
   1204 	attrs = papiServiceGetAttributeList(svc);
   1205 	if (attrs != NULL) {
   1206 		result = report(name, attrs, verbose);
   1207 
   1208 		if (verbose > 1) {
   1209 			printf("\n");
   1210 			papiAttributeListPrint(stdout, attrs, "\t");
   1211 			printf("\n");
   1212 		}
   1213 	}
   1214 
   1215 	papiServiceDestroy(svc);
   1216 
   1217 	return (result);
   1218 }
   1219 
   1220 int
   1221 main(int ac, char *av[])
   1222 {
   1223 	int exit_code = 0;
   1224 	papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
   1225 	int rank = 0;
   1226 	int verbose = 0;
   1227 	int description = 0;
   1228 	int c;
   1229 	char **argv;
   1230 
   1231 	(void) setlocale(LC_ALL, "");
   1232 	(void) textdomain("SUNW_OST_OSCMD");
   1233 
   1234 	argv = (char **)calloc((ac + 1), sizeof (char *));
   1235 	for (c = 0; c < ac; c++) {
   1236 		if ((av[c][0] == '-') && (av[c][1] == 'l') &&
   1237 		    (isalpha(av[c][2]) != 0)) {
   1238 			/* preserve old "-l[po...]" behavior */
   1239 			argv[c] = &av[c][1];
   1240 			argv[c][0] = '-';
   1241 			verbose = 1;
   1242 
   1243 		} else
   1244 			argv[c] = av[c];
   1245 	}
   1246 
   1247 	argv[c++] = "--";
   1248 	ac = c;
   1249 
   1250 	/* preprocess argument list looking for '-l' or '-R' so it can trail */
   1251 	while ((c = getopt(ac, argv, "LEDf:S:stc:p:a:drs:v:l:o:R:u:")) != EOF) {
   1252 		switch (c) {    /* these may or may not have an option */
   1253 		case 'a':
   1254 		case 'c':
   1255 		case 'p':
   1256 		case 'o':
   1257 		case 'R':
   1258 		case 'u':
   1259 		case 'v':
   1260 		case 'l':
   1261 		case 'f':
   1262 		case 'S':
   1263 			if (optarg[0] == '-') {
   1264 				/* this check stop a possible infinite loop */
   1265 				if ((optind > 1) && (argv[optind-1][1] != c))
   1266 					optind--;
   1267 				optarg = NULL;
   1268 			} else if (strcmp(optarg, "all") == 0)
   1269 				optarg = NULL;
   1270 		}
   1271 
   1272 		switch (c) {
   1273 		case 'l':
   1274 			if ((optarg == NULL) || (optarg[0] == '-'))
   1275 				optarg = "1";
   1276 			verbose = atoi(optarg);
   1277 			break;
   1278 		case 'D':
   1279 			description = 1;
   1280 			break;
   1281 		case 'R':
   1282 			rank = 1;
   1283 			break;
   1284 		case 'E':
   1285 			encryption = PAPI_ENCRYPT_REQUIRED;
   1286 			break;
   1287 		default:
   1288 			break;
   1289 		}
   1290 	}
   1291 	optind = 1;
   1292 
   1293 	/* process command line arguments */
   1294 	while ((c = getopt(ac, argv, "LEDf:S:stc:p:a:drs:v:l:o:R:u:")) != EOF) {
   1295 		switch (c) {	/* these may or may not have an option */
   1296 		case 'a':
   1297 		case 'c':
   1298 		case 'p':
   1299 		case 'o':
   1300 		case 'R':
   1301 		case 'u':
   1302 		case 'v':
   1303 		case 'l':
   1304 		case 'f':
   1305 		case 'S':
   1306 			if (optarg[0] == '-') {
   1307 				/* this check stop a possible infinite loop */
   1308 				if ((optind > 1) && (argv[optind-1][1] != c))
   1309 					optind--;
   1310 				optarg = NULL;
   1311 			} else if (strcmp(optarg, "all") == 0)
   1312 				optarg = NULL;
   1313 		}
   1314 
   1315 		switch (c) {
   1316 		case 'a':
   1317 			exit_code += printer_query(optarg, report_accepting,
   1318 			    encryption, verbose, 0);
   1319 			break;
   1320 		case 'c':
   1321 			exit_code += printer_query(optarg, report_class,
   1322 			    encryption, verbose, 0);
   1323 			break;
   1324 		case 'p':
   1325 			exit_code += printer_query(optarg, report_printer,
   1326 			    encryption, verbose, description);
   1327 			break;
   1328 		case 'd':
   1329 			exit_code += lpstat_default_printer(encryption);
   1330 			break;
   1331 		case 'r':
   1332 			exit_code += lpstat_service_status(encryption);
   1333 			break;
   1334 		case 'u':
   1335 			if (optarg != NULL)
   1336 				users = strsplit(optarg, ", \n");
   1337 			exit_code += job_query(NULL, report_job,
   1338 			    encryption, rank, verbose);
   1339 			if (users != NULL) {
   1340 				free(users);
   1341 				users = NULL;
   1342 			}
   1343 			break;
   1344 		case 'v':
   1345 			exit_code += printer_query(optarg, report_device,
   1346 			    encryption, verbose, 0);
   1347 			break;
   1348 		case 'R':	/* set "rank" flag in first pass */
   1349 		case 'o':
   1350 			exit_code += job_query(optarg, report_job,
   1351 			    encryption, rank, verbose);
   1352 			break;
   1353 		case 'f':
   1354 			exit_code += service_query(optarg, report_form,
   1355 			    encryption, verbose);
   1356 			break;
   1357 		case 'S':
   1358 			exit_code += service_query(optarg, report_print_wheels,
   1359 			    encryption, verbose);
   1360 			break;
   1361 		case 's':
   1362 			exit_code += lpstat_service_status(encryption);
   1363 			exit_code += lpstat_default_printer(encryption);
   1364 			exit_code += printer_query(NULL, report_class,
   1365 			    encryption, verbose, 0);
   1366 			exit_code += printer_query(NULL, report_device,
   1367 			    encryption, verbose, 0);
   1368 			exit_code += service_query(optarg, report_form,
   1369 			    encryption, verbose);
   1370 			exit_code += service_query(optarg, report_print_wheels,
   1371 			    encryption, verbose);
   1372 			break;
   1373 		case 't':
   1374 			exit_code += lpstat_service_status(encryption);
   1375 			exit_code += lpstat_default_printer(encryption);
   1376 			exit_code += printer_query(NULL, report_class,
   1377 			    encryption, verbose, 0);
   1378 			exit_code += printer_query(NULL, report_device,
   1379 			    encryption, verbose, 0);
   1380 			exit_code += printer_query(NULL, report_accepting,
   1381 			    encryption, verbose, 0);
   1382 			exit_code += printer_query(NULL, report_printer,
   1383 			    encryption, verbose, 0);
   1384 			exit_code += service_query(optarg, report_form,
   1385 			    encryption, verbose);
   1386 			exit_code += service_query(optarg, report_print_wheels,
   1387 			    encryption, verbose);
   1388 			exit_code += job_query(NULL, report_job,
   1389 			    encryption, rank, verbose);
   1390 			break;
   1391 		case 'L':	/* local-only, ignored */
   1392 		case 'l':	/* increased verbose level in first pass */
   1393 		case 'D':	/* set "description" flag in first pass */
   1394 		case 'E':	/* set encryption in the first pass */
   1395 			break;
   1396 		default:
   1397 			usage(av[0]);
   1398 		}
   1399 	}
   1400 	ac--;
   1401 
   1402 	if (ac == 1) {	/* report on my jobs */
   1403 		struct passwd *pw = getpwuid(getuid());
   1404 
   1405 		if (pw != NULL)
   1406 			users = strsplit(pw->pw_name, "");
   1407 		exit_code += job_query(NULL, report_job, encryption,
   1408 		    rank, verbose);
   1409 		if (users != NULL) {
   1410 			free(users);
   1411 			users = NULL;
   1412 		}
   1413 	} else {
   1414 		for (c = optind; c < ac; c++)
   1415 			exit_code += job_query(argv[c], report_job, encryption,
   1416 			    rank, verbose);
   1417 	}
   1418 
   1419 
   1420 	if (exit_code != 0)
   1421 		exit_code = 1;
   1422 
   1423 	return (exit_code);
   1424 }
   1425