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