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