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