|
|
/*
|
|
|
* "lpq" command for CUPS.
|
|
|
*
|
|
|
* Copyright © 2007-2018 by Apple Inc.
|
|
|
* Copyright © 1997-2006 by Easy Software Products.
|
|
|
*
|
|
|
* Licensed under Apache License v2.0. See the file "LICENSE" for more
|
|
|
* information.
|
|
|
*/
|
|
|
|
|
|
/*
|
|
|
* Include necessary headers...
|
|
|
*/
|
|
|
|
|
|
#include <cups/cups-private.h>
|
|
|
|
|
|
|
|
|
/*
|
|
|
* Local functions...
|
|
|
*/
|
|
|
|
|
|
static http_t *connect_server(const char *, http_t *);
|
|
|
static int show_jobs(const char *, http_t *, const char *,
|
|
|
const char *, const int, const int);
|
|
|
static void show_printer(const char *, http_t *, const char *);
|
|
|
static void usage(void) _CUPS_NORETURN;
|
|
|
|
|
|
|
|
|
/*
|
|
|
* 'main()' - Parse options and commands.
|
|
|
*/
|
|
|
|
|
|
int
|
|
|
main(int argc, /* I - Number of command-line arguments */
|
|
|
char *argv[]) /* I - Command-line arguments */
|
|
|
{
|
|
|
int i; /* Looping var */
|
|
|
http_t *http; /* Connection to server */
|
|
|
const char *opt, /* Option pointer */
|
|
|
*dest, /* Desired printer */
|
|
|
*user, /* Desired user */
|
|
|
*val; /* Environment variable name */
|
|
|
char *instance; /* Printer instance */
|
|
|
int id, /* Desired job ID */
|
|
|
all, /* All printers */
|
|
|
interval, /* Reporting interval */
|
|
|
longstatus; /* Show file details */
|
|
|
cups_dest_t *named_dest; /* Named destination */
|
|
|
|
|
|
|
|
|
_cupsSetLocale(argv);
|
|
|
|
|
|
/*
|
|
|
* Check for command-line options...
|
|
|
*/
|
|
|
|
|
|
http = NULL;
|
|
|
dest = NULL;
|
|
|
user = NULL;
|
|
|
id = 0;
|
|
|
interval = 0;
|
|
|
longstatus = 0;
|
|
|
all = 0;
|
|
|
|
|
|
for (i = 1; i < argc; i ++)
|
|
|
{
|
|
|
if (argv[i][0] == '+')
|
|
|
{
|
|
|
interval = atoi(argv[i] + 1);
|
|
|
}
|
|
|
else if (!strcmp(argv[i], "--help"))
|
|
|
usage();
|
|
|
else if (argv[i][0] == '-')
|
|
|
{
|
|
|
for (opt = argv[i] + 1; *opt; opt ++)
|
|
|
{
|
|
|
switch (*opt)
|
|
|
{
|
|
|
case 'E' : /* Encrypt */
|
|
|
#ifdef HAVE_SSL
|
|
|
cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
|
|
|
|
|
|
if (http)
|
|
|
httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
|
|
|
#else
|
|
|
_cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]);
|
|
|
#endif /* HAVE_SSL */
|
|
|
break;
|
|
|
|
|
|
case 'U' : /* Username */
|
|
|
if (opt[1] != '\0')
|
|
|
{
|
|
|
cupsSetUser(opt + 1);
|
|
|
opt += strlen(opt) - 1;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
i ++;
|
|
|
if (i >= argc)
|
|
|
{
|
|
|
_cupsLangPrintf(stderr, _("%s: Error - expected username after \"-U\" option."), argv[0]);
|
|
|
return (1);
|
|
|
}
|
|
|
|
|
|
cupsSetUser(argv[i]);
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case 'P' : /* Printer */
|
|
|
if (opt[1] != '\0')
|
|
|
{
|
|
|
dest = opt + 1;
|
|
|
opt += strlen(opt) - 1;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
i ++;
|
|
|
|
|
|
if (i >= argc)
|
|
|
{
|
|
|
httpClose(http);
|
|
|
|
|
|
usage();
|
|
|
}
|
|
|
|
|
|
dest = argv[i];
|
|
|
}
|
|
|
|
|
|
if ((instance = strchr(dest, '/')) != NULL)
|
|
|
*instance++ = '\0';
|
|
|
|
|
|
http = connect_server(argv[0], http);
|
|
|
|
|
|
if ((named_dest = cupsGetNamedDest(http, dest, instance)) == NULL)
|
|
|
{
|
|
|
if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
|
|
|
cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED)
|
|
|
_cupsLangPrintf(stderr, _("%s: Error - add '/version=1.1' to server name."), argv[0]);
|
|
|
else if (instance)
|
|
|
_cupsLangPrintf(stderr, _("%s: Error - unknown destination \"%s/%s\"."), argv[0], dest, instance);
|
|
|
else
|
|
|
_cupsLangPrintf(stderr, _("%s: Unknown destination \"%s\"."), argv[0], dest);
|
|
|
|
|
|
return (1);
|
|
|
}
|
|
|
|
|
|
cupsFreeDests(1, named_dest);
|
|
|
break;
|
|
|
|
|
|
case 'a' : /* All printers */
|
|
|
all = 1;
|
|
|
break;
|
|
|
|
|
|
case 'h' : /* Connect to host */
|
|
|
if (http)
|
|
|
{
|
|
|
httpClose(http);
|
|
|
http = NULL;
|
|
|
}
|
|
|
|
|
|
if (opt[1] != '\0')
|
|
|
{
|
|
|
cupsSetServer(opt + 1);
|
|
|
opt += strlen(opt) - 1;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
i ++;
|
|
|
|
|
|
if (i >= argc)
|
|
|
{
|
|
|
_cupsLangPrintf(stderr, _("%s: Error - expected hostname after \"-h\" option."), argv[0]);
|
|
|
return (1);
|
|
|
}
|
|
|
else
|
|
|
cupsSetServer(argv[i]);
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case 'l' : /* Long status */
|
|
|
longstatus = 1;
|
|
|
break;
|
|
|
|
|
|
default :
|
|
|
httpClose(http);
|
|
|
|
|
|
usage();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else if (isdigit(argv[i][0] & 255))
|
|
|
{
|
|
|
id = atoi(argv[i]);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
user = argv[i];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
http = connect_server(argv[0], http);
|
|
|
|
|
|
if (dest == NULL && !all)
|
|
|
{
|
|
|
if ((named_dest = cupsGetNamedDest(http, NULL, NULL)) == NULL)
|
|
|
{
|
|
|
if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
|
|
|
cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED)
|
|
|
{
|
|
|
_cupsLangPrintf(stderr,
|
|
|
_("%s: Error - add '/version=1.1' to server name."),
|
|
|
argv[0]);
|
|
|
return (1);
|
|
|
}
|
|
|
|
|
|
val = NULL;
|
|
|
|
|
|
if ((dest = getenv("LPDEST")) == NULL)
|
|
|
{
|
|
|
if ((dest = getenv("PRINTER")) != NULL)
|
|
|
{
|
|
|
if (!strcmp(dest, "lp"))
|
|
|
dest = NULL;
|
|
|
else
|
|
|
val = "PRINTER";
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
val = "LPDEST";
|
|
|
|
|
|
if (dest && val)
|
|
|
_cupsLangPrintf(stderr,
|
|
|
_("%s: Error - %s environment variable names "
|
|
|
"non-existent destination \"%s\"."), argv[0], val,
|
|
|
dest);
|
|
|
else
|
|
|
_cupsLangPrintf(stderr,
|
|
|
_("%s: Error - no default destination available."),
|
|
|
argv[0]);
|
|
|
httpClose(http);
|
|
|
return (1);
|
|
|
}
|
|
|
|
|
|
dest = named_dest->name;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* Show the status in a loop...
|
|
|
*/
|
|
|
|
|
|
for (;;)
|
|
|
{
|
|
|
if (dest)
|
|
|
show_printer(argv[0], http, dest);
|
|
|
|
|
|
i = show_jobs(argv[0], http, dest, user, id, longstatus);
|
|
|
|
|
|
if (i && interval)
|
|
|
{
|
|
|
fflush(stdout);
|
|
|
sleep((unsigned)interval);
|
|
|
}
|
|
|
else
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* Close the connection to the server and return...
|
|
|
*/
|
|
|
|
|
|
httpClose(http);
|
|
|
|
|
|
return (0);
|
|
|
}
|
|
|
|
|
|
|
|
|
/*
|
|
|
* 'connect_server()' - Connect to the server as necessary...
|
|
|
*/
|
|
|
|
|
|
static http_t * /* O - New HTTP connection */
|
|
|
connect_server(const char *command, /* I - Command name */
|
|
|
http_t *http) /* I - Current HTTP connection */
|
|
|
{
|
|
|
if (!http)
|
|
|
{
|
|
|
http = httpConnectEncrypt(cupsServer(), ippPort(),
|
|
|
cupsEncryption());
|
|
|
|
|
|
if (http == NULL)
|
|
|
{
|
|
|
_cupsLangPrintf(stderr, _("%s: Unable to connect to server."), command);
|
|
|
exit(1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return (http);
|
|
|
}
|
|
|
|
|
|
|
|
|
/*
|
|
|
* 'show_jobs()' - Show jobs.
|
|
|
*/
|
|
|
|
|
|
static int /* O - Number of jobs in queue */
|
|
|
show_jobs(const char *command, /* I - Command name */
|
|
|
http_t *http, /* I - HTTP connection to server */
|
|
|
const char *dest, /* I - Destination */
|
|
|
const char *user, /* I - User */
|
|
|
const int id, /* I - Job ID */
|
|
|
const int longstatus) /* I - 1 if long report desired */
|
|
|
{
|
|
|
ipp_t *request, /* IPP Request */
|
|
|
*response; /* IPP Response */
|
|
|
ipp_attribute_t *attr; /* Current attribute */
|
|
|
const char *jobdest, /* Pointer into job-printer-uri */
|
|
|
*jobuser, /* Pointer to job-originating-user-name */
|
|
|
*jobname; /* Pointer to job-name */
|
|
|
ipp_jstate_t jobstate; /* job-state */
|
|
|
int jobid, /* job-id */
|
|
|
jobsize, /* job-k-octets */
|
|
|
jobcount, /* Number of jobs */
|
|
|
jobcopies, /* Number of copies */
|
|
|
rank; /* Rank of job */
|
|
|
char resource[1024]; /* Resource string */
|
|
|
char rankstr[255]; /* Rank string */
|
|
|
char namestr[1024]; /* Job name string */
|
|
|
static const char * const jobattrs[] =/* Job attributes we want to see */
|
|
|
{
|
|
|
"copies",
|
|
|
"job-id",
|
|
|
"job-k-octets",
|
|
|
"job-name",
|
|
|
"job-originating-user-name",
|
|
|
"job-printer-uri",
|
|
|
"job-priority",
|
|
|
"job-state"
|
|
|
};
|
|
|
static const char * const ranks[10] = /* Ranking strings */
|
|
|
{
|
|
|
"th",
|
|
|
"st",
|
|
|
"nd",
|
|
|
"rd",
|
|
|
"th",
|
|
|
"th",
|
|
|
"th",
|
|
|
"th",
|
|
|
"th",
|
|
|
"th"
|
|
|
};
|
|
|
|
|
|
|
|
|
if (http == NULL)
|
|
|
return (0);
|
|
|
|
|
|
/*
|
|
|
* Build an IPP_GET_JOBS or IPP_GET_JOB_ATTRIBUTES request, which requires
|
|
|
* the following attributes:
|
|
|
*
|
|
|
* attributes-charset
|
|
|
* attributes-natural-language
|
|
|
* job-uri or printer-uri
|
|
|
* requested-attributes
|
|
|
* requesting-user-name
|
|
|
*/
|
|
|
|
|
|
request = ippNewRequest(id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS);
|
|
|
|
|
|
if (id)
|
|
|
{
|
|
|
snprintf(resource, sizeof(resource), "ipp://localhost/jobs/%d", id);
|
|
|
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
|
|
|
NULL, resource);
|
|
|
}
|
|
|
else if (dest)
|
|
|
{
|
|
|
httpAssembleURIf(HTTP_URI_CODING_ALL, resource, sizeof(resource), "ipp",
|
|
|
NULL, "localhost", 0, "/printers/%s", dest);
|
|
|
|
|
|
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
|
|
|
NULL, resource);
|
|
|
}
|
|
|
else
|
|
|
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
|
|
|
NULL, "ipp://localhost/");
|
|
|
|
|
|
if (user)
|
|
|
{
|
|
|
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
|
|
|
"requesting-user-name", NULL, user);
|
|
|
ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1);
|
|
|
}
|
|
|
else
|
|
|
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
|
|
|
"requesting-user-name", NULL, cupsUser());
|
|
|
|
|
|
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
|
|
"requested-attributes",
|
|
|
(int)(sizeof(jobattrs) / sizeof(jobattrs[0])), NULL, jobattrs);
|
|
|
|
|
|
/*
|
|
|
* Do the request and get back a response...
|
|
|
*/
|
|
|
|
|
|
jobcount = 0;
|
|
|
|
|
|
if ((response = cupsDoRequest(http, request, "/")) != NULL)
|
|
|
{
|
|
|
if (response->request.status.status_code > IPP_OK_CONFLICT)
|
|
|
{
|
|
|
_cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString());
|
|
|
ippDelete(response);
|
|
|
return (0);
|
|
|
}
|
|
|
|
|
|
rank = 1;
|
|
|
|
|
|
/*
|
|
|
* Loop through the job list and display them...
|
|
|
*/
|
|
|
|
|
|
for (attr = response->attrs; attr != NULL; attr = attr->next)
|
|
|
{
|
|
|
/*
|
|
|
* Skip leading attributes until we hit a job...
|
|
|
*/
|
|
|
|
|
|
while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
|
|
|
attr = attr->next;
|
|
|
|
|
|
if (attr == NULL)
|
|
|
break;
|
|
|
|
|
|
/*
|
|
|
* Pull the needed attributes from this job...
|
|
|
*/
|
|
|
|
|
|
jobid = 0;
|
|
|
jobsize = 0;
|
|
|
jobstate = IPP_JOB_PENDING;
|
|
|
jobname = "unknown";
|
|
|
jobuser = "unknown";
|
|
|
jobdest = NULL;
|
|
|
jobcopies = 1;
|
|
|
|
|
|
while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
|
|
|
{
|
|
|
if (!strcmp(attr->name, "job-id") &&
|
|
|
attr->value_tag == IPP_TAG_INTEGER)
|
|
|
jobid = attr->values[0].integer;
|
|
|
|
|
|
if (!strcmp(attr->name, "job-k-octets") &&
|
|
|
attr->value_tag == IPP_TAG_INTEGER)
|
|
|
jobsize = attr->values[0].integer;
|
|
|
|
|
|
if (!strcmp(attr->name, "job-state") &&
|
|
|
attr->value_tag == IPP_TAG_ENUM)
|
|
|
jobstate = (ipp_jstate_t)attr->values[0].integer;
|
|
|
|
|
|
if (!strcmp(attr->name, "job-printer-uri") &&
|
|
|
attr->value_tag == IPP_TAG_URI)
|
|
|
if ((jobdest = strrchr(attr->values[0].string.text, '/')) != NULL)
|
|
|
jobdest ++;
|
|
|
|
|
|
if (!strcmp(attr->name, "job-originating-user-name") &&
|
|
|
attr->value_tag == IPP_TAG_NAME)
|
|
|
jobuser = attr->values[0].string.text;
|
|
|
|
|
|
if (!strcmp(attr->name, "job-name") &&
|
|
|
attr->value_tag == IPP_TAG_NAME)
|
|
|
jobname = attr->values[0].string.text;
|
|
|
|
|
|
if (!strcmp(attr->name, "copies") &&
|
|
|
attr->value_tag == IPP_TAG_INTEGER)
|
|
|
jobcopies = attr->values[0].integer;
|
|
|
|
|
|
attr = attr->next;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* See if we have everything needed...
|
|
|
*/
|
|
|
|
|
|
if (jobdest == NULL || jobid == 0)
|
|
|
{
|
|
|
if (attr == NULL)
|
|
|
break;
|
|
|
else
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
if (!longstatus && jobcount == 0)
|
|
|
_cupsLangPuts(stdout,
|
|
|
_("Rank Owner Job File(s)"
|
|
|
" Total Size"));
|
|
|
|
|
|
jobcount ++;
|
|
|
|
|
|
/*
|
|
|
* Display the job...
|
|
|
*/
|
|
|
|
|
|
if (jobstate == IPP_JOB_PROCESSING)
|
|
|
strlcpy(rankstr, "active", sizeof(rankstr));
|
|
|
else
|
|
|
{
|
|
|
/*
|
|
|
* Make the rank show the "correct" suffix for each number
|
|
|
* (11-13 are the only special cases, for English anyways...)
|
|
|
*/
|
|
|
|
|
|
if ((rank % 100) >= 11 && (rank % 100) <= 13)
|
|
|
snprintf(rankstr, sizeof(rankstr), "%dth", rank);
|
|
|
else
|
|
|
snprintf(rankstr, sizeof(rankstr), "%d%s", rank, ranks[rank % 10]);
|
|
|
|
|
|
rank ++;
|
|
|
}
|
|
|
|
|
|
if (longstatus)
|
|
|
{
|
|
|
_cupsLangPuts(stdout, "\n");
|
|
|
|
|
|
if (jobcopies > 1)
|
|
|
snprintf(namestr, sizeof(namestr), "%d copies of %s", jobcopies,
|
|
|
jobname);
|
|
|
else
|
|
|
strlcpy(namestr, jobname, sizeof(namestr));
|
|
|
|
|
|
_cupsLangPrintf(stdout, _("%s: %-33.33s [job %d localhost]"),
|
|
|
jobuser, rankstr, jobid);
|
|
|
_cupsLangPrintf(stdout, _(" %-39.39s %.0f bytes"),
|
|
|
namestr, 1024.0 * jobsize);
|
|
|
}
|
|
|
else
|
|
|
_cupsLangPrintf(stdout,
|
|
|
_("%-7s %-7.7s %-7d %-31.31s %.0f bytes"),
|
|
|
rankstr, jobuser, jobid, jobname, 1024.0 * jobsize);
|
|
|
|
|
|
if (attr == NULL)
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
ippDelete(response);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString());
|
|
|
return (0);
|
|
|
}
|
|
|
|
|
|
if (jobcount == 0)
|
|
|
_cupsLangPuts(stdout, _("no entries"));
|
|
|
|
|
|
return (jobcount);
|
|
|
}
|
|
|
|
|
|
|
|
|
/*
|
|
|
* 'show_printer()' - Show printer status.
|
|
|
*/
|
|
|
|
|
|
static void
|
|
|
show_printer(const char *command, /* I - Command name */
|
|
|
http_t *http, /* I - HTTP connection to server */
|
|
|
const char *dest) /* I - Destination */
|
|
|
{
|
|
|
ipp_t *request, /* IPP Request */
|
|
|
*response; /* IPP Response */
|
|
|
ipp_attribute_t *attr; /* Current attribute */
|
|
|
ipp_pstate_t state; /* Printer state */
|
|
|
char uri[HTTP_MAX_URI]; /* Printer URI */
|
|
|
|
|
|
|
|
|
if (http == NULL)
|
|
|
return;
|
|
|
|
|
|
/*
|
|
|
* Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
|
|
|
* attributes:
|
|
|
*
|
|
|
* attributes-charset
|
|
|
* attributes-natural-language
|
|
|
* printer-uri
|
|
|
*/
|
|
|
|
|
|
request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
|
|
|
|
|
|
httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
|
|
|
"localhost", 0, "/printers/%s", dest);
|
|
|
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
|
|
|
"printer-uri", NULL, uri);
|
|
|
|
|
|
/*
|
|
|
* Do the request and get back a response...
|
|
|
*/
|
|
|
|
|
|
if ((response = cupsDoRequest(http, request, "/")) != NULL)
|
|
|
{
|
|
|
if (response->request.status.status_code > IPP_OK_CONFLICT)
|
|
|
{
|
|
|
_cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString());
|
|
|
ippDelete(response);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
|
|
|
state = (ipp_pstate_t)attr->values[0].integer;
|
|
|
else
|
|
|
state = IPP_PRINTER_STOPPED;
|
|
|
|
|
|
switch (state)
|
|
|
{
|
|
|
case IPP_PRINTER_IDLE :
|
|
|
_cupsLangPrintf(stdout, _("%s is ready"), dest);
|
|
|
break;
|
|
|
case IPP_PRINTER_PROCESSING :
|
|
|
_cupsLangPrintf(stdout, _("%s is ready and printing"),
|
|
|
dest);
|
|
|
break;
|
|
|
case IPP_PRINTER_STOPPED :
|
|
|
_cupsLangPrintf(stdout, _("%s is not ready"), dest);
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
ippDelete(response);
|
|
|
}
|
|
|
else
|
|
|
_cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString());
|
|
|
}
|
|
|
|
|
|
|
|
|
/*
|
|
|
* 'usage()' - Show program usage.
|
|
|
*/
|
|
|
|
|
|
static void
|
|
|
usage(void)
|
|
|
{
|
|
|
_cupsLangPuts(stderr, _("Usage: lpq [options] [+interval]"));
|
|
|
_cupsLangPuts(stdout, _("Options:"));
|
|
|
_cupsLangPuts(stdout, _("-a Show jobs on all destinations"));
|
|
|
_cupsLangPuts(stdout, _("-E Encrypt the connection to the server"));
|
|
|
_cupsLangPuts(stdout, _("-h server[:port] Connect to the named server and port"));
|
|
|
_cupsLangPuts(stdout, _("-l Show verbose (long) output"));
|
|
|
_cupsLangPuts(stdout, _("-P destination Show status for the specified destination"));
|
|
|
_cupsLangPuts(stdout, _("-U username Specify the username to use for authentication"));
|
|
|
|
|
|
exit(1);
|
|
|
}
|