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