2 * "lpstat" command for CUPS.
4 * Copyright © 2007-2018 by Apple Inc.
5 * Copyright © 1997-2006 by Easy Software Products.
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more
12 * Include necessary headers...
15 #include <cups/cups-private.h>
22 static void check_dest(const char *command
, const char *name
,
23 int *num_dests
, cups_dest_t
**dests
);
24 static int match_list(const char *list
, const char *name
);
25 static int show_accepting(const char *printers
, int num_dests
,
27 static int show_classes(const char *dests
);
28 static void show_default(cups_dest_t
*dest
);
29 static int show_devices(const char *printers
, int num_dests
,
31 static int show_jobs(const char *dests
, const char *users
, int long_status
,
32 int ranking
, const char *which
);
33 static int show_printers(const char *printers
, int num_dests
,
34 cups_dest_t
*dests
, int long_status
);
35 static void show_scheduler(void);
36 static void usage(void) _CUPS_NORETURN
;
40 * 'main()' - Parse options and show status information.
44 main(int argc
, /* I - Number of command-line arguments */
45 char *argv
[]) /* I - Command-line arguments */
47 int i
, /* Looping var */
48 status
; /* Exit status */
49 char *opt
; /* Option pointer */
50 int num_dests
; /* Number of user destinations */
51 cups_dest_t
*dests
; /* User destinations */
52 int long_status
; /* Long status report? */
53 int ranking
; /* Show job ranking? */
54 const char *which
; /* Which jobs to show? */
55 char op
; /* Last operation on command-line */
61 * Parse command-line options...
69 which
= "not-completed";
72 for (i
= 1; i
< argc
; i
++)
74 if (!strcmp(argv
[i
], "--help"))
76 else if (argv
[i
][0] == '-')
78 for (opt
= argv
[i
] + 1; *opt
; opt
++)
82 case 'D' : /* Show description */
86 case 'E' : /* Encrypt */
88 cupsSetEncryption(HTTP_ENCRYPT_REQUIRED
);
90 _cupsLangPrintf(stderr
,
91 _("%s: Sorry, no encryption support."),
96 case 'H' : /* Show server and port */
97 if (cupsServer()[0] == '/')
98 _cupsLangPuts(stdout
, cupsServer());
100 _cupsLangPrintf(stdout
, "%s:%d", cupsServer(), ippPort());
104 case 'P' : /* Show paper types */
108 case 'R' : /* Show ranking */
112 case 'S' : /* Show charsets */
118 case 'U' : /* Username */
121 cupsSetUser(opt
+ 1);
122 opt
+= strlen(opt
) - 1;
129 _cupsLangPrintf(stderr
, _("%s: Error - expected username after \"-U\" option."), argv
[0]);
133 cupsSetUser(argv
[i
]);
137 case 'W' : /* Show which jobs? */
141 opt
+= strlen(opt
) - 1;
149 _cupsLangPrintf(stderr
, _("%s: Error - need \"completed\", \"not-completed\", or \"all\" after \"-W\" option."), argv
[0]);
156 if (strcmp(which
, "completed") && strcmp(which
, "not-completed") && strcmp(which
, "all"))
158 _cupsLangPrintf(stderr
, _("%s: Error - need \"completed\", \"not-completed\", or \"all\" after \"-W\" option."), argv
[0]);
163 case 'a' : /* Show acceptance status */
168 check_dest(argv
[0], opt
+ 1, &num_dests
, &dests
);
170 status
|= show_accepting(opt
+ 1, num_dests
, dests
);
171 opt
+= strlen(opt
) - 1;
173 else if ((i
+ 1) < argc
&& argv
[i
+ 1][0] != '-')
177 check_dest(argv
[0], argv
[i
], &num_dests
, &dests
);
179 status
|= show_accepting(argv
[i
], num_dests
, dests
);
185 cupsFreeDests(num_dests
, dests
);
186 num_dests
= cupsGetDests(&dests
);
188 if (num_dests
== 0 && (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST
|| cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED
))
190 _cupsLangPrintf(stderr
, _("%s: Error - add '/version=1.1' to server name."), argv
[0]);
195 status
|= show_accepting(NULL
, num_dests
, dests
);
199 case 'c' : /* Show classes and members */
204 check_dest(argv
[0], opt
+ 1, &num_dests
, &dests
);
206 status
|= show_classes(opt
+ 1);
207 opt
+= strlen(opt
) - 1;
209 else if ((i
+ 1) < argc
&& argv
[i
+ 1][0] != '-')
213 check_dest(argv
[0], argv
[i
], &num_dests
, &dests
);
215 status
|= show_classes(argv
[i
]);
218 status
|= show_classes(NULL
);
221 case 'd' : /* Show default destination */
224 if (num_dests
!= 1 || !dests
[0].is_default
)
226 cupsFreeDests(num_dests
, dests
);
228 dests
= cupsGetNamedDest(CUPS_HTTP_DEFAULT
, NULL
, NULL
);
229 num_dests
= dests
? 1 : 0;
231 if (num_dests
== 0 &&
232 (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST
||
233 cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED
))
235 _cupsLangPrintf(stderr
, _("%s: Error - add '/version=1.1' to server name."), argv
[0]);
243 case 'e' : /* List destinations */
245 cups_dest_t
*temp
= NULL
, *dest
;
246 int j
, num_temp
= cupsGetDests(&temp
);
250 for (j
= num_temp
, dest
= temp
; j
> 0; j
--, dest
++)
253 printf("%s/%s", dest
->name
, dest
->instance
);
255 fputs(dest
->name
, stdout
);
259 const char *printer_uri_supported
= cupsGetOption("printer-uri-supported", dest
->num_options
, dest
->options
);
260 const char *printer_is_temporary
= cupsGetOption("printer-is-temporary", dest
->num_options
, dest
->options
);
261 const char *type
= "network";
263 if (printer_is_temporary
&& !strcmp(printer_is_temporary
, "true"))
265 else if (printer_uri_supported
)
268 printf(" %s %s %s\n", type
, printer_uri_supported
? printer_uri_supported
: "none", cupsGetOption("device-uri", dest
->num_options
, dest
->options
));
274 cupsFreeDests(num_temp
, temp
);
278 case 'f' : /* Show forms */
282 opt
+= strlen(opt
) - 1;
292 case 'h' : /* Connect to host */
295 cupsSetServer(opt
+ 1);
296 opt
+= strlen(opt
) - 1;
304 _cupsLangPrintf(stderr
, _("%s: Error - expected hostname after \"-h\" option."), argv
[0]);
308 cupsSetServer(argv
[i
]);
312 case 'l' : /* Long status or long job status */
316 case 'o' : /* Show jobs by destination */
321 check_dest(argv
[0], opt
+ 1, &num_dests
, &dests
);
323 status
|= show_jobs(opt
+ 1, NULL
, long_status
, ranking
, which
);
324 opt
+= strlen(opt
) - 1;
326 else if ((i
+ 1) < argc
&& argv
[i
+ 1][0] != '-')
330 check_dest(argv
[0], argv
[i
], &num_dests
, &dests
);
332 status
|= show_jobs(argv
[i
], NULL
, long_status
, ranking
, which
);
335 status
|= show_jobs(NULL
, NULL
, long_status
, ranking
, which
);
338 case 'p' : /* Show printers */
343 check_dest(argv
[0], opt
+ 1, &num_dests
, &dests
);
345 status
|= show_printers(opt
+ 1, num_dests
, dests
,
347 opt
+= strlen(opt
) - 1;
349 else if ((i
+ 1) < argc
&& argv
[i
+ 1][0] != '-')
353 check_dest(argv
[0], argv
[i
], &num_dests
, &dests
);
355 status
|= show_printers(argv
[i
], num_dests
, dests
, long_status
);
361 cupsFreeDests(num_dests
, dests
);
362 num_dests
= cupsGetDests(&dests
);
364 if (num_dests
== 0 &&
365 (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST
||
366 cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED
))
368 _cupsLangPrintf(stderr
, _("%s: Error - add '/version=1.1' to server name."), argv
[0]);
373 status
|= show_printers(NULL
, num_dests
, dests
, long_status
);
377 case 'r' : /* Show scheduler status */
383 case 's' : /* Show summary */
388 cupsFreeDests(num_dests
, dests
);
389 num_dests
= cupsGetDests(&dests
);
391 if (num_dests
== 0 &&
392 (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST
||
393 cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED
))
395 _cupsLangPrintf(stderr
, _("%s: Error - add '/version=1.1' to server name."), argv
[0]);
400 show_default(cupsGetDest(NULL
, NULL
, num_dests
, dests
));
401 status
|= show_classes(NULL
);
402 status
|= show_devices(NULL
, num_dests
, dests
);
405 case 't' : /* Show all info */
410 cupsFreeDests(num_dests
, dests
);
411 num_dests
= cupsGetDests(&dests
);
413 if (num_dests
== 0 &&
414 (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST
||
415 cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED
))
417 _cupsLangPrintf(stderr
, _("%s: Error - add '/version=1.1' to server name."), argv
[0]);
423 show_default(cupsGetDest(NULL
, NULL
, num_dests
, dests
));
424 status
|= show_classes(NULL
);
425 status
|= show_devices(NULL
, num_dests
, dests
);
426 status
|= show_accepting(NULL
, num_dests
, dests
);
427 status
|= show_printers(NULL
, num_dests
, dests
, long_status
);
428 status
|= show_jobs(NULL
, NULL
, long_status
, ranking
, which
);
431 case 'u' : /* Show jobs by user */
436 status
|= show_jobs(NULL
, opt
+ 1, long_status
, ranking
, which
);
437 opt
+= strlen(opt
) - 1;
439 else if ((i
+ 1) < argc
&& argv
[i
+ 1][0] != '-')
442 status
|= show_jobs(NULL
, argv
[i
], long_status
, ranking
, which
);
445 status
|= show_jobs(NULL
, NULL
, long_status
, ranking
, which
);
448 case 'v' : /* Show printer devices */
453 check_dest(argv
[0], opt
+ 1, &num_dests
, &dests
);
455 status
|= show_devices(opt
+ 1, num_dests
, dests
);
456 opt
+= strlen(opt
) - 1;
458 else if ((i
+ 1) < argc
&& argv
[i
+ 1][0] != '-')
462 check_dest(argv
[0], argv
[i
], &num_dests
, &dests
);
464 status
|= show_devices(argv
[i
], num_dests
, dests
);
470 cupsFreeDests(num_dests
, dests
);
471 num_dests
= cupsGetDests(&dests
);
473 if (num_dests
== 0 &&
474 (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST
||
475 cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED
))
477 _cupsLangPrintf(stderr
, _("%s: Error - add '/version=1.1' to server name."), argv
[0]);
482 status
|= show_devices(NULL
, num_dests
, dests
);
487 _cupsLangPrintf(stderr
, _("%s: Error - unknown option \"%c\"."), argv
[0], argv
[i
][1]);
494 status
|= show_jobs(argv
[i
], NULL
, long_status
, ranking
, which
);
500 status
|= show_jobs(NULL
, cupsUser(), long_status
, ranking
, which
);
507 * 'check_dest()' - Verify that the named destination(s) exists.
511 check_dest(const char *command
, /* I - Command name */
512 const char *name
, /* I - List of printer/class names */
513 int *num_dests
, /* IO - Number of destinations */
514 cups_dest_t
**dests
) /* IO - Destinations */
516 const char *dptr
; /* Pointer into name */
517 char *pptr
, /* Pointer into printer */
518 printer
[1024]; /* Current printer/class name */
522 * Load the destination list as necessary...
528 cupsFreeDests(*num_dests
, *dests
);
530 if (strchr(name
, ','))
531 *num_dests
= cupsGetDests(dests
);
534 strlcpy(printer
, name
, sizeof(printer
));
535 if ((pptr
= strchr(printer
, '/')) != NULL
)
538 if ((*dests
= cupsGetNamedDest(CUPS_HTTP_DEFAULT
, printer
, pptr
)) == NULL
)
540 if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST
||
541 cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED
)
542 _cupsLangPrintf(stderr
,
543 _("%s: Error - add '/version=1.1' to server name."),
546 _cupsLangPrintf(stderr
,
547 _("%s: Invalid destination name in list \"%s\"."),
561 * Scan the name string for printer/class name(s)...
564 for (dptr
= name
; *dptr
;)
567 * Skip leading whitespace and commas...
570 while (isspace(*dptr
& 255) || *dptr
== ',')
577 * Extract a single destination name from the name string...
580 for (pptr
= printer
; !isspace(*dptr
& 255) && *dptr
!= ',' && *dptr
;)
582 if ((size_t)(pptr
- printer
) < (sizeof(printer
) - 1))
586 _cupsLangPrintf(stderr
,
587 _("%s: Invalid destination name in list \"%s\"."),
596 * Check the destination...
599 if (!cupsGetDest(printer
, NULL
, *num_dests
, *dests
))
601 if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST
||
602 cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED
)
603 _cupsLangPrintf(stderr
,
604 _("%s: Error - add '/version=1.1' to server name."),
607 _cupsLangPrintf(stderr
,
608 _("%s: Unknown destination \"%s\"."), command
, printer
);
617 * 'match_list()' - Match a name from a list of comma or space-separated names.
620 static int /* O - 1 on match, 0 on no match */
621 match_list(const char *list
, /* I - List of names */
622 const char *name
) /* I - Name to find */
624 const char *nameptr
; /* Pointer into name */
628 * An empty list always matches...
640 * Skip leading whitespace and commas...
643 while (isspace(*list
& 255) || *list
== ',')
654 *nameptr
&& *list
&& tolower(*nameptr
& 255) == tolower(*list
& 255);
655 nameptr
++, list
++);
657 if (!*nameptr
&& (!*list
|| *list
== ',' || isspace(*list
& 255)))
660 while (*list
&& !isspace(*list
& 255) && *list
!= ',')
669 * 'show_accepting()' - Show acceptance status.
672 static int /* O - 0 on success, 1 on fail */
673 show_accepting(const char *printers
, /* I - Destinations */
674 int num_dests
, /* I - Number of user-defined dests */
675 cups_dest_t
*dests
) /* I - User-defined destinations */
677 int i
; /* Looping var */
678 ipp_t
*request
, /* IPP Request */
679 *response
; /* IPP Response */
680 ipp_attribute_t
*attr
; /* Current attribute */
681 const char *printer
, /* Printer name */
682 *message
; /* Printer device URI */
683 int accepting
; /* Accepting requests? */
684 time_t ptime
; /* Printer state time */
685 char printer_state_time
[255];/* Printer state time */
686 static const char *pattrs
[] = /* Attributes we need for printers... */
689 "printer-state-change-time",
690 "printer-state-message",
691 "printer-is-accepting-jobs"
695 if (printers
!= NULL
&& !strcmp(printers
, "all"))
699 * Build a CUPS_GET_PRINTERS request, which requires the following
703 * attributes-natural-language
704 * requested-attributes
705 * requesting-user-name
708 request
= ippNewRequest(CUPS_GET_PRINTERS
);
710 ippAddStrings(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
,
711 "requested-attributes", sizeof(pattrs
) / sizeof(pattrs
[0]),
714 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "requesting-user-name",
718 * Do the request and get back a response...
721 response
= cupsDoRequest(CUPS_HTTP_DEFAULT
, request
, "/");
723 if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST
||
724 cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED
)
726 _cupsLangPrintf(stderr
,
727 _("%s: Error - add '/version=1.1' to server name."),
732 else if (cupsLastError() > IPP_STATUS_OK_CONFLICTING
)
734 _cupsLangPrintf(stderr
, "lpstat: %s", cupsLastErrorString());
742 * Loop through the printers returned in the list and display
746 for (attr
= response
->attrs
; attr
!= NULL
; attr
= attr
->next
)
749 * Skip leading attributes until we hit a printer...
752 while (attr
!= NULL
&& attr
->group_tag
!= IPP_TAG_PRINTER
)
759 * Pull the needed attributes from this printer...
767 while (attr
!= NULL
&& attr
->group_tag
== IPP_TAG_PRINTER
)
769 if (!strcmp(attr
->name
, "printer-name") &&
770 attr
->value_tag
== IPP_TAG_NAME
)
771 printer
= attr
->values
[0].string
.text
;
772 else if (!strcmp(attr
->name
, "printer-state-change-time") &&
773 attr
->value_tag
== IPP_TAG_INTEGER
)
774 ptime
= (time_t)attr
->values
[0].integer
;
775 else if (!strcmp(attr
->name
, "printer-state-message") &&
776 attr
->value_tag
== IPP_TAG_TEXT
)
777 message
= attr
->values
[0].string
.text
;
778 else if (!strcmp(attr
->name
, "printer-is-accepting-jobs") &&
779 attr
->value_tag
== IPP_TAG_BOOLEAN
)
780 accepting
= attr
->values
[0].boolean
;
786 * See if we have everything needed...
798 * Display the printer entry if needed...
801 if (match_list(printers
, printer
))
803 _cupsStrDate(printer_state_time
, sizeof(printer_state_time
), ptime
);
806 _cupsLangPrintf(stdout
, _("%s accepting requests since %s"),
807 printer
, printer_state_time
);
810 _cupsLangPrintf(stdout
, _("%s not accepting requests since %s -"),
811 printer
, printer_state_time
);
812 _cupsLangPrintf(stdout
, _("\t%s"),
813 (message
== NULL
|| !*message
) ?
814 "reason unknown" : message
);
817 for (i
= 0; i
< num_dests
; i
++)
818 if (!_cups_strcasecmp(dests
[i
].name
, printer
) && dests
[i
].instance
)
821 _cupsLangPrintf(stdout
, _("%s/%s accepting requests since %s"),
822 printer
, dests
[i
].instance
, printer_state_time
);
825 _cupsLangPrintf(stdout
,
826 _("%s/%s not accepting requests since %s -"),
827 printer
, dests
[i
].instance
, printer_state_time
);
828 _cupsLangPrintf(stdout
, _("\t%s"),
829 (message
== NULL
|| !*message
) ?
830 "reason unknown" : message
);
847 * 'show_classes()' - Show printer classes.
850 static int /* O - 0 on success, 1 on fail */
851 show_classes(const char *dests
) /* I - Destinations */
853 int i
; /* Looping var */
854 ipp_t
*request
, /* IPP Request */
855 *response
, /* IPP Response */
856 *response2
; /* IPP response from remote server */
857 http_t
*http2
; /* Remote server */
858 ipp_attribute_t
*attr
; /* Current attribute */
859 const char *printer
, /* Printer class name */
860 *printer_uri
; /* Printer class URI */
861 ipp_attribute_t
*members
; /* Printer members */
862 char method
[HTTP_MAX_URI
], /* Request method */
863 username
[HTTP_MAX_URI
], /* Username:password */
864 server
[HTTP_MAX_URI
], /* Server name */
865 resource
[HTTP_MAX_URI
]; /* Resource name */
866 int port
; /* Port number */
867 static const char *cattrs
[] = /* Attributes we need for classes... */
870 "printer-uri-supported",
875 if (dests
!= NULL
&& !strcmp(dests
, "all"))
879 * Build a CUPS_GET_CLASSES request, which requires the following
883 * attributes-natural-language
884 * requested-attributes
885 * requesting-user-name
888 request
= ippNewRequest(CUPS_GET_CLASSES
);
890 ippAddStrings(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
,
891 "requested-attributes", sizeof(cattrs
) / sizeof(cattrs
[0]),
894 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "requesting-user-name",
898 * Do the request and get back a response...
901 response
= cupsDoRequest(CUPS_HTTP_DEFAULT
, request
, "/");
903 if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST
||
904 cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED
)
906 _cupsLangPrintf(stderr
,
907 _("%s: Error - add '/version=1.1' to server name."),
912 else if (cupsLastError() > IPP_STATUS_OK_CONFLICTING
)
914 _cupsLangPrintf(stderr
, "lpstat: %s", cupsLastErrorString());
921 if (response
->request
.status
.status_code
> IPP_OK_CONFLICT
)
923 _cupsLangPrintf(stderr
, "lpstat: %s", cupsLastErrorString());
929 * Loop through the printers returned in the list and display
933 for (attr
= response
->attrs
; attr
!= NULL
; attr
= attr
->next
)
936 * Skip leading attributes until we hit a job...
939 while (attr
!= NULL
&& attr
->group_tag
!= IPP_TAG_PRINTER
)
946 * Pull the needed attributes from this job...
953 while (attr
!= NULL
&& attr
->group_tag
== IPP_TAG_PRINTER
)
955 if (!strcmp(attr
->name
, "printer-name") &&
956 attr
->value_tag
== IPP_TAG_NAME
)
957 printer
= attr
->values
[0].string
.text
;
959 if (!strcmp(attr
->name
, "printer-uri-supported") &&
960 attr
->value_tag
== IPP_TAG_URI
)
961 printer_uri
= attr
->values
[0].string
.text
;
963 if (!strcmp(attr
->name
, "member-names") &&
964 attr
->value_tag
== IPP_TAG_NAME
)
971 * If this is a remote class, grab the class info from the
976 if (members
== NULL
&& printer_uri
!= NULL
)
978 httpSeparateURI(HTTP_URI_CODING_ALL
, printer_uri
, method
, sizeof(method
),
979 username
, sizeof(username
), server
, sizeof(server
),
980 &port
, resource
, sizeof(resource
));
982 if (!_cups_strcasecmp(server
, cupsServer()))
983 http2
= CUPS_HTTP_DEFAULT
;
985 http2
= httpConnectEncrypt(server
, port
, cupsEncryption());
988 * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
989 * following attributes:
992 * attributes-natural-language
994 * requested-attributes
997 request
= ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES
);
999 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
,
1000 "printer-uri", NULL
, printer_uri
);
1002 ippAddStrings(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
,
1003 "requested-attributes",
1004 sizeof(cattrs
) / sizeof(cattrs
[0]),
1007 if ((response2
= cupsDoRequest(http2
, request
, "/")) != NULL
)
1008 members
= ippFindAttribute(response2
, "member-names", IPP_TAG_NAME
);
1015 * See if we have everything needed...
1018 if (printer
== NULL
)
1021 ippDelete(response2
);
1030 * Display the printer entry if needed...
1033 if (match_list(dests
, printer
))
1035 _cupsLangPrintf(stdout
, _("members of class %s:"), printer
);
1039 for (i
= 0; i
< members
->num_values
; i
++)
1040 _cupsLangPrintf(stdout
, "\t%s", members
->values
[i
].string
.text
);
1043 _cupsLangPuts(stdout
, "\tunknown");
1047 ippDelete(response2
);
1053 ippDelete(response
);
1061 * 'show_default()' - Show default destination.
1065 show_default(cups_dest_t
*dest
) /* I - Default destination */
1067 const char *printer
, /* Printer name */
1068 *val
; /* Environment variable name */
1074 _cupsLangPrintf(stdout
, _("system default destination: %s/%s"),
1075 dest
->name
, dest
->instance
);
1077 _cupsLangPrintf(stdout
, _("system default destination: %s"),
1084 if ((printer
= getenv("LPDEST")) == NULL
)
1086 if ((printer
= getenv("PRINTER")) != NULL
)
1088 if (!strcmp(printer
, "lp"))
1098 _cupsLangPrintf(stdout
,
1099 _("lpstat: error - %s environment variable names "
1100 "non-existent destination \"%s\"."),
1103 _cupsLangPuts(stdout
, _("no system default destination"));
1109 * 'show_devices()' - Show printer devices.
1112 static int /* O - 0 on success, 1 on fail */
1113 show_devices(const char *printers
, /* I - Destinations */
1114 int num_dests
, /* I - Number of user-defined dests */
1115 cups_dest_t
*dests
) /* I - User-defined destinations */
1117 int i
; /* Looping var */
1118 ipp_t
*request
, /* IPP Request */
1119 *response
; /* IPP Response */
1120 ipp_attribute_t
*attr
; /* Current attribute */
1121 const char *printer
, /* Printer name */
1122 *uri
, /* Printer URI */
1123 *device
; /* Printer device URI */
1124 static const char *pattrs
[] = /* Attributes we need for printers... */
1127 "printer-uri-supported",
1132 if (printers
!= NULL
&& !strcmp(printers
, "all"))
1136 * Build a CUPS_GET_PRINTERS request, which requires the following
1139 * attributes-charset
1140 * attributes-natural-language
1141 * requested-attributes
1142 * requesting-user-name
1145 request
= ippNewRequest(CUPS_GET_PRINTERS
);
1147 ippAddStrings(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
,
1148 "requested-attributes", sizeof(pattrs
) / sizeof(pattrs
[0]),
1151 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "requesting-user-name",
1155 * Do the request and get back a response...
1158 response
= cupsDoRequest(CUPS_HTTP_DEFAULT
, request
, "/");
1160 if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST
||
1161 cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED
)
1163 _cupsLangPrintf(stderr
,
1164 _("%s: Error - add '/version=1.1' to server name."),
1166 ippDelete(response
);
1169 else if (cupsLastError() > IPP_STATUS_OK_CONFLICTING
)
1171 _cupsLangPrintf(stderr
, "lpstat: %s", cupsLastErrorString());
1172 ippDelete(response
);
1179 * Loop through the printers returned in the list and display
1183 for (attr
= response
->attrs
; attr
!= NULL
; attr
= attr
->next
)
1186 * Skip leading attributes until we hit a job...
1189 while (attr
!= NULL
&& attr
->group_tag
!= IPP_TAG_PRINTER
)
1196 * Pull the needed attributes from this job...
1203 while (attr
!= NULL
&& attr
->group_tag
== IPP_TAG_PRINTER
)
1205 if (!strcmp(attr
->name
, "printer-name") &&
1206 attr
->value_tag
== IPP_TAG_NAME
)
1207 printer
= attr
->values
[0].string
.text
;
1209 if (!strcmp(attr
->name
, "printer-uri-supported") &&
1210 attr
->value_tag
== IPP_TAG_URI
)
1211 uri
= attr
->values
[0].string
.text
;
1213 if (!strcmp(attr
->name
, "device-uri") &&
1214 attr
->value_tag
== IPP_TAG_URI
)
1215 device
= attr
->values
[0].string
.text
;
1221 * See if we have everything needed...
1224 if (printer
== NULL
)
1233 * Display the printer entry if needed...
1236 if (match_list(printers
, printer
))
1239 _cupsLangPrintf(stdout
, _("device for %s: %s"),
1241 else if (!strncmp(device
, "file:", 5))
1242 _cupsLangPrintf(stdout
, _("device for %s: %s"),
1243 printer
, device
+ 5);
1245 _cupsLangPrintf(stdout
, _("device for %s: %s"),
1248 for (i
= 0; i
< num_dests
; i
++)
1250 if (!_cups_strcasecmp(printer
, dests
[i
].name
) && dests
[i
].instance
)
1253 _cupsLangPrintf(stdout
, _("device for %s/%s: %s"),
1254 printer
, dests
[i
].instance
, uri
);
1255 else if (!strncmp(device
, "file:", 5))
1256 _cupsLangPrintf(stdout
, _("device for %s/%s: %s"),
1257 printer
, dests
[i
].instance
, device
+ 5);
1259 _cupsLangPrintf(stdout
, _("device for %s/%s: %s"),
1260 printer
, dests
[i
].instance
, device
);
1269 ippDelete(response
);
1277 * 'show_jobs()' - Show active print jobs.
1280 static int /* O - 0 on success, 1 on fail */
1281 show_jobs(const char *dests
, /* I - Destinations */
1282 const char *users
, /* I - Users */
1283 int long_status
, /* I - Show long status? */
1284 int ranking
, /* I - Show job ranking? */
1285 const char *which
) /* I - Show which jobs? */
1287 int i
; /* Looping var */
1288 ipp_t
*request
, /* IPP Request */
1289 *response
; /* IPP Response */
1290 ipp_attribute_t
*attr
, /* Current attribute */
1291 *reasons
; /* Job state reasons attribute */
1292 const char *dest
, /* Pointer into job-printer-uri */
1293 *username
, /* Pointer to job-originating-user-name */
1294 *message
, /* Pointer to job-printer-state-message */
1295 *time_at
; /* time-at-xxx attribute name to use */
1296 int rank
, /* Rank in queue */
1298 size
; /* job-k-octets */
1299 time_t jobtime
; /* time-at-creation */
1300 char temp
[255], /* Temporary buffer */
1301 date
[255]; /* Date buffer */
1302 static const char *jattrs
[] = /* Attributes we need for jobs... */
1307 "job-originating-user-name",
1308 "job-printer-state-message",
1310 "job-state-reasons",
1316 if (dests
!= NULL
&& !strcmp(dests
, "all"))
1320 * Build a IPP_GET_JOBS request, which requires the following
1323 * attributes-charset
1324 * attributes-natural-language
1326 * requested-attributes
1327 * requesting-user-name
1331 request
= ippNewRequest(IPP_GET_JOBS
);
1333 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
1334 NULL
, "ipp://localhost/");
1336 ippAddStrings(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
,
1337 "requested-attributes", sizeof(jattrs
) / sizeof(jattrs
[0]),
1340 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "requesting-user-name",
1343 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
, "which-jobs",
1347 * Do the request and get back a response...
1350 response
= cupsDoRequest(CUPS_HTTP_DEFAULT
, request
, "/");
1352 if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST
||
1353 cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED
)
1355 _cupsLangPrintf(stderr
,
1356 _("%s: Error - add '/version=1.1' to server name."),
1358 ippDelete(response
);
1361 else if (cupsLastError() > IPP_STATUS_OK_CONFLICTING
)
1363 _cupsLangPrintf(stderr
, "lpstat: %s", cupsLastErrorString());
1364 ippDelete(response
);
1371 * Loop through the job list and display them...
1374 if (!strcmp(which
, "aborted") ||
1375 !strcmp(which
, "canceled") ||
1376 !strcmp(which
, "completed"))
1377 time_at
= "time-at-completed";
1379 time_at
= "time-at-creation";
1383 for (attr
= response
->attrs
; attr
!= NULL
; attr
= attr
->next
)
1386 * Skip leading attributes until we hit a job...
1389 while (attr
!= NULL
&& attr
->group_tag
!= IPP_TAG_JOB
)
1396 * Pull the needed attributes from this job...
1407 while (attr
!= NULL
&& attr
->group_tag
== IPP_TAG_JOB
)
1409 if (!strcmp(attr
->name
, "job-id") &&
1410 attr
->value_tag
== IPP_TAG_INTEGER
)
1411 jobid
= attr
->values
[0].integer
;
1412 else if (!strcmp(attr
->name
, "job-k-octets") &&
1413 attr
->value_tag
== IPP_TAG_INTEGER
)
1414 size
= attr
->values
[0].integer
;
1415 else if (!strcmp(attr
->name
, time_at
) && attr
->value_tag
== IPP_TAG_INTEGER
)
1416 jobtime
= attr
->values
[0].integer
;
1417 else if (!strcmp(attr
->name
, "job-printer-state-message") &&
1418 attr
->value_tag
== IPP_TAG_TEXT
)
1419 message
= attr
->values
[0].string
.text
;
1420 else if (!strcmp(attr
->name
, "job-printer-uri") &&
1421 attr
->value_tag
== IPP_TAG_URI
)
1423 if ((dest
= strrchr(attr
->values
[0].string
.text
, '/')) != NULL
)
1426 else if (!strcmp(attr
->name
, "job-originating-user-name") &&
1427 attr
->value_tag
== IPP_TAG_NAME
)
1428 username
= attr
->values
[0].string
.text
;
1429 else if (!strcmp(attr
->name
, "job-state-reasons") &&
1430 attr
->value_tag
== IPP_TAG_KEYWORD
)
1437 * See if we have everything needed...
1440 if (dest
== NULL
|| jobid
== 0)
1449 * Display the job...
1454 if (match_list(dests
, dest
) && match_list(users
, username
))
1456 snprintf(temp
, sizeof(temp
), "%s-%d", dest
, jobid
);
1458 _cupsStrDate(date
, sizeof(date
), jobtime
);
1461 _cupsLangPrintf(stdout
, "%3d %-21s %-13s %8.0f %s",
1462 rank
, temp
, username
? username
: "unknown",
1463 1024.0 * size
, date
);
1465 _cupsLangPrintf(stdout
, "%-23s %-13s %8.0f %s",
1466 temp
, username
? username
: "unknown",
1467 1024.0 * size
, date
);
1471 _cupsLangPrintf(stdout
, _("\tStatus: %s"), message
);
1475 char alerts
[1024], /* Alerts string */
1476 *aptr
; /* Pointer into alerts string */
1478 for (i
= 0, aptr
= alerts
; i
< reasons
->num_values
; i
++)
1481 snprintf(aptr
, sizeof(alerts
) - (size_t)(aptr
- alerts
), " %s", reasons
->values
[i
].string
.text
);
1483 strlcpy(alerts
, reasons
->values
[i
].string
.text
, sizeof(alerts
));
1485 aptr
+= strlen(aptr
);
1488 _cupsLangPrintf(stdout
, _("\tAlerts: %s"), alerts
);
1491 _cupsLangPrintf(stdout
, _("\tqueued for %s"), dest
);
1499 ippDelete(response
);
1507 * 'show_printers()' - Show printers.
1510 static int /* O - 0 on success, 1 on fail */
1511 show_printers(const char *printers
, /* I - Destinations */
1512 int num_dests
, /* I - Number of user-defined dests */
1513 cups_dest_t
*dests
, /* I - User-defined destinations */
1514 int long_status
) /* I - Show long status? */
1516 int i
, j
; /* Looping vars */
1517 ipp_t
*request
, /* IPP Request */
1518 *response
, /* IPP Response */
1519 *jobs
; /* IPP Get Jobs response */
1520 ipp_attribute_t
*attr
, /* Current attribute */
1521 *jobattr
, /* Job ID attribute */
1522 *reasons
; /* Job state reasons attribute */
1523 const char *printer
, /* Printer name */
1524 *message
, /* Printer state message */
1525 *description
, /* Description of printer */
1526 *location
, /* Location of printer */
1527 *make_model
, /* Make and model of printer */
1528 *uri
; /* URI of printer */
1529 ipp_attribute_t
*allowed
, /* requesting-user-name-allowed */
1530 *denied
; /* requestint-user-name-denied */
1531 ipp_pstate_t pstate
; /* Printer state */
1532 cups_ptype_t ptype
; /* Printer type */
1533 time_t ptime
; /* Printer state time */
1534 int jobid
; /* Job ID of current job */
1535 char printer_uri
[HTTP_MAX_URI
],
1537 printer_state_time
[255];/* Printer state time */
1538 _cups_globals_t
*cg
= _cupsGlobals(); /* Global data */
1539 static const char *pattrs
[] = /* Attributes we need for printers... */
1543 "printer-state-message",
1544 "printer-state-reasons",
1545 "printer-state-change-time",
1549 "printer-make-and-model",
1550 "printer-uri-supported",
1551 "requesting-user-name-allowed",
1552 "requesting-user-name-denied"
1554 static const char *jattrs
[] = /* Attributes we need for jobs... */
1561 if (printers
!= NULL
&& !strcmp(printers
, "all"))
1565 * Build a CUPS_GET_PRINTERS request, which requires the following
1568 * attributes-charset
1569 * attributes-natural-language
1570 * requested-attributes
1571 * requesting-user-name
1574 request
= ippNewRequest(CUPS_GET_PRINTERS
);
1576 ippAddStrings(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
,
1577 "requested-attributes", sizeof(pattrs
) / sizeof(pattrs
[0]),
1580 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "requesting-user-name",
1584 * Do the request and get back a response...
1587 response
= cupsDoRequest(CUPS_HTTP_DEFAULT
, request
, "/");
1589 if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST
||
1590 cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED
)
1592 _cupsLangPrintf(stderr
,
1593 _("%s: Error - add '/version=1.1' to server name."),
1595 ippDelete(response
);
1598 else if (cupsLastError() > IPP_STATUS_OK_CONFLICTING
)
1600 _cupsLangPrintf(stderr
, "lpstat: %s", cupsLastErrorString());
1601 ippDelete(response
);
1608 * Loop through the printers returned in the list and display
1612 for (attr
= response
->attrs
; attr
!= NULL
; attr
= attr
->next
)
1615 * Skip leading attributes until we hit a job...
1618 while (attr
!= NULL
&& attr
->group_tag
!= IPP_TAG_PRINTER
)
1625 * Pull the needed attributes from this job...
1630 ptype
= CUPS_PRINTER_LOCAL
;
1631 pstate
= IPP_PRINTER_IDLE
;
1642 while (attr
!= NULL
&& attr
->group_tag
== IPP_TAG_PRINTER
)
1644 if (!strcmp(attr
->name
, "printer-name") &&
1645 attr
->value_tag
== IPP_TAG_NAME
)
1646 printer
= attr
->values
[0].string
.text
;
1647 else if (!strcmp(attr
->name
, "printer-state") &&
1648 attr
->value_tag
== IPP_TAG_ENUM
)
1649 pstate
= (ipp_pstate_t
)attr
->values
[0].integer
;
1650 else if (!strcmp(attr
->name
, "printer-type") &&
1651 attr
->value_tag
== IPP_TAG_ENUM
)
1652 ptype
= (cups_ptype_t
)attr
->values
[0].integer
;
1653 else if (!strcmp(attr
->name
, "printer-state-message") &&
1654 attr
->value_tag
== IPP_TAG_TEXT
)
1655 message
= attr
->values
[0].string
.text
;
1656 else if (!strcmp(attr
->name
, "printer-state-change-time") &&
1657 attr
->value_tag
== IPP_TAG_INTEGER
)
1658 ptime
= (time_t)attr
->values
[0].integer
;
1659 else if (!strcmp(attr
->name
, "printer-info") &&
1660 attr
->value_tag
== IPP_TAG_TEXT
)
1661 description
= attr
->values
[0].string
.text
;
1662 else if (!strcmp(attr
->name
, "printer-location") &&
1663 attr
->value_tag
== IPP_TAG_TEXT
)
1664 location
= attr
->values
[0].string
.text
;
1665 else if (!strcmp(attr
->name
, "printer-make-and-model") &&
1666 attr
->value_tag
== IPP_TAG_TEXT
)
1667 make_model
= attr
->values
[0].string
.text
;
1668 else if (!strcmp(attr
->name
, "printer-uri-supported") &&
1669 attr
->value_tag
== IPP_TAG_URI
)
1670 uri
= attr
->values
[0].string
.text
;
1671 else if (!strcmp(attr
->name
, "printer-state-reasons") &&
1672 attr
->value_tag
== IPP_TAG_KEYWORD
)
1674 else if (!strcmp(attr
->name
, "requesting-user-name-allowed") &&
1675 attr
->value_tag
== IPP_TAG_NAME
)
1677 else if (!strcmp(attr
->name
, "requesting-user-name-denied") &&
1678 attr
->value_tag
== IPP_TAG_NAME
)
1685 * See if we have everything needed...
1688 if (printer
== NULL
)
1697 * Display the printer entry if needed...
1700 if (match_list(printers
, printer
))
1703 * If the printer state is "IPP_PRINTER_PROCESSING", then grab the
1704 * current job for the printer.
1707 if (pstate
== IPP_PRINTER_PROCESSING
)
1710 * Build an IPP_GET_JOBS request, which requires the following
1713 * attributes-charset
1714 * attributes-natural-language
1717 * requested-attributes
1720 request
= ippNewRequest(IPP_GET_JOBS
);
1722 request
->request
.op
.operation_id
= IPP_GET_JOBS
;
1723 request
->request
.op
.request_id
= 1;
1725 ippAddStrings(request
, IPP_TAG_OPERATION
, IPP_TAG_KEYWORD
,
1726 "requested-attributes",
1727 sizeof(jattrs
) / sizeof(jattrs
[0]), NULL
, jattrs
);
1729 httpAssembleURIf(HTTP_URI_CODING_ALL
, printer_uri
, sizeof(printer_uri
),
1730 "ipp", NULL
, "localhost", 0, "/printers/%s", printer
);
1731 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
,
1732 "printer-uri", NULL
, printer_uri
);
1734 if ((jobs
= cupsDoRequest(CUPS_HTTP_DEFAULT
, request
, "/")) != NULL
)
1737 * Get the current active job on this queue...
1740 ipp_jstate_t jobstate
= IPP_JOB_PENDING
;
1743 for (jobattr
= jobs
->attrs
; jobattr
; jobattr
= jobattr
->next
)
1747 if (jobstate
== IPP_JOB_PROCESSING
)
1753 if (!strcmp(jobattr
->name
, "job-id") &&
1754 jobattr
->value_tag
== IPP_TAG_INTEGER
)
1755 jobid
= jobattr
->values
[0].integer
;
1756 else if (!strcmp(jobattr
->name
, "job-state") &&
1757 jobattr
->value_tag
== IPP_TAG_ENUM
)
1758 jobstate
= (ipp_jstate_t
)jobattr
->values
[0].integer
;
1761 if (jobstate
!= IPP_JOB_PROCESSING
)
1772 _cupsStrDate(printer_state_time
, sizeof(printer_state_time
), ptime
);
1776 case IPP_PRINTER_IDLE
:
1777 if (ippContainsString(reasons
, "hold-new-jobs"))
1778 _cupsLangPrintf(stdout
, _("printer %s is holding new jobs. enabled since %s"), printer
, printer_state_time
);
1780 _cupsLangPrintf(stdout
, _("printer %s is idle. enabled since %s"), printer
, printer_state_time
);
1782 case IPP_PRINTER_PROCESSING
:
1783 _cupsLangPrintf(stdout
, _("printer %s now printing %s-%d. enabled since %s"), printer
, printer
, jobid
, printer_state_time
);
1785 case IPP_PRINTER_STOPPED
:
1786 _cupsLangPrintf(stdout
, _("printer %s disabled since %s -"), printer
, printer_state_time
);
1790 if ((message
&& *message
) || pstate
== IPP_PRINTER_STOPPED
)
1792 if (!message
|| !*message
)
1793 _cupsLangPuts(stdout
, _("\treason unknown"));
1795 _cupsLangPrintf(stdout
, "\t%s", message
);
1798 if (long_status
> 1)
1800 _cupsLangPuts(stdout
, _("\tForm mounted:"));
1801 _cupsLangPuts(stdout
, _("\tContent types: any"));
1802 _cupsLangPuts(stdout
, _("\tPrinter types: unknown"));
1807 _cupsLangPrintf(stdout
, _("\tDescription: %s"),
1808 description
? description
: "");
1812 char alerts
[1024], /* Alerts string */
1813 *aptr
; /* Pointer into alerts string */
1815 for (i
= 0, aptr
= alerts
; i
< reasons
->num_values
; i
++)
1818 snprintf(aptr
, sizeof(alerts
) - (size_t)(aptr
- alerts
), " %s", reasons
->values
[i
].string
.text
);
1820 strlcpy(alerts
, reasons
->values
[i
].string
.text
, sizeof(alerts
));
1822 aptr
+= strlen(aptr
);
1825 _cupsLangPrintf(stdout
, _("\tAlerts: %s"), alerts
);
1828 if (long_status
> 1)
1830 _cupsLangPrintf(stdout
, _("\tLocation: %s"),
1831 location
? location
: "");
1833 if (ptype
& CUPS_PRINTER_REMOTE
)
1835 _cupsLangPuts(stdout
, _("\tConnection: remote"));
1837 if (make_model
&& !strstr(make_model
, "System V Printer") &&
1838 !strstr(make_model
, "Raw Printer") && uri
)
1839 _cupsLangPrintf(stdout
, _("\tInterface: %s.ppd"),
1844 _cupsLangPuts(stdout
, _("\tConnection: direct"));
1846 if (make_model
&& !strstr(make_model
, "Raw Printer"))
1847 _cupsLangPrintf(stdout
,
1848 _("\tInterface: %s/ppd/%s.ppd"),
1849 cg
->cups_serverroot
, printer
);
1851 _cupsLangPuts(stdout
, _("\tOn fault: no alert"));
1852 _cupsLangPuts(stdout
, _("\tAfter fault: continue"));
1853 /* TODO update to use printer-error-policy */
1856 _cupsLangPuts(stdout
, _("\tUsers allowed:"));
1857 for (j
= 0; j
< allowed
->num_values
; j
++)
1858 _cupsLangPrintf(stdout
, "\t\t%s",
1859 allowed
->values
[j
].string
.text
);
1863 _cupsLangPuts(stdout
, _("\tUsers denied:"));
1864 for (j
= 0; j
< denied
->num_values
; j
++)
1865 _cupsLangPrintf(stdout
, "\t\t%s",
1866 denied
->values
[j
].string
.text
);
1870 _cupsLangPuts(stdout
, _("\tUsers allowed:"));
1871 _cupsLangPuts(stdout
, _("\t\t(all)"));
1873 _cupsLangPuts(stdout
, _("\tForms allowed:"));
1874 _cupsLangPuts(stdout
, _("\t\t(none)"));
1875 _cupsLangPuts(stdout
, _("\tBanner required"));
1876 _cupsLangPuts(stdout
, _("\tCharset sets:"));
1877 _cupsLangPuts(stdout
, _("\t\t(none)"));
1878 _cupsLangPuts(stdout
, _("\tDefault pitch:"));
1879 _cupsLangPuts(stdout
, _("\tDefault page size:"));
1880 _cupsLangPuts(stdout
, _("\tDefault port settings:"));
1883 for (i
= 0; i
< num_dests
; i
++)
1884 if (!_cups_strcasecmp(printer
, dests
[i
].name
) && dests
[i
].instance
)
1888 case IPP_PRINTER_IDLE
:
1889 _cupsLangPrintf(stdout
,
1890 _("printer %s/%s is idle. "
1891 "enabled since %s"),
1892 printer
, dests
[i
].instance
,
1893 printer_state_time
);
1895 case IPP_PRINTER_PROCESSING
:
1896 _cupsLangPrintf(stdout
,
1897 _("printer %s/%s now printing %s-%d. "
1898 "enabled since %s"),
1899 printer
, dests
[i
].instance
, printer
, jobid
,
1900 printer_state_time
);
1902 case IPP_PRINTER_STOPPED
:
1903 _cupsLangPrintf(stdout
,
1904 _("printer %s/%s disabled since %s -"),
1905 printer
, dests
[i
].instance
,
1906 printer_state_time
);
1910 if ((message
&& *message
) || pstate
== IPP_PRINTER_STOPPED
)
1912 if (!message
|| !*message
)
1913 _cupsLangPuts(stdout
, _("\treason unknown"));
1915 _cupsLangPrintf(stdout
, "\t%s", message
);
1918 if (long_status
> 1)
1920 _cupsLangPuts(stdout
, _("\tForm mounted:"));
1921 _cupsLangPuts(stdout
, _("\tContent types: any"));
1922 _cupsLangPuts(stdout
, _("\tPrinter types: unknown"));
1927 _cupsLangPrintf(stdout
, _("\tDescription: %s"),
1928 description
? description
: "");
1932 char alerts
[1024], /* Alerts string */
1933 *aptr
; /* Pointer into alerts string */
1935 for (i
= 0, aptr
= alerts
; i
< reasons
->num_values
; i
++)
1938 snprintf(aptr
, sizeof(alerts
) - (size_t)(aptr
- alerts
), " %s", reasons
->values
[i
].string
.text
);
1940 strlcpy(alerts
, reasons
->values
[i
].string
.text
, sizeof(alerts
));
1942 aptr
+= strlen(aptr
);
1945 _cupsLangPrintf(stdout
, _("\tAlerts: %s"), alerts
);
1948 if (long_status
> 1)
1950 _cupsLangPrintf(stdout
, _("\tLocation: %s"),
1951 location
? location
: "");
1953 if (ptype
& CUPS_PRINTER_REMOTE
)
1955 _cupsLangPuts(stdout
, _("\tConnection: remote"));
1957 if (make_model
&& !strstr(make_model
, "System V Printer") &&
1958 !strstr(make_model
, "Raw Printer") && uri
)
1959 _cupsLangPrintf(stdout
, _("\tInterface: %s.ppd"), uri
);
1963 _cupsLangPuts(stdout
, _("\tConnection: direct"));
1965 if (make_model
&& !strstr(make_model
, "Raw Printer"))
1966 _cupsLangPrintf(stdout
,
1967 _("\tInterface: %s/ppd/%s.ppd"),
1968 cg
->cups_serverroot
, printer
);
1970 _cupsLangPuts(stdout
, _("\tOn fault: no alert"));
1971 _cupsLangPuts(stdout
, _("\tAfter fault: continue"));
1972 /* TODO update to use printer-error-policy */
1975 _cupsLangPuts(stdout
, _("\tUsers allowed:"));
1976 for (j
= 0; j
< allowed
->num_values
; j
++)
1977 _cupsLangPrintf(stdout
, "\t\t%s",
1978 allowed
->values
[j
].string
.text
);
1982 _cupsLangPuts(stdout
, _("\tUsers denied:"));
1983 for (j
= 0; j
< denied
->num_values
; j
++)
1984 _cupsLangPrintf(stdout
, "\t\t%s",
1985 denied
->values
[j
].string
.text
);
1989 _cupsLangPuts(stdout
, _("\tUsers allowed:"));
1990 _cupsLangPuts(stdout
, _("\t\t(all)"));
1992 _cupsLangPuts(stdout
, _("\tForms allowed:"));
1993 _cupsLangPuts(stdout
, _("\t\t(none)"));
1994 _cupsLangPuts(stdout
, _("\tBanner required"));
1995 _cupsLangPuts(stdout
, _("\tCharset sets:"));
1996 _cupsLangPuts(stdout
, _("\t\t(none)"));
1997 _cupsLangPuts(stdout
, _("\tDefault pitch:"));
1998 _cupsLangPuts(stdout
, _("\tDefault page size:"));
1999 _cupsLangPuts(stdout
, _("\tDefault port settings:"));
2008 ippDelete(response
);
2016 * 'show_scheduler()' - Show scheduler status.
2020 show_scheduler(void)
2022 http_t
*http
; /* Connection to server */
2025 if ((http
= httpConnectEncrypt(cupsServer(), ippPort(),
2026 cupsEncryption())) != NULL
)
2028 _cupsLangPuts(stdout
, _("scheduler is running"));
2032 _cupsLangPuts(stdout
, _("scheduler is not running"));
2037 * 'usage()' - Show program usage and exit.
2043 _cupsLangPuts(stdout
, _("Usage: lpstat [options]"));
2044 _cupsLangPuts(stdout
, _("Options:"));
2045 _cupsLangPuts(stdout
, _("-E Encrypt the connection to the server"));
2046 _cupsLangPuts(stdout
, _("-h server[:port] Connect to the named server and port"));
2047 _cupsLangPuts(stdout
, _("-l Show verbose (long) output"));
2048 _cupsLangPuts(stdout
, _("-U username Specify the username to use for authentication"));
2050 _cupsLangPuts(stdout
, _("-H Show the default server and port"));
2051 _cupsLangPuts(stdout
, _("-W completed Show completed jobs"));
2052 _cupsLangPuts(stdout
, _("-W not-completed Show pending jobs"));
2053 _cupsLangPuts(stdout
, _("-a [destination(s)] Show the accepting state of destinations"));
2054 _cupsLangPuts(stdout
, _("-c [class(es)] Show classes and their member printers"));
2055 _cupsLangPuts(stdout
, _("-d Show the default destination"));
2056 _cupsLangPuts(stdout
, _("-e Show available destinations on the network"));
2057 _cupsLangPuts(stdout
, _("-o [destination(s)] Show jobs"));
2058 _cupsLangPuts(stdout
, _("-p [printer(s)] Show the processing state of destinations"));
2059 _cupsLangPuts(stdout
, _("-r Show whether the CUPS server is running"));
2060 _cupsLangPuts(stdout
, _("-R Show the ranking of jobs"));
2061 _cupsLangPuts(stdout
, _("-s Show a status summary"));
2062 _cupsLangPuts(stdout
, _("-t Show all status information"));
2063 _cupsLangPuts(stdout
, _("-u [user(s)] Show jobs queued by the current or specified users"));
2064 _cupsLangPuts(stdout
, _("-v [printer(s)] Show the devices for each destination"));