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 2010 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
usage(char * program)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 *
nctime(time_t * t)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 *
printer_name(papi_printer_t printer)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
lpstat_default_printer(papi_encryption_t encryption)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
lpstat_service_status(papi_encryption_t encryption)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 *
get_device_uri(papi_service_t svc,char * name)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
print_description(papi_attribute_t ** list,char * printer_name)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
report_device(papi_service_t svc,char * name,papi_printer_t printer,int verbose,int description)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
report_accepting(papi_service_t svc,char * name,papi_printer_t printer,int verbose,int description)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
report_class(papi_service_t svc,char * name,papi_printer_t printer,int verbose,int description)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
get_remote_hostname(papi_attribute_t ** attrs,char ** host)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
report_printer(papi_service_t svc,char * name,papi_printer_t printer,int verbose,int description)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 case 0x06: /* faulted printing */
410 status = papiPrinterListJobs(svc, name, NULL,
411 0, 0, &j);
412
413 if (status == PAPI_OK) {
414 if (j != NULL) {
415 int i = 0;
416 int32_t jobid = 0;
417 int32_t jstate = 0;
418
419 for (i = 0; j[i] != NULL; ++i) {
420 papi_attribute_t **attr =
421 papiJobGetAttributeList(j[i]);
422
423 papiAttributeListGetInteger(attr,
424 NULL, "job-state", &jstate);
425 papiAttributeListGetInteger(attr,
426 NULL, "job-id", &jobid);
427 /*
428 * For lpd protocol "job-id-requested"
429 * should be read.
430 */
431 papiAttributeListGetInteger(attr,
432 NULL, "job-id-requested", &jobid);
433
434 /*
435 * When lpd protocol is used job-state
436 * cannot be retrieved, therefore
437 * job-state will be 0.
438 * When ipp protocol is used, the
439 * active/printing job-state will be
440 * RS_PRINTING (0x0008) post s10u5.
441 * For pre-s10u5 job-state will be
442 * RS_ACTIVE (0x05). So print only when
443 * the job-state is RS_PRINTING (0x0008)
444 * or RS_ACTIVE (0x05) or 0
445 */
446 if ((jstate == 0x0008) ||
447 (jstate == 0x05) ||
448 (jstate == 0)) {
449 if (pstat == 0x04)
450 printf(gettext
451 ("now printing"\
452 " %s-%d. enabled"),
453 name, jobid);
454 if (pstat == 0x06)
455 printf(gettext
456 ("faulted printing"\
457 " %s-%d. enabled"),
458 name, jobid);
459 break;
460 }
461 }
462 papiJobListFree(j);
463 }
464 }
465 break;
466 case 0x05: /* stopped */
467 printf(gettext("disabled"));
468 break;
469 case 0x07: /* faulted printer */
470 printf(gettext("faulted. enabled"));
471 break;
472 case 0x08: /* waiting for auto retry */
473 printf(gettext("waiting for auto-retry."));
474 break;
475 default:
476 printf(gettext("unknown state(0x%x)."), pstat);
477 break;
478 }
479
480 if (pstat == 0x08)
481 printf(gettext(" available.\n"));
482 else {
483 (void) time(&curr);
484 (void) papiAttributeListGetDatetime(attrs, NULL,
485 "printer-up-time", &curr);
486 (void) papiAttributeListGetDatetime(attrs, NULL,
487 "printer-state-time", &curr);
488 (void) papiAttributeListGetDatetime(attrs, NULL,
489 "lpsched-disable-date", &curr);
490 printf(gettext(" since %s. available.\n"), nctime(&curr));
491 }
492
493 if ((pstat == 0x05) ||
494 (pstat == 0x06) ||
495 (pstat == 0x07) ||
496 (pstat == 0x08)) {
497 char *reason = "unknown reason";
498
499 (void) papiAttributeListGetString(attrs, NULL,
500 "printer-state-reasons", &reason);
501 (void) papiAttributeListGetString(attrs, NULL,
502 "lpsched-disable-reason", &reason);
503 printf(gettext("\t%s\n"), reason);
504 }
505
506 if (verbose == 1) {
507 void *iter;
508 char *str;
509 char *host = NULL;
510
511 if ((get_remote_hostname(attrs, &host)) != 0) {
512 (void) printf(
513 gettext("\tRemote Name: %s\n\tRemote Server: "
514 "%s\n"), name, host);
515 free(host);
516 return (0);
517 }
518 str = "";
519 (void) papiAttributeListGetString(attrs, NULL,
520 "form-ready", &str);
521 printf(gettext("\tForm mounted: %s\n"), str);
522
523 str = "";
524 iter = NULL;
525 (void) papiAttributeListGetString(attrs, &iter,
526 "document-format-supported", &str);
527 printf(gettext("\tContent types: %s"), str);
528 while (papiAttributeListGetString(attrs, &iter, NULL, &str)
529 == PAPI_OK)
530 printf(", %s", str);
531 printf("\n");
532
533 /* Display the printer description */
534 print_description(attrs, name);
535
536 str = "";
537 iter = NULL;
538 (void) papiAttributeListGetString(attrs, &iter,
539 "lpsched-printer-type", &str);
540 printf(gettext("\tPrinter types: %s"), str);
541 while (papiAttributeListGetString(attrs, &iter, NULL, &str)
542 == PAPI_OK)
543 printf(", %s", str);
544 printf("\n");
545
546 str = "";
547 (void) papiAttributeListGetString(attrs, NULL,
548 "lpsched-dial-info", &str);
549 printf(gettext("\tConnection: %s\n"),
550 ((str[0] == '\0') ? gettext("direct") : str));
551
552 str = "";
553 (void) papiAttributeListGetString(attrs, NULL,
554 "lpsched-interface-script", &str);
555 printf(gettext("\tInterface: %s\n"), str);
556
557 str = NULL;
558 (void) papiAttributeListGetString(attrs, NULL,
559 "ppd-file-uri", &str);
560 (void) papiAttributeListGetString(attrs, NULL,
561 "lpsched-ppd-source-path", &str);
562 if (str != NULL)
563 printf(gettext("\tPPD: %s\n"), str);
564
565 str = NULL;
566 (void) papiAttributeListGetString(attrs, NULL,
567 "lpsched-fault-alert-command", &str);
568 if (str != NULL)
569 printf(gettext("\tOn fault: %s\n"), str);
570
571 str = "";
572 (void) papiAttributeListGetString(attrs, NULL,
573 "lpsched-fault-recovery", &str);
574 printf(gettext("\tAfter fault: %s\n"),
575 ((str[0] == '\0') ? gettext("continue") : str));
576
577 str = "(all)";
578 iter = NULL;
579 (void) papiAttributeListGetString(attrs, &iter,
580 "requesting-user-name-allowed", &str);
581 printf(gettext("\tUsers allowed:\n\t\t%s\n"),
582 ((str[0] == '\0') ? gettext("(none)") : str));
583 if ((str != NULL) && (str[0] != '\0'))
584 while (papiAttributeListGetString(attrs, &iter, NULL,
585 &str) == PAPI_OK)
586 printf("\t\t%s\n", str);
587
588 str = NULL;
589 iter = NULL;
590 (void) papiAttributeListGetString(attrs, &iter,
591 "requesting-user-name-denied", &str);
592 if (str != NULL) {
593 printf(gettext("\tUsers denied:\n\t\t%s\n"),
594 ((str[0] == '\0') ? gettext("(none)") : str));
595 if ((str != NULL) && (str[0] != '\0'))
596 while (papiAttributeListGetString(attrs, &iter,
597 NULL, &str) == PAPI_OK)
598 printf("\t\t%s\n", str);
599 }
600
601 str = "none";
602 iter = NULL;
603 (void) papiAttributeListGetString(attrs, &iter,
604 "form-supported", &str);
605 printf(gettext("\tForms allowed:\n\t\t(%s)\n"),
606 ((str[0] == '\0') ? gettext("none") : str));
607 if ((str != NULL) && (str[0] != '\0'))
608 while (papiAttributeListGetString(attrs, &iter, NULL,
609 &str) == PAPI_OK)
610 printf("\t\t(%s)\n", str);
611
612 str = "";
613 iter = NULL;
614 (void) papiAttributeListGetString(attrs, &iter,
615 "media-supported", &str);
616 printf(gettext("\tMedia supported:\n\t\t%s\n"),
617 ((str[0] == '\0') ? gettext("(none)") : str));
618 if ((str != NULL) && (str[0] != '\0'))
619 while (papiAttributeListGetString(attrs, &iter, NULL,
620 &str) == PAPI_OK)
621 printf("\t\t%s\n", str);
622
623 str = "";
624 (void) papiAttributeListGetString(attrs, NULL,
625 "job-sheets-supported", &str);
626 if ((strcasecmp(str, "none")) == 0)
627 str = gettext("page never printed");
628 else if (strcasecmp(str, "optional") == 0)
629 str = gettext("not required");
630 else
631 str = gettext("required");
632
633 printf(gettext("\tBanner %s\n"), str);
634
635
636 str = "";
637 iter = NULL;
638 (void) papiAttributeListGetString(attrs, &iter,
639 "lpsched-print-wheels", &str);
640 printf(gettext("\tCharacter sets:\n\t\t%s\n"),
641 ((str[0] == '\0') ? gettext("(none)") : str));
642 if ((str != NULL) && (str[0] != '\0'))
643 while (papiAttributeListGetString(attrs, &iter, NULL,
644 &str) == PAPI_OK)
645 printf("\t\t%s\n", str);
646
647 printf(gettext("\tDefault pitch:\n"));
648 printf(gettext("\tDefault page size:\n"));
649 printf(gettext("\tDefault port setting:\n"));
650
651 str = "";
652 iter = NULL;
653 (void) papiAttributeListGetString(attrs, &iter,
654 "lpsched-options", &str);
655 if (str != NULL) {
656 printf(gettext("\tOptions: %s"), str);
657 while (papiAttributeListGetString(attrs, &iter, NULL,
658 &str) == PAPI_OK)
659 printf(", %s", str);
660 printf("\n");
661 }
662
663 } else if (description == 1)
664 /* Display printer description */
665 print_description(attrs, name);
666 else if (verbose > 1)
667 papiAttributeListPrint(stdout, attrs, "\t");
668
669 if (verbose > 0)
670 printf("\n");
671
672 return (0);
673 }
674
675 static int
printer_query(char * name,int (* report)(papi_service_t,char *,papi_printer_t,int,int),papi_encryption_t encryption,int verbose,int description)676 printer_query(char *name, int (*report)(papi_service_t, char *, papi_printer_t,
677 int, int), papi_encryption_t encryption,
678 int verbose, int description)
679 {
680 int result = 0, i = 0;
681 papi_status_t status;
682 papi_service_t svc = NULL;
683 char **list = getlist(name, LP_WS, LP_SEP);
684
685 if (list == NULL) {
686 list = (char **)malloc(sizeof (char *));
687 list[0] = name;
688 }
689
690 /*
691 * The for loop executes once for every printer
692 * entry in list. If list is NULL that implies
693 * name is also NULL, the loop runs only one time.
694 */
695
696 for (i = 0; name == NULL || list[i] != NULL; i++) {
697 name = list[i];
698
699 status = papiServiceCreate(&svc, name, NULL, NULL,
700 cli_auth_callback, encryption, NULL);
701 if (status != PAPI_OK) {
702 if (status == PAPI_NOT_FOUND)
703 fprintf(stderr,
704 gettext("%s: unknown printer\n"),
705 name ? name : "(NULL)");
706 else
707 fprintf(stderr, gettext(
708 "Failed to contact service for %s: %s\n"),
709 name ? name : "(NULL)",
710 verbose_papi_message(svc, status));
711 papiServiceDestroy(svc);
712 result--;
713 continue;
714 }
715
716 if (name == NULL) { /* all */
717 char **interest = interest_list(svc);
718
719 if (interest != NULL) {
720 int i;
721
722 for (i = 0; interest[i] != NULL; i++)
723 result += printer_query(interest[i],
724 report, encryption, verbose,
725 description);
726 }
727 } else {
728 papi_printer_t printer = NULL;
729 char **keys = NULL;
730
731 /*
732 * Limit the query to only required data
733 * to reduce the need to go remote for
734 * information.
735 */
736 if (report == report_device)
737 keys = report_device_keys;
738 else if (report == report_class)
739 keys = report_class_keys;
740 else if (report == report_accepting)
741 keys = report_accepting_keys;
742 else if ((report == report_printer) && (verbose == 0))
743 keys = report_printer_keys;
744
745 status = papiPrinterQuery(svc, name, keys,
746 NULL, &printer);
747 if (status != PAPI_OK) {
748 fprintf(stderr, gettext(
749 "Failed to get printer info for %s: %s\n"),
750 name, verbose_papi_message(svc, status));
751 papiServiceDestroy(svc);
752 result--;
753 continue;
754 }
755
756 if (printer != NULL)
757 result += report(svc, name, printer, verbose,
758 description);
759
760 papiPrinterFree(printer);
761 }
762
763 papiServiceDestroy(svc);
764
765 if (name == NULL)
766 break;
767 }
768
769 freelist(list);
770
771 return (result);
772 }
773
774 static int
match_user(char * user,char ** list)775 match_user(char *user, char **list)
776 {
777 int i;
778
779 for (i = 0; list[i] != NULL; i++) {
780 if (strcmp(user, list[i]) == 0)
781 return (0);
782 }
783
784 return (-1);
785 }
786
787 static char **users = NULL;
788
789 static int
report_job(char * printer,papi_job_t job,int show_rank,int verbose)790 report_job(char *printer, papi_job_t job, int show_rank, int verbose)
791 {
792 papi_attribute_t **attrs = papiJobGetAttributeList(job);
793 time_t clock = 0;
794 char date[24];
795 char request[26];
796 char *user = "unknown";
797 char *host = NULL;
798 int32_t size = 0;
799 int32_t jstate = 0;
800 char User[50];
801
802 char *destination = "unknown";
803 int32_t id = -1;
804 static int check = 0;
805 static char *uri = NULL;
806 static char *puri = NULL; /* printer-uri */
807 static char *pname = NULL; /* printer-name */
808
809 (void) papiAttributeListGetString(attrs, NULL,
810 "job-originating-user-name", &user);
811
812 if ((users != NULL) && (match_user(user, users) < 0))
813 return (0);
814
815 (void) papiAttributeListGetString(attrs, NULL,
816 "job-originating-host-name", &host);
817
818 /*
819 * When lpstat is called for multiple printers
820 * internally the function 'report_job' gets
821 * called multiple times with different printer-names.
822 * The following block of code handles the case when lpstat is
823 * executed for multiple printers. In other words when 'report_job'
824 * is called multiple times for different printers for
825 * one lpstat command
826 * For e.g: lpstat printer1 printer2 printer3
827 */
828 if (pname == NULL) {
829 /*
830 * When lpstat is queried for the first time
831 * pname is NULL so this part of the code gets executed.
832 * Read the attribute "job-printer-uri"
833 * first time
834 */
835 (void) papiAttributeListGetString(attrs, NULL,
836 "job-printer-uri", &uri);
837
838 if (printer != NULL) {
839 /*
840 * Set pname to the printer that is being
841 * queried so that this can be used later
842 * if 'report_job' is called multiple times for
843 * different printers for one lpstat command
844 */
845 pname = printer;
846 }
847
848 if (uri != NULL) {
849 /*
850 * Set puri so that "job-printer-uri" corresponding
851 * to a particular printer can be used later when
852 * lpstat is queried for the same printer as
853 * "job-printer-uri" for a printer is read just once.
854 */
855 puri = strdup(uri);
856 }
857 } else {
858 /*
859 * This part of the code will get executed when
860 * 'report_job' is called more than once for the same
861 * lpstat command
862 */
863 if (printer != NULL) {
864 if (strcasecmp(pname, printer) != 0) {
865 /*
866 * Read the job-printer-uri as
867 * it will be different for
868 * different printers
869 */
870 uri = NULL;
871 (void) papiAttributeListGetString(attrs,
872 NULL, "job-printer-uri", &uri);
873 pname = printer;
874 if (uri != NULL)
875 puri = strdup(uri);
876 else
877 puri = NULL;
878 } else {
879 /*
880 * Same printer queried twice
881 * uri should be the same as
882 * already read in the previous call
883 * to 'report_job'.
884 * For the same printer 'job-printer-uri'
885 * is read just once because only in the
886 * first call it contains the host information
887 */
888 uri = puri;
889 }
890 }
891 }
892
893 if (host) {
894 /* Check if it is local printer or remote printer */
895 uri_t *u = NULL;
896
897 if ((uri != NULL) && (uri_from_string(uri, &u) == 0)) {
898 char *nodename = localhostname();
899
900 if ((u->host == NULL) ||
901 (strcasecmp(u->host, "localhost") == 0) ||
902 (strcasecmp(u->host, nodename) == 0)) {
903
904 if (strcasecmp(host, nodename) == 0) {
905 /*
906 * Request submitted locally
907 * for the local queue.
908 * Hostname will not be displayed
909 */
910 snprintf(User, sizeof (User), "%s",
911 user);
912 }
913 else
914 snprintf(User, sizeof (User), "%s@%s",
915 user, host);
916 } else if (uri != NULL) {
917 /*
918 * It's a remote printer.
919 * In case of remote printers hostname is
920 * always displayed.
921 */
922 snprintf(User, sizeof (User), "%s@%s",
923 user, host);
924 }
925 uri_free(u);
926 } else {
927 /*
928 * If attribute "job-printer-uri"
929 * cannot be read
930 * by default append the hostname
931 */
932 snprintf(User, sizeof (User), "%s@%s", user, host);
933 }
934 } else {
935 /*
936 * When print server is s10u4 and ipp service is used
937 * "job-originating-hostname" attribute is not set
938 * So get the host information from the uri
939 */
940 uri_t *u = NULL;
941 if ((uri != NULL) && (uri_from_string(uri, &u) == 0)) {
942 if ((u != NULL) && (u->host != NULL))
943 snprintf(User, sizeof (User), "%s@%s",
944 user, u->host);
945 else
946 snprintf(User, sizeof (User), "%s", user);
947
948 uri_free(u);
949 } else
950 snprintf(User, sizeof (User), "%s", user);
951 }
952 (void) papiAttributeListGetInteger(attrs, NULL, "job-k-octets", &size);
953 size *= 1024; /* for the approximate byte size */
954 (void) papiAttributeListGetInteger(attrs, NULL, "job-octets", &size);
955
956 (void) time(&clock);
957 (void) papiAttributeListGetInteger(attrs, NULL,
958 "time-at-creation", (int32_t *)&clock);
959 (void) strftime(date, sizeof (date), "%b %d %R", localtime(&clock));
960
961 (void) papiAttributeListGetString(attrs, NULL,
962 "job-printer-uri", &destination);
963 (void) papiAttributeListGetString(attrs, NULL,
964 "printer-name", &destination);
965 (void) papiAttributeListGetInteger(attrs, NULL,
966 "job-id", &id);
967 (void) papiAttributeListGetInteger(attrs, NULL,
968 "job-id-requested", &id);
969
970
971 snprintf(request, sizeof (request), "%s-%d", printer, id);
972
973 if (show_rank != 0) {
974 int32_t rank = -1;
975
976 (void) papiAttributeListGetInteger(attrs, NULL,
977 "number-of-intervening-jobs", &rank);
978 rank++;
979
980 printf("%3d %-21s %-14s %7ld %s",
981 rank, request, User, size, date);
982 } else
983 printf("%-23s %-14s %7ld %s", request, User, size, date);
984
985 (void) papiAttributeListGetInteger(attrs, NULL,
986 "job-state", &jstate);
987
988 if (jstate == 0x0001)
989 printf(gettext(" being held"));
990 else if (jstate == 0x0800)
991 printf(gettext(" notifying user"));
992 else if (jstate == 0x0040)
993 printf(gettext(" cancelled"));
994 else if (jstate == 0x0010)
995 printf(gettext(" finished printing"));
996 else if (jstate == 0x0008)
997 printf(gettext(" on %s"), destination);
998 else if (jstate == 0x2000)
999 printf(gettext(" held by admin"));
1000 else if (jstate == 0x0002)
1001 printf(gettext(" being filtered"));
1002 else if (jstate == 0x0004)
1003 printf(gettext(" filtered"));
1004 else if (jstate == 0x0020)
1005 printf(gettext(" held for change"));
1006
1007 if (verbose == 1) {
1008 char *form = NULL;
1009
1010 (void) papiAttributeListGetString(attrs, NULL,
1011 "output-device-assigned", &destination);
1012 printf("\n\t assigned %s", destination);
1013
1014 (void) papiAttributeListGetString(attrs, NULL, "form", &form);
1015 if (form != NULL)
1016 printf(", form %s", form);
1017 } else if (verbose > 1) {
1018 printf("\n");
1019 papiAttributeListPrint(stdout, attrs, "\t");
1020 }
1021
1022 printf("\n");
1023
1024 return (0);
1025 }
1026
1027 static int
job_query(char * request,int (* report)(char *,papi_job_t,int,int),papi_encryption_t encryption,int show_rank,int verbose)1028 job_query(char *request, int (*report)(char *, papi_job_t, int, int),
1029 papi_encryption_t encryption, int show_rank, int verbose)
1030 {
1031 int result = 0;
1032 papi_status_t status;
1033 papi_service_t svc = NULL;
1034 char *printer = request;
1035 int32_t id = -1;
1036 int flag1 = 0;
1037 int flag = 1;
1038 int print_flag = 0;
1039
1040 do {
1041 status = papiServiceCreate(&svc, printer, NULL, NULL,
1042 cli_auth_callback, encryption, NULL);
1043
1044 if ((status == PAPI_OK) && (printer != NULL))
1045 print_flag = 1;
1046
1047 /* <name>-# printer name does not exist */
1048 if (status != PAPI_OK) {
1049 /*
1050 * Check if <name>-# is a request-id
1051 * Once this check is done flag1 is set
1052 */
1053 if (flag1 == 1)
1054 break;
1055
1056 get_printer_id(printer, &printer, &id);
1057
1058 status = papiServiceCreate(&svc, printer, NULL, NULL,
1059 cli_auth_callback, encryption, NULL);
1060
1061 if (status != PAPI_OK) {
1062 fprintf(stderr, gettext(
1063 "Failed to contact service for %s: %s\n"),
1064 (printer ? printer : "all"),
1065 verbose_papi_message(svc, status));
1066 return (-1);
1067 }
1068 }
1069
1070 if (printer == NULL) { /* all */
1071 char **interest = interest_list(svc);
1072
1073 if (interest != NULL) {
1074 int i;
1075
1076 for (i = 0; interest[i] != NULL; i++)
1077 result += job_query(interest[i], report,
1078 encryption, show_rank, verbose);
1079 }
1080 } else if (id == -1) { /* a printer */
1081 papi_job_t *jobs = NULL;
1082
1083 status = papiPrinterListJobs(svc, printer, NULL,
1084 0, 0, &jobs);
1085 if (status != PAPI_OK) {
1086 fprintf(stderr, gettext(
1087 "Failed to get job list: %s\n"),
1088 verbose_papi_message(svc, status));
1089 papiServiceDestroy(svc);
1090 return (-1);
1091 }
1092
1093 if (jobs != NULL) {
1094 int i;
1095
1096 for (i = 0; jobs[i] != NULL; i++)
1097 result += report(printer,
1098 jobs[i], show_rank,
1099 verbose);
1100 }
1101
1102 papiJobListFree(jobs);
1103 } else { /* a job */
1104 papi_job_t job = NULL;
1105
1106 /* Once a job has been found stop processing */
1107 flag = 0;
1108
1109 /*
1110 * Job-id could be the job-id requested
1111 * Check if it is job-id or job-id-requested
1112 */
1113 id = job_to_be_queried(svc, printer, id);
1114
1115 if (id >= 0)
1116 status = papiJobQuery(svc, printer, id,
1117 NULL, &job);
1118 else
1119 /* id not found */
1120 status = PAPI_NOT_FOUND;
1121
1122 if (status != PAPI_OK) {
1123 if (!print_flag)
1124 fprintf(stderr, gettext(
1125 "Failed to get job"\
1126 " info for %s: %s\n"),
1127 request,
1128 verbose_papi_message(svc, status));
1129 papiServiceDestroy(svc);
1130 return (-1);
1131 }
1132
1133 if (job != NULL)
1134 result = report(printer, job,
1135 show_rank, verbose);
1136
1137 papiJobFree(job);
1138 }
1139
1140 if (flag) {
1141 id = -1;
1142 get_printer_id(printer, &printer, &id);
1143 if (id == -1)
1144 flag = 0;
1145 else
1146 flag1 = 1;
1147 }
1148 } while (flag);
1149
1150 papiServiceDestroy(svc);
1151
1152 return (result);
1153 }
1154
1155 static int
report_form(char * name,papi_attribute_t ** attrs,int verbose)1156 report_form(char *name, papi_attribute_t **attrs, int verbose)
1157 {
1158 papi_status_t status;
1159 char *form = NULL;
1160 void *iter = NULL;
1161
1162 for (status = papiAttributeListGetString(attrs, &iter,
1163 "form-supported", &form);
1164 status == PAPI_OK;
1165 status = papiAttributeListGetString(attrs, &iter,
1166 NULL, &form)) {
1167 if ((name == NULL) || (strcmp(name, form) == 0)) {
1168 printf(gettext("form %s is available to you\n"), form);
1169 if (verbose != 0) {
1170 char *detail = NULL;
1171 status = papiAttributeListGetString(attrs, NULL,
1172 "form-supported-detail", &detail);
1173 if (status == PAPI_OK)
1174 printf("%s\n", detail);
1175 }
1176 }
1177 }
1178
1179 return (0);
1180 }
1181
1182 static int
report_print_wheels(char * name,papi_attribute_t ** attrs,int verbose)1183 report_print_wheels(char *name, papi_attribute_t **attrs, int verbose)
1184 {
1185 papi_status_t status;
1186 char *pw = NULL;
1187 void *iter = NULL;
1188
1189 for (status = papiAttributeListGetString(attrs, &iter,
1190 "pw-supported", &pw);
1191 status == PAPI_OK;
1192 status = papiAttributeListGetString(attrs, &iter, NULL, &pw)) {
1193 if ((name == NULL) || (strcmp(name, pw) == 0)) {
1194 printf(gettext("charset %s is available\n"), pw);
1195 if (verbose != 0) {
1196 char *info = NULL;
1197 status = papiAttributeListGetString(attrs, NULL,
1198 "pw-supported-extra", &info);
1199 if (status == PAPI_OK)
1200 printf("%s\n", info);
1201 }
1202 }
1203 }
1204
1205 return (0);
1206 }
1207
1208 static int
service_query(char * name,int (* report)(char *,papi_attribute_t **,int),papi_encryption_t encryption,int verbose)1209 service_query(char *name, int (*report)(char *, papi_attribute_t **, int),
1210 papi_encryption_t encryption, int verbose)
1211 {
1212 int result = 0;
1213 papi_status_t status;
1214 papi_service_t svc = NULL;
1215 papi_attribute_t **attrs = NULL;
1216
1217 status = papiServiceCreate(&svc, name, NULL, NULL, cli_auth_callback,
1218 encryption, NULL);
1219 if (status != PAPI_OK) {
1220 papiServiceDestroy(svc);
1221 return (-1);
1222 }
1223
1224 attrs = papiServiceGetAttributeList(svc);
1225 if (attrs != NULL) {
1226 result = report(name, attrs, verbose);
1227
1228 if (verbose > 1) {
1229 printf("\n");
1230 papiAttributeListPrint(stdout, attrs, "\t");
1231 printf("\n");
1232 }
1233 }
1234
1235 papiServiceDestroy(svc);
1236
1237 return (result);
1238 }
1239
1240 int
main(int ac,char * av[])1241 main(int ac, char *av[])
1242 {
1243 int exit_code = 0;
1244 papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
1245 int rank = 0;
1246 int verbose = 0;
1247 int description = 0;
1248 int c;
1249 char **argv;
1250
1251 (void) setlocale(LC_ALL, "");
1252 (void) textdomain("SUNW_OST_OSCMD");
1253
1254 argv = (char **)calloc((ac + 1), sizeof (char *));
1255 for (c = 0; c < ac; c++) {
1256 if ((av[c][0] == '-') && (av[c][1] == 'l') &&
1257 (isalpha(av[c][2]) != 0)) {
1258 /* preserve old "-l[po...]" behavior */
1259 argv[c] = &av[c][1];
1260 argv[c][0] = '-';
1261 verbose = 1;
1262
1263 } else
1264 argv[c] = av[c];
1265 }
1266
1267 argv[c++] = "--";
1268 ac = c;
1269
1270 /* preprocess argument list looking for '-l' or '-R' so it can trail */
1271 while ((c = getopt(ac, argv, "LEDf:S:stc:p:a:drs:v:l:o:R:u:")) != EOF) {
1272 switch (c) { /* these may or may not have an option */
1273 case 'a':
1274 case 'c':
1275 case 'p':
1276 case 'o':
1277 case 'R':
1278 case 'u':
1279 case 'v':
1280 case 'l':
1281 case 'f':
1282 case 'S':
1283 if (optarg[0] == '-') {
1284 /* this check stop a possible infinite loop */
1285 if ((optind > 1) && (argv[optind-1][1] != c))
1286 optind--;
1287 optarg = NULL;
1288 } else if (strcmp(optarg, "all") == 0)
1289 optarg = NULL;
1290 }
1291
1292 switch (c) {
1293 case 'l':
1294 if ((optarg == NULL) || (optarg[0] == '-'))
1295 optarg = "1";
1296 verbose = atoi(optarg);
1297 break;
1298 case 'D':
1299 description = 1;
1300 break;
1301 case 'R':
1302 rank = 1;
1303 break;
1304 case 'E':
1305 encryption = PAPI_ENCRYPT_REQUIRED;
1306 break;
1307 default:
1308 break;
1309 }
1310 }
1311 optind = 1;
1312
1313 /* process command line arguments */
1314 while ((c = getopt(ac, argv, "LEDf:S:stc:p:a:drs:v:l:o:R:u:")) != EOF) {
1315 switch (c) { /* these may or may not have an option */
1316 case 'a':
1317 case 'c':
1318 case 'p':
1319 case 'o':
1320 case 'R':
1321 case 'u':
1322 case 'v':
1323 case 'l':
1324 case 'f':
1325 case 'S':
1326 if (optarg[0] == '-') {
1327 /* this check stop a possible infinite loop */
1328 if ((optind > 1) && (argv[optind-1][1] != c))
1329 optind--;
1330 optarg = NULL;
1331 } else if (strcmp(optarg, "all") == 0)
1332 optarg = NULL;
1333 }
1334
1335 switch (c) {
1336 case 'a':
1337 exit_code += printer_query(optarg, report_accepting,
1338 encryption, verbose, 0);
1339 break;
1340 case 'c':
1341 exit_code += printer_query(optarg, report_class,
1342 encryption, verbose, 0);
1343 break;
1344 case 'p':
1345 exit_code += printer_query(optarg, report_printer,
1346 encryption, verbose, description);
1347 break;
1348 case 'd':
1349 exit_code += lpstat_default_printer(encryption);
1350 break;
1351 case 'r':
1352 exit_code += lpstat_service_status(encryption);
1353 break;
1354 case 'u':
1355 if (optarg != NULL)
1356 users = strsplit(optarg, ", \n");
1357 exit_code += job_query(NULL, report_job,
1358 encryption, rank, verbose);
1359 if (users != NULL) {
1360 free(users);
1361 users = NULL;
1362 }
1363 break;
1364 case 'v':
1365 exit_code += printer_query(optarg, report_device,
1366 encryption, verbose, 0);
1367 break;
1368 case 'R': /* set "rank" flag in first pass */
1369 case 'o':
1370 exit_code += job_query(optarg, report_job,
1371 encryption, rank, verbose);
1372 break;
1373 case 'f':
1374 exit_code += service_query(optarg, report_form,
1375 encryption, verbose);
1376 break;
1377 case 'S':
1378 exit_code += service_query(optarg, report_print_wheels,
1379 encryption, verbose);
1380 break;
1381 case 's':
1382 exit_code += lpstat_service_status(encryption);
1383 exit_code += lpstat_default_printer(encryption);
1384 exit_code += printer_query(NULL, report_class,
1385 encryption, verbose, 0);
1386 exit_code += printer_query(NULL, report_device,
1387 encryption, verbose, 0);
1388 exit_code += service_query(optarg, report_form,
1389 encryption, verbose);
1390 exit_code += service_query(optarg, report_print_wheels,
1391 encryption, verbose);
1392 break;
1393 case 't':
1394 exit_code += lpstat_service_status(encryption);
1395 exit_code += lpstat_default_printer(encryption);
1396 exit_code += printer_query(NULL, report_class,
1397 encryption, verbose, 0);
1398 exit_code += printer_query(NULL, report_device,
1399 encryption, verbose, 0);
1400 exit_code += printer_query(NULL, report_accepting,
1401 encryption, verbose, 0);
1402 exit_code += printer_query(NULL, report_printer,
1403 encryption, verbose, 0);
1404 exit_code += service_query(optarg, report_form,
1405 encryption, verbose);
1406 exit_code += service_query(optarg, report_print_wheels,
1407 encryption, verbose);
1408 exit_code += job_query(NULL, report_job,
1409 encryption, rank, verbose);
1410 break;
1411 case 'L': /* local-only, ignored */
1412 case 'l': /* increased verbose level in first pass */
1413 case 'D': /* set "description" flag in first pass */
1414 case 'E': /* set encryption in the first pass */
1415 break;
1416 default:
1417 usage(av[0]);
1418 }
1419 }
1420 ac--;
1421
1422 if (ac == 1) { /* report on my jobs */
1423 struct passwd *pw = getpwuid(getuid());
1424
1425 if (pw != NULL)
1426 users = strsplit(pw->pw_name, "");
1427 exit_code += job_query(NULL, report_job, encryption,
1428 rank, verbose);
1429 if (users != NULL) {
1430 free(users);
1431 users = NULL;
1432 }
1433 } else {
1434 for (c = optind; c < ac; c++)
1435 exit_code += job_query(argv[c], report_job, encryption,
1436 rank, verbose);
1437 }
1438
1439
1440 if (exit_code != 0)
1441 exit_code = 1;
1442
1443 return (exit_code);
1444 }
1445