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 787 (void) papiAttributeListGetString(attrs, NULL, 788 "job-originating-user-name", &user); 789 790 if ((users != NULL) && (match_user(user, users) < 0)) 791 return (0); 792 793 (void) papiAttributeListGetString(attrs, NULL, 794 "job-originating-host-name", &host); 795 796 if (check == 0) { 797 /* 798 * Read the attribute "job-printer-uri" 799 * just once 800 */ 801 (void) papiAttributeListGetString(attrs, NULL, 802 "job-printer-uri", &uri); 803 check = 1; 804 } 805 806 if (host) { 807 /* Check if it is local printer or remote printer */ 808 uri_t *u = NULL; 809 810 if ((uri != NULL) && (uri_from_string(uri, &u) == 0)) { 811 char *nodename = localhostname(); 812 813 if ((u->host == NULL) || 814 (strcasecmp(u->host, "localhost") == 0) || 815 (strcasecmp(u->host, nodename) == 0)) { 816 817 if (strcasecmp(host, nodename) == 0) { 818 /* 819 * Request submitted locally 820 * for the local queue. 821 * Hostname will not be displayed 822 */ 823 snprintf(User, sizeof (User), "%s", 824 user); 825 } 826 else 827 snprintf(User, sizeof (User), "%s@%s", 828 user, host); 829 } else if (uri != NULL) { 830 /* 831 * It's a remote printer. 832 * In case of remote printers hostname is 833 * always displayed. 834 */ 835 snprintf(User, sizeof (User), "%s@%s", 836 user, host); 837 } 838 uri_free(u); 839 } else { 840 /* 841 * If attribute "job-printer-uri" 842 * cannot be read 843 * by default append the hostname 844 */ 845 snprintf(User, sizeof (User), "%s@%s", user, host); 846 } 847 } else { 848 /* 849 * When print server is s10u4 and ipp service is used 850 * "job-originating-hostname" attribute is not set 851 * So get the host information from the uri 852 */ 853 uri_t *u = NULL; 854 if ((uri != NULL) && (uri_from_string(uri, &u) == 0)) { 855 if ((u != NULL) && (u->host != NULL)) 856 snprintf(User, sizeof (User), "%s@%s", 857 user, u->host); 858 else 859 snprintf(User, sizeof (User), "%s", user); 860 861 uri_free(u); 862 } else 863 snprintf(User, sizeof (User), "%s", user); 864 } 865 (void) papiAttributeListGetInteger(attrs, NULL, "job-k-octets", &size); 866 size *= 1024; /* for the approximate byte size */ 867 (void) papiAttributeListGetInteger(attrs, NULL, "job-octets", &size); 868 869 (void) time(&clock); 870 (void) papiAttributeListGetInteger(attrs, NULL, 871 "time-at-creation", (int32_t *)&clock); 872 (void) strftime(date, sizeof (date), "%b %d %R", localtime(&clock)); 873 874 (void) papiAttributeListGetString(attrs, NULL, 875 "job-printer-uri", &destination); 876 (void) papiAttributeListGetString(attrs, NULL, 877 "printer-name", &destination); 878 (void) papiAttributeListGetInteger(attrs, NULL, 879 "job-id", &id); 880 (void) papiAttributeListGetInteger(attrs, NULL, 881 "job-id-requested", &id); 882 883 884 snprintf(request, sizeof (request), "%s-%d", printer, id); 885 886 if (show_rank != 0) { 887 int32_t rank = -1; 888 889 (void) papiAttributeListGetInteger(attrs, NULL, 890 "number-of-intervening-jobs", &rank); 891 rank++; 892 893 printf("%3d %-21s %-14s %7ld %s", 894 rank, request, User, size, date); 895 } else 896 printf("%-23s %-14s %7ld %s", request, User, size, date); 897 898 (void) papiAttributeListGetInteger(attrs, NULL, 899 "job-state", &jstate); 900 901 if (jstate == 0x0001) 902 printf(gettext(" being held")); 903 else if (jstate == 0x0800) 904 printf(gettext(" notifying user")); 905 else if (jstate == 0x0040) 906 printf(gettext(" cancelled")); 907 else if (jstate == 0x0010) 908 printf(gettext(" finished printing")); 909 else if (jstate == 0x0008) 910 printf(gettext(" on %s"), destination); 911 else if (jstate == 0x2000) 912 printf(gettext(" held by admin")); 913 else if (jstate == 0x0002) 914 printf(gettext(" being filtered")); 915 else if (jstate == 0x0004) 916 printf(gettext(" filtered")); 917 else if (jstate == 0x0020) 918 printf(gettext(" held for change")); 919 920 if (verbose == 1) { 921 char *form = NULL; 922 923 (void) papiAttributeListGetString(attrs, NULL, 924 "output-device-assigned", &destination); 925 printf("\n\t assigned %s", destination); 926 927 (void) papiAttributeListGetString(attrs, NULL, "form", &form); 928 if (form != NULL) 929 printf(", form %s", form); 930 } else if (verbose > 1) { 931 printf("\n"); 932 papiAttributeListPrint(stdout, attrs, "\t"); 933 } 934 935 printf("\n"); 936 937 return (0); 938 } 939 940 static int 941 job_query(char *request, int (*report)(char *, papi_job_t, int, int), 942 papi_encryption_t encryption, int show_rank, int verbose) 943 { 944 int result = 0; 945 papi_status_t status; 946 papi_service_t svc = NULL; 947 char *printer = request; 948 int32_t id = -1; 949 int flag1 = 0; 950 int flag = 1; 951 int print_flag = 0; 952 953 do { 954 status = papiServiceCreate(&svc, printer, NULL, NULL, 955 cli_auth_callback, encryption, NULL); 956 957 if ((status == PAPI_OK) && (printer != NULL)) 958 print_flag = 1; 959 960 /* <name>-# printer name does not exist */ 961 if (status != PAPI_OK) { 962 /* 963 * Check if <name>-# is a request-id 964 * Once this check is done flag1 is set 965 */ 966 if (flag1 == 1) 967 break; 968 969 get_printer_id(printer, &printer, &id); 970 971 status = papiServiceCreate(&svc, printer, NULL, NULL, 972 cli_auth_callback, encryption, NULL); 973 974 if (status != PAPI_OK) { 975 fprintf(stderr, gettext( 976 "Failed to contact service for %s: %s\n"), 977 (printer ? printer : "all"), 978 verbose_papi_message(svc, status)); 979 return (-1); 980 } 981 } 982 983 if (printer == NULL) { /* all */ 984 char **interest = interest_list(svc); 985 986 if (interest != NULL) { 987 int i; 988 989 for (i = 0; interest[i] != NULL; i++) 990 result += job_query(interest[i], report, 991 encryption, show_rank, verbose); 992 } 993 } else if (id == -1) { /* a printer */ 994 papi_job_t *jobs = NULL; 995 996 status = papiPrinterListJobs(svc, printer, NULL, 997 0, 0, &jobs); 998 if (status != PAPI_OK) { 999 fprintf(stderr, gettext( 1000 "Failed to get job list: %s\n"), 1001 verbose_papi_message(svc, status)); 1002 papiServiceDestroy(svc); 1003 return (-1); 1004 } 1005 1006 if (jobs != NULL) { 1007 int i; 1008 1009 for (i = 0; jobs[i] != NULL; i++) 1010 result += report(printer, 1011 jobs[i], show_rank, 1012 verbose); 1013 } 1014 1015 papiJobListFree(jobs); 1016 } else { /* a job */ 1017 papi_job_t job = NULL; 1018 int rid = id; 1019 1020 /* Once a job has been found stop processing */ 1021 flag = 0; 1022 1023 /* 1024 * Job-id could be the job-id requested 1025 * Check if it is job-id or job-id-requested 1026 */ 1027 id = job_to_be_queried(svc, printer, id); 1028 1029 if (id > 0) 1030 status = papiJobQuery(svc, printer, id, 1031 NULL, &job); 1032 else 1033 status = papiJobQuery(svc, printer, rid, 1034 NULL, &job); 1035 1036 if (status != PAPI_OK) { 1037 if (!print_flag) 1038 fprintf(stderr, gettext( 1039 "Failed to get job"\ 1040 " info for %s: %s\n"), 1041 request, 1042 verbose_papi_message(svc, status)); 1043 papiServiceDestroy(svc); 1044 return (-1); 1045 } 1046 1047 if (job != NULL) 1048 result = report(printer, job, 1049 show_rank, verbose); 1050 1051 papiJobFree(job); 1052 } 1053 1054 if (flag) { 1055 id = -1; 1056 get_printer_id(printer, &printer, &id); 1057 if (id == -1) 1058 flag = 0; 1059 else 1060 flag1 = 1; 1061 } 1062 } while (flag); 1063 1064 papiServiceDestroy(svc); 1065 1066 return (result); 1067 } 1068 1069 static int 1070 report_form(char *name, papi_attribute_t **attrs, int verbose) 1071 { 1072 papi_status_t status; 1073 char *form = NULL; 1074 void *iter = NULL; 1075 1076 for (status = papiAttributeListGetString(attrs, &iter, 1077 "form-supported", &form); 1078 status == PAPI_OK; 1079 status = papiAttributeListGetString(attrs, &iter, 1080 NULL, &form)) { 1081 if ((name == NULL) || (strcmp(name, form) == 0)) { 1082 printf(gettext("form %s is available to you\n"), form); 1083 if (verbose != 0) { 1084 char *detail = NULL; 1085 status = papiAttributeListGetString(attrs, NULL, 1086 "form-supported-detail", &detail); 1087 if (status == PAPI_OK) 1088 printf("%s\n", detail); 1089 } 1090 } 1091 } 1092 1093 return (0); 1094 } 1095 1096 static int 1097 report_print_wheels(char *name, papi_attribute_t **attrs, int verbose) 1098 { 1099 papi_status_t status; 1100 char *pw = NULL; 1101 void *iter = NULL; 1102 1103 for (status = papiAttributeListGetString(attrs, &iter, 1104 "pw-supported", &pw); 1105 status == PAPI_OK; 1106 status = papiAttributeListGetString(attrs, &iter, NULL, &pw)) { 1107 if ((name == NULL) || (strcmp(name, pw) == 0)) { 1108 printf(gettext("charset %s is available\n"), pw); 1109 if (verbose != 0) { 1110 char *info = NULL; 1111 status = papiAttributeListGetString(attrs, NULL, 1112 "pw-supported-extra", &info); 1113 if (status == PAPI_OK) 1114 printf("%s\n", info); 1115 } 1116 } 1117 } 1118 1119 return (0); 1120 } 1121 1122 static int 1123 service_query(char *name, int (*report)(char *, papi_attribute_t **, int), 1124 papi_encryption_t encryption, int verbose) 1125 { 1126 int result = 0; 1127 papi_status_t status; 1128 papi_service_t svc = NULL; 1129 papi_attribute_t **attrs = NULL; 1130 1131 status = papiServiceCreate(&svc, name, NULL, NULL, cli_auth_callback, 1132 encryption, NULL); 1133 if (status != PAPI_OK) { 1134 papiServiceDestroy(svc); 1135 return (-1); 1136 } 1137 1138 attrs = papiServiceGetAttributeList(svc); 1139 if (attrs != NULL) { 1140 result = report(name, attrs, verbose); 1141 1142 if (verbose > 1) { 1143 printf("\n"); 1144 papiAttributeListPrint(stdout, attrs, "\t"); 1145 printf("\n"); 1146 } 1147 } 1148 1149 papiServiceDestroy(svc); 1150 1151 return (result); 1152 } 1153 1154 int 1155 main(int ac, char *av[]) 1156 { 1157 int exit_code = 0; 1158 papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; 1159 int rank = 0; 1160 int verbose = 0; 1161 int description = 0; 1162 int c; 1163 char **argv; 1164 1165 (void) setlocale(LC_ALL, ""); 1166 (void) textdomain("SUNW_OST_OSCMD"); 1167 1168 argv = (char **)calloc((ac + 1), sizeof (char *)); 1169 for (c = 0; c < ac; c++) { 1170 if ((av[c][0] == '-') && (av[c][1] == 'l') && 1171 (isalpha(av[c][2]) != 0)) { 1172 /* preserve old "-l[po...]" behavior */ 1173 argv[c] = &av[c][1]; 1174 argv[c][0] = '-'; 1175 verbose = 1; 1176 1177 } else 1178 argv[c] = av[c]; 1179 } 1180 1181 argv[c++] = "--"; 1182 ac = c; 1183 1184 /* preprocess argument list looking for '-l' or '-R' so it can trail */ 1185 while ((c = getopt(ac, argv, "LEDf:S:stc:p:a:drs:v:l:o:R:u:")) != EOF) { 1186 switch (c) { /* these may or may not have an option */ 1187 case 'a': 1188 case 'c': 1189 case 'p': 1190 case 'o': 1191 case 'R': 1192 case 'u': 1193 case 'v': 1194 case 'l': 1195 case 'f': 1196 case 'S': 1197 if (optarg[0] == '-') { 1198 /* this check stop a possible infinite loop */ 1199 if ((optind > 1) && (argv[optind-1][1] != c)) 1200 optind--; 1201 optarg = NULL; 1202 } else if (strcmp(optarg, "all") == 0) 1203 optarg = NULL; 1204 } 1205 1206 switch (c) { 1207 case 'l': 1208 if ((optarg == NULL) || (optarg[0] == '-')) 1209 optarg = "1"; 1210 verbose = atoi(optarg); 1211 break; 1212 case 'D': 1213 description = 1; 1214 break; 1215 case 'R': 1216 rank = 1; 1217 break; 1218 case 'E': 1219 encryption = PAPI_ENCRYPT_REQUIRED; 1220 break; 1221 default: 1222 break; 1223 } 1224 } 1225 optind = 1; 1226 1227 /* process command line arguments */ 1228 while ((c = getopt(ac, argv, "LEDf:S:stc:p:a:drs:v:l:o:R:u:")) != EOF) { 1229 switch (c) { /* these may or may not have an option */ 1230 case 'a': 1231 case 'c': 1232 case 'p': 1233 case 'o': 1234 case 'R': 1235 case 'u': 1236 case 'v': 1237 case 'l': 1238 case 'f': 1239 case 'S': 1240 if (optarg[0] == '-') { 1241 /* this check stop a possible infinite loop */ 1242 if ((optind > 1) && (argv[optind-1][1] != c)) 1243 optind--; 1244 optarg = NULL; 1245 } else if (strcmp(optarg, "all") == 0) 1246 optarg = NULL; 1247 } 1248 1249 switch (c) { 1250 case 'a': 1251 exit_code += printer_query(optarg, report_accepting, 1252 encryption, verbose, 0); 1253 break; 1254 case 'c': 1255 exit_code += printer_query(optarg, report_class, 1256 encryption, verbose, 0); 1257 break; 1258 case 'p': 1259 exit_code += printer_query(optarg, report_printer, 1260 encryption, verbose, description); 1261 break; 1262 case 'd': 1263 exit_code += lpstat_default_printer(encryption); 1264 break; 1265 case 'r': 1266 exit_code += lpstat_service_status(encryption); 1267 break; 1268 case 'u': 1269 if (optarg != NULL) 1270 users = strsplit(optarg, ", \n"); 1271 exit_code += job_query(NULL, report_job, 1272 encryption, rank, verbose); 1273 if (users != NULL) { 1274 free(users); 1275 users = NULL; 1276 } 1277 break; 1278 case 'v': 1279 exit_code += printer_query(optarg, report_device, 1280 encryption, verbose, 0); 1281 break; 1282 case 'R': /* set "rank" flag in first pass */ 1283 case 'o': 1284 exit_code += job_query(optarg, report_job, 1285 encryption, rank, verbose); 1286 break; 1287 case 'f': 1288 exit_code += service_query(optarg, report_form, 1289 encryption, verbose); 1290 break; 1291 case 'S': 1292 exit_code += service_query(optarg, report_print_wheels, 1293 encryption, verbose); 1294 break; 1295 case 's': 1296 exit_code += lpstat_service_status(encryption); 1297 exit_code += lpstat_default_printer(encryption); 1298 exit_code += printer_query(NULL, report_class, 1299 encryption, verbose, 0); 1300 exit_code += printer_query(NULL, report_device, 1301 encryption, verbose, 0); 1302 exit_code += service_query(optarg, report_form, 1303 encryption, verbose); 1304 exit_code += service_query(optarg, report_print_wheels, 1305 encryption, verbose); 1306 break; 1307 case 't': 1308 exit_code += lpstat_service_status(encryption); 1309 exit_code += lpstat_default_printer(encryption); 1310 exit_code += printer_query(NULL, report_class, 1311 encryption, verbose, 0); 1312 exit_code += printer_query(NULL, report_device, 1313 encryption, verbose, 0); 1314 exit_code += printer_query(NULL, report_accepting, 1315 encryption, verbose, 0); 1316 exit_code += printer_query(NULL, report_printer, 1317 encryption, verbose, 0); 1318 exit_code += service_query(optarg, report_form, 1319 encryption, verbose); 1320 exit_code += service_query(optarg, report_print_wheels, 1321 encryption, verbose); 1322 exit_code += job_query(NULL, report_job, 1323 encryption, rank, verbose); 1324 break; 1325 case 'L': /* local-only, ignored */ 1326 case 'l': /* increased verbose level in first pass */ 1327 case 'D': /* set "description" flag in first pass */ 1328 case 'E': /* set encryption in the first pass */ 1329 break; 1330 default: 1331 usage(av[0]); 1332 } 1333 } 1334 ac--; 1335 1336 if (ac == 1) { /* report on my jobs */ 1337 struct passwd *pw = getpwuid(getuid()); 1338 1339 if (pw != NULL) 1340 users = strsplit(pw->pw_name, ""); 1341 exit_code += job_query(NULL, report_job, encryption, 1342 rank, verbose); 1343 if (users != NULL) { 1344 free(users); 1345 users = NULL; 1346 } 1347 } else { 1348 for (c = optind; c < ac; c++) 1349 exit_code += job_query(argv[c], report_job, encryption, 1350 rank, verbose); 1351 } 1352 1353 1354 if (exit_code != 0) 1355 exit_code = 1; 1356 1357 return (exit_code); 1358 } 1359