]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/testdest.c
Update ipp documentation to reflect the behavior of configuring WiFi on IPP USB printers.
[thirdparty/cups.git] / cups / testdest.c
CommitLineData
104fd4ae 1/*
104fd4ae
MS
2 * CUPS destination API test program for CUPS.
3 *
e22f464e 4 * Copyright © 2012-2018 by Apple Inc.
104fd4ae 5 *
e3101897 6 * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
104fd4ae
MS
7 */
8
9/*
10 * Include necessary headers...
11 */
12
13#include <stdio.h>
c585706d 14#include <errno.h>
104fd4ae
MS
15#include "cups.h"
16
17
18/*
19 * Local functions...
20 */
21
46385a1a 22static int enum_cb(void *user_data, unsigned flags, cups_dest_t *dest);
104fd4ae
MS
23static void localize(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option, const char *value);
24static void print_file(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *filename, int num_options, cups_option_t *options);
25static void show_conflicts(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, int num_options, cups_option_t *options);
26static void show_default(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option);
27static void show_media(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, unsigned flags, const char *name);
28static void show_supported(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option, const char *value);
a32af27c 29static void usage(const char *arg) _CUPS_NORETURN;
104fd4ae
MS
30
31
32/*
33 * 'main()' - Main entry.
34 */
35
36int /* O - Exit status */
37main(int argc, /* I - Number of command-line arguments */
38 char *argv[]) /* I - Command-line arguments */
39{
b969d5af 40 int i; /* Looping var */
104fd4ae
MS
41 http_t *http; /* Connection to destination */
42 cups_dest_t *dest = NULL; /* Destination */
43 cups_dinfo_t *dinfo; /* Destination info */
b969d5af
MS
44 unsigned dflags = CUPS_DEST_FLAGS_NONE;
45 /* Destination flags */
104fd4ae
MS
46
47
48 if (argc < 2)
e22f464e 49 return (0);
104fd4ae 50
c5f5c5a7
MS
51 if (!strcmp(argv[1], "--get"))
52 {
c5f5c5a7
MS
53 cups_dest_t *dests; /* Destinations */
54 int num_dests = cupsGetDests2(CUPS_HTTP_DEFAULT, &dests);
55 /* Number of destinations */
56
57 for (i = 0; i < num_dests; i ++)
58 enum_cb(NULL, 0, dests + i);
59
60 cupsFreeDests(num_dests, dests);
61 return (0);
62 }
63 else if (!strcmp(argv[1], "--enum"))
104fd4ae 64 {
46385a1a
MS
65 cups_ptype_t type = 0, /* Printer type filter */
66 mask = 0; /* Printer type mask */
67
68
69 for (i = 2; i < argc; i ++)
70 {
71 if (!strcmp(argv[i], "grayscale"))
72 {
73 type |= CUPS_PRINTER_BW;
74 mask |= CUPS_PRINTER_BW;
75 }
76 else if (!strcmp(argv[i], "color"))
77 {
78 type |= CUPS_PRINTER_COLOR;
79 mask |= CUPS_PRINTER_COLOR;
80 }
81 else if (!strcmp(argv[i], "duplex"))
82 {
83 type |= CUPS_PRINTER_DUPLEX;
84 mask |= CUPS_PRINTER_DUPLEX;
85 }
86 else if (!strcmp(argv[i], "staple"))
87 {
88 type |= CUPS_PRINTER_STAPLE;
89 mask |= CUPS_PRINTER_STAPLE;
90 }
91 else if (!strcmp(argv[i], "small"))
92 {
93 type |= CUPS_PRINTER_SMALL;
94 mask |= CUPS_PRINTER_SMALL;
95 }
96 else if (!strcmp(argv[i], "medium"))
97 {
98 type |= CUPS_PRINTER_MEDIUM;
99 mask |= CUPS_PRINTER_MEDIUM;
100 }
101 else if (!strcmp(argv[i], "large"))
102 {
103 type |= CUPS_PRINTER_LARGE;
104 mask |= CUPS_PRINTER_LARGE;
105 }
106 else
107 usage(argv[i]);
108 }
109
110 cupsEnumDests(CUPS_DEST_FLAGS_NONE, 5000, NULL, type, mask, enum_cb, NULL);
111
104fd4ae
MS
112 return (0);
113 }
b969d5af
MS
114
115 i = 1;
116 if (!strcmp(argv[i], "--device"))
117 {
118 dflags = CUPS_DEST_FLAGS_DEVICE;
119 i ++;
120 }
121
122 if (!strncmp(argv[i], "ipp://", 6) || !strncmp(argv[i], "ipps://", 7))
123 dest = cupsGetDestWithURI(NULL, argv[i]);
124 else if (!strcmp(argv[i], "default"))
c536b6c5
MS
125 {
126 dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, NULL, NULL);
127 if (dest && dest->instance)
128 printf("default is \"%s/%s\".\n", dest->name, dest->instance);
e22f464e 129 else if (dest)
c536b6c5 130 printf("default is \"%s\".\n", dest->name);
e22f464e
MS
131 else
132 puts("no default destination.");
c536b6c5 133 }
104fd4ae 134 else
b969d5af 135 dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, argv[i], NULL);
104fd4ae
MS
136
137 if (!dest)
138 {
b969d5af 139 printf("testdest: Unable to get destination \"%s\": %s\n", argv[i], cupsLastErrorString());
104fd4ae
MS
140 return (1);
141 }
142
b969d5af
MS
143 i ++;
144
145 if ((http = cupsConnectDest(dest, dflags, 30000, NULL, NULL, 0, NULL, NULL)) == NULL)
104fd4ae 146 {
b969d5af 147 printf("testdest: Unable to connect to destination \"%s\": %s\n", dest->name, cupsLastErrorString());
104fd4ae
MS
148 return (1);
149 }
150
151 if ((dinfo = cupsCopyDestInfo(http, dest)) == NULL)
152 {
b969d5af 153 printf("testdest: Unable to get information for destination \"%s\": %s\n", dest->name, cupsLastErrorString());
104fd4ae
MS
154 return (1);
155 }
156
b969d5af 157 if (i == argc || !strcmp(argv[i], "supported"))
104fd4ae 158 {
b969d5af
MS
159 i ++;
160
161 if ((i + 1) < argc)
162 show_supported(http, dest, dinfo, argv[i], argv[i + 1]);
104fd4ae 163 else if (argc > 2)
b969d5af 164 show_supported(http, dest, dinfo, argv[i], NULL);
104fd4ae
MS
165 else
166 show_supported(http, dest, dinfo, NULL, NULL);
167 }
b969d5af 168 else if (!strcmp(argv[i], "conflicts") && (i + 1) < argc)
104fd4ae 169 {
b969d5af 170 int num_options = 0;/* Number of options */
104fd4ae
MS
171 cups_option_t *options = NULL;/* Options */
172
b969d5af 173 for (i ++; i < argc; i ++)
104fd4ae
MS
174 num_options = cupsParseOptions(argv[i], num_options, &options);
175
176 show_conflicts(http, dest, dinfo, num_options, options);
177 }
b969d5af 178 else if (!strcmp(argv[i], "default") && (i + 1) < argc)
104fd4ae 179 {
b969d5af 180 show_default(http, dest, dinfo, argv[i + 1]);
104fd4ae 181 }
b969d5af 182 else if (!strcmp(argv[i], "localize"))
104fd4ae 183 {
b969d5af
MS
184 i ++;
185 if ((i + 1) < argc)
186 localize(http, dest, dinfo, argv[i], argv[i + 1]);
c585706d 187 else if (argc > 2)
b969d5af 188 localize(http, dest, dinfo, argv[i], NULL);
c585706d
MS
189 else
190 localize(http, dest, dinfo, NULL, NULL);
104fd4ae 191 }
b969d5af 192 else if (!strcmp(argv[i], "media"))
104fd4ae 193 {
104fd4ae
MS
194 const char *name = NULL; /* Media name, if any */
195 unsigned flags = CUPS_MEDIA_FLAGS_DEFAULT;
196 /* Media selection flags */
197
b969d5af 198 for (i ++; i < argc; i ++)
104fd4ae
MS
199 {
200 if (!strcmp(argv[i], "borderless"))
201 flags = CUPS_MEDIA_FLAGS_BORDERLESS;
202 else if (!strcmp(argv[i], "duplex"))
203 flags = CUPS_MEDIA_FLAGS_DUPLEX;
204 else if (!strcmp(argv[i], "exact"))
205 flags = CUPS_MEDIA_FLAGS_EXACT;
206 else if (!strcmp(argv[i], "ready"))
207 flags = CUPS_MEDIA_FLAGS_READY;
208 else if (name)
209 usage(argv[i]);
210 else
211 name = argv[i];
212 }
213
214 show_media(http, dest, dinfo, flags, name);
215 }
b969d5af 216 else if (!strcmp(argv[i], "print") && (i + 1) < argc)
104fd4ae 217 {
b969d5af 218 int num_options = 0;/* Number of options */
104fd4ae 219 cups_option_t *options = NULL;/* Options */
b969d5af 220 const char *filename = argv[i + 1];
104fd4ae 221
b969d5af 222 for (i += 2; i < argc; i ++)
104fd4ae
MS
223 num_options = cupsParseOptions(argv[i], num_options, &options);
224
b969d5af 225 print_file(http, dest, dinfo, filename, num_options, options);
104fd4ae
MS
226 }
227 else
b969d5af 228 usage(argv[i]);
104fd4ae
MS
229
230 return (0);
231}
232
233
46385a1a
MS
234/*
235 * 'enum_cb()' - Print the results from the enumeration of destinations.
236 */
237
238static int /* O - 1 to continue */
239enum_cb(void *user_data, /* I - User data (unused) */
240 unsigned flags, /* I - Flags */
241 cups_dest_t *dest) /* I - Destination */
242{
243 int i; /* Looping var */
244
245
246 (void)user_data;
247 (void)flags;
248
249 if (dest->instance)
c5f5c5a7 250 printf("%s%s/%s%s:\n", (flags & CUPS_DEST_FLAGS_REMOVED) ? "REMOVE " : "", dest->name, dest->instance, dest->is_default ? " (Default)" : "");
46385a1a 251 else
c5f5c5a7 252 printf("%s%s%s:\n", (flags & CUPS_DEST_FLAGS_REMOVED) ? "REMOVE " : "", dest->name, dest->is_default ? " (Default)" : "");
46385a1a
MS
253
254 for (i = 0; i < dest->num_options; i ++)
255 printf(" %s=\"%s\"\n", dest->options[i].name, dest->options[i].value);
256
c5f5c5a7
MS
257 puts("");
258
46385a1a
MS
259 return (1);
260}
261
262
104fd4ae
MS
263/*
264 * 'localize()' - Localize an option and value.
265 */
266
267static void
268localize(http_t *http, /* I - Connection to destination */
269 cups_dest_t *dest, /* I - Destination */
270 cups_dinfo_t *dinfo, /* I - Destination information */
271 const char *option, /* I - Option */
272 const char *value) /* I - Value, if any */
273{
c585706d
MS
274 ipp_attribute_t *attr; /* Attribute */
275 int i, /* Looping var */
276 count; /* Number of values */
277
278
279 if (!option)
280 {
281 attr = cupsFindDestSupported(http, dest, dinfo, "job-creation-attributes");
282 if (attr)
283 {
284 count = ippGetCount(attr);
285 for (i = 0; i < count; i ++)
286 localize(http, dest, dinfo, ippGetString(attr, i, NULL), NULL);
287 }
288 else
289 {
290 static const char * const options[] =
291 { /* List of standard options */
292 CUPS_COPIES,
293 CUPS_FINISHINGS,
294 CUPS_MEDIA,
295 CUPS_NUMBER_UP,
296 CUPS_ORIENTATION,
297 CUPS_PRINT_COLOR_MODE,
298 CUPS_PRINT_QUALITY,
299 CUPS_SIDES
300 };
301
302 puts("No job-creation-attributes-supported attribute, probing instead.");
303
304 for (i = 0; i < (int)(sizeof(options) / sizeof(options[0])); i ++)
305 if (cupsCheckDestSupported(http, dest, dinfo, options[i], NULL))
306 localize(http, dest, dinfo, options[i], NULL);
307 }
308 }
309 else if (!value)
310 {
311 printf("%s (%s)\n", option, cupsLocalizeDestOption(http, dest, dinfo, option));
312
313 if ((attr = cupsFindDestSupported(http, dest, dinfo, option)) != NULL)
314 {
315 count = ippGetCount(attr);
316
317 switch (ippGetValueTag(attr))
318 {
319 case IPP_TAG_INTEGER :
320 for (i = 0; i < count; i ++)
321 printf(" %d\n", ippGetInteger(attr, i));
322 break;
323
324 case IPP_TAG_ENUM :
325 for (i = 0; i < count; i ++)
326 printf(" %s\n", ippEnumString(option, ippGetInteger(attr, i)));
327 break;
328
329 case IPP_TAG_RANGE :
330 for (i = 0; i < count; i ++)
331 {
332 int upper, lower = ippGetRange(attr, i, &upper);
333
334 printf(" %d-%d\n", lower, upper);
335 }
336 break;
337
338 case IPP_TAG_RESOLUTION :
339 for (i = 0; i < count; i ++)
340 {
341 int xres, yres;
342 ipp_res_t units;
343 xres = ippGetResolution(attr, i, &yres, &units);
344
345 if (xres == yres)
346 printf(" %d%s\n", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
347 else
348 printf(" %dx%d%s\n", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
349 }
350 break;
351
352 case IPP_TAG_TEXTLANG :
353 case IPP_TAG_NAMELANG :
354 case IPP_TAG_TEXT :
355 case IPP_TAG_NAME :
356 case IPP_TAG_KEYWORD :
357 case IPP_TAG_URI :
358 case IPP_TAG_URISCHEME :
359 case IPP_TAG_CHARSET :
360 case IPP_TAG_LANGUAGE :
361 case IPP_TAG_MIMETYPE :
362 for (i = 0; i < count; i ++)
363 printf(" %s (%s)\n", ippGetString(attr, i, NULL), cupsLocalizeDestValue(http, dest, dinfo, option, ippGetString(attr, i, NULL)));
364 break;
365
366 case IPP_TAG_STRING :
367 for (i = 0; i < count; i ++)
368 {
369 int j, len;
370 unsigned char *data = ippGetOctetString(attr, i, &len);
371
372 fputs(" ", stdout);
373 for (j = 0; j < len; j ++)
374 {
375 if (data[j] < ' ' || data[j] >= 0x7f)
376 printf("<%02X>", data[j]);
377 else
378 putchar(data[j]);
379 }
380 putchar('\n');
381 }
382 break;
383
384 case IPP_TAG_BOOLEAN :
385 break;
386
387 default :
388 printf(" %s\n", ippTagString(ippGetValueTag(attr)));
389 break;
390 }
391 }
503b54c9 392
c585706d
MS
393 }
394 else
395 puts(cupsLocalizeDestValue(http, dest, dinfo, option, value));
104fd4ae
MS
396}
397
398
399/*
400 * 'print_file()' - Print a file.
401 */
402
403static void
404print_file(http_t *http, /* I - Connection to destination */
405 cups_dest_t *dest, /* I - Destination */
406 cups_dinfo_t *dinfo, /* I - Destination information */
407 const char *filename, /* I - File to print */
408 int num_options, /* I - Number of options */
409 cups_option_t *options) /* I - Options */
410{
c585706d
MS
411 cups_file_t *fp; /* File to print */
412 int job_id; /* Job ID */
c585706d
MS
413 const char *title; /* Title of job */
414 char buffer[32768]; /* File buffer */
415 ssize_t bytes; /* Bytes read/to write */
416
417
418 if ((fp = cupsFileOpen(filename, "r")) == NULL)
419 {
420 printf("Unable to open \"%s\": %s\n", filename, strerror(errno));
421 return;
422 }
423
424 if ((title = strrchr(filename, '/')) != NULL)
425 title ++;
426 else
427 title = filename;
428
064e50fb 429 if (cupsCreateDestJob(http, dest, dinfo, &job_id, title, num_options, options) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED)
c585706d
MS
430 {
431 printf("Unable to create job: %s\n", cupsLastErrorString());
432 cupsFileClose(fp);
433 return;
434 }
435
436 printf("Created job ID: %d\n", job_id);
437
438 if (cupsStartDestDocument(http, dest, dinfo, job_id, title, CUPS_FORMAT_AUTO, 0, NULL, 1) != HTTP_STATUS_CONTINUE)
439 {
440 printf("Unable to send document: %s\n", cupsLastErrorString());
441 cupsFileClose(fp);
442 return;
443 }
444
445 while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0)
446 {
447 if (cupsWriteRequestData(http, buffer, (size_t)bytes) != HTTP_STATUS_CONTINUE)
448 {
449 printf("Unable to write document data: %s\n", cupsLastErrorString());
450 break;
451 }
452 }
453
454 cupsFileClose(fp);
455
064e50fb 456 if (cupsFinishDestDocument(http, dest, dinfo) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED)
c585706d
MS
457 {
458 printf("Unable to send document: %s\n", cupsLastErrorString());
459 return;
460 }
461
462 puts("Job queued.");
104fd4ae
MS
463}
464
465
466/*
467 * 'show_conflicts()' - Show conflicts for selected options.
468 */
469
470static void
471show_conflicts(
472 http_t *http, /* I - Connection to destination */
473 cups_dest_t *dest, /* I - Destination */
474 cups_dinfo_t *dinfo, /* I - Destination information */
475 int num_options, /* I - Number of options */
476 cups_option_t *options) /* I - Options */
477{
478 (void)http;
479 (void)dest;
480 (void)dinfo;
481 (void)num_options;
482 (void)options;
483}
484
485
486/*
487 * 'show_default()' - Show default value for option.
488 */
489
490static void
491show_default(http_t *http, /* I - Connection to destination */
492 cups_dest_t *dest, /* I - Destination */
493 cups_dinfo_t *dinfo, /* I - Destination information */
494 const char *option) /* I - Option */
495{
534dfe8e
MS
496 if (!strcmp(option, "media"))
497 {
498 /*
499 * Show default media option...
500 */
501
502 cups_size_t size; /* Media size information */
503
504 if (cupsGetDestMediaDefault(http, dest, dinfo, CUPS_MEDIA_FLAGS_DEFAULT, &size))
505 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);
506 else
507 puts("FAILED");
508 }
509 else
510 {
511 /*
512 * Show default other option...
513 */
514
515 ipp_attribute_t *defattr; /* Default attribute */
516
517 if ((defattr = cupsFindDestDefault(http, dest, dinfo, option)) != NULL)
518 {
519 char value[1024]; /* Value of default attribute */
520
521 ippAttributeString(defattr, value, sizeof(value));
522 puts(value);
523 }
524 else
525 puts("FAILED");
526 }
104fd4ae
MS
527}
528
529
530/*
531 * 'show_media()' - Show available media.
532 */
533
534static void
535show_media(http_t *http, /* I - Connection to destination */
536 cups_dest_t *dest, /* I - Destination */
537 cups_dinfo_t *dinfo, /* I - Destination information */
538 unsigned flags, /* I - Media flags */
539 const char *name) /* I - Size name */
540{
541 int i, /* Looping var */
542 count; /* Number of sizes */
543 cups_size_t size; /* Media size info */
544
545
546 if (name)
547 {
548 double dw, dl; /* Width and length from name */
549 char units[32]; /* Units */
550 int width, /* Width in 100ths of millimeters */
551 length; /* Length in 100ths of millimeters */
552
553
554 if (sscanf(name, "%lfx%lf%31s", &dw, &dl, units) == 3)
555 {
556 if (!strcmp(units, "in"))
557 {
558 width = (int)(dw * 2540.0);
559 length = (int)(dl * 2540.0);
560 }
561 else if (!strcmp(units, "mm"))
562 {
563 width = (int)(dw * 100.0);
564 length = (int)(dl * 100.0);
565 }
566 else
567 {
568 puts(" bad units in size");
569 return;
570 }
571
572 if (cupsGetDestMediaBySize(http, dest, dinfo, width, length, flags, &size))
573 {
574 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);
575 }
576 else
577 {
578 puts(" not supported");
579 }
580 }
581 else if (cupsGetDestMediaByName(http, dest, dinfo, name, flags, &size))
582 {
583 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);
584 }
585 else
586 {
587 puts(" not supported");
588 }
589 }
590 else
591 {
592 count = cupsGetDestMediaCount(http, dest, dinfo, flags);
593 printf("%d size%s:\n", count, count == 1 ? "" : "s");
594
595 for (i = 0; i < count; i ++)
596 {
597 if (cupsGetDestMediaByIndex(http, dest, dinfo, i, flags, &size))
598 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);
599 else
600 puts(" error");
601 }
602 }
603}
604
605
606/*
607 * 'show_supported()' - Show supported options, values, etc.
608 */
609
610static void
611show_supported(http_t *http, /* I - Connection to destination */
612 cups_dest_t *dest, /* I - Destination */
613 cups_dinfo_t *dinfo, /* I - Destination information */
614 const char *option, /* I - Option, if any */
615 const char *value) /* I - Value, if any */
616{
617 ipp_attribute_t *attr; /* Attribute */
618 int i, /* Looping var */
619 count; /* Number of values */
620
621
622 if (!option)
623 {
624 attr = cupsFindDestSupported(http, dest, dinfo, "job-creation-attributes");
625 if (attr)
626 {
627 count = ippGetCount(attr);
628 for (i = 0; i < count; i ++)
629 show_supported(http, dest, dinfo, ippGetString(attr, i, NULL), NULL);
630 }
631 else
632 {
633 static const char * const options[] =
634 { /* List of standard options */
635 CUPS_COPIES,
636 CUPS_FINISHINGS,
637 CUPS_MEDIA,
638 CUPS_NUMBER_UP,
639 CUPS_ORIENTATION,
640 CUPS_PRINT_COLOR_MODE,
641 CUPS_PRINT_QUALITY,
642 CUPS_SIDES
643 };
644
645 puts("No job-creation-attributes-supported attribute, probing instead.");
646
647 for (i = 0; i < (int)(sizeof(options) / sizeof(options[0])); i ++)
648 if (cupsCheckDestSupported(http, dest, dinfo, options[i], NULL))
649 show_supported(http, dest, dinfo, options[i], NULL);
650 }
651 }
652 else if (!value)
653 {
a9357c9d 654 printf("%s (%s - %s)\n", option, cupsLocalizeDestOption(http, dest, dinfo, option), cupsCheckDestSupported(http, dest, dinfo, option, NULL) ? "supported" : "not-supported");
ca9e55c9 655
104fd4ae
MS
656 if ((attr = cupsFindDestSupported(http, dest, dinfo, option)) != NULL)
657 {
658 count = ippGetCount(attr);
659
660 switch (ippGetValueTag(attr))
661 {
662 case IPP_TAG_INTEGER :
663 for (i = 0; i < count; i ++)
664 printf(" %d\n", ippGetInteger(attr, i));
665 break;
666
667 case IPP_TAG_ENUM :
668 for (i = 0; i < count; i ++)
a9357c9d
MS
669 {
670 int val = ippGetInteger(attr, i);
671 char valstr[256];
672
673 snprintf(valstr, sizeof(valstr), "%d", val);
674 printf(" %s (%s)\n", ippEnumString(option, ippGetInteger(attr, i)), cupsLocalizeDestValue(http, dest, dinfo, option, valstr));
675 }
104fd4ae
MS
676 break;
677
678 case IPP_TAG_RANGE :
679 for (i = 0; i < count; i ++)
680 {
681 int upper, lower = ippGetRange(attr, i, &upper);
682
683 printf(" %d-%d\n", lower, upper);
684 }
685 break;
686
4db7fcee
MS
687 case IPP_TAG_RESOLUTION :
688 for (i = 0; i < count; i ++)
689 {
690 int xres, yres;
691 ipp_res_t units;
692 xres = ippGetResolution(attr, i, &yres, &units);
693
694 if (xres == yres)
695 printf(" %d%s\n", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
696 else
697 printf(" %dx%d%s\n", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
698 }
699 break;
700
a9357c9d
MS
701 case IPP_TAG_KEYWORD :
702 for (i = 0; i < count; i ++)
703 printf(" %s (%s)\n", ippGetString(attr, i, NULL), cupsLocalizeDestValue(http, dest, dinfo, option, ippGetString(attr, i, NULL)));
704 break;
705
104fd4ae
MS
706 case IPP_TAG_TEXTLANG :
707 case IPP_TAG_NAMELANG :
708 case IPP_TAG_TEXT :
709 case IPP_TAG_NAME :
104fd4ae
MS
710 case IPP_TAG_URI :
711 case IPP_TAG_URISCHEME :
712 case IPP_TAG_CHARSET :
713 case IPP_TAG_LANGUAGE :
714 case IPP_TAG_MIMETYPE :
715 for (i = 0; i < count; i ++)
716 printf(" %s\n", ippGetString(attr, i, NULL));
717 break;
718
719 case IPP_TAG_STRING :
720 for (i = 0; i < count; i ++)
721 {
722 int j, len;
723 unsigned char *data = ippGetOctetString(attr, i, &len);
724
725 fputs(" ", stdout);
726 for (j = 0; j < len; j ++)
727 {
728 if (data[j] < ' ' || data[j] >= 0x7f)
729 printf("<%02X>", data[j]);
730 else
731 putchar(data[j]);
732 }
733 putchar('\n');
734 }
735 break;
736
737 case IPP_TAG_BOOLEAN :
738 break;
739
740 default :
741 printf(" %s\n", ippTagString(ippGetValueTag(attr)));
742 break;
743 }
744 }
503b54c9 745
104fd4ae
MS
746 }
747 else if (cupsCheckDestSupported(http, dest, dinfo, option, value))
748 puts("YES");
749 else
750 puts("NO");
104fd4ae
MS
751}
752
753
754/*
755 * 'usage()' - Show program usage.
756 */
757
758static void
759usage(const char *arg) /* I - Argument for usage message */
760{
761 if (arg)
762 printf("testdest: Unknown option \"%s\".\n", arg);
763
764 puts("Usage:");
b969d5af
MS
765 puts(" ./testdest [--device] name [operation ...]");
766 puts(" ./testdest [--device] ipp://... [operation ...]");
767 puts(" ./testdest [--device] ipps://... [operation ...]");
8d59b9f7 768 puts(" ./testdest --get");
104fd4ae
MS
769 puts(" ./testdest --enum [grayscale] [color] [duplex] [staple] [small]\n"
770 " [medium] [large]");
771 puts("");
772 puts("Operations:");
773 puts(" conflicts options");
774 puts(" default option");
775 puts(" localize option [value]");
776 puts(" media [borderless] [duplex] [exact] [ready] [name or size]");
777 puts(" print filename [options]");
778 puts(" supported [option [value]]");
779
780 exit(arg != NULL);
781}