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.
783 lines
21 KiB
783 lines
21 KiB
/*
|
|
* CUPS destination API test program for CUPS.
|
|
*
|
|
* Copyright © 2012-2018 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.h"
|
|
|
|
|
|
/*
|
|
* Local functions...
|
|
*/
|
|
|
|
static int enum_cb(void *user_data, unsigned flags, cups_dest_t *dest);
|
|
static void localize(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option, const char *value);
|
|
static void print_file(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *filename, int num_options, cups_option_t *options);
|
|
static void show_conflicts(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, int num_options, cups_option_t *options);
|
|
static void show_default(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option);
|
|
static void show_media(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, unsigned flags, const char *name);
|
|
static void show_supported(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option, const char *value);
|
|
static void usage(const char *arg) _CUPS_NORETURN;
|
|
|
|
|
|
/*
|
|
* 'main()' - Main entry.
|
|
*/
|
|
|
|
int /* O - Exit status */
|
|
main(int argc, /* I - Number of command-line arguments */
|
|
char *argv[]) /* I - Command-line arguments */
|
|
{
|
|
int i; /* Looping var */
|
|
http_t *http; /* Connection to destination */
|
|
cups_dest_t *dest = NULL; /* Destination */
|
|
cups_dinfo_t *dinfo; /* Destination info */
|
|
unsigned dflags = CUPS_DEST_FLAGS_NONE;
|
|
/* Destination flags */
|
|
|
|
|
|
if (argc < 2)
|
|
return (0);
|
|
|
|
if (!strcmp(argv[1], "--get"))
|
|
{
|
|
cups_dest_t *dests; /* Destinations */
|
|
int num_dests = cupsGetDests2(CUPS_HTTP_DEFAULT, &dests);
|
|
/* Number of destinations */
|
|
|
|
for (i = 0; i < num_dests; i ++)
|
|
enum_cb(NULL, 0, dests + i);
|
|
|
|
cupsFreeDests(num_dests, dests);
|
|
return (0);
|
|
}
|
|
else if (!strcmp(argv[1], "--enum"))
|
|
{
|
|
cups_ptype_t type = 0, /* Printer type filter */
|
|
mask = 0; /* Printer type mask */
|
|
|
|
|
|
for (i = 2; i < argc; i ++)
|
|
{
|
|
if (!strcmp(argv[i], "grayscale"))
|
|
{
|
|
type |= CUPS_PRINTER_BW;
|
|
mask |= CUPS_PRINTER_BW;
|
|
}
|
|
else if (!strcmp(argv[i], "color"))
|
|
{
|
|
type |= CUPS_PRINTER_COLOR;
|
|
mask |= CUPS_PRINTER_COLOR;
|
|
}
|
|
else if (!strcmp(argv[i], "duplex"))
|
|
{
|
|
type |= CUPS_PRINTER_DUPLEX;
|
|
mask |= CUPS_PRINTER_DUPLEX;
|
|
}
|
|
else if (!strcmp(argv[i], "staple"))
|
|
{
|
|
type |= CUPS_PRINTER_STAPLE;
|
|
mask |= CUPS_PRINTER_STAPLE;
|
|
}
|
|
else if (!strcmp(argv[i], "small"))
|
|
{
|
|
type |= CUPS_PRINTER_SMALL;
|
|
mask |= CUPS_PRINTER_SMALL;
|
|
}
|
|
else if (!strcmp(argv[i], "medium"))
|
|
{
|
|
type |= CUPS_PRINTER_MEDIUM;
|
|
mask |= CUPS_PRINTER_MEDIUM;
|
|
}
|
|
else if (!strcmp(argv[i], "large"))
|
|
{
|
|
type |= CUPS_PRINTER_LARGE;
|
|
mask |= CUPS_PRINTER_LARGE;
|
|
}
|
|
else
|
|
usage(argv[i]);
|
|
}
|
|
|
|
cupsEnumDests(CUPS_DEST_FLAGS_NONE, 5000, NULL, type, mask, enum_cb, NULL);
|
|
|
|
return (0);
|
|
}
|
|
|
|
i = 1;
|
|
if (!strcmp(argv[i], "--device"))
|
|
{
|
|
dflags = CUPS_DEST_FLAGS_DEVICE;
|
|
i ++;
|
|
}
|
|
|
|
if (!strncmp(argv[i], "ipp://", 6) || !strncmp(argv[i], "ipps://", 7))
|
|
dest = cupsGetDestWithURI(NULL, argv[i]);
|
|
else if (!strcmp(argv[i], "default"))
|
|
{
|
|
dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, NULL, NULL);
|
|
if (dest && dest->instance)
|
|
printf("default is \"%s/%s\".\n", dest->name, dest->instance);
|
|
else if (dest)
|
|
printf("default is \"%s\".\n", dest->name);
|
|
else
|
|
puts("no default destination.");
|
|
}
|
|
else
|
|
dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, argv[i], NULL);
|
|
|
|
if (!dest)
|
|
{
|
|
printf("testdest: Unable to get destination \"%s\": %s\n", argv[i], cupsLastErrorString());
|
|
return (1);
|
|
}
|
|
|
|
i ++;
|
|
|
|
if ((http = cupsConnectDest(dest, dflags, 30000, NULL, NULL, 0, NULL, NULL)) == NULL)
|
|
{
|
|
printf("testdest: Unable to connect to destination \"%s\": %s\n", dest->name, cupsLastErrorString());
|
|
return (1);
|
|
}
|
|
|
|
if ((dinfo = cupsCopyDestInfo(http, dest)) == NULL)
|
|
{
|
|
printf("testdest: Unable to get information for destination \"%s\": %s\n", dest->name, cupsLastErrorString());
|
|
return (1);
|
|
}
|
|
|
|
if (i == argc || !strcmp(argv[i], "supported"))
|
|
{
|
|
i ++;
|
|
|
|
if ((i + 1) < argc)
|
|
show_supported(http, dest, dinfo, argv[i], argv[i + 1]);
|
|
else if (argc > 2)
|
|
show_supported(http, dest, dinfo, argv[i], NULL);
|
|
else
|
|
show_supported(http, dest, dinfo, NULL, NULL);
|
|
}
|
|
else if (!strcmp(argv[i], "conflicts") && (i + 1) < argc)
|
|
{
|
|
int num_options = 0;/* Number of options */
|
|
cups_option_t *options = NULL;/* Options */
|
|
|
|
for (i ++; i < argc; i ++)
|
|
num_options = cupsParseOptions(argv[i], num_options, &options);
|
|
|
|
show_conflicts(http, dest, dinfo, num_options, options);
|
|
}
|
|
else if (!strcmp(argv[i], "default") && (i + 1) < argc)
|
|
{
|
|
show_default(http, dest, dinfo, argv[i + 1]);
|
|
}
|
|
else if (!strcmp(argv[i], "localize"))
|
|
{
|
|
i ++;
|
|
if ((i + 1) < argc)
|
|
localize(http, dest, dinfo, argv[i], argv[i + 1]);
|
|
else if (argc > 2)
|
|
localize(http, dest, dinfo, argv[i], NULL);
|
|
else
|
|
localize(http, dest, dinfo, NULL, NULL);
|
|
}
|
|
else if (!strcmp(argv[i], "media"))
|
|
{
|
|
const char *name = NULL; /* Media name, if any */
|
|
unsigned flags = CUPS_MEDIA_FLAGS_DEFAULT;
|
|
/* Media selection flags */
|
|
|
|
for (i ++; i < argc; i ++)
|
|
{
|
|
if (!strcmp(argv[i], "borderless"))
|
|
flags = CUPS_MEDIA_FLAGS_BORDERLESS;
|
|
else if (!strcmp(argv[i], "duplex"))
|
|
flags = CUPS_MEDIA_FLAGS_DUPLEX;
|
|
else if (!strcmp(argv[i], "exact"))
|
|
flags = CUPS_MEDIA_FLAGS_EXACT;
|
|
else if (!strcmp(argv[i], "ready"))
|
|
flags = CUPS_MEDIA_FLAGS_READY;
|
|
else if (name)
|
|
usage(argv[i]);
|
|
else
|
|
name = argv[i];
|
|
}
|
|
|
|
show_media(http, dest, dinfo, flags, name);
|
|
}
|
|
else if (!strcmp(argv[i], "print") && (i + 1) < argc)
|
|
{
|
|
int num_options = 0;/* Number of options */
|
|
cups_option_t *options = NULL;/* Options */
|
|
const char *filename = argv[i + 1];
|
|
|
|
for (i += 2; i < argc; i ++)
|
|
num_options = cupsParseOptions(argv[i], num_options, &options);
|
|
|
|
print_file(http, dest, dinfo, filename, num_options, options);
|
|
}
|
|
else
|
|
usage(argv[i]);
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
/*
|
|
* 'enum_cb()' - Print the results from the enumeration of destinations.
|
|
*/
|
|
|
|
static int /* O - 1 to continue */
|
|
enum_cb(void *user_data, /* I - User data (unused) */
|
|
unsigned flags, /* I - Flags */
|
|
cups_dest_t *dest) /* I - Destination */
|
|
{
|
|
int i; /* Looping var */
|
|
|
|
|
|
(void)user_data;
|
|
(void)flags;
|
|
|
|
if (dest->instance)
|
|
printf("%s%s/%s%s:\n", (flags & CUPS_DEST_FLAGS_REMOVED) ? "REMOVE " : "", dest->name, dest->instance, dest->is_default ? " (Default)" : "");
|
|
else
|
|
printf("%s%s%s:\n", (flags & CUPS_DEST_FLAGS_REMOVED) ? "REMOVE " : "", dest->name, dest->is_default ? " (Default)" : "");
|
|
|
|
for (i = 0; i < dest->num_options; i ++)
|
|
printf(" %s=\"%s\"\n", dest->options[i].name, dest->options[i].value);
|
|
|
|
puts("");
|
|
|
|
return (1);
|
|
}
|
|
|
|
|
|
/*
|
|
* 'localize()' - Localize an option and value.
|
|
*/
|
|
|
|
static void
|
|
localize(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 */
|
|
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 ++)
|
|
localize(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))
|
|
localize(http, dest, dinfo, options[i], NULL);
|
|
}
|
|
}
|
|
else if (!value)
|
|
{
|
|
printf("%s (%s)\n", option, cupsLocalizeDestOption(http, dest, dinfo, option));
|
|
|
|
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 ++)
|
|
printf(" %s\n", ippEnumString(option, ippGetInteger(attr, i)));
|
|
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_TEXTLANG :
|
|
case IPP_TAG_NAMELANG :
|
|
case IPP_TAG_TEXT :
|
|
case IPP_TAG_NAME :
|
|
case IPP_TAG_KEYWORD :
|
|
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 (%s)\n", ippGetString(attr, i, NULL), cupsLocalizeDestValue(http, dest, dinfo, option, 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
|
|
puts(cupsLocalizeDestValue(http, dest, dinfo, option, value));
|
|
}
|
|
|
|
|
|
/*
|
|
* 'print_file()' - Print a file.
|
|
*/
|
|
|
|
static void
|
|
print_file(http_t *http, /* I - Connection to destination */
|
|
cups_dest_t *dest, /* I - Destination */
|
|
cups_dinfo_t *dinfo, /* I - Destination information */
|
|
const char *filename, /* I - File to print */
|
|
int num_options, /* I - Number of options */
|
|
cups_option_t *options) /* I - Options */
|
|
{
|
|
cups_file_t *fp; /* File to print */
|
|
int job_id; /* Job ID */
|
|
ipp_status_t status; /* Submission status */
|
|
const char *title; /* Title of job */
|
|
char buffer[32768]; /* File buffer */
|
|
ssize_t bytes; /* Bytes read/to write */
|
|
|
|
|
|
if ((fp = cupsFileOpen(filename, "r")) == NULL)
|
|
{
|
|
printf("Unable to open \"%s\": %s\n", filename, strerror(errno));
|
|
return;
|
|
}
|
|
|
|
if ((title = strrchr(filename, '/')) != NULL)
|
|
title ++;
|
|
else
|
|
title = filename;
|
|
|
|
if ((status = cupsCreateDestJob(http, dest, dinfo, &job_id, title, num_options, options)) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED)
|
|
{
|
|
printf("Unable to create job: %s\n", cupsLastErrorString());
|
|
cupsFileClose(fp);
|
|
return;
|
|
}
|
|
|
|
printf("Created job ID: %d\n", job_id);
|
|
|
|
if (cupsStartDestDocument(http, dest, dinfo, job_id, title, CUPS_FORMAT_AUTO, 0, NULL, 1) != HTTP_STATUS_CONTINUE)
|
|
{
|
|
printf("Unable to send document: %s\n", cupsLastErrorString());
|
|
cupsFileClose(fp);
|
|
return;
|
|
}
|
|
|
|
while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0)
|
|
{
|
|
if (cupsWriteRequestData(http, buffer, (size_t)bytes) != HTTP_STATUS_CONTINUE)
|
|
{
|
|
printf("Unable to write document data: %s\n", cupsLastErrorString());
|
|
break;
|
|
}
|
|
}
|
|
|
|
cupsFileClose(fp);
|
|
|
|
if ((status = cupsFinishDestDocument(http, dest, dinfo)) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED)
|
|
{
|
|
printf("Unable to send document: %s\n", cupsLastErrorString());
|
|
return;
|
|
}
|
|
|
|
puts("Job queued.");
|
|
}
|
|
|
|
|
|
/*
|
|
* 'show_conflicts()' - Show conflicts for selected options.
|
|
*/
|
|
|
|
static void
|
|
show_conflicts(
|
|
http_t *http, /* I - Connection to destination */
|
|
cups_dest_t *dest, /* I - Destination */
|
|
cups_dinfo_t *dinfo, /* I - Destination information */
|
|
int num_options, /* I - Number of options */
|
|
cups_option_t *options) /* I - Options */
|
|
{
|
|
(void)http;
|
|
(void)dest;
|
|
(void)dinfo;
|
|
(void)num_options;
|
|
(void)options;
|
|
}
|
|
|
|
|
|
/*
|
|
* 'show_default()' - Show default value for option.
|
|
*/
|
|
|
|
static void
|
|
show_default(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 (!strcmp(option, "media"))
|
|
{
|
|
/*
|
|
* Show default media option...
|
|
*/
|
|
|
|
cups_size_t size; /* Media size information */
|
|
|
|
if (cupsGetDestMediaDefault(http, dest, dinfo, CUPS_MEDIA_FLAGS_DEFAULT, &size))
|
|
printf("%s (%.2fx%.2fmm, margins=[%.2f %.2f %.2f %.2f])\n", size.media, size.width * 0.01, size.length * 0.01, size.left * 0.01, size.bottom * 0.01, size.right * 0.01, size.top * 0.01);
|
|
else
|
|
puts("FAILED");
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* Show default other option...
|
|
*/
|
|
|
|
ipp_attribute_t *defattr; /* Default attribute */
|
|
|
|
if ((defattr = cupsFindDestDefault(http, dest, dinfo, option)) != NULL)
|
|
{
|
|
char value[1024]; /* Value of default attribute */
|
|
|
|
ippAttributeString(defattr, value, sizeof(value));
|
|
puts(value);
|
|
}
|
|
else
|
|
puts("FAILED");
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* 'show_media()' - Show available media.
|
|
*/
|
|
|
|
static void
|
|
show_media(http_t *http, /* I - Connection to destination */
|
|
cups_dest_t *dest, /* I - Destination */
|
|
cups_dinfo_t *dinfo, /* I - Destination information */
|
|
unsigned flags, /* I - Media flags */
|
|
const char *name) /* I - Size name */
|
|
{
|
|
int i, /* Looping var */
|
|
count; /* Number of sizes */
|
|
cups_size_t size; /* Media size info */
|
|
|
|
|
|
if (name)
|
|
{
|
|
double dw, dl; /* Width and length from name */
|
|
char units[32]; /* Units */
|
|
int width, /* Width in 100ths of millimeters */
|
|
length; /* Length in 100ths of millimeters */
|
|
|
|
|
|
if (sscanf(name, "%lfx%lf%31s", &dw, &dl, units) == 3)
|
|
{
|
|
if (!strcmp(units, "in"))
|
|
{
|
|
width = (int)(dw * 2540.0);
|
|
length = (int)(dl * 2540.0);
|
|
}
|
|
else if (!strcmp(units, "mm"))
|
|
{
|
|
width = (int)(dw * 100.0);
|
|
length = (int)(dl * 100.0);
|
|
}
|
|
else
|
|
{
|
|
puts(" bad units in size");
|
|
return;
|
|
}
|
|
|
|
if (cupsGetDestMediaBySize(http, dest, dinfo, width, length, flags, &size))
|
|
{
|
|
printf(" %s (%s) %dx%d B%d L%d R%d T%d\n", size.media, cupsLocalizeDestMedia(http, dest, dinfo, flags, &size), size.width, size.length, size.bottom, size.left, size.right, size.top);
|
|
}
|
|
else
|
|
{
|
|
puts(" not supported");
|
|
}
|
|
}
|
|
else if (cupsGetDestMediaByName(http, dest, dinfo, name, flags, &size))
|
|
{
|
|
printf(" %s (%s) %dx%d B%d L%d R%d T%d\n", size.media, cupsLocalizeDestMedia(http, dest, dinfo, flags, &size), size.width, size.length, size.bottom, size.left, size.right, size.top);
|
|
}
|
|
else
|
|
{
|
|
puts(" not supported");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
count = cupsGetDestMediaCount(http, dest, dinfo, flags);
|
|
printf("%d size%s:\n", count, count == 1 ? "" : "s");
|
|
|
|
for (i = 0; i < count; i ++)
|
|
{
|
|
if (cupsGetDestMediaByIndex(http, dest, dinfo, i, flags, &size))
|
|
printf(" %s (%s) %dx%d B%d L%d R%d T%d\n", size.media, cupsLocalizeDestMedia(http, dest, dinfo, flags, &size), size.width, size.length, size.bottom, size.left, size.right, size.top);
|
|
else
|
|
puts(" error");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* '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");
|
|
}
|
|
|
|
|
|
/*
|
|
* 'usage()' - Show program usage.
|
|
*/
|
|
|
|
static void
|
|
usage(const char *arg) /* I - Argument for usage message */
|
|
{
|
|
if (arg)
|
|
printf("testdest: Unknown option \"%s\".\n", arg);
|
|
|
|
puts("Usage:");
|
|
puts(" ./testdest [--device] name [operation ...]");
|
|
puts(" ./testdest [--device] ipp://... [operation ...]");
|
|
puts(" ./testdest [--device] ipps://... [operation ...]");
|
|
puts(" ./testdest --get");
|
|
puts(" ./testdest --enum [grayscale] [color] [duplex] [staple] [small]\n"
|
|
" [medium] [large]");
|
|
puts("");
|
|
puts("Operations:");
|
|
puts(" conflicts options");
|
|
puts(" default option");
|
|
puts(" localize option [value]");
|
|
puts(" media [borderless] [duplex] [exact] [ready] [name or size]");
|
|
puts(" print filename [options]");
|
|
puts(" supported [option [value]]");
|
|
|
|
exit(arg != NULL);
|
|
}
|