#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <cups/cups.h>
#include <cups/language.h>
#include <cups/debug.h>
#include <cups/string.h>
static int compare_strings(char *, char *, int);
static void do_command(http_t *, char *, char *);
static void show_help(char *);
static void show_status(http_t *, char *);
int
main(int argc,
char *argv[])
{
http_t *http;
char line[1024],
*params;
http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
if (argc > 1)
{
do_command(http, argv[1], argv[2]);
}
else
{
printf("lpc> ");
while (fgets(line, sizeof(line), stdin) != NULL)
{
line[strlen(line) - 1] = '\0';
while (isspace(line[0]))
strcpy(line, line + 1);
for (params = line; *params != '\0'; params ++)
if (isspace(*params))
break;
while (isspace(*params))
*params++ = '\0';
if (compare_strings(line, "quit", 1) == 0 ||
compare_strings(line, "exit", 2) == 0)
break;
if (*params == '\0')
do_command(http, line, NULL);
else
do_command(http, line, params);
printf("lpc> ");
}
}
httpClose(http);
return (0);
}
static int
compare_strings(char *s,
char *t,
int tmin)
{
int slen;
slen = strlen(s);
if (slen < tmin)
return (-1);
else
return (strncmp(s, t, slen));
}
static void
do_command(http_t *http,
char *command,
char *params)
{
if (compare_strings(command, "status", 4) == 0)
show_status(http, params);
else if (compare_strings(command, "help", 1) == 0 ||
strcmp(command, "?") == 0)
show_help(params);
else
printf("%s is not implemented by the CUPS version of lpc.\n", command);
}
static void
show_help(char *command)
{
if (command == NULL)
{
puts("Commands may be abbreviated. Commands are:");
puts("");
puts("exit help quit status ?");
}
else if (compare_strings(command, "help", 1) == 0 ||
strcmp(command, "?") == 0)
puts("help\t\tget help on commands");
else if (compare_strings(command, "status", 4) == 0)
puts("status\t\tshow status of daemon and queue");
else
puts("?Invalid help command unknown");
}
static void
show_status(http_t *http,
char *dests)
{
ipp_t *request,
*response,
*jobs;
ipp_attribute_t *attr,
*jattr;
cups_lang_t *language;
char *printer,
*device;
ipp_pstate_t pstate;
int accepting;
int jobcount;
char *dptr,
*ptr;
int match;
char printer_uri[HTTP_MAX_URI];
static const char *requested[] =
{
"printer-name",
"device-uri",
"printer-state",
"printer-is-accepting-jobs"
};
DEBUG_printf(("show_status(%08x, %08x)\n", http, dests));
if (http == NULL)
return;
request = ippNew();
request->request.op.operation_id = CUPS_GET_PRINTERS;
request->request.op.request_id = 1;
language = cupsLangDefault();
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
"requested-attributes", sizeof(requested) / sizeof(requested[0]),
NULL, requested);
if ((response = cupsDoRequest(http, request, "/printers/")) != NULL)
{
DEBUG_puts("show_status: request succeeded...");
for (attr = response->attrs; attr != NULL; attr = attr->next)
{
while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
attr = attr->next;
if (attr == NULL)
break;
printer = NULL;
device = "file:/dev/null";
pstate = IPP_PRINTER_IDLE;
jobcount = 0;
accepting = 1;
while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
{
if (strcmp(attr->name, "printer-name") == 0 &&
attr->value_tag == IPP_TAG_NAME)
printer = attr->values[0].string.text;
if (strcmp(attr->name, "device-uri") == 0 &&
attr->value_tag == IPP_TAG_URI)
device = attr->values[0].string.text;
if (strcmp(attr->name, "printer-state") == 0 &&
attr->value_tag == IPP_TAG_ENUM)
pstate = (ipp_pstate_t)attr->values[0].integer;
if (strcmp(attr->name, "printer-is-accepting-jobs") == 0 &&
attr->value_tag == IPP_TAG_BOOLEAN)
accepting = attr->values[0].boolean;
attr = attr->next;
}
if (printer == NULL)
{
if (attr == NULL)
break;
else
continue;
}
match = dests == NULL;
if (dests != NULL)
{
for (dptr = dests; *dptr != '\0';)
{
while (isspace(*dptr) || *dptr == ',')
dptr ++;
if (*dptr == '\0')
break;
for (ptr = printer;
*ptr != '\0' && *dptr != '\0' && *ptr == *dptr;
ptr ++, dptr ++);
if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' || isspace(*dptr)))
{
match = 1;
break;
}
while (!isspace(*dptr) && *dptr != '\0')
dptr ++;
while (isspace(*dptr) || *dptr == ',')
dptr ++;
if (*dptr == '\0')
break;
}
}
if (match)
{
if (pstate == IPP_PRINTER_PROCESSING)
{
request = ippNew();
request->request.op.operation_id = IPP_GET_JOBS;
request->request.op.request_id = 1;
language = cupsLangDefault();
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL,
cupsLangEncoding(language));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL,
language->language);
snprintf(printer_uri, sizeof(printer_uri),
"ipp://localhost/printers/%s", printer);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, printer_uri);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
"requested-attributes", NULL, "job-id");
if ((jobs = cupsDoRequest(http, request, "/jobs/")) != NULL)
{
for (jattr = jobs->attrs; jattr != NULL; jattr = jattr->next)
if (jattr->name && strcmp(jattr->name, "job-id") == 0)
jobcount ++;
ippDelete(jobs);
}
}
printf("%s:\n", printer);
if (strncmp(device, "file:", 5) == 0)
printf("\tprinter is on device \'%s\' speed -1\n", device + 5);
else
{
*strchr(device, ':') = '\0';
printf("\tprinter is on device \'%s\' speed -1\n", device);
}
printf("\tqueuing is %sabled\n", accepting ? "en" : "dis");
printf("\tprinting is %sabled\n",
pstate == IPP_PRINTER_STOPPED ? "dis" : "en");
if (jobcount == 0)
puts("\tno entries");
else
printf("\t%d entries\n", jobcount);
puts("\tdaemon present");
}
if (attr == NULL)
break;
}
ippDelete(response);
}
}