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