2 * CUPS API test program for CUPS.
4 * Copyright 2007-2017 by Apple Inc.
5 * Copyright 2007 by Easy Software Products.
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
11 * Include necessary headers...
14 #undef _CUPS_NO_DEPRECATED
15 #include "string-private.h"
25 static int dests_equal(cups_dest_t
*a
, cups_dest_t
*b
);
26 static int enum_cb(void *user_data
, unsigned flags
, cups_dest_t
*dest
);
27 static void show_diffs(cups_dest_t
*a
, cups_dest_t
*b
);
31 * 'main()' - Main entry.
34 int /* O - Exit status */
35 main(int argc
, /* I - Number of command-line arguments */
36 char *argv
[]) /* I - Command-line arguments */
38 int status
= 0, /* Exit status */
40 num_dests
; /* Number of destinations */
41 cups_dest_t
*dests
, /* Destinations */
42 *dest
, /* Current destination */
43 *named_dest
; /* Current named destination */
44 const char *dest_name
, /* Destination name */
45 *dval
, /* Destination value */
46 *ppdfile
; /* PPD file */
47 ppd_file_t
*ppd
; /* PPD file data */
48 int num_jobs
; /* Number of jobs for queue */
49 cups_job_t
*jobs
; /* Jobs for queue */
54 if (!strcmp(argv
[1], "enum"))
56 cups_ptype_t mask
= CUPS_PRINTER_LOCAL
,
57 /* Printer type mask */
58 type
= CUPS_PRINTER_LOCAL
;
60 int msec
= 0; /* Timeout in milliseconds */
63 for (i
= 2; i
< argc
; i
++)
64 if (isdigit(argv
[i
][0] & 255) || argv
[i
][0] == '.')
65 msec
= (int)(atof(argv
[i
]) * 1000);
66 else if (!_cups_strcasecmp(argv
[i
], "bw"))
68 mask
|= CUPS_PRINTER_BW
;
69 type
|= CUPS_PRINTER_BW
;
71 else if (!_cups_strcasecmp(argv
[i
], "color"))
73 mask
|= CUPS_PRINTER_COLOR
;
74 type
|= CUPS_PRINTER_COLOR
;
76 else if (!_cups_strcasecmp(argv
[i
], "mono"))
78 mask
|= CUPS_PRINTER_COLOR
;
80 else if (!_cups_strcasecmp(argv
[i
], "duplex"))
82 mask
|= CUPS_PRINTER_DUPLEX
;
83 type
|= CUPS_PRINTER_DUPLEX
;
85 else if (!_cups_strcasecmp(argv
[i
], "simplex"))
87 mask
|= CUPS_PRINTER_DUPLEX
;
89 else if (!_cups_strcasecmp(argv
[i
], "staple"))
91 mask
|= CUPS_PRINTER_STAPLE
;
92 type
|= CUPS_PRINTER_STAPLE
;
94 else if (!_cups_strcasecmp(argv
[i
], "copies"))
96 mask
|= CUPS_PRINTER_COPIES
;
97 type
|= CUPS_PRINTER_COPIES
;
99 else if (!_cups_strcasecmp(argv
[i
], "collate"))
101 mask
|= CUPS_PRINTER_COLLATE
;
102 type
|= CUPS_PRINTER_COLLATE
;
104 else if (!_cups_strcasecmp(argv
[i
], "punch"))
106 mask
|= CUPS_PRINTER_PUNCH
;
107 type
|= CUPS_PRINTER_PUNCH
;
109 else if (!_cups_strcasecmp(argv
[i
], "cover"))
111 mask
|= CUPS_PRINTER_COVER
;
112 type
|= CUPS_PRINTER_COVER
;
114 else if (!_cups_strcasecmp(argv
[i
], "bind"))
116 mask
|= CUPS_PRINTER_BIND
;
117 type
|= CUPS_PRINTER_BIND
;
119 else if (!_cups_strcasecmp(argv
[i
], "sort"))
121 mask
|= CUPS_PRINTER_SORT
;
122 type
|= CUPS_PRINTER_SORT
;
124 else if (!_cups_strcasecmp(argv
[i
], "mfp"))
126 mask
|= CUPS_PRINTER_MFP
;
127 type
|= CUPS_PRINTER_MFP
;
129 else if (!_cups_strcasecmp(argv
[i
], "printer"))
131 mask
|= CUPS_PRINTER_MFP
;
133 else if (!_cups_strcasecmp(argv
[i
], "large"))
135 mask
|= CUPS_PRINTER_LARGE
;
136 type
|= CUPS_PRINTER_LARGE
;
138 else if (!_cups_strcasecmp(argv
[i
], "medium"))
140 mask
|= CUPS_PRINTER_MEDIUM
;
141 type
|= CUPS_PRINTER_MEDIUM
;
143 else if (!_cups_strcasecmp(argv
[i
], "small"))
145 mask
|= CUPS_PRINTER_SMALL
;
146 type
|= CUPS_PRINTER_SMALL
;
149 fprintf(stderr
, "Unknown argument \"%s\" ignored...\n", argv
[i
]);
151 cupsEnumDests(CUPS_DEST_FLAGS_NONE
, msec
, NULL
, type
, mask
, enum_cb
, NULL
);
153 else if (!strcmp(argv
[1], "password"))
155 const char *pass
= cupsGetPassword("Password:");
156 /* Password string */
159 printf("Password entered: %s\n", pass
);
161 puts("No password entered.");
163 else if (!strcmp(argv
[1], "ppd") && argc
== 3)
166 * ./testcups ppd printer
169 http_status_t http_status
; /* Status */
170 char buffer
[1024]; /* PPD filename */
171 time_t modtime
= 0; /* Last modified */
173 if ((http_status
= cupsGetPPD3(CUPS_HTTP_DEFAULT
, argv
[2], &modtime
,
174 buffer
, sizeof(buffer
))) != HTTP_STATUS_OK
)
175 printf("Unable to get PPD: %d (%s)\n", (int)http_status
,
176 cupsLastErrorString());
180 else if (!strcmp(argv
[1], "print") && argc
== 5)
183 * ./testcups print printer file interval
186 int interval
, /* Interval between writes */
188 cups_file_t
*fp
; /* Print file */
189 char buffer
[16384]; /* Read/write buffer */
190 ssize_t bytes
; /* Bytes read/written */
192 if ((fp
= cupsFileOpen(argv
[3], "r")) == NULL
)
194 printf("Unable to open \"%s\": %s\n", argv
[2], strerror(errno
));
198 if ((job_id
= cupsCreateJob(CUPS_HTTP_DEFAULT
, argv
[2], "testcups", 0,
201 printf("Unable to create print job on %s: %s\n", argv
[1],
202 cupsLastErrorString());
206 interval
= atoi(argv
[4]);
208 if (cupsStartDocument(CUPS_HTTP_DEFAULT
, argv
[1], job_id
, argv
[2],
209 CUPS_FORMAT_AUTO
, 1) != HTTP_STATUS_CONTINUE
)
211 puts("Unable to start document!");
215 while ((bytes
= cupsFileRead(fp
, buffer
, sizeof(buffer
))) > 0)
217 printf("Writing %d bytes...\n", (int)bytes
);
219 if (cupsWriteRequestData(CUPS_HTTP_DEFAULT
, buffer
, (size_t)bytes
) != HTTP_STATUS_CONTINUE
)
221 puts("Unable to write bytes!");
226 sleep((unsigned)interval
);
231 if (cupsFinishDocument(CUPS_HTTP_DEFAULT
,
232 argv
[1]) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED
)
234 puts("Unable to finish document!");
242 puts("Run basic unit tests:");
246 puts("Enumerate printers (for N seconds, -1 for indefinitely):");
248 puts(" ./testcups enum [seconds]");
250 puts("Ask for a password:");
252 puts(" ./testcups password");
254 puts("Get the PPD file:");
256 puts(" ./testcups ppd printer");
258 puts("Print a file (interval controls delay between buffers in seconds):");
260 puts(" ./testcups print printer file interval");
271 fputs("cupsGetDests: ", stdout
);
274 num_dests
= cupsGetDests(&dests
);
283 printf("PASS (%d dests)\n", num_dests
);
285 for (i
= num_dests
, dest
= dests
; i
> 0; i
--, dest
++)
287 printf(" %s", dest
->name
);
290 printf(" /%s", dest
->instance
);
292 if (dest
->is_default
)
293 puts(" ***DEFAULT***");
303 fputs("cupsGetDest(NULL): ", stdout
);
306 if ((dest
= cupsGetDest(NULL
, NULL
, num_dests
, dests
)) == NULL
)
308 for (i
= num_dests
, dest
= dests
; i
> 0; i
--, dest
++)
309 if (dest
->is_default
)
318 puts("PASS (no default)");
323 printf("PASS (%s)\n", dest
->name
);
326 * cupsGetNamedDest(NULL, NULL, NULL)
329 fputs("cupsGetNamedDest(NULL, NULL, NULL): ", stdout
);
332 if ((named_dest
= cupsGetNamedDest(NULL
, NULL
, NULL
)) == NULL
||
333 !dests_equal(dest
, named_dest
))
336 puts("PASS (no default)");
339 puts("FAIL (different values)");
340 show_diffs(dest
, named_dest
);
345 puts("FAIL (no default)");
350 printf("PASS (%s)\n", named_dest
->name
);
353 cupsFreeDests(1, named_dest
);
356 * cupsGetDest(printer)
359 for (i
= 0, dest_name
= NULL
; i
< num_dests
; i
++)
361 if ((dval
= cupsGetOption("printer-is-temporary", dests
[i
].num_options
, dest
[i
].options
)) != NULL
&& !strcmp(dval
, "false"))
363 dest_name
= dests
[i
].name
;
368 printf("cupsGetDest(\"%s\"): ", dest_name
? dest_name
: "(null)");
371 if ((dest
= cupsGetDest(dest_name
, NULL
, num_dests
, dests
)) == NULL
)
380 * cupsGetNamedDest(NULL, printer, instance)
383 printf("cupsGetNamedDest(NULL, \"%s\", \"%s\"): ", dest
->name
,
384 dest
->instance
? dest
->instance
: "(null)");
387 if ((named_dest
= cupsGetNamedDest(NULL
, dest
->name
, dest
->instance
)) == NULL
||
388 !dests_equal(dest
, named_dest
))
392 puts("FAIL (different values)");
393 show_diffs(dest
, named_dest
);
396 puts("FAIL (no destination)");
405 cupsFreeDests(1, named_dest
);
411 fputs("cupsPrintFile: ", stdout
);
414 if (cupsPrintFile(dest
->name
, "../test/testfile.pdf", "Test Page",
415 dest
->num_options
, dest
->options
) <= 0)
417 printf("FAIL (%s)\n", cupsLastErrorString());
424 * cupsGetPPD(printer)
427 fputs("cupsGetPPD: ", stdout
);
430 if ((ppdfile
= cupsGetPPD(dest
->name
)) == NULL
)
442 fputs("ppdOpenFile: ", stdout
);
445 if ((ppd
= ppdOpenFile(ppdfile
)) == NULL
)
461 fputs("cupsGetJobs: ", stdout
);
464 num_jobs
= cupsGetJobs(&jobs
, NULL
, 0, -1);
474 cupsFreeJobs(num_jobs
, jobs
);
475 cupsFreeDests(num_dests
, dests
);
482 * 'dests_equal()' - Determine whether two destinations are equal.
485 static int /* O - 1 if equal, 0 if not equal */
486 dests_equal(cups_dest_t
*a
, /* I - First destination */
487 cups_dest_t
*b
) /* I - Second destination */
489 int i
; /* Looping var */
490 cups_option_t
*aoption
; /* Current option */
491 const char *bval
; /* Option value */
500 if (_cups_strcasecmp(a
->name
, b
->name
) ||
501 (a
->instance
&& !b
->instance
) ||
502 (!a
->instance
&& b
->instance
) ||
503 (a
->instance
&& _cups_strcasecmp(a
->instance
, b
->instance
)) ||
504 a
->num_options
!= b
->num_options
)
507 for (i
= a
->num_options
, aoption
= a
->options
; i
> 0; i
--, aoption
++)
508 if ((bval
= cupsGetOption(aoption
->name
, b
->num_options
,
509 b
->options
)) == NULL
||
510 strcmp(aoption
->value
, bval
))
518 * 'enum_cb()' - Report additions and removals.
521 static int /* O - 1 to continue, 0 to stop */
522 enum_cb(void *user_data
, /* I - User data (unused) */
523 unsigned flags
, /* I - Destination flags */
524 cups_dest_t
*dest
) /* I - Destination */
526 int i
; /* Looping var */
527 cups_option_t
*option
; /* Current option */
532 if (flags
& CUPS_DEST_FLAGS_REMOVED
)
533 printf("Removed '%s':\n", dest
->name
);
535 printf("Added '%s':\n", dest
->name
);
537 for (i
= dest
->num_options
, option
= dest
->options
; i
> 0; i
--, option
++)
538 printf(" %s=\"%s\"\n", option
->name
, option
->value
);
547 * 'show_diffs()' - Show differences between two destinations.
551 show_diffs(cups_dest_t
*a
, /* I - First destination */
552 cups_dest_t
*b
) /* I - Second destination */
554 int i
; /* Looping var */
555 cups_option_t
*aoption
; /* Current option */
556 cups_option_t
*boption
; /* Current option */
557 const char *bval
; /* Option value */
563 puts(" Item cupsGetDest cupsGetNamedDest");
564 puts(" -------------------- ------------------------ ------------------------");
566 if (_cups_strcasecmp(a
->name
, b
->name
))
567 printf(" name %-24.24s %-24.24s\n", a
->name
, b
->name
);
569 if ((a
->instance
&& !b
->instance
) ||
570 (!a
->instance
&& b
->instance
) ||
571 (a
->instance
&& _cups_strcasecmp(a
->instance
, b
->instance
)))
572 printf(" instance %-24.24s %-24.24s\n",
573 a
->instance
? a
->instance
: "(null)",
574 b
->instance
? b
->instance
: "(null)");
576 if (a
->num_options
!= b
->num_options
)
577 printf(" num_options %-24d %-24d\n", a
->num_options
,
580 for (i
= a
->num_options
, aoption
= a
->options
; i
> 0; i
--, aoption
++)
581 if ((bval
= cupsGetOption(aoption
->name
, b
->num_options
,
582 b
->options
)) == NULL
||
583 strcmp(aoption
->value
, bval
))
584 printf(" %-20.20s %-24.24s %-24.24s\n", aoption
->name
,
585 aoption
->value
, bval
? bval
: "(null)");
587 for (i
= b
->num_options
, boption
= b
->options
; i
> 0; i
--, boption
++)
588 if (!cupsGetOption(boption
->name
, a
->num_options
, a
->options
))
589 printf(" %-20.20s %-24.24s %-24.24s\n", boption
->name
,
590 boption
->value
, "(null)");