]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/testcups.c
ARM-based Linux doesn't allow pointer comparisons on va_list values; not sure
[thirdparty/cups.git] / cups / testcups.c
CommitLineData
09a101d6 1/*
2 * "$Id$"
3 *
71e16022 4 * CUPS API test program for CUPS.
09a101d6 5 *
cb7f98ee 6 * Copyright 2007-2013 by Apple Inc.
09a101d6 7 * Copyright 2007 by Easy Software Products.
8 *
9 * These coded instructions, statements, and computer programs are the
bc44d920 10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
09a101d6 14 *
15 * This file is subject to the Apple OS-Developed Software exception.
16 *
17 * Contents:
18 *
a4924f6c
MS
19 * main() - Main entry.
20 * dests_equal() - Determine whether two destinations are equal.
09a101d6 21 */
22
23/*
24 * Include necessary headers...
25 */
26
71e16022 27#include "string-private.h"
09a101d6 28#include "cups.h"
aaf19ab0 29#include "ppd.h"
71e16022 30#include <stdlib.h>
09a101d6 31
32
a4924f6c
MS
33/*
34 * Local functions...
35 */
36
37static int dests_equal(cups_dest_t *a, cups_dest_t *b);
dcb445bc 38static int enum_cb(void *user_data, unsigned flags, cups_dest_t *dest);
a4924f6c
MS
39static void show_diffs(cups_dest_t *a, cups_dest_t *b);
40
41
09a101d6 42/*
43 * 'main()' - Main entry.
44 */
45
46int /* O - Exit status */
47main(int argc, /* I - Number of command-line arguments */
48 char *argv[]) /* I - Command-line arguments */
49{
50 int status = 0, /* Exit status */
a4924f6c 51 i, /* Looping var */
09a101d6 52 num_dests; /* Number of destinations */
53 cups_dest_t *dests, /* Destinations */
a4924f6c
MS
54 *dest, /* Current destination */
55 *named_dest; /* Current named destination */
09a101d6 56 const char *ppdfile; /* PPD file */
57 ppd_file_t *ppd; /* PPD file data */
58 int num_jobs; /* Number of jobs for queue */
59 cups_job_t *jobs; /* Jobs for queue */
60
a29fd7dd 61
dfd5680b
MS
62 if (argc > 1)
63 {
dcb445bc
MS
64 if (!strcmp(argv[1], "enum"))
65 {
a29fd7dd
MS
66 cups_ptype_t mask = CUPS_PRINTER_LOCAL,
67 /* Printer type mask */
68 type = CUPS_PRINTER_LOCAL;
69 /* Printer type */
70 int msec = 0; /* Timeout in milliseconds */
71
72
73 for (i = 2; i < argc; i ++)
74 if (isdigit(argv[i][0] & 255) || argv[i][0] == '.')
75 msec = (int)(atof(argv[i]) * 1000);
76 else if (!_cups_strcasecmp(argv[i], "bw"))
77 {
78 mask |= CUPS_PRINTER_BW;
79 type |= CUPS_PRINTER_BW;
80 }
81 else if (!_cups_strcasecmp(argv[i], "color"))
82 {
83 mask |= CUPS_PRINTER_COLOR;
84 type |= CUPS_PRINTER_COLOR;
85 }
86 else if (!_cups_strcasecmp(argv[i], "mono"))
87 {
88 mask |= CUPS_PRINTER_COLOR;
89 }
90 else if (!_cups_strcasecmp(argv[i], "duplex"))
91 {
92 mask |= CUPS_PRINTER_DUPLEX;
93 type |= CUPS_PRINTER_DUPLEX;
94 }
95 else if (!_cups_strcasecmp(argv[i], "simplex"))
96 {
97 mask |= CUPS_PRINTER_DUPLEX;
98 }
99 else if (!_cups_strcasecmp(argv[i], "staple"))
100 {
101 mask |= CUPS_PRINTER_STAPLE;
102 type |= CUPS_PRINTER_STAPLE;
103 }
104 else if (!_cups_strcasecmp(argv[i], "copies"))
105 {
106 mask |= CUPS_PRINTER_COPIES;
107 type |= CUPS_PRINTER_COPIES;
108 }
109 else if (!_cups_strcasecmp(argv[i], "collate"))
110 {
111 mask |= CUPS_PRINTER_COLLATE;
112 type |= CUPS_PRINTER_COLLATE;
113 }
114 else if (!_cups_strcasecmp(argv[i], "punch"))
115 {
116 mask |= CUPS_PRINTER_PUNCH;
117 type |= CUPS_PRINTER_PUNCH;
118 }
119 else if (!_cups_strcasecmp(argv[i], "cover"))
120 {
121 mask |= CUPS_PRINTER_COVER;
122 type |= CUPS_PRINTER_COVER;
123 }
124 else if (!_cups_strcasecmp(argv[i], "bind"))
125 {
126 mask |= CUPS_PRINTER_BIND;
127 type |= CUPS_PRINTER_BIND;
128 }
129 else if (!_cups_strcasecmp(argv[i], "sort"))
130 {
131 mask |= CUPS_PRINTER_SORT;
132 type |= CUPS_PRINTER_SORT;
133 }
134 else if (!_cups_strcasecmp(argv[i], "mfp"))
135 {
136 mask |= CUPS_PRINTER_MFP;
137 type |= CUPS_PRINTER_MFP;
138 }
139 else if (!_cups_strcasecmp(argv[i], "printer"))
140 {
141 mask |= CUPS_PRINTER_MFP;
142 }
143 else if (!_cups_strcasecmp(argv[i], "large"))
144 {
145 mask |= CUPS_PRINTER_LARGE;
146 type |= CUPS_PRINTER_LARGE;
147 }
148 else if (!_cups_strcasecmp(argv[i], "medium"))
149 {
150 mask |= CUPS_PRINTER_MEDIUM;
151 type |= CUPS_PRINTER_MEDIUM;
152 }
153 else if (!_cups_strcasecmp(argv[i], "small"))
154 {
155 mask |= CUPS_PRINTER_SMALL;
156 type |= CUPS_PRINTER_SMALL;
157 }
158 else
159 fprintf(stderr, "Unknown argument \"%s\" ignored...\n", argv[i]);
160
161 cupsEnumDests(CUPS_DEST_FLAGS_NONE, msec, NULL, type, mask, enum_cb, NULL);
dfd5680b 162 }
dcb445bc 163 else if (!strcmp(argv[1], "password"))
dfd5680b 164 {
dcb445bc
MS
165 const char *pass = cupsGetPassword("Password:");
166 /* Password string */
dfd5680b 167
dcb445bc
MS
168 if (pass)
169 printf("Password entered: %s\n", pass);
170 else
171 puts("No password entered.");
dfd5680b 172 }
dcb445bc
MS
173 else if (!strcmp(argv[1], "print") && argc == 5)
174 {
175 /*
176 * ./testcups printer file interval
177 */
aaf19ab0 178
dcb445bc
MS
179 int interval, /* Interval between writes */
180 job_id; /* Job ID */
181 cups_file_t *fp; /* Print file */
182 char buffer[16384]; /* Read/write buffer */
183 ssize_t bytes; /* Bytes read/written */
dfd5680b 184
dcb445bc
MS
185 if ((fp = cupsFileOpen(argv[3], "r")) == NULL)
186 {
187 printf("Unable to open \"%s\": %s\n", argv[2], strerror(errno));
188 return (1);
189 }
dfd5680b 190
dcb445bc
MS
191 if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, argv[2], "testcups", 0,
192 NULL)) <= 0)
193 {
194 printf("Unable to create print job on %s: %s\n", argv[1],
195 cupsLastErrorString());
196 return (1);
197 }
198
199 interval = atoi(argv[4]);
dfd5680b 200
dcb445bc 201 if (cupsStartDocument(CUPS_HTTP_DEFAULT, argv[1], job_id, argv[2],
cb7f98ee 202 CUPS_FORMAT_AUTO, 1) != HTTP_STATUS_CONTINUE)
dfd5680b 203 {
dcb445bc 204 puts("Unable to start document!");
dfd5680b
MS
205 return (1);
206 }
207
dcb445bc
MS
208 while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0)
209 {
210 printf("Writing %d bytes...\n", (int)bytes);
211
212 if (cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer,
cb7f98ee 213 bytes) != HTTP_STATUS_CONTINUE)
dcb445bc
MS
214 {
215 puts("Unable to write bytes!");
216 return (1);
217 }
dfd5680b 218
dcb445bc
MS
219 if (interval > 0)
220 sleep(interval);
221 }
222
223 cupsFileClose(fp);
dfd5680b 224
cb7f98ee
MS
225 if (cupsFinishDocument(CUPS_HTTP_DEFAULT,
226 argv[1]) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED)
dcb445bc
MS
227 {
228 puts("Unable to finish document!");
229 return (1);
230 }
231 }
232 else
dfd5680b 233 {
dcb445bc
MS
234 puts("Usage:");
235 puts("");
236 puts("Run basic unit tests:");
237 puts("");
238 puts(" ./testcups");
239 puts("");
240 puts("Enumerate printers (for N seconds, -1 for indefinitely):");
241 puts("");
242 puts(" ./testcups enum [seconds]");
243 puts("");
244 puts("Ask for a password:");
245 puts("");
246 puts(" ./testcups password");
247 puts("");
248 puts("Print a file (interval controls delay between buffers in seconds):");
249 puts("");
250 puts(" ./testcups print printer file interval");
dfd5680b
MS
251 return (1);
252 }
253
254 return (0);
255 }
256
09a101d6 257 /*
258 * cupsGetDests()
259 */
260
261 fputs("cupsGetDests: ", stdout);
262 fflush(stdout);
263
264 num_dests = cupsGetDests(&dests);
265
266 if (num_dests == 0)
267 {
268 puts("FAIL");
269 return (1);
270 }
271 else
a4924f6c
MS
272 {
273 printf("PASS (%d dests)\n", num_dests);
274
275 for (i = num_dests, dest = dests; i > 0; i --, dest ++)
276 {
277 printf(" %s", dest->name);
278
279 if (dest->instance)
280 printf(" /%s", dest->instance);
281
282 if (dest->is_default)
283 puts(" ***DEFAULT***");
284 else
285 putchar('\n');
286 }
287 }
288
289 /*
290 * cupsGetDest(NULL)
291 */
292
293 fputs("cupsGetDest(NULL): ", stdout);
294 fflush(stdout);
295
296 if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
297 {
298 for (i = num_dests, dest = dests; i > 0; i --, dest ++)
299 if (dest->is_default)
300 break;
301
302 if (i)
303 {
304 status = 1;
305 puts("FAIL");
306 }
307 else
308 puts("PASS (no default)");
309
310 dest = NULL;
311 }
312 else
313 printf("PASS (%s)\n", dest->name);
314
315 /*
316 * cupsGetNamedDest(NULL, NULL, NULL)
317 */
318
319 fputs("cupsGetNamedDest(NULL, NULL, NULL): ", stdout);
320 fflush(stdout);
321
322 if ((named_dest = cupsGetNamedDest(NULL, NULL, NULL)) == NULL ||
323 !dests_equal(dest, named_dest))
324 {
325 if (!dest)
326 puts("PASS (no default)");
327 else if (named_dest)
328 {
329 puts("FAIL (different values)");
330 show_diffs(dest, named_dest);
331 status = 1;
332 }
333 else
334 {
335 puts("FAIL (no default)");
336 status = 1;
337 }
338 }
339 else
340 printf("PASS (%s)\n", named_dest->name);
341
342 if (named_dest)
343 cupsFreeDests(1, named_dest);
09a101d6 344
345 /*
346 * cupsGetDest(printer)
347 */
348
349 printf("cupsGetDest(\"%s\"): ", dests[num_dests / 2].name);
350 fflush(stdout);
351
352 if ((dest = cupsGetDest(dests[num_dests / 2].name, NULL, num_dests,
353 dests)) == NULL)
354 {
09a101d6 355 puts("FAIL");
91c84a35 356 return (1);
09a101d6 357 }
358 else
359 puts("PASS");
360
361 /*
a4924f6c 362 * cupsGetNamedDest(NULL, printer, instance)
09a101d6 363 */
364
a4924f6c
MS
365 printf("cupsGetNamedDest(NULL, \"%s\", \"%s\"): ", dest->name,
366 dest->instance ? dest->instance : "(null)");
09a101d6 367 fflush(stdout);
368
a4924f6c
MS
369 if ((named_dest = cupsGetNamedDest(NULL, dest->name,
370 dest->instance)) == NULL ||
371 !dests_equal(dest, named_dest))
09a101d6 372 {
a4924f6c
MS
373 if (named_dest)
374 {
375 puts("FAIL (different values)");
376 show_diffs(dest, named_dest);
377 }
378 else
379 puts("FAIL (no destination)");
380
381
09a101d6 382 status = 1;
09a101d6 383 }
384 else
385 puts("PASS");
386
a4924f6c
MS
387 if (named_dest)
388 cupsFreeDests(1, named_dest);
389
09a101d6 390 /*
391 * cupsPrintFile()
392 */
393
394 fputs("cupsPrintFile: ", stdout);
395 fflush(stdout);
396
426c6a59 397 if (cupsPrintFile(dest->name, "../data/testprint", "Test Page",
09a101d6 398 dest->num_options, dest->options) <= 0)
399 {
426c6a59 400 printf("FAIL (%s)\n", cupsLastErrorString());
1f0275e3 401 return (1);
09a101d6 402 }
403 else
404 puts("PASS");
405
406 /*
407 * cupsGetPPD(printer)
408 */
409
410 fputs("cupsGetPPD(): ", stdout);
411 fflush(stdout);
412
413 if ((ppdfile = cupsGetPPD(dest->name)) == NULL)
414 {
09a101d6 415 puts("FAIL");
416 }
417 else
418 {
419 puts("PASS");
420
421 /*
422 * ppdOpenFile()
423 */
424
425 fputs("ppdOpenFile(): ", stdout);
426 fflush(stdout);
427
428 if ((ppd = ppdOpenFile(ppdfile)) == NULL)
429 {
430 puts("FAIL");
431 return (1);
432 }
433 else
434 puts("PASS");
435
436 ppdClose(ppd);
437 unlink(ppdfile);
438 }
439
440 /*
441 * cupsGetJobs()
442 */
443
444 fputs("cupsGetJobs: ", stdout);
445 fflush(stdout);
446
447 num_jobs = cupsGetJobs(&jobs, NULL, 0, -1);
448
449 if (num_jobs == 0)
450 {
451 puts("FAIL");
452 return (1);
453 }
454 else
455 puts("PASS");
456
457 cupsFreeJobs(num_jobs, jobs);
458 cupsFreeDests(num_dests, dests);
459
460 return (status);
461}
462
463
a4924f6c
MS
464/*
465 * 'dests_equal()' - Determine whether two destinations are equal.
466 */
467
468static int /* O - 1 if equal, 0 if not equal */
469dests_equal(cups_dest_t *a, /* I - First destination */
470 cups_dest_t *b) /* I - Second destination */
471{
472 int i; /* Looping var */
473 cups_option_t *aoption; /* Current option */
474 const char *bval; /* Option value */
475
476
477 if (a == b)
478 return (1);
479
1f0275e3 480 if (!a || !b)
a4924f6c
MS
481 return (0);
482
88f9aafc 483 if (_cups_strcasecmp(a->name, b->name) ||
a4924f6c
MS
484 (a->instance && !b->instance) ||
485 (!a->instance && b->instance) ||
88f9aafc 486 (a->instance && _cups_strcasecmp(a->instance, b->instance)) ||
a4924f6c
MS
487 a->num_options != b->num_options)
488 return (0);
489
490 for (i = a->num_options, aoption = a->options; i > 0; i --, aoption ++)
491 if ((bval = cupsGetOption(aoption->name, b->num_options,
492 b->options)) == NULL ||
493 strcmp(aoption->value, bval))
494 return (0);
495
496 return (1);
497}
498
499
dcb445bc
MS
500/*
501 * 'enum_cb()' - Report additions and removals.
502 */
503
504static int /* O - 1 to continue, 0 to stop */
505enum_cb(void *user_data, /* I - User data (unused) */
506 unsigned flags, /* I - Destination flags */
507 cups_dest_t *dest) /* I - Destination */
508{
a29fd7dd
MS
509 int i; /* Looping var */
510 cups_option_t *option; /* Current option */
511
512
dcb445bc 513 if (flags & CUPS_DEST_FLAGS_REMOVED)
a29fd7dd 514 printf("Removed '%s':\n", dest->name);
dcb445bc 515 else
a29fd7dd
MS
516 printf("Added '%s':\n", dest->name);
517
518 for (i = dest->num_options, option = dest->options; i > 0; i --, option ++)
519 printf(" %s=\"%s\"\n", option->name, option->value);
520
521 putchar('\n');
dcb445bc
MS
522
523 return (1);
524}
525
526
a4924f6c
MS
527/*
528 * 'show_diffs()' - Show differences between two destinations.
529 */
530
531static void
532show_diffs(cups_dest_t *a, /* I - First destination */
533 cups_dest_t *b) /* I - Second destination */
534{
535 int i; /* Looping var */
536 cups_option_t *aoption; /* Current option */
537 const char *bval; /* Option value */
538
539
540 if (!a || !b)
541 return;
542
543 puts(" Item cupsGetDest cupsGetNamedDest");
544 puts(" -------------------- -------------------- --------------------");
545
88f9aafc 546 if (_cups_strcasecmp(a->name, b->name))
a4924f6c
MS
547 printf(" name %-20.20s %-20.20s\n", a->name, b->name);
548
549 if ((a->instance && !b->instance) ||
550 (!a->instance && b->instance) ||
88f9aafc 551 (a->instance && _cups_strcasecmp(a->instance, b->instance)))
a4924f6c
MS
552 printf(" instance %-20.20s %-20.20s\n",
553 a->instance ? a->instance : "(null)",
554 b->instance ? b->instance : "(null)");
555
556 if (a->num_options != b->num_options)
557 printf(" num_options %-20d %-20d\n", a->num_options,
558 b->num_options);
559
560 for (i = a->num_options, aoption = a->options; i > 0; i --, aoption ++)
561 if ((bval = cupsGetOption(aoption->name, b->num_options,
562 b->options)) == NULL ||
563 strcmp(aoption->value, bval))
564 printf(" %-20.20s %-20.20s %-20.20s\n", aoption->name,
565 aoption->value, bval ? bval : "(null)");
566}
567
568
09a101d6 569/*
1f0275e3 570 * End of "$Id$".
09a101d6 571 */