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