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 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 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 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 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 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 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 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 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 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 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