]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/testcups.c
Merge changes from CUPS 1.6svn-r10510.
[thirdparty/cups.git] / cups / testcups.c
1 /*
2 * "$Id$"
3 *
4 * CUPS API test program for CUPS.
5 *
6 * Copyright 2007-2012 by Apple Inc.
7 * Copyright 2007 by Easy Software Products.
8 *
9 * These coded instructions, statements, and computer programs are the
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/".
14 *
15 * This file is subject to the Apple OS-Developed Software exception.
16 *
17 * Contents:
18 *
19 * main() - Main entry.
20 * dests_equal() - Determine whether two destinations are equal.
21 */
22
23 /*
24 * Include necessary headers...
25 */
26
27 #include "string-private.h"
28 #include "cups.h"
29 #include "ppd.h"
30 #include <stdlib.h>
31
32
33 /*
34 * Local functions...
35 */
36
37 static int dests_equal(cups_dest_t *a, cups_dest_t *b);
38 static int enum_cb(void *user_data, unsigned flags, cups_dest_t *dest);
39 static void show_diffs(cups_dest_t *a, cups_dest_t *b);
40
41
42 /*
43 * 'main()' - Main entry.
44 */
45
46 int /* O - Exit status */
47 main(int argc, /* I - Number of command-line arguments */
48 char *argv[]) /* I - Command-line arguments */
49 {
50 int status = 0, /* Exit status */
51 i, /* Looping var */
52 num_dests; /* Number of destinations */
53 cups_dest_t *dests, /* Destinations */
54 *dest, /* Current destination */
55 *named_dest; /* Current named destination */
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
61
62 if (argc > 1)
63 {
64 if (!strcmp(argv[1], "enum"))
65 {
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);
162 }
163 else if (!strcmp(argv[1], "password"))
164 {
165 const char *pass = cupsGetPassword("Password:");
166 /* Password string */
167
168 if (pass)
169 printf("Password entered: %s\n", pass);
170 else
171 puts("No password entered.");
172 }
173 else if (!strcmp(argv[1], "print") && argc == 5)
174 {
175 /*
176 * ./testcups printer file interval
177 */
178
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 */
184
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 }
190
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]);
200
201 if (cupsStartDocument(CUPS_HTTP_DEFAULT, argv[1], job_id, argv[2],
202 CUPS_FORMAT_AUTO, 1) != HTTP_CONTINUE)
203 {
204 puts("Unable to start document!");
205 return (1);
206 }
207
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,
213 bytes) != HTTP_CONTINUE)
214 {
215 puts("Unable to write bytes!");
216 return (1);
217 }
218
219 if (interval > 0)
220 sleep(interval);
221 }
222
223 cupsFileClose(fp);
224
225 if (cupsFinishDocument(CUPS_HTTP_DEFAULT, argv[1]) > IPP_OK_SUBST)
226 {
227 puts("Unable to finish document!");
228 return (1);
229 }
230 }
231 else
232 {
233 puts("Usage:");
234 puts("");
235 puts("Run basic unit tests:");
236 puts("");
237 puts(" ./testcups");
238 puts("");
239 puts("Enumerate printers (for N seconds, -1 for indefinitely):");
240 puts("");
241 puts(" ./testcups enum [seconds]");
242 puts("");
243 puts("Ask for a password:");
244 puts("");
245 puts(" ./testcups password");
246 puts("");
247 puts("Print a file (interval controls delay between buffers in seconds):");
248 puts("");
249 puts(" ./testcups print printer file interval");
250 return (1);
251 }
252
253 return (0);
254 }
255
256 /*
257 * cupsGetDests()
258 */
259
260 fputs("cupsGetDests: ", stdout);
261 fflush(stdout);
262
263 num_dests = cupsGetDests(&dests);
264
265 if (num_dests == 0)
266 {
267 puts("FAIL");
268 return (1);
269 }
270 else
271 {
272 printf("PASS (%d dests)\n", num_dests);
273
274 for (i = num_dests, dest = dests; i > 0; i --, dest ++)
275 {
276 printf(" %s", dest->name);
277
278 if (dest->instance)
279 printf(" /%s", dest->instance);
280
281 if (dest->is_default)
282 puts(" ***DEFAULT***");
283 else
284 putchar('\n');
285 }
286 }
287
288 /*
289 * cupsGetDest(NULL)
290 */
291
292 fputs("cupsGetDest(NULL): ", stdout);
293 fflush(stdout);
294
295 if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
296 {
297 for (i = num_dests, dest = dests; i > 0; i --, dest ++)
298 if (dest->is_default)
299 break;
300
301 if (i)
302 {
303 status = 1;
304 puts("FAIL");
305 }
306 else
307 puts("PASS (no default)");
308
309 dest = NULL;
310 }
311 else
312 printf("PASS (%s)\n", dest->name);
313
314 /*
315 * cupsGetNamedDest(NULL, NULL, NULL)
316 */
317
318 fputs("cupsGetNamedDest(NULL, NULL, NULL): ", stdout);
319 fflush(stdout);
320
321 if ((named_dest = cupsGetNamedDest(NULL, NULL, NULL)) == NULL ||
322 !dests_equal(dest, named_dest))
323 {
324 if (!dest)
325 puts("PASS (no default)");
326 else if (named_dest)
327 {
328 puts("FAIL (different values)");
329 show_diffs(dest, named_dest);
330 status = 1;
331 }
332 else
333 {
334 puts("FAIL (no default)");
335 status = 1;
336 }
337 }
338 else
339 printf("PASS (%s)\n", named_dest->name);
340
341 if (named_dest)
342 cupsFreeDests(1, named_dest);
343
344 /*
345 * cupsGetDest(printer)
346 */
347
348 printf("cupsGetDest(\"%s\"): ", dests[num_dests / 2].name);
349 fflush(stdout);
350
351 if ((dest = cupsGetDest(dests[num_dests / 2].name, NULL, num_dests,
352 dests)) == NULL)
353 {
354 puts("FAIL");
355 return (1);
356 }
357 else
358 puts("PASS");
359
360 /*
361 * cupsGetNamedDest(NULL, printer, instance)
362 */
363
364 printf("cupsGetNamedDest(NULL, \"%s\", \"%s\"): ", dest->name,
365 dest->instance ? dest->instance : "(null)");
366 fflush(stdout);
367
368 if ((named_dest = cupsGetNamedDest(NULL, dest->name,
369 dest->instance)) == NULL ||
370 !dests_equal(dest, named_dest))
371 {
372 if (named_dest)
373 {
374 puts("FAIL (different values)");
375 show_diffs(dest, named_dest);
376 }
377 else
378 puts("FAIL (no destination)");
379
380
381 status = 1;
382 }
383 else
384 puts("PASS");
385
386 if (named_dest)
387 cupsFreeDests(1, named_dest);
388
389 /*
390 * cupsPrintFile()
391 */
392
393 fputs("cupsPrintFile: ", stdout);
394 fflush(stdout);
395
396 if (cupsPrintFile(dest->name, "../data/testprint", "Test Page",
397 dest->num_options, dest->options) <= 0)
398 {
399 printf("FAIL (%s)\n", cupsLastErrorString());
400 return (1);
401 }
402 else
403 puts("PASS");
404
405 /*
406 * cupsGetPPD(printer)
407 */
408
409 fputs("cupsGetPPD(): ", stdout);
410 fflush(stdout);
411
412 if ((ppdfile = cupsGetPPD(dest->name)) == NULL)
413 {
414 puts("FAIL");
415 }
416 else
417 {
418 puts("PASS");
419
420 /*
421 * ppdOpenFile()
422 */
423
424 fputs("ppdOpenFile(): ", stdout);
425 fflush(stdout);
426
427 if ((ppd = ppdOpenFile(ppdfile)) == NULL)
428 {
429 puts("FAIL");
430 return (1);
431 }
432 else
433 puts("PASS");
434
435 ppdClose(ppd);
436 unlink(ppdfile);
437 }
438
439 /*
440 * cupsGetJobs()
441 */
442
443 fputs("cupsGetJobs: ", stdout);
444 fflush(stdout);
445
446 num_jobs = cupsGetJobs(&jobs, NULL, 0, -1);
447
448 if (num_jobs == 0)
449 {
450 puts("FAIL");
451 return (1);
452 }
453 else
454 puts("PASS");
455
456 cupsFreeJobs(num_jobs, jobs);
457 cupsFreeDests(num_dests, dests);
458
459 return (status);
460 }
461
462
463 /*
464 * 'dests_equal()' - Determine whether two destinations are equal.
465 */
466
467 static int /* O - 1 if equal, 0 if not equal */
468 dests_equal(cups_dest_t *a, /* I - First destination */
469 cups_dest_t *b) /* I - Second destination */
470 {
471 int i; /* Looping var */
472 cups_option_t *aoption; /* Current option */
473 const char *bval; /* Option value */
474
475
476 if (a == b)
477 return (1);
478
479 if (!a || !b)
480 return (0);
481
482 if (_cups_strcasecmp(a->name, b->name) ||
483 (a->instance && !b->instance) ||
484 (!a->instance && b->instance) ||
485 (a->instance && _cups_strcasecmp(a->instance, b->instance)) ||
486 a->num_options != b->num_options)
487 return (0);
488
489 for (i = a->num_options, aoption = a->options; i > 0; i --, aoption ++)
490 if ((bval = cupsGetOption(aoption->name, b->num_options,
491 b->options)) == NULL ||
492 strcmp(aoption->value, bval))
493 return (0);
494
495 return (1);
496 }
497
498
499 /*
500 * 'enum_cb()' - Report additions and removals.
501 */
502
503 static int /* O - 1 to continue, 0 to stop */
504 enum_cb(void *user_data, /* I - User data (unused) */
505 unsigned flags, /* I - Destination flags */
506 cups_dest_t *dest) /* I - Destination */
507 {
508 int i; /* Looping var */
509 cups_option_t *option; /* Current option */
510
511
512 if (flags & CUPS_DEST_FLAGS_REMOVED)
513 printf("Removed '%s':\n", dest->name);
514 else
515 printf("Added '%s':\n", dest->name);
516
517 for (i = dest->num_options, option = dest->options; i > 0; i --, option ++)
518 printf(" %s=\"%s\"\n", option->name, option->value);
519
520 putchar('\n');
521
522 return (1);
523 }
524
525
526 /*
527 * 'show_diffs()' - Show differences between two destinations.
528 */
529
530 static void
531 show_diffs(cups_dest_t *a, /* I - First destination */
532 cups_dest_t *b) /* I - Second destination */
533 {
534 int i; /* Looping var */
535 cups_option_t *aoption; /* Current option */
536 const char *bval; /* Option value */
537
538
539 if (!a || !b)
540 return;
541
542 puts(" Item cupsGetDest cupsGetNamedDest");
543 puts(" -------------------- -------------------- --------------------");
544
545 if (_cups_strcasecmp(a->name, b->name))
546 printf(" name %-20.20s %-20.20s\n", a->name, b->name);
547
548 if ((a->instance && !b->instance) ||
549 (!a->instance && b->instance) ||
550 (a->instance && _cups_strcasecmp(a->instance, b->instance)))
551 printf(" instance %-20.20s %-20.20s\n",
552 a->instance ? a->instance : "(null)",
553 b->instance ? b->instance : "(null)");
554
555 if (a->num_options != b->num_options)
556 printf(" num_options %-20d %-20d\n", a->num_options,
557 b->num_options);
558
559 for (i = a->num_options, aoption = a->options; i > 0; i --, aoption ++)
560 if ((bval = cupsGetOption(aoption->name, b->num_options,
561 b->options)) == NULL ||
562 strcmp(aoption->value, bval))
563 printf(" %-20.20s %-20.20s %-20.20s\n", aoption->name,
564 aoption->value, bval ? bval : "(null)");
565 }
566
567
568 /*
569 * End of "$Id$".
570 */