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