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