OpenPrinting / cups

OpenPrinting CUPS Sources
https://openprinting.github.io/cups
Apache License 2.0
967 stars 177 forks source link

cupsLocalizeDestMedia fails with error "Invalid argument" #853

Closed GeorgeCraggs closed 6 months ago

GeorgeCraggs commented 6 months ago

Describe the bug cupsLocalizeDestMedia fails with "Invalid argument".

To Reproduce Run the following MWE, updating the dest name with a valid printer (I've tried both a Dymo LabelWriter 400, and a Xerox Workcentre 6515). I compiled with gcc -o mwe -lcups mwe.c.

#include <stdio.h>
#include <cups/cups.h>

int main() {
    cups_dest_t *dests;
    int destsCount = cupsGetDests2(CUPS_HTTP_DEFAULT, &dests);
    printf("Found %d Dests\n", destsCount);

    cups_dest_t *dest = cupsGetDest("lw400", NULL, destsCount, dests);
    cups_dinfo_t *dinfo = cupsCopyDestInfo(CUPS_HTTP_DEFAULT, dest);

    size_t count = cupsGetDestMediaCount(CUPS_HTTP_DEFAULT, dest, dinfo, CUPS_MEDIA_FLAGS_DEFAULT);
    cups_size_t size;
    for (int i = 0; i < count; i++) {
        if (cupsGetDestMediaByIndex(CUPS_HTTP_DEFAULT, dest, dinfo, i, CUPS_MEDIA_FLAGS_DEFAULT, &size)) {
            const char *name = cupsLocalizeDestMedia(CUPS_HTTP_DEFAULT, dest, dinfo, CUPS_MEDIA_FLAGS_DEFAULT, &size);
            const char *lastErr = cupsLastErrorString();
            printf("Found media: (%s): %s\n", name, size.media);
            printf("  (last err: %s)\n", lastErr);
        }
    }

    cupsFreeDests(destsCount, dests);
    cupsFreeDestInfo(dinfo);
    return 0;
}

Expected behavior cupsLocalizeDestMedia should return a localized media name (returns NULL currently), and cupsLastErrorString should remain as "successful-ok".

Screenshots N/A

System Information:

Additional context The Dymo LabelWriter 400 is connected via USB, and the Xerox is setup using IPP Everywhere.

michaelrsweet commented 6 months ago

cupsLocalizeDestMedia needs a connection to the destination, it doesn't support CUPS_HTTP_DEFAULT. Here is a variation of your example code that does work (and allows you to specify the destination on the command-line):

#include <stdio.h>
#include <cups/cups.h>

int main(int argc, char *argv[]) {
    cups_dest_t *dests;
    int destsCount = cupsGetDests2(CUPS_HTTP_DEFAULT, &dests);
    printf("Found %d Dests\n", destsCount);

    cups_dest_t *dest = cupsGetDest(argv[1], NULL, destsCount, dests);
    char resource[256];
    http_t *http = cupsConnectDest(dest, CUPS_DEST_FLAGS_NONE, /*msec*/30000, /*cancel*/NULL, resource, sizeof(resource), /*dest_cb*/NULL, /*user_data*/NULL);
    cups_dinfo_t *dinfo = cupsCopyDestInfo(http, dest);

        printf("dest=%p(%s), dinfo=%p\n", dest, dest ? dest->name : "null", dinfo);
    size_t count = cupsGetDestMediaCount(http, dest, dinfo, CUPS_MEDIA_FLAGS_DEFAULT);
    cups_size_t size;
    for (int i = 0; i < count; i++) {
        if (cupsGetDestMediaByIndex(http, dest, dinfo, i, CUPS_MEDIA_FLAGS_DEFAULT, &size)) {
            const char *name = cupsLocalizeDestMedia(http, dest, dinfo, CUPS_MEDIA_FLAGS_DEFAULT, &size);
            const char *lastErr = cupsLastErrorString();
            printf("Found media: (%s): %s\n", name, size.media);
            printf("  (last err: %s)\n", lastErr);
        }
    }

    cupsFreeDests(destsCount, dests);
    cupsFreeDestInfo(dinfo);
    httpClose(http);
    return 0;
}