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