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