]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/testdest.c
Fix some bugs in the implementation that have been around for a while...
[thirdparty/cups.git] / cups / testdest.c
CommitLineData
104fd4ae 1/*
104fd4ae
MS
2 * CUPS destination API test program for CUPS.
3 *
46385a1a 4 * Copyright 2016 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
10 * file is missing or damaged, see the license at "http://www.cups.org/".
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>
20#include "cups.h"
21
22
23/*
24 * Local functions...
25 */
26
46385a1a 27static int enum_cb(void *user_data, unsigned flags, cups_dest_t *dest);
104fd4ae
MS
28static void localize(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option, const char *value);
29static void print_file(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *filename, int num_options, cups_option_t *options);
30static void show_conflicts(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, int num_options, cups_option_t *options);
31static void show_default(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option);
32static void show_media(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, unsigned flags, const char *name);
33static void show_supported(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option, const char *value);
34static void usage(const char *arg) __attribute__((noreturn));
35
36
37/*
38 * 'main()' - Main entry.
39 */
40
41int /* O - Exit status */
42main(int argc, /* I - Number of command-line arguments */
43 char *argv[]) /* I - Command-line arguments */
44{
45 http_t *http; /* Connection to destination */
46 cups_dest_t *dest = NULL; /* Destination */
47 cups_dinfo_t *dinfo; /* Destination info */
48
49
50 if (argc < 2)
51 usage(NULL);
52
53 if (!strcmp(argv[1], "--enum"))
54 {
46385a1a
MS
55 int i; /* Looping var */
56 cups_ptype_t type = 0, /* Printer type filter */
57 mask = 0; /* Printer type mask */
58
59
60 for (i = 2; i < argc; i ++)
61 {
62 if (!strcmp(argv[i], "grayscale"))
63 {
64 type |= CUPS_PRINTER_BW;
65 mask |= CUPS_PRINTER_BW;
66 }
67 else if (!strcmp(argv[i], "color"))
68 {
69 type |= CUPS_PRINTER_COLOR;
70 mask |= CUPS_PRINTER_COLOR;
71 }
72 else if (!strcmp(argv[i], "duplex"))
73 {
74 type |= CUPS_PRINTER_DUPLEX;
75 mask |= CUPS_PRINTER_DUPLEX;
76 }
77 else if (!strcmp(argv[i], "staple"))
78 {
79 type |= CUPS_PRINTER_STAPLE;
80 mask |= CUPS_PRINTER_STAPLE;
81 }
82 else if (!strcmp(argv[i], "small"))
83 {
84 type |= CUPS_PRINTER_SMALL;
85 mask |= CUPS_PRINTER_SMALL;
86 }
87 else if (!strcmp(argv[i], "medium"))
88 {
89 type |= CUPS_PRINTER_MEDIUM;
90 mask |= CUPS_PRINTER_MEDIUM;
91 }
92 else if (!strcmp(argv[i], "large"))
93 {
94 type |= CUPS_PRINTER_LARGE;
95 mask |= CUPS_PRINTER_LARGE;
96 }
97 else
98 usage(argv[i]);
99 }
100
101 cupsEnumDests(CUPS_DEST_FLAGS_NONE, 5000, NULL, type, mask, enum_cb, NULL);
102
104fd4ae
MS
103 return (0);
104 }
105 else if (!strncmp(argv[1], "ipp://", 6) || !strncmp(argv[1], "ipps://", 7))
106 dest = cupsGetDestWithURI(NULL, argv[1]);
107 else
108 dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, argv[1], NULL);
109
110 if (!dest)
111 {
112 printf("testdest: Unable to get destination \"%s\": %s\n", argv[1], cupsLastErrorString());
113 return (1);
114 }
115
116 if ((http = cupsConnectDest(dest, CUPS_DEST_FLAGS_NONE, 30000, NULL, NULL, 0, NULL, NULL)) == NULL)
117 {
118 printf("testdest: Unable to connect to destination \"%s\": %s\n", argv[1], cupsLastErrorString());
119 return (1);
120 }
121
122 if ((dinfo = cupsCopyDestInfo(http, dest)) == NULL)
123 {
124 printf("testdest: Unable to get information for destination \"%s\": %s\n", argv[1], cupsLastErrorString());
125 return (1);
126 }
127
128 if (argc == 2 || (!strcmp(argv[2], "supported") && argc < 6))
129 {
130 if (argc > 3)
131 show_supported(http, dest, dinfo, argv[3], argv[4]);
132 else if (argc > 2)
133 show_supported(http, dest, dinfo, argv[3], NULL);
134 else
135 show_supported(http, dest, dinfo, NULL, NULL);
136 }
137 else if (!strcmp(argv[2], "conflicts") && argc > 3)
138 {
139 int i, /* Looping var */
140 num_options = 0;/* Number of options */
141 cups_option_t *options = NULL;/* Options */
142
143 for (i = 3; i < argc; i ++)
144 num_options = cupsParseOptions(argv[i], num_options, &options);
145
146 show_conflicts(http, dest, dinfo, num_options, options);
147 }
148 else if (!strcmp(argv[2], "default") && argc == 4)
149 {
150 show_default(http, dest, dinfo, argv[3]);
151 }
152 else if (!strcmp(argv[2], "localize") && argc > 3 && argc < 6)
153 {
154 localize(http, dest, dinfo, argv[3], argv[4]);
155 }
156 else if (!strcmp(argv[2], "media"))
157 {
158 int i; /* Looping var */
159 const char *name = NULL; /* Media name, if any */
160 unsigned flags = CUPS_MEDIA_FLAGS_DEFAULT;
161 /* Media selection flags */
162
163 for (i = 3; i < argc; i ++)
164 {
165 if (!strcmp(argv[i], "borderless"))
166 flags = CUPS_MEDIA_FLAGS_BORDERLESS;
167 else if (!strcmp(argv[i], "duplex"))
168 flags = CUPS_MEDIA_FLAGS_DUPLEX;
169 else if (!strcmp(argv[i], "exact"))
170 flags = CUPS_MEDIA_FLAGS_EXACT;
171 else if (!strcmp(argv[i], "ready"))
172 flags = CUPS_MEDIA_FLAGS_READY;
173 else if (name)
174 usage(argv[i]);
175 else
176 name = argv[i];
177 }
178
179 show_media(http, dest, dinfo, flags, name);
180 }
181 else if (!strcmp(argv[2], "print") && argc > 3)
182 {
183 int i, /* Looping var */
184 num_options = 0;/* Number of options */
185 cups_option_t *options = NULL;/* Options */
186
187 for (i = 4; i < argc; i ++)
188 num_options = cupsParseOptions(argv[i], num_options, &options);
189
190 print_file(http, dest, dinfo, argv[3], num_options, options);
191 }
192 else
193 usage(argv[2]);
194
195 return (0);
196}
197
198
46385a1a
MS
199/*
200 * 'enum_cb()' - Print the results from the enumeration of destinations.
201 */
202
203static int /* O - 1 to continue */
204enum_cb(void *user_data, /* I - User data (unused) */
205 unsigned flags, /* I - Flags */
206 cups_dest_t *dest) /* I - Destination */
207{
208 int i; /* Looping var */
209
210
211 (void)user_data;
212 (void)flags;
213
214 if (dest->instance)
215 printf("%s/%s:\n", dest->name, dest->instance);
216 else
217 printf("%s:\n", dest->name);
218
219 for (i = 0; i < dest->num_options; i ++)
220 printf(" %s=\"%s\"\n", dest->options[i].name, dest->options[i].value);
221
222 return (1);
223}
224
225
104fd4ae
MS
226/*
227 * 'localize()' - Localize an option and value.
228 */
229
230static void
231localize(http_t *http, /* I - Connection to destination */
232 cups_dest_t *dest, /* I - Destination */
233 cups_dinfo_t *dinfo, /* I - Destination information */
234 const char *option, /* I - Option */
235 const char *value) /* I - Value, if any */
236{
237 (void)http;
238 (void)dest;
239 (void)dinfo;
240 (void)option;
241 (void)value;
242}
243
244
245/*
246 * 'print_file()' - Print a file.
247 */
248
249static void
250print_file(http_t *http, /* I - Connection to destination */
251 cups_dest_t *dest, /* I - Destination */
252 cups_dinfo_t *dinfo, /* I - Destination information */
253 const char *filename, /* I - File to print */
254 int num_options, /* I - Number of options */
255 cups_option_t *options) /* I - Options */
256{
257 (void)http;
258 (void)dest;
259 (void)dinfo;
260 (void)filename;
261 (void)num_options;
262 (void)options;
263}
264
265
266/*
267 * 'show_conflicts()' - Show conflicts for selected options.
268 */
269
270static void
271show_conflicts(
272 http_t *http, /* I - Connection to destination */
273 cups_dest_t *dest, /* I - Destination */
274 cups_dinfo_t *dinfo, /* I - Destination information */
275 int num_options, /* I - Number of options */
276 cups_option_t *options) /* I - Options */
277{
278 (void)http;
279 (void)dest;
280 (void)dinfo;
281 (void)num_options;
282 (void)options;
283}
284
285
286/*
287 * 'show_default()' - Show default value for option.
288 */
289
290static void
291show_default(http_t *http, /* I - Connection to destination */
292 cups_dest_t *dest, /* I - Destination */
293 cups_dinfo_t *dinfo, /* I - Destination information */
294 const char *option) /* I - Option */
295{
296 (void)http;
297 (void)dest;
298 (void)dinfo;
299 (void)option;
300}
301
302
303/*
304 * 'show_media()' - Show available media.
305 */
306
307static void
308show_media(http_t *http, /* I - Connection to destination */
309 cups_dest_t *dest, /* I - Destination */
310 cups_dinfo_t *dinfo, /* I - Destination information */
311 unsigned flags, /* I - Media flags */
312 const char *name) /* I - Size name */
313{
314 int i, /* Looping var */
315 count; /* Number of sizes */
316 cups_size_t size; /* Media size info */
317
318
319 if (name)
320 {
321 double dw, dl; /* Width and length from name */
322 char units[32]; /* Units */
323 int width, /* Width in 100ths of millimeters */
324 length; /* Length in 100ths of millimeters */
325
326
327 if (sscanf(name, "%lfx%lf%31s", &dw, &dl, units) == 3)
328 {
329 if (!strcmp(units, "in"))
330 {
331 width = (int)(dw * 2540.0);
332 length = (int)(dl * 2540.0);
333 }
334 else if (!strcmp(units, "mm"))
335 {
336 width = (int)(dw * 100.0);
337 length = (int)(dl * 100.0);
338 }
339 else
340 {
341 puts(" bad units in size");
342 return;
343 }
344
345 if (cupsGetDestMediaBySize(http, dest, dinfo, width, length, flags, &size))
346 {
347 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);
348 }
349 else
350 {
351 puts(" not supported");
352 }
353 }
354 else if (cupsGetDestMediaByName(http, dest, dinfo, name, flags, &size))
355 {
356 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);
357 }
358 else
359 {
360 puts(" not supported");
361 }
362 }
363 else
364 {
365 count = cupsGetDestMediaCount(http, dest, dinfo, flags);
366 printf("%d size%s:\n", count, count == 1 ? "" : "s");
367
368 for (i = 0; i < count; i ++)
369 {
370 if (cupsGetDestMediaByIndex(http, dest, dinfo, i, flags, &size))
371 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);
372 else
373 puts(" error");
374 }
375 }
376}
377
378
379/*
380 * 'show_supported()' - Show supported options, values, etc.
381 */
382
383static void
384show_supported(http_t *http, /* I - Connection to destination */
385 cups_dest_t *dest, /* I - Destination */
386 cups_dinfo_t *dinfo, /* I - Destination information */
387 const char *option, /* I - Option, if any */
388 const char *value) /* I - Value, if any */
389{
390 ipp_attribute_t *attr; /* Attribute */
391 int i, /* Looping var */
392 count; /* Number of values */
393
394
395 if (!option)
396 {
397 attr = cupsFindDestSupported(http, dest, dinfo, "job-creation-attributes");
398 if (attr)
399 {
400 count = ippGetCount(attr);
401 for (i = 0; i < count; i ++)
402 show_supported(http, dest, dinfo, ippGetString(attr, i, NULL), NULL);
403 }
404 else
405 {
406 static const char * const options[] =
407 { /* List of standard options */
408 CUPS_COPIES,
409 CUPS_FINISHINGS,
410 CUPS_MEDIA,
411 CUPS_NUMBER_UP,
412 CUPS_ORIENTATION,
413 CUPS_PRINT_COLOR_MODE,
414 CUPS_PRINT_QUALITY,
415 CUPS_SIDES
416 };
417
418 puts("No job-creation-attributes-supported attribute, probing instead.");
419
420 for (i = 0; i < (int)(sizeof(options) / sizeof(options[0])); i ++)
421 if (cupsCheckDestSupported(http, dest, dinfo, options[i], NULL))
422 show_supported(http, dest, dinfo, options[i], NULL);
423 }
424 }
425 else if (!value)
426 {
427 puts(option);
428 if ((attr = cupsFindDestSupported(http, dest, dinfo, option)) != NULL)
429 {
430 count = ippGetCount(attr);
431
432 switch (ippGetValueTag(attr))
433 {
434 case IPP_TAG_INTEGER :
435 for (i = 0; i < count; i ++)
436 printf(" %d\n", ippGetInteger(attr, i));
437 break;
438
439 case IPP_TAG_ENUM :
440 for (i = 0; i < count; i ++)
441 printf(" %s\n", ippEnumString(option, ippGetInteger(attr, i)));
442 break;
443
444 case IPP_TAG_RANGE :
445 for (i = 0; i < count; i ++)
446 {
447 int upper, lower = ippGetRange(attr, i, &upper);
448
449 printf(" %d-%d\n", lower, upper);
450 }
451 break;
452
4db7fcee
MS
453 case IPP_TAG_RESOLUTION :
454 for (i = 0; i < count; i ++)
455 {
456 int xres, yres;
457 ipp_res_t units;
458 xres = ippGetResolution(attr, i, &yres, &units);
459
460 if (xres == yres)
461 printf(" %d%s\n", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
462 else
463 printf(" %dx%d%s\n", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
464 }
465 break;
466
104fd4ae
MS
467 case IPP_TAG_TEXTLANG :
468 case IPP_TAG_NAMELANG :
469 case IPP_TAG_TEXT :
470 case IPP_TAG_NAME :
471 case IPP_TAG_KEYWORD :
472 case IPP_TAG_URI :
473 case IPP_TAG_URISCHEME :
474 case IPP_TAG_CHARSET :
475 case IPP_TAG_LANGUAGE :
476 case IPP_TAG_MIMETYPE :
477 for (i = 0; i < count; i ++)
478 printf(" %s\n", ippGetString(attr, i, NULL));
479 break;
480
481 case IPP_TAG_STRING :
482 for (i = 0; i < count; i ++)
483 {
484 int j, len;
485 unsigned char *data = ippGetOctetString(attr, i, &len);
486
487 fputs(" ", stdout);
488 for (j = 0; j < len; j ++)
489 {
490 if (data[j] < ' ' || data[j] >= 0x7f)
491 printf("<%02X>", data[j]);
492 else
493 putchar(data[j]);
494 }
495 putchar('\n');
496 }
497 break;
498
499 case IPP_TAG_BOOLEAN :
500 break;
501
502 default :
503 printf(" %s\n", ippTagString(ippGetValueTag(attr)));
504 break;
505 }
506 }
507
508 }
509 else if (cupsCheckDestSupported(http, dest, dinfo, option, value))
510 puts("YES");
511 else
512 puts("NO");
513
514}
515
516
517/*
518 * 'usage()' - Show program usage.
519 */
520
521static void
522usage(const char *arg) /* I - Argument for usage message */
523{
524 if (arg)
525 printf("testdest: Unknown option \"%s\".\n", arg);
526
527 puts("Usage:");
528 puts(" ./testdest name [operation ...]");
529 puts(" ./testdest ipp://... [operation ...]");
530 puts(" ./testdest ipps://... [operation ...]");
531 puts(" ./testdest --enum [grayscale] [color] [duplex] [staple] [small]\n"
532 " [medium] [large]");
533 puts("");
534 puts("Operations:");
535 puts(" conflicts options");
536 puts(" default option");
537 puts(" localize option [value]");
538 puts(" media [borderless] [duplex] [exact] [ready] [name or size]");
539 puts(" print filename [options]");
540 puts(" supported [option [value]]");
541
542 exit(arg != NULL);
543}
544
545
546/*
547 * End of "$Id$".
548 */