2 * CUPS API test program for CUPS.
4 * Copyright © 2007-2018 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 "cups-private.h"
24 static int dests_equal(cups_dest_t
*a
, cups_dest_t
*b
);
25 static int enum_cb(void *user_data
, unsigned flags
, cups_dest_t
*dest
);
26 static void show_diffs(cups_dest_t
*a
, cups_dest_t
*b
);
30 * 'main()' - Main entry.
33 int /* O - Exit status */
34 main(int argc
, /* I - Number of command-line arguments */
35 char *argv
[]) /* I - Command-line arguments */
37 http_t
*http
, /* First HTTP connection */
38 *http2
; /* Second HTTP connection */
39 int status
= 0, /* Exit status */
41 num_dests
; /* Number of destinations */
42 cups_dest_t
*dests
, /* Destinations */
43 *dest
, /* Current destination */
44 *named_dest
; /* Current named destination */
45 const char *dest_name
, /* Destination name */
46 *dval
, /* Destination value */
47 *ppdfile
; /* PPD file */
48 ppd_file_t
*ppd
; /* PPD file data */
49 int num_jobs
; /* Number of jobs for queue */
50 cups_job_t
*jobs
; /* Jobs for queue */
55 if (!strcmp(argv
[1], "enum"))
57 cups_ptype_t mask
= CUPS_PRINTER_LOCAL
,
58 /* Printer type mask */
59 type
= CUPS_PRINTER_LOCAL
;
61 int msec
= 0; /* Timeout in milliseconds */
64 for (i
= 2; i
< argc
; i
++)
65 if (isdigit(argv
[i
][0] & 255) || argv
[i
][0] == '.')
66 msec
= (int)(atof(argv
[i
]) * 1000);
67 else if (!_cups_strcasecmp(argv
[i
], "bw"))
69 mask
|= CUPS_PRINTER_BW
;
70 type
|= CUPS_PRINTER_BW
;
72 else if (!_cups_strcasecmp(argv
[i
], "color"))
74 mask
|= CUPS_PRINTER_COLOR
;
75 type
|= CUPS_PRINTER_COLOR
;
77 else if (!_cups_strcasecmp(argv
[i
], "mono"))
79 mask
|= CUPS_PRINTER_COLOR
;
81 else if (!_cups_strcasecmp(argv
[i
], "duplex"))
83 mask
|= CUPS_PRINTER_DUPLEX
;
84 type
|= CUPS_PRINTER_DUPLEX
;
86 else if (!_cups_strcasecmp(argv
[i
], "simplex"))
88 mask
|= CUPS_PRINTER_DUPLEX
;
90 else if (!_cups_strcasecmp(argv
[i
], "staple"))
92 mask
|= CUPS_PRINTER_STAPLE
;
93 type
|= CUPS_PRINTER_STAPLE
;
95 else if (!_cups_strcasecmp(argv
[i
], "copies"))
97 mask
|= CUPS_PRINTER_COPIES
;
98 type
|= CUPS_PRINTER_COPIES
;
100 else if (!_cups_strcasecmp(argv
[i
], "collate"))
102 mask
|= CUPS_PRINTER_COLLATE
;
103 type
|= CUPS_PRINTER_COLLATE
;
105 else if (!_cups_strcasecmp(argv
[i
], "punch"))
107 mask
|= CUPS_PRINTER_PUNCH
;
108 type
|= CUPS_PRINTER_PUNCH
;
110 else if (!_cups_strcasecmp(argv
[i
], "cover"))
112 mask
|= CUPS_PRINTER_COVER
;
113 type
|= CUPS_PRINTER_COVER
;
115 else if (!_cups_strcasecmp(argv
[i
], "bind"))
117 mask
|= CUPS_PRINTER_BIND
;
118 type
|= CUPS_PRINTER_BIND
;
120 else if (!_cups_strcasecmp(argv
[i
], "sort"))
122 mask
|= CUPS_PRINTER_SORT
;
123 type
|= CUPS_PRINTER_SORT
;
125 else if (!_cups_strcasecmp(argv
[i
], "mfp"))
127 mask
|= CUPS_PRINTER_MFP
;
128 type
|= CUPS_PRINTER_MFP
;
130 else if (!_cups_strcasecmp(argv
[i
], "printer"))
132 mask
|= CUPS_PRINTER_MFP
;
134 else if (!_cups_strcasecmp(argv
[i
], "large"))
136 mask
|= CUPS_PRINTER_LARGE
;
137 type
|= CUPS_PRINTER_LARGE
;
139 else if (!_cups_strcasecmp(argv
[i
], "medium"))
141 mask
|= CUPS_PRINTER_MEDIUM
;
142 type
|= CUPS_PRINTER_MEDIUM
;
144 else if (!_cups_strcasecmp(argv
[i
], "small"))
146 mask
|= CUPS_PRINTER_SMALL
;
147 type
|= CUPS_PRINTER_SMALL
;
150 fprintf(stderr
, "Unknown argument \"%s\" ignored...\n", argv
[i
]);
152 cupsEnumDests(CUPS_DEST_FLAGS_NONE
, msec
, NULL
, type
, mask
, enum_cb
, NULL
);
154 else if (!strcmp(argv
[1], "password"))
156 const char *pass
= cupsGetPassword("Password:");
157 /* Password string */
160 printf("Password entered: %s\n", pass
);
162 puts("No password entered.");
164 else if (!strcmp(argv
[1], "ppd") && argc
== 3)
167 * ./testcups ppd printer
170 http_status_t http_status
; /* Status */
171 char buffer
[1024]; /* PPD filename */
172 time_t modtime
= 0; /* Last modified */
174 if ((http_status
= cupsGetPPD3(CUPS_HTTP_DEFAULT
, argv
[2], &modtime
,
175 buffer
, sizeof(buffer
))) != HTTP_STATUS_OK
)
176 printf("Unable to get PPD: %d (%s)\n", (int)http_status
,
177 cupsLastErrorString());
181 else if (!strcmp(argv
[1], "print") && argc
== 5)
184 * ./testcups print printer file interval
187 int interval
, /* Interval between writes */
189 cups_file_t
*fp
; /* Print file */
190 char buffer
[16384]; /* Read/write buffer */
191 ssize_t bytes
; /* Bytes read/written */
193 if ((fp
= cupsFileOpen(argv
[3], "r")) == NULL
)
195 printf("Unable to open \"%s\": %s\n", argv
[2], strerror(errno
));
199 if ((job_id
= cupsCreateJob(CUPS_HTTP_DEFAULT
, argv
[2], "testcups", 0,
202 printf("Unable to create print job on %s: %s\n", argv
[1],
203 cupsLastErrorString());
207 interval
= atoi(argv
[4]);
209 if (cupsStartDocument(CUPS_HTTP_DEFAULT
, argv
[1], job_id
, argv
[2],
210 CUPS_FORMAT_AUTO
, 1) != HTTP_STATUS_CONTINUE
)
212 puts("Unable to start document!");
216 while ((bytes
= cupsFileRead(fp
, buffer
, sizeof(buffer
))) > 0)
218 printf("Writing %d bytes...\n", (int)bytes
);
220 if (cupsWriteRequestData(CUPS_HTTP_DEFAULT
, buffer
, (size_t)bytes
) != HTTP_STATUS_CONTINUE
)
222 puts("Unable to write bytes!");
227 sleep((unsigned)interval
);
232 if (cupsFinishDocument(CUPS_HTTP_DEFAULT
,
233 argv
[1]) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED
)
235 puts("Unable to finish document!");
243 puts("Run basic unit tests:");
247 puts("Enumerate printers (for N seconds, -1 for indefinitely):");
249 puts(" ./testcups enum [seconds]");
251 puts("Ask for a password:");
253 puts(" ./testcups password");
255 puts("Get the PPD file:");
257 puts(" ./testcups ppd printer");
259 puts("Print a file (interval controls delay between buffers in seconds):");
261 puts(" ./testcups print printer file interval");
269 * _cupsConnect() connection reuse...
272 fputs("_cupsConnect: ", stdout
);
273 http
= _cupsConnect();
274 http2
= _cupsConnect();
282 puts("FAIL (different connections)");
290 fputs("cupsGetDests: ", stdout
);
293 num_dests
= cupsGetDests(&dests
);
302 printf("PASS (%d dests)\n", num_dests
);
304 for (i
= num_dests
, dest
= dests
; i
> 0; i
--, dest
++)
306 printf(" %s", dest
->name
);
309 printf(" /%s", dest
->instance
);
311 if (dest
->is_default
)
312 puts(" ***DEFAULT***");
322 fputs("cupsGetDest(NULL): ", stdout
);
325 if ((dest
= cupsGetDest(NULL
, NULL
, num_dests
, dests
)) == NULL
)
327 for (i
= num_dests
, dest
= dests
; i
> 0; i
--, dest
++)
328 if (dest
->is_default
)
337 puts("PASS (no default)");
342 printf("PASS (%s)\n", dest
->name
);
345 * cupsGetNamedDest(NULL, NULL, NULL)
348 fputs("cupsGetNamedDest(NULL, NULL, NULL): ", stdout
);
351 if ((named_dest
= cupsGetNamedDest(NULL
, NULL
, NULL
)) == NULL
||
352 !dests_equal(dest
, named_dest
))
355 puts("PASS (no default)");
358 puts("FAIL (different values)");
359 show_diffs(dest
, named_dest
);
364 puts("FAIL (no default)");
369 printf("PASS (%s)\n", named_dest
->name
);
372 cupsFreeDests(1, named_dest
);
375 * cupsGetDest(printer)
378 for (i
= 0, dest_name
= NULL
; i
< num_dests
; i
++)
380 if ((dval
= cupsGetOption("printer-is-temporary", dests
[i
].num_options
, dest
[i
].options
)) != NULL
&& !strcmp(dval
, "false"))
382 dest_name
= dests
[i
].name
;
387 printf("cupsGetDest(\"%s\"): ", dest_name
? dest_name
: "(null)");
390 if ((dest
= cupsGetDest(dest_name
, NULL
, num_dests
, dests
)) == NULL
)
399 * cupsGetNamedDest(NULL, printer, instance)
402 printf("cupsGetNamedDest(NULL, \"%s\", \"%s\"): ", dest
->name
,
403 dest
->instance
? dest
->instance
: "(null)");
406 if ((named_dest
= cupsGetNamedDest(NULL
, dest
->name
, dest
->instance
)) == NULL
||
407 !dests_equal(dest
, named_dest
))
411 puts("FAIL (different values)");
412 show_diffs(dest
, named_dest
);
415 puts("FAIL (no destination)");
424 cupsFreeDests(1, named_dest
);
430 fputs("cupsPrintFile: ", stdout
);
433 if (cupsPrintFile(dest
->name
, "../test/testfile.pdf", "Test Page",
434 dest
->num_options
, dest
->options
) <= 0)
436 printf("FAIL (%s)\n", cupsLastErrorString());
443 * cupsGetPPD(printer)
446 fputs("cupsGetPPD: ", stdout
);
449 if ((ppdfile
= cupsGetPPD(dest
->name
)) == NULL
)
461 fputs("ppdOpenFile: ", stdout
);
464 if ((ppd
= ppdOpenFile(ppdfile
)) == NULL
)
480 fputs("cupsGetJobs: ", stdout
);
483 num_jobs
= cupsGetJobs(&jobs
, NULL
, 0, -1);
493 cupsFreeJobs(num_jobs
, jobs
);
494 cupsFreeDests(num_dests
, dests
);
501 * 'dests_equal()' - Determine whether two destinations are equal.
504 static int /* O - 1 if equal, 0 if not equal */
505 dests_equal(cups_dest_t
*a
, /* I - First destination */
506 cups_dest_t
*b
) /* I - Second destination */
508 int i
; /* Looping var */
509 cups_option_t
*aoption
; /* Current option */
510 const char *bval
; /* Option value */
519 if (_cups_strcasecmp(a
->name
, b
->name
) ||
520 (a
->instance
&& !b
->instance
) ||
521 (!a
->instance
&& b
->instance
) ||
522 (a
->instance
&& _cups_strcasecmp(a
->instance
, b
->instance
)) ||
523 a
->num_options
!= b
->num_options
)
526 for (i
= a
->num_options
, aoption
= a
->options
; i
> 0; i
--, aoption
++)
527 if ((bval
= cupsGetOption(aoption
->name
, b
->num_options
,
528 b
->options
)) == NULL
||
529 strcmp(aoption
->value
, bval
))
537 * 'enum_cb()' - Report additions and removals.
540 static int /* O - 1 to continue, 0 to stop */
541 enum_cb(void *user_data
, /* I - User data (unused) */
542 unsigned flags
, /* I - Destination flags */
543 cups_dest_t
*dest
) /* I - Destination */
545 int i
; /* Looping var */
546 cups_option_t
*option
; /* Current option */
551 if (flags
& CUPS_DEST_FLAGS_REMOVED
)
552 printf("Removed '%s':\n", dest
->name
);
554 printf("Added '%s':\n", dest
->name
);
556 for (i
= dest
->num_options
, option
= dest
->options
; i
> 0; i
--, option
++)
557 printf(" %s=\"%s\"\n", option
->name
, option
->value
);
566 * 'show_diffs()' - Show differences between two destinations.
570 show_diffs(cups_dest_t
*a
, /* I - First destination */
571 cups_dest_t
*b
) /* I - Second destination */
573 int i
; /* Looping var */
574 cups_option_t
*aoption
; /* Current option */
575 cups_option_t
*boption
; /* Current option */
576 const char *bval
; /* Option value */
582 puts(" Item cupsGetDest cupsGetNamedDest");
583 puts(" -------------------- ------------------------ ------------------------");
585 if (_cups_strcasecmp(a
->name
, b
->name
))
586 printf(" name %-24.24s %-24.24s\n", a
->name
, b
->name
);
588 if ((a
->instance
&& !b
->instance
) ||
589 (!a
->instance
&& b
->instance
) ||
590 (a
->instance
&& _cups_strcasecmp(a
->instance
, b
->instance
)))
591 printf(" instance %-24.24s %-24.24s\n",
592 a
->instance
? a
->instance
: "(null)",
593 b
->instance
? b
->instance
: "(null)");
595 if (a
->num_options
!= b
->num_options
)
596 printf(" num_options %-24d %-24d\n", a
->num_options
,
599 for (i
= a
->num_options
, aoption
= a
->options
; i
> 0; i
--, aoption
++)
600 if ((bval
= cupsGetOption(aoption
->name
, b
->num_options
,
601 b
->options
)) == NULL
||
602 strcmp(aoption
->value
, bval
))
603 printf(" %-20.20s %-24.24s %-24.24s\n", aoption
->name
,
604 aoption
->value
, bval
? bval
: "(null)");
606 for (i
= b
->num_options
, boption
= b
->options
; i
> 0; i
--, boption
++)
607 if (!cupsGetOption(boption
->name
, a
->num_options
, a
->options
))
608 printf(" %-20.20s %-24.24s %-24.24s\n", boption
->name
,
609 boption
->value
, "(null)");