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