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("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 int rid = id; 1086 1087 /* Once a job has been found stop processing */ 1088 flag = 0; 1089 1090 /* 1091 * Job-id could be the job-id requested 1092 * Check if it is job-id or job-id-requested 1093 */ 1094 id = job_to_be_queried(svc, printer, id); 1095 1096 if (id > 0) 1097 status = papiJobQuery(svc, printer, id, 1098 NULL, &job); 1099 else 1100 status = papiJobQuery(svc, printer, rid, 1101 NULL, &job); 1102 1103 if (status != PAPI_OK) { 1104 if (!print_flag) 1105 fprintf(stderr, gettext( 1106 "Failed to get job"\ 1107 " info for %s: %s\n"), 1108 request, 1109 verbose_papi_message(svc, status)); 1110 papiServiceDestroy(svc); 1111 return (-1); 1112 } 1113 1114 if (job != NULL) 1115 result = report(printer, job, 1116 show_rank, verbose); 1117 1118 papiJobFree(job); 1119 } 1120 1121 if (flag) { 1122 id = -1; 1123 get_printer_id(printer, &printer, &id); 1124 if (id == -1) 1125 flag = 0; 1126 else 1127 flag1 = 1; 1128 } 1129 } while (flag); 1130 1131 papiServiceDestroy(svc); 1132 1133 return (result); 1134 } 1135 1136 static int 1137 report_form(char *name, papi_attribute_t **attrs, int verbose) 1138 { 1139 papi_status_t status; 1140 char *form = NULL; 1141 void *iter = NULL; 1142 1143 for (status = papiAttributeListGetString(attrs, &iter, 1144 "form-supported", &form); 1145 status == PAPI_OK; 1146 status = papiAttributeListGetString(attrs, &iter, 1147 NULL, &form)) { 1148 if ((name == NULL) || (strcmp(name, form) == 0)) { 1149 printf(gettext("form %s is available to you\n"), form); 1150 if (verbose != 0) { 1151 char *detail = NULL; 1152 status = papiAttributeListGetString(attrs, NULL, 1153 "form-supported-detail", &detail); 1154 if (status == PAPI_OK) 1155 printf("%s\n", detail); 1156 } 1157 } 1158 } 1159 1160 return (0); 1161 } 1162 1163 static int 1164 report_print_wheels(char *name, papi_attribute_t **attrs, int verbose) 1165 { 1166 papi_status_t status; 1167 char *pw = NULL; 1168 void *iter = NULL; 1169 1170 for (status = papiAttributeListGetString(attrs, &iter, 1171 "pw-supported", &pw); 1172 status == PAPI_OK; 1173 status = papiAttributeListGetString(attrs, &iter, NULL, &pw)) { 1174 if ((name == NULL) || (strcmp(name, pw) == 0)) { 1175 printf(gettext("charset %s is available\n"), pw); 1176 if (verbose != 0) { 1177 char *info = NULL; 1178 status = papiAttributeListGetString(attrs, NULL, 1179 "pw-supported-extra", &info); 1180 if (status == PAPI_OK) 1181 printf("%s\n", info); 1182 } 1183 } 1184 } 1185 1186 return (0); 1187 } 1188 1189 static int 1190 service_query(char *name, int (*report)(char *, papi_attribute_t **, int), 1191 papi_encryption_t encryption, int verbose) 1192 { 1193 int result = 0; 1194 papi_status_t status; 1195 papi_service_t svc = NULL; 1196 papi_attribute_t **attrs = NULL; 1197 1198 status = papiServiceCreate(&svc, name, NULL, NULL, cli_auth_callback, 1199 encryption, NULL); 1200 if (status != PAPI_OK) { 1201 papiServiceDestroy(svc); 1202 return (-1); 1203 } 1204 1205 attrs = papiServiceGetAttributeList(svc); 1206 if (attrs != NULL) { 1207 result = report(name, attrs, verbose); 1208 1209 if (verbose > 1) { 1210 printf("\n"); 1211 papiAttributeListPrint(stdout, attrs, "\t"); 1212 printf("\n"); 1213 } 1214 } 1215 1216 papiServiceDestroy(svc); 1217 1218 return (result); 1219 } 1220 1221 int 1222 main(int ac, char *av[]) 1223 { 1224 int exit_code = 0; 1225 papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; 1226 int rank = 0; 1227 int verbose = 0; 1228 int description = 0; 1229 int c; 1230 char **argv; 1231 1232 (void) setlocale(LC_ALL, ""); 1233 (void) textdomain("SUNW_OST_OSCMD"); 1234 1235 argv = (char **)calloc((ac + 1), sizeof (char *)); 1236 for (c = 0; c < ac; c++) { 1237 if ((av[c][0] == '-') && (av[c][1] == 'l') && 1238 (isalpha(av[c][2]) != 0)) { 1239 /* preserve old "-l[po...]" behavior */ 1240 argv[c] = &av[c][1]; 1241 argv[c][0] = '-'; 1242 verbose = 1; 1243 1244 } else 1245 argv[c] = av[c]; 1246 } 1247 1248 argv[c++] = "--"; 1249 ac = c; 1250 1251 /* preprocess argument list looking for '-l' or '-R' so it can trail */ 1252 while ((c = getopt(ac, argv, "LEDf:S:stc:p:a:drs:v:l:o:R:u:")) != EOF) { 1253 switch (c) { /* these may or may not have an option */ 1254 case 'a': 1255 case 'c': 1256 case 'p': 1257 case 'o': 1258 case 'R': 1259 case 'u': 1260 case 'v': 1261 case 'l': 1262 case 'f': 1263 case 'S': 1264 if (optarg[0] == '-') { 1265 /* this check stop a possible infinite loop */ 1266 if ((optind > 1) && (argv[optind-1][1] != c)) 1267 optind--; 1268 optarg = NULL; 1269 } else if (strcmp(optarg, "all") == 0) 1270 optarg = NULL; 1271 } 1272 1273 switch (c) { 1274 case 'l': 1275 if ((optarg == NULL) || (optarg[0] == '-')) 1276 optarg = "1"; 1277 verbose = atoi(optarg); 1278 break; 1279 case 'D': 1280 description = 1; 1281 break; 1282 case 'R': 1283 rank = 1; 1284 break; 1285 case 'E': 1286 encryption = PAPI_ENCRYPT_REQUIRED; 1287 break; 1288 default: 1289 break; 1290 } 1291 } 1292 optind = 1; 1293 1294 /* process command line arguments */ 1295 while ((c = getopt(ac, argv, "LEDf:S:stc:p:a:drs:v:l:o:R:u:")) != EOF) { 1296 switch (c) { /* these may or may not have an option */ 1297 case 'a': 1298 case 'c': 1299 case 'p': 1300 case 'o': 1301 case 'R': 1302 case 'u': 1303 case 'v': 1304 case 'l': 1305 case 'f': 1306 case 'S': 1307 if (optarg[0] == '-') { 1308 /* this check stop a possible infinite loop */ 1309 if ((optind > 1) && (argv[optind-1][1] != c)) 1310 optind--; 1311 optarg = NULL; 1312 } else if (strcmp(optarg, "all") == 0) 1313 optarg = NULL; 1314 } 1315 1316 switch (c) { 1317 case 'a': 1318 exit_code += printer_query(optarg, report_accepting, 1319 encryption, verbose, 0); 1320 break; 1321 case 'c': 1322 exit_code += printer_query(optarg, report_class, 1323 encryption, verbose, 0); 1324 break; 1325 case 'p': 1326 exit_code += printer_query(optarg, report_printer, 1327 encryption, verbose, description); 1328 break; 1329 case 'd': 1330 exit_code += lpstat_default_printer(encryption); 1331 break; 1332 case 'r': 1333 exit_code += lpstat_service_status(encryption); 1334 break; 1335 case 'u': 1336 if (optarg != NULL) 1337 users = strsplit(optarg, ", \n"); 1338 exit_code += job_query(NULL, report_job, 1339 encryption, rank, verbose); 1340 if (users != NULL) { 1341 free(users); 1342 users = NULL; 1343 } 1344 break; 1345 case 'v': 1346 exit_code += printer_query(optarg, report_device, 1347 encryption, verbose, 0); 1348 break; 1349 case 'R': /* set "rank" flag in first pass */ 1350 case 'o': 1351 exit_code += job_query(optarg, report_job, 1352 encryption, rank, verbose); 1353 break; 1354 case 'f': 1355 exit_code += service_query(optarg, report_form, 1356 encryption, verbose); 1357 break; 1358 case 'S': 1359 exit_code += service_query(optarg, report_print_wheels, 1360 encryption, verbose); 1361 break; 1362 case 's': 1363 exit_code += lpstat_service_status(encryption); 1364 exit_code += lpstat_default_printer(encryption); 1365 exit_code += printer_query(NULL, report_class, 1366 encryption, verbose, 0); 1367 exit_code += printer_query(NULL, report_device, 1368 encryption, verbose, 0); 1369 exit_code += service_query(optarg, report_form, 1370 encryption, verbose); 1371 exit_code += service_query(optarg, report_print_wheels, 1372 encryption, verbose); 1373 break; 1374 case 't': 1375 exit_code += lpstat_service_status(encryption); 1376 exit_code += lpstat_default_printer(encryption); 1377 exit_code += printer_query(NULL, report_class, 1378 encryption, verbose, 0); 1379 exit_code += printer_query(NULL, report_device, 1380 encryption, verbose, 0); 1381 exit_code += printer_query(NULL, report_accepting, 1382 encryption, verbose, 0); 1383 exit_code += printer_query(NULL, report_printer, 1384 encryption, verbose, 0); 1385 exit_code += service_query(optarg, report_form, 1386 encryption, verbose); 1387 exit_code += service_query(optarg, report_print_wheels, 1388 encryption, verbose); 1389 exit_code += job_query(NULL, report_job, 1390 encryption, rank, verbose); 1391 break; 1392 case 'L': /* local-only, ignored */ 1393 case 'l': /* increased verbose level in first pass */ 1394 case 'D': /* set "description" flag in first pass */ 1395 case 'E': /* set encryption in the first pass */ 1396 break; 1397 default: 1398 usage(av[0]); 1399 } 1400 } 1401 ac--; 1402 1403 if (ac == 1) { /* report on my jobs */ 1404 struct passwd *pw = getpwuid(getuid()); 1405 1406 if (pw != NULL) 1407 users = strsplit(pw->pw_name, ""); 1408 exit_code += job_query(NULL, report_job, encryption, 1409 rank, verbose); 1410 if (users != NULL) { 1411 free(users); 1412 users = NULL; 1413 } 1414 } else { 1415 for (c = optind; c < ac; c++) 1416 exit_code += job_query(argv[c], report_job, encryption, 1417 rank, verbose); 1418 } 1419 1420 1421 if (exit_code != 0) 1422 exit_code = 1; 1423 1424 return (exit_code); 1425 } 1426