You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
269 lines
6.7 KiB
269 lines
6.7 KiB
/*
|
|
* Threaded test program for CUPS.
|
|
*
|
|
* Copyright © 2012-2019 by Apple Inc.
|
|
*
|
|
* Licensed under Apache License v2.0. See the file "LICENSE" for more
|
|
* information.
|
|
*/
|
|
|
|
/*
|
|
* Include necessary headers...
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <cups/cups.h>
|
|
#include <cups/thread-private.h>
|
|
|
|
|
|
/*
|
|
* Local functions...
|
|
*/
|
|
|
|
static int enum_dests_cb(void *_name, unsigned flags, cups_dest_t *dest);
|
|
static void *run_query(cups_dest_t *dest);
|
|
static void show_supported(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option, const char *value);
|
|
|
|
|
|
/*
|
|
* 'main()' - Main entry.
|
|
*/
|
|
|
|
int /* O - Exit status */
|
|
main(int argc, /* I - Number of command-line arguments */
|
|
char *argv[]) /* I - Command-line arguments */
|
|
{
|
|
/*
|
|
* Go through all the available destinations to find the requested one...
|
|
*/
|
|
|
|
(void)argc;
|
|
|
|
cupsEnumDests(CUPS_DEST_FLAGS_NONE, -1, NULL, 0, 0, enum_dests_cb, argv[1]);
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
/*
|
|
* 'enum_dests_cb()' - Destination enumeration function...
|
|
*/
|
|
|
|
static int /* O - 1 to continue, 0 to stop */
|
|
enum_dests_cb(void *_name, /* I - Printer name, if any */
|
|
unsigned flags, /* I - Enumeration flags */
|
|
cups_dest_t *dest) /* I - Found destination */
|
|
{
|
|
const char *name = (const char *)_name;
|
|
/* Printer name */
|
|
cups_dest_t *cdest; /* Copied destination */
|
|
|
|
|
|
(void)flags;
|
|
|
|
/*
|
|
* If a name was specified, compare it...
|
|
*/
|
|
|
|
if (name && strcasecmp(name, dest->name))
|
|
return (1); /* Continue */
|
|
|
|
/*
|
|
* Copy the destination and run the query on a separate thread...
|
|
*/
|
|
|
|
cupsCopyDest(dest, 0, &cdest);
|
|
_cupsThreadWait(_cupsThreadCreate((_cups_thread_func_t)run_query, cdest));
|
|
|
|
cupsFreeDests(1, cdest);
|
|
|
|
/*
|
|
* Continue if no name was specified or the name matches...
|
|
*/
|
|
|
|
return (!name || !strcasecmp(name, dest->name));
|
|
}
|
|
|
|
|
|
/*
|
|
* 'run_query()' - Query printer capabilities on a separate thread.
|
|
*/
|
|
|
|
static void * /* O - Return value (not used) */
|
|
run_query(cups_dest_t *dest) /* I - Destination to query */
|
|
{
|
|
http_t *http; /* Connection to destination */
|
|
cups_dinfo_t *dinfo; /* Destination info */
|
|
unsigned dflags = CUPS_DEST_FLAGS_NONE;
|
|
/* Destination flags */
|
|
|
|
|
|
if ((http = cupsConnectDest(dest, dflags, 300, NULL, NULL, 0, NULL, NULL)) == NULL)
|
|
{
|
|
printf("testthreads: Unable to connect to destination \"%s\": %s\n", dest->name, cupsLastErrorString());
|
|
return (NULL);
|
|
}
|
|
|
|
if ((dinfo = cupsCopyDestInfo(http, dest)) == NULL)
|
|
{
|
|
printf("testdest: Unable to get information for destination \"%s\": %s\n", dest->name, cupsLastErrorString());
|
|
return (NULL);
|
|
}
|
|
|
|
printf("\n%s:\n", dest->name);
|
|
|
|
show_supported(http, dest, dinfo, NULL, NULL);
|
|
|
|
return (NULL);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* 'show_supported()' - Show supported options, values, etc.
|
|
*/
|
|
|
|
static void
|
|
show_supported(http_t *http, /* I - Connection to destination */
|
|
cups_dest_t *dest, /* I - Destination */
|
|
cups_dinfo_t *dinfo, /* I - Destination information */
|
|
const char *option, /* I - Option, if any */
|
|
const char *value) /* I - Value, if any */
|
|
{
|
|
ipp_attribute_t *attr; /* Attribute */
|
|
int i, /* Looping var */
|
|
count; /* Number of values */
|
|
|
|
|
|
if (!option)
|
|
{
|
|
attr = cupsFindDestSupported(http, dest, dinfo, "job-creation-attributes");
|
|
if (attr)
|
|
{
|
|
count = ippGetCount(attr);
|
|
for (i = 0; i < count; i ++)
|
|
show_supported(http, dest, dinfo, ippGetString(attr, i, NULL), NULL);
|
|
}
|
|
else
|
|
{
|
|
static const char * const options[] =
|
|
{ /* List of standard options */
|
|
CUPS_COPIES,
|
|
CUPS_FINISHINGS,
|
|
CUPS_MEDIA,
|
|
CUPS_NUMBER_UP,
|
|
CUPS_ORIENTATION,
|
|
CUPS_PRINT_COLOR_MODE,
|
|
CUPS_PRINT_QUALITY,
|
|
CUPS_SIDES
|
|
};
|
|
|
|
puts(" No job-creation-attributes-supported attribute, probing instead.");
|
|
|
|
for (i = 0; i < (int)(sizeof(options) / sizeof(options[0])); i ++)
|
|
if (cupsCheckDestSupported(http, dest, dinfo, options[i], NULL))
|
|
show_supported(http, dest, dinfo, options[i], NULL);
|
|
}
|
|
}
|
|
else if (!value)
|
|
{
|
|
printf(" %s (%s - %s)\n", option, cupsLocalizeDestOption(http, dest, dinfo, option), cupsCheckDestSupported(http, dest, dinfo, option, NULL) ? "supported" : "not-supported");
|
|
|
|
if ((attr = cupsFindDestSupported(http, dest, dinfo, option)) != NULL)
|
|
{
|
|
count = ippGetCount(attr);
|
|
|
|
switch (ippGetValueTag(attr))
|
|
{
|
|
case IPP_TAG_INTEGER :
|
|
for (i = 0; i < count; i ++)
|
|
printf(" %d\n", ippGetInteger(attr, i));
|
|
break;
|
|
|
|
case IPP_TAG_ENUM :
|
|
for (i = 0; i < count; i ++)
|
|
{
|
|
int val = ippGetInteger(attr, i);
|
|
char valstr[256];
|
|
|
|
snprintf(valstr, sizeof(valstr), "%d", val);
|
|
printf(" %s (%s)\n", ippEnumString(option, ippGetInteger(attr, i)), cupsLocalizeDestValue(http, dest, dinfo, option, valstr));
|
|
}
|
|
break;
|
|
|
|
case IPP_TAG_RANGE :
|
|
for (i = 0; i < count; i ++)
|
|
{
|
|
int upper, lower = ippGetRange(attr, i, &upper);
|
|
|
|
printf(" %d-%d\n", lower, upper);
|
|
}
|
|
break;
|
|
|
|
case IPP_TAG_RESOLUTION :
|
|
for (i = 0; i < count; i ++)
|
|
{
|
|
int xres, yres;
|
|
ipp_res_t units;
|
|
xres = ippGetResolution(attr, i, &yres, &units);
|
|
|
|
if (xres == yres)
|
|
printf(" %d%s\n", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
|
|
else
|
|
printf(" %dx%d%s\n", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
|
|
}
|
|
break;
|
|
|
|
case IPP_TAG_KEYWORD :
|
|
for (i = 0; i < count; i ++)
|
|
printf(" %s (%s)\n", ippGetString(attr, i, NULL), cupsLocalizeDestValue(http, dest, dinfo, option, ippGetString(attr, i, NULL)));
|
|
break;
|
|
|
|
case IPP_TAG_TEXTLANG :
|
|
case IPP_TAG_NAMELANG :
|
|
case IPP_TAG_TEXT :
|
|
case IPP_TAG_NAME :
|
|
case IPP_TAG_URI :
|
|
case IPP_TAG_URISCHEME :
|
|
case IPP_TAG_CHARSET :
|
|
case IPP_TAG_LANGUAGE :
|
|
case IPP_TAG_MIMETYPE :
|
|
for (i = 0; i < count; i ++)
|
|
printf(" %s\n", ippGetString(attr, i, NULL));
|
|
break;
|
|
|
|
case IPP_TAG_STRING :
|
|
for (i = 0; i < count; i ++)
|
|
{
|
|
int j, len;
|
|
unsigned char *data = ippGetOctetString(attr, i, &len);
|
|
|
|
fputs(" ", stdout);
|
|
for (j = 0; j < len; j ++)
|
|
{
|
|
if (data[j] < ' ' || data[j] >= 0x7f)
|
|
printf("<%02X>", data[j]);
|
|
else
|
|
putchar(data[j]);
|
|
}
|
|
putchar('\n');
|
|
}
|
|
break;
|
|
|
|
case IPP_TAG_BOOLEAN :
|
|
break;
|
|
|
|
default :
|
|
printf(" %s\n", ippTagString(ippGetValueTag(attr)));
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
else if (cupsCheckDestSupported(http, dest, dinfo, option, value))
|
|
puts("YES");
|
|
else
|
|
puts("NO");
|
|
}
|