/* * Derived from 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 #include #include /* * Local functions... */ static void show_supported(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option, const char *value); cups_dest_t *found_dest = NULL; int enum_dests_cb(void *_name, unsigned flags, cups_dest_t *dest) { char *name = (char *)_name; if (strcasecmp(name, dest->name)) return 1; cupsCopyDest(dest, 0, &found_dest); return 0; } /* * 'main()' - Main entry. */ int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { 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 */ char printer_uri[1024]; /* The name of an existing print queue needs to be given as first argument */ if (argc < 2) return (0); /* With any given 2nd argument we run ippPort() to initialize the global variables (default settings) of libcups */ if (argc > 2) ippPort(); /* Go through all the available destinations to find the requested one */ cupsEnumDests(CUPS_DEST_FLAGS_NONE, -1, //NO timeout NULL, 0, //TYPE 0, //MASK enum_dests_cb, argv[1]); if (found_dest == 0) { printf("testdest: Destination \"%s\" not found.\n", argv[1]); return (1); } dest = found_dest; if ((http = cupsConnectDest(dest, dflags, 300, 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); } show_supported(http, dest, dinfo, NULL, NULL); return (0); } /* * '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"); }