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