#include <stdio.h>
#include "cups.h"
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) __attribute__((noreturn));
int
main(int argc,
char *argv[])
{
http_t *http;
cups_dest_t *dest = NULL;
cups_dinfo_t *dinfo;
if (argc < 2)
usage(NULL);
if (!strcmp(argv[1], "--enum"))
{
return (0);
}
else if (!strncmp(argv[1], "ipp://", 6) || !strncmp(argv[1], "ipps://", 7))
dest = cupsGetDestWithURI(NULL, argv[1]);
else
dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, argv[1], NULL);
if (!dest)
{
printf("testdest: Unable to get destination \"%s\": %s\n", argv[1], cupsLastErrorString());
return (1);
}
if ((http = cupsConnectDest(dest, CUPS_DEST_FLAGS_NONE, 30000, NULL, NULL, 0, NULL, NULL)) == NULL)
{
printf("testdest: Unable to connect to destination \"%s\": %s\n", argv[1], cupsLastErrorString());
return (1);
}
if ((dinfo = cupsCopyDestInfo(http, dest)) == NULL)
{
printf("testdest: Unable to get information for destination \"%s\": %s\n", argv[1], cupsLastErrorString());
return (1);
}
if (argc == 2 || (!strcmp(argv[2], "supported") && argc < 6))
{
if (argc > 3)
show_supported(http, dest, dinfo, argv[3], argv[4]);
else if (argc > 2)
show_supported(http, dest, dinfo, argv[3], NULL);
else
show_supported(http, dest, dinfo, NULL, NULL);
}
else if (!strcmp(argv[2], "conflicts") && argc > 3)
{
int i,
num_options = 0;
cups_option_t *options = NULL;
for (i = 3; i < argc; i ++)
num_options = cupsParseOptions(argv[i], num_options, &options);
show_conflicts(http, dest, dinfo, num_options, options);
}
else if (!strcmp(argv[2], "default") && argc == 4)
{
show_default(http, dest, dinfo, argv[3]);
}
else if (!strcmp(argv[2], "localize") && argc > 3 && argc < 6)
{
localize(http, dest, dinfo, argv[3], argv[4]);
}
else if (!strcmp(argv[2], "media"))
{
int i;
const char *name = NULL;
unsigned flags = CUPS_MEDIA_FLAGS_DEFAULT;
for (i = 3; 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[2], "print") && argc > 3)
{
int i,
num_options = 0;
cups_option_t *options = NULL;
for (i = 4; i < argc; i ++)
num_options = cupsParseOptions(argv[i], num_options, &options);
print_file(http, dest, dinfo, argv[3], num_options, options);
}
else
usage(argv[2]);
return (0);
}
static void
localize(http_t *http,
cups_dest_t *dest,
cups_dinfo_t *dinfo,
const char *option,
const char *value)
{
(void)http;
(void)dest;
(void)dinfo;
(void)option;
(void)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)
{
(void)http;
(void)dest;
(void)dinfo;
(void)filename;
(void)num_options;
(void)options;
}
static void
show_conflicts(
http_t *http,
cups_dest_t *dest,
cups_dinfo_t *dinfo,
int num_options,
cups_option_t *options)
{
(void)http;
(void)dest;
(void)dinfo;
(void)num_options;
(void)options;
}
static void
show_default(http_t *http,
cups_dest_t *dest,
cups_dinfo_t *dinfo,
const char *option)
{
(void)http;
(void)dest;
(void)dinfo;
(void)option;
}
static void
show_media(http_t *http,
cups_dest_t *dest,
cups_dinfo_t *dinfo,
unsigned flags,
const char *name)
{
int i,
count;
cups_size_t size;
if (name)
{
double dw, dl;
char units[32];
int width,
length;
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");
}
}
}
static void
show_supported(http_t *http,
cups_dest_t *dest,
cups_dinfo_t *dinfo,
const char *option,
const char *value)
{
ipp_attribute_t *attr;
int i,
count;
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[] =
{
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)
{
puts(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_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\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");
}
static void
usage(const char *arg)
{
if (arg)
printf("testdest: Unknown option \"%s\".\n", arg);
puts("Usage:");
puts(" ./testdest name [operation ...]");
puts(" ./testdest ipp://... [operation ...]");
puts(" ./testdest ipps://... [operation ...]");
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);
}