2 * CUPS API test program for CUPS.
4 * Copyright 2007-2014 by Apple Inc.
5 * Copyright 2007 by Easy Software Products.
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
11 * file is missing or damaged, see the license at "http://www.cups.org/".
13 * This file is subject to the Apple OS-Developed Software exception.
17 * Include necessary headers...
20 #undef _CUPS_NO_DEPRECATED
21 #include "string-private.h"
31 static int dests_equal(cups_dest_t
*a
, cups_dest_t
*b
);
32 static int enum_cb(void *user_data
, unsigned flags
, cups_dest_t
*dest
);
33 static void show_diffs(cups_dest_t
*a
, cups_dest_t
*b
);
37 * 'main()' - Main entry.
40 int /* O - Exit status */
41 main(int argc
, /* I - Number of command-line arguments */
42 char *argv
[]) /* I - Command-line arguments */
44 int status
= 0, /* Exit status */
46 num_dests
; /* Number of destinations */
47 cups_dest_t
*dests
, /* Destinations */
48 *dest
, /* Current destination */
49 *named_dest
; /* Current named destination */
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 */
58 if (!strcmp(argv
[1], "enum"))
60 cups_ptype_t mask
= CUPS_PRINTER_LOCAL
,
61 /* Printer type mask */
62 type
= CUPS_PRINTER_LOCAL
;
64 int msec
= 0; /* Timeout in milliseconds */
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"))
72 mask
|= CUPS_PRINTER_BW
;
73 type
|= CUPS_PRINTER_BW
;
75 else if (!_cups_strcasecmp(argv
[i
], "color"))
77 mask
|= CUPS_PRINTER_COLOR
;
78 type
|= CUPS_PRINTER_COLOR
;
80 else if (!_cups_strcasecmp(argv
[i
], "mono"))
82 mask
|= CUPS_PRINTER_COLOR
;
84 else if (!_cups_strcasecmp(argv
[i
], "duplex"))
86 mask
|= CUPS_PRINTER_DUPLEX
;
87 type
|= CUPS_PRINTER_DUPLEX
;
89 else if (!_cups_strcasecmp(argv
[i
], "simplex"))
91 mask
|= CUPS_PRINTER_DUPLEX
;
93 else if (!_cups_strcasecmp(argv
[i
], "staple"))
95 mask
|= CUPS_PRINTER_STAPLE
;
96 type
|= CUPS_PRINTER_STAPLE
;
98 else if (!_cups_strcasecmp(argv
[i
], "copies"))
100 mask
|= CUPS_PRINTER_COPIES
;
101 type
|= CUPS_PRINTER_COPIES
;
103 else if (!_cups_strcasecmp(argv
[i
], "collate"))
105 mask
|= CUPS_PRINTER_COLLATE
;
106 type
|= CUPS_PRINTER_COLLATE
;
108 else if (!_cups_strcasecmp(argv
[i
], "punch"))
110 mask
|= CUPS_PRINTER_PUNCH
;
111 type
|= CUPS_PRINTER_PUNCH
;
113 else if (!_cups_strcasecmp(argv
[i
], "cover"))
115 mask
|= CUPS_PRINTER_COVER
;
116 type
|= CUPS_PRINTER_COVER
;
118 else if (!_cups_strcasecmp(argv
[i
], "bind"))
120 mask
|= CUPS_PRINTER_BIND
;
121 type
|= CUPS_PRINTER_BIND
;
123 else if (!_cups_strcasecmp(argv
[i
], "sort"))
125 mask
|= CUPS_PRINTER_SORT
;
126 type
|= CUPS_PRINTER_SORT
;
128 else if (!_cups_strcasecmp(argv
[i
], "mfp"))
130 mask
|= CUPS_PRINTER_MFP
;
131 type
|= CUPS_PRINTER_MFP
;
133 else if (!_cups_strcasecmp(argv
[i
], "printer"))
135 mask
|= CUPS_PRINTER_MFP
;
137 else if (!_cups_strcasecmp(argv
[i
], "large"))
139 mask
|= CUPS_PRINTER_LARGE
;
140 type
|= CUPS_PRINTER_LARGE
;
142 else if (!_cups_strcasecmp(argv
[i
], "medium"))
144 mask
|= CUPS_PRINTER_MEDIUM
;
145 type
|= CUPS_PRINTER_MEDIUM
;
147 else if (!_cups_strcasecmp(argv
[i
], "small"))
149 mask
|= CUPS_PRINTER_SMALL
;
150 type
|= CUPS_PRINTER_SMALL
;
153 fprintf(stderr
, "Unknown argument \"%s\" ignored...\n", argv
[i
]);
155 cupsEnumDests(CUPS_DEST_FLAGS_NONE
, msec
, NULL
, type
, mask
, enum_cb
, NULL
);
157 else if (!strcmp(argv
[1], "password"))
159 const char *pass
= cupsGetPassword("Password:");
160 /* Password string */
163 printf("Password entered: %s\n", pass
);
165 puts("No password entered.");
167 else if (!strcmp(argv
[1], "ppd") && argc
== 3)
170 * ./testcups ppd printer
173 http_status_t http_status
; /* Status */
174 char buffer
[1024]; /* PPD filename */
175 time_t modtime
= 0; /* Last modified */
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());
184 else if (!strcmp(argv
[1], "print") && argc
== 5)
187 * ./testcups print printer file interval
190 int interval
, /* Interval between writes */
192 cups_file_t
*fp
; /* Print file */
193 char buffer
[16384]; /* Read/write buffer */
194 ssize_t bytes
; /* Bytes read/written */
196 if ((fp
= cupsFileOpen(argv
[3], "r")) == NULL
)
198 printf("Unable to open \"%s\": %s\n", argv
[2], strerror(errno
));
202 if ((job_id
= cupsCreateJob(CUPS_HTTP_DEFAULT
, argv
[2], "testcups", 0,
205 printf("Unable to create print job on %s: %s\n", argv
[1],
206 cupsLastErrorString());
210 interval
= atoi(argv
[4]);
212 if (cupsStartDocument(CUPS_HTTP_DEFAULT
, argv
[1], job_id
, argv
[2],
213 CUPS_FORMAT_AUTO
, 1) != HTTP_STATUS_CONTINUE
)
215 puts("Unable to start document!");
219 while ((bytes
= cupsFileRead(fp
, buffer
, sizeof(buffer
))) > 0)
221 printf("Writing %d bytes...\n", (int)bytes
);
223 if (cupsWriteRequestData(CUPS_HTTP_DEFAULT
, buffer
, (size_t)bytes
) != HTTP_STATUS_CONTINUE
)
225 puts("Unable to write bytes!");
230 sleep((unsigned)interval
);
235 if (cupsFinishDocument(CUPS_HTTP_DEFAULT
,
236 argv
[1]) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED
)
238 puts("Unable to finish document!");
246 puts("Run basic unit tests:");
250 puts("Enumerate printers (for N seconds, -1 for indefinitely):");
252 puts(" ./testcups enum [seconds]");
254 puts("Ask for a password:");
256 puts(" ./testcups password");
258 puts("Get the PPD file:");
260 puts(" ./testcups ppd printer");
262 puts("Print a file (interval controls delay between buffers in seconds):");
264 puts(" ./testcups print printer file interval");
275 fputs("cupsGetDests: ", stdout
);
278 num_dests
= cupsGetDests(&dests
);
287 printf("PASS (%d dests)\n", num_dests
);
289 for (i
= num_dests
, dest
= dests
; i
> 0; i
--, dest
++)
291 printf(" %s", dest
->name
);
294 printf(" /%s", dest
->instance
);
296 if (dest
->is_default
)
297 puts(" ***DEFAULT***");
307 fputs("cupsGetDest(NULL): ", stdout
);
310 if ((dest
= cupsGetDest(NULL
, NULL
, num_dests
, dests
)) == NULL
)
312 for (i
= num_dests
, dest
= dests
; i
> 0; i
--, dest
++)
313 if (dest
->is_default
)
322 puts("PASS (no default)");
327 printf("PASS (%s)\n", dest
->name
);
330 * cupsGetNamedDest(NULL, NULL, NULL)
333 fputs("cupsGetNamedDest(NULL, NULL, NULL): ", stdout
);
336 if ((named_dest
= cupsGetNamedDest(NULL
, NULL
, NULL
)) == NULL
||
337 !dests_equal(dest
, named_dest
))
340 puts("PASS (no default)");
343 puts("FAIL (different values)");
344 show_diffs(dest
, named_dest
);
349 puts("FAIL (no default)");
354 printf("PASS (%s)\n", named_dest
->name
);
357 cupsFreeDests(1, named_dest
);
360 * cupsGetDest(printer)
363 printf("cupsGetDest(\"%s\"): ", dests
[num_dests
/ 2].name
);
366 if ((dest
= cupsGetDest(dests
[num_dests
/ 2].name
, NULL
, num_dests
,
376 * cupsGetNamedDest(NULL, printer, instance)
379 printf("cupsGetNamedDest(NULL, \"%s\", \"%s\"): ", dest
->name
,
380 dest
->instance
? dest
->instance
: "(null)");
383 if ((named_dest
= cupsGetNamedDest(NULL
, dest
->name
,
384 dest
->instance
)) == NULL
||
385 !dests_equal(dest
, named_dest
))
389 puts("FAIL (different values)");
390 show_diffs(dest
, named_dest
);
393 puts("FAIL (no destination)");
402 cupsFreeDests(1, named_dest
);
408 fputs("cupsPrintFile: ", stdout
);
411 if (cupsPrintFile(dest
->name
, "../data/testprint", "Test Page",
412 dest
->num_options
, dest
->options
) <= 0)
414 printf("FAIL (%s)\n", cupsLastErrorString());
421 * cupsGetPPD(printer)
424 fputs("cupsGetPPD(): ", stdout
);
427 if ((ppdfile
= cupsGetPPD(dest
->name
)) == NULL
)
439 fputs("ppdOpenFile(): ", stdout
);
442 if ((ppd
= ppdOpenFile(ppdfile
)) == NULL
)
458 fputs("cupsGetJobs: ", stdout
);
461 num_jobs
= cupsGetJobs(&jobs
, NULL
, 0, -1);
471 cupsFreeJobs(num_jobs
, jobs
);
472 cupsFreeDests(num_dests
, dests
);
479 * 'dests_equal()' - Determine whether two destinations are equal.
482 static int /* O - 1 if equal, 0 if not equal */
483 dests_equal(cups_dest_t
*a
, /* I - First destination */
484 cups_dest_t
*b
) /* I - Second destination */
486 int i
; /* Looping var */
487 cups_option_t
*aoption
; /* Current option */
488 const char *bval
; /* Option value */
497 if (_cups_strcasecmp(a
->name
, b
->name
) ||
498 (a
->instance
&& !b
->instance
) ||
499 (!a
->instance
&& b
->instance
) ||
500 (a
->instance
&& _cups_strcasecmp(a
->instance
, b
->instance
)) ||
501 a
->num_options
!= b
->num_options
)
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
))
515 * 'enum_cb()' - Report additions and removals.
518 static int /* O - 1 to continue, 0 to stop */
519 enum_cb(void *user_data
, /* I - User data (unused) */
520 unsigned flags
, /* I - Destination flags */
521 cups_dest_t
*dest
) /* I - Destination */
523 int i
; /* Looping var */
524 cups_option_t
*option
; /* Current option */
529 if (flags
& CUPS_DEST_FLAGS_REMOVED
)
530 printf("Removed '%s':\n", dest
->name
);
532 printf("Added '%s':\n", dest
->name
);
534 for (i
= dest
->num_options
, option
= dest
->options
; i
> 0; i
--, option
++)
535 printf(" %s=\"%s\"\n", option
->name
, option
->value
);
544 * 'show_diffs()' - Show differences between two destinations.
548 show_diffs(cups_dest_t
*a
, /* I - First destination */
549 cups_dest_t
*b
) /* I - Second destination */
551 int i
; /* Looping var */
552 cups_option_t
*aoption
; /* Current option */
553 const char *bval
; /* Option value */
559 puts(" Item cupsGetDest cupsGetNamedDest");
560 puts(" -------------------- -------------------- --------------------");
562 if (_cups_strcasecmp(a
->name
, b
->name
))
563 printf(" name %-20.20s %-20.20s\n", a
->name
, b
->name
);
565 if ((a
->instance
&& !b
->instance
) ||
566 (!a
->instance
&& b
->instance
) ||
567 (a
->instance
&& _cups_strcasecmp(a
->instance
, b
->instance
)))
568 printf(" instance %-20.20s %-20.20s\n",
569 a
->instance
? a
->instance
: "(null)",
570 b
->instance
? b
->instance
: "(null)");
572 if (a
->num_options
!= b
->num_options
)
573 printf(" num_options %-20d %-20d\n", a
->num_options
,
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)");