]> git.ipfire.org Git - thirdparty/cups.git/blame - systemv/lpstat.c
Merge changes from CUPS 1.5svn-r9400
[thirdparty/cups.git] / systemv / lpstat.c
CommitLineData
ef416fc2 1/*
b19ccc9e 2 * "$Id: lpstat.c 7921 2008-09-10 15:42:24Z mike $"
ef416fc2 3 *
f8b3a85b 4 * "lpstat" command for CUPS.
ef416fc2 5 *
f8b3a85b 6 * Copyright 2007-2010 by Apple Inc.
ef416fc2 7 * Copyright 1997-2006 by Easy Software Products.
8 *
9 * These coded instructions, statements, and computer programs are the
bc44d920 10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 14 *
15 * Contents:
16 *
17 * main() - Parse options and show status information.
18 * check_dest() - Verify that the named destination(s) exists.
61cf44e2
MS
19 * match_list() - Match a name from a list of comma or space-separated
20 * names.
ef416fc2 21 * show_accepting() - Show acceptance status.
22 * show_classes() - Show printer classes.
23 * show_default() - Show default destination.
24 * show_devices() - Show printer devices.
25 * show_jobs() - Show active print jobs.
26 * show_printers() - Show printers.
27 * show_scheduler() - Show scheduler status.
28 */
29
30/*
31 * Include necessary headers...
32 */
33
71e16022 34#include <cups/cups-private.h>
ef416fc2 35
36
37/*
38 * Local functions...
39 */
40
61cf44e2
MS
41static void check_dest(const char *command, const char *name,
42 int *num_dests, cups_dest_t **dests);
43static int match_list(const char *list, const char *name);
44static int show_accepting(const char *printers, int num_dests,
45 cups_dest_t *dests);
46static int show_classes(const char *dests);
47static void show_default(cups_dest_t *dest);
48static int show_devices(const char *printers, int num_dests,
49 cups_dest_t *dests);
50static int show_jobs(const char *dests, const char *users, int long_status,
51 int ranking, const char *which);
52static int show_printers(const char *printers, int num_dests,
53 cups_dest_t *dests, int long_status);
54static void show_scheduler(void);
ef416fc2 55
56
57/*
58 * 'main()' - Parse options and show status information.
59 */
60
61int
ed486911 62main(int argc, /* I - Number of command-line arguments */
63 char *argv[]) /* I - Command-line arguments */
ef416fc2 64{
ed486911 65 int i, /* Looping var */
66 status; /* Exit status */
ed486911 67 int num_dests; /* Number of user destinations */
68 cups_dest_t *dests; /* User destinations */
69 int long_status; /* Long status report? */
70 int ranking; /* Show job ranking? */
71 const char *which; /* Which jobs to show? */
72 char op; /* Last operation on command-line */
ef416fc2 73
74
07725fee 75 _cupsSetLocale(argv);
ed486911 76
ed486911 77 /*
78 * Parse command-line options...
79 */
80
ef416fc2 81 num_dests = 0;
82 dests = NULL;
83 long_status = 0;
84 ranking = 0;
85 status = 0;
86 which = "not-completed";
87 op = 0;
88
89 for (i = 1; i < argc; i ++)
90 if (argv[i][0] == '-')
91 switch (argv[i][1])
92 {
93 case 'D' : /* Show description */
94 long_status = 1;
95 break;
96
97 case 'E' : /* Encrypt */
98#ifdef HAVE_SSL
99 cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
ef416fc2 100#else
fa73b229 101 _cupsLangPrintf(stderr,
0837b7e8 102 _("%s: Sorry, no encryption support."),
ef416fc2 103 argv[0]);
104#endif /* HAVE_SSL */
105 break;
106
49d87452
MS
107 case 'H' : /* Show server and port */
108 if (cupsServer()[0] == '/')
0837b7e8 109 _cupsLangPuts(stdout, cupsServer());
49d87452 110 else
0837b7e8 111 _cupsLangPrintf(stdout, "%s:%d", cupsServer(), ippPort());
49d87452
MS
112 break;
113
ef416fc2 114 case 'P' : /* Show paper types */
115 op = 'P';
116 break;
117
118 case 'R' : /* Show ranking */
119 ranking = 1;
120 break;
121
122 case 'S' : /* Show charsets */
123 op = 'S';
124 if (!argv[i][2])
125 i ++;
126 break;
127
fa73b229 128 case 'U' : /* Username */
61cf44e2 129 if (argv[i][2])
fa73b229 130 cupsSetUser(argv[i] + 2);
131 else
132 {
133 i ++;
134 if (i >= argc)
135 {
136 _cupsLangPrintf(stderr,
137 _("%s: Error - expected username after "
0837b7e8 138 "\"-U\" option."),
fa73b229 139 argv[0]);
140 return (1);
141 }
142
143 cupsSetUser(argv[i]);
144 }
145 break;
146
ef416fc2 147 case 'W' : /* Show which jobs? */
148 if (argv[i][2])
149 which = argv[i] + 2;
150 else
151 {
152 i ++;
153
154 if (i >= argc)
155 {
fa73b229 156 _cupsLangPrintf(stderr,
157 _("%s: Error - need \"completed\", "
158 "\"not-completed\", or \"all\" after "
0837b7e8 159 "\"-W\" option."),
fa73b229 160 argv[0]);
ef416fc2 161 return (1);
162 }
163
164 which = argv[i];
165 }
166
fa73b229 167 if (strcmp(which, "completed") && strcmp(which, "not-completed") &&
168 strcmp(which, "all"))
ef416fc2 169 {
fa73b229 170 _cupsLangPrintf(stderr,
171 _("%s: Error - need \"completed\", "
172 "\"not-completed\", or \"all\" after "
0837b7e8 173 "\"-W\" option."),
fa73b229 174 argv[0]);
ef416fc2 175 return (1);
176 }
177 break;
178
179 case 'a' : /* Show acceptance status */
61cf44e2 180 op = 'a';
ef416fc2 181
61cf44e2 182 if (argv[i][2])
ef416fc2 183 {
61cf44e2 184 check_dest(argv[0], argv[i] + 2, &num_dests, &dests);
ef416fc2 185
61cf44e2 186 status |= show_accepting(argv[i] + 2, num_dests, dests);
ef416fc2 187 }
188 else if ((i + 1) < argc && argv[i + 1][0] != '-')
189 {
190 i ++;
191
61cf44e2 192 check_dest(argv[0], argv[i], &num_dests, &dests);
ef416fc2 193
61cf44e2 194 status |= show_accepting(argv[i], num_dests, dests);
ef416fc2 195 }
196 else
197 {
61cf44e2
MS
198 if (num_dests <= 1)
199 {
200 cupsFreeDests(num_dests, dests);
201 num_dests = cupsGetDests(&dests);
202 }
ef416fc2 203
61cf44e2 204 status |= show_accepting(NULL, num_dests, dests);
ef416fc2 205 }
206 break;
207
208#ifdef __sgi
209 case 'b' : /* Show both the local and remote status */
61cf44e2 210 op = 'b';
ef416fc2 211
61cf44e2 212 if (argv[i][2])
ef416fc2 213 {
214 /*
215 * The local and remote status are separated by a blank line;
216 * since all CUPS jobs are networked, we only output the
217 * second list for now... In the future, we might further
218 * emulate this by listing the remote server's queue, but
219 * for now this is enough to make the SGI printstatus program
220 * happy...
221 */
222
61cf44e2 223 check_dest(argv[0], argv[i] + 2, &num_dests, &dests);
ef416fc2 224
225 puts("");
61cf44e2 226 status |= show_jobs(argv[i] + 2, NULL, 3, ranking, which);
ef416fc2 227 }
228 else
229 {
f301802f 230 _cupsLangPrintf(stderr,
231 _("%s: Error - expected destination after "
0837b7e8 232 "\"-b\" option."),
f301802f 233 argv[0]);
ef416fc2 234
235 return (1);
236 }
237 break;
238#endif /* __sgi */
239
240 case 'c' : /* Show classes and members */
61cf44e2 241 op = 'c';
ef416fc2 242
61cf44e2 243 if (argv[i][2])
ef416fc2 244 {
61cf44e2 245 check_dest(argv[0], argv[i] + 2, &num_dests, &dests);
ef416fc2 246
61cf44e2 247 status |= show_classes(argv[i] + 2);
ef416fc2 248 }
249 else if ((i + 1) < argc && argv[i + 1][0] != '-')
250 {
251 i ++;
252
61cf44e2 253 check_dest(argv[0], argv[i], &num_dests, &dests);
ef416fc2 254
61cf44e2 255 status |= show_classes(argv[i]);
ef416fc2 256 }
257 else
61cf44e2 258 status |= show_classes(NULL);
ef416fc2 259 break;
260
261 case 'd' : /* Show default destination */
61cf44e2 262 op = 'd';
ef416fc2 263
61cf44e2
MS
264 if (num_dests != 1 || !dests[0].is_default)
265 {
266 cupsFreeDests(num_dests, dests);
ef416fc2 267
61cf44e2
MS
268 dests = cupsGetNamedDest(CUPS_HTTP_DEFAULT, NULL, NULL);
269 num_dests = dests ? 1 : 0;
270 }
271
272 show_default(dests);
ef416fc2 273 break;
274
275 case 'f' : /* Show forms */
276 op = 'f';
277 if (!argv[i][2])
278 i ++;
279 break;
280
281 case 'h' : /* Connect to host */
61cf44e2 282 if (argv[i][2])
ef416fc2 283 cupsSetServer(argv[i] + 2);
284 else
285 {
286 i ++;
287
288 if (i >= argc)
289 {
fa73b229 290 _cupsLangPrintf(stderr,
291 _("%s: Error - expected hostname after "
0837b7e8 292 "\"-h\" option."),
fa73b229 293 argv[0]);
ef416fc2 294 return (1);
295 }
296
297 cupsSetServer(argv[i]);
298 }
299 break;
300
301 case 'l' : /* Long status or long job status */
302#ifdef __sgi
61cf44e2 303 op = 'l';
ef416fc2 304
61cf44e2 305 if (argv[i][2])
ef416fc2 306 {
61cf44e2 307 check_dest(argv[0], argv[i] + 2, &num_dests, &dests);
ef416fc2 308
61cf44e2 309 status |= show_jobs(argv[i] + 2, NULL, 3, ranking, which);
ef416fc2 310 }
311 else
312#endif /* __sgi */
313 long_status = 2;
314 break;
315
316 case 'o' : /* Show jobs by destination */
61cf44e2 317 op = 'o';
ef416fc2 318
61cf44e2 319 if (argv[i][2])
ef416fc2 320 {
61cf44e2 321 check_dest(argv[0], argv[i] + 2, &num_dests, &dests);
ef416fc2 322
61cf44e2
MS
323 status |= show_jobs(argv[i] + 2, NULL, long_status, ranking,
324 which);
ef416fc2 325 }
326 else if ((i + 1) < argc && argv[i + 1][0] != '-')
327 {
328 i ++;
329
61cf44e2 330 check_dest(argv[0], argv[i], &num_dests, &dests);
ef416fc2 331
61cf44e2 332 status |= show_jobs(argv[i], NULL, long_status, ranking, which);
ef416fc2 333 }
334 else
61cf44e2 335 status |= show_jobs(NULL, NULL, long_status, ranking, which);
ef416fc2 336 break;
337
338 case 'p' : /* Show printers */
61cf44e2 339 op = 'p';
ef416fc2 340
61cf44e2 341 if (argv[i][2])
ef416fc2 342 {
61cf44e2 343 check_dest(argv[0], argv[i] + 2, &num_dests, &dests);
ef416fc2 344
61cf44e2
MS
345 status |= show_printers(argv[i] + 2, num_dests, dests,
346 long_status);
ef416fc2 347 }
348 else if ((i + 1) < argc && argv[i + 1][0] != '-')
349 {
350 i ++;
351
61cf44e2 352 check_dest(argv[0], argv[i], &num_dests, &dests);
ef416fc2 353
61cf44e2 354 status |= show_printers(argv[i], num_dests, dests, long_status);
ef416fc2 355 }
356 else
357 {
61cf44e2
MS
358 if (num_dests <= 1)
359 {
360 cupsFreeDests(num_dests, dests);
361 num_dests = cupsGetDests(&dests);
362 }
ef416fc2 363
61cf44e2 364 status |= show_printers(NULL, num_dests, dests, long_status);
ef416fc2 365 }
366 break;
367
368 case 'r' : /* Show scheduler status */
61cf44e2 369 op = 'r';
ef416fc2 370
61cf44e2 371 show_scheduler();
ef416fc2 372 break;
373
374 case 's' : /* Show summary */
61cf44e2 375 op = 's';
ef416fc2 376
61cf44e2
MS
377 if (num_dests <= 1)
378 {
379 cupsFreeDests(num_dests, dests);
380 num_dests = cupsGetDests(&dests);
381 }
ef416fc2 382
61cf44e2
MS
383 show_default(cupsGetDest(NULL, NULL, num_dests, dests));
384 status |= show_classes(NULL);
385 status |= show_devices(NULL, num_dests, dests);
ef416fc2 386 break;
387
388 case 't' : /* Show all info */
61cf44e2
MS
389 op = 't';
390
391 if (num_dests <= 1)
392 {
393 cupsFreeDests(num_dests, dests);
394 num_dests = cupsGetDests(&dests);
395 }
396
397 show_scheduler();
398 show_default(cupsGetDest(NULL, NULL, num_dests, dests));
399 status |= show_classes(NULL);
400 status |= show_devices(NULL, num_dests, dests);
401 status |= show_accepting(NULL, num_dests, dests);
402 status |= show_printers(NULL, num_dests, dests, long_status);
403 status |= show_jobs(NULL, NULL, long_status, ranking, which);
ef416fc2 404 break;
405
406 case 'u' : /* Show jobs by user */
61cf44e2 407 op = 'u';
ef416fc2 408
61cf44e2
MS
409 if (argv[i][2])
410 status |= show_jobs(NULL, argv[i] + 2, long_status, ranking,
411 which);
ef416fc2 412 else if ((i + 1) < argc && argv[i + 1][0] != '-')
413 {
414 i ++;
61cf44e2 415 status |= show_jobs(NULL, argv[i], long_status, ranking, which);
ef416fc2 416 }
417 else
61cf44e2 418 status |= show_jobs(NULL, NULL, long_status, ranking, which);
ef416fc2 419 break;
420
421 case 'v' : /* Show printer devices */
61cf44e2 422 op = 'v';
ef416fc2 423
61cf44e2 424 if (argv[i][2])
ef416fc2 425 {
61cf44e2 426 check_dest(argv[0], argv[i] + 2, &num_dests, &dests);
ef416fc2 427
61cf44e2 428 status |= show_devices(argv[i] + 2, num_dests, dests);
ef416fc2 429 }
430 else if ((i + 1) < argc && argv[i + 1][0] != '-')
431 {
432 i ++;
433
61cf44e2 434 check_dest(argv[0], argv[i], &num_dests, &dests);
ef416fc2 435
61cf44e2 436 status |= show_devices(argv[i], num_dests, dests);
ef416fc2 437 }
438 else
439 {
61cf44e2
MS
440 if (num_dests <= 1)
441 {
442 cupsFreeDests(num_dests, dests);
443 num_dests = cupsGetDests(&dests);
444 }
ef416fc2 445
61cf44e2 446 status |= show_devices(NULL, num_dests, dests);
ef416fc2 447 }
448 break;
449
ef416fc2 450 default :
fa73b229 451 _cupsLangPrintf(stderr,
0837b7e8 452 _("%s: Error - unknown option \"%c\"."),
fa73b229 453 argv[0], argv[i][1]);
ef416fc2 454 return (1);
455 }
456 else
457 {
61cf44e2 458 status |= show_jobs(argv[i], NULL, long_status, ranking, which);
ef416fc2 459 op = 'o';
460 }
461
462 if (!op)
61cf44e2 463 status |= show_jobs(NULL, cupsUser(), long_status, ranking, which);
ef416fc2 464
465 return (status);
466}
467
468
469/*
470 * 'check_dest()' - Verify that the named destination(s) exists.
471 */
472
473static void
fa73b229 474check_dest(const char *command, /* I - Command name */
61cf44e2 475 const char *name, /* I - List of printer/class names */
ef416fc2 476 int *num_dests, /* IO - Number of destinations */
477 cups_dest_t **dests) /* IO - Destinations */
478{
61cf44e2
MS
479 const char *dptr; /* Pointer into name */
480 char *pptr, /* Pointer into printer */
481 printer[1024]; /* Current printer/class name */
ef416fc2 482
483
484 /*
485 * Load the destination list as necessary...
486 */
487
61cf44e2
MS
488 if (*num_dests <= 1)
489 {
490 if (*num_dests)
491 cupsFreeDests(*num_dests, *dests);
492
493 if (strchr(name, ','))
494 *num_dests = cupsGetDests(dests);
495 else
496 {
497 strlcpy(printer, name, sizeof(printer));
498 if ((pptr = strchr(printer, '/')) != NULL)
499 *pptr++ = '\0';
500
501 if ((*dests = cupsGetNamedDest(CUPS_HTTP_DEFAULT, printer, pptr)) == NULL)
502 {
503 _cupsLangPrintf(stderr,
0837b7e8 504 _("%s: Invalid destination name in list \"%s\"."),
61cf44e2
MS
505 command, name);
506 exit(1);
507 }
508 else
509 {
510 *num_dests = 1;
511 return;
512 }
513 }
514 }
ef416fc2 515
516 /*
517 * Scan the name string for printer/class name(s)...
518 */
519
61cf44e2 520 for (dptr = name; *dptr;)
ef416fc2 521 {
522 /*
523 * Skip leading whitespace and commas...
524 */
525
526 while (isspace(*dptr & 255) || *dptr == ',')
527 dptr ++;
528
61cf44e2 529 if (!*dptr)
ef416fc2 530 break;
531
532 /*
533 * Extract a single destination name from the name string...
534 */
535
61cf44e2 536 for (pptr = printer; !isspace(*dptr & 255) && *dptr != ',' && *dptr;)
ef416fc2 537 {
538 if ((pptr - printer) < (sizeof(printer) - 1))
539 *pptr++ = *dptr++;
540 else
541 {
fa73b229 542 _cupsLangPrintf(stderr,
0837b7e8 543 _("%s: Invalid destination name in list \"%s\"."),
fa73b229 544 command, name);
ef416fc2 545 exit(1);
546 }
547 }
548
549 *pptr = '\0';
550
551 /*
552 * Check the destination...
553 */
554
61cf44e2 555 if (!cupsGetDest(printer, NULL, *num_dests, *dests))
ef416fc2 556 {
fa73b229 557 _cupsLangPrintf(stderr,
0837b7e8 558 _("%s: Unknown destination \"%s\"."), command, printer);
ef416fc2 559 exit(1);
560 }
561 }
562}
563
564
565/*
61cf44e2 566 * 'match_list()' - Match a name from a list of comma or space-separated names.
ef416fc2 567 */
568
61cf44e2
MS
569static int /* O - 1 on match, 0 on no match */
570match_list(const char *list, /* I - List of names */
571 const char *name) /* I - Name to find */
ef416fc2 572{
61cf44e2
MS
573 const char *nameptr; /* Pointer into name */
574
575
576 /*
cc754834 577 * An empty list always matches...
61cf44e2
MS
578 */
579
580 if (!list || !*list)
cc754834 581 return (1);
61cf44e2
MS
582
583 while (*list)
ef416fc2 584 {
61cf44e2
MS
585 /*
586 * Skip leading whitespace and commas...
587 */
ef416fc2 588
61cf44e2
MS
589 while (isspace(*list & 255) || *list == ',')
590 list ++;
591
592 if (!*list)
593 break;
594
595 /*
596 * Compare names...
597 */
598
599 for (nameptr = name;
600 *nameptr && *list && tolower(*nameptr & 255) == tolower(*list & 255);
601 nameptr ++, list ++);
602
603 if (!*nameptr && (!*list || *list == ',' || isspace(*list & 255)))
604 return (1);
605
606 while (*list && !isspace(*list & 255) && *list != ',')
607 list ++;
ef416fc2 608 }
609
61cf44e2 610 return (0);
ef416fc2 611}
612
613
614/*
615 * 'show_accepting()' - Show acceptance status.
616 */
617
618static int /* O - 0 on success, 1 on fail */
61cf44e2 619show_accepting(const char *printers, /* I - Destinations */
ef416fc2 620 int num_dests, /* I - Number of user-defined dests */
621 cups_dest_t *dests) /* I - User-defined destinations */
622{
623 int i; /* Looping var */
624 ipp_t *request, /* IPP Request */
625 *response; /* IPP Response */
626 ipp_attribute_t *attr; /* Current attribute */
627 const char *printer, /* Printer name */
628 *message; /* Printer device URI */
629 int accepting; /* Accepting requests? */
fa73b229 630 time_t ptime; /* Printer state time */
631 struct tm *pdate; /* Printer state date & time */
632 char printer_state_time[255];/* Printer state time */
ef416fc2 633 static const char *pattrs[] = /* Attributes we need for printers... */
634 {
635 "printer-name",
fa73b229 636 "printer-state-change-time",
ef416fc2 637 "printer-state-message",
638 "printer-is-accepting-jobs"
639 };
640
641
61cf44e2 642 DEBUG_printf(("show_accepting(printers=\"%s\")\n", printers));
ef416fc2 643
fa73b229 644 if (printers != NULL && !strcmp(printers, "all"))
ef416fc2 645 printers = NULL;
646
647 /*
648 * Build a CUPS_GET_PRINTERS request, which requires the following
649 * attributes:
650 *
651 * attributes-charset
652 * attributes-natural-language
653 * requested-attributes
fa73b229 654 * requesting-user-name
ef416fc2 655 */
656
657 request = ippNewRequest(CUPS_GET_PRINTERS);
658
659 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
660 "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
661 NULL, pattrs);
662
fa73b229 663 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
664 NULL, cupsUser());
665
ef416fc2 666 /*
667 * Do the request and get back a response...
668 */
669
61cf44e2 670 if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL)
ef416fc2 671 {
672 DEBUG_puts("show_accepting: request succeeded...");
673
674 if (response->request.status.status_code > IPP_OK_CONFLICT)
675 {
0837b7e8 676 _cupsLangPrintf(stderr, "lpstat: %s", cupsLastErrorString());
ef416fc2 677 ippDelete(response);
678 return (1);
679 }
680
681 /*
682 * Loop through the printers returned in the list and display
683 * their devices...
684 */
685
686 for (attr = response->attrs; attr != NULL; attr = attr->next)
687 {
688 /*
689 * Skip leading attributes until we hit a printer...
690 */
691
692 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
693 attr = attr->next;
694
695 if (attr == NULL)
696 break;
697
698 /*
699 * Pull the needed attributes from this printer...
700 */
701
702 printer = NULL;
703 message = NULL;
704 accepting = 1;
fa73b229 705 ptime = 0;
ef416fc2 706
707 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
708 {
709 if (!strcmp(attr->name, "printer-name") &&
710 attr->value_tag == IPP_TAG_NAME)
711 printer = attr->values[0].string.text;
fa73b229 712 else if (!strcmp(attr->name, "printer-state-change-time") &&
713 attr->value_tag == IPP_TAG_INTEGER)
714 ptime = (time_t)attr->values[0].integer;
715 else if (!strcmp(attr->name, "printer-state-message") &&
716 attr->value_tag == IPP_TAG_TEXT)
ef416fc2 717 message = attr->values[0].string.text;
fa73b229 718 else if (!strcmp(attr->name, "printer-is-accepting-jobs") &&
719 attr->value_tag == IPP_TAG_BOOLEAN)
ef416fc2 720 accepting = attr->values[0].boolean;
721
722 attr = attr->next;
723 }
724
725 /*
726 * See if we have everything needed...
727 */
728
729 if (printer == NULL)
730 {
731 if (attr == NULL)
732 break;
733 else
734 continue;
735 }
736
ef416fc2 737 /*
738 * Display the printer entry if needed...
739 */
740
61cf44e2 741 if (match_list(printers, printer))
ef416fc2 742 {
fa73b229 743 pdate = localtime(&ptime);
744 strftime(printer_state_time, sizeof(printer_state_time), "%c", pdate);
745
ef416fc2 746 if (accepting)
0837b7e8 747 _cupsLangPrintf(stdout, _("%s accepting requests since %s"),
fa73b229 748 printer, printer_state_time);
ef416fc2 749 else
0837b7e8
MS
750 {
751 _cupsLangPrintf(stdout, _("%s not accepting requests since %s -"),
752 printer, printer_state_time);
753 _cupsLangPrintf(stdout, _("\t%s"),
61cf44e2
MS
754 (message == NULL || !*message) ?
755 "reason unknown" : message);
0837b7e8 756 }
ef416fc2 757
758 for (i = 0; i < num_dests; i ++)
759 if (!strcasecmp(dests[i].name, printer) && dests[i].instance)
760 {
761 if (accepting)
0837b7e8 762 _cupsLangPrintf(stdout, _("%s/%s accepting requests since %s"),
fa73b229 763 printer, dests[i].instance, printer_state_time);
ef416fc2 764 else
0837b7e8
MS
765 {
766 _cupsLangPrintf(stdout,
767 _("%s/%s not accepting requests since %s -"),
768 printer, dests[i].instance, printer_state_time);
769 _cupsLangPrintf(stdout, _("\t%s"),
61cf44e2
MS
770 (message == NULL || !*message) ?
771 "reason unknown" : message);
0837b7e8 772 }
ef416fc2 773 }
774 }
775
776 if (attr == NULL)
777 break;
778 }
779
780 ippDelete(response);
781 }
782 else
783 {
0837b7e8 784 _cupsLangPrintf(stderr, "lpstat: %s", cupsLastErrorString());
ef416fc2 785 return (1);
786 }
787
788 return (0);
789}
790
791
792/*
793 * 'show_classes()' - Show printer classes.
794 */
795
796static int /* O - 0 on success, 1 on fail */
61cf44e2 797show_classes(const char *dests) /* I - Destinations */
ef416fc2 798{
799 int i; /* Looping var */
800 ipp_t *request, /* IPP Request */
801 *response, /* IPP Response */
802 *response2; /* IPP response from remote server */
803 http_t *http2; /* Remote server */
804 ipp_attribute_t *attr; /* Current attribute */
805 const char *printer, /* Printer class name */
806 *printer_uri; /* Printer class URI */
807 ipp_attribute_t *members; /* Printer members */
808 char method[HTTP_MAX_URI], /* Request method */
809 username[HTTP_MAX_URI], /* Username:password */
810 server[HTTP_MAX_URI], /* Server name */
811 resource[HTTP_MAX_URI]; /* Resource name */
812 int port; /* Port number */
ef416fc2 813 static const char *cattrs[] = /* Attributes we need for classes... */
814 {
815 "printer-name",
816 "printer-uri-supported",
817 "member-names"
818 };
819
820
61cf44e2 821 DEBUG_printf(("show_classes(dests=\"%s\")\n", dests));
ef416fc2 822
fa73b229 823 if (dests != NULL && !strcmp(dests, "all"))
ef416fc2 824 dests = NULL;
825
826 /*
827 * Build a CUPS_GET_CLASSES request, which requires the following
828 * attributes:
829 *
830 * attributes-charset
831 * attributes-natural-language
832 * requested-attributes
fa73b229 833 * requesting-user-name
ef416fc2 834 */
835
836 request = ippNewRequest(CUPS_GET_CLASSES);
837
838 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
839 "requested-attributes", sizeof(cattrs) / sizeof(cattrs[0]),
840 NULL, cattrs);
841
fa73b229 842 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
843 NULL, cupsUser());
844
ef416fc2 845 /*
846 * Do the request and get back a response...
847 */
848
61cf44e2 849 if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL)
ef416fc2 850 {
851 DEBUG_puts("show_classes: request succeeded...");
852
853 if (response->request.status.status_code > IPP_OK_CONFLICT)
854 {
0837b7e8 855 _cupsLangPrintf(stderr, "lpstat: %s", cupsLastErrorString());
ef416fc2 856 ippDelete(response);
857 return (1);
858 }
859
860 /*
861 * Loop through the printers returned in the list and display
862 * their devices...
863 */
864
865 for (attr = response->attrs; attr != NULL; attr = attr->next)
866 {
867 /*
868 * Skip leading attributes until we hit a job...
869 */
870
871 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
872 attr = attr->next;
873
874 if (attr == NULL)
875 break;
876
877 /*
878 * Pull the needed attributes from this job...
879 */
880
881 printer = NULL;
882 printer_uri = NULL;
883 members = NULL;
884
885 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
886 {
887 if (!strcmp(attr->name, "printer-name") &&
888 attr->value_tag == IPP_TAG_NAME)
889 printer = attr->values[0].string.text;
890
891 if (!strcmp(attr->name, "printer-uri-supported") &&
892 attr->value_tag == IPP_TAG_URI)
893 printer_uri = attr->values[0].string.text;
894
895 if (!strcmp(attr->name, "member-names") &&
896 attr->value_tag == IPP_TAG_NAME)
897 members = attr;
898
899 attr = attr->next;
900 }
901
902 /*
903 * If this is a remote class, grab the class info from the
904 * remote server...
905 */
906
907 response2 = NULL;
908 if (members == NULL && printer_uri != NULL)
909 {
a4d04587 910 httpSeparateURI(HTTP_URI_CODING_ALL, printer_uri, method, sizeof(method),
ef416fc2 911 username, sizeof(username), server, sizeof(server),
912 &port, resource, sizeof(resource));
913
61cf44e2
MS
914 if (!strcasecmp(server, cupsServer()))
915 http2 = CUPS_HTTP_DEFAULT;
ef416fc2 916 else
917 http2 = httpConnectEncrypt(server, port, cupsEncryption());
918
61cf44e2
MS
919 /*
920 * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
921 * following attributes:
922 *
923 * attributes-charset
924 * attributes-natural-language
925 * printer-uri
926 * requested-attributes
927 */
ef416fc2 928
61cf44e2 929 request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
ef416fc2 930
61cf44e2
MS
931 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
932 "printer-uri", NULL, printer_uri);
ef416fc2 933
61cf44e2
MS
934 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
935 "requested-attributes",
936 sizeof(cattrs) / sizeof(cattrs[0]),
937 NULL, cattrs);
ef416fc2 938
61cf44e2
MS
939 if ((response2 = cupsDoRequest(http2, request, "/")) != NULL)
940 members = ippFindAttribute(response2, "member-names", IPP_TAG_NAME);
ef416fc2 941
61cf44e2
MS
942 if (http2)
943 httpClose(http2);
ef416fc2 944 }
945
946 /*
947 * See if we have everything needed...
948 */
949
950 if (printer == NULL)
951 {
952 if (response2)
953 ippDelete(response2);
954
955 if (attr == NULL)
956 break;
957 else
958 continue;
959 }
960
ef416fc2 961 /*
962 * Display the printer entry if needed...
963 */
964
61cf44e2 965 if (match_list(dests, printer))
ef416fc2 966 {
0837b7e8 967 _cupsLangPrintf(stdout, _("members of class %s:"), printer);
ef416fc2 968
969 if (members)
970 {
971 for (i = 0; i < members->num_values; i ++)
0837b7e8 972 _cupsLangPrintf(stdout, "\t%s", members->values[i].string.text);
ef416fc2 973 }
974 else
0837b7e8 975 _cupsLangPuts(stdout, "\tunknown");
ef416fc2 976 }
977
978 if (response2)
979 ippDelete(response2);
980
981 if (attr == NULL)
982 break;
983 }
984
985 ippDelete(response);
986 }
987 else
988 {
0837b7e8 989 _cupsLangPrintf(stderr, "lpstat: %s", cupsLastErrorString());
ef416fc2 990 return (1);
991 }
992
993 return (0);
994}
995
996
997/*
998 * 'show_default()' - Show default destination.
999 */
1000
1001static void
61cf44e2 1002show_default(cups_dest_t *dest) /* I - Default destination */
ef416fc2 1003{
ef416fc2 1004 const char *printer, /* Printer name */
1005 *val; /* Environment variable name */
1006
61cf44e2
MS
1007
1008 if (dest)
ef416fc2 1009 {
1010 if (dest->instance)
0837b7e8 1011 _cupsLangPrintf(stdout, _("system default destination: %s/%s"),
ef416fc2 1012 dest->name, dest->instance);
1013 else
0837b7e8 1014 _cupsLangPrintf(stdout, _("system default destination: %s"),
ef416fc2 1015 dest->name);
1016 }
1017 else
1018 {
1019 val = NULL;
1020
1021 if ((printer = getenv("LPDEST")) == NULL)
1022 {
1023 if ((printer = getenv("PRINTER")) != NULL)
1024 {
1025 if (!strcmp(printer, "lp"))
1026 printer = NULL;
1027 else
1028 val = "PRINTER";
1029 }
1030 }
1031 else
1032 val = "LPDEST";
1033
61cf44e2 1034 if (printer)
fa73b229 1035 _cupsLangPrintf(stdout,
ef416fc2 1036 _("lpstat: error - %s environment variable names "
0837b7e8 1037 "non-existent destination \"%s\"."),
ef416fc2 1038 val, printer);
1039 else
0837b7e8 1040 _cupsLangPuts(stdout, _("no system default destination"));
ef416fc2 1041 }
1042}
1043
1044
1045/*
1046 * 'show_devices()' - Show printer devices.
1047 */
1048
1049static int /* O - 0 on success, 1 on fail */
61cf44e2 1050show_devices(const char *printers, /* I - Destinations */
ef416fc2 1051 int num_dests, /* I - Number of user-defined dests */
1052 cups_dest_t *dests) /* I - User-defined destinations */
1053{
1054 int i; /* Looping var */
1055 ipp_t *request, /* IPP Request */
1056 *response; /* IPP Response */
1057 ipp_attribute_t *attr; /* Current attribute */
1058 const char *printer, /* Printer name */
1059 *uri, /* Printer URI */
61cf44e2 1060 *device; /* Printer device URI */
ef416fc2 1061 static const char *pattrs[] = /* Attributes we need for printers... */
1062 {
1063 "printer-name",
1064 "printer-uri-supported",
1065 "device-uri"
1066 };
1067
1068
61cf44e2 1069 DEBUG_printf(("show_devices(printers=\"%s\")\n", printers));
ef416fc2 1070
fa73b229 1071 if (printers != NULL && !strcmp(printers, "all"))
ef416fc2 1072 printers = NULL;
1073
1074 /*
1075 * Build a CUPS_GET_PRINTERS request, which requires the following
1076 * attributes:
1077 *
1078 * attributes-charset
1079 * attributes-natural-language
1080 * requested-attributes
fa73b229 1081 * requesting-user-name
ef416fc2 1082 */
1083
1084 request = ippNewRequest(CUPS_GET_PRINTERS);
1085
1086 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
1087 "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
1088 NULL, pattrs);
1089
fa73b229 1090 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
1091 NULL, cupsUser());
1092
ef416fc2 1093 /*
1094 * Do the request and get back a response...
1095 */
1096
61cf44e2 1097 if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL)
ef416fc2 1098 {
1099 DEBUG_puts("show_devices: request succeeded...");
1100
1101 if (response->request.status.status_code > IPP_OK_CONFLICT)
1102 {
0837b7e8 1103 _cupsLangPrintf(stderr, "lpstat: %s", cupsLastErrorString());
ef416fc2 1104 ippDelete(response);
1105 return (1);
1106 }
1107
1108 /*
1109 * Loop through the printers returned in the list and display
1110 * their devices...
1111 */
1112
1113 for (attr = response->attrs; attr != NULL; attr = attr->next)
1114 {
1115 /*
1116 * Skip leading attributes until we hit a job...
1117 */
1118
1119 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
1120 attr = attr->next;
1121
1122 if (attr == NULL)
1123 break;
1124
1125 /*
1126 * Pull the needed attributes from this job...
1127 */
1128
1129 printer = NULL;
1130 device = NULL;
1131 uri = NULL;
1132
1133 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
1134 {
1135 if (!strcmp(attr->name, "printer-name") &&
1136 attr->value_tag == IPP_TAG_NAME)
1137 printer = attr->values[0].string.text;
1138
1139 if (!strcmp(attr->name, "printer-uri-supported") &&
1140 attr->value_tag == IPP_TAG_URI)
1141 uri = attr->values[0].string.text;
1142
1143 if (!strcmp(attr->name, "device-uri") &&
1144 attr->value_tag == IPP_TAG_URI)
1145 device = attr->values[0].string.text;
1146
1147 attr = attr->next;
1148 }
1149
1150 /*
1151 * See if we have everything needed...
1152 */
1153
1154 if (printer == NULL)
1155 {
1156 if (attr == NULL)
1157 break;
1158 else
1159 continue;
1160 }
1161
ef416fc2 1162 /*
1163 * Display the printer entry if needed...
1164 */
1165
61cf44e2 1166 if (match_list(printers, printer))
ef416fc2 1167 {
1168#ifdef __osf__ /* Compaq/Digital like to do it their own way... */
61cf44e2 1169 char scheme[HTTP_MAX_URI], /* Components of printer URI */
ef416fc2 1170 username[HTTP_MAX_URI],
1171 hostname[HTTP_MAX_URI],
1172 resource[HTTP_MAX_URI];
1173 int port;
1174
1175
1176 if (device == NULL)
1177 {
61cf44e2 1178 httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme),
a4d04587 1179 username, sizeof(username), hostname,
1180 sizeof(hostname), &port, resource, sizeof(resource));
fa73b229 1181 _cupsLangPrintf(stdout,
ef416fc2 1182 _("Output for printer %s is sent to remote "
0837b7e8 1183 "printer %s on %s"),
ef416fc2 1184 printer, strrchr(resource, '/') + 1, hostname);
1185 }
fa73b229 1186 else if (!strncmp(device, "file:", 5))
1187 _cupsLangPrintf(stdout,
0837b7e8 1188 _("Output for printer %s is sent to %s"),
ef416fc2 1189 printer, device + 5);
1190 else
fa73b229 1191 _cupsLangPrintf(stdout,
0837b7e8 1192 _("Output for printer %s is sent to %s"),
ef416fc2 1193 printer, device);
1194
1195 for (i = 0; i < num_dests; i ++)
1196 if (!strcasecmp(printer, dests[i].name) && dests[i].instance)
1197 {
1198 if (device == NULL)
fa73b229 1199 _cupsLangPrintf(stdout,
ef416fc2 1200 _("Output for printer %s/%s is sent to "
0837b7e8 1201 "remote printer %s on %s"),
ef416fc2 1202 printer, dests[i].instance,
1203 strrchr(resource, '/') + 1, hostname);
1204 else if (!strncmp(device, "file:", 5))
fa73b229 1205 _cupsLangPrintf(stdout,
0837b7e8 1206 _("Output for printer %s/%s is sent to %s"),
ef416fc2 1207 printer, dests[i].instance, device + 5);
1208 else
fa73b229 1209 _cupsLangPrintf(stdout,
0837b7e8 1210 _("Output for printer %s/%s is sent to %s"),
ef416fc2 1211 printer, dests[i].instance, device);
1212 }
1213#else
1214 if (device == NULL)
0837b7e8 1215 _cupsLangPrintf(stdout, _("device for %s: %s"),
ef416fc2 1216 printer, uri);
1217 else if (!strncmp(device, "file:", 5))
0837b7e8 1218 _cupsLangPrintf(stdout, _("device for %s: %s"),
ef416fc2 1219 printer, device + 5);
1220 else
0837b7e8 1221 _cupsLangPrintf(stdout, _("device for %s: %s"),
ef416fc2 1222 printer, device);
1223
1224 for (i = 0; i < num_dests; i ++)
1225 if (!strcasecmp(printer, dests[i].name) && dests[i].instance)
1226 {
1227 if (device == NULL)
0837b7e8 1228 _cupsLangPrintf(stdout, _("device for %s/%s: %s"),
ef416fc2 1229 printer, dests[i].instance, uri);
1230 else if (!strncmp(device, "file:", 5))
0837b7e8 1231 _cupsLangPrintf(stdout, _("device for %s/%s: %s"),
ef416fc2 1232 printer, dests[i].instance, device + 5);
1233 else
0837b7e8 1234 _cupsLangPrintf(stdout, _("device for %s/%s: %s"),
ef416fc2 1235 printer, dests[i].instance, device);
1236 }
1237#endif /* __osf__ */
1238 }
1239
1240 if (attr == NULL)
1241 break;
1242 }
1243
1244 ippDelete(response);
1245 }
1246 else
1247 {
0837b7e8 1248 _cupsLangPrintf(stderr, "lpstat: %s", cupsLastErrorString());
ef416fc2 1249 return (1);
1250 }
1251
1252 return (0);
1253}
1254
1255
1256/*
1257 * 'show_jobs()' - Show active print jobs.
1258 */
1259
1260static int /* O - 0 on success, 1 on fail */
61cf44e2 1261show_jobs(const char *dests, /* I - Destinations */
ef416fc2 1262 const char *users, /* I - Users */
1263 int long_status, /* I - Show long status? */
1264 int ranking, /* I - Show job ranking? */
1265 const char *which) /* I - Show which jobs? */
1266{
09a101d6 1267 int i; /* Looping var */
ef416fc2 1268 ipp_t *request, /* IPP Request */
1269 *response; /* IPP Response */
09a101d6 1270 ipp_attribute_t *attr, /* Current attribute */
1271 *reasons; /* Job state reasons attribute */
ef416fc2 1272 const char *dest, /* Pointer into job-printer-uri */
1273 *username, /* Pointer to job-originating-user-name */
229681c1
MS
1274 *title, /* Pointer to job-name */
1275 *message; /* Pointer to job-printer-state-message */
ef416fc2 1276 int rank, /* Rank in queue */
1277 jobid, /* job-id */
1278 size; /* job-k-octets */
1279 time_t jobtime; /* time-at-creation */
1280 struct tm *jobdate; /* Date & time */
ef416fc2 1281 char temp[255], /* Temporary buffer */
1282 date[255]; /* Date buffer */
1283 static const char *jattrs[] = /* Attributes we need for jobs... */
1284 {
1285 "job-id",
1286 "job-k-octets",
1287 "job-name",
09a101d6 1288 "job-originating-user-name",
229681c1 1289 "job-printer-state-message",
5a662dc0
MS
1290 "job-printer-uri",
1291 "job-state-reasons",
1292 "time-at-creation"
ef416fc2 1293 };
1294
1295
61cf44e2
MS
1296 DEBUG_printf(("show_jobs(dests=\"%s\", users=\"%s\", long_status=%d, "
1297 "ranking=%d, which=\"%s\")\n", dests, users, long_status,
1298 ranking, which));
ef416fc2 1299
fa73b229 1300 if (dests != NULL && !strcmp(dests, "all"))
ef416fc2 1301 dests = NULL;
1302
1303 /*
1304 * Build a IPP_GET_JOBS request, which requires the following
1305 * attributes:
1306 *
1307 * attributes-charset
1308 * attributes-natural-language
52f6f666 1309 * printer-uri
ef416fc2 1310 * requested-attributes
52f6f666
MS
1311 * requesting-user-name
1312 * which-jobs
ef416fc2 1313 */
1314
1315 request = ippNewRequest(IPP_GET_JOBS);
1316
52f6f666
MS
1317 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
1318 NULL, "ipp://localhost/");
1319
ef416fc2 1320 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
1321 "requested-attributes", sizeof(jattrs) / sizeof(jattrs[0]),
1322 NULL, jattrs);
1323
52f6f666
MS
1324 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
1325 NULL, cupsUser());
ef416fc2 1326
1327 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs",
1328 NULL, which);
1329
1330 /*
1331 * Do the request and get back a response...
1332 */
1333
61cf44e2 1334 if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL)
ef416fc2 1335 {
1336 /*
1337 * Loop through the job list and display them...
1338 */
1339
1340 if (response->request.status.status_code > IPP_OK_CONFLICT)
1341 {
0837b7e8 1342 _cupsLangPrintf(stderr, "lpstat: %s", cupsLastErrorString());
ef416fc2 1343 ippDelete(response);
1344 return (1);
1345 }
1346
1347 rank = -1;
1348
1349 for (attr = response->attrs; attr != NULL; attr = attr->next)
1350 {
1351 /*
1352 * Skip leading attributes until we hit a job...
1353 */
1354
1355 while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
1356 attr = attr->next;
1357
1358 if (attr == NULL)
1359 break;
1360
1361 /*
1362 * Pull the needed attributes from this job...
1363 */
1364
1365 jobid = 0;
1366 size = 0;
1367 username = NULL;
1368 dest = NULL;
1369 jobtime = 0;
1370 title = "no title";
229681c1 1371 message = NULL;
09a101d6 1372 reasons = NULL;
ef416fc2 1373
1374 while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
1375 {
fa73b229 1376 if (!strcmp(attr->name, "job-id") &&
ef416fc2 1377 attr->value_tag == IPP_TAG_INTEGER)
1378 jobid = attr->values[0].integer;
229681c1
MS
1379 else if (!strcmp(attr->name, "job-k-octets") &&
1380 attr->value_tag == IPP_TAG_INTEGER)
ef416fc2 1381 size = attr->values[0].integer;
229681c1
MS
1382 else if (!strcmp(attr->name, "time-at-creation") &&
1383 attr->value_tag == IPP_TAG_INTEGER)
ef416fc2 1384 jobtime = attr->values[0].integer;
229681c1
MS
1385 else if (!strcmp(attr->name, "job-printer-state-message") &&
1386 attr->value_tag == IPP_TAG_TEXT)
1387 message = attr->values[0].string.text;
1388 else if (!strcmp(attr->name, "job-printer-uri") &&
1389 attr->value_tag == IPP_TAG_URI)
1390 {
ef416fc2 1391 if ((dest = strrchr(attr->values[0].string.text, '/')) != NULL)
1392 dest ++;
229681c1
MS
1393 }
1394 else if (!strcmp(attr->name, "job-originating-user-name") &&
1395 attr->value_tag == IPP_TAG_NAME)
ef416fc2 1396 username = attr->values[0].string.text;
229681c1
MS
1397 else if (!strcmp(attr->name, "job-name") &&
1398 attr->value_tag == IPP_TAG_NAME)
ef416fc2 1399 title = attr->values[0].string.text;
229681c1
MS
1400 else if (!strcmp(attr->name, "job-state-reasons") &&
1401 attr->value_tag == IPP_TAG_KEYWORD)
09a101d6 1402 reasons = attr;
1403
ef416fc2 1404 attr = attr->next;
1405 }
1406
1407 /*
1408 * See if we have everything needed...
1409 */
1410
1411 if (dest == NULL || jobid == 0)
1412 {
1413 if (attr == NULL)
1414 break;
1415 else
1416 continue;
1417 }
1418
1419 /*
61cf44e2 1420 * Display the job...
ef416fc2 1421 */
1422
ef416fc2 1423 rank ++;
1424
cc754834 1425 if (match_list(dests, dest) && match_list(users, username))
ef416fc2 1426 {
1427 jobdate = localtime(&jobtime);
1428 snprintf(temp, sizeof(temp), "%s-%d", dest, jobid);
1429
1430 if (long_status == 3)
1431 {
1432 /*
1433 * Show the consolidated output format for the SGI tools...
1434 */
1435
1436 if (!strftime(date, sizeof(date), "%b %d %H:%M", jobdate))
1437 strcpy(date, "Unknown");
1438
0837b7e8 1439 _cupsLangPrintf(stdout, "%s;%s;%d;%s;%s",
ef416fc2 1440 temp, username ? username : "unknown",
1441 size, title ? title : "unknown", date);
1442 }
1443 else
1444 {
1445 if (!strftime(date, sizeof(date), "%c", jobdate))
1446 strcpy(date, "Unknown");
1447
1448 if (ranking)
0837b7e8 1449 _cupsLangPrintf(stdout, "%3d %-21s %-13s %8.0f %s",
ef416fc2 1450 rank, temp, username ? username : "unknown",
1451 1024.0 * size, date);
1452 else
0837b7e8 1453 _cupsLangPrintf(stdout, "%-23s %-13s %8.0f %s",
ef416fc2 1454 temp, username ? username : "unknown",
1455 1024.0 * size, date);
1456 if (long_status)
09a101d6 1457 {
229681c1
MS
1458 if (message)
1459 _cupsLangPrintf(stdout, _("\tStatus: %s"), message);
1460
09a101d6 1461 if (reasons)
1462 {
0837b7e8
MS
1463 char alerts[1024], /* Alerts string */
1464 *aptr; /* Pointer into alerts string */
1465
1466 for (i = 0, aptr = alerts; i < reasons->num_values; i ++)
1467 {
1468 if (i)
1469 snprintf(aptr, sizeof(alerts) - (aptr - alerts), " %s",
1470 reasons->values[i].string.text);
1471 else
1472 strlcpy(alerts, reasons->values[i].string.text,
1473 sizeof(alerts));
1474
1475 aptr += strlen(aptr);
1476 }
1477
1478 _cupsLangPrintf(stdout, _("\tAlerts: %s"), alerts);
09a101d6 1479 }
0837b7e8
MS
1480
1481 _cupsLangPrintf(stdout, _("\tqueued for %s"), dest);
09a101d6 1482 }
ef416fc2 1483 }
1484 }
1485
1486 if (attr == NULL)
1487 break;
1488 }
1489
1490 ippDelete(response);
1491 }
1492 else
1493 {
0837b7e8 1494 _cupsLangPrintf(stderr, "lpstat: %s", cupsLastErrorString());
ef416fc2 1495 return (1);
1496 }
1497
1498 return (0);
1499}
1500
1501
1502/*
1503 * 'show_printers()' - Show printers.
1504 */
1505
1506static int /* O - 0 on success, 1 on fail */
61cf44e2 1507show_printers(const char *printers, /* I - Destinations */
ef416fc2 1508 int num_dests, /* I - Number of user-defined dests */
1509 cups_dest_t *dests, /* I - User-defined destinations */
1510 int long_status) /* I - Show long status? */
1511{
26d47ec6 1512 int i, j; /* Looping vars */
ef416fc2 1513 ipp_t *request, /* IPP Request */
1514 *response, /* IPP Response */
1515 *jobs; /* IPP Get Jobs response */
1516 ipp_attribute_t *attr, /* Current attribute */
1517 *jobattr, /* Job ID attribute */
1518 *reasons; /* Job state reasons attribute */
1519 const char *printer, /* Printer name */
1520 *message, /* Printer state message */
1521 *description, /* Description of printer */
1522 *location, /* Location of printer */
1523 *make_model, /* Make and model of printer */
1524 *uri; /* URI of printer */
1525 ipp_attribute_t *allowed, /* requesting-user-name-allowed */
1526 *denied; /* requestint-user-name-denied */
1527 ipp_pstate_t pstate; /* Printer state */
1528 cups_ptype_t ptype; /* Printer type */
1529 time_t ptime; /* Printer state time */
1530 struct tm *pdate; /* Printer state date & time */
1531 int jobid; /* Job ID of current job */
ef416fc2 1532 char printer_uri[HTTP_MAX_URI],
1533 /* Printer URI */
1534 printer_state_time[255];/* Printer state time */
f8b3a85b 1535 _cups_globals_t *cg = _cupsGlobals(); /* Global data */
ef416fc2 1536 static const char *pattrs[] = /* Attributes we need for printers... */
1537 {
1538 "printer-name",
1539 "printer-state",
1540 "printer-state-message",
1541 "printer-state-reasons",
1542 "printer-state-change-time",
1543 "printer-type",
1544 "printer-info",
1545 "printer-location",
1546 "printer-make-and-model",
1547 "printer-uri-supported",
1548 "requesting-user-name-allowed",
1549 "requesting-user-name-denied"
1550 };
1551 static const char *jattrs[] = /* Attributes we need for jobs... */
1552 {
7cf5915e
MS
1553 "job-id",
1554 "job-state"
ef416fc2 1555 };
1556
1557
bf3816c7
MS
1558 DEBUG_printf(("show_printers(printers=\"%s\", num_dests=%d, dests=%p, "
1559 "long_status=%d)\n", printers, num_dests, dests, long_status));
ef416fc2 1560
fa73b229 1561 if (printers != NULL && !strcmp(printers, "all"))
ef416fc2 1562 printers = NULL;
1563
1564 /*
1565 * Build a CUPS_GET_PRINTERS request, which requires the following
1566 * attributes:
1567 *
1568 * attributes-charset
1569 * attributes-natural-language
1570 * requested-attributes
fa73b229 1571 * requesting-user-name
ef416fc2 1572 */
1573
1574 request = ippNewRequest(CUPS_GET_PRINTERS);
1575
1576 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
1577 "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
1578 NULL, pattrs);
1579
fa73b229 1580 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
1581 NULL, cupsUser());
1582
ef416fc2 1583 /*
1584 * Do the request and get back a response...
1585 */
1586
61cf44e2 1587 if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL)
ef416fc2 1588 {
1589 DEBUG_puts("show_printers: request succeeded...");
1590
1591 if (response->request.status.status_code > IPP_OK_CONFLICT)
1592 {
0837b7e8 1593 _cupsLangPrintf(stderr, "lpstat: %s", cupsLastErrorString());
ef416fc2 1594 ippDelete(response);
1595 return (1);
1596 }
1597
1598 /*
1599 * Loop through the printers returned in the list and display
1600 * their status...
1601 */
1602
1603 for (attr = response->attrs; attr != NULL; attr = attr->next)
1604 {
1605 /*
1606 * Skip leading attributes until we hit a job...
1607 */
1608
1609 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
1610 attr = attr->next;
1611
1612 if (attr == NULL)
1613 break;
1614
1615 /*
1616 * Pull the needed attributes from this job...
1617 */
1618
1619 printer = NULL;
1620 ptime = 0;
1621 ptype = CUPS_PRINTER_LOCAL;
1622 pstate = IPP_PRINTER_IDLE;
1623 message = NULL;
1624 description = NULL;
1625 location = NULL;
1626 make_model = NULL;
1627 reasons = NULL;
1628 uri = NULL;
1629 jobid = 0;
1630 allowed = NULL;
1631 denied = NULL;
1632
1633 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
1634 {
1635 if (!strcmp(attr->name, "printer-name") &&
1636 attr->value_tag == IPP_TAG_NAME)
1637 printer = attr->values[0].string.text;
1638 else if (!strcmp(attr->name, "printer-state") &&
1639 attr->value_tag == IPP_TAG_ENUM)
1640 pstate = (ipp_pstate_t)attr->values[0].integer;
1641 else if (!strcmp(attr->name, "printer-type") &&
1642 attr->value_tag == IPP_TAG_ENUM)
1643 ptype = (cups_ptype_t)attr->values[0].integer;
1644 else if (!strcmp(attr->name, "printer-state-message") &&
1645 attr->value_tag == IPP_TAG_TEXT)
1646 message = attr->values[0].string.text;
1647 else if (!strcmp(attr->name, "printer-state-change-time") &&
1648 attr->value_tag == IPP_TAG_INTEGER)
1649 ptime = (time_t)attr->values[0].integer;
1650 else if (!strcmp(attr->name, "printer-info") &&
1651 attr->value_tag == IPP_TAG_TEXT)
1652 description = attr->values[0].string.text;
1653 else if (!strcmp(attr->name, "printer-location") &&
1654 attr->value_tag == IPP_TAG_TEXT)
1655 location = attr->values[0].string.text;
1656 else if (!strcmp(attr->name, "printer-make-and-model") &&
1657 attr->value_tag == IPP_TAG_TEXT)
1658 make_model = attr->values[0].string.text;
1659 else if (!strcmp(attr->name, "printer-uri-supported") &&
1660 attr->value_tag == IPP_TAG_URI)
1661 uri = attr->values[0].string.text;
1662 else if (!strcmp(attr->name, "printer-state-reasons") &&
1663 attr->value_tag == IPP_TAG_KEYWORD)
1664 reasons = attr;
1665 else if (!strcmp(attr->name, "requesting-user-name-allowed") &&
1666 attr->value_tag == IPP_TAG_NAME)
1667 allowed = attr;
1668 else if (!strcmp(attr->name, "requesting-user-name-denied") &&
1669 attr->value_tag == IPP_TAG_NAME)
1670 denied = attr;
1671
1672 attr = attr->next;
1673 }
1674
1675 /*
1676 * See if we have everything needed...
1677 */
1678
1679 if (printer == NULL)
1680 {
1681 if (attr == NULL)
1682 break;
1683 else
1684 continue;
1685 }
1686
ef416fc2 1687 /*
1688 * Display the printer entry if needed...
1689 */
1690
61cf44e2 1691 if (match_list(printers, printer))
ef416fc2 1692 {
1693 /*
1694 * If the printer state is "IPP_PRINTER_PROCESSING", then grab the
1695 * current job for the printer.
1696 */
1697
1698 if (pstate == IPP_PRINTER_PROCESSING)
1699 {
1700 /*
1701 * Build an IPP_GET_JOBS request, which requires the following
1702 * attributes:
1703 *
1704 * attributes-charset
1705 * attributes-natural-language
1706 * printer-uri
1707 * limit
1708 * requested-attributes
1709 */
1710
1711 request = ippNewRequest(IPP_GET_JOBS);
1712
1713 request->request.op.operation_id = IPP_GET_JOBS;
1714 request->request.op.request_id = 1;
1715
1716 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
1717 "requested-attributes",
1718 sizeof(jattrs) / sizeof(jattrs[0]), NULL, jattrs);
1719
a4d04587 1720 httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
1721 "ipp", NULL, "localhost", 0, "/printers/%s", printer);
ef416fc2 1722 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1723 "printer-uri", NULL, printer_uri);
1724
61cf44e2 1725 if ((jobs = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL)
ef416fc2 1726 {
1727 /*
1728 * Get the current active job on this queue...
1729 */
1730
c934a06c 1731 ipp_jstate_t jobstate = IPP_JOB_PENDING;
ef416fc2 1732 jobid = 0;
1733
1734 for (jobattr = jobs->attrs; jobattr; jobattr = jobattr->next)
1735 {
1736 if (!jobattr->name)
c934a06c
MS
1737 {
1738 if (jobstate == IPP_JOB_PROCESSING)
1739 break;
1740 else
1741 continue;
1742 }
ef416fc2 1743
1744 if (!strcmp(jobattr->name, "job-id") &&
1745 jobattr->value_tag == IPP_TAG_INTEGER)
1746 jobid = jobattr->values[0].integer;
1747 else if (!strcmp(jobattr->name, "job-state") &&
c934a06c
MS
1748 jobattr->value_tag == IPP_TAG_ENUM)
1749 jobstate = jobattr->values[0].integer;
ef416fc2 1750 }
1751
c934a06c
MS
1752 if (jobstate != IPP_JOB_PROCESSING)
1753 jobid = 0;
1754
ef416fc2 1755 ippDelete(jobs);
1756 }
1757 }
1758
1759 /*
1760 * Display it...
1761 */
1762
1763 pdate = localtime(&ptime);
1764 strftime(printer_state_time, sizeof(printer_state_time), "%c", pdate);
1765
1766 switch (pstate)
1767 {
1768 case IPP_PRINTER_IDLE :
fa73b229 1769 _cupsLangPrintf(stdout,
0837b7e8 1770 _("printer %s is idle. enabled since %s"),
ef416fc2 1771 printer, printer_state_time);
1772 break;
1773 case IPP_PRINTER_PROCESSING :
fa73b229 1774 _cupsLangPrintf(stdout,
ef416fc2 1775 _("printer %s now printing %s-%d. "
0837b7e8 1776 "enabled since %s"),
ef416fc2 1777 printer, printer, jobid, printer_state_time);
1778 break;
1779 case IPP_PRINTER_STOPPED :
fa73b229 1780 _cupsLangPrintf(stdout,
0837b7e8 1781 _("printer %s disabled since %s -"),
ef416fc2 1782 printer, printer_state_time);
1783 break;
1784 }
1785
1786 if ((message && *message) || pstate == IPP_PRINTER_STOPPED)
1787 {
1788 if (!message || !*message)
0837b7e8 1789 _cupsLangPuts(stdout, _("\treason unknown"));
ef416fc2 1790 else
0837b7e8 1791 _cupsLangPrintf(stdout, "\t%s", message);
ef416fc2 1792 }
1793
1794 if (long_status > 1)
0837b7e8
MS
1795 {
1796 _cupsLangPuts(stdout, _("\tForm mounted:"));
1797 _cupsLangPuts(stdout, _("\tContent types: any"));
1798 _cupsLangPuts(stdout, _("\tPrinter types: unknown"));
1799 }
ef416fc2 1800
1801 if (long_status)
1802 {
0837b7e8 1803 _cupsLangPrintf(stdout, _("\tDescription: %s"),
ef416fc2 1804 description ? description : "");
1805
1806 if (reasons)
1807 {
0837b7e8
MS
1808 char alerts[1024], /* Alerts string */
1809 *aptr; /* Pointer into alerts string */
1810
1811 for (i = 0, aptr = alerts; i < reasons->num_values; i ++)
1812 {
1813 if (i)
1814 snprintf(aptr, sizeof(alerts) - (aptr - alerts), " %s",
1815 reasons->values[i].string.text);
1816 else
1817 strlcpy(alerts, reasons->values[i].string.text,
1818 sizeof(alerts));
1819
1820 aptr += strlen(aptr);
1821 }
1822
1823 _cupsLangPrintf(stdout, _("\tAlerts: %s"), alerts);
ef416fc2 1824 }
1825 }
1826 if (long_status > 1)
1827 {
0837b7e8 1828 _cupsLangPrintf(stdout, _("\tLocation: %s"),
ef416fc2 1829 location ? location : "");
1830
1831 if (ptype & CUPS_PRINTER_REMOTE)
1832 {
0837b7e8 1833 _cupsLangPuts(stdout, _("\tConnection: remote"));
ef416fc2 1834
1835 if (make_model && !strstr(make_model, "System V Printer") &&
1836 !strstr(make_model, "Raw Printer") && uri)
0837b7e8 1837 _cupsLangPrintf(stdout, _("\tInterface: %s.ppd"),
ef416fc2 1838 uri);
1839 }
1840 else
1841 {
0837b7e8 1842 _cupsLangPuts(stdout, _("\tConnection: direct"));
ef416fc2 1843
1844 if (make_model && strstr(make_model, "System V Printer"))
fa73b229 1845 _cupsLangPrintf(stdout,
0837b7e8 1846 _("\tInterface: %s/interfaces/%s"),
f8b3a85b 1847 cg->cups_serverroot, printer);
ef416fc2 1848 else if (make_model && !strstr(make_model, "Raw Printer"))
fa73b229 1849 _cupsLangPrintf(stdout,
0837b7e8 1850 _("\tInterface: %s/ppd/%s.ppd"),
f8b3a85b 1851 cg->cups_serverroot, printer);
ef416fc2 1852 }
0837b7e8
MS
1853 _cupsLangPuts(stdout, _("\tOn fault: no alert"));
1854 _cupsLangPuts(stdout, _("\tAfter fault: continue"));
b423cd4c 1855 /* TODO update to use printer-error-policy */
ef416fc2 1856 if (allowed)
1857 {
0837b7e8 1858 _cupsLangPuts(stdout, _("\tUsers allowed:"));
26d47ec6 1859 for (j = 0; j < allowed->num_values; j ++)
0837b7e8 1860 _cupsLangPrintf(stdout, "\t\t%s",
26d47ec6 1861 allowed->values[j].string.text);
ef416fc2 1862 }
1863 else if (denied)
1864 {
0837b7e8 1865 _cupsLangPuts(stdout, _("\tUsers denied:"));
26d47ec6 1866 for (j = 0; j < denied->num_values; j ++)
0837b7e8 1867 _cupsLangPrintf(stdout, "\t\t%s",
26d47ec6 1868 denied->values[j].string.text);
ef416fc2 1869 }
1870 else
1871 {
0837b7e8
MS
1872 _cupsLangPuts(stdout, _("\tUsers allowed:"));
1873 _cupsLangPuts(stdout, _("\t\t(all)"));
ef416fc2 1874 }
0837b7e8
MS
1875 _cupsLangPuts(stdout, _("\tForms allowed:"));
1876 _cupsLangPuts(stdout, _("\t\t(none)"));
1877 _cupsLangPuts(stdout, _("\tBanner required"));
1878 _cupsLangPuts(stdout, _("\tCharset sets:"));
1879 _cupsLangPuts(stdout, _("\t\t(none)"));
1880 _cupsLangPuts(stdout, _("\tDefault pitch:"));
1881 _cupsLangPuts(stdout, _("\tDefault page size:"));
1882 _cupsLangPuts(stdout, _("\tDefault port settings:"));
ef416fc2 1883 }
1884
1885 for (i = 0; i < num_dests; i ++)
1886 if (!strcasecmp(printer, dests[i].name) && dests[i].instance)
1887 {
1888 switch (pstate)
1889 {
1890 case IPP_PRINTER_IDLE :
fa73b229 1891 _cupsLangPrintf(stdout,
ef416fc2 1892 _("printer %s/%s is idle. "
0837b7e8 1893 "enabled since %s"),
ef416fc2 1894 printer, dests[i].instance,
1895 printer_state_time);
1896 break;
1897 case IPP_PRINTER_PROCESSING :
fa73b229 1898 _cupsLangPrintf(stdout,
ef416fc2 1899 _("printer %s/%s now printing %s-%d. "
0837b7e8 1900 "enabled since %s"),
ef416fc2 1901 printer, dests[i].instance, printer, jobid,
1902 printer_state_time);
1903 break;
1904 case IPP_PRINTER_STOPPED :
fa73b229 1905 _cupsLangPrintf(stdout,
0837b7e8 1906 _("printer %s/%s disabled since %s -"),
ef416fc2 1907 printer, dests[i].instance,
1908 printer_state_time);
1909 break;
1910 }
1911
1912 if ((message && *message) || pstate == IPP_PRINTER_STOPPED)
1913 {
1914 if (!message || !*message)
0837b7e8 1915 _cupsLangPuts(stdout, _("\treason unknown"));
ef416fc2 1916 else
0837b7e8 1917 _cupsLangPrintf(stdout, "\t%s", message);
ef416fc2 1918 }
1919
1920 if (long_status > 1)
0837b7e8
MS
1921 {
1922 _cupsLangPuts(stdout, _("\tForm mounted:"));
1923 _cupsLangPuts(stdout, _("\tContent types: any"));
1924 _cupsLangPuts(stdout, _("\tPrinter types: unknown"));
1925 }
ef416fc2 1926
1927 if (long_status)
1928 {
0837b7e8 1929 _cupsLangPrintf(stdout, _("\tDescription: %s"),
ef416fc2 1930 description ? description : "");
1931
1932 if (reasons)
1933 {
0837b7e8
MS
1934 char alerts[1024], /* Alerts string */
1935 *aptr; /* Pointer into alerts string */
1936
1937 for (i = 0, aptr = alerts; i < reasons->num_values; i ++)
1938 {
1939 if (i)
1940 snprintf(aptr, sizeof(alerts) - (aptr - alerts), " %s",
1941 reasons->values[i].string.text);
1942 else
1943 strlcpy(alerts, reasons->values[i].string.text,
1944 sizeof(alerts));
1945
1946 aptr += strlen(aptr);
1947 }
1948
1949 _cupsLangPrintf(stdout, _("\tAlerts: %s"), alerts);
ef416fc2 1950 }
1951 }
1952 if (long_status > 1)
1953 {
0837b7e8 1954 _cupsLangPrintf(stdout, _("\tLocation: %s"),
ef416fc2 1955 location ? location : "");
1956
1957 if (ptype & CUPS_PRINTER_REMOTE)
1958 {
0837b7e8 1959 _cupsLangPuts(stdout, _("\tConnection: remote"));
ef416fc2 1960
1961 if (make_model && !strstr(make_model, "System V Printer") &&
1962 !strstr(make_model, "Raw Printer") && uri)
0837b7e8 1963 _cupsLangPrintf(stdout, _("\tInterface: %s.ppd"), uri);
ef416fc2 1964 }
1965 else
1966 {
0837b7e8 1967 _cupsLangPuts(stdout, _("\tConnection: direct"));
ef416fc2 1968
1969 if (make_model && strstr(make_model, "System V Printer"))
fa73b229 1970 _cupsLangPrintf(stdout,
0837b7e8 1971 _("\tInterface: %s/interfaces/%s"),
f8b3a85b 1972 cg->cups_serverroot, printer);
ef416fc2 1973 else if (make_model && !strstr(make_model, "Raw Printer"))
fa73b229 1974 _cupsLangPrintf(stdout,
0837b7e8 1975 _("\tInterface: %s/ppd/%s.ppd"),
f8b3a85b 1976 cg->cups_serverroot, printer);
ef416fc2 1977 }
0837b7e8
MS
1978 _cupsLangPuts(stdout, _("\tOn fault: no alert"));
1979 _cupsLangPuts(stdout, _("\tAfter fault: continue"));
b423cd4c 1980 /* TODO update to use printer-error-policy */
ef416fc2 1981 if (allowed)
1982 {
0837b7e8 1983 _cupsLangPuts(stdout, _("\tUsers allowed:"));
26d47ec6 1984 for (j = 0; j < allowed->num_values; j ++)
0837b7e8 1985 _cupsLangPrintf(stdout, "\t\t%s",
26d47ec6 1986 allowed->values[j].string.text);
ef416fc2 1987 }
1988 else if (denied)
1989 {
0837b7e8 1990 _cupsLangPuts(stdout, _("\tUsers denied:"));
26d47ec6 1991 for (j = 0; j < denied->num_values; j ++)
0837b7e8 1992 _cupsLangPrintf(stdout, "\t\t%s",
26d47ec6 1993 denied->values[j].string.text);
ef416fc2 1994 }
1995 else
1996 {
0837b7e8
MS
1997 _cupsLangPuts(stdout, _("\tUsers allowed:"));
1998 _cupsLangPuts(stdout, _("\t\t(all)"));
ef416fc2 1999 }
0837b7e8
MS
2000 _cupsLangPuts(stdout, _("\tForms allowed:"));
2001 _cupsLangPuts(stdout, _("\t\t(none)"));
2002 _cupsLangPuts(stdout, _("\tBanner required"));
2003 _cupsLangPuts(stdout, _("\tCharset sets:"));
2004 _cupsLangPuts(stdout, _("\t\t(none)"));
2005 _cupsLangPuts(stdout, _("\tDefault pitch:"));
2006 _cupsLangPuts(stdout, _("\tDefault page size:"));
2007 _cupsLangPuts(stdout, _("\tDefault port settings:"));
ef416fc2 2008 }
2009 }
2010 }
2011
2012 if (attr == NULL)
2013 break;
2014 }
2015
2016 ippDelete(response);
2017 }
2018 else
2019 {
0837b7e8 2020 _cupsLangPrintf(stderr, "lpstat: %s", cupsLastErrorString());
ef416fc2 2021 return (1);
2022 }
2023
2024 return (0);
2025}
2026
2027
2028/*
2029 * 'show_scheduler()' - Show scheduler status.
2030 */
2031
2032static void
61cf44e2 2033show_scheduler(void)
ef416fc2 2034{
61cf44e2
MS
2035 http_t *http; /* Connection to server */
2036
2037
2038 if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
2039 cupsEncryption())) != NULL)
2040 {
0837b7e8 2041 _cupsLangPuts(stdout, _("scheduler is running"));
61cf44e2
MS
2042 httpClose(http);
2043 }
ef416fc2 2044 else
0837b7e8 2045 _cupsLangPuts(stdout, _("scheduler is not running"));
ef416fc2 2046}
2047
2048
2049/*
b19ccc9e 2050 * End of "$Id: lpstat.c 7921 2008-09-10 15:42:24Z mike $".
ef416fc2 2051 */