1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * ipptool command for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2021 by OpenPrinting.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2020 by The Printer Working Group.
6*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2007-2021 by Apple Inc.
7*5e7646d2SAndroid Build Coastguard Worker * Copyright © 1997-2007 by Easy Software Products.
8*5e7646d2SAndroid Build Coastguard Worker *
9*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
10*5e7646d2SAndroid Build Coastguard Worker * information.
11*5e7646d2SAndroid Build Coastguard Worker */
12*5e7646d2SAndroid Build Coastguard Worker
13*5e7646d2SAndroid Build Coastguard Worker /*
14*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
15*5e7646d2SAndroid Build Coastguard Worker */
16*5e7646d2SAndroid Build Coastguard Worker
17*5e7646d2SAndroid Build Coastguard Worker #include <cups/cups-private.h>
18*5e7646d2SAndroid Build Coastguard Worker #include <regex.h>
19*5e7646d2SAndroid Build Coastguard Worker #include <sys/stat.h>
20*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
21*5e7646d2SAndroid Build Coastguard Worker # include <windows.h>
22*5e7646d2SAndroid Build Coastguard Worker # ifndef R_OK
23*5e7646d2SAndroid Build Coastguard Worker # define R_OK 0
24*5e7646d2SAndroid Build Coastguard Worker # endif /* !R_OK */
25*5e7646d2SAndroid Build Coastguard Worker #else
26*5e7646d2SAndroid Build Coastguard Worker # include <signal.h>
27*5e7646d2SAndroid Build Coastguard Worker # include <termios.h>
28*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
29*5e7646d2SAndroid Build Coastguard Worker #ifndef O_BINARY
30*5e7646d2SAndroid Build Coastguard Worker # define O_BINARY 0
31*5e7646d2SAndroid Build Coastguard Worker #endif /* !O_BINARY */
32*5e7646d2SAndroid Build Coastguard Worker
33*5e7646d2SAndroid Build Coastguard Worker
34*5e7646d2SAndroid Build Coastguard Worker /*
35*5e7646d2SAndroid Build Coastguard Worker * Limits...
36*5e7646d2SAndroid Build Coastguard Worker */
37*5e7646d2SAndroid Build Coastguard Worker
38*5e7646d2SAndroid Build Coastguard Worker #define MAX_EXPECT 200 // Maximum number of EXPECT directives
39*5e7646d2SAndroid Build Coastguard Worker #define MAX_DISPLAY 200 // Maximum number of DISPLAY directives
40*5e7646d2SAndroid Build Coastguard Worker #define MAX_MONITOR 10 // Maximum number of MONITOR-PRINTER-STATE EXPECT directives
41*5e7646d2SAndroid Build Coastguard Worker
42*5e7646d2SAndroid Build Coastguard Worker
43*5e7646d2SAndroid Build Coastguard Worker /*
44*5e7646d2SAndroid Build Coastguard Worker * Types...
45*5e7646d2SAndroid Build Coastguard Worker */
46*5e7646d2SAndroid Build Coastguard Worker
47*5e7646d2SAndroid Build Coastguard Worker typedef enum ipptool_transfer_e /**** How to send request data ****/
48*5e7646d2SAndroid Build Coastguard Worker {
49*5e7646d2SAndroid Build Coastguard Worker IPPTOOL_TRANSFER_AUTO, /* Chunk for files, length for static */
50*5e7646d2SAndroid Build Coastguard Worker IPPTOOL_TRANSFER_CHUNKED, /* Chunk always */
51*5e7646d2SAndroid Build Coastguard Worker IPPTOOL_TRANSFER_LENGTH /* Length always */
52*5e7646d2SAndroid Build Coastguard Worker } ipptool_transfer_t;
53*5e7646d2SAndroid Build Coastguard Worker
54*5e7646d2SAndroid Build Coastguard Worker typedef enum ipptool_output_e /**** Output mode ****/
55*5e7646d2SAndroid Build Coastguard Worker {
56*5e7646d2SAndroid Build Coastguard Worker IPPTOOL_OUTPUT_QUIET, /* No output */
57*5e7646d2SAndroid Build Coastguard Worker IPPTOOL_OUTPUT_TEST, /* Traditional CUPS test output */
58*5e7646d2SAndroid Build Coastguard Worker IPPTOOL_OUTPUT_PLIST, /* XML plist test output */
59*5e7646d2SAndroid Build Coastguard Worker IPPTOOL_OUTPUT_IPPSERVER, /* ippserver attribute file output */
60*5e7646d2SAndroid Build Coastguard Worker IPPTOOL_OUTPUT_LIST, /* Tabular list output */
61*5e7646d2SAndroid Build Coastguard Worker IPPTOOL_OUTPUT_CSV /* Comma-separated values output */
62*5e7646d2SAndroid Build Coastguard Worker } ipptool_output_t;
63*5e7646d2SAndroid Build Coastguard Worker
64*5e7646d2SAndroid Build Coastguard Worker typedef enum ipptool_with_e /**** WITH flags ****/
65*5e7646d2SAndroid Build Coastguard Worker {
66*5e7646d2SAndroid Build Coastguard Worker IPPTOOL_WITH_LITERAL = 0, /* Match string is a literal value */
67*5e7646d2SAndroid Build Coastguard Worker IPPTOOL_WITH_ALL = 1, /* Must match all values */
68*5e7646d2SAndroid Build Coastguard Worker IPPTOOL_WITH_REGEX = 2, /* Match string is a regular expression */
69*5e7646d2SAndroid Build Coastguard Worker IPPTOOL_WITH_HOSTNAME = 4, /* Match string is a URI hostname */
70*5e7646d2SAndroid Build Coastguard Worker IPPTOOL_WITH_RESOURCE = 8, /* Match string is a URI resource */
71*5e7646d2SAndroid Build Coastguard Worker IPPTOOL_WITH_SCHEME = 16 /* Match string is a URI scheme */
72*5e7646d2SAndroid Build Coastguard Worker } ipptool_with_t;
73*5e7646d2SAndroid Build Coastguard Worker
74*5e7646d2SAndroid Build Coastguard Worker typedef struct ipptool_expect_s /**** Expected attribute info ****/
75*5e7646d2SAndroid Build Coastguard Worker {
76*5e7646d2SAndroid Build Coastguard Worker int optional, /* Optional attribute? */
77*5e7646d2SAndroid Build Coastguard Worker not_expect, /* Don't expect attribute? */
78*5e7646d2SAndroid Build Coastguard Worker expect_all; /* Expect all attributes to match/not match */
79*5e7646d2SAndroid Build Coastguard Worker char *name, /* Attribute name */
80*5e7646d2SAndroid Build Coastguard Worker *of_type, /* Type name */
81*5e7646d2SAndroid Build Coastguard Worker *same_count_as, /* Parallel attribute name */
82*5e7646d2SAndroid Build Coastguard Worker *if_defined, /* Only required if variable defined */
83*5e7646d2SAndroid Build Coastguard Worker *if_not_defined, /* Only required if variable is not defined */
84*5e7646d2SAndroid Build Coastguard Worker *with_value, /* Attribute must include this value */
85*5e7646d2SAndroid Build Coastguard Worker *with_value_from, /* Attribute must have one of the values in this attribute */
86*5e7646d2SAndroid Build Coastguard Worker *define_match, /* Variable to define on match */
87*5e7646d2SAndroid Build Coastguard Worker *define_no_match, /* Variable to define on no-match */
88*5e7646d2SAndroid Build Coastguard Worker *define_value, /* Variable to define with value */
89*5e7646d2SAndroid Build Coastguard Worker *display_match; /* Message to display on a match */
90*5e7646d2SAndroid Build Coastguard Worker int repeat_limit, /* Maximum number of times to repeat */
91*5e7646d2SAndroid Build Coastguard Worker repeat_match, /* Repeat test on match */
92*5e7646d2SAndroid Build Coastguard Worker repeat_no_match, /* Repeat test on no match */
93*5e7646d2SAndroid Build Coastguard Worker with_distinct, /* WITH-DISTINCT-VALUES? */
94*5e7646d2SAndroid Build Coastguard Worker with_flags, /* WITH flags */
95*5e7646d2SAndroid Build Coastguard Worker count; /* Expected count if > 0 */
96*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t in_group; /* IN-GROUP value */
97*5e7646d2SAndroid Build Coastguard Worker } ipptool_expect_t;
98*5e7646d2SAndroid Build Coastguard Worker
99*5e7646d2SAndroid Build Coastguard Worker typedef struct ipptool_status_s /**** Status info ****/
100*5e7646d2SAndroid Build Coastguard Worker {
101*5e7646d2SAndroid Build Coastguard Worker ipp_status_t status; /* Expected status code */
102*5e7646d2SAndroid Build Coastguard Worker char *if_defined, /* Only if variable is defined */
103*5e7646d2SAndroid Build Coastguard Worker *if_not_defined, /* Only if variable is not defined */
104*5e7646d2SAndroid Build Coastguard Worker *define_match, /* Variable to define on match */
105*5e7646d2SAndroid Build Coastguard Worker *define_no_match, /* Variable to define on no-match */
106*5e7646d2SAndroid Build Coastguard Worker *define_value; /* Variable to define with value */
107*5e7646d2SAndroid Build Coastguard Worker int repeat_limit, /* Maximum number of times to repeat */
108*5e7646d2SAndroid Build Coastguard Worker repeat_match, /* Repeat the test when it does not match */
109*5e7646d2SAndroid Build Coastguard Worker repeat_no_match; /* Repeat the test when it matches */
110*5e7646d2SAndroid Build Coastguard Worker } ipptool_status_t;
111*5e7646d2SAndroid Build Coastguard Worker
112*5e7646d2SAndroid Build Coastguard Worker typedef struct ipptool_test_s /**** Test Data ****/
113*5e7646d2SAndroid Build Coastguard Worker {
114*5e7646d2SAndroid Build Coastguard Worker /* Global Options */
115*5e7646d2SAndroid Build Coastguard Worker _ipp_vars_t *vars; /* Variables */
116*5e7646d2SAndroid Build Coastguard Worker http_encryption_t encryption; /* Encryption for connection */
117*5e7646d2SAndroid Build Coastguard Worker int family; /* Address family */
118*5e7646d2SAndroid Build Coastguard Worker ipptool_output_t output; /* Output mode */
119*5e7646d2SAndroid Build Coastguard Worker int repeat_on_busy; /* Repeat tests on server-error-busy */
120*5e7646d2SAndroid Build Coastguard Worker int stop_after_include_error;
121*5e7646d2SAndroid Build Coastguard Worker /* Stop after include errors? */
122*5e7646d2SAndroid Build Coastguard Worker double timeout; /* Timeout for connection */
123*5e7646d2SAndroid Build Coastguard Worker int validate_headers, /* Validate HTTP headers in response? */
124*5e7646d2SAndroid Build Coastguard Worker verbosity; /* Show all attributes? */
125*5e7646d2SAndroid Build Coastguard Worker
126*5e7646d2SAndroid Build Coastguard Worker /* Test Defaults */
127*5e7646d2SAndroid Build Coastguard Worker int def_ignore_errors; /* Default IGNORE-ERRORS value */
128*5e7646d2SAndroid Build Coastguard Worker ipptool_transfer_t def_transfer; /* Default TRANSFER value */
129*5e7646d2SAndroid Build Coastguard Worker int def_version; /* Default IPP version */
130*5e7646d2SAndroid Build Coastguard Worker
131*5e7646d2SAndroid Build Coastguard Worker /* Global State */
132*5e7646d2SAndroid Build Coastguard Worker http_t *http; /* HTTP connection to printer/server */
133*5e7646d2SAndroid Build Coastguard Worker cups_file_t *outfile; /* Output file */
134*5e7646d2SAndroid Build Coastguard Worker int show_header, /* Show the test header? */
135*5e7646d2SAndroid Build Coastguard Worker xml_header; /* 1 if XML plist header was written */
136*5e7646d2SAndroid Build Coastguard Worker int pass, /* Have we passed all tests? */
137*5e7646d2SAndroid Build Coastguard Worker test_count, /* Number of tests (total) */
138*5e7646d2SAndroid Build Coastguard Worker pass_count, /* Number of tests that passed */
139*5e7646d2SAndroid Build Coastguard Worker fail_count, /* Number of tests that failed */
140*5e7646d2SAndroid Build Coastguard Worker skip_count; /* Number of tests that were skipped */
141*5e7646d2SAndroid Build Coastguard Worker
142*5e7646d2SAndroid Build Coastguard Worker /* Per-Test State */
143*5e7646d2SAndroid Build Coastguard Worker cups_array_t *errors; /* Errors array */
144*5e7646d2SAndroid Build Coastguard Worker int prev_pass, /* Result of previous test */
145*5e7646d2SAndroid Build Coastguard Worker skip_previous; /* Skip on previous test failure? */
146*5e7646d2SAndroid Build Coastguard Worker char compression[16]; /* COMPRESSION value */
147*5e7646d2SAndroid Build Coastguard Worker useconds_t delay; /* Initial delay */
148*5e7646d2SAndroid Build Coastguard Worker int num_displayed; /* Number of displayed attributes */
149*5e7646d2SAndroid Build Coastguard Worker char *displayed[MAX_DISPLAY];/* Displayed attributes */
150*5e7646d2SAndroid Build Coastguard Worker int num_expects; /* Number of expected attributes */
151*5e7646d2SAndroid Build Coastguard Worker ipptool_expect_t expects[MAX_EXPECT], /* Expected attributes */
152*5e7646d2SAndroid Build Coastguard Worker *expect, /* Current expected attribute */
153*5e7646d2SAndroid Build Coastguard Worker *last_expect; /* Last EXPECT (for predicates) */
154*5e7646d2SAndroid Build Coastguard Worker char file[1024], /* Data filename */
155*5e7646d2SAndroid Build Coastguard Worker file_id[1024]; /* File identifier */
156*5e7646d2SAndroid Build Coastguard Worker int ignore_errors; /* Ignore test failures? */
157*5e7646d2SAndroid Build Coastguard Worker char name[1024]; /* Test name */
158*5e7646d2SAndroid Build Coastguard Worker char pause[1024]; /* PAUSE value */
159*5e7646d2SAndroid Build Coastguard Worker useconds_t repeat_interval; /* Repeat interval (delay) */
160*5e7646d2SAndroid Build Coastguard Worker int request_id; /* Current request ID */
161*5e7646d2SAndroid Build Coastguard Worker char resource[512]; /* Resource for request */
162*5e7646d2SAndroid Build Coastguard Worker int pass_test, /* Pass this test? */
163*5e7646d2SAndroid Build Coastguard Worker skip_test, /* Skip this test? */
164*5e7646d2SAndroid Build Coastguard Worker num_statuses; /* Number of valid status codes */
165*5e7646d2SAndroid Build Coastguard Worker ipptool_status_t statuses[100], /* Valid status codes */
166*5e7646d2SAndroid Build Coastguard Worker *last_status; /* Last STATUS (for predicates) */
167*5e7646d2SAndroid Build Coastguard Worker char test_id[1024]; /* Test identifier */
168*5e7646d2SAndroid Build Coastguard Worker ipptool_transfer_t transfer; /* To chunk or not to chunk */
169*5e7646d2SAndroid Build Coastguard Worker int version; /* IPP version number to use */
170*5e7646d2SAndroid Build Coastguard Worker _cups_thread_t monitor_thread; /* Monitoring thread ID */
171*5e7646d2SAndroid Build Coastguard Worker int monitor_done; /* Set to 1 to stop monitor thread */
172*5e7646d2SAndroid Build Coastguard Worker char *monitor_uri; /* MONITOR-PRINTER-STATE URI */
173*5e7646d2SAndroid Build Coastguard Worker useconds_t monitor_delay, /* MONITOR-PRINTER-STATE DELAY value, if any */
174*5e7646d2SAndroid Build Coastguard Worker monitor_interval; /* MONITOR-PRINTER-STATE DELAY interval */
175*5e7646d2SAndroid Build Coastguard Worker int num_monitor_expects; /* Number MONITOR-PRINTER-STATE EXPECTs */
176*5e7646d2SAndroid Build Coastguard Worker ipptool_expect_t monitor_expects[MAX_MONITOR];
177*5e7646d2SAndroid Build Coastguard Worker /* MONITOR-PRINTER-STATE EXPECTs */
178*5e7646d2SAndroid Build Coastguard Worker } ipptool_test_t;
179*5e7646d2SAndroid Build Coastguard Worker
180*5e7646d2SAndroid Build Coastguard Worker
181*5e7646d2SAndroid Build Coastguard Worker /*
182*5e7646d2SAndroid Build Coastguard Worker * Globals...
183*5e7646d2SAndroid Build Coastguard Worker */
184*5e7646d2SAndroid Build Coastguard Worker
185*5e7646d2SAndroid Build Coastguard Worker static int Cancel = 0; /* Cancel test? */
186*5e7646d2SAndroid Build Coastguard Worker
187*5e7646d2SAndroid Build Coastguard Worker
188*5e7646d2SAndroid Build Coastguard Worker /*
189*5e7646d2SAndroid Build Coastguard Worker * Local functions...
190*5e7646d2SAndroid Build Coastguard Worker */
191*5e7646d2SAndroid Build Coastguard Worker
192*5e7646d2SAndroid Build Coastguard Worker static void add_stringf(cups_array_t *a, const char *s, ...) _CUPS_FORMAT(2, 3);
193*5e7646d2SAndroid Build Coastguard Worker static int compare_uris(const char *a, const char *b);
194*5e7646d2SAndroid Build Coastguard Worker static void copy_hex_string(char *buffer, unsigned char *data, int datalen, size_t bufsize);
195*5e7646d2SAndroid Build Coastguard Worker static void *do_monitor_printer_state(ipptool_test_t *data);
196*5e7646d2SAndroid Build Coastguard Worker static int do_test(_ipp_file_t *f, ipptool_test_t *data);
197*5e7646d2SAndroid Build Coastguard Worker static int do_tests(const char *testfile, ipptool_test_t *data);
198*5e7646d2SAndroid Build Coastguard Worker static int error_cb(_ipp_file_t *f, ipptool_test_t *data, const char *error);
199*5e7646d2SAndroid Build Coastguard Worker static int expect_matches(ipptool_expect_t *expect, ipp_attribute_t *attr);
200*5e7646d2SAndroid Build Coastguard Worker static char *get_filename(const char *testfile, char *dst, const char *src, size_t dstsize);
201*5e7646d2SAndroid Build Coastguard Worker static const char *get_string(ipp_attribute_t *attr, int element, int flags, char *buffer, size_t bufsize);
202*5e7646d2SAndroid Build Coastguard Worker static void init_data(ipptool_test_t *data);
203*5e7646d2SAndroid Build Coastguard Worker static char *iso_date(const ipp_uchar_t *date);
204*5e7646d2SAndroid Build Coastguard Worker static int parse_monitor_printer_state(_ipp_file_t *f, ipptool_test_t *data);
205*5e7646d2SAndroid Build Coastguard Worker static void pause_message(const char *message);
206*5e7646d2SAndroid Build Coastguard Worker static void print_attr(cups_file_t *outfile, ipptool_output_t output, ipp_attribute_t *attr, ipp_tag_t *group);
207*5e7646d2SAndroid Build Coastguard Worker static ipp_attribute_t *print_csv(ipptool_test_t *data, ipp_t *ipp, ipp_attribute_t *attr, int num_displayed, char **displayed, size_t *widths);
208*5e7646d2SAndroid Build Coastguard Worker static void print_fatal_error(ipptool_test_t *data, const char *s, ...) _CUPS_FORMAT(2, 3);
209*5e7646d2SAndroid Build Coastguard Worker static void print_ippserver_attr(ipptool_test_t *data, ipp_attribute_t *attr, int indent);
210*5e7646d2SAndroid Build Coastguard Worker static void print_ippserver_string(ipptool_test_t *data, const char *s, size_t len);
211*5e7646d2SAndroid Build Coastguard Worker static ipp_attribute_t *print_line(ipptool_test_t *data, ipp_t *ipp, ipp_attribute_t *attr, int num_displayed, char **displayed, size_t *widths);
212*5e7646d2SAndroid Build Coastguard Worker static void print_xml_header(ipptool_test_t *data);
213*5e7646d2SAndroid Build Coastguard Worker static void print_xml_string(cups_file_t *outfile, const char *element, const char *s);
214*5e7646d2SAndroid Build Coastguard Worker static void print_xml_trailer(ipptool_test_t *data, int success, const char *message);
215*5e7646d2SAndroid Build Coastguard Worker #ifndef _WIN32
216*5e7646d2SAndroid Build Coastguard Worker static void sigterm_handler(int sig);
217*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
218*5e7646d2SAndroid Build Coastguard Worker static int timeout_cb(http_t *http, void *user_data);
219*5e7646d2SAndroid Build Coastguard Worker static int token_cb(_ipp_file_t *f, _ipp_vars_t *vars, ipptool_test_t *data, const char *token);
220*5e7646d2SAndroid Build Coastguard Worker static void usage(void) _CUPS_NORETURN;
221*5e7646d2SAndroid Build Coastguard Worker static int with_distinct_values(cups_array_t *errors, ipp_attribute_t *attr);
222*5e7646d2SAndroid Build Coastguard Worker static const char *with_flags_string(int flags);
223*5e7646d2SAndroid Build Coastguard Worker static int with_value(ipptool_test_t *data, cups_array_t *errors, char *value, int flags, ipp_attribute_t *attr, char *matchbuf, size_t matchlen);
224*5e7646d2SAndroid Build Coastguard Worker static int with_value_from(cups_array_t *errors, ipp_attribute_t *fromattr, ipp_attribute_t *attr, char *matchbuf, size_t matchlen);
225*5e7646d2SAndroid Build Coastguard Worker
226*5e7646d2SAndroid Build Coastguard Worker
227*5e7646d2SAndroid Build Coastguard Worker /*
228*5e7646d2SAndroid Build Coastguard Worker * 'main()' - Parse options and do tests.
229*5e7646d2SAndroid Build Coastguard Worker */
230*5e7646d2SAndroid Build Coastguard Worker
231*5e7646d2SAndroid Build Coastguard Worker int /* O - Exit status */
main(int argc,char * argv[])232*5e7646d2SAndroid Build Coastguard Worker main(int argc, /* I - Number of command-line args */
233*5e7646d2SAndroid Build Coastguard Worker char *argv[]) /* I - Command-line arguments */
234*5e7646d2SAndroid Build Coastguard Worker {
235*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
236*5e7646d2SAndroid Build Coastguard Worker int status; /* Status of tests... */
237*5e7646d2SAndroid Build Coastguard Worker char *opt, /* Current option */
238*5e7646d2SAndroid Build Coastguard Worker name[1024], /* Name/value buffer */
239*5e7646d2SAndroid Build Coastguard Worker *value, /* Pointer to value */
240*5e7646d2SAndroid Build Coastguard Worker filename[1024], /* Real filename */
241*5e7646d2SAndroid Build Coastguard Worker testname[1024]; /* Real test filename */
242*5e7646d2SAndroid Build Coastguard Worker const char *ext, /* Extension on filename */
243*5e7646d2SAndroid Build Coastguard Worker *testfile; /* Test file to use */
244*5e7646d2SAndroid Build Coastguard Worker int interval, /* Test interval in microseconds */
245*5e7646d2SAndroid Build Coastguard Worker repeat; /* Repeat count */
246*5e7646d2SAndroid Build Coastguard Worker _ipp_vars_t vars; /* Variables */
247*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t data; /* Test data */
248*5e7646d2SAndroid Build Coastguard Worker _cups_globals_t *cg = _cupsGlobals();
249*5e7646d2SAndroid Build Coastguard Worker /* Global data */
250*5e7646d2SAndroid Build Coastguard Worker
251*5e7646d2SAndroid Build Coastguard Worker
252*5e7646d2SAndroid Build Coastguard Worker #ifndef _WIN32
253*5e7646d2SAndroid Build Coastguard Worker /*
254*5e7646d2SAndroid Build Coastguard Worker * Catch SIGINT and SIGTERM...
255*5e7646d2SAndroid Build Coastguard Worker */
256*5e7646d2SAndroid Build Coastguard Worker
257*5e7646d2SAndroid Build Coastguard Worker signal(SIGINT, sigterm_handler);
258*5e7646d2SAndroid Build Coastguard Worker signal(SIGTERM, sigterm_handler);
259*5e7646d2SAndroid Build Coastguard Worker #endif /* !_WIN32 */
260*5e7646d2SAndroid Build Coastguard Worker
261*5e7646d2SAndroid Build Coastguard Worker /*
262*5e7646d2SAndroid Build Coastguard Worker * Initialize the locale and variables...
263*5e7646d2SAndroid Build Coastguard Worker */
264*5e7646d2SAndroid Build Coastguard Worker
265*5e7646d2SAndroid Build Coastguard Worker _cupsSetLocale(argv);
266*5e7646d2SAndroid Build Coastguard Worker
267*5e7646d2SAndroid Build Coastguard Worker init_data(&data);
268*5e7646d2SAndroid Build Coastguard Worker
269*5e7646d2SAndroid Build Coastguard Worker _ippVarsInit(&vars, NULL, (_ipp_ferror_cb_t)error_cb, (_ipp_ftoken_cb_t)token_cb);
270*5e7646d2SAndroid Build Coastguard Worker data.vars = &vars;
271*5e7646d2SAndroid Build Coastguard Worker
272*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "date-start", iso_date(ippTimeToDate(time(NULL))));
273*5e7646d2SAndroid Build Coastguard Worker
274*5e7646d2SAndroid Build Coastguard Worker /*
275*5e7646d2SAndroid Build Coastguard Worker * We need at least:
276*5e7646d2SAndroid Build Coastguard Worker *
277*5e7646d2SAndroid Build Coastguard Worker * ipptool URI testfile
278*5e7646d2SAndroid Build Coastguard Worker */
279*5e7646d2SAndroid Build Coastguard Worker
280*5e7646d2SAndroid Build Coastguard Worker interval = 0;
281*5e7646d2SAndroid Build Coastguard Worker repeat = 0;
282*5e7646d2SAndroid Build Coastguard Worker status = 0;
283*5e7646d2SAndroid Build Coastguard Worker testfile = NULL;
284*5e7646d2SAndroid Build Coastguard Worker
285*5e7646d2SAndroid Build Coastguard Worker for (i = 1; i < argc; i ++)
286*5e7646d2SAndroid Build Coastguard Worker {
287*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(argv[i], "--help"))
288*5e7646d2SAndroid Build Coastguard Worker {
289*5e7646d2SAndroid Build Coastguard Worker usage();
290*5e7646d2SAndroid Build Coastguard Worker }
291*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(argv[i], "--ippserver"))
292*5e7646d2SAndroid Build Coastguard Worker {
293*5e7646d2SAndroid Build Coastguard Worker i ++;
294*5e7646d2SAndroid Build Coastguard Worker
295*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
296*5e7646d2SAndroid Build Coastguard Worker {
297*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("ipptool: Missing filename for \"--ippserver\"."));
298*5e7646d2SAndroid Build Coastguard Worker usage();
299*5e7646d2SAndroid Build Coastguard Worker }
300*5e7646d2SAndroid Build Coastguard Worker
301*5e7646d2SAndroid Build Coastguard Worker if (data.outfile != cupsFileStdout())
302*5e7646d2SAndroid Build Coastguard Worker usage();
303*5e7646d2SAndroid Build Coastguard Worker
304*5e7646d2SAndroid Build Coastguard Worker if ((data.outfile = cupsFileOpen(argv[i], "w")) == NULL)
305*5e7646d2SAndroid Build Coastguard Worker {
306*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Unable to open \"%s\": %s"), "ipptool", argv[i], strerror(errno));
307*5e7646d2SAndroid Build Coastguard Worker exit(1);
308*5e7646d2SAndroid Build Coastguard Worker }
309*5e7646d2SAndroid Build Coastguard Worker
310*5e7646d2SAndroid Build Coastguard Worker data.output = IPPTOOL_OUTPUT_IPPSERVER;
311*5e7646d2SAndroid Build Coastguard Worker }
312*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(argv[i], "--stop-after-include-error"))
313*5e7646d2SAndroid Build Coastguard Worker {
314*5e7646d2SAndroid Build Coastguard Worker data.stop_after_include_error = 1;
315*5e7646d2SAndroid Build Coastguard Worker }
316*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(argv[i], "--version"))
317*5e7646d2SAndroid Build Coastguard Worker {
318*5e7646d2SAndroid Build Coastguard Worker puts(CUPS_SVERSION);
319*5e7646d2SAndroid Build Coastguard Worker return (0);
320*5e7646d2SAndroid Build Coastguard Worker }
321*5e7646d2SAndroid Build Coastguard Worker else if (argv[i][0] == '-')
322*5e7646d2SAndroid Build Coastguard Worker {
323*5e7646d2SAndroid Build Coastguard Worker for (opt = argv[i] + 1; *opt; opt ++)
324*5e7646d2SAndroid Build Coastguard Worker {
325*5e7646d2SAndroid Build Coastguard Worker switch (*opt)
326*5e7646d2SAndroid Build Coastguard Worker {
327*5e7646d2SAndroid Build Coastguard Worker case '4' : /* Connect using IPv4 only */
328*5e7646d2SAndroid Build Coastguard Worker data.family = AF_INET;
329*5e7646d2SAndroid Build Coastguard Worker break;
330*5e7646d2SAndroid Build Coastguard Worker
331*5e7646d2SAndroid Build Coastguard Worker #ifdef AF_INET6
332*5e7646d2SAndroid Build Coastguard Worker case '6' : /* Connect using IPv6 only */
333*5e7646d2SAndroid Build Coastguard Worker data.family = AF_INET6;
334*5e7646d2SAndroid Build Coastguard Worker break;
335*5e7646d2SAndroid Build Coastguard Worker #endif /* AF_INET6 */
336*5e7646d2SAndroid Build Coastguard Worker
337*5e7646d2SAndroid Build Coastguard Worker case 'C' : /* Enable HTTP chunking */
338*5e7646d2SAndroid Build Coastguard Worker data.def_transfer = IPPTOOL_TRANSFER_CHUNKED;
339*5e7646d2SAndroid Build Coastguard Worker break;
340*5e7646d2SAndroid Build Coastguard Worker
341*5e7646d2SAndroid Build Coastguard Worker case 'E' : /* Encrypt with TLS */
342*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_TLS
343*5e7646d2SAndroid Build Coastguard Worker data.encryption = HTTP_ENCRYPT_REQUIRED;
344*5e7646d2SAndroid Build Coastguard Worker #else
345*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."),
346*5e7646d2SAndroid Build Coastguard Worker argv[0]);
347*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_TLS */
348*5e7646d2SAndroid Build Coastguard Worker break;
349*5e7646d2SAndroid Build Coastguard Worker
350*5e7646d2SAndroid Build Coastguard Worker case 'I' : /* Ignore errors */
351*5e7646d2SAndroid Build Coastguard Worker data.def_ignore_errors = 1;
352*5e7646d2SAndroid Build Coastguard Worker break;
353*5e7646d2SAndroid Build Coastguard Worker
354*5e7646d2SAndroid Build Coastguard Worker case 'L' : /* Disable HTTP chunking */
355*5e7646d2SAndroid Build Coastguard Worker data.def_transfer = IPPTOOL_TRANSFER_LENGTH;
356*5e7646d2SAndroid Build Coastguard Worker break;
357*5e7646d2SAndroid Build Coastguard Worker
358*5e7646d2SAndroid Build Coastguard Worker case 'P' : /* Output to plist file */
359*5e7646d2SAndroid Build Coastguard Worker i ++;
360*5e7646d2SAndroid Build Coastguard Worker
361*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
362*5e7646d2SAndroid Build Coastguard Worker {
363*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Missing filename for \"-P\"."), "ipptool");
364*5e7646d2SAndroid Build Coastguard Worker usage();
365*5e7646d2SAndroid Build Coastguard Worker }
366*5e7646d2SAndroid Build Coastguard Worker
367*5e7646d2SAndroid Build Coastguard Worker if (data.outfile != cupsFileStdout())
368*5e7646d2SAndroid Build Coastguard Worker usage();
369*5e7646d2SAndroid Build Coastguard Worker
370*5e7646d2SAndroid Build Coastguard Worker if ((data.outfile = cupsFileOpen(argv[i], "w")) == NULL)
371*5e7646d2SAndroid Build Coastguard Worker {
372*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Unable to open \"%s\": %s"), "ipptool", argv[i], strerror(errno));
373*5e7646d2SAndroid Build Coastguard Worker exit(1);
374*5e7646d2SAndroid Build Coastguard Worker }
375*5e7646d2SAndroid Build Coastguard Worker
376*5e7646d2SAndroid Build Coastguard Worker data.output = IPPTOOL_OUTPUT_PLIST;
377*5e7646d2SAndroid Build Coastguard Worker
378*5e7646d2SAndroid Build Coastguard Worker if (interval || repeat)
379*5e7646d2SAndroid Build Coastguard Worker {
380*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("ipptool: \"-i\" and \"-n\" are incompatible with \"-P\" and \"-X\"."));
381*5e7646d2SAndroid Build Coastguard Worker usage();
382*5e7646d2SAndroid Build Coastguard Worker }
383*5e7646d2SAndroid Build Coastguard Worker break;
384*5e7646d2SAndroid Build Coastguard Worker
385*5e7646d2SAndroid Build Coastguard Worker case 'R' : /* Repeat on server-error-busy */
386*5e7646d2SAndroid Build Coastguard Worker data.repeat_on_busy = 1;
387*5e7646d2SAndroid Build Coastguard Worker break;
388*5e7646d2SAndroid Build Coastguard Worker
389*5e7646d2SAndroid Build Coastguard Worker case 'S' : /* Encrypt with SSL */
390*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_TLS
391*5e7646d2SAndroid Build Coastguard Worker data.encryption = HTTP_ENCRYPT_ALWAYS;
392*5e7646d2SAndroid Build Coastguard Worker #else
393*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), "ipptool");
394*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_TLS */
395*5e7646d2SAndroid Build Coastguard Worker break;
396*5e7646d2SAndroid Build Coastguard Worker
397*5e7646d2SAndroid Build Coastguard Worker case 'T' : /* Set timeout */
398*5e7646d2SAndroid Build Coastguard Worker i ++;
399*5e7646d2SAndroid Build Coastguard Worker
400*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
401*5e7646d2SAndroid Build Coastguard Worker {
402*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Missing timeout for \"-T\"."), "ipptool");
403*5e7646d2SAndroid Build Coastguard Worker usage();
404*5e7646d2SAndroid Build Coastguard Worker }
405*5e7646d2SAndroid Build Coastguard Worker
406*5e7646d2SAndroid Build Coastguard Worker data.timeout = _cupsStrScand(argv[i], NULL, localeconv());
407*5e7646d2SAndroid Build Coastguard Worker break;
408*5e7646d2SAndroid Build Coastguard Worker
409*5e7646d2SAndroid Build Coastguard Worker case 'V' : /* Set IPP version */
410*5e7646d2SAndroid Build Coastguard Worker i ++;
411*5e7646d2SAndroid Build Coastguard Worker
412*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
413*5e7646d2SAndroid Build Coastguard Worker {
414*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Missing version for \"-V\"."), "ipptool");
415*5e7646d2SAndroid Build Coastguard Worker usage();
416*5e7646d2SAndroid Build Coastguard Worker }
417*5e7646d2SAndroid Build Coastguard Worker
418*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(argv[i], "1.0"))
419*5e7646d2SAndroid Build Coastguard Worker {
420*5e7646d2SAndroid Build Coastguard Worker data.def_version = 10;
421*5e7646d2SAndroid Build Coastguard Worker }
422*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(argv[i], "1.1"))
423*5e7646d2SAndroid Build Coastguard Worker {
424*5e7646d2SAndroid Build Coastguard Worker data.def_version = 11;
425*5e7646d2SAndroid Build Coastguard Worker }
426*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(argv[i], "2.0"))
427*5e7646d2SAndroid Build Coastguard Worker {
428*5e7646d2SAndroid Build Coastguard Worker data.def_version = 20;
429*5e7646d2SAndroid Build Coastguard Worker }
430*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(argv[i], "2.1"))
431*5e7646d2SAndroid Build Coastguard Worker {
432*5e7646d2SAndroid Build Coastguard Worker data.def_version = 21;
433*5e7646d2SAndroid Build Coastguard Worker }
434*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(argv[i], "2.2"))
435*5e7646d2SAndroid Build Coastguard Worker {
436*5e7646d2SAndroid Build Coastguard Worker data.def_version = 22;
437*5e7646d2SAndroid Build Coastguard Worker }
438*5e7646d2SAndroid Build Coastguard Worker else
439*5e7646d2SAndroid Build Coastguard Worker {
440*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Bad version %s for \"-V\"."), "ipptool", argv[i]);
441*5e7646d2SAndroid Build Coastguard Worker usage();
442*5e7646d2SAndroid Build Coastguard Worker }
443*5e7646d2SAndroid Build Coastguard Worker break;
444*5e7646d2SAndroid Build Coastguard Worker
445*5e7646d2SAndroid Build Coastguard Worker case 'X' : /* Produce XML output */
446*5e7646d2SAndroid Build Coastguard Worker data.output = IPPTOOL_OUTPUT_PLIST;
447*5e7646d2SAndroid Build Coastguard Worker
448*5e7646d2SAndroid Build Coastguard Worker if (interval || repeat)
449*5e7646d2SAndroid Build Coastguard Worker {
450*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("ipptool: \"-i\" and \"-n\" are incompatible with \"-P\" and \"-X\"."));
451*5e7646d2SAndroid Build Coastguard Worker usage();
452*5e7646d2SAndroid Build Coastguard Worker }
453*5e7646d2SAndroid Build Coastguard Worker break;
454*5e7646d2SAndroid Build Coastguard Worker
455*5e7646d2SAndroid Build Coastguard Worker case 'c' : /* CSV output */
456*5e7646d2SAndroid Build Coastguard Worker data.output = IPPTOOL_OUTPUT_CSV;
457*5e7646d2SAndroid Build Coastguard Worker break;
458*5e7646d2SAndroid Build Coastguard Worker
459*5e7646d2SAndroid Build Coastguard Worker case 'd' : /* Define a variable */
460*5e7646d2SAndroid Build Coastguard Worker i ++;
461*5e7646d2SAndroid Build Coastguard Worker
462*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
463*5e7646d2SAndroid Build Coastguard Worker {
464*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("ipptool: Missing name=value for \"-d\"."));
465*5e7646d2SAndroid Build Coastguard Worker usage();
466*5e7646d2SAndroid Build Coastguard Worker }
467*5e7646d2SAndroid Build Coastguard Worker
468*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, argv[i], sizeof(name));
469*5e7646d2SAndroid Build Coastguard Worker if ((value = strchr(name, '=')) != NULL)
470*5e7646d2SAndroid Build Coastguard Worker *value++ = '\0';
471*5e7646d2SAndroid Build Coastguard Worker else
472*5e7646d2SAndroid Build Coastguard Worker value = name + strlen(name);
473*5e7646d2SAndroid Build Coastguard Worker
474*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, name, value);
475*5e7646d2SAndroid Build Coastguard Worker break;
476*5e7646d2SAndroid Build Coastguard Worker
477*5e7646d2SAndroid Build Coastguard Worker case 'f' : /* Set the default test filename */
478*5e7646d2SAndroid Build Coastguard Worker i ++;
479*5e7646d2SAndroid Build Coastguard Worker
480*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
481*5e7646d2SAndroid Build Coastguard Worker {
482*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("ipptool: Missing filename for \"-f\"."));
483*5e7646d2SAndroid Build Coastguard Worker usage();
484*5e7646d2SAndroid Build Coastguard Worker }
485*5e7646d2SAndroid Build Coastguard Worker
486*5e7646d2SAndroid Build Coastguard Worker if (access(argv[i], 0))
487*5e7646d2SAndroid Build Coastguard Worker {
488*5e7646d2SAndroid Build Coastguard Worker /*
489*5e7646d2SAndroid Build Coastguard Worker * Try filename.gz...
490*5e7646d2SAndroid Build Coastguard Worker */
491*5e7646d2SAndroid Build Coastguard Worker
492*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s.gz", argv[i]);
493*5e7646d2SAndroid Build Coastguard Worker if (access(filename, 0) && filename[0] != '/'
494*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
495*5e7646d2SAndroid Build Coastguard Worker && (!isalpha(filename[0] & 255) || filename[1] != ':')
496*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
497*5e7646d2SAndroid Build Coastguard Worker )
498*5e7646d2SAndroid Build Coastguard Worker {
499*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/ipptool/%s", cg->cups_datadir, argv[i]);
500*5e7646d2SAndroid Build Coastguard Worker if (access(filename, 0))
501*5e7646d2SAndroid Build Coastguard Worker {
502*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/ipptool/%s.gz", cg->cups_datadir, argv[i]);
503*5e7646d2SAndroid Build Coastguard Worker if (access(filename, 0))
504*5e7646d2SAndroid Build Coastguard Worker strlcpy(filename, argv[i], sizeof(filename));
505*5e7646d2SAndroid Build Coastguard Worker }
506*5e7646d2SAndroid Build Coastguard Worker }
507*5e7646d2SAndroid Build Coastguard Worker }
508*5e7646d2SAndroid Build Coastguard Worker else
509*5e7646d2SAndroid Build Coastguard Worker strlcpy(filename, argv[i], sizeof(filename));
510*5e7646d2SAndroid Build Coastguard Worker
511*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "filename", filename);
512*5e7646d2SAndroid Build Coastguard Worker
513*5e7646d2SAndroid Build Coastguard Worker if ((ext = strrchr(filename, '.')) != NULL)
514*5e7646d2SAndroid Build Coastguard Worker {
515*5e7646d2SAndroid Build Coastguard Worker /*
516*5e7646d2SAndroid Build Coastguard Worker * Guess the MIME media type based on the extension...
517*5e7646d2SAndroid Build Coastguard Worker */
518*5e7646d2SAndroid Build Coastguard Worker
519*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(ext, ".gif"))
520*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "filetype", "image/gif");
521*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ext, ".htm") ||
522*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(ext, ".htm.gz") ||
523*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(ext, ".html") ||
524*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(ext, ".html.gz"))
525*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "filetype", "text/html");
526*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ext, ".jpg") ||
527*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(ext, ".jpeg"))
528*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "filetype", "image/jpeg");
529*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ext, ".pcl") ||
530*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(ext, ".pcl.gz"))
531*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "filetype", "application/vnd.hp-PCL");
532*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ext, ".pdf"))
533*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "filetype", "application/pdf");
534*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ext, ".png"))
535*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "filetype", "image/png");
536*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ext, ".ps") ||
537*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(ext, ".ps.gz"))
538*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "filetype", "application/postscript");
539*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ext, ".pwg") ||
540*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(ext, ".pwg.gz") ||
541*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(ext, ".ras") ||
542*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(ext, ".ras.gz"))
543*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "filetype", "image/pwg-raster");
544*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ext, ".tif") ||
545*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(ext, ".tiff"))
546*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "filetype", "image/tiff");
547*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ext, ".txt") ||
548*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(ext, ".txt.gz"))
549*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "filetype", "text/plain");
550*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ext, ".urf") ||
551*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(ext, ".urf.gz"))
552*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "filetype", "image/urf");
553*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ext, ".xps"))
554*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "filetype", "application/openxps");
555*5e7646d2SAndroid Build Coastguard Worker else
556*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "filetype", "application/octet-stream");
557*5e7646d2SAndroid Build Coastguard Worker }
558*5e7646d2SAndroid Build Coastguard Worker else
559*5e7646d2SAndroid Build Coastguard Worker {
560*5e7646d2SAndroid Build Coastguard Worker /*
561*5e7646d2SAndroid Build Coastguard Worker * Use the "auto-type" MIME media type...
562*5e7646d2SAndroid Build Coastguard Worker */
563*5e7646d2SAndroid Build Coastguard Worker
564*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data.vars, "filetype", "application/octet-stream");
565*5e7646d2SAndroid Build Coastguard Worker }
566*5e7646d2SAndroid Build Coastguard Worker break;
567*5e7646d2SAndroid Build Coastguard Worker
568*5e7646d2SAndroid Build Coastguard Worker case 'h' : /* Validate response headers */
569*5e7646d2SAndroid Build Coastguard Worker data.validate_headers = 1;
570*5e7646d2SAndroid Build Coastguard Worker break;
571*5e7646d2SAndroid Build Coastguard Worker
572*5e7646d2SAndroid Build Coastguard Worker case 'i' : /* Test every N seconds */
573*5e7646d2SAndroid Build Coastguard Worker i ++;
574*5e7646d2SAndroid Build Coastguard Worker
575*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
576*5e7646d2SAndroid Build Coastguard Worker {
577*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("ipptool: Missing seconds for \"-i\"."));
578*5e7646d2SAndroid Build Coastguard Worker usage();
579*5e7646d2SAndroid Build Coastguard Worker }
580*5e7646d2SAndroid Build Coastguard Worker else
581*5e7646d2SAndroid Build Coastguard Worker {
582*5e7646d2SAndroid Build Coastguard Worker interval = (int)(_cupsStrScand(argv[i], NULL, localeconv()) * 1000000.0);
583*5e7646d2SAndroid Build Coastguard Worker if (interval <= 0)
584*5e7646d2SAndroid Build Coastguard Worker {
585*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("ipptool: Invalid seconds for \"-i\"."));
586*5e7646d2SAndroid Build Coastguard Worker usage();
587*5e7646d2SAndroid Build Coastguard Worker }
588*5e7646d2SAndroid Build Coastguard Worker }
589*5e7646d2SAndroid Build Coastguard Worker
590*5e7646d2SAndroid Build Coastguard Worker if ((data.output == IPPTOOL_OUTPUT_PLIST || data.output == IPPTOOL_OUTPUT_IPPSERVER) && interval)
591*5e7646d2SAndroid Build Coastguard Worker {
592*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("ipptool: \"-i\" and \"-n\" are incompatible with \"--ippserver\", \"-P\", and \"-X\"."));
593*5e7646d2SAndroid Build Coastguard Worker usage();
594*5e7646d2SAndroid Build Coastguard Worker }
595*5e7646d2SAndroid Build Coastguard Worker break;
596*5e7646d2SAndroid Build Coastguard Worker
597*5e7646d2SAndroid Build Coastguard Worker case 'l' : /* List as a table */
598*5e7646d2SAndroid Build Coastguard Worker data.output = IPPTOOL_OUTPUT_LIST;
599*5e7646d2SAndroid Build Coastguard Worker break;
600*5e7646d2SAndroid Build Coastguard Worker
601*5e7646d2SAndroid Build Coastguard Worker case 'n' : /* Repeat count */
602*5e7646d2SAndroid Build Coastguard Worker i ++;
603*5e7646d2SAndroid Build Coastguard Worker
604*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
605*5e7646d2SAndroid Build Coastguard Worker {
606*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("ipptool: Missing count for \"-n\"."));
607*5e7646d2SAndroid Build Coastguard Worker usage();
608*5e7646d2SAndroid Build Coastguard Worker }
609*5e7646d2SAndroid Build Coastguard Worker else
610*5e7646d2SAndroid Build Coastguard Worker repeat = atoi(argv[i]);
611*5e7646d2SAndroid Build Coastguard Worker
612*5e7646d2SAndroid Build Coastguard Worker if ((data.output == IPPTOOL_OUTPUT_PLIST || data.output == IPPTOOL_OUTPUT_IPPSERVER) && repeat)
613*5e7646d2SAndroid Build Coastguard Worker {
614*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("ipptool: \"-i\" and \"-n\" are incompatible with \"--ippserver\", \"-P\", and \"-X\"."));
615*5e7646d2SAndroid Build Coastguard Worker usage();
616*5e7646d2SAndroid Build Coastguard Worker }
617*5e7646d2SAndroid Build Coastguard Worker break;
618*5e7646d2SAndroid Build Coastguard Worker
619*5e7646d2SAndroid Build Coastguard Worker case 'q' : /* Be quiet */
620*5e7646d2SAndroid Build Coastguard Worker data.output = IPPTOOL_OUTPUT_QUIET;
621*5e7646d2SAndroid Build Coastguard Worker break;
622*5e7646d2SAndroid Build Coastguard Worker
623*5e7646d2SAndroid Build Coastguard Worker case 't' : /* CUPS test output */
624*5e7646d2SAndroid Build Coastguard Worker data.output = IPPTOOL_OUTPUT_TEST;
625*5e7646d2SAndroid Build Coastguard Worker break;
626*5e7646d2SAndroid Build Coastguard Worker
627*5e7646d2SAndroid Build Coastguard Worker case 'v' : /* Be verbose */
628*5e7646d2SAndroid Build Coastguard Worker data.verbosity ++;
629*5e7646d2SAndroid Build Coastguard Worker break;
630*5e7646d2SAndroid Build Coastguard Worker
631*5e7646d2SAndroid Build Coastguard Worker default :
632*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Unknown option \"-%c\"."), "ipptool", *opt);
633*5e7646d2SAndroid Build Coastguard Worker usage();
634*5e7646d2SAndroid Build Coastguard Worker }
635*5e7646d2SAndroid Build Coastguard Worker }
636*5e7646d2SAndroid Build Coastguard Worker }
637*5e7646d2SAndroid Build Coastguard Worker else if (!strncmp(argv[i], "ipp://", 6) || !strncmp(argv[i], "http://", 7)
638*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_TLS
639*5e7646d2SAndroid Build Coastguard Worker || !strncmp(argv[i], "ipps://", 7) || !strncmp(argv[i], "https://", 8)
640*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_TLS */
641*5e7646d2SAndroid Build Coastguard Worker )
642*5e7646d2SAndroid Build Coastguard Worker {
643*5e7646d2SAndroid Build Coastguard Worker /*
644*5e7646d2SAndroid Build Coastguard Worker * Set URI...
645*5e7646d2SAndroid Build Coastguard Worker */
646*5e7646d2SAndroid Build Coastguard Worker
647*5e7646d2SAndroid Build Coastguard Worker if (data.vars->uri)
648*5e7646d2SAndroid Build Coastguard Worker {
649*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("ipptool: May only specify a single URI."));
650*5e7646d2SAndroid Build Coastguard Worker usage();
651*5e7646d2SAndroid Build Coastguard Worker }
652*5e7646d2SAndroid Build Coastguard Worker
653*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_TLS
654*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(argv[i], "ipps://", 7) || !strncmp(argv[i], "https://", 8))
655*5e7646d2SAndroid Build Coastguard Worker data.encryption = HTTP_ENCRYPT_ALWAYS;
656*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_TLS */
657*5e7646d2SAndroid Build Coastguard Worker
658*5e7646d2SAndroid Build Coastguard Worker if (!_ippVarsSet(data.vars, "uri", argv[i]))
659*5e7646d2SAndroid Build Coastguard Worker {
660*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("ipptool: Bad URI \"%s\"."), argv[i]);
661*5e7646d2SAndroid Build Coastguard Worker return (1);
662*5e7646d2SAndroid Build Coastguard Worker }
663*5e7646d2SAndroid Build Coastguard Worker
664*5e7646d2SAndroid Build Coastguard Worker if (data.vars->username[0] && data.vars->password)
665*5e7646d2SAndroid Build Coastguard Worker cupsSetPasswordCB2(_ippVarsPasswordCB, data.vars);
666*5e7646d2SAndroid Build Coastguard Worker }
667*5e7646d2SAndroid Build Coastguard Worker else
668*5e7646d2SAndroid Build Coastguard Worker {
669*5e7646d2SAndroid Build Coastguard Worker /*
670*5e7646d2SAndroid Build Coastguard Worker * Run test...
671*5e7646d2SAndroid Build Coastguard Worker */
672*5e7646d2SAndroid Build Coastguard Worker
673*5e7646d2SAndroid Build Coastguard Worker if (!data.vars->uri)
674*5e7646d2SAndroid Build Coastguard Worker {
675*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("ipptool: URI required before test file."));
676*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, argv[i]);
677*5e7646d2SAndroid Build Coastguard Worker usage();
678*5e7646d2SAndroid Build Coastguard Worker }
679*5e7646d2SAndroid Build Coastguard Worker
680*5e7646d2SAndroid Build Coastguard Worker if (access(argv[i], 0) && argv[i][0] != '/'
681*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
682*5e7646d2SAndroid Build Coastguard Worker && (!isalpha(argv[i][0] & 255) || argv[i][1] != ':')
683*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
684*5e7646d2SAndroid Build Coastguard Worker )
685*5e7646d2SAndroid Build Coastguard Worker {
686*5e7646d2SAndroid Build Coastguard Worker snprintf(testname, sizeof(testname), "%s/ipptool/%s", cg->cups_datadir, argv[i]);
687*5e7646d2SAndroid Build Coastguard Worker if (access(testname, 0))
688*5e7646d2SAndroid Build Coastguard Worker testfile = argv[i];
689*5e7646d2SAndroid Build Coastguard Worker else
690*5e7646d2SAndroid Build Coastguard Worker testfile = testname;
691*5e7646d2SAndroid Build Coastguard Worker }
692*5e7646d2SAndroid Build Coastguard Worker else
693*5e7646d2SAndroid Build Coastguard Worker testfile = argv[i];
694*5e7646d2SAndroid Build Coastguard Worker
695*5e7646d2SAndroid Build Coastguard Worker if (access(testfile, 0))
696*5e7646d2SAndroid Build Coastguard Worker {
697*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Unable to open \"%s\": %s"), "ipptool", testfile, strerror(errno));
698*5e7646d2SAndroid Build Coastguard Worker status = 1;
699*5e7646d2SAndroid Build Coastguard Worker }
700*5e7646d2SAndroid Build Coastguard Worker else if (!do_tests(testfile, &data))
701*5e7646d2SAndroid Build Coastguard Worker status = 1;
702*5e7646d2SAndroid Build Coastguard Worker }
703*5e7646d2SAndroid Build Coastguard Worker }
704*5e7646d2SAndroid Build Coastguard Worker
705*5e7646d2SAndroid Build Coastguard Worker if (!data.vars->uri || !testfile)
706*5e7646d2SAndroid Build Coastguard Worker usage();
707*5e7646d2SAndroid Build Coastguard Worker
708*5e7646d2SAndroid Build Coastguard Worker /*
709*5e7646d2SAndroid Build Coastguard Worker * Loop if the interval is set...
710*5e7646d2SAndroid Build Coastguard Worker */
711*5e7646d2SAndroid Build Coastguard Worker
712*5e7646d2SAndroid Build Coastguard Worker if (data.output == IPPTOOL_OUTPUT_PLIST)
713*5e7646d2SAndroid Build Coastguard Worker print_xml_trailer(&data, !status, NULL);
714*5e7646d2SAndroid Build Coastguard Worker else if (interval > 0 && repeat > 0)
715*5e7646d2SAndroid Build Coastguard Worker {
716*5e7646d2SAndroid Build Coastguard Worker while (repeat > 1)
717*5e7646d2SAndroid Build Coastguard Worker {
718*5e7646d2SAndroid Build Coastguard Worker usleep((useconds_t)interval);
719*5e7646d2SAndroid Build Coastguard Worker do_tests(testfile, &data);
720*5e7646d2SAndroid Build Coastguard Worker repeat --;
721*5e7646d2SAndroid Build Coastguard Worker }
722*5e7646d2SAndroid Build Coastguard Worker }
723*5e7646d2SAndroid Build Coastguard Worker else if (interval > 0)
724*5e7646d2SAndroid Build Coastguard Worker {
725*5e7646d2SAndroid Build Coastguard Worker for (;;)
726*5e7646d2SAndroid Build Coastguard Worker {
727*5e7646d2SAndroid Build Coastguard Worker usleep((useconds_t)interval);
728*5e7646d2SAndroid Build Coastguard Worker do_tests(testfile, &data);
729*5e7646d2SAndroid Build Coastguard Worker }
730*5e7646d2SAndroid Build Coastguard Worker }
731*5e7646d2SAndroid Build Coastguard Worker
732*5e7646d2SAndroid Build Coastguard Worker if ((data.output == IPPTOOL_OUTPUT_TEST || (data.output == IPPTOOL_OUTPUT_PLIST && data.outfile)) && data.test_count > 1)
733*5e7646d2SAndroid Build Coastguard Worker {
734*5e7646d2SAndroid Build Coastguard Worker /*
735*5e7646d2SAndroid Build Coastguard Worker * Show a summary report if there were multiple tests...
736*5e7646d2SAndroid Build Coastguard Worker */
737*5e7646d2SAndroid Build Coastguard Worker
738*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(cupsFileStdout(), "\nSummary: %d tests, %d passed, %d failed, %d skipped\nScore: %d%%\n", data.test_count, data.pass_count, data.fail_count, data.skip_count, 100 * (data.pass_count + data.skip_count) / data.test_count);
739*5e7646d2SAndroid Build Coastguard Worker }
740*5e7646d2SAndroid Build Coastguard Worker
741*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(data.outfile);
742*5e7646d2SAndroid Build Coastguard Worker
743*5e7646d2SAndroid Build Coastguard Worker /*
744*5e7646d2SAndroid Build Coastguard Worker * Exit...
745*5e7646d2SAndroid Build Coastguard Worker */
746*5e7646d2SAndroid Build Coastguard Worker
747*5e7646d2SAndroid Build Coastguard Worker return (status);
748*5e7646d2SAndroid Build Coastguard Worker }
749*5e7646d2SAndroid Build Coastguard Worker
750*5e7646d2SAndroid Build Coastguard Worker
751*5e7646d2SAndroid Build Coastguard Worker /*
752*5e7646d2SAndroid Build Coastguard Worker * 'add_stringf()' - Add a formatted string to an array.
753*5e7646d2SAndroid Build Coastguard Worker */
754*5e7646d2SAndroid Build Coastguard Worker
755*5e7646d2SAndroid Build Coastguard Worker static void
add_stringf(cups_array_t * a,const char * s,...)756*5e7646d2SAndroid Build Coastguard Worker add_stringf(cups_array_t *a, /* I - Array */
757*5e7646d2SAndroid Build Coastguard Worker const char *s, /* I - Printf-style format string */
758*5e7646d2SAndroid Build Coastguard Worker ...) /* I - Additional args as needed */
759*5e7646d2SAndroid Build Coastguard Worker {
760*5e7646d2SAndroid Build Coastguard Worker char buffer[10240]; /* Format buffer */
761*5e7646d2SAndroid Build Coastguard Worker va_list ap; /* Argument pointer */
762*5e7646d2SAndroid Build Coastguard Worker
763*5e7646d2SAndroid Build Coastguard Worker
764*5e7646d2SAndroid Build Coastguard Worker /*
765*5e7646d2SAndroid Build Coastguard Worker * Don't bother is the array is NULL...
766*5e7646d2SAndroid Build Coastguard Worker */
767*5e7646d2SAndroid Build Coastguard Worker
768*5e7646d2SAndroid Build Coastguard Worker if (!a)
769*5e7646d2SAndroid Build Coastguard Worker return;
770*5e7646d2SAndroid Build Coastguard Worker
771*5e7646d2SAndroid Build Coastguard Worker /*
772*5e7646d2SAndroid Build Coastguard Worker * Format the message...
773*5e7646d2SAndroid Build Coastguard Worker */
774*5e7646d2SAndroid Build Coastguard Worker
775*5e7646d2SAndroid Build Coastguard Worker va_start(ap, s);
776*5e7646d2SAndroid Build Coastguard Worker vsnprintf(buffer, sizeof(buffer), s, ap);
777*5e7646d2SAndroid Build Coastguard Worker va_end(ap);
778*5e7646d2SAndroid Build Coastguard Worker
779*5e7646d2SAndroid Build Coastguard Worker /*
780*5e7646d2SAndroid Build Coastguard Worker * Add it to the array...
781*5e7646d2SAndroid Build Coastguard Worker */
782*5e7646d2SAndroid Build Coastguard Worker
783*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(a, buffer);
784*5e7646d2SAndroid Build Coastguard Worker }
785*5e7646d2SAndroid Build Coastguard Worker
786*5e7646d2SAndroid Build Coastguard Worker
787*5e7646d2SAndroid Build Coastguard Worker /*
788*5e7646d2SAndroid Build Coastguard Worker * 'compare_uris()' - Compare two URIs...
789*5e7646d2SAndroid Build Coastguard Worker */
790*5e7646d2SAndroid Build Coastguard Worker
791*5e7646d2SAndroid Build Coastguard Worker static int /* O - Result of comparison */
compare_uris(const char * a,const char * b)792*5e7646d2SAndroid Build Coastguard Worker compare_uris(const char *a, /* I - First URI */
793*5e7646d2SAndroid Build Coastguard Worker const char *b) /* I - Second URI */
794*5e7646d2SAndroid Build Coastguard Worker {
795*5e7646d2SAndroid Build Coastguard Worker char ascheme[32], /* Components of first URI */
796*5e7646d2SAndroid Build Coastguard Worker auserpass[256],
797*5e7646d2SAndroid Build Coastguard Worker ahost[256],
798*5e7646d2SAndroid Build Coastguard Worker aresource[256];
799*5e7646d2SAndroid Build Coastguard Worker int aport;
800*5e7646d2SAndroid Build Coastguard Worker char bscheme[32], /* Components of second URI */
801*5e7646d2SAndroid Build Coastguard Worker buserpass[256],
802*5e7646d2SAndroid Build Coastguard Worker bhost[256],
803*5e7646d2SAndroid Build Coastguard Worker bresource[256];
804*5e7646d2SAndroid Build Coastguard Worker int bport;
805*5e7646d2SAndroid Build Coastguard Worker char *ptr; /* Pointer into string */
806*5e7646d2SAndroid Build Coastguard Worker int result; /* Result of comparison */
807*5e7646d2SAndroid Build Coastguard Worker
808*5e7646d2SAndroid Build Coastguard Worker
809*5e7646d2SAndroid Build Coastguard Worker /*
810*5e7646d2SAndroid Build Coastguard Worker * Separate the URIs into their components...
811*5e7646d2SAndroid Build Coastguard Worker */
812*5e7646d2SAndroid Build Coastguard Worker
813*5e7646d2SAndroid Build Coastguard Worker if (httpSeparateURI(HTTP_URI_CODING_ALL, a, ascheme, sizeof(ascheme), auserpass, sizeof(auserpass), ahost, sizeof(ahost), &aport, aresource, sizeof(aresource)) < HTTP_URI_STATUS_OK)
814*5e7646d2SAndroid Build Coastguard Worker return (-1);
815*5e7646d2SAndroid Build Coastguard Worker
816*5e7646d2SAndroid Build Coastguard Worker if (httpSeparateURI(HTTP_URI_CODING_ALL, b, bscheme, sizeof(bscheme), buserpass, sizeof(buserpass), bhost, sizeof(bhost), &bport, bresource, sizeof(bresource)) < HTTP_URI_STATUS_OK)
817*5e7646d2SAndroid Build Coastguard Worker return (-1);
818*5e7646d2SAndroid Build Coastguard Worker
819*5e7646d2SAndroid Build Coastguard Worker /*
820*5e7646d2SAndroid Build Coastguard Worker * Strip trailing dots from the host components, if present...
821*5e7646d2SAndroid Build Coastguard Worker */
822*5e7646d2SAndroid Build Coastguard Worker
823*5e7646d2SAndroid Build Coastguard Worker if ((ptr = ahost + strlen(ahost) - 1) > ahost && *ptr == '.')
824*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
825*5e7646d2SAndroid Build Coastguard Worker
826*5e7646d2SAndroid Build Coastguard Worker if ((ptr = bhost + strlen(bhost) - 1) > bhost && *ptr == '.')
827*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
828*5e7646d2SAndroid Build Coastguard Worker
829*5e7646d2SAndroid Build Coastguard Worker /*
830*5e7646d2SAndroid Build Coastguard Worker * Compare each component...
831*5e7646d2SAndroid Build Coastguard Worker */
832*5e7646d2SAndroid Build Coastguard Worker
833*5e7646d2SAndroid Build Coastguard Worker if ((result = _cups_strcasecmp(ascheme, bscheme)) != 0)
834*5e7646d2SAndroid Build Coastguard Worker return (result);
835*5e7646d2SAndroid Build Coastguard Worker
836*5e7646d2SAndroid Build Coastguard Worker if ((result = strcmp(auserpass, buserpass)) != 0)
837*5e7646d2SAndroid Build Coastguard Worker return (result);
838*5e7646d2SAndroid Build Coastguard Worker
839*5e7646d2SAndroid Build Coastguard Worker if ((result = _cups_strcasecmp(ahost, bhost)) != 0)
840*5e7646d2SAndroid Build Coastguard Worker return (result);
841*5e7646d2SAndroid Build Coastguard Worker
842*5e7646d2SAndroid Build Coastguard Worker if (aport != bport)
843*5e7646d2SAndroid Build Coastguard Worker return (aport - bport);
844*5e7646d2SAndroid Build Coastguard Worker
845*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(ascheme, "mailto") || !_cups_strcasecmp(ascheme, "urn"))
846*5e7646d2SAndroid Build Coastguard Worker return (_cups_strcasecmp(aresource, bresource));
847*5e7646d2SAndroid Build Coastguard Worker else
848*5e7646d2SAndroid Build Coastguard Worker return (strcmp(aresource, bresource));
849*5e7646d2SAndroid Build Coastguard Worker }
850*5e7646d2SAndroid Build Coastguard Worker
851*5e7646d2SAndroid Build Coastguard Worker
852*5e7646d2SAndroid Build Coastguard Worker /*
853*5e7646d2SAndroid Build Coastguard Worker * 'copy_hex_string()' - Copy an octetString to a C string and encode as hex if
854*5e7646d2SAndroid Build Coastguard Worker * needed.
855*5e7646d2SAndroid Build Coastguard Worker */
856*5e7646d2SAndroid Build Coastguard Worker
857*5e7646d2SAndroid Build Coastguard Worker static void
copy_hex_string(char * buffer,unsigned char * data,int datalen,size_t bufsize)858*5e7646d2SAndroid Build Coastguard Worker copy_hex_string(char *buffer, /* I - String buffer */
859*5e7646d2SAndroid Build Coastguard Worker unsigned char *data, /* I - octetString data */
860*5e7646d2SAndroid Build Coastguard Worker int datalen, /* I - octetString length */
861*5e7646d2SAndroid Build Coastguard Worker size_t bufsize) /* I - Size of string buffer */
862*5e7646d2SAndroid Build Coastguard Worker {
863*5e7646d2SAndroid Build Coastguard Worker char *bufptr, /* Pointer into string buffer */
864*5e7646d2SAndroid Build Coastguard Worker *bufend = buffer + bufsize - 2;
865*5e7646d2SAndroid Build Coastguard Worker /* End of string buffer */
866*5e7646d2SAndroid Build Coastguard Worker unsigned char *dataptr, /* Pointer into octetString data */
867*5e7646d2SAndroid Build Coastguard Worker *dataend = data + datalen;
868*5e7646d2SAndroid Build Coastguard Worker /* End of octetString data */
869*5e7646d2SAndroid Build Coastguard Worker static const char *hexdigits = "0123456789ABCDEF";
870*5e7646d2SAndroid Build Coastguard Worker /* Hex digits */
871*5e7646d2SAndroid Build Coastguard Worker
872*5e7646d2SAndroid Build Coastguard Worker
873*5e7646d2SAndroid Build Coastguard Worker /*
874*5e7646d2SAndroid Build Coastguard Worker * First see if there are any non-ASCII bytes in the octetString...
875*5e7646d2SAndroid Build Coastguard Worker */
876*5e7646d2SAndroid Build Coastguard Worker
877*5e7646d2SAndroid Build Coastguard Worker for (dataptr = data; dataptr < dataend; dataptr ++)
878*5e7646d2SAndroid Build Coastguard Worker if (*dataptr < 0x20 || *dataptr >= 0x7f)
879*5e7646d2SAndroid Build Coastguard Worker break;
880*5e7646d2SAndroid Build Coastguard Worker
881*5e7646d2SAndroid Build Coastguard Worker if (dataptr < dataend)
882*5e7646d2SAndroid Build Coastguard Worker {
883*5e7646d2SAndroid Build Coastguard Worker /*
884*5e7646d2SAndroid Build Coastguard Worker * Yes, encode as hex...
885*5e7646d2SAndroid Build Coastguard Worker */
886*5e7646d2SAndroid Build Coastguard Worker
887*5e7646d2SAndroid Build Coastguard Worker *buffer = '<';
888*5e7646d2SAndroid Build Coastguard Worker
889*5e7646d2SAndroid Build Coastguard Worker for (bufptr = buffer + 1, dataptr = data; bufptr < bufend && dataptr < dataend; dataptr ++)
890*5e7646d2SAndroid Build Coastguard Worker {
891*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = hexdigits[*dataptr >> 4];
892*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = hexdigits[*dataptr & 15];
893*5e7646d2SAndroid Build Coastguard Worker }
894*5e7646d2SAndroid Build Coastguard Worker
895*5e7646d2SAndroid Build Coastguard Worker if (bufptr < bufend)
896*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '>';
897*5e7646d2SAndroid Build Coastguard Worker
898*5e7646d2SAndroid Build Coastguard Worker *bufptr = '\0';
899*5e7646d2SAndroid Build Coastguard Worker }
900*5e7646d2SAndroid Build Coastguard Worker else
901*5e7646d2SAndroid Build Coastguard Worker {
902*5e7646d2SAndroid Build Coastguard Worker /*
903*5e7646d2SAndroid Build Coastguard Worker * No, copy as a string...
904*5e7646d2SAndroid Build Coastguard Worker */
905*5e7646d2SAndroid Build Coastguard Worker
906*5e7646d2SAndroid Build Coastguard Worker if ((size_t)datalen > bufsize)
907*5e7646d2SAndroid Build Coastguard Worker datalen = (int)bufsize - 1;
908*5e7646d2SAndroid Build Coastguard Worker
909*5e7646d2SAndroid Build Coastguard Worker memcpy(buffer, data, (size_t)datalen);
910*5e7646d2SAndroid Build Coastguard Worker buffer[datalen] = '\0';
911*5e7646d2SAndroid Build Coastguard Worker }
912*5e7646d2SAndroid Build Coastguard Worker }
913*5e7646d2SAndroid Build Coastguard Worker
914*5e7646d2SAndroid Build Coastguard Worker
915*5e7646d2SAndroid Build Coastguard Worker /*
916*5e7646d2SAndroid Build Coastguard Worker * 'do_monitor_printer_state()' - Do the MONITOR-PRINTER-STATE tests in the background.
917*5e7646d2SAndroid Build Coastguard Worker */
918*5e7646d2SAndroid Build Coastguard Worker
919*5e7646d2SAndroid Build Coastguard Worker static void * // O - Thread exit status
do_monitor_printer_state(ipptool_test_t * data)920*5e7646d2SAndroid Build Coastguard Worker do_monitor_printer_state(
921*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t *data) // I - Test data
922*5e7646d2SAndroid Build Coastguard Worker {
923*5e7646d2SAndroid Build Coastguard Worker int i, j; // Looping vars
924*5e7646d2SAndroid Build Coastguard Worker char scheme[32], // URI scheme
925*5e7646d2SAndroid Build Coastguard Worker userpass[32], // URI username:password
926*5e7646d2SAndroid Build Coastguard Worker host[256], // URI hostname/IP address
927*5e7646d2SAndroid Build Coastguard Worker resource[256]; // URI resource path
928*5e7646d2SAndroid Build Coastguard Worker int port; // URI port number
929*5e7646d2SAndroid Build Coastguard Worker http_encryption_t encryption; // Encryption to use
930*5e7646d2SAndroid Build Coastguard Worker http_t *http; // Connection to printer
931*5e7646d2SAndroid Build Coastguard Worker ipp_t *request, // IPP request
932*5e7646d2SAndroid Build Coastguard Worker *response = NULL; // IPP response
933*5e7646d2SAndroid Build Coastguard Worker http_status_t status; // Request status
934*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *found; // Found attribute
935*5e7646d2SAndroid Build Coastguard Worker ipptool_expect_t *expect; // Current EXPECT test
936*5e7646d2SAndroid Build Coastguard Worker char buffer[131072]; // Copy buffer
937*5e7646d2SAndroid Build Coastguard Worker int num_pattrs; // Number of printer attributes
938*5e7646d2SAndroid Build Coastguard Worker const char *pattrs[100]; // Printer attributes we care about
939*5e7646d2SAndroid Build Coastguard Worker
940*5e7646d2SAndroid Build Coastguard Worker
941*5e7646d2SAndroid Build Coastguard Worker // Connect to the printer...
942*5e7646d2SAndroid Build Coastguard Worker if (httpSeparateURI(HTTP_URI_CODING_ALL, data->monitor_uri, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
943*5e7646d2SAndroid Build Coastguard Worker {
944*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad printer URI \"%s\".", data->monitor_uri);
945*5e7646d2SAndroid Build Coastguard Worker return (NULL);
946*5e7646d2SAndroid Build Coastguard Worker }
947*5e7646d2SAndroid Build Coastguard Worker
948*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(scheme, "https") || !_cups_strcasecmp(scheme, "ipps") || port == 443)
949*5e7646d2SAndroid Build Coastguard Worker encryption = HTTP_ENCRYPTION_ALWAYS;
950*5e7646d2SAndroid Build Coastguard Worker else
951*5e7646d2SAndroid Build Coastguard Worker encryption = data->encryption;
952*5e7646d2SAndroid Build Coastguard Worker
953*5e7646d2SAndroid Build Coastguard Worker if ((http = httpConnect2(host, port, NULL, data->family, encryption, 1, 30000, NULL)) == NULL)
954*5e7646d2SAndroid Build Coastguard Worker {
955*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Unable to connect to \"%s\" on port %d - %s", host, port, cupsLastErrorString());
956*5e7646d2SAndroid Build Coastguard Worker return (0);
957*5e7646d2SAndroid Build Coastguard Worker }
958*5e7646d2SAndroid Build Coastguard Worker
959*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
960*5e7646d2SAndroid Build Coastguard Worker httpSetDefaultField(http, HTTP_FIELD_ACCEPT_ENCODING, "deflate, gzip, identity");
961*5e7646d2SAndroid Build Coastguard Worker #else
962*5e7646d2SAndroid Build Coastguard Worker httpSetDefaultField(http, HTTP_FIELD_ACCEPT_ENCODING, "identity");
963*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
964*5e7646d2SAndroid Build Coastguard Worker
965*5e7646d2SAndroid Build Coastguard Worker if (data->timeout > 0.0)
966*5e7646d2SAndroid Build Coastguard Worker httpSetTimeout(http, data->timeout, timeout_cb, NULL);
967*5e7646d2SAndroid Build Coastguard Worker
968*5e7646d2SAndroid Build Coastguard Worker // Wait for the initial delay as needed...
969*5e7646d2SAndroid Build Coastguard Worker if (data->monitor_delay)
970*5e7646d2SAndroid Build Coastguard Worker usleep(data->monitor_delay);
971*5e7646d2SAndroid Build Coastguard Worker
972*5e7646d2SAndroid Build Coastguard Worker // Create a query request that we'll reuse...
973*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
974*5e7646d2SAndroid Build Coastguard Worker ippSetRequestId(request, data->request_id * 100 - 1);
975*5e7646d2SAndroid Build Coastguard Worker ippSetVersion(request, data->version / 10, data->version % 10);
976*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, data->monitor_uri);
977*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser());
978*5e7646d2SAndroid Build Coastguard Worker
979*5e7646d2SAndroid Build Coastguard Worker for (i = data->num_monitor_expects, expect = data->monitor_expects, num_pattrs = 0; i > 0; i --, expect ++)
980*5e7646d2SAndroid Build Coastguard Worker {
981*5e7646d2SAndroid Build Coastguard Worker // Add EXPECT attribute names...
982*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < num_pattrs; j ++)
983*5e7646d2SAndroid Build Coastguard Worker {
984*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(expect->name, pattrs[j]))
985*5e7646d2SAndroid Build Coastguard Worker break;
986*5e7646d2SAndroid Build Coastguard Worker }
987*5e7646d2SAndroid Build Coastguard Worker
988*5e7646d2SAndroid Build Coastguard Worker if (j >= num_pattrs && num_pattrs < (int)(sizeof(pattrs) / sizeof(pattrs[0])))
989*5e7646d2SAndroid Build Coastguard Worker pattrs[num_pattrs ++] = expect->name;
990*5e7646d2SAndroid Build Coastguard Worker }
991*5e7646d2SAndroid Build Coastguard Worker
992*5e7646d2SAndroid Build Coastguard Worker if (num_pattrs > 0)
993*5e7646d2SAndroid Build Coastguard Worker ippAddStrings(request, IPP_TAG_OPERATION, IPP_CONST_TAG(IPP_TAG_KEYWORD), "requested-attributes", num_pattrs, NULL, pattrs);
994*5e7646d2SAndroid Build Coastguard Worker
995*5e7646d2SAndroid Build Coastguard Worker // Loop until we need to stop...
996*5e7646d2SAndroid Build Coastguard Worker while (!data->monitor_done && !Cancel)
997*5e7646d2SAndroid Build Coastguard Worker {
998*5e7646d2SAndroid Build Coastguard Worker // Poll the printer state...
999*5e7646d2SAndroid Build Coastguard Worker ippSetRequestId(request, ippGetRequestId(request) + 1);
1000*5e7646d2SAndroid Build Coastguard Worker
1001*5e7646d2SAndroid Build Coastguard Worker if ((status = cupsSendRequest(http, request, resource, ippLength(request))) != HTTP_STATUS_ERROR)
1002*5e7646d2SAndroid Build Coastguard Worker {
1003*5e7646d2SAndroid Build Coastguard Worker response = cupsGetResponse(http, resource);
1004*5e7646d2SAndroid Build Coastguard Worker status = httpGetStatus(http);
1005*5e7646d2SAndroid Build Coastguard Worker }
1006*5e7646d2SAndroid Build Coastguard Worker
1007*5e7646d2SAndroid Build Coastguard Worker if (!data->monitor_done && !Cancel && status == HTTP_STATUS_ERROR && httpError(data->http) != EINVAL &&
1008*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
1009*5e7646d2SAndroid Build Coastguard Worker httpError(data->http) != WSAETIMEDOUT)
1010*5e7646d2SAndroid Build Coastguard Worker #else
1011*5e7646d2SAndroid Build Coastguard Worker httpError(data->http) != ETIMEDOUT)
1012*5e7646d2SAndroid Build Coastguard Worker #endif // _WIN32
1013*5e7646d2SAndroid Build Coastguard Worker {
1014*5e7646d2SAndroid Build Coastguard Worker if (httpReconnect2(http, 30000, NULL))
1015*5e7646d2SAndroid Build Coastguard Worker break;
1016*5e7646d2SAndroid Build Coastguard Worker }
1017*5e7646d2SAndroid Build Coastguard Worker else if (status == HTTP_STATUS_ERROR || status == HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED)
1018*5e7646d2SAndroid Build Coastguard Worker {
1019*5e7646d2SAndroid Build Coastguard Worker break;
1020*5e7646d2SAndroid Build Coastguard Worker }
1021*5e7646d2SAndroid Build Coastguard Worker else if (status != HTTP_STATUS_OK)
1022*5e7646d2SAndroid Build Coastguard Worker {
1023*5e7646d2SAndroid Build Coastguard Worker httpFlush(http);
1024*5e7646d2SAndroid Build Coastguard Worker
1025*5e7646d2SAndroid Build Coastguard Worker if (status == HTTP_STATUS_UNAUTHORIZED)
1026*5e7646d2SAndroid Build Coastguard Worker continue;
1027*5e7646d2SAndroid Build Coastguard Worker
1028*5e7646d2SAndroid Build Coastguard Worker break;
1029*5e7646d2SAndroid Build Coastguard Worker }
1030*5e7646d2SAndroid Build Coastguard Worker
1031*5e7646d2SAndroid Build Coastguard Worker for (i = data->num_monitor_expects, expect = data->monitor_expects; i > 0; i --, expect ++)
1032*5e7646d2SAndroid Build Coastguard Worker {
1033*5e7646d2SAndroid Build Coastguard Worker if (expect->if_defined && !_ippVarsGet(data->vars, expect->if_defined))
1034*5e7646d2SAndroid Build Coastguard Worker continue;
1035*5e7646d2SAndroid Build Coastguard Worker
1036*5e7646d2SAndroid Build Coastguard Worker if (expect->if_not_defined && _ippVarsGet(data->vars, expect->if_not_defined))
1037*5e7646d2SAndroid Build Coastguard Worker continue;
1038*5e7646d2SAndroid Build Coastguard Worker
1039*5e7646d2SAndroid Build Coastguard Worker found = ippFindAttribute(response, expect->name, IPP_TAG_ZERO);
1040*5e7646d2SAndroid Build Coastguard Worker
1041*5e7646d2SAndroid Build Coastguard Worker if ((found && expect->not_expect) ||
1042*5e7646d2SAndroid Build Coastguard Worker (!found && !(expect->not_expect || expect->optional)) ||
1043*5e7646d2SAndroid Build Coastguard Worker (found && !expect_matches(expect, found)) ||
1044*5e7646d2SAndroid Build Coastguard Worker (expect->in_group && ippGetGroupTag(found) != expect->in_group) ||
1045*5e7646d2SAndroid Build Coastguard Worker (expect->with_distinct && !with_distinct_values(NULL, found)))
1046*5e7646d2SAndroid Build Coastguard Worker {
1047*5e7646d2SAndroid Build Coastguard Worker if (expect->define_no_match)
1048*5e7646d2SAndroid Build Coastguard Worker {
1049*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, expect->define_no_match, "1");
1050*5e7646d2SAndroid Build Coastguard Worker data->monitor_done = 1;
1051*5e7646d2SAndroid Build Coastguard Worker }
1052*5e7646d2SAndroid Build Coastguard Worker break;
1053*5e7646d2SAndroid Build Coastguard Worker }
1054*5e7646d2SAndroid Build Coastguard Worker
1055*5e7646d2SAndroid Build Coastguard Worker if (found)
1056*5e7646d2SAndroid Build Coastguard Worker ippAttributeString(found, buffer, sizeof(buffer));
1057*5e7646d2SAndroid Build Coastguard Worker
1058*5e7646d2SAndroid Build Coastguard Worker if (found && !with_value(data, NULL, expect->with_value, expect->with_flags, found, buffer, sizeof(buffer)))
1059*5e7646d2SAndroid Build Coastguard Worker {
1060*5e7646d2SAndroid Build Coastguard Worker if (expect->define_no_match)
1061*5e7646d2SAndroid Build Coastguard Worker {
1062*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, expect->define_no_match, "1");
1063*5e7646d2SAndroid Build Coastguard Worker data->monitor_done = 1;
1064*5e7646d2SAndroid Build Coastguard Worker }
1065*5e7646d2SAndroid Build Coastguard Worker break;
1066*5e7646d2SAndroid Build Coastguard Worker }
1067*5e7646d2SAndroid Build Coastguard Worker
1068*5e7646d2SAndroid Build Coastguard Worker if (found && expect->count > 0 && ippGetCount(found) != expect->count)
1069*5e7646d2SAndroid Build Coastguard Worker {
1070*5e7646d2SAndroid Build Coastguard Worker if (expect->define_no_match)
1071*5e7646d2SAndroid Build Coastguard Worker {
1072*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, expect->define_no_match, "1");
1073*5e7646d2SAndroid Build Coastguard Worker data->monitor_done = 1;
1074*5e7646d2SAndroid Build Coastguard Worker }
1075*5e7646d2SAndroid Build Coastguard Worker break;
1076*5e7646d2SAndroid Build Coastguard Worker }
1077*5e7646d2SAndroid Build Coastguard Worker
1078*5e7646d2SAndroid Build Coastguard Worker if (found && expect->display_match && (data->output == IPPTOOL_OUTPUT_TEST || (data->output == IPPTOOL_OUTPUT_PLIST && data->outfile != cupsFileStdout())))
1079*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(cupsFileStdout(), "CONT]\n\n%s\n\n %-68.68s [", expect->display_match, data->name);
1080*5e7646d2SAndroid Build Coastguard Worker
1081*5e7646d2SAndroid Build Coastguard Worker if (found && expect->define_match)
1082*5e7646d2SAndroid Build Coastguard Worker {
1083*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, expect->define_match, "1");
1084*5e7646d2SAndroid Build Coastguard Worker data->monitor_done = 1;
1085*5e7646d2SAndroid Build Coastguard Worker }
1086*5e7646d2SAndroid Build Coastguard Worker
1087*5e7646d2SAndroid Build Coastguard Worker if (found && expect->define_value)
1088*5e7646d2SAndroid Build Coastguard Worker {
1089*5e7646d2SAndroid Build Coastguard Worker if (!expect->with_value)
1090*5e7646d2SAndroid Build Coastguard Worker {
1091*5e7646d2SAndroid Build Coastguard Worker int last = ippGetCount(found) - 1;
1092*5e7646d2SAndroid Build Coastguard Worker // Last element in attribute
1093*5e7646d2SAndroid Build Coastguard Worker
1094*5e7646d2SAndroid Build Coastguard Worker switch (ippGetValueTag(found))
1095*5e7646d2SAndroid Build Coastguard Worker {
1096*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
1097*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
1098*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "%d", ippGetInteger(found, last));
1099*5e7646d2SAndroid Build Coastguard Worker break;
1100*5e7646d2SAndroid Build Coastguard Worker
1101*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BOOLEAN :
1102*5e7646d2SAndroid Build Coastguard Worker if (ippGetBoolean(found, last))
1103*5e7646d2SAndroid Build Coastguard Worker strlcpy(buffer, "true", sizeof(buffer));
1104*5e7646d2SAndroid Build Coastguard Worker else
1105*5e7646d2SAndroid Build Coastguard Worker strlcpy(buffer, "false", sizeof(buffer));
1106*5e7646d2SAndroid Build Coastguard Worker break;
1107*5e7646d2SAndroid Build Coastguard Worker
1108*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
1109*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
1110*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
1111*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
1112*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
1113*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
1114*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
1115*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
1116*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
1117*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
1118*5e7646d2SAndroid Build Coastguard Worker strlcpy(buffer, ippGetString(found, last, NULL), sizeof(buffer));
1119*5e7646d2SAndroid Build Coastguard Worker break;
1120*5e7646d2SAndroid Build Coastguard Worker
1121*5e7646d2SAndroid Build Coastguard Worker default :
1122*5e7646d2SAndroid Build Coastguard Worker ippAttributeString(found, buffer, sizeof(buffer));
1123*5e7646d2SAndroid Build Coastguard Worker break;
1124*5e7646d2SAndroid Build Coastguard Worker }
1125*5e7646d2SAndroid Build Coastguard Worker }
1126*5e7646d2SAndroid Build Coastguard Worker
1127*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, expect->define_value, buffer);
1128*5e7646d2SAndroid Build Coastguard Worker data->monitor_done = 1;
1129*5e7646d2SAndroid Build Coastguard Worker }
1130*5e7646d2SAndroid Build Coastguard Worker }
1131*5e7646d2SAndroid Build Coastguard Worker
1132*5e7646d2SAndroid Build Coastguard Worker if (i == 0)
1133*5e7646d2SAndroid Build Coastguard Worker data->monitor_done = 1; // All tests passed
1134*5e7646d2SAndroid Build Coastguard Worker
1135*5e7646d2SAndroid Build Coastguard Worker ippDelete(response);
1136*5e7646d2SAndroid Build Coastguard Worker response = NULL;
1137*5e7646d2SAndroid Build Coastguard Worker
1138*5e7646d2SAndroid Build Coastguard Worker // Sleep between requests...
1139*5e7646d2SAndroid Build Coastguard Worker if (data->monitor_done || Cancel)
1140*5e7646d2SAndroid Build Coastguard Worker break;
1141*5e7646d2SAndroid Build Coastguard Worker
1142*5e7646d2SAndroid Build Coastguard Worker usleep(data->monitor_interval);
1143*5e7646d2SAndroid Build Coastguard Worker }
1144*5e7646d2SAndroid Build Coastguard Worker
1145*5e7646d2SAndroid Build Coastguard Worker // Close the connection to the printer and return...
1146*5e7646d2SAndroid Build Coastguard Worker httpClose(http);
1147*5e7646d2SAndroid Build Coastguard Worker ippDelete(request);
1148*5e7646d2SAndroid Build Coastguard Worker ippDelete(response);
1149*5e7646d2SAndroid Build Coastguard Worker
1150*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1151*5e7646d2SAndroid Build Coastguard Worker }
1152*5e7646d2SAndroid Build Coastguard Worker
1153*5e7646d2SAndroid Build Coastguard Worker
1154*5e7646d2SAndroid Build Coastguard Worker /*
1155*5e7646d2SAndroid Build Coastguard Worker * 'do_test()' - Do a single test from the test file.
1156*5e7646d2SAndroid Build Coastguard Worker */
1157*5e7646d2SAndroid Build Coastguard Worker
1158*5e7646d2SAndroid Build Coastguard Worker static int /* O - 1 on success, 0 on failure */
do_test(_ipp_file_t * f,ipptool_test_t * data)1159*5e7646d2SAndroid Build Coastguard Worker do_test(_ipp_file_t *f, /* I - IPP data file */
1160*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t *data) /* I - Test data */
1161*5e7646d2SAndroid Build Coastguard Worker
1162*5e7646d2SAndroid Build Coastguard Worker {
1163*5e7646d2SAndroid Build Coastguard Worker int i, /* Looping var */
1164*5e7646d2SAndroid Build Coastguard Worker status_ok, /* Did we get a matching status? */
1165*5e7646d2SAndroid Build Coastguard Worker repeat_count = 0, /* Repeat count */
1166*5e7646d2SAndroid Build Coastguard Worker repeat_test; /* Repeat the test? */
1167*5e7646d2SAndroid Build Coastguard Worker ipptool_expect_t *expect; /* Current expected attribute */
1168*5e7646d2SAndroid Build Coastguard Worker ipp_t *request, /* IPP request */
1169*5e7646d2SAndroid Build Coastguard Worker *response; /* IPP response */
1170*5e7646d2SAndroid Build Coastguard Worker size_t length; /* Length of IPP request */
1171*5e7646d2SAndroid Build Coastguard Worker http_status_t status; /* HTTP status */
1172*5e7646d2SAndroid Build Coastguard Worker cups_array_t *a; /* Duplicate attribute array */
1173*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group; /* Current group */
1174*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attrptr, /* Attribute pointer */
1175*5e7646d2SAndroid Build Coastguard Worker *found; /* Found attribute */
1176*5e7646d2SAndroid Build Coastguard Worker char temp[1024]; /* Temporary string */
1177*5e7646d2SAndroid Build Coastguard Worker cups_file_t *reqfile; /* File to send */
1178*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes; /* Bytes read/written */
1179*5e7646d2SAndroid Build Coastguard Worker char buffer[131072]; /* Copy buffer */
1180*5e7646d2SAndroid Build Coastguard Worker size_t widths[200]; /* Width of columns */
1181*5e7646d2SAndroid Build Coastguard Worker const char *error; /* Current error */
1182*5e7646d2SAndroid Build Coastguard Worker
1183*5e7646d2SAndroid Build Coastguard Worker
1184*5e7646d2SAndroid Build Coastguard Worker if (Cancel)
1185*5e7646d2SAndroid Build Coastguard Worker return (0);
1186*5e7646d2SAndroid Build Coastguard Worker
1187*5e7646d2SAndroid Build Coastguard Worker /*
1188*5e7646d2SAndroid Build Coastguard Worker * Show any PAUSE message, as needed...
1189*5e7646d2SAndroid Build Coastguard Worker */
1190*5e7646d2SAndroid Build Coastguard Worker
1191*5e7646d2SAndroid Build Coastguard Worker if (data->pause[0])
1192*5e7646d2SAndroid Build Coastguard Worker {
1193*5e7646d2SAndroid Build Coastguard Worker if (!data->skip_test && !data->pass_test)
1194*5e7646d2SAndroid Build Coastguard Worker pause_message(data->pause);
1195*5e7646d2SAndroid Build Coastguard Worker
1196*5e7646d2SAndroid Build Coastguard Worker data->pause[0] = '\0';
1197*5e7646d2SAndroid Build Coastguard Worker }
1198*5e7646d2SAndroid Build Coastguard Worker
1199*5e7646d2SAndroid Build Coastguard Worker /*
1200*5e7646d2SAndroid Build Coastguard Worker * Start the background thread as needed...
1201*5e7646d2SAndroid Build Coastguard Worker */
1202*5e7646d2SAndroid Build Coastguard Worker
1203*5e7646d2SAndroid Build Coastguard Worker if (data->monitor_uri)
1204*5e7646d2SAndroid Build Coastguard Worker {
1205*5e7646d2SAndroid Build Coastguard Worker data->monitor_done = 0;
1206*5e7646d2SAndroid Build Coastguard Worker data->monitor_thread = _cupsThreadCreate((_cups_thread_func_t)do_monitor_printer_state, data);
1207*5e7646d2SAndroid Build Coastguard Worker }
1208*5e7646d2SAndroid Build Coastguard Worker
1209*5e7646d2SAndroid Build Coastguard Worker /*
1210*5e7646d2SAndroid Build Coastguard Worker * Take over control of the attributes in the request...
1211*5e7646d2SAndroid Build Coastguard Worker */
1212*5e7646d2SAndroid Build Coastguard Worker
1213*5e7646d2SAndroid Build Coastguard Worker request = f->attrs;
1214*5e7646d2SAndroid Build Coastguard Worker f->attrs = NULL;
1215*5e7646d2SAndroid Build Coastguard Worker
1216*5e7646d2SAndroid Build Coastguard Worker /*
1217*5e7646d2SAndroid Build Coastguard Worker * Submit the IPP request...
1218*5e7646d2SAndroid Build Coastguard Worker */
1219*5e7646d2SAndroid Build Coastguard Worker
1220*5e7646d2SAndroid Build Coastguard Worker data->test_count ++;
1221*5e7646d2SAndroid Build Coastguard Worker
1222*5e7646d2SAndroid Build Coastguard Worker ippSetVersion(request, data->version / 10, data->version % 10);
1223*5e7646d2SAndroid Build Coastguard Worker ippSetRequestId(request, data->request_id);
1224*5e7646d2SAndroid Build Coastguard Worker
1225*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_PLIST)
1226*5e7646d2SAndroid Build Coastguard Worker {
1227*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<dict>\n");
1228*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>Name</key>\n");
1229*5e7646d2SAndroid Build Coastguard Worker print_xml_string(data->outfile, "string", data->name);
1230*5e7646d2SAndroid Build Coastguard Worker if (data->file_id[0])
1231*5e7646d2SAndroid Build Coastguard Worker {
1232*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>FileId</key>\n");
1233*5e7646d2SAndroid Build Coastguard Worker print_xml_string(data->outfile, "string", data->file_id);
1234*5e7646d2SAndroid Build Coastguard Worker }
1235*5e7646d2SAndroid Build Coastguard Worker if (data->test_id[0])
1236*5e7646d2SAndroid Build Coastguard Worker {
1237*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>TestId</key>\n");
1238*5e7646d2SAndroid Build Coastguard Worker print_xml_string(data->outfile, "string", data->test_id);
1239*5e7646d2SAndroid Build Coastguard Worker }
1240*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>Version</key>\n");
1241*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(data->outfile, "<string>%d.%d</string>\n", data->version / 10, data->version % 10);
1242*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>Operation</key>\n");
1243*5e7646d2SAndroid Build Coastguard Worker print_xml_string(data->outfile, "string", ippOpString(ippGetOperation(request)));
1244*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>RequestId</key>\n");
1245*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(data->outfile, "<integer>%d</integer>\n", data->request_id);
1246*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>RequestAttributes</key>\n");
1247*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<array>\n");
1248*5e7646d2SAndroid Build Coastguard Worker if (ippFirstAttribute(request))
1249*5e7646d2SAndroid Build Coastguard Worker {
1250*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<dict>\n");
1251*5e7646d2SAndroid Build Coastguard Worker for (attrptr = ippFirstAttribute(request), group = ippGetGroupTag(attrptr); attrptr; attrptr = ippNextAttribute(request))
1252*5e7646d2SAndroid Build Coastguard Worker print_attr(data->outfile, data->output, attrptr, &group);
1253*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "</dict>\n");
1254*5e7646d2SAndroid Build Coastguard Worker }
1255*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "</array>\n");
1256*5e7646d2SAndroid Build Coastguard Worker }
1257*5e7646d2SAndroid Build Coastguard Worker
1258*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_TEST || (data->output == IPPTOOL_OUTPUT_PLIST && data->outfile != cupsFileStdout()))
1259*5e7646d2SAndroid Build Coastguard Worker {
1260*5e7646d2SAndroid Build Coastguard Worker if (data->verbosity)
1261*5e7646d2SAndroid Build Coastguard Worker {
1262*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(cupsFileStdout(), " %s:\n", ippOpString(ippGetOperation(request)));
1263*5e7646d2SAndroid Build Coastguard Worker
1264*5e7646d2SAndroid Build Coastguard Worker for (attrptr = ippFirstAttribute(request); attrptr; attrptr = ippNextAttribute(request))
1265*5e7646d2SAndroid Build Coastguard Worker print_attr(cupsFileStdout(), IPPTOOL_OUTPUT_TEST, attrptr, NULL);
1266*5e7646d2SAndroid Build Coastguard Worker }
1267*5e7646d2SAndroid Build Coastguard Worker
1268*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(cupsFileStdout(), " %-68.68s [", data->name);
1269*5e7646d2SAndroid Build Coastguard Worker }
1270*5e7646d2SAndroid Build Coastguard Worker
1271*5e7646d2SAndroid Build Coastguard Worker if ((data->skip_previous && !data->prev_pass) || data->skip_test || data->pass_test)
1272*5e7646d2SAndroid Build Coastguard Worker {
1273*5e7646d2SAndroid Build Coastguard Worker if (!data->pass_test)
1274*5e7646d2SAndroid Build Coastguard Worker data->skip_count ++;
1275*5e7646d2SAndroid Build Coastguard Worker
1276*5e7646d2SAndroid Build Coastguard Worker ippDelete(request);
1277*5e7646d2SAndroid Build Coastguard Worker request = NULL;
1278*5e7646d2SAndroid Build Coastguard Worker response = NULL;
1279*5e7646d2SAndroid Build Coastguard Worker
1280*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_PLIST)
1281*5e7646d2SAndroid Build Coastguard Worker {
1282*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>Successful</key>\n");
1283*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<true />\n");
1284*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>Skipped</key>\n");
1285*5e7646d2SAndroid Build Coastguard Worker if (data->pass_test)
1286*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<false />\n");
1287*5e7646d2SAndroid Build Coastguard Worker else
1288*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<true />\n");
1289*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>StatusCode</key>\n");
1290*5e7646d2SAndroid Build Coastguard Worker if (data->pass_test)
1291*5e7646d2SAndroid Build Coastguard Worker print_xml_string(data->outfile, "string", "pass");
1292*5e7646d2SAndroid Build Coastguard Worker else
1293*5e7646d2SAndroid Build Coastguard Worker print_xml_string(data->outfile, "string", "skip");
1294*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>ResponseAttributes</key>\n");
1295*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<dict />\n");
1296*5e7646d2SAndroid Build Coastguard Worker }
1297*5e7646d2SAndroid Build Coastguard Worker
1298*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_TEST || (data->output == IPPTOOL_OUTPUT_PLIST && data->outfile != cupsFileStdout()))
1299*5e7646d2SAndroid Build Coastguard Worker {
1300*5e7646d2SAndroid Build Coastguard Worker if (data->pass_test)
1301*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(cupsFileStdout(), "PASS]\n");
1302*5e7646d2SAndroid Build Coastguard Worker else
1303*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(cupsFileStdout(), "SKIP]\n");
1304*5e7646d2SAndroid Build Coastguard Worker }
1305*5e7646d2SAndroid Build Coastguard Worker
1306*5e7646d2SAndroid Build Coastguard Worker goto skip_error;
1307*5e7646d2SAndroid Build Coastguard Worker }
1308*5e7646d2SAndroid Build Coastguard Worker
1309*5e7646d2SAndroid Build Coastguard Worker data->vars->password_tries = 0;
1310*5e7646d2SAndroid Build Coastguard Worker
1311*5e7646d2SAndroid Build Coastguard Worker do
1312*5e7646d2SAndroid Build Coastguard Worker {
1313*5e7646d2SAndroid Build Coastguard Worker if (data->delay > 0)
1314*5e7646d2SAndroid Build Coastguard Worker usleep(data->delay);
1315*5e7646d2SAndroid Build Coastguard Worker
1316*5e7646d2SAndroid Build Coastguard Worker data->delay = data->repeat_interval;
1317*5e7646d2SAndroid Build Coastguard Worker repeat_count ++;
1318*5e7646d2SAndroid Build Coastguard Worker
1319*5e7646d2SAndroid Build Coastguard Worker status = HTTP_STATUS_OK;
1320*5e7646d2SAndroid Build Coastguard Worker
1321*5e7646d2SAndroid Build Coastguard Worker if (data->transfer == IPPTOOL_TRANSFER_CHUNKED || (data->transfer == IPPTOOL_TRANSFER_AUTO && data->file[0]))
1322*5e7646d2SAndroid Build Coastguard Worker {
1323*5e7646d2SAndroid Build Coastguard Worker /*
1324*5e7646d2SAndroid Build Coastguard Worker * Send request using chunking - a 0 length means "chunk".
1325*5e7646d2SAndroid Build Coastguard Worker */
1326*5e7646d2SAndroid Build Coastguard Worker
1327*5e7646d2SAndroid Build Coastguard Worker length = 0;
1328*5e7646d2SAndroid Build Coastguard Worker }
1329*5e7646d2SAndroid Build Coastguard Worker else
1330*5e7646d2SAndroid Build Coastguard Worker {
1331*5e7646d2SAndroid Build Coastguard Worker /*
1332*5e7646d2SAndroid Build Coastguard Worker * Send request using content length...
1333*5e7646d2SAndroid Build Coastguard Worker */
1334*5e7646d2SAndroid Build Coastguard Worker
1335*5e7646d2SAndroid Build Coastguard Worker length = ippLength(request);
1336*5e7646d2SAndroid Build Coastguard Worker
1337*5e7646d2SAndroid Build Coastguard Worker if (data->file[0] && (reqfile = cupsFileOpen(data->file, "r")) != NULL)
1338*5e7646d2SAndroid Build Coastguard Worker {
1339*5e7646d2SAndroid Build Coastguard Worker /*
1340*5e7646d2SAndroid Build Coastguard Worker * Read the file to get the uncompressed file size...
1341*5e7646d2SAndroid Build Coastguard Worker */
1342*5e7646d2SAndroid Build Coastguard Worker
1343*5e7646d2SAndroid Build Coastguard Worker while ((bytes = cupsFileRead(reqfile, buffer, sizeof(buffer))) > 0)
1344*5e7646d2SAndroid Build Coastguard Worker length += (size_t)bytes;
1345*5e7646d2SAndroid Build Coastguard Worker
1346*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(reqfile);
1347*5e7646d2SAndroid Build Coastguard Worker }
1348*5e7646d2SAndroid Build Coastguard Worker }
1349*5e7646d2SAndroid Build Coastguard Worker
1350*5e7646d2SAndroid Build Coastguard Worker /*
1351*5e7646d2SAndroid Build Coastguard Worker * Send the request...
1352*5e7646d2SAndroid Build Coastguard Worker */
1353*5e7646d2SAndroid Build Coastguard Worker
1354*5e7646d2SAndroid Build Coastguard Worker data->prev_pass = 1;
1355*5e7646d2SAndroid Build Coastguard Worker repeat_test = 0;
1356*5e7646d2SAndroid Build Coastguard Worker response = NULL;
1357*5e7646d2SAndroid Build Coastguard Worker
1358*5e7646d2SAndroid Build Coastguard Worker if (status != HTTP_STATUS_ERROR)
1359*5e7646d2SAndroid Build Coastguard Worker {
1360*5e7646d2SAndroid Build Coastguard Worker while (!response && !Cancel && data->prev_pass)
1361*5e7646d2SAndroid Build Coastguard Worker {
1362*5e7646d2SAndroid Build Coastguard Worker ippSetRequestId(request, ++ data->request_id);
1363*5e7646d2SAndroid Build Coastguard Worker
1364*5e7646d2SAndroid Build Coastguard Worker status = cupsSendRequest(data->http, request, data->resource, length);
1365*5e7646d2SAndroid Build Coastguard Worker
1366*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
1367*5e7646d2SAndroid Build Coastguard Worker if (data->compression[0])
1368*5e7646d2SAndroid Build Coastguard Worker httpSetField(data->http, HTTP_FIELD_CONTENT_ENCODING, data->compression);
1369*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
1370*5e7646d2SAndroid Build Coastguard Worker
1371*5e7646d2SAndroid Build Coastguard Worker if (!Cancel && status == HTTP_STATUS_CONTINUE && ippGetState(request) == IPP_DATA && data->file[0])
1372*5e7646d2SAndroid Build Coastguard Worker {
1373*5e7646d2SAndroid Build Coastguard Worker if ((reqfile = cupsFileOpen(data->file, "r")) != NULL)
1374*5e7646d2SAndroid Build Coastguard Worker {
1375*5e7646d2SAndroid Build Coastguard Worker while (!Cancel && (bytes = cupsFileRead(reqfile, buffer, sizeof(buffer))) > 0)
1376*5e7646d2SAndroid Build Coastguard Worker {
1377*5e7646d2SAndroid Build Coastguard Worker if ((status = cupsWriteRequestData(data->http, buffer, (size_t)bytes)) != HTTP_STATUS_CONTINUE)
1378*5e7646d2SAndroid Build Coastguard Worker break;
1379*5e7646d2SAndroid Build Coastguard Worker }
1380*5e7646d2SAndroid Build Coastguard Worker
1381*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(reqfile);
1382*5e7646d2SAndroid Build Coastguard Worker }
1383*5e7646d2SAndroid Build Coastguard Worker else
1384*5e7646d2SAndroid Build Coastguard Worker {
1385*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "%s: %s", data->file, strerror(errno));
1386*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_INTERNAL_ERROR, buffer, 0);
1387*5e7646d2SAndroid Build Coastguard Worker
1388*5e7646d2SAndroid Build Coastguard Worker status = HTTP_STATUS_ERROR;
1389*5e7646d2SAndroid Build Coastguard Worker }
1390*5e7646d2SAndroid Build Coastguard Worker }
1391*5e7646d2SAndroid Build Coastguard Worker
1392*5e7646d2SAndroid Build Coastguard Worker /*
1393*5e7646d2SAndroid Build Coastguard Worker * Get the server's response...
1394*5e7646d2SAndroid Build Coastguard Worker */
1395*5e7646d2SAndroid Build Coastguard Worker
1396*5e7646d2SAndroid Build Coastguard Worker if (!Cancel && status != HTTP_STATUS_ERROR)
1397*5e7646d2SAndroid Build Coastguard Worker {
1398*5e7646d2SAndroid Build Coastguard Worker response = cupsGetResponse(data->http, data->resource);
1399*5e7646d2SAndroid Build Coastguard Worker status = httpGetStatus(data->http);
1400*5e7646d2SAndroid Build Coastguard Worker }
1401*5e7646d2SAndroid Build Coastguard Worker
1402*5e7646d2SAndroid Build Coastguard Worker if (!Cancel && status == HTTP_STATUS_ERROR && httpError(data->http) != EINVAL &&
1403*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
1404*5e7646d2SAndroid Build Coastguard Worker httpError(data->http) != WSAETIMEDOUT)
1405*5e7646d2SAndroid Build Coastguard Worker #else
1406*5e7646d2SAndroid Build Coastguard Worker httpError(data->http) != ETIMEDOUT)
1407*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
1408*5e7646d2SAndroid Build Coastguard Worker {
1409*5e7646d2SAndroid Build Coastguard Worker if (httpReconnect2(data->http, 30000, NULL))
1410*5e7646d2SAndroid Build Coastguard Worker data->prev_pass = 0;
1411*5e7646d2SAndroid Build Coastguard Worker }
1412*5e7646d2SAndroid Build Coastguard Worker else if (status == HTTP_STATUS_ERROR || status == HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED)
1413*5e7646d2SAndroid Build Coastguard Worker {
1414*5e7646d2SAndroid Build Coastguard Worker data->prev_pass = 0;
1415*5e7646d2SAndroid Build Coastguard Worker break;
1416*5e7646d2SAndroid Build Coastguard Worker }
1417*5e7646d2SAndroid Build Coastguard Worker else if (status != HTTP_STATUS_OK)
1418*5e7646d2SAndroid Build Coastguard Worker {
1419*5e7646d2SAndroid Build Coastguard Worker httpFlush(data->http);
1420*5e7646d2SAndroid Build Coastguard Worker
1421*5e7646d2SAndroid Build Coastguard Worker if (status == HTTP_STATUS_UNAUTHORIZED)
1422*5e7646d2SAndroid Build Coastguard Worker continue;
1423*5e7646d2SAndroid Build Coastguard Worker
1424*5e7646d2SAndroid Build Coastguard Worker break;
1425*5e7646d2SAndroid Build Coastguard Worker }
1426*5e7646d2SAndroid Build Coastguard Worker }
1427*5e7646d2SAndroid Build Coastguard Worker }
1428*5e7646d2SAndroid Build Coastguard Worker
1429*5e7646d2SAndroid Build Coastguard Worker if (!Cancel && status == HTTP_STATUS_ERROR && httpError(data->http) != EINVAL &&
1430*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
1431*5e7646d2SAndroid Build Coastguard Worker httpError(data->http) != WSAETIMEDOUT)
1432*5e7646d2SAndroid Build Coastguard Worker #else
1433*5e7646d2SAndroid Build Coastguard Worker httpError(data->http) != ETIMEDOUT)
1434*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
1435*5e7646d2SAndroid Build Coastguard Worker {
1436*5e7646d2SAndroid Build Coastguard Worker if (httpReconnect2(data->http, 30000, NULL))
1437*5e7646d2SAndroid Build Coastguard Worker data->prev_pass = 0;
1438*5e7646d2SAndroid Build Coastguard Worker }
1439*5e7646d2SAndroid Build Coastguard Worker else if (status == HTTP_STATUS_ERROR)
1440*5e7646d2SAndroid Build Coastguard Worker {
1441*5e7646d2SAndroid Build Coastguard Worker if (!Cancel)
1442*5e7646d2SAndroid Build Coastguard Worker httpReconnect2(data->http, 30000, NULL);
1443*5e7646d2SAndroid Build Coastguard Worker
1444*5e7646d2SAndroid Build Coastguard Worker data->prev_pass = 0;
1445*5e7646d2SAndroid Build Coastguard Worker }
1446*5e7646d2SAndroid Build Coastguard Worker else if (status != HTTP_STATUS_OK)
1447*5e7646d2SAndroid Build Coastguard Worker {
1448*5e7646d2SAndroid Build Coastguard Worker httpFlush(data->http);
1449*5e7646d2SAndroid Build Coastguard Worker data->prev_pass = 0;
1450*5e7646d2SAndroid Build Coastguard Worker }
1451*5e7646d2SAndroid Build Coastguard Worker
1452*5e7646d2SAndroid Build Coastguard Worker /*
1453*5e7646d2SAndroid Build Coastguard Worker * Check results of request...
1454*5e7646d2SAndroid Build Coastguard Worker */
1455*5e7646d2SAndroid Build Coastguard Worker
1456*5e7646d2SAndroid Build Coastguard Worker cupsArrayClear(data->errors);
1457*5e7646d2SAndroid Build Coastguard Worker
1458*5e7646d2SAndroid Build Coastguard Worker if (httpGetVersion(data->http) != HTTP_1_1)
1459*5e7646d2SAndroid Build Coastguard Worker {
1460*5e7646d2SAndroid Build Coastguard Worker int version = (int)httpGetVersion(data->http);
1461*5e7646d2SAndroid Build Coastguard Worker
1462*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "Bad HTTP version (%d.%d)", version / 100, version % 100);
1463*5e7646d2SAndroid Build Coastguard Worker }
1464*5e7646d2SAndroid Build Coastguard Worker
1465*5e7646d2SAndroid Build Coastguard Worker if (data->validate_headers)
1466*5e7646d2SAndroid Build Coastguard Worker {
1467*5e7646d2SAndroid Build Coastguard Worker const char *header; /* HTTP header value */
1468*5e7646d2SAndroid Build Coastguard Worker
1469*5e7646d2SAndroid Build Coastguard Worker if ((header = httpGetField(data->http, HTTP_FIELD_CONTENT_TYPE)) == NULL || _cups_strcasecmp(header, "application/ipp"))
1470*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "Bad HTTP Content-Type in response (%s)", header && *header ? header : "<missing>");
1471*5e7646d2SAndroid Build Coastguard Worker
1472*5e7646d2SAndroid Build Coastguard Worker if ((header = httpGetField(data->http, HTTP_FIELD_DATE)) != NULL && *header && httpGetDateTime(header) == 0)
1473*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "Bad HTTP Date in response (%s)", header);
1474*5e7646d2SAndroid Build Coastguard Worker }
1475*5e7646d2SAndroid Build Coastguard Worker
1476*5e7646d2SAndroid Build Coastguard Worker if (!response)
1477*5e7646d2SAndroid Build Coastguard Worker {
1478*5e7646d2SAndroid Build Coastguard Worker /*
1479*5e7646d2SAndroid Build Coastguard Worker * No response, log error...
1480*5e7646d2SAndroid Build Coastguard Worker */
1481*5e7646d2SAndroid Build Coastguard Worker
1482*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "IPP request failed with status %s (%s)", ippErrorString(cupsLastError()), cupsLastErrorString());
1483*5e7646d2SAndroid Build Coastguard Worker }
1484*5e7646d2SAndroid Build Coastguard Worker else
1485*5e7646d2SAndroid Build Coastguard Worker {
1486*5e7646d2SAndroid Build Coastguard Worker /*
1487*5e7646d2SAndroid Build Coastguard Worker * Collect common attribute values...
1488*5e7646d2SAndroid Build Coastguard Worker */
1489*5e7646d2SAndroid Build Coastguard Worker
1490*5e7646d2SAndroid Build Coastguard Worker if ((attrptr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL)
1491*5e7646d2SAndroid Build Coastguard Worker {
1492*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), "%d", ippGetInteger(attrptr, 0));
1493*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, "job-id", temp);
1494*5e7646d2SAndroid Build Coastguard Worker }
1495*5e7646d2SAndroid Build Coastguard Worker
1496*5e7646d2SAndroid Build Coastguard Worker if ((attrptr = ippFindAttribute(response, "job-uri", IPP_TAG_URI)) != NULL)
1497*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, "job-uri", ippGetString(attrptr, 0, NULL));
1498*5e7646d2SAndroid Build Coastguard Worker
1499*5e7646d2SAndroid Build Coastguard Worker if ((attrptr = ippFindAttribute(response, "notify-subscription-id", IPP_TAG_INTEGER)) != NULL)
1500*5e7646d2SAndroid Build Coastguard Worker {
1501*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), "%d", ippGetInteger(attrptr, 0));
1502*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, "notify-subscription-id", temp);
1503*5e7646d2SAndroid Build Coastguard Worker }
1504*5e7646d2SAndroid Build Coastguard Worker
1505*5e7646d2SAndroid Build Coastguard Worker /*
1506*5e7646d2SAndroid Build Coastguard Worker * Check response, validating groups and attributes and logging errors
1507*5e7646d2SAndroid Build Coastguard Worker * as needed...
1508*5e7646d2SAndroid Build Coastguard Worker */
1509*5e7646d2SAndroid Build Coastguard Worker
1510*5e7646d2SAndroid Build Coastguard Worker if (ippGetState(response) != IPP_DATA)
1511*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "Missing end-of-attributes-tag in response (RFC 2910 section 3.5.1)");
1512*5e7646d2SAndroid Build Coastguard Worker
1513*5e7646d2SAndroid Build Coastguard Worker if (data->version)
1514*5e7646d2SAndroid Build Coastguard Worker {
1515*5e7646d2SAndroid Build Coastguard Worker int major, minor; /* IPP version */
1516*5e7646d2SAndroid Build Coastguard Worker
1517*5e7646d2SAndroid Build Coastguard Worker major = ippGetVersion(response, &minor);
1518*5e7646d2SAndroid Build Coastguard Worker
1519*5e7646d2SAndroid Build Coastguard Worker if (major != (data->version / 10) || minor != (data->version % 10))
1520*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "Bad version %d.%d in response - expected %d.%d (RFC 8011 section 4.1.8).", major, minor, data->version / 10, data->version % 10);
1521*5e7646d2SAndroid Build Coastguard Worker }
1522*5e7646d2SAndroid Build Coastguard Worker
1523*5e7646d2SAndroid Build Coastguard Worker if (ippGetRequestId(response) != data->request_id)
1524*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "Bad request ID %d in response - expected %d (RFC 8011 section 4.1.1)", ippGetRequestId(response), data->request_id);
1525*5e7646d2SAndroid Build Coastguard Worker
1526*5e7646d2SAndroid Build Coastguard Worker attrptr = ippFirstAttribute(response);
1527*5e7646d2SAndroid Build Coastguard Worker if (!attrptr)
1528*5e7646d2SAndroid Build Coastguard Worker {
1529*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "Missing first attribute \"attributes-charset (charset)\" in group operation-attributes-tag (RFC 8011 section 4.1.4).");
1530*5e7646d2SAndroid Build Coastguard Worker }
1531*5e7646d2SAndroid Build Coastguard Worker else
1532*5e7646d2SAndroid Build Coastguard Worker {
1533*5e7646d2SAndroid Build Coastguard Worker if (!ippGetName(attrptr) || ippGetValueTag(attrptr) != IPP_TAG_CHARSET || ippGetGroupTag(attrptr) != IPP_TAG_OPERATION || ippGetCount(attrptr) != 1 ||strcmp(ippGetName(attrptr), "attributes-charset"))
1534*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "Bad first attribute \"%s (%s%s)\" in group %s, expected \"attributes-charset (charset)\" in group operation-attributes-tag (RFC 8011 section 4.1.4).", ippGetName(attrptr) ? ippGetName(attrptr) : "(null)", ippGetCount(attrptr) > 1 ? "1setOf " : "", ippTagString(ippGetValueTag(attrptr)), ippTagString(ippGetGroupTag(attrptr)));
1535*5e7646d2SAndroid Build Coastguard Worker
1536*5e7646d2SAndroid Build Coastguard Worker attrptr = ippNextAttribute(response);
1537*5e7646d2SAndroid Build Coastguard Worker if (!attrptr)
1538*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "Missing second attribute \"attributes-natural-language (naturalLanguage)\" in group operation-attributes-tag (RFC 8011 section 4.1.4).");
1539*5e7646d2SAndroid Build Coastguard Worker else if (!ippGetName(attrptr) || ippGetValueTag(attrptr) != IPP_TAG_LANGUAGE || ippGetGroupTag(attrptr) != IPP_TAG_OPERATION || ippGetCount(attrptr) != 1 || strcmp(ippGetName(attrptr), "attributes-natural-language"))
1540*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "Bad first attribute \"%s (%s%s)\" in group %s, expected \"attributes-natural-language (naturalLanguage)\" in group operation-attributes-tag (RFC 8011 section 4.1.4).", ippGetName(attrptr) ? ippGetName(attrptr) : "(null)", ippGetCount(attrptr) > 1 ? "1setOf " : "", ippTagString(ippGetValueTag(attrptr)), ippTagString(ippGetGroupTag(attrptr)));
1541*5e7646d2SAndroid Build Coastguard Worker }
1542*5e7646d2SAndroid Build Coastguard Worker
1543*5e7646d2SAndroid Build Coastguard Worker if ((attrptr = ippFindAttribute(response, "status-message", IPP_TAG_ZERO)) != NULL)
1544*5e7646d2SAndroid Build Coastguard Worker {
1545*5e7646d2SAndroid Build Coastguard Worker const char *status_message = ippGetString(attrptr, 0, NULL);
1546*5e7646d2SAndroid Build Coastguard Worker /* String value */
1547*5e7646d2SAndroid Build Coastguard Worker
1548*5e7646d2SAndroid Build Coastguard Worker if (ippGetValueTag(attrptr) != IPP_TAG_TEXT)
1549*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "status-message (text(255)) has wrong value tag %s (RFC 8011 section 4.1.6.2).", ippTagString(ippGetValueTag(attrptr)));
1550*5e7646d2SAndroid Build Coastguard Worker if (ippGetGroupTag(attrptr) != IPP_TAG_OPERATION)
1551*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "status-message (text(255)) has wrong group tag %s (RFC 8011 section 4.1.6.2).", ippTagString(ippGetGroupTag(attrptr)));
1552*5e7646d2SAndroid Build Coastguard Worker if (ippGetCount(attrptr) != 1)
1553*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "status-message (text(255)) has %d values (RFC 8011 section 4.1.6.2).", ippGetCount(attrptr));
1554*5e7646d2SAndroid Build Coastguard Worker if (status_message && strlen(status_message) > 255)
1555*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "status-message (text(255)) has bad length %d (RFC 8011 section 4.1.6.2).", (int)strlen(status_message));
1556*5e7646d2SAndroid Build Coastguard Worker }
1557*5e7646d2SAndroid Build Coastguard Worker
1558*5e7646d2SAndroid Build Coastguard Worker if ((attrptr = ippFindAttribute(response, "detailed-status-message",
1559*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_ZERO)) != NULL)
1560*5e7646d2SAndroid Build Coastguard Worker {
1561*5e7646d2SAndroid Build Coastguard Worker const char *detailed_status_message = ippGetString(attrptr, 0, NULL);
1562*5e7646d2SAndroid Build Coastguard Worker /* String value */
1563*5e7646d2SAndroid Build Coastguard Worker
1564*5e7646d2SAndroid Build Coastguard Worker if (ippGetValueTag(attrptr) != IPP_TAG_TEXT)
1565*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "detailed-status-message (text(MAX)) has wrong value tag %s (RFC 8011 section 4.1.6.3).", ippTagString(ippGetValueTag(attrptr)));
1566*5e7646d2SAndroid Build Coastguard Worker if (ippGetGroupTag(attrptr) != IPP_TAG_OPERATION)
1567*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "detailed-status-message (text(MAX)) has wrong group tag %s (RFC 8011 section 4.1.6.3).", ippTagString(ippGetGroupTag(attrptr)));
1568*5e7646d2SAndroid Build Coastguard Worker if (ippGetCount(attrptr) != 1)
1569*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "detailed-status-message (text(MAX)) has %d values (RFC 8011 section 4.1.6.3).", ippGetCount(attrptr));
1570*5e7646d2SAndroid Build Coastguard Worker if (detailed_status_message && strlen(detailed_status_message) > 1023)
1571*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "detailed-status-message (text(MAX)) has bad length %d (RFC 8011 section 4.1.6.3).", (int)strlen(detailed_status_message));
1572*5e7646d2SAndroid Build Coastguard Worker }
1573*5e7646d2SAndroid Build Coastguard Worker
1574*5e7646d2SAndroid Build Coastguard Worker a = cupsArrayNew((cups_array_func_t)strcmp, NULL);
1575*5e7646d2SAndroid Build Coastguard Worker
1576*5e7646d2SAndroid Build Coastguard Worker for (attrptr = ippFirstAttribute(response), group = ippGetGroupTag(attrptr);
1577*5e7646d2SAndroid Build Coastguard Worker attrptr;
1578*5e7646d2SAndroid Build Coastguard Worker attrptr = ippNextAttribute(response))
1579*5e7646d2SAndroid Build Coastguard Worker {
1580*5e7646d2SAndroid Build Coastguard Worker if (ippGetGroupTag(attrptr) != group)
1581*5e7646d2SAndroid Build Coastguard Worker {
1582*5e7646d2SAndroid Build Coastguard Worker int out_of_order = 0; /* Are attribute groups out-of-order? */
1583*5e7646d2SAndroid Build Coastguard Worker cupsArrayClear(a);
1584*5e7646d2SAndroid Build Coastguard Worker
1585*5e7646d2SAndroid Build Coastguard Worker switch (ippGetGroupTag(attrptr))
1586*5e7646d2SAndroid Build Coastguard Worker {
1587*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ZERO :
1588*5e7646d2SAndroid Build Coastguard Worker break;
1589*5e7646d2SAndroid Build Coastguard Worker
1590*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_OPERATION :
1591*5e7646d2SAndroid Build Coastguard Worker out_of_order = 1;
1592*5e7646d2SAndroid Build Coastguard Worker break;
1593*5e7646d2SAndroid Build Coastguard Worker
1594*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNSUPPORTED_GROUP :
1595*5e7646d2SAndroid Build Coastguard Worker if (group != IPP_TAG_OPERATION)
1596*5e7646d2SAndroid Build Coastguard Worker out_of_order = 1;
1597*5e7646d2SAndroid Build Coastguard Worker break;
1598*5e7646d2SAndroid Build Coastguard Worker
1599*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_JOB :
1600*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_PRINTER :
1601*5e7646d2SAndroid Build Coastguard Worker if (group != IPP_TAG_OPERATION && group != IPP_TAG_UNSUPPORTED_GROUP)
1602*5e7646d2SAndroid Build Coastguard Worker out_of_order = 1;
1603*5e7646d2SAndroid Build Coastguard Worker break;
1604*5e7646d2SAndroid Build Coastguard Worker
1605*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_SUBSCRIPTION :
1606*5e7646d2SAndroid Build Coastguard Worker if (group > ippGetGroupTag(attrptr) && group != IPP_TAG_DOCUMENT)
1607*5e7646d2SAndroid Build Coastguard Worker out_of_order = 1;
1608*5e7646d2SAndroid Build Coastguard Worker break;
1609*5e7646d2SAndroid Build Coastguard Worker
1610*5e7646d2SAndroid Build Coastguard Worker default :
1611*5e7646d2SAndroid Build Coastguard Worker if (group > ippGetGroupTag(attrptr))
1612*5e7646d2SAndroid Build Coastguard Worker out_of_order = 1;
1613*5e7646d2SAndroid Build Coastguard Worker break;
1614*5e7646d2SAndroid Build Coastguard Worker }
1615*5e7646d2SAndroid Build Coastguard Worker
1616*5e7646d2SAndroid Build Coastguard Worker if (out_of_order)
1617*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "Attribute groups out of order (%s < %s)", ippTagString(ippGetGroupTag(attrptr)), ippTagString(group));
1618*5e7646d2SAndroid Build Coastguard Worker
1619*5e7646d2SAndroid Build Coastguard Worker if (ippGetGroupTag(attrptr) != IPP_TAG_ZERO)
1620*5e7646d2SAndroid Build Coastguard Worker group = ippGetGroupTag(attrptr);
1621*5e7646d2SAndroid Build Coastguard Worker }
1622*5e7646d2SAndroid Build Coastguard Worker
1623*5e7646d2SAndroid Build Coastguard Worker if (!ippValidateAttribute(attrptr))
1624*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(data->errors, (void *)cupsLastErrorString());
1625*5e7646d2SAndroid Build Coastguard Worker
1626*5e7646d2SAndroid Build Coastguard Worker if (ippGetName(attrptr))
1627*5e7646d2SAndroid Build Coastguard Worker {
1628*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayFind(a, (void *)ippGetName(attrptr)) && data->output < IPPTOOL_OUTPUT_LIST)
1629*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "Duplicate \"%s\" attribute in %s group", ippGetName(attrptr), ippTagString(group));
1630*5e7646d2SAndroid Build Coastguard Worker
1631*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(a, (void *)ippGetName(attrptr));
1632*5e7646d2SAndroid Build Coastguard Worker }
1633*5e7646d2SAndroid Build Coastguard Worker }
1634*5e7646d2SAndroid Build Coastguard Worker
1635*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(a);
1636*5e7646d2SAndroid Build Coastguard Worker
1637*5e7646d2SAndroid Build Coastguard Worker /*
1638*5e7646d2SAndroid Build Coastguard Worker * Now check the test-defined expected status-code and attribute
1639*5e7646d2SAndroid Build Coastguard Worker * values...
1640*5e7646d2SAndroid Build Coastguard Worker */
1641*5e7646d2SAndroid Build Coastguard Worker
1642*5e7646d2SAndroid Build Coastguard Worker if (ippGetStatusCode(response) == IPP_STATUS_ERROR_BUSY && data->repeat_on_busy)
1643*5e7646d2SAndroid Build Coastguard Worker {
1644*5e7646d2SAndroid Build Coastguard Worker // Repeat on a server-error-busy status code...
1645*5e7646d2SAndroid Build Coastguard Worker status_ok = 1;
1646*5e7646d2SAndroid Build Coastguard Worker repeat_test = 1;
1647*5e7646d2SAndroid Build Coastguard Worker }
1648*5e7646d2SAndroid Build Coastguard Worker
1649*5e7646d2SAndroid Build Coastguard Worker for (i = 0, status_ok = 0; i < data->num_statuses; i ++)
1650*5e7646d2SAndroid Build Coastguard Worker {
1651*5e7646d2SAndroid Build Coastguard Worker if (data->statuses[i].if_defined &&
1652*5e7646d2SAndroid Build Coastguard Worker !_ippVarsGet(data->vars, data->statuses[i].if_defined))
1653*5e7646d2SAndroid Build Coastguard Worker continue;
1654*5e7646d2SAndroid Build Coastguard Worker
1655*5e7646d2SAndroid Build Coastguard Worker if (data->statuses[i].if_not_defined &&
1656*5e7646d2SAndroid Build Coastguard Worker _ippVarsGet(data->vars, data->statuses[i].if_not_defined))
1657*5e7646d2SAndroid Build Coastguard Worker continue;
1658*5e7646d2SAndroid Build Coastguard Worker
1659*5e7646d2SAndroid Build Coastguard Worker if (ippGetStatusCode(response) == data->statuses[i].status)
1660*5e7646d2SAndroid Build Coastguard Worker {
1661*5e7646d2SAndroid Build Coastguard Worker status_ok = 1;
1662*5e7646d2SAndroid Build Coastguard Worker
1663*5e7646d2SAndroid Build Coastguard Worker if (data->statuses[i].repeat_match && repeat_count < data->statuses[i].repeat_limit)
1664*5e7646d2SAndroid Build Coastguard Worker repeat_test = 1;
1665*5e7646d2SAndroid Build Coastguard Worker
1666*5e7646d2SAndroid Build Coastguard Worker if (data->statuses[i].define_match)
1667*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, data->statuses[i].define_match, "1");
1668*5e7646d2SAndroid Build Coastguard Worker }
1669*5e7646d2SAndroid Build Coastguard Worker else
1670*5e7646d2SAndroid Build Coastguard Worker {
1671*5e7646d2SAndroid Build Coastguard Worker if (data->statuses[i].repeat_no_match && repeat_count < data->statuses[i].repeat_limit)
1672*5e7646d2SAndroid Build Coastguard Worker repeat_test = 1;
1673*5e7646d2SAndroid Build Coastguard Worker
1674*5e7646d2SAndroid Build Coastguard Worker if (data->statuses[i].define_no_match)
1675*5e7646d2SAndroid Build Coastguard Worker {
1676*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, data->statuses[i].define_no_match, "1");
1677*5e7646d2SAndroid Build Coastguard Worker status_ok = 1;
1678*5e7646d2SAndroid Build Coastguard Worker }
1679*5e7646d2SAndroid Build Coastguard Worker }
1680*5e7646d2SAndroid Build Coastguard Worker }
1681*5e7646d2SAndroid Build Coastguard Worker
1682*5e7646d2SAndroid Build Coastguard Worker if (!status_ok && data->num_statuses > 0)
1683*5e7646d2SAndroid Build Coastguard Worker {
1684*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < data->num_statuses; i ++)
1685*5e7646d2SAndroid Build Coastguard Worker {
1686*5e7646d2SAndroid Build Coastguard Worker if (data->statuses[i].if_defined &&
1687*5e7646d2SAndroid Build Coastguard Worker !_ippVarsGet(data->vars, data->statuses[i].if_defined))
1688*5e7646d2SAndroid Build Coastguard Worker continue;
1689*5e7646d2SAndroid Build Coastguard Worker
1690*5e7646d2SAndroid Build Coastguard Worker if (data->statuses[i].if_not_defined &&
1691*5e7646d2SAndroid Build Coastguard Worker _ippVarsGet(data->vars, data->statuses[i].if_not_defined))
1692*5e7646d2SAndroid Build Coastguard Worker continue;
1693*5e7646d2SAndroid Build Coastguard Worker
1694*5e7646d2SAndroid Build Coastguard Worker if (!data->statuses[i].repeat_match || repeat_count >= data->statuses[i].repeat_limit)
1695*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "EXPECTED: STATUS %s (got %s)", ippErrorString(data->statuses[i].status), ippErrorString(cupsLastError()));
1696*5e7646d2SAndroid Build Coastguard Worker }
1697*5e7646d2SAndroid Build Coastguard Worker
1698*5e7646d2SAndroid Build Coastguard Worker if ((attrptr = ippFindAttribute(response, "status-message", IPP_TAG_TEXT)) != NULL)
1699*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "status-message=\"%s\"", ippGetString(attrptr, 0, NULL));
1700*5e7646d2SAndroid Build Coastguard Worker }
1701*5e7646d2SAndroid Build Coastguard Worker
1702*5e7646d2SAndroid Build Coastguard Worker for (i = data->num_expects, expect = data->expects; i > 0; i --, expect ++)
1703*5e7646d2SAndroid Build Coastguard Worker {
1704*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *group_found; /* Found parent attribute for group tests */
1705*5e7646d2SAndroid Build Coastguard Worker
1706*5e7646d2SAndroid Build Coastguard Worker if (expect->if_defined && !_ippVarsGet(data->vars, expect->if_defined))
1707*5e7646d2SAndroid Build Coastguard Worker continue;
1708*5e7646d2SAndroid Build Coastguard Worker
1709*5e7646d2SAndroid Build Coastguard Worker if (expect->if_not_defined &&
1710*5e7646d2SAndroid Build Coastguard Worker _ippVarsGet(data->vars, expect->if_not_defined))
1711*5e7646d2SAndroid Build Coastguard Worker continue;
1712*5e7646d2SAndroid Build Coastguard Worker
1713*5e7646d2SAndroid Build Coastguard Worker if ((found = ippFindAttribute(response, expect->name, IPP_TAG_ZERO)) != NULL && expect->in_group && expect->in_group != ippGetGroupTag(found))
1714*5e7646d2SAndroid Build Coastguard Worker {
1715*5e7646d2SAndroid Build Coastguard Worker while ((found = ippFindNextAttribute(response, expect->name, IPP_TAG_ZERO)) != NULL)
1716*5e7646d2SAndroid Build Coastguard Worker if (expect->in_group == ippGetGroupTag(found))
1717*5e7646d2SAndroid Build Coastguard Worker break;
1718*5e7646d2SAndroid Build Coastguard Worker }
1719*5e7646d2SAndroid Build Coastguard Worker
1720*5e7646d2SAndroid Build Coastguard Worker do
1721*5e7646d2SAndroid Build Coastguard Worker {
1722*5e7646d2SAndroid Build Coastguard Worker group_found = found;
1723*5e7646d2SAndroid Build Coastguard Worker
1724*5e7646d2SAndroid Build Coastguard Worker if (expect->in_group && strchr(expect->name, '/'))
1725*5e7646d2SAndroid Build Coastguard Worker {
1726*5e7646d2SAndroid Build Coastguard Worker char group_name[256],/* Parent attribute name */
1727*5e7646d2SAndroid Build Coastguard Worker *group_ptr; /* Pointer into parent attribute name */
1728*5e7646d2SAndroid Build Coastguard Worker
1729*5e7646d2SAndroid Build Coastguard Worker strlcpy(group_name, expect->name, sizeof(group_name));
1730*5e7646d2SAndroid Build Coastguard Worker if ((group_ptr = strchr(group_name, '/')) != NULL)
1731*5e7646d2SAndroid Build Coastguard Worker *group_ptr = '\0';
1732*5e7646d2SAndroid Build Coastguard Worker
1733*5e7646d2SAndroid Build Coastguard Worker group_found = ippFindAttribute(response, group_name, IPP_TAG_ZERO);
1734*5e7646d2SAndroid Build Coastguard Worker }
1735*5e7646d2SAndroid Build Coastguard Worker
1736*5e7646d2SAndroid Build Coastguard Worker if ((found && expect->not_expect) ||
1737*5e7646d2SAndroid Build Coastguard Worker (!found && !(expect->not_expect || expect->optional)) ||
1738*5e7646d2SAndroid Build Coastguard Worker (found && !expect_matches(expect, found)) ||
1739*5e7646d2SAndroid Build Coastguard Worker (group_found && expect->in_group && ippGetGroupTag(group_found) != expect->in_group) ||
1740*5e7646d2SAndroid Build Coastguard Worker (expect->with_distinct && !with_distinct_values(NULL, found)))
1741*5e7646d2SAndroid Build Coastguard Worker {
1742*5e7646d2SAndroid Build Coastguard Worker if (expect->define_no_match)
1743*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, expect->define_no_match, "1");
1744*5e7646d2SAndroid Build Coastguard Worker else if (!expect->define_match && !expect->define_value)
1745*5e7646d2SAndroid Build Coastguard Worker {
1746*5e7646d2SAndroid Build Coastguard Worker if (found && expect->not_expect && !expect->with_value && !expect->with_value_from)
1747*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "NOT EXPECTED: %s", expect->name);
1748*5e7646d2SAndroid Build Coastguard Worker else if (!found && !(expect->not_expect || expect->optional))
1749*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "EXPECTED: %s", expect->name);
1750*5e7646d2SAndroid Build Coastguard Worker else if (found)
1751*5e7646d2SAndroid Build Coastguard Worker {
1752*5e7646d2SAndroid Build Coastguard Worker if (!expect_matches(expect, found))
1753*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "EXPECTED: %s OF-TYPE %s (got %s)",
1754*5e7646d2SAndroid Build Coastguard Worker expect->name, expect->of_type,
1755*5e7646d2SAndroid Build Coastguard Worker ippTagString(ippGetValueTag(found)));
1756*5e7646d2SAndroid Build Coastguard Worker
1757*5e7646d2SAndroid Build Coastguard Worker if (expect->in_group && ippGetGroupTag(group_found) != expect->in_group)
1758*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "EXPECTED: %s IN-GROUP %s (got %s).",
1759*5e7646d2SAndroid Build Coastguard Worker expect->name, ippTagString(expect->in_group),
1760*5e7646d2SAndroid Build Coastguard Worker ippTagString(ippGetGroupTag(group_found)));
1761*5e7646d2SAndroid Build Coastguard Worker
1762*5e7646d2SAndroid Build Coastguard Worker if (expect->with_distinct)
1763*5e7646d2SAndroid Build Coastguard Worker with_distinct_values(data->errors, found);
1764*5e7646d2SAndroid Build Coastguard Worker }
1765*5e7646d2SAndroid Build Coastguard Worker }
1766*5e7646d2SAndroid Build Coastguard Worker
1767*5e7646d2SAndroid Build Coastguard Worker if (expect->repeat_no_match && repeat_count < expect->repeat_limit)
1768*5e7646d2SAndroid Build Coastguard Worker repeat_test = 1;
1769*5e7646d2SAndroid Build Coastguard Worker break;
1770*5e7646d2SAndroid Build Coastguard Worker }
1771*5e7646d2SAndroid Build Coastguard Worker
1772*5e7646d2SAndroid Build Coastguard Worker if (found)
1773*5e7646d2SAndroid Build Coastguard Worker ippAttributeString(found, buffer, sizeof(buffer));
1774*5e7646d2SAndroid Build Coastguard Worker
1775*5e7646d2SAndroid Build Coastguard Worker if (found && expect->with_value_from && !with_value_from(NULL, ippFindAttribute(response, expect->with_value_from, IPP_TAG_ZERO), found, buffer, sizeof(buffer)))
1776*5e7646d2SAndroid Build Coastguard Worker {
1777*5e7646d2SAndroid Build Coastguard Worker if (expect->define_no_match)
1778*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, expect->define_no_match, "1");
1779*5e7646d2SAndroid Build Coastguard Worker else if (!expect->define_match && !expect->define_value && ((!expect->repeat_match && !expect->repeat_no_match) || repeat_count >= expect->repeat_limit))
1780*5e7646d2SAndroid Build Coastguard Worker {
1781*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "EXPECTED: %s WITH-VALUES-FROM %s", expect->name, expect->with_value_from);
1782*5e7646d2SAndroid Build Coastguard Worker
1783*5e7646d2SAndroid Build Coastguard Worker with_value_from(data->errors, ippFindAttribute(response, expect->with_value_from, IPP_TAG_ZERO), found, buffer, sizeof(buffer));
1784*5e7646d2SAndroid Build Coastguard Worker }
1785*5e7646d2SAndroid Build Coastguard Worker
1786*5e7646d2SAndroid Build Coastguard Worker if (expect->repeat_no_match && repeat_count < expect->repeat_limit)
1787*5e7646d2SAndroid Build Coastguard Worker repeat_test = 1;
1788*5e7646d2SAndroid Build Coastguard Worker
1789*5e7646d2SAndroid Build Coastguard Worker break;
1790*5e7646d2SAndroid Build Coastguard Worker }
1791*5e7646d2SAndroid Build Coastguard Worker else if (found && !with_value(data, NULL, expect->with_value, expect->with_flags, found, buffer, sizeof(buffer)))
1792*5e7646d2SAndroid Build Coastguard Worker {
1793*5e7646d2SAndroid Build Coastguard Worker if (expect->define_no_match)
1794*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, expect->define_no_match, "1");
1795*5e7646d2SAndroid Build Coastguard Worker else if (!expect->define_match && !expect->define_value &&
1796*5e7646d2SAndroid Build Coastguard Worker !expect->repeat_match && (!expect->repeat_no_match || repeat_count >= expect->repeat_limit))
1797*5e7646d2SAndroid Build Coastguard Worker {
1798*5e7646d2SAndroid Build Coastguard Worker if (expect->with_flags & IPPTOOL_WITH_REGEX)
1799*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "EXPECTED: %s %s /%s/", expect->name, with_flags_string(expect->with_flags), expect->with_value);
1800*5e7646d2SAndroid Build Coastguard Worker else
1801*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "EXPECTED: %s %s \"%s\"", expect->name, with_flags_string(expect->with_flags), expect->with_value);
1802*5e7646d2SAndroid Build Coastguard Worker
1803*5e7646d2SAndroid Build Coastguard Worker with_value(data, data->errors, expect->with_value, expect->with_flags, found, buffer, sizeof(buffer));
1804*5e7646d2SAndroid Build Coastguard Worker }
1805*5e7646d2SAndroid Build Coastguard Worker
1806*5e7646d2SAndroid Build Coastguard Worker if (expect->repeat_no_match &&
1807*5e7646d2SAndroid Build Coastguard Worker repeat_count < expect->repeat_limit)
1808*5e7646d2SAndroid Build Coastguard Worker repeat_test = 1;
1809*5e7646d2SAndroid Build Coastguard Worker
1810*5e7646d2SAndroid Build Coastguard Worker break;
1811*5e7646d2SAndroid Build Coastguard Worker }
1812*5e7646d2SAndroid Build Coastguard Worker
1813*5e7646d2SAndroid Build Coastguard Worker if (found && expect->count > 0 && ippGetCount(found) != expect->count)
1814*5e7646d2SAndroid Build Coastguard Worker {
1815*5e7646d2SAndroid Build Coastguard Worker if (expect->define_no_match)
1816*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, expect->define_no_match, "1");
1817*5e7646d2SAndroid Build Coastguard Worker else if (!expect->define_match && !expect->define_value)
1818*5e7646d2SAndroid Build Coastguard Worker {
1819*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "EXPECTED: %s COUNT %d (got %d)", expect->name, expect->count, ippGetCount(found));
1820*5e7646d2SAndroid Build Coastguard Worker }
1821*5e7646d2SAndroid Build Coastguard Worker
1822*5e7646d2SAndroid Build Coastguard Worker if (expect->repeat_no_match &&
1823*5e7646d2SAndroid Build Coastguard Worker repeat_count < expect->repeat_limit)
1824*5e7646d2SAndroid Build Coastguard Worker repeat_test = 1;
1825*5e7646d2SAndroid Build Coastguard Worker
1826*5e7646d2SAndroid Build Coastguard Worker break;
1827*5e7646d2SAndroid Build Coastguard Worker }
1828*5e7646d2SAndroid Build Coastguard Worker
1829*5e7646d2SAndroid Build Coastguard Worker if (found && expect->same_count_as)
1830*5e7646d2SAndroid Build Coastguard Worker {
1831*5e7646d2SAndroid Build Coastguard Worker attrptr = ippFindAttribute(response, expect->same_count_as,
1832*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_ZERO);
1833*5e7646d2SAndroid Build Coastguard Worker
1834*5e7646d2SAndroid Build Coastguard Worker if (!attrptr || ippGetCount(attrptr) != ippGetCount(found))
1835*5e7646d2SAndroid Build Coastguard Worker {
1836*5e7646d2SAndroid Build Coastguard Worker if (expect->define_no_match)
1837*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, expect->define_no_match, "1");
1838*5e7646d2SAndroid Build Coastguard Worker else if (!expect->define_match && !expect->define_value)
1839*5e7646d2SAndroid Build Coastguard Worker {
1840*5e7646d2SAndroid Build Coastguard Worker if (!attrptr)
1841*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "EXPECTED: %s (%d values) SAME-COUNT-AS %s (not returned)", expect->name, ippGetCount(found), expect->same_count_as);
1842*5e7646d2SAndroid Build Coastguard Worker else if (ippGetCount(attrptr) != ippGetCount(found))
1843*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "EXPECTED: %s (%d values) SAME-COUNT-AS %s (%d values)", expect->name, ippGetCount(found), expect->same_count_as, ippGetCount(attrptr));
1844*5e7646d2SAndroid Build Coastguard Worker }
1845*5e7646d2SAndroid Build Coastguard Worker
1846*5e7646d2SAndroid Build Coastguard Worker if (expect->repeat_no_match &&
1847*5e7646d2SAndroid Build Coastguard Worker repeat_count < expect->repeat_limit)
1848*5e7646d2SAndroid Build Coastguard Worker repeat_test = 1;
1849*5e7646d2SAndroid Build Coastguard Worker
1850*5e7646d2SAndroid Build Coastguard Worker break;
1851*5e7646d2SAndroid Build Coastguard Worker }
1852*5e7646d2SAndroid Build Coastguard Worker }
1853*5e7646d2SAndroid Build Coastguard Worker
1854*5e7646d2SAndroid Build Coastguard Worker if (found && expect->display_match && (data->output == IPPTOOL_OUTPUT_TEST || (data->output == IPPTOOL_OUTPUT_PLIST && data->outfile != cupsFileStdout())))
1855*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(cupsFileStdout(), "\n%s\n\n", expect->display_match);
1856*5e7646d2SAndroid Build Coastguard Worker
1857*5e7646d2SAndroid Build Coastguard Worker if (found && expect->define_match)
1858*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, expect->define_match, "1");
1859*5e7646d2SAndroid Build Coastguard Worker
1860*5e7646d2SAndroid Build Coastguard Worker if (found && expect->define_value)
1861*5e7646d2SAndroid Build Coastguard Worker {
1862*5e7646d2SAndroid Build Coastguard Worker if (!expect->with_value)
1863*5e7646d2SAndroid Build Coastguard Worker {
1864*5e7646d2SAndroid Build Coastguard Worker int last = ippGetCount(found) - 1;
1865*5e7646d2SAndroid Build Coastguard Worker /* Last element in attribute */
1866*5e7646d2SAndroid Build Coastguard Worker
1867*5e7646d2SAndroid Build Coastguard Worker switch (ippGetValueTag(found))
1868*5e7646d2SAndroid Build Coastguard Worker {
1869*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
1870*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
1871*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "%d", ippGetInteger(found, last));
1872*5e7646d2SAndroid Build Coastguard Worker break;
1873*5e7646d2SAndroid Build Coastguard Worker
1874*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BOOLEAN :
1875*5e7646d2SAndroid Build Coastguard Worker if (ippGetBoolean(found, last))
1876*5e7646d2SAndroid Build Coastguard Worker strlcpy(buffer, "true", sizeof(buffer));
1877*5e7646d2SAndroid Build Coastguard Worker else
1878*5e7646d2SAndroid Build Coastguard Worker strlcpy(buffer, "false", sizeof(buffer));
1879*5e7646d2SAndroid Build Coastguard Worker break;
1880*5e7646d2SAndroid Build Coastguard Worker
1881*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
1882*5e7646d2SAndroid Build Coastguard Worker {
1883*5e7646d2SAndroid Build Coastguard Worker int xres, /* Horizontal resolution */
1884*5e7646d2SAndroid Build Coastguard Worker yres; /* Vertical resolution */
1885*5e7646d2SAndroid Build Coastguard Worker ipp_res_t units; /* Resolution units */
1886*5e7646d2SAndroid Build Coastguard Worker
1887*5e7646d2SAndroid Build Coastguard Worker xres = ippGetResolution(found, last, &yres, &units);
1888*5e7646d2SAndroid Build Coastguard Worker
1889*5e7646d2SAndroid Build Coastguard Worker if (xres == yres)
1890*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "%d%s", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
1891*5e7646d2SAndroid Build Coastguard Worker else
1892*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "%dx%d%s", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
1893*5e7646d2SAndroid Build Coastguard Worker }
1894*5e7646d2SAndroid Build Coastguard Worker break;
1895*5e7646d2SAndroid Build Coastguard Worker
1896*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
1897*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
1898*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
1899*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
1900*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
1901*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
1902*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
1903*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
1904*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
1905*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
1906*5e7646d2SAndroid Build Coastguard Worker strlcpy(buffer, ippGetString(found, last, NULL), sizeof(buffer));
1907*5e7646d2SAndroid Build Coastguard Worker break;
1908*5e7646d2SAndroid Build Coastguard Worker
1909*5e7646d2SAndroid Build Coastguard Worker default :
1910*5e7646d2SAndroid Build Coastguard Worker ippAttributeString(found, buffer, sizeof(buffer));
1911*5e7646d2SAndroid Build Coastguard Worker break;
1912*5e7646d2SAndroid Build Coastguard Worker }
1913*5e7646d2SAndroid Build Coastguard Worker }
1914*5e7646d2SAndroid Build Coastguard Worker
1915*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(data->vars, expect->define_value, buffer);
1916*5e7646d2SAndroid Build Coastguard Worker }
1917*5e7646d2SAndroid Build Coastguard Worker
1918*5e7646d2SAndroid Build Coastguard Worker if (found && expect->repeat_match &&
1919*5e7646d2SAndroid Build Coastguard Worker repeat_count < expect->repeat_limit)
1920*5e7646d2SAndroid Build Coastguard Worker repeat_test = 1;
1921*5e7646d2SAndroid Build Coastguard Worker }
1922*5e7646d2SAndroid Build Coastguard Worker while (expect->expect_all && (found = ippFindNextAttribute(response, expect->name, IPP_TAG_ZERO)) != NULL);
1923*5e7646d2SAndroid Build Coastguard Worker }
1924*5e7646d2SAndroid Build Coastguard Worker }
1925*5e7646d2SAndroid Build Coastguard Worker
1926*5e7646d2SAndroid Build Coastguard Worker /*
1927*5e7646d2SAndroid Build Coastguard Worker * If we are going to repeat this test, display intermediate results...
1928*5e7646d2SAndroid Build Coastguard Worker */
1929*5e7646d2SAndroid Build Coastguard Worker
1930*5e7646d2SAndroid Build Coastguard Worker if (repeat_test)
1931*5e7646d2SAndroid Build Coastguard Worker {
1932*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_TEST || (data->output == IPPTOOL_OUTPUT_PLIST && data->outfile != cupsFileStdout()))
1933*5e7646d2SAndroid Build Coastguard Worker {
1934*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(cupsFileStdout(), "%04d]\n", repeat_count);
1935*5e7646d2SAndroid Build Coastguard Worker \
1936*5e7646d2SAndroid Build Coastguard Worker if (data->num_displayed > 0)
1937*5e7646d2SAndroid Build Coastguard Worker {
1938*5e7646d2SAndroid Build Coastguard Worker for (attrptr = ippFirstAttribute(response); attrptr; attrptr = ippNextAttribute(response))
1939*5e7646d2SAndroid Build Coastguard Worker {
1940*5e7646d2SAndroid Build Coastguard Worker const char *attrname = ippGetName(attrptr);
1941*5e7646d2SAndroid Build Coastguard Worker if (attrname)
1942*5e7646d2SAndroid Build Coastguard Worker {
1943*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < data->num_displayed; i ++)
1944*5e7646d2SAndroid Build Coastguard Worker {
1945*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(data->displayed[i], attrname))
1946*5e7646d2SAndroid Build Coastguard Worker {
1947*5e7646d2SAndroid Build Coastguard Worker print_attr(cupsFileStdout(), IPPTOOL_OUTPUT_TEST, attrptr, NULL);
1948*5e7646d2SAndroid Build Coastguard Worker break;
1949*5e7646d2SAndroid Build Coastguard Worker }
1950*5e7646d2SAndroid Build Coastguard Worker }
1951*5e7646d2SAndroid Build Coastguard Worker }
1952*5e7646d2SAndroid Build Coastguard Worker }
1953*5e7646d2SAndroid Build Coastguard Worker }
1954*5e7646d2SAndroid Build Coastguard Worker }
1955*5e7646d2SAndroid Build Coastguard Worker
1956*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_TEST || (data->output == IPPTOOL_OUTPUT_PLIST && data->outfile != cupsFileStdout()))
1957*5e7646d2SAndroid Build Coastguard Worker {
1958*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(cupsFileStdout(), " %-68.68s [", data->name);
1959*5e7646d2SAndroid Build Coastguard Worker }
1960*5e7646d2SAndroid Build Coastguard Worker
1961*5e7646d2SAndroid Build Coastguard Worker ippDelete(response);
1962*5e7646d2SAndroid Build Coastguard Worker response = NULL;
1963*5e7646d2SAndroid Build Coastguard Worker }
1964*5e7646d2SAndroid Build Coastguard Worker }
1965*5e7646d2SAndroid Build Coastguard Worker while (repeat_test);
1966*5e7646d2SAndroid Build Coastguard Worker
1967*5e7646d2SAndroid Build Coastguard Worker ippDelete(request);
1968*5e7646d2SAndroid Build Coastguard Worker
1969*5e7646d2SAndroid Build Coastguard Worker request = NULL;
1970*5e7646d2SAndroid Build Coastguard Worker
1971*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayCount(data->errors) > 0)
1972*5e7646d2SAndroid Build Coastguard Worker data->prev_pass = data->pass = 0;
1973*5e7646d2SAndroid Build Coastguard Worker
1974*5e7646d2SAndroid Build Coastguard Worker if (data->prev_pass)
1975*5e7646d2SAndroid Build Coastguard Worker data->pass_count ++;
1976*5e7646d2SAndroid Build Coastguard Worker else
1977*5e7646d2SAndroid Build Coastguard Worker data->fail_count ++;
1978*5e7646d2SAndroid Build Coastguard Worker
1979*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_PLIST)
1980*5e7646d2SAndroid Build Coastguard Worker {
1981*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>Successful</key>\n");
1982*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, data->prev_pass ? "<true />\n" : "<false />\n");
1983*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>StatusCode</key>\n");
1984*5e7646d2SAndroid Build Coastguard Worker print_xml_string(data->outfile, "string", ippErrorString(cupsLastError()));
1985*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>ResponseAttributes</key>\n");
1986*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<array>\n");
1987*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<dict>\n");
1988*5e7646d2SAndroid Build Coastguard Worker for (attrptr = ippFirstAttribute(response), group = ippGetGroupTag(attrptr);
1989*5e7646d2SAndroid Build Coastguard Worker attrptr;
1990*5e7646d2SAndroid Build Coastguard Worker attrptr = ippNextAttribute(response))
1991*5e7646d2SAndroid Build Coastguard Worker print_attr(data->outfile, data->output, attrptr, &group);
1992*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "</dict>\n");
1993*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "</array>\n");
1994*5e7646d2SAndroid Build Coastguard Worker }
1995*5e7646d2SAndroid Build Coastguard Worker else if (data->output == IPPTOOL_OUTPUT_IPPSERVER && response)
1996*5e7646d2SAndroid Build Coastguard Worker {
1997*5e7646d2SAndroid Build Coastguard Worker for (attrptr = ippFirstAttribute(response); attrptr; attrptr = ippNextAttribute(response))
1998*5e7646d2SAndroid Build Coastguard Worker {
1999*5e7646d2SAndroid Build Coastguard Worker if (!ippGetName(attrptr) || ippGetGroupTag(attrptr) != IPP_TAG_PRINTER)
2000*5e7646d2SAndroid Build Coastguard Worker continue;
2001*5e7646d2SAndroid Build Coastguard Worker
2002*5e7646d2SAndroid Build Coastguard Worker print_ippserver_attr(data, attrptr, 0);
2003*5e7646d2SAndroid Build Coastguard Worker }
2004*5e7646d2SAndroid Build Coastguard Worker }
2005*5e7646d2SAndroid Build Coastguard Worker
2006*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_TEST || (data->output == IPPTOOL_OUTPUT_PLIST && data->outfile != cupsFileStdout()))
2007*5e7646d2SAndroid Build Coastguard Worker {
2008*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(cupsFileStdout(), data->prev_pass ? "PASS]\n" : "FAIL]\n");
2009*5e7646d2SAndroid Build Coastguard Worker
2010*5e7646d2SAndroid Build Coastguard Worker if (!data->prev_pass || (data->verbosity && response))
2011*5e7646d2SAndroid Build Coastguard Worker {
2012*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(cupsFileStdout(), " RECEIVED: %lu bytes in response\n", (unsigned long)ippLength(response));
2013*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(cupsFileStdout(), " status-code = %s (%s)\n", ippErrorString(cupsLastError()), cupsLastErrorString());
2014*5e7646d2SAndroid Build Coastguard Worker
2015*5e7646d2SAndroid Build Coastguard Worker if (data->verbosity && response)
2016*5e7646d2SAndroid Build Coastguard Worker {
2017*5e7646d2SAndroid Build Coastguard Worker for (attrptr = ippFirstAttribute(response); attrptr; attrptr = ippNextAttribute(response))
2018*5e7646d2SAndroid Build Coastguard Worker print_attr(cupsFileStdout(), IPPTOOL_OUTPUT_TEST, attrptr, NULL);
2019*5e7646d2SAndroid Build Coastguard Worker }
2020*5e7646d2SAndroid Build Coastguard Worker }
2021*5e7646d2SAndroid Build Coastguard Worker }
2022*5e7646d2SAndroid Build Coastguard Worker else if (!data->prev_pass && data->output != IPPTOOL_OUTPUT_QUIET)
2023*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "%s\n", cupsLastErrorString());
2024*5e7646d2SAndroid Build Coastguard Worker
2025*5e7646d2SAndroid Build Coastguard Worker if (data->prev_pass && data->output >= IPPTOOL_OUTPUT_LIST && !data->verbosity && data->num_displayed > 0)
2026*5e7646d2SAndroid Build Coastguard Worker {
2027*5e7646d2SAndroid Build Coastguard Worker size_t width; /* Length of value */
2028*5e7646d2SAndroid Build Coastguard Worker
2029*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < data->num_displayed; i ++)
2030*5e7646d2SAndroid Build Coastguard Worker {
2031*5e7646d2SAndroid Build Coastguard Worker widths[i] = strlen(data->displayed[i]);
2032*5e7646d2SAndroid Build Coastguard Worker
2033*5e7646d2SAndroid Build Coastguard Worker for (attrptr = ippFindAttribute(response, data->displayed[i], IPP_TAG_ZERO);
2034*5e7646d2SAndroid Build Coastguard Worker attrptr;
2035*5e7646d2SAndroid Build Coastguard Worker attrptr = ippFindNextAttribute(response, data->displayed[i], IPP_TAG_ZERO))
2036*5e7646d2SAndroid Build Coastguard Worker {
2037*5e7646d2SAndroid Build Coastguard Worker width = ippAttributeString(attrptr, NULL, 0);
2038*5e7646d2SAndroid Build Coastguard Worker if (width > widths[i])
2039*5e7646d2SAndroid Build Coastguard Worker widths[i] = width;
2040*5e7646d2SAndroid Build Coastguard Worker }
2041*5e7646d2SAndroid Build Coastguard Worker }
2042*5e7646d2SAndroid Build Coastguard Worker
2043*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_CSV)
2044*5e7646d2SAndroid Build Coastguard Worker print_csv(data, NULL, NULL, data->num_displayed, data->displayed, widths);
2045*5e7646d2SAndroid Build Coastguard Worker else
2046*5e7646d2SAndroid Build Coastguard Worker print_line(data, NULL, NULL, data->num_displayed, data->displayed, widths);
2047*5e7646d2SAndroid Build Coastguard Worker
2048*5e7646d2SAndroid Build Coastguard Worker attrptr = ippFirstAttribute(response);
2049*5e7646d2SAndroid Build Coastguard Worker
2050*5e7646d2SAndroid Build Coastguard Worker while (attrptr)
2051*5e7646d2SAndroid Build Coastguard Worker {
2052*5e7646d2SAndroid Build Coastguard Worker while (attrptr && ippGetGroupTag(attrptr) <= IPP_TAG_OPERATION)
2053*5e7646d2SAndroid Build Coastguard Worker attrptr = ippNextAttribute(response);
2054*5e7646d2SAndroid Build Coastguard Worker
2055*5e7646d2SAndroid Build Coastguard Worker if (attrptr)
2056*5e7646d2SAndroid Build Coastguard Worker {
2057*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_CSV)
2058*5e7646d2SAndroid Build Coastguard Worker attrptr = print_csv(data, response, attrptr, data->num_displayed, data->displayed, widths);
2059*5e7646d2SAndroid Build Coastguard Worker else
2060*5e7646d2SAndroid Build Coastguard Worker attrptr = print_line(data, response, attrptr, data->num_displayed, data->displayed, widths);
2061*5e7646d2SAndroid Build Coastguard Worker
2062*5e7646d2SAndroid Build Coastguard Worker while (attrptr && ippGetGroupTag(attrptr) > IPP_TAG_OPERATION)
2063*5e7646d2SAndroid Build Coastguard Worker attrptr = ippNextAttribute(response);
2064*5e7646d2SAndroid Build Coastguard Worker }
2065*5e7646d2SAndroid Build Coastguard Worker }
2066*5e7646d2SAndroid Build Coastguard Worker }
2067*5e7646d2SAndroid Build Coastguard Worker else if (!data->prev_pass)
2068*5e7646d2SAndroid Build Coastguard Worker {
2069*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_PLIST)
2070*5e7646d2SAndroid Build Coastguard Worker {
2071*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>Errors</key>\n");
2072*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<array>\n");
2073*5e7646d2SAndroid Build Coastguard Worker
2074*5e7646d2SAndroid Build Coastguard Worker for (error = (char *)cupsArrayFirst(data->errors);
2075*5e7646d2SAndroid Build Coastguard Worker error;
2076*5e7646d2SAndroid Build Coastguard Worker error = (char *)cupsArrayNext(data->errors))
2077*5e7646d2SAndroid Build Coastguard Worker print_xml_string(data->outfile, "string", error);
2078*5e7646d2SAndroid Build Coastguard Worker
2079*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "</array>\n");
2080*5e7646d2SAndroid Build Coastguard Worker }
2081*5e7646d2SAndroid Build Coastguard Worker
2082*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_TEST || (data->output == IPPTOOL_OUTPUT_PLIST && data->outfile != cupsFileStdout()))
2083*5e7646d2SAndroid Build Coastguard Worker {
2084*5e7646d2SAndroid Build Coastguard Worker for (error = (char *)cupsArrayFirst(data->errors);
2085*5e7646d2SAndroid Build Coastguard Worker error;
2086*5e7646d2SAndroid Build Coastguard Worker error = (char *)cupsArrayNext(data->errors))
2087*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(cupsFileStdout(), " %s\n", error);
2088*5e7646d2SAndroid Build Coastguard Worker }
2089*5e7646d2SAndroid Build Coastguard Worker }
2090*5e7646d2SAndroid Build Coastguard Worker
2091*5e7646d2SAndroid Build Coastguard Worker if (data->num_displayed > 0 && !data->verbosity && response && (data->output == IPPTOOL_OUTPUT_TEST || (data->output == IPPTOOL_OUTPUT_PLIST && data->outfile != cupsFileStdout())))
2092*5e7646d2SAndroid Build Coastguard Worker {
2093*5e7646d2SAndroid Build Coastguard Worker for (attrptr = ippFirstAttribute(response); attrptr; attrptr = ippNextAttribute(response))
2094*5e7646d2SAndroid Build Coastguard Worker {
2095*5e7646d2SAndroid Build Coastguard Worker if (ippGetName(attrptr))
2096*5e7646d2SAndroid Build Coastguard Worker {
2097*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < data->num_displayed; i ++)
2098*5e7646d2SAndroid Build Coastguard Worker {
2099*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(data->displayed[i], ippGetName(attrptr)))
2100*5e7646d2SAndroid Build Coastguard Worker {
2101*5e7646d2SAndroid Build Coastguard Worker print_attr(data->outfile, data->output, attrptr, NULL);
2102*5e7646d2SAndroid Build Coastguard Worker break;
2103*5e7646d2SAndroid Build Coastguard Worker }
2104*5e7646d2SAndroid Build Coastguard Worker }
2105*5e7646d2SAndroid Build Coastguard Worker }
2106*5e7646d2SAndroid Build Coastguard Worker }
2107*5e7646d2SAndroid Build Coastguard Worker }
2108*5e7646d2SAndroid Build Coastguard Worker
2109*5e7646d2SAndroid Build Coastguard Worker skip_error:
2110*5e7646d2SAndroid Build Coastguard Worker
2111*5e7646d2SAndroid Build Coastguard Worker if (data->monitor_thread)
2112*5e7646d2SAndroid Build Coastguard Worker {
2113*5e7646d2SAndroid Build Coastguard Worker data->monitor_done = 1;
2114*5e7646d2SAndroid Build Coastguard Worker _cupsThreadWait(data->monitor_thread);
2115*5e7646d2SAndroid Build Coastguard Worker }
2116*5e7646d2SAndroid Build Coastguard Worker
2117*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_PLIST)
2118*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "</dict>\n");
2119*5e7646d2SAndroid Build Coastguard Worker
2120*5e7646d2SAndroid Build Coastguard Worker ippDelete(response);
2121*5e7646d2SAndroid Build Coastguard Worker response = NULL;
2122*5e7646d2SAndroid Build Coastguard Worker
2123*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < data->num_statuses; i ++)
2124*5e7646d2SAndroid Build Coastguard Worker {
2125*5e7646d2SAndroid Build Coastguard Worker free(data->statuses[i].if_defined);
2126*5e7646d2SAndroid Build Coastguard Worker free(data->statuses[i].if_not_defined);
2127*5e7646d2SAndroid Build Coastguard Worker free(data->statuses[i].define_match);
2128*5e7646d2SAndroid Build Coastguard Worker free(data->statuses[i].define_no_match);
2129*5e7646d2SAndroid Build Coastguard Worker }
2130*5e7646d2SAndroid Build Coastguard Worker data->num_statuses = 0;
2131*5e7646d2SAndroid Build Coastguard Worker
2132*5e7646d2SAndroid Build Coastguard Worker for (i = data->num_expects, expect = data->expects; i > 0; i --, expect ++)
2133*5e7646d2SAndroid Build Coastguard Worker {
2134*5e7646d2SAndroid Build Coastguard Worker free(expect->name);
2135*5e7646d2SAndroid Build Coastguard Worker free(expect->of_type);
2136*5e7646d2SAndroid Build Coastguard Worker free(expect->same_count_as);
2137*5e7646d2SAndroid Build Coastguard Worker free(expect->if_defined);
2138*5e7646d2SAndroid Build Coastguard Worker free(expect->if_not_defined);
2139*5e7646d2SAndroid Build Coastguard Worker free(expect->with_value);
2140*5e7646d2SAndroid Build Coastguard Worker free(expect->define_match);
2141*5e7646d2SAndroid Build Coastguard Worker free(expect->define_no_match);
2142*5e7646d2SAndroid Build Coastguard Worker free(expect->define_value);
2143*5e7646d2SAndroid Build Coastguard Worker free(expect->display_match);
2144*5e7646d2SAndroid Build Coastguard Worker }
2145*5e7646d2SAndroid Build Coastguard Worker data->num_expects = 0;
2146*5e7646d2SAndroid Build Coastguard Worker
2147*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < data->num_displayed; i ++)
2148*5e7646d2SAndroid Build Coastguard Worker free(data->displayed[i]);
2149*5e7646d2SAndroid Build Coastguard Worker data->num_displayed = 0;
2150*5e7646d2SAndroid Build Coastguard Worker
2151*5e7646d2SAndroid Build Coastguard Worker free(data->monitor_uri);
2152*5e7646d2SAndroid Build Coastguard Worker data->monitor_uri = NULL;
2153*5e7646d2SAndroid Build Coastguard Worker
2154*5e7646d2SAndroid Build Coastguard Worker for (i = data->num_monitor_expects, expect = data->monitor_expects; i > 0; i --, expect ++)
2155*5e7646d2SAndroid Build Coastguard Worker {
2156*5e7646d2SAndroid Build Coastguard Worker free(expect->name);
2157*5e7646d2SAndroid Build Coastguard Worker free(expect->of_type);
2158*5e7646d2SAndroid Build Coastguard Worker free(expect->same_count_as);
2159*5e7646d2SAndroid Build Coastguard Worker free(expect->if_defined);
2160*5e7646d2SAndroid Build Coastguard Worker free(expect->if_not_defined);
2161*5e7646d2SAndroid Build Coastguard Worker free(expect->with_value);
2162*5e7646d2SAndroid Build Coastguard Worker free(expect->define_match);
2163*5e7646d2SAndroid Build Coastguard Worker free(expect->define_no_match);
2164*5e7646d2SAndroid Build Coastguard Worker free(expect->define_value);
2165*5e7646d2SAndroid Build Coastguard Worker free(expect->display_match);
2166*5e7646d2SAndroid Build Coastguard Worker }
2167*5e7646d2SAndroid Build Coastguard Worker data->num_monitor_expects = 0;
2168*5e7646d2SAndroid Build Coastguard Worker
2169*5e7646d2SAndroid Build Coastguard Worker return (data->ignore_errors || data->prev_pass);
2170*5e7646d2SAndroid Build Coastguard Worker }
2171*5e7646d2SAndroid Build Coastguard Worker
2172*5e7646d2SAndroid Build Coastguard Worker
2173*5e7646d2SAndroid Build Coastguard Worker /*
2174*5e7646d2SAndroid Build Coastguard Worker * 'do_tests()' - Do tests as specified in the test file.
2175*5e7646d2SAndroid Build Coastguard Worker */
2176*5e7646d2SAndroid Build Coastguard Worker
2177*5e7646d2SAndroid Build Coastguard Worker static int /* O - 1 on success, 0 on failure */
do_tests(const char * testfile,ipptool_test_t * data)2178*5e7646d2SAndroid Build Coastguard Worker do_tests(const char *testfile, /* I - Test file to use */
2179*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t *data) /* I - Test data */
2180*5e7646d2SAndroid Build Coastguard Worker {
2181*5e7646d2SAndroid Build Coastguard Worker http_encryption_t encryption; /* Encryption mode */
2182*5e7646d2SAndroid Build Coastguard Worker
2183*5e7646d2SAndroid Build Coastguard Worker
2184*5e7646d2SAndroid Build Coastguard Worker /*
2185*5e7646d2SAndroid Build Coastguard Worker * Connect to the printer/server...
2186*5e7646d2SAndroid Build Coastguard Worker */
2187*5e7646d2SAndroid Build Coastguard Worker
2188*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(data->vars->scheme, "https") || !_cups_strcasecmp(data->vars->scheme, "ipps") || data->vars->port == 443)
2189*5e7646d2SAndroid Build Coastguard Worker encryption = HTTP_ENCRYPTION_ALWAYS;
2190*5e7646d2SAndroid Build Coastguard Worker else
2191*5e7646d2SAndroid Build Coastguard Worker encryption = data->encryption;
2192*5e7646d2SAndroid Build Coastguard Worker
2193*5e7646d2SAndroid Build Coastguard Worker if ((data->http = httpConnect2(data->vars->host, data->vars->port, NULL, data->family, encryption, 1, 30000, NULL)) == NULL)
2194*5e7646d2SAndroid Build Coastguard Worker {
2195*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Unable to connect to \"%s\" on port %d - %s", data->vars->host, data->vars->port, cupsLastErrorString());
2196*5e7646d2SAndroid Build Coastguard Worker return (0);
2197*5e7646d2SAndroid Build Coastguard Worker }
2198*5e7646d2SAndroid Build Coastguard Worker
2199*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
2200*5e7646d2SAndroid Build Coastguard Worker httpSetDefaultField(data->http, HTTP_FIELD_ACCEPT_ENCODING, "deflate, gzip, identity");
2201*5e7646d2SAndroid Build Coastguard Worker #else
2202*5e7646d2SAndroid Build Coastguard Worker httpSetDefaultField(data->http, HTTP_FIELD_ACCEPT_ENCODING, "identity");
2203*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
2204*5e7646d2SAndroid Build Coastguard Worker
2205*5e7646d2SAndroid Build Coastguard Worker if (data->timeout > 0.0)
2206*5e7646d2SAndroid Build Coastguard Worker httpSetTimeout(data->http, data->timeout, timeout_cb, NULL);
2207*5e7646d2SAndroid Build Coastguard Worker
2208*5e7646d2SAndroid Build Coastguard Worker /*
2209*5e7646d2SAndroid Build Coastguard Worker * Run tests...
2210*5e7646d2SAndroid Build Coastguard Worker */
2211*5e7646d2SAndroid Build Coastguard Worker
2212*5e7646d2SAndroid Build Coastguard Worker _ippFileParse(data->vars, testfile, (void *)data);
2213*5e7646d2SAndroid Build Coastguard Worker
2214*5e7646d2SAndroid Build Coastguard Worker /*
2215*5e7646d2SAndroid Build Coastguard Worker * Close connection and return...
2216*5e7646d2SAndroid Build Coastguard Worker */
2217*5e7646d2SAndroid Build Coastguard Worker
2218*5e7646d2SAndroid Build Coastguard Worker httpClose(data->http);
2219*5e7646d2SAndroid Build Coastguard Worker data->http = NULL;
2220*5e7646d2SAndroid Build Coastguard Worker
2221*5e7646d2SAndroid Build Coastguard Worker return (data->pass);
2222*5e7646d2SAndroid Build Coastguard Worker }
2223*5e7646d2SAndroid Build Coastguard Worker
2224*5e7646d2SAndroid Build Coastguard Worker
2225*5e7646d2SAndroid Build Coastguard Worker /*
2226*5e7646d2SAndroid Build Coastguard Worker * 'error_cb()' - Print/add an error message.
2227*5e7646d2SAndroid Build Coastguard Worker */
2228*5e7646d2SAndroid Build Coastguard Worker
2229*5e7646d2SAndroid Build Coastguard Worker static int /* O - 1 to continue, 0 to stop */
error_cb(_ipp_file_t * f,ipptool_test_t * data,const char * error)2230*5e7646d2SAndroid Build Coastguard Worker error_cb(_ipp_file_t *f, /* I - IPP file data */
2231*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t *data, /* I - Test data */
2232*5e7646d2SAndroid Build Coastguard Worker const char *error) /* I - Error message */
2233*5e7646d2SAndroid Build Coastguard Worker {
2234*5e7646d2SAndroid Build Coastguard Worker (void)f;
2235*5e7646d2SAndroid Build Coastguard Worker
2236*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "%s", error);
2237*5e7646d2SAndroid Build Coastguard Worker
2238*5e7646d2SAndroid Build Coastguard Worker return (1);
2239*5e7646d2SAndroid Build Coastguard Worker }
2240*5e7646d2SAndroid Build Coastguard Worker
2241*5e7646d2SAndroid Build Coastguard Worker
2242*5e7646d2SAndroid Build Coastguard Worker /*
2243*5e7646d2SAndroid Build Coastguard Worker * 'expect_matches()' - Return true if the tag matches the specification.
2244*5e7646d2SAndroid Build Coastguard Worker */
2245*5e7646d2SAndroid Build Coastguard Worker
2246*5e7646d2SAndroid Build Coastguard Worker static int /* O - 1 if matches, 0 otherwise */
expect_matches(ipptool_expect_t * expect,ipp_attribute_t * attr)2247*5e7646d2SAndroid Build Coastguard Worker expect_matches(
2248*5e7646d2SAndroid Build Coastguard Worker ipptool_expect_t *expect, /* I - Expected attribute */
2249*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr) /* I - Attribute */
2250*5e7646d2SAndroid Build Coastguard Worker {
2251*5e7646d2SAndroid Build Coastguard Worker int i, /* Looping var */
2252*5e7646d2SAndroid Build Coastguard Worker count, /* Number of values */
2253*5e7646d2SAndroid Build Coastguard Worker match; /* Match? */
2254*5e7646d2SAndroid Build Coastguard Worker char *of_type, /* Type name to match */
2255*5e7646d2SAndroid Build Coastguard Worker *paren, /* Pointer to opening parenthesis */
2256*5e7646d2SAndroid Build Coastguard Worker *next, /* Next name to match */
2257*5e7646d2SAndroid Build Coastguard Worker sep; /* Separator character */
2258*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag; /* Syntax/value tag */
2259*5e7646d2SAndroid Build Coastguard Worker int lower, upper; /* Lower and upper bounds for syntax */
2260*5e7646d2SAndroid Build Coastguard Worker
2261*5e7646d2SAndroid Build Coastguard Worker
2262*5e7646d2SAndroid Build Coastguard Worker /*
2263*5e7646d2SAndroid Build Coastguard Worker * If we don't expect a particular type, return immediately...
2264*5e7646d2SAndroid Build Coastguard Worker */
2265*5e7646d2SAndroid Build Coastguard Worker
2266*5e7646d2SAndroid Build Coastguard Worker if (!expect->of_type)
2267*5e7646d2SAndroid Build Coastguard Worker return (1);
2268*5e7646d2SAndroid Build Coastguard Worker
2269*5e7646d2SAndroid Build Coastguard Worker /*
2270*5e7646d2SAndroid Build Coastguard Worker * Parse the "of_type" value since the string can contain multiple attribute
2271*5e7646d2SAndroid Build Coastguard Worker * types separated by "," or "|"...
2272*5e7646d2SAndroid Build Coastguard Worker */
2273*5e7646d2SAndroid Build Coastguard Worker
2274*5e7646d2SAndroid Build Coastguard Worker value_tag = ippGetValueTag(attr);
2275*5e7646d2SAndroid Build Coastguard Worker count = ippGetCount(attr);
2276*5e7646d2SAndroid Build Coastguard Worker
2277*5e7646d2SAndroid Build Coastguard Worker for (of_type = expect->of_type, match = 0; !match && *of_type; of_type = next)
2278*5e7646d2SAndroid Build Coastguard Worker {
2279*5e7646d2SAndroid Build Coastguard Worker /*
2280*5e7646d2SAndroid Build Coastguard Worker * Find the next separator, and set it (temporarily) to nul if present.
2281*5e7646d2SAndroid Build Coastguard Worker */
2282*5e7646d2SAndroid Build Coastguard Worker
2283*5e7646d2SAndroid Build Coastguard Worker for (next = of_type; *next && *next != '|' && *next != ','; next ++);
2284*5e7646d2SAndroid Build Coastguard Worker
2285*5e7646d2SAndroid Build Coastguard Worker if ((sep = *next) != '\0')
2286*5e7646d2SAndroid Build Coastguard Worker *next = '\0';
2287*5e7646d2SAndroid Build Coastguard Worker
2288*5e7646d2SAndroid Build Coastguard Worker /*
2289*5e7646d2SAndroid Build Coastguard Worker * Support some meta-types to make it easier to write the test file.
2290*5e7646d2SAndroid Build Coastguard Worker */
2291*5e7646d2SAndroid Build Coastguard Worker
2292*5e7646d2SAndroid Build Coastguard Worker if ((paren = strchr(of_type, '(')) != NULL)
2293*5e7646d2SAndroid Build Coastguard Worker {
2294*5e7646d2SAndroid Build Coastguard Worker char *ptr; // Pointer into syntax string
2295*5e7646d2SAndroid Build Coastguard Worker
2296*5e7646d2SAndroid Build Coastguard Worker *paren = '\0';
2297*5e7646d2SAndroid Build Coastguard Worker
2298*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(paren + 1, "MIN:", 4))
2299*5e7646d2SAndroid Build Coastguard Worker {
2300*5e7646d2SAndroid Build Coastguard Worker lower = INT_MIN;
2301*5e7646d2SAndroid Build Coastguard Worker ptr = paren + 5;
2302*5e7646d2SAndroid Build Coastguard Worker }
2303*5e7646d2SAndroid Build Coastguard Worker else if ((ptr = strchr(paren + 1, ':')) != NULL)
2304*5e7646d2SAndroid Build Coastguard Worker {
2305*5e7646d2SAndroid Build Coastguard Worker lower = atoi(paren + 1);
2306*5e7646d2SAndroid Build Coastguard Worker }
2307*5e7646d2SAndroid Build Coastguard Worker else
2308*5e7646d2SAndroid Build Coastguard Worker {
2309*5e7646d2SAndroid Build Coastguard Worker lower = 0;
2310*5e7646d2SAndroid Build Coastguard Worker ptr = paren + 1;
2311*5e7646d2SAndroid Build Coastguard Worker }
2312*5e7646d2SAndroid Build Coastguard Worker
2313*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(ptr, "MAX)"))
2314*5e7646d2SAndroid Build Coastguard Worker upper = INT_MAX;
2315*5e7646d2SAndroid Build Coastguard Worker else
2316*5e7646d2SAndroid Build Coastguard Worker upper = atoi(ptr);
2317*5e7646d2SAndroid Build Coastguard Worker }
2318*5e7646d2SAndroid Build Coastguard Worker else
2319*5e7646d2SAndroid Build Coastguard Worker {
2320*5e7646d2SAndroid Build Coastguard Worker lower = INT_MIN;
2321*5e7646d2SAndroid Build Coastguard Worker upper = INT_MAX;
2322*5e7646d2SAndroid Build Coastguard Worker }
2323*5e7646d2SAndroid Build Coastguard Worker
2324*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(of_type, "text"))
2325*5e7646d2SAndroid Build Coastguard Worker {
2326*5e7646d2SAndroid Build Coastguard Worker if (upper == INT_MAX)
2327*5e7646d2SAndroid Build Coastguard Worker upper = 1023;
2328*5e7646d2SAndroid Build Coastguard Worker
2329*5e7646d2SAndroid Build Coastguard Worker if (value_tag == IPP_TAG_TEXTLANG || value_tag == IPP_TAG_TEXT)
2330*5e7646d2SAndroid Build Coastguard Worker {
2331*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
2332*5e7646d2SAndroid Build Coastguard Worker {
2333*5e7646d2SAndroid Build Coastguard Worker if (strlen(ippGetString(attr, i, NULL)) > (size_t)upper)
2334*5e7646d2SAndroid Build Coastguard Worker break;
2335*5e7646d2SAndroid Build Coastguard Worker }
2336*5e7646d2SAndroid Build Coastguard Worker
2337*5e7646d2SAndroid Build Coastguard Worker match = (i == count);
2338*5e7646d2SAndroid Build Coastguard Worker }
2339*5e7646d2SAndroid Build Coastguard Worker }
2340*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(of_type, "name"))
2341*5e7646d2SAndroid Build Coastguard Worker {
2342*5e7646d2SAndroid Build Coastguard Worker if (upper == INT_MAX)
2343*5e7646d2SAndroid Build Coastguard Worker upper = 255;
2344*5e7646d2SAndroid Build Coastguard Worker
2345*5e7646d2SAndroid Build Coastguard Worker if (value_tag == IPP_TAG_NAMELANG || value_tag == IPP_TAG_NAME)
2346*5e7646d2SAndroid Build Coastguard Worker {
2347*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
2348*5e7646d2SAndroid Build Coastguard Worker {
2349*5e7646d2SAndroid Build Coastguard Worker if (strlen(ippGetString(attr, i, NULL)) > (size_t)upper)
2350*5e7646d2SAndroid Build Coastguard Worker break;
2351*5e7646d2SAndroid Build Coastguard Worker }
2352*5e7646d2SAndroid Build Coastguard Worker
2353*5e7646d2SAndroid Build Coastguard Worker match = (i == count);
2354*5e7646d2SAndroid Build Coastguard Worker }
2355*5e7646d2SAndroid Build Coastguard Worker }
2356*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(of_type, "collection"))
2357*5e7646d2SAndroid Build Coastguard Worker {
2358*5e7646d2SAndroid Build Coastguard Worker match = value_tag == IPP_TAG_BEGIN_COLLECTION;
2359*5e7646d2SAndroid Build Coastguard Worker }
2360*5e7646d2SAndroid Build Coastguard Worker else if (value_tag == ippTagValue(of_type))
2361*5e7646d2SAndroid Build Coastguard Worker {
2362*5e7646d2SAndroid Build Coastguard Worker switch (value_tag)
2363*5e7646d2SAndroid Build Coastguard Worker {
2364*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
2365*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
2366*5e7646d2SAndroid Build Coastguard Worker if (upper == INT_MAX)
2367*5e7646d2SAndroid Build Coastguard Worker {
2368*5e7646d2SAndroid Build Coastguard Worker if (value_tag == IPP_TAG_KEYWORD)
2369*5e7646d2SAndroid Build Coastguard Worker upper = 255;
2370*5e7646d2SAndroid Build Coastguard Worker else
2371*5e7646d2SAndroid Build Coastguard Worker upper = 1023;
2372*5e7646d2SAndroid Build Coastguard Worker }
2373*5e7646d2SAndroid Build Coastguard Worker
2374*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
2375*5e7646d2SAndroid Build Coastguard Worker {
2376*5e7646d2SAndroid Build Coastguard Worker if (strlen(ippGetString(attr, i, NULL)) > (size_t)upper)
2377*5e7646d2SAndroid Build Coastguard Worker break;
2378*5e7646d2SAndroid Build Coastguard Worker }
2379*5e7646d2SAndroid Build Coastguard Worker
2380*5e7646d2SAndroid Build Coastguard Worker match = (i == count);
2381*5e7646d2SAndroid Build Coastguard Worker break;
2382*5e7646d2SAndroid Build Coastguard Worker
2383*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_STRING :
2384*5e7646d2SAndroid Build Coastguard Worker if (upper == INT_MAX)
2385*5e7646d2SAndroid Build Coastguard Worker upper = 1023;
2386*5e7646d2SAndroid Build Coastguard Worker
2387*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
2388*5e7646d2SAndroid Build Coastguard Worker {
2389*5e7646d2SAndroid Build Coastguard Worker int datalen; // Length of octetString value
2390*5e7646d2SAndroid Build Coastguard Worker
2391*5e7646d2SAndroid Build Coastguard Worker ippGetOctetString(attr, i, &datalen);
2392*5e7646d2SAndroid Build Coastguard Worker
2393*5e7646d2SAndroid Build Coastguard Worker if (datalen > upper)
2394*5e7646d2SAndroid Build Coastguard Worker break;
2395*5e7646d2SAndroid Build Coastguard Worker }
2396*5e7646d2SAndroid Build Coastguard Worker
2397*5e7646d2SAndroid Build Coastguard Worker match = (i == count);
2398*5e7646d2SAndroid Build Coastguard Worker break;
2399*5e7646d2SAndroid Build Coastguard Worker
2400*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
2401*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
2402*5e7646d2SAndroid Build Coastguard Worker {
2403*5e7646d2SAndroid Build Coastguard Worker int value = ippGetInteger(attr, i);
2404*5e7646d2SAndroid Build Coastguard Worker // Integer value
2405*5e7646d2SAndroid Build Coastguard Worker
2406*5e7646d2SAndroid Build Coastguard Worker if (value < lower || value > upper)
2407*5e7646d2SAndroid Build Coastguard Worker break;
2408*5e7646d2SAndroid Build Coastguard Worker }
2409*5e7646d2SAndroid Build Coastguard Worker
2410*5e7646d2SAndroid Build Coastguard Worker match = (i == count);
2411*5e7646d2SAndroid Build Coastguard Worker break;
2412*5e7646d2SAndroid Build Coastguard Worker
2413*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
2414*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
2415*5e7646d2SAndroid Build Coastguard Worker {
2416*5e7646d2SAndroid Build Coastguard Worker int vupper, vlower = ippGetRange(attr, i, &vupper);
2417*5e7646d2SAndroid Build Coastguard Worker // Range value
2418*5e7646d2SAndroid Build Coastguard Worker
2419*5e7646d2SAndroid Build Coastguard Worker if (vlower < lower || vlower > upper || vupper < lower || vupper > upper)
2420*5e7646d2SAndroid Build Coastguard Worker break;
2421*5e7646d2SAndroid Build Coastguard Worker }
2422*5e7646d2SAndroid Build Coastguard Worker
2423*5e7646d2SAndroid Build Coastguard Worker match = (i == count);
2424*5e7646d2SAndroid Build Coastguard Worker break;
2425*5e7646d2SAndroid Build Coastguard Worker
2426*5e7646d2SAndroid Build Coastguard Worker default :
2427*5e7646d2SAndroid Build Coastguard Worker // No other constraints, so this is a match
2428*5e7646d2SAndroid Build Coastguard Worker match = 1;
2429*5e7646d2SAndroid Build Coastguard Worker break;
2430*5e7646d2SAndroid Build Coastguard Worker }
2431*5e7646d2SAndroid Build Coastguard Worker }
2432*5e7646d2SAndroid Build Coastguard Worker
2433*5e7646d2SAndroid Build Coastguard Worker /*
2434*5e7646d2SAndroid Build Coastguard Worker * Restore the separators if we have them...
2435*5e7646d2SAndroid Build Coastguard Worker */
2436*5e7646d2SAndroid Build Coastguard Worker
2437*5e7646d2SAndroid Build Coastguard Worker if (paren)
2438*5e7646d2SAndroid Build Coastguard Worker *paren = '(';
2439*5e7646d2SAndroid Build Coastguard Worker
2440*5e7646d2SAndroid Build Coastguard Worker if (sep)
2441*5e7646d2SAndroid Build Coastguard Worker *next++ = sep;
2442*5e7646d2SAndroid Build Coastguard Worker }
2443*5e7646d2SAndroid Build Coastguard Worker
2444*5e7646d2SAndroid Build Coastguard Worker return (match);
2445*5e7646d2SAndroid Build Coastguard Worker }
2446*5e7646d2SAndroid Build Coastguard Worker
2447*5e7646d2SAndroid Build Coastguard Worker
2448*5e7646d2SAndroid Build Coastguard Worker /*
2449*5e7646d2SAndroid Build Coastguard Worker * 'get_filename()' - Get a filename based on the current test file.
2450*5e7646d2SAndroid Build Coastguard Worker */
2451*5e7646d2SAndroid Build Coastguard Worker
2452*5e7646d2SAndroid Build Coastguard Worker static char * /* O - Filename */
get_filename(const char * testfile,char * dst,const char * src,size_t dstsize)2453*5e7646d2SAndroid Build Coastguard Worker get_filename(const char *testfile, /* I - Current test file */
2454*5e7646d2SAndroid Build Coastguard Worker char *dst, /* I - Destination filename */
2455*5e7646d2SAndroid Build Coastguard Worker const char *src, /* I - Source filename */
2456*5e7646d2SAndroid Build Coastguard Worker size_t dstsize) /* I - Size of destination buffer */
2457*5e7646d2SAndroid Build Coastguard Worker {
2458*5e7646d2SAndroid Build Coastguard Worker char *dstptr; /* Pointer into destination */
2459*5e7646d2SAndroid Build Coastguard Worker _cups_globals_t *cg = _cupsGlobals();
2460*5e7646d2SAndroid Build Coastguard Worker /* Global data */
2461*5e7646d2SAndroid Build Coastguard Worker
2462*5e7646d2SAndroid Build Coastguard Worker
2463*5e7646d2SAndroid Build Coastguard Worker if (*src == '<' && src[strlen(src) - 1] == '>')
2464*5e7646d2SAndroid Build Coastguard Worker {
2465*5e7646d2SAndroid Build Coastguard Worker /*
2466*5e7646d2SAndroid Build Coastguard Worker * Map <filename> to CUPS_DATADIR/ipptool/filename...
2467*5e7646d2SAndroid Build Coastguard Worker */
2468*5e7646d2SAndroid Build Coastguard Worker
2469*5e7646d2SAndroid Build Coastguard Worker snprintf(dst, dstsize, "%s/ipptool/%s", cg->cups_datadir, src + 1);
2470*5e7646d2SAndroid Build Coastguard Worker dstptr = dst + strlen(dst) - 1;
2471*5e7646d2SAndroid Build Coastguard Worker if (*dstptr == '>')
2472*5e7646d2SAndroid Build Coastguard Worker *dstptr = '\0';
2473*5e7646d2SAndroid Build Coastguard Worker }
2474*5e7646d2SAndroid Build Coastguard Worker else if (!access(src, R_OK) || *src == '/'
2475*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
2476*5e7646d2SAndroid Build Coastguard Worker || (isalpha(*src & 255) && src[1] == ':')
2477*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
2478*5e7646d2SAndroid Build Coastguard Worker )
2479*5e7646d2SAndroid Build Coastguard Worker {
2480*5e7646d2SAndroid Build Coastguard Worker /*
2481*5e7646d2SAndroid Build Coastguard Worker * Use the path as-is...
2482*5e7646d2SAndroid Build Coastguard Worker */
2483*5e7646d2SAndroid Build Coastguard Worker
2484*5e7646d2SAndroid Build Coastguard Worker strlcpy(dst, src, dstsize);
2485*5e7646d2SAndroid Build Coastguard Worker }
2486*5e7646d2SAndroid Build Coastguard Worker else
2487*5e7646d2SAndroid Build Coastguard Worker {
2488*5e7646d2SAndroid Build Coastguard Worker /*
2489*5e7646d2SAndroid Build Coastguard Worker * Make path relative to testfile...
2490*5e7646d2SAndroid Build Coastguard Worker */
2491*5e7646d2SAndroid Build Coastguard Worker
2492*5e7646d2SAndroid Build Coastguard Worker strlcpy(dst, testfile, dstsize);
2493*5e7646d2SAndroid Build Coastguard Worker if ((dstptr = strrchr(dst, '/')) != NULL)
2494*5e7646d2SAndroid Build Coastguard Worker dstptr ++;
2495*5e7646d2SAndroid Build Coastguard Worker else
2496*5e7646d2SAndroid Build Coastguard Worker dstptr = dst; /* Should never happen */
2497*5e7646d2SAndroid Build Coastguard Worker
2498*5e7646d2SAndroid Build Coastguard Worker strlcpy(dstptr, src, dstsize - (size_t)(dstptr - dst));
2499*5e7646d2SAndroid Build Coastguard Worker
2500*5e7646d2SAndroid Build Coastguard Worker #if _WIN32
2501*5e7646d2SAndroid Build Coastguard Worker if (_access(dst, 0))
2502*5e7646d2SAndroid Build Coastguard Worker {
2503*5e7646d2SAndroid Build Coastguard Worker /*
2504*5e7646d2SAndroid Build Coastguard Worker * Not available relative to the testfile, see if it can be found on the
2505*5e7646d2SAndroid Build Coastguard Worker * desktop...
2506*5e7646d2SAndroid Build Coastguard Worker */
2507*5e7646d2SAndroid Build Coastguard Worker const char *userprofile = getenv("USERPROFILE");
2508*5e7646d2SAndroid Build Coastguard Worker /* User home directory */
2509*5e7646d2SAndroid Build Coastguard Worker
2510*5e7646d2SAndroid Build Coastguard Worker if (userprofile)
2511*5e7646d2SAndroid Build Coastguard Worker snprintf(dst, dstsize, "%s/Desktop/%s", userprofile, src);
2512*5e7646d2SAndroid Build Coastguard Worker }
2513*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
2514*5e7646d2SAndroid Build Coastguard Worker }
2515*5e7646d2SAndroid Build Coastguard Worker
2516*5e7646d2SAndroid Build Coastguard Worker return (dst);
2517*5e7646d2SAndroid Build Coastguard Worker }
2518*5e7646d2SAndroid Build Coastguard Worker
2519*5e7646d2SAndroid Build Coastguard Worker
2520*5e7646d2SAndroid Build Coastguard Worker /*
2521*5e7646d2SAndroid Build Coastguard Worker * 'get_string()' - Get a pointer to a string value or the portion of interest.
2522*5e7646d2SAndroid Build Coastguard Worker */
2523*5e7646d2SAndroid Build Coastguard Worker
2524*5e7646d2SAndroid Build Coastguard Worker static const char * /* O - Pointer to string */
get_string(ipp_attribute_t * attr,int element,int flags,char * buffer,size_t bufsize)2525*5e7646d2SAndroid Build Coastguard Worker get_string(ipp_attribute_t *attr, /* I - IPP attribute */
2526*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Element to fetch */
2527*5e7646d2SAndroid Build Coastguard Worker int flags, /* I - Value ("with") flags */
2528*5e7646d2SAndroid Build Coastguard Worker char *buffer, /* I - Temporary buffer */
2529*5e7646d2SAndroid Build Coastguard Worker size_t bufsize) /* I - Size of temporary buffer */
2530*5e7646d2SAndroid Build Coastguard Worker {
2531*5e7646d2SAndroid Build Coastguard Worker const char *value; /* Value */
2532*5e7646d2SAndroid Build Coastguard Worker char *ptr, /* Pointer into value */
2533*5e7646d2SAndroid Build Coastguard Worker scheme[256], /* URI scheme */
2534*5e7646d2SAndroid Build Coastguard Worker userpass[256], /* Username/password */
2535*5e7646d2SAndroid Build Coastguard Worker hostname[256], /* Hostname */
2536*5e7646d2SAndroid Build Coastguard Worker resource[1024]; /* Resource */
2537*5e7646d2SAndroid Build Coastguard Worker int port; /* Port number */
2538*5e7646d2SAndroid Build Coastguard Worker
2539*5e7646d2SAndroid Build Coastguard Worker
2540*5e7646d2SAndroid Build Coastguard Worker value = ippGetString(attr, element, NULL);
2541*5e7646d2SAndroid Build Coastguard Worker
2542*5e7646d2SAndroid Build Coastguard Worker if (flags & IPPTOOL_WITH_HOSTNAME)
2543*5e7646d2SAndroid Build Coastguard Worker {
2544*5e7646d2SAndroid Build Coastguard Worker if (httpSeparateURI(HTTP_URI_CODING_ALL, value, scheme, sizeof(scheme), userpass, sizeof(userpass), buffer, (int)bufsize, &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
2545*5e7646d2SAndroid Build Coastguard Worker buffer[0] = '\0';
2546*5e7646d2SAndroid Build Coastguard Worker
2547*5e7646d2SAndroid Build Coastguard Worker ptr = buffer + strlen(buffer) - 1;
2548*5e7646d2SAndroid Build Coastguard Worker if (ptr >= buffer && *ptr == '.')
2549*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0'; /* Drop trailing "." */
2550*5e7646d2SAndroid Build Coastguard Worker
2551*5e7646d2SAndroid Build Coastguard Worker return (buffer);
2552*5e7646d2SAndroid Build Coastguard Worker }
2553*5e7646d2SAndroid Build Coastguard Worker else if (flags & IPPTOOL_WITH_RESOURCE)
2554*5e7646d2SAndroid Build Coastguard Worker {
2555*5e7646d2SAndroid Build Coastguard Worker if (httpSeparateURI(HTTP_URI_CODING_ALL, value, scheme, sizeof(scheme), userpass, sizeof(userpass), hostname, sizeof(hostname), &port, buffer, (int)bufsize) < HTTP_URI_STATUS_OK)
2556*5e7646d2SAndroid Build Coastguard Worker buffer[0] = '\0';
2557*5e7646d2SAndroid Build Coastguard Worker
2558*5e7646d2SAndroid Build Coastguard Worker return (buffer);
2559*5e7646d2SAndroid Build Coastguard Worker }
2560*5e7646d2SAndroid Build Coastguard Worker else if (flags & IPPTOOL_WITH_SCHEME)
2561*5e7646d2SAndroid Build Coastguard Worker {
2562*5e7646d2SAndroid Build Coastguard Worker if (httpSeparateURI(HTTP_URI_CODING_ALL, value, buffer, (int)bufsize, userpass, sizeof(userpass), hostname, sizeof(hostname), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
2563*5e7646d2SAndroid Build Coastguard Worker buffer[0] = '\0';
2564*5e7646d2SAndroid Build Coastguard Worker
2565*5e7646d2SAndroid Build Coastguard Worker return (buffer);
2566*5e7646d2SAndroid Build Coastguard Worker }
2567*5e7646d2SAndroid Build Coastguard Worker else if (ippGetValueTag(attr) == IPP_TAG_URI && (!strncmp(value, "ipp://", 6) || !strncmp(value, "http://", 7) || !strncmp(value, "ipps://", 7) || !strncmp(value, "https://", 8)))
2568*5e7646d2SAndroid Build Coastguard Worker {
2569*5e7646d2SAndroid Build Coastguard Worker http_uri_status_t status = httpSeparateURI(HTTP_URI_CODING_ALL, value, scheme, sizeof(scheme), userpass, sizeof(userpass), hostname, sizeof(hostname), &port, resource, sizeof(resource));
2570*5e7646d2SAndroid Build Coastguard Worker
2571*5e7646d2SAndroid Build Coastguard Worker if (status < HTTP_URI_STATUS_OK)
2572*5e7646d2SAndroid Build Coastguard Worker {
2573*5e7646d2SAndroid Build Coastguard Worker /*
2574*5e7646d2SAndroid Build Coastguard Worker * Bad URI...
2575*5e7646d2SAndroid Build Coastguard Worker */
2576*5e7646d2SAndroid Build Coastguard Worker
2577*5e7646d2SAndroid Build Coastguard Worker buffer[0] = '\0';
2578*5e7646d2SAndroid Build Coastguard Worker }
2579*5e7646d2SAndroid Build Coastguard Worker else
2580*5e7646d2SAndroid Build Coastguard Worker {
2581*5e7646d2SAndroid Build Coastguard Worker /*
2582*5e7646d2SAndroid Build Coastguard Worker * Normalize URI with no trailing dot...
2583*5e7646d2SAndroid Build Coastguard Worker */
2584*5e7646d2SAndroid Build Coastguard Worker
2585*5e7646d2SAndroid Build Coastguard Worker if ((ptr = hostname + strlen(hostname) - 1) >= hostname && *ptr == '.')
2586*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
2587*5e7646d2SAndroid Build Coastguard Worker
2588*5e7646d2SAndroid Build Coastguard Worker httpAssembleURI(HTTP_URI_CODING_ALL, buffer, (int)bufsize, scheme, userpass, hostname, port, resource);
2589*5e7646d2SAndroid Build Coastguard Worker }
2590*5e7646d2SAndroid Build Coastguard Worker
2591*5e7646d2SAndroid Build Coastguard Worker return (buffer);
2592*5e7646d2SAndroid Build Coastguard Worker }
2593*5e7646d2SAndroid Build Coastguard Worker else
2594*5e7646d2SAndroid Build Coastguard Worker return (value);
2595*5e7646d2SAndroid Build Coastguard Worker }
2596*5e7646d2SAndroid Build Coastguard Worker
2597*5e7646d2SAndroid Build Coastguard Worker
2598*5e7646d2SAndroid Build Coastguard Worker /*
2599*5e7646d2SAndroid Build Coastguard Worker * 'init_data()' - Initialize test data.
2600*5e7646d2SAndroid Build Coastguard Worker */
2601*5e7646d2SAndroid Build Coastguard Worker
2602*5e7646d2SAndroid Build Coastguard Worker static void
init_data(ipptool_test_t * data)2603*5e7646d2SAndroid Build Coastguard Worker init_data(ipptool_test_t *data) /* I - Data */
2604*5e7646d2SAndroid Build Coastguard Worker {
2605*5e7646d2SAndroid Build Coastguard Worker memset(data, 0, sizeof(ipptool_test_t));
2606*5e7646d2SAndroid Build Coastguard Worker
2607*5e7646d2SAndroid Build Coastguard Worker data->output = IPPTOOL_OUTPUT_LIST;
2608*5e7646d2SAndroid Build Coastguard Worker data->outfile = cupsFileStdout();
2609*5e7646d2SAndroid Build Coastguard Worker data->family = AF_UNSPEC;
2610*5e7646d2SAndroid Build Coastguard Worker data->def_transfer = IPPTOOL_TRANSFER_AUTO;
2611*5e7646d2SAndroid Build Coastguard Worker data->def_version = 11;
2612*5e7646d2SAndroid Build Coastguard Worker data->errors = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
2613*5e7646d2SAndroid Build Coastguard Worker data->pass = 1;
2614*5e7646d2SAndroid Build Coastguard Worker data->prev_pass = 1;
2615*5e7646d2SAndroid Build Coastguard Worker data->request_id = (CUPS_RAND() % 1000) * 137;
2616*5e7646d2SAndroid Build Coastguard Worker data->show_header = 1;
2617*5e7646d2SAndroid Build Coastguard Worker }
2618*5e7646d2SAndroid Build Coastguard Worker
2619*5e7646d2SAndroid Build Coastguard Worker
2620*5e7646d2SAndroid Build Coastguard Worker /*
2621*5e7646d2SAndroid Build Coastguard Worker * 'iso_date()' - Return an ISO 8601 date/time string for the given IPP dateTime
2622*5e7646d2SAndroid Build Coastguard Worker * value.
2623*5e7646d2SAndroid Build Coastguard Worker */
2624*5e7646d2SAndroid Build Coastguard Worker
2625*5e7646d2SAndroid Build Coastguard Worker static char * /* O - ISO 8601 date/time string */
iso_date(const ipp_uchar_t * date)2626*5e7646d2SAndroid Build Coastguard Worker iso_date(const ipp_uchar_t *date) /* I - IPP (RFC 1903) date/time value */
2627*5e7646d2SAndroid Build Coastguard Worker {
2628*5e7646d2SAndroid Build Coastguard Worker time_t utctime; /* UTC time since 1970 */
2629*5e7646d2SAndroid Build Coastguard Worker struct tm utcdate; /* UTC date/time */
2630*5e7646d2SAndroid Build Coastguard Worker static char buffer[255]; /* String buffer */
2631*5e7646d2SAndroid Build Coastguard Worker
2632*5e7646d2SAndroid Build Coastguard Worker
2633*5e7646d2SAndroid Build Coastguard Worker utctime = ippDateToTime(date);
2634*5e7646d2SAndroid Build Coastguard Worker gmtime_r(&utctime, &utcdate);
2635*5e7646d2SAndroid Build Coastguard Worker
2636*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "%04d-%02d-%02dT%02d:%02d:%02dZ",
2637*5e7646d2SAndroid Build Coastguard Worker utcdate.tm_year + 1900, utcdate.tm_mon + 1, utcdate.tm_mday,
2638*5e7646d2SAndroid Build Coastguard Worker utcdate.tm_hour, utcdate.tm_min, utcdate.tm_sec);
2639*5e7646d2SAndroid Build Coastguard Worker
2640*5e7646d2SAndroid Build Coastguard Worker return (buffer);
2641*5e7646d2SAndroid Build Coastguard Worker }
2642*5e7646d2SAndroid Build Coastguard Worker
2643*5e7646d2SAndroid Build Coastguard Worker
2644*5e7646d2SAndroid Build Coastguard Worker /*
2645*5e7646d2SAndroid Build Coastguard Worker * 'parse_monitor_printer_state()' - Parse the MONITOR-PRINTER-STATE directive.
2646*5e7646d2SAndroid Build Coastguard Worker *
2647*5e7646d2SAndroid Build Coastguard Worker * MONITOR-PRINTER-STATE [printer-uri] {
2648*5e7646d2SAndroid Build Coastguard Worker * DELAY nnn
2649*5e7646d2SAndroid Build Coastguard Worker * EXPECT attribute-name ...
2650*5e7646d2SAndroid Build Coastguard Worker * }
2651*5e7646d2SAndroid Build Coastguard Worker */
2652*5e7646d2SAndroid Build Coastguard Worker
2653*5e7646d2SAndroid Build Coastguard Worker static int /* O - 1 to continue, 0 to stop */
parse_monitor_printer_state(_ipp_file_t * f,ipptool_test_t * data)2654*5e7646d2SAndroid Build Coastguard Worker parse_monitor_printer_state(
2655*5e7646d2SAndroid Build Coastguard Worker _ipp_file_t *f, /* I - IPP file data */
2656*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t *data) /* I - Test data */
2657*5e7646d2SAndroid Build Coastguard Worker {
2658*5e7646d2SAndroid Build Coastguard Worker char token[256], /* Token string */
2659*5e7646d2SAndroid Build Coastguard Worker name[1024], /* Name string */
2660*5e7646d2SAndroid Build Coastguard Worker temp[1024], /* Temporary string */
2661*5e7646d2SAndroid Build Coastguard Worker value[1024], /* Value string */
2662*5e7646d2SAndroid Build Coastguard Worker *ptr; /* Pointer into value */
2663*5e7646d2SAndroid Build Coastguard Worker
2664*5e7646d2SAndroid Build Coastguard Worker
2665*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
2666*5e7646d2SAndroid Build Coastguard Worker {
2667*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing printer URI on line %d of \"%s\".", f->linenum, f->filename);
2668*5e7646d2SAndroid Build Coastguard Worker return (0);
2669*5e7646d2SAndroid Build Coastguard Worker }
2670*5e7646d2SAndroid Build Coastguard Worker
2671*5e7646d2SAndroid Build Coastguard Worker if (strcmp(temp, "{"))
2672*5e7646d2SAndroid Build Coastguard Worker {
2673*5e7646d2SAndroid Build Coastguard Worker // Got a printer URI so copy it...
2674*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(data->vars, value, temp, sizeof(value));
2675*5e7646d2SAndroid Build Coastguard Worker data->monitor_uri = strdup(value);
2676*5e7646d2SAndroid Build Coastguard Worker
2677*5e7646d2SAndroid Build Coastguard Worker // Then see if we have an opening brace...
2678*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)) || strcmp(temp, "{"))
2679*5e7646d2SAndroid Build Coastguard Worker {
2680*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing opening brace on line %d of \"%s\".", f->linenum, f->filename);
2681*5e7646d2SAndroid Build Coastguard Worker return (0);
2682*5e7646d2SAndroid Build Coastguard Worker }
2683*5e7646d2SAndroid Build Coastguard Worker }
2684*5e7646d2SAndroid Build Coastguard Worker else
2685*5e7646d2SAndroid Build Coastguard Worker {
2686*5e7646d2SAndroid Build Coastguard Worker // Use the default printer URI...
2687*5e7646d2SAndroid Build Coastguard Worker data->monitor_uri = strdup(data->vars->uri);
2688*5e7646d2SAndroid Build Coastguard Worker }
2689*5e7646d2SAndroid Build Coastguard Worker
2690*5e7646d2SAndroid Build Coastguard Worker // Loop until we get a closing brace...
2691*5e7646d2SAndroid Build Coastguard Worker while (_ippFileReadToken(f, token, sizeof(token)))
2692*5e7646d2SAndroid Build Coastguard Worker {
2693*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(token, "COUNT") &&
2694*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "DEFINE-MATCH") &&
2695*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "DEFINE-NO-MATCH") &&
2696*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "DEFINE-VALUE") &&
2697*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "DISPLAY-MATCH") &&
2698*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "IF-DEFINED") &&
2699*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "IF-NOT-DEFINED") &&
2700*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "IN-GROUP") &&
2701*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "OF-TYPE") &&
2702*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "WITH-DISTINCT-VALUES") &&
2703*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "WITH-VALUE"))
2704*5e7646d2SAndroid Build Coastguard Worker data->last_expect = NULL;
2705*5e7646d2SAndroid Build Coastguard Worker
2706*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(token, "}"))
2707*5e7646d2SAndroid Build Coastguard Worker return (1);
2708*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "EXPECT"))
2709*5e7646d2SAndroid Build Coastguard Worker {
2710*5e7646d2SAndroid Build Coastguard Worker /*
2711*5e7646d2SAndroid Build Coastguard Worker * Expected attributes...
2712*5e7646d2SAndroid Build Coastguard Worker */
2713*5e7646d2SAndroid Build Coastguard Worker
2714*5e7646d2SAndroid Build Coastguard Worker if (data->num_monitor_expects >= (int)(sizeof(data->monitor_expects) / sizeof(data->monitor_expects[0])))
2715*5e7646d2SAndroid Build Coastguard Worker {
2716*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Too many EXPECT's on line %d of \"%s\".", f->linenum, f->filename);
2717*5e7646d2SAndroid Build Coastguard Worker return (0);
2718*5e7646d2SAndroid Build Coastguard Worker }
2719*5e7646d2SAndroid Build Coastguard Worker
2720*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, name, sizeof(name)))
2721*5e7646d2SAndroid Build Coastguard Worker {
2722*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing EXPECT name on line %d of \"%s\".", f->linenum, f->filename);
2723*5e7646d2SAndroid Build Coastguard Worker return (0);
2724*5e7646d2SAndroid Build Coastguard Worker }
2725*5e7646d2SAndroid Build Coastguard Worker
2726*5e7646d2SAndroid Build Coastguard Worker data->last_expect = data->monitor_expects + data->num_monitor_expects;
2727*5e7646d2SAndroid Build Coastguard Worker data->num_monitor_expects ++;
2728*5e7646d2SAndroid Build Coastguard Worker
2729*5e7646d2SAndroid Build Coastguard Worker memset(data->last_expect, 0, sizeof(ipptool_expect_t));
2730*5e7646d2SAndroid Build Coastguard Worker data->last_expect->repeat_limit = 1000;
2731*5e7646d2SAndroid Build Coastguard Worker
2732*5e7646d2SAndroid Build Coastguard Worker if (name[0] == '!')
2733*5e7646d2SAndroid Build Coastguard Worker {
2734*5e7646d2SAndroid Build Coastguard Worker data->last_expect->not_expect = 1;
2735*5e7646d2SAndroid Build Coastguard Worker data->last_expect->name = strdup(name + 1);
2736*5e7646d2SAndroid Build Coastguard Worker }
2737*5e7646d2SAndroid Build Coastguard Worker else if (name[0] == '?')
2738*5e7646d2SAndroid Build Coastguard Worker {
2739*5e7646d2SAndroid Build Coastguard Worker data->last_expect->optional = 1;
2740*5e7646d2SAndroid Build Coastguard Worker data->last_expect->name = strdup(name + 1);
2741*5e7646d2SAndroid Build Coastguard Worker }
2742*5e7646d2SAndroid Build Coastguard Worker else
2743*5e7646d2SAndroid Build Coastguard Worker data->last_expect->name = strdup(name);
2744*5e7646d2SAndroid Build Coastguard Worker }
2745*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "COUNT"))
2746*5e7646d2SAndroid Build Coastguard Worker {
2747*5e7646d2SAndroid Build Coastguard Worker int count; /* Count value */
2748*5e7646d2SAndroid Build Coastguard Worker
2749*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
2750*5e7646d2SAndroid Build Coastguard Worker {
2751*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing COUNT number on line %d of \"%s\".", f->linenum, f->filename);
2752*5e7646d2SAndroid Build Coastguard Worker return (0);
2753*5e7646d2SAndroid Build Coastguard Worker }
2754*5e7646d2SAndroid Build Coastguard Worker
2755*5e7646d2SAndroid Build Coastguard Worker if ((count = atoi(temp)) <= 0)
2756*5e7646d2SAndroid Build Coastguard Worker {
2757*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad COUNT \"%s\" on line %d of \"%s\".", temp, f->linenum, f->filename);
2758*5e7646d2SAndroid Build Coastguard Worker return (0);
2759*5e7646d2SAndroid Build Coastguard Worker }
2760*5e7646d2SAndroid Build Coastguard Worker
2761*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
2762*5e7646d2SAndroid Build Coastguard Worker {
2763*5e7646d2SAndroid Build Coastguard Worker data->last_expect->count = count;
2764*5e7646d2SAndroid Build Coastguard Worker }
2765*5e7646d2SAndroid Build Coastguard Worker else
2766*5e7646d2SAndroid Build Coastguard Worker {
2767*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "COUNT without a preceding EXPECT on line %d of \"%s\".", f->linenum, f->filename);
2768*5e7646d2SAndroid Build Coastguard Worker return (0);
2769*5e7646d2SAndroid Build Coastguard Worker }
2770*5e7646d2SAndroid Build Coastguard Worker }
2771*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "DEFINE-MATCH"))
2772*5e7646d2SAndroid Build Coastguard Worker {
2773*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
2774*5e7646d2SAndroid Build Coastguard Worker {
2775*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing DEFINE-MATCH variable on line %d of \"%s\".", f->linenum, f->filename);
2776*5e7646d2SAndroid Build Coastguard Worker return (0);
2777*5e7646d2SAndroid Build Coastguard Worker }
2778*5e7646d2SAndroid Build Coastguard Worker
2779*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
2780*5e7646d2SAndroid Build Coastguard Worker {
2781*5e7646d2SAndroid Build Coastguard Worker data->last_expect->define_match = strdup(temp);
2782*5e7646d2SAndroid Build Coastguard Worker }
2783*5e7646d2SAndroid Build Coastguard Worker else
2784*5e7646d2SAndroid Build Coastguard Worker {
2785*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "DEFINE-MATCH without a preceding EXPECT on line %d of \"%s\".", f->linenum, f->filename);
2786*5e7646d2SAndroid Build Coastguard Worker return (0);
2787*5e7646d2SAndroid Build Coastguard Worker }
2788*5e7646d2SAndroid Build Coastguard Worker }
2789*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "DEFINE-NO-MATCH"))
2790*5e7646d2SAndroid Build Coastguard Worker {
2791*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
2792*5e7646d2SAndroid Build Coastguard Worker {
2793*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing DEFINE-NO-MATCH variable on line %d of \"%s\".", f->linenum, f->filename);
2794*5e7646d2SAndroid Build Coastguard Worker return (0);
2795*5e7646d2SAndroid Build Coastguard Worker }
2796*5e7646d2SAndroid Build Coastguard Worker
2797*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
2798*5e7646d2SAndroid Build Coastguard Worker {
2799*5e7646d2SAndroid Build Coastguard Worker data->last_expect->define_no_match = strdup(temp);
2800*5e7646d2SAndroid Build Coastguard Worker }
2801*5e7646d2SAndroid Build Coastguard Worker else
2802*5e7646d2SAndroid Build Coastguard Worker {
2803*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "DEFINE-NO-MATCH without a preceding EXPECT on line %d of \"%s\".", f->linenum, f->filename);
2804*5e7646d2SAndroid Build Coastguard Worker return (0);
2805*5e7646d2SAndroid Build Coastguard Worker }
2806*5e7646d2SAndroid Build Coastguard Worker }
2807*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "DEFINE-VALUE"))
2808*5e7646d2SAndroid Build Coastguard Worker {
2809*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
2810*5e7646d2SAndroid Build Coastguard Worker {
2811*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing DEFINE-VALUE variable on line %d of \"%s\".", f->linenum, f->filename);
2812*5e7646d2SAndroid Build Coastguard Worker return (0);
2813*5e7646d2SAndroid Build Coastguard Worker }
2814*5e7646d2SAndroid Build Coastguard Worker
2815*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
2816*5e7646d2SAndroid Build Coastguard Worker {
2817*5e7646d2SAndroid Build Coastguard Worker data->last_expect->define_value = strdup(temp);
2818*5e7646d2SAndroid Build Coastguard Worker }
2819*5e7646d2SAndroid Build Coastguard Worker else
2820*5e7646d2SAndroid Build Coastguard Worker {
2821*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "DEFINE-VALUE without a preceding EXPECT on line %d of \"%s\".", f->linenum, f->filename);
2822*5e7646d2SAndroid Build Coastguard Worker return (0);
2823*5e7646d2SAndroid Build Coastguard Worker }
2824*5e7646d2SAndroid Build Coastguard Worker }
2825*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "DISPLAY-MATCH"))
2826*5e7646d2SAndroid Build Coastguard Worker {
2827*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
2828*5e7646d2SAndroid Build Coastguard Worker {
2829*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing DISPLAY-MATCH message on line %d of \"%s\".", f->linenum, f->filename);
2830*5e7646d2SAndroid Build Coastguard Worker return (0);
2831*5e7646d2SAndroid Build Coastguard Worker }
2832*5e7646d2SAndroid Build Coastguard Worker
2833*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
2834*5e7646d2SAndroid Build Coastguard Worker {
2835*5e7646d2SAndroid Build Coastguard Worker data->last_expect->display_match = strdup(temp);
2836*5e7646d2SAndroid Build Coastguard Worker }
2837*5e7646d2SAndroid Build Coastguard Worker else
2838*5e7646d2SAndroid Build Coastguard Worker {
2839*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "DISPLAY-MATCH without a preceding EXPECT on line %d of \"%s\".", f->linenum, f->filename);
2840*5e7646d2SAndroid Build Coastguard Worker return (0);
2841*5e7646d2SAndroid Build Coastguard Worker }
2842*5e7646d2SAndroid Build Coastguard Worker }
2843*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "DELAY"))
2844*5e7646d2SAndroid Build Coastguard Worker {
2845*5e7646d2SAndroid Build Coastguard Worker /*
2846*5e7646d2SAndroid Build Coastguard Worker * Delay before operation...
2847*5e7646d2SAndroid Build Coastguard Worker */
2848*5e7646d2SAndroid Build Coastguard Worker
2849*5e7646d2SAndroid Build Coastguard Worker double dval; /* Delay value */
2850*5e7646d2SAndroid Build Coastguard Worker
2851*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
2852*5e7646d2SAndroid Build Coastguard Worker {
2853*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing DELAY value on line %d of \"%s\".", f->linenum, f->filename);
2854*5e7646d2SAndroid Build Coastguard Worker return (0);
2855*5e7646d2SAndroid Build Coastguard Worker }
2856*5e7646d2SAndroid Build Coastguard Worker
2857*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(data->vars, value, temp, sizeof(value));
2858*5e7646d2SAndroid Build Coastguard Worker
2859*5e7646d2SAndroid Build Coastguard Worker if ((dval = _cupsStrScand(value, &ptr, localeconv())) < 0.0 || (*ptr && *ptr != ','))
2860*5e7646d2SAndroid Build Coastguard Worker {
2861*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad DELAY value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename);
2862*5e7646d2SAndroid Build Coastguard Worker return (0);
2863*5e7646d2SAndroid Build Coastguard Worker }
2864*5e7646d2SAndroid Build Coastguard Worker
2865*5e7646d2SAndroid Build Coastguard Worker data->monitor_delay = (useconds_t)(1000000.0 * dval);
2866*5e7646d2SAndroid Build Coastguard Worker
2867*5e7646d2SAndroid Build Coastguard Worker if (*ptr == ',')
2868*5e7646d2SAndroid Build Coastguard Worker {
2869*5e7646d2SAndroid Build Coastguard Worker if ((dval = _cupsStrScand(ptr + 1, &ptr, localeconv())) <= 0.0 || *ptr)
2870*5e7646d2SAndroid Build Coastguard Worker {
2871*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad DELAY value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename);
2872*5e7646d2SAndroid Build Coastguard Worker return (0);
2873*5e7646d2SAndroid Build Coastguard Worker }
2874*5e7646d2SAndroid Build Coastguard Worker
2875*5e7646d2SAndroid Build Coastguard Worker data->monitor_interval = (useconds_t)(1000000.0 * dval);
2876*5e7646d2SAndroid Build Coastguard Worker }
2877*5e7646d2SAndroid Build Coastguard Worker else
2878*5e7646d2SAndroid Build Coastguard Worker data->monitor_interval = data->monitor_delay;
2879*5e7646d2SAndroid Build Coastguard Worker }
2880*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "OF-TYPE"))
2881*5e7646d2SAndroid Build Coastguard Worker {
2882*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
2883*5e7646d2SAndroid Build Coastguard Worker {
2884*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing OF-TYPE value tag(s) on line %d of \"%s\".", f->linenum, f->filename);
2885*5e7646d2SAndroid Build Coastguard Worker return (0);
2886*5e7646d2SAndroid Build Coastguard Worker }
2887*5e7646d2SAndroid Build Coastguard Worker
2888*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
2889*5e7646d2SAndroid Build Coastguard Worker {
2890*5e7646d2SAndroid Build Coastguard Worker data->last_expect->of_type = strdup(temp);
2891*5e7646d2SAndroid Build Coastguard Worker }
2892*5e7646d2SAndroid Build Coastguard Worker else
2893*5e7646d2SAndroid Build Coastguard Worker {
2894*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "OF-TYPE without a preceding EXPECT on line %d of \"%s\".", f->linenum, f->filename);
2895*5e7646d2SAndroid Build Coastguard Worker return (0);
2896*5e7646d2SAndroid Build Coastguard Worker }
2897*5e7646d2SAndroid Build Coastguard Worker }
2898*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "IN-GROUP"))
2899*5e7646d2SAndroid Build Coastguard Worker {
2900*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t in_group; /* IN-GROUP value */
2901*5e7646d2SAndroid Build Coastguard Worker
2902*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
2903*5e7646d2SAndroid Build Coastguard Worker {
2904*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing IN-GROUP group tag on line %d of \"%s\".", f->linenum, f->filename);
2905*5e7646d2SAndroid Build Coastguard Worker return (0);
2906*5e7646d2SAndroid Build Coastguard Worker }
2907*5e7646d2SAndroid Build Coastguard Worker
2908*5e7646d2SAndroid Build Coastguard Worker if ((in_group = ippTagValue(temp)) == IPP_TAG_ZERO || in_group >= IPP_TAG_UNSUPPORTED_VALUE)
2909*5e7646d2SAndroid Build Coastguard Worker {
2910*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad IN-GROUP group tag \"%s\" on line %d of \"%s\".", temp, f->linenum, f->filename);
2911*5e7646d2SAndroid Build Coastguard Worker return (0);
2912*5e7646d2SAndroid Build Coastguard Worker }
2913*5e7646d2SAndroid Build Coastguard Worker else if (data->last_expect)
2914*5e7646d2SAndroid Build Coastguard Worker {
2915*5e7646d2SAndroid Build Coastguard Worker data->last_expect->in_group = in_group;
2916*5e7646d2SAndroid Build Coastguard Worker }
2917*5e7646d2SAndroid Build Coastguard Worker else
2918*5e7646d2SAndroid Build Coastguard Worker {
2919*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "IN-GROUP without a preceding EXPECT on line %d of \"%s\".", f->linenum, f->filename);
2920*5e7646d2SAndroid Build Coastguard Worker return (0);
2921*5e7646d2SAndroid Build Coastguard Worker }
2922*5e7646d2SAndroid Build Coastguard Worker }
2923*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "IF-DEFINED"))
2924*5e7646d2SAndroid Build Coastguard Worker {
2925*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
2926*5e7646d2SAndroid Build Coastguard Worker {
2927*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing IF-DEFINED name on line %d of \"%s\".", f->linenum, f->filename);
2928*5e7646d2SAndroid Build Coastguard Worker return (0);
2929*5e7646d2SAndroid Build Coastguard Worker }
2930*5e7646d2SAndroid Build Coastguard Worker
2931*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
2932*5e7646d2SAndroid Build Coastguard Worker {
2933*5e7646d2SAndroid Build Coastguard Worker data->last_expect->if_defined = strdup(temp);
2934*5e7646d2SAndroid Build Coastguard Worker }
2935*5e7646d2SAndroid Build Coastguard Worker else
2936*5e7646d2SAndroid Build Coastguard Worker {
2937*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "IF-DEFINED without a preceding EXPECT on line %d of \"%s\".", f->linenum, f->filename);
2938*5e7646d2SAndroid Build Coastguard Worker return (0);
2939*5e7646d2SAndroid Build Coastguard Worker }
2940*5e7646d2SAndroid Build Coastguard Worker }
2941*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "IF-NOT-DEFINED"))
2942*5e7646d2SAndroid Build Coastguard Worker {
2943*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
2944*5e7646d2SAndroid Build Coastguard Worker {
2945*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing IF-NOT-DEFINED name on line %d of \"%s\".", f->linenum, f->filename);
2946*5e7646d2SAndroid Build Coastguard Worker return (0);
2947*5e7646d2SAndroid Build Coastguard Worker }
2948*5e7646d2SAndroid Build Coastguard Worker
2949*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
2950*5e7646d2SAndroid Build Coastguard Worker {
2951*5e7646d2SAndroid Build Coastguard Worker data->last_expect->if_not_defined = strdup(temp);
2952*5e7646d2SAndroid Build Coastguard Worker }
2953*5e7646d2SAndroid Build Coastguard Worker else
2954*5e7646d2SAndroid Build Coastguard Worker {
2955*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "IF-NOT-DEFINED without a preceding EXPECT on line %d of \"%s\".", f->linenum, f->filename);
2956*5e7646d2SAndroid Build Coastguard Worker return (0);
2957*5e7646d2SAndroid Build Coastguard Worker }
2958*5e7646d2SAndroid Build Coastguard Worker }
2959*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "WITH-DISTINCT-VALUES"))
2960*5e7646d2SAndroid Build Coastguard Worker {
2961*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
2962*5e7646d2SAndroid Build Coastguard Worker {
2963*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_distinct = 1;
2964*5e7646d2SAndroid Build Coastguard Worker }
2965*5e7646d2SAndroid Build Coastguard Worker else
2966*5e7646d2SAndroid Build Coastguard Worker {
2967*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "%s without a preceding EXPECT on line %d of \"%s\".", token, f->linenum, f->filename);
2968*5e7646d2SAndroid Build Coastguard Worker return (0);
2969*5e7646d2SAndroid Build Coastguard Worker }
2970*5e7646d2SAndroid Build Coastguard Worker }
2971*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "WITH-VALUE"))
2972*5e7646d2SAndroid Build Coastguard Worker {
2973*5e7646d2SAndroid Build Coastguard Worker off_t lastpos; /* Last file position */
2974*5e7646d2SAndroid Build Coastguard Worker int lastline; /* Last line number */
2975*5e7646d2SAndroid Build Coastguard Worker
2976*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
2977*5e7646d2SAndroid Build Coastguard Worker {
2978*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing %s value on line %d of \"%s\".", token, f->linenum, f->filename);
2979*5e7646d2SAndroid Build Coastguard Worker return (0);
2980*5e7646d2SAndroid Build Coastguard Worker }
2981*5e7646d2SAndroid Build Coastguard Worker
2982*5e7646d2SAndroid Build Coastguard Worker /*
2983*5e7646d2SAndroid Build Coastguard Worker * Read additional comma-delimited values - needed since legacy test files
2984*5e7646d2SAndroid Build Coastguard Worker * will have unquoted WITH-VALUE values with commas...
2985*5e7646d2SAndroid Build Coastguard Worker */
2986*5e7646d2SAndroid Build Coastguard Worker
2987*5e7646d2SAndroid Build Coastguard Worker ptr = temp + strlen(temp);
2988*5e7646d2SAndroid Build Coastguard Worker
2989*5e7646d2SAndroid Build Coastguard Worker for (;;)
2990*5e7646d2SAndroid Build Coastguard Worker {
2991*5e7646d2SAndroid Build Coastguard Worker lastpos = cupsFileTell(f->fp);
2992*5e7646d2SAndroid Build Coastguard Worker lastline = f->linenum;
2993*5e7646d2SAndroid Build Coastguard Worker ptr += strlen(ptr);
2994*5e7646d2SAndroid Build Coastguard Worker
2995*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, ptr, (sizeof(temp) - (size_t)(ptr - temp))))
2996*5e7646d2SAndroid Build Coastguard Worker break;
2997*5e7646d2SAndroid Build Coastguard Worker
2998*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(ptr, ","))
2999*5e7646d2SAndroid Build Coastguard Worker {
3000*5e7646d2SAndroid Build Coastguard Worker /*
3001*5e7646d2SAndroid Build Coastguard Worker * Append a value...
3002*5e7646d2SAndroid Build Coastguard Worker */
3003*5e7646d2SAndroid Build Coastguard Worker
3004*5e7646d2SAndroid Build Coastguard Worker ptr += strlen(ptr);
3005*5e7646d2SAndroid Build Coastguard Worker
3006*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, ptr, (sizeof(temp) - (size_t)(ptr - temp))))
3007*5e7646d2SAndroid Build Coastguard Worker break;
3008*5e7646d2SAndroid Build Coastguard Worker }
3009*5e7646d2SAndroid Build Coastguard Worker else
3010*5e7646d2SAndroid Build Coastguard Worker {
3011*5e7646d2SAndroid Build Coastguard Worker /*
3012*5e7646d2SAndroid Build Coastguard Worker * Not another value, stop here...
3013*5e7646d2SAndroid Build Coastguard Worker */
3014*5e7646d2SAndroid Build Coastguard Worker
3015*5e7646d2SAndroid Build Coastguard Worker cupsFileSeek(f->fp, lastpos);
3016*5e7646d2SAndroid Build Coastguard Worker f->linenum = lastline;
3017*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
3018*5e7646d2SAndroid Build Coastguard Worker break;
3019*5e7646d2SAndroid Build Coastguard Worker }
3020*5e7646d2SAndroid Build Coastguard Worker }
3021*5e7646d2SAndroid Build Coastguard Worker
3022*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
3023*5e7646d2SAndroid Build Coastguard Worker {
3024*5e7646d2SAndroid Build Coastguard Worker /*
3025*5e7646d2SAndroid Build Coastguard Worker * Expand any variables in the value and then save it.
3026*5e7646d2SAndroid Build Coastguard Worker */
3027*5e7646d2SAndroid Build Coastguard Worker
3028*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(data->vars, value, temp, sizeof(value));
3029*5e7646d2SAndroid Build Coastguard Worker
3030*5e7646d2SAndroid Build Coastguard Worker ptr = value + strlen(value) - 1;
3031*5e7646d2SAndroid Build Coastguard Worker
3032*5e7646d2SAndroid Build Coastguard Worker if (value[0] == '/' && ptr > value && *ptr == '/')
3033*5e7646d2SAndroid Build Coastguard Worker {
3034*5e7646d2SAndroid Build Coastguard Worker /*
3035*5e7646d2SAndroid Build Coastguard Worker * WITH-VALUE is a POSIX extended regular expression.
3036*5e7646d2SAndroid Build Coastguard Worker */
3037*5e7646d2SAndroid Build Coastguard Worker
3038*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_value = calloc(1, (size_t)(ptr - value));
3039*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_flags |= IPPTOOL_WITH_REGEX;
3040*5e7646d2SAndroid Build Coastguard Worker
3041*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect->with_value)
3042*5e7646d2SAndroid Build Coastguard Worker memcpy(data->last_expect->with_value, value + 1, (size_t)(ptr - value - 1));
3043*5e7646d2SAndroid Build Coastguard Worker }
3044*5e7646d2SAndroid Build Coastguard Worker else
3045*5e7646d2SAndroid Build Coastguard Worker {
3046*5e7646d2SAndroid Build Coastguard Worker /*
3047*5e7646d2SAndroid Build Coastguard Worker * WITH-VALUE is a literal value...
3048*5e7646d2SAndroid Build Coastguard Worker */
3049*5e7646d2SAndroid Build Coastguard Worker
3050*5e7646d2SAndroid Build Coastguard Worker for (ptr = value; *ptr; ptr ++)
3051*5e7646d2SAndroid Build Coastguard Worker {
3052*5e7646d2SAndroid Build Coastguard Worker if (*ptr == '\\' && ptr[1])
3053*5e7646d2SAndroid Build Coastguard Worker {
3054*5e7646d2SAndroid Build Coastguard Worker /*
3055*5e7646d2SAndroid Build Coastguard Worker * Remove \ from \foo...
3056*5e7646d2SAndroid Build Coastguard Worker */
3057*5e7646d2SAndroid Build Coastguard Worker
3058*5e7646d2SAndroid Build Coastguard Worker _cups_strcpy(ptr, ptr + 1);
3059*5e7646d2SAndroid Build Coastguard Worker }
3060*5e7646d2SAndroid Build Coastguard Worker }
3061*5e7646d2SAndroid Build Coastguard Worker
3062*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_value = strdup(value);
3063*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_flags |= IPPTOOL_WITH_LITERAL;
3064*5e7646d2SAndroid Build Coastguard Worker }
3065*5e7646d2SAndroid Build Coastguard Worker }
3066*5e7646d2SAndroid Build Coastguard Worker else
3067*5e7646d2SAndroid Build Coastguard Worker {
3068*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "%s without a preceding EXPECT on line %d of \"%s\".", token, f->linenum, f->filename);
3069*5e7646d2SAndroid Build Coastguard Worker return (0);
3070*5e7646d2SAndroid Build Coastguard Worker }
3071*5e7646d2SAndroid Build Coastguard Worker }
3072*5e7646d2SAndroid Build Coastguard Worker }
3073*5e7646d2SAndroid Build Coastguard Worker
3074*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing closing brace on line %d of \"%s\".", f->linenum, f->filename);
3075*5e7646d2SAndroid Build Coastguard Worker
3076*5e7646d2SAndroid Build Coastguard Worker return (0);
3077*5e7646d2SAndroid Build Coastguard Worker }
3078*5e7646d2SAndroid Build Coastguard Worker
3079*5e7646d2SAndroid Build Coastguard Worker
3080*5e7646d2SAndroid Build Coastguard Worker /*
3081*5e7646d2SAndroid Build Coastguard Worker * 'pause_message()' - Display the message and pause until the user presses a key.
3082*5e7646d2SAndroid Build Coastguard Worker */
3083*5e7646d2SAndroid Build Coastguard Worker
3084*5e7646d2SAndroid Build Coastguard Worker static void
pause_message(const char * message)3085*5e7646d2SAndroid Build Coastguard Worker pause_message(const char *message) /* I - Message */
3086*5e7646d2SAndroid Build Coastguard Worker {
3087*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
3088*5e7646d2SAndroid Build Coastguard Worker HANDLE tty; /* Console handle */
3089*5e7646d2SAndroid Build Coastguard Worker DWORD mode; /* Console mode */
3090*5e7646d2SAndroid Build Coastguard Worker char key; /* Key press */
3091*5e7646d2SAndroid Build Coastguard Worker DWORD bytes; /* Bytes read for key press */
3092*5e7646d2SAndroid Build Coastguard Worker
3093*5e7646d2SAndroid Build Coastguard Worker
3094*5e7646d2SAndroid Build Coastguard Worker /*
3095*5e7646d2SAndroid Build Coastguard Worker * Disable input echo and set raw input...
3096*5e7646d2SAndroid Build Coastguard Worker */
3097*5e7646d2SAndroid Build Coastguard Worker
3098*5e7646d2SAndroid Build Coastguard Worker if ((tty = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE)
3099*5e7646d2SAndroid Build Coastguard Worker return;
3100*5e7646d2SAndroid Build Coastguard Worker
3101*5e7646d2SAndroid Build Coastguard Worker if (!GetConsoleMode(tty, &mode))
3102*5e7646d2SAndroid Build Coastguard Worker return;
3103*5e7646d2SAndroid Build Coastguard Worker
3104*5e7646d2SAndroid Build Coastguard Worker if (!SetConsoleMode(tty, 0))
3105*5e7646d2SAndroid Build Coastguard Worker return;
3106*5e7646d2SAndroid Build Coastguard Worker
3107*5e7646d2SAndroid Build Coastguard Worker #else
3108*5e7646d2SAndroid Build Coastguard Worker int tty; /* /dev/tty - never read from stdin */
3109*5e7646d2SAndroid Build Coastguard Worker struct termios original, /* Original input mode */
3110*5e7646d2SAndroid Build Coastguard Worker noecho; /* No echo input mode */
3111*5e7646d2SAndroid Build Coastguard Worker char key; /* Current key press */
3112*5e7646d2SAndroid Build Coastguard Worker
3113*5e7646d2SAndroid Build Coastguard Worker
3114*5e7646d2SAndroid Build Coastguard Worker /*
3115*5e7646d2SAndroid Build Coastguard Worker * Disable input echo and set raw input...
3116*5e7646d2SAndroid Build Coastguard Worker */
3117*5e7646d2SAndroid Build Coastguard Worker
3118*5e7646d2SAndroid Build Coastguard Worker if ((tty = open("/dev/tty", O_RDONLY)) < 0)
3119*5e7646d2SAndroid Build Coastguard Worker return;
3120*5e7646d2SAndroid Build Coastguard Worker
3121*5e7646d2SAndroid Build Coastguard Worker if (tcgetattr(tty, &original))
3122*5e7646d2SAndroid Build Coastguard Worker {
3123*5e7646d2SAndroid Build Coastguard Worker close(tty);
3124*5e7646d2SAndroid Build Coastguard Worker return;
3125*5e7646d2SAndroid Build Coastguard Worker }
3126*5e7646d2SAndroid Build Coastguard Worker
3127*5e7646d2SAndroid Build Coastguard Worker noecho = original;
3128*5e7646d2SAndroid Build Coastguard Worker noecho.c_lflag &= (tcflag_t)~(ICANON | ECHO | ECHOE | ISIG);
3129*5e7646d2SAndroid Build Coastguard Worker
3130*5e7646d2SAndroid Build Coastguard Worker if (tcsetattr(tty, TCSAFLUSH, &noecho))
3131*5e7646d2SAndroid Build Coastguard Worker {
3132*5e7646d2SAndroid Build Coastguard Worker close(tty);
3133*5e7646d2SAndroid Build Coastguard Worker return;
3134*5e7646d2SAndroid Build Coastguard Worker }
3135*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
3136*5e7646d2SAndroid Build Coastguard Worker
3137*5e7646d2SAndroid Build Coastguard Worker /*
3138*5e7646d2SAndroid Build Coastguard Worker * Display the prompt...
3139*5e7646d2SAndroid Build Coastguard Worker */
3140*5e7646d2SAndroid Build Coastguard Worker
3141*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(cupsFileStdout(), "\n%s\n\n---- PRESS ANY KEY ----", message);
3142*5e7646d2SAndroid Build Coastguard Worker
3143*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
3144*5e7646d2SAndroid Build Coastguard Worker /*
3145*5e7646d2SAndroid Build Coastguard Worker * Read a key...
3146*5e7646d2SAndroid Build Coastguard Worker */
3147*5e7646d2SAndroid Build Coastguard Worker
3148*5e7646d2SAndroid Build Coastguard Worker ReadFile(tty, &key, 1, &bytes, NULL);
3149*5e7646d2SAndroid Build Coastguard Worker
3150*5e7646d2SAndroid Build Coastguard Worker /*
3151*5e7646d2SAndroid Build Coastguard Worker * Cleanup...
3152*5e7646d2SAndroid Build Coastguard Worker */
3153*5e7646d2SAndroid Build Coastguard Worker
3154*5e7646d2SAndroid Build Coastguard Worker SetConsoleMode(tty, mode);
3155*5e7646d2SAndroid Build Coastguard Worker
3156*5e7646d2SAndroid Build Coastguard Worker #else
3157*5e7646d2SAndroid Build Coastguard Worker /*
3158*5e7646d2SAndroid Build Coastguard Worker * Read a key...
3159*5e7646d2SAndroid Build Coastguard Worker */
3160*5e7646d2SAndroid Build Coastguard Worker
3161*5e7646d2SAndroid Build Coastguard Worker read(tty, &key, 1);
3162*5e7646d2SAndroid Build Coastguard Worker
3163*5e7646d2SAndroid Build Coastguard Worker /*
3164*5e7646d2SAndroid Build Coastguard Worker * Cleanup...
3165*5e7646d2SAndroid Build Coastguard Worker */
3166*5e7646d2SAndroid Build Coastguard Worker
3167*5e7646d2SAndroid Build Coastguard Worker tcsetattr(tty, TCSAFLUSH, &original);
3168*5e7646d2SAndroid Build Coastguard Worker close(tty);
3169*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
3170*5e7646d2SAndroid Build Coastguard Worker
3171*5e7646d2SAndroid Build Coastguard Worker /*
3172*5e7646d2SAndroid Build Coastguard Worker * Erase the "press any key" prompt...
3173*5e7646d2SAndroid Build Coastguard Worker */
3174*5e7646d2SAndroid Build Coastguard Worker
3175*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(cupsFileStdout(), "\r \r");
3176*5e7646d2SAndroid Build Coastguard Worker }
3177*5e7646d2SAndroid Build Coastguard Worker
3178*5e7646d2SAndroid Build Coastguard Worker
3179*5e7646d2SAndroid Build Coastguard Worker /*
3180*5e7646d2SAndroid Build Coastguard Worker * 'print_attr()' - Print an attribute on the screen.
3181*5e7646d2SAndroid Build Coastguard Worker */
3182*5e7646d2SAndroid Build Coastguard Worker
3183*5e7646d2SAndroid Build Coastguard Worker static void
print_attr(cups_file_t * outfile,ipptool_output_t output,ipp_attribute_t * attr,ipp_tag_t * group)3184*5e7646d2SAndroid Build Coastguard Worker print_attr(cups_file_t *outfile, /* I - Output file */
3185*5e7646d2SAndroid Build Coastguard Worker ipptool_output_t output, /* I - Output format */
3186*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr, /* I - Attribute to print */
3187*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t *group) /* IO - Current group */
3188*5e7646d2SAndroid Build Coastguard Worker {
3189*5e7646d2SAndroid Build Coastguard Worker int i, /* Looping var */
3190*5e7646d2SAndroid Build Coastguard Worker count; /* Number of values */
3191*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *colattr; /* Collection attribute */
3192*5e7646d2SAndroid Build Coastguard Worker
3193*5e7646d2SAndroid Build Coastguard Worker
3194*5e7646d2SAndroid Build Coastguard Worker if (output == IPPTOOL_OUTPUT_PLIST)
3195*5e7646d2SAndroid Build Coastguard Worker {
3196*5e7646d2SAndroid Build Coastguard Worker if (!ippGetName(attr) || (group && *group != ippGetGroupTag(attr)))
3197*5e7646d2SAndroid Build Coastguard Worker {
3198*5e7646d2SAndroid Build Coastguard Worker if (ippGetGroupTag(attr) != IPP_TAG_ZERO)
3199*5e7646d2SAndroid Build Coastguard Worker {
3200*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(outfile, "</dict>\n");
3201*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(outfile, "<dict>\n");
3202*5e7646d2SAndroid Build Coastguard Worker }
3203*5e7646d2SAndroid Build Coastguard Worker
3204*5e7646d2SAndroid Build Coastguard Worker if (group)
3205*5e7646d2SAndroid Build Coastguard Worker *group = ippGetGroupTag(attr);
3206*5e7646d2SAndroid Build Coastguard Worker }
3207*5e7646d2SAndroid Build Coastguard Worker
3208*5e7646d2SAndroid Build Coastguard Worker if (!ippGetName(attr))
3209*5e7646d2SAndroid Build Coastguard Worker return;
3210*5e7646d2SAndroid Build Coastguard Worker
3211*5e7646d2SAndroid Build Coastguard Worker print_xml_string(outfile, "key", ippGetName(attr));
3212*5e7646d2SAndroid Build Coastguard Worker if ((count = ippGetCount(attr)) > 1)
3213*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(outfile, "<array>\n");
3214*5e7646d2SAndroid Build Coastguard Worker
3215*5e7646d2SAndroid Build Coastguard Worker switch (ippGetValueTag(attr))
3216*5e7646d2SAndroid Build Coastguard Worker {
3217*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
3218*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
3219*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3220*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(outfile, "<integer>%d</integer>\n", ippGetInteger(attr, i));
3221*5e7646d2SAndroid Build Coastguard Worker break;
3222*5e7646d2SAndroid Build Coastguard Worker
3223*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BOOLEAN :
3224*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3225*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(outfile, ippGetBoolean(attr, i) ? "<true />\n" : "<false />\n");
3226*5e7646d2SAndroid Build Coastguard Worker break;
3227*5e7646d2SAndroid Build Coastguard Worker
3228*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
3229*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3230*5e7646d2SAndroid Build Coastguard Worker {
3231*5e7646d2SAndroid Build Coastguard Worker int lower, upper; /* Lower and upper ranges */
3232*5e7646d2SAndroid Build Coastguard Worker
3233*5e7646d2SAndroid Build Coastguard Worker lower = ippGetRange(attr, i, &upper);
3234*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(outfile, "<dict><key>lower</key><integer>%d</integer><key>upper</key><integer>%d</integer></dict>\n", lower, upper);
3235*5e7646d2SAndroid Build Coastguard Worker }
3236*5e7646d2SAndroid Build Coastguard Worker break;
3237*5e7646d2SAndroid Build Coastguard Worker
3238*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
3239*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3240*5e7646d2SAndroid Build Coastguard Worker {
3241*5e7646d2SAndroid Build Coastguard Worker int xres, yres; /* Resolution values */
3242*5e7646d2SAndroid Build Coastguard Worker ipp_res_t units; /* Resolution units */
3243*5e7646d2SAndroid Build Coastguard Worker
3244*5e7646d2SAndroid Build Coastguard Worker xres = ippGetResolution(attr, i, &yres, &units);
3245*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(outfile, "<dict><key>xres</key><integer>%d</integer><key>yres</key><integer>%d</integer><key>units</key><string>%s</string></dict>\n", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
3246*5e7646d2SAndroid Build Coastguard Worker }
3247*5e7646d2SAndroid Build Coastguard Worker break;
3248*5e7646d2SAndroid Build Coastguard Worker
3249*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DATE :
3250*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3251*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(outfile, "<date>%s</date>\n", iso_date(ippGetDate(attr, i)));
3252*5e7646d2SAndroid Build Coastguard Worker break;
3253*5e7646d2SAndroid Build Coastguard Worker
3254*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_STRING :
3255*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3256*5e7646d2SAndroid Build Coastguard Worker {
3257*5e7646d2SAndroid Build Coastguard Worker int datalen; /* Length of data */
3258*5e7646d2SAndroid Build Coastguard Worker void *data = ippGetOctetString(attr, i, &datalen);
3259*5e7646d2SAndroid Build Coastguard Worker /* Data */
3260*5e7646d2SAndroid Build Coastguard Worker char buffer[IPP_MAX_LENGTH * 5 / 4 + 1];
3261*5e7646d2SAndroid Build Coastguard Worker /* Base64 output buffer */
3262*5e7646d2SAndroid Build Coastguard Worker
3263*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(outfile, "<data>%s</data>\n", httpEncode64_2(buffer, sizeof(buffer), data, datalen));
3264*5e7646d2SAndroid Build Coastguard Worker }
3265*5e7646d2SAndroid Build Coastguard Worker break;
3266*5e7646d2SAndroid Build Coastguard Worker
3267*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
3268*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
3269*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
3270*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
3271*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
3272*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
3273*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
3274*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
3275*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3276*5e7646d2SAndroid Build Coastguard Worker print_xml_string(outfile, "string", ippGetString(attr, i, NULL));
3277*5e7646d2SAndroid Build Coastguard Worker break;
3278*5e7646d2SAndroid Build Coastguard Worker
3279*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
3280*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
3281*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3282*5e7646d2SAndroid Build Coastguard Worker {
3283*5e7646d2SAndroid Build Coastguard Worker const char *s, /* String */
3284*5e7646d2SAndroid Build Coastguard Worker *lang; /* Language */
3285*5e7646d2SAndroid Build Coastguard Worker
3286*5e7646d2SAndroid Build Coastguard Worker s = ippGetString(attr, i, &lang);
3287*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(outfile, "<dict><key>language</key><string>");
3288*5e7646d2SAndroid Build Coastguard Worker print_xml_string(outfile, NULL, lang);
3289*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(outfile, "</string><key>string</key><string>");
3290*5e7646d2SAndroid Build Coastguard Worker print_xml_string(outfile, NULL, s);
3291*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(outfile, "</string></dict>\n");
3292*5e7646d2SAndroid Build Coastguard Worker }
3293*5e7646d2SAndroid Build Coastguard Worker break;
3294*5e7646d2SAndroid Build Coastguard Worker
3295*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BEGIN_COLLECTION :
3296*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3297*5e7646d2SAndroid Build Coastguard Worker {
3298*5e7646d2SAndroid Build Coastguard Worker ipp_t *col = ippGetCollection(attr, i);
3299*5e7646d2SAndroid Build Coastguard Worker /* Collection value */
3300*5e7646d2SAndroid Build Coastguard Worker
3301*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(outfile, "<dict>\n");
3302*5e7646d2SAndroid Build Coastguard Worker for (colattr = ippFirstAttribute(col); colattr; colattr = ippNextAttribute(col))
3303*5e7646d2SAndroid Build Coastguard Worker print_attr(outfile, output, colattr, NULL);
3304*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(outfile, "</dict>\n");
3305*5e7646d2SAndroid Build Coastguard Worker }
3306*5e7646d2SAndroid Build Coastguard Worker break;
3307*5e7646d2SAndroid Build Coastguard Worker
3308*5e7646d2SAndroid Build Coastguard Worker default :
3309*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(outfile, "<string><<%s>></string>\n", ippTagString(ippGetValueTag(attr)));
3310*5e7646d2SAndroid Build Coastguard Worker break;
3311*5e7646d2SAndroid Build Coastguard Worker }
3312*5e7646d2SAndroid Build Coastguard Worker
3313*5e7646d2SAndroid Build Coastguard Worker if (count > 1)
3314*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(outfile, "</array>\n");
3315*5e7646d2SAndroid Build Coastguard Worker }
3316*5e7646d2SAndroid Build Coastguard Worker else
3317*5e7646d2SAndroid Build Coastguard Worker {
3318*5e7646d2SAndroid Build Coastguard Worker char buffer[131072]; /* Value buffer */
3319*5e7646d2SAndroid Build Coastguard Worker
3320*5e7646d2SAndroid Build Coastguard Worker if (output == IPPTOOL_OUTPUT_TEST)
3321*5e7646d2SAndroid Build Coastguard Worker {
3322*5e7646d2SAndroid Build Coastguard Worker if (!ippGetName(attr))
3323*5e7646d2SAndroid Build Coastguard Worker {
3324*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(outfile, " -- separator --\n");
3325*5e7646d2SAndroid Build Coastguard Worker return;
3326*5e7646d2SAndroid Build Coastguard Worker }
3327*5e7646d2SAndroid Build Coastguard Worker
3328*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(outfile, " %s (%s%s) = ", ippGetName(attr), ippGetCount(attr) > 1 ? "1setOf " : "", ippTagString(ippGetValueTag(attr)));
3329*5e7646d2SAndroid Build Coastguard Worker }
3330*5e7646d2SAndroid Build Coastguard Worker
3331*5e7646d2SAndroid Build Coastguard Worker ippAttributeString(attr, buffer, sizeof(buffer));
3332*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(outfile, "%s\n", buffer);
3333*5e7646d2SAndroid Build Coastguard Worker }
3334*5e7646d2SAndroid Build Coastguard Worker }
3335*5e7646d2SAndroid Build Coastguard Worker
3336*5e7646d2SAndroid Build Coastguard Worker
3337*5e7646d2SAndroid Build Coastguard Worker /*
3338*5e7646d2SAndroid Build Coastguard Worker * 'print_csv()' - Print a line of CSV text.
3339*5e7646d2SAndroid Build Coastguard Worker */
3340*5e7646d2SAndroid Build Coastguard Worker
3341*5e7646d2SAndroid Build Coastguard Worker static ipp_attribute_t * /* O - Next attribute */
print_csv(ipptool_test_t * data,ipp_t * ipp,ipp_attribute_t * attr,int num_displayed,char ** displayed,size_t * widths)3342*5e7646d2SAndroid Build Coastguard Worker print_csv(
3343*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t *data, /* I - Test data */
3344*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp, /* I - Response message */
3345*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr, /* I - First attribute for line */
3346*5e7646d2SAndroid Build Coastguard Worker int num_displayed, /* I - Number of attributes to display */
3347*5e7646d2SAndroid Build Coastguard Worker char **displayed, /* I - Attributes to display */
3348*5e7646d2SAndroid Build Coastguard Worker size_t *widths) /* I - Column widths */
3349*5e7646d2SAndroid Build Coastguard Worker {
3350*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
3351*5e7646d2SAndroid Build Coastguard Worker size_t maxlength; /* Max length of all columns */
3352*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *current = attr; /* Current attribute */
3353*5e7646d2SAndroid Build Coastguard Worker char *values[MAX_DISPLAY], /* Strings to display */
3354*5e7646d2SAndroid Build Coastguard Worker *valptr; /* Pointer into value */
3355*5e7646d2SAndroid Build Coastguard Worker
3356*5e7646d2SAndroid Build Coastguard Worker /*
3357*5e7646d2SAndroid Build Coastguard Worker * Get the maximum string length we have to show and allocate...
3358*5e7646d2SAndroid Build Coastguard Worker */
3359*5e7646d2SAndroid Build Coastguard Worker
3360*5e7646d2SAndroid Build Coastguard Worker for (i = 1, maxlength = widths[0]; i < num_displayed; i ++)
3361*5e7646d2SAndroid Build Coastguard Worker if (widths[i] > maxlength)
3362*5e7646d2SAndroid Build Coastguard Worker maxlength = widths[i];
3363*5e7646d2SAndroid Build Coastguard Worker
3364*5e7646d2SAndroid Build Coastguard Worker maxlength += 2;
3365*5e7646d2SAndroid Build Coastguard Worker
3366*5e7646d2SAndroid Build Coastguard Worker /*
3367*5e7646d2SAndroid Build Coastguard Worker * Loop through the attributes to display...
3368*5e7646d2SAndroid Build Coastguard Worker */
3369*5e7646d2SAndroid Build Coastguard Worker
3370*5e7646d2SAndroid Build Coastguard Worker if (attr)
3371*5e7646d2SAndroid Build Coastguard Worker {
3372*5e7646d2SAndroid Build Coastguard Worker // Collect the values...
3373*5e7646d2SAndroid Build Coastguard Worker memset(values, 0, sizeof(values));
3374*5e7646d2SAndroid Build Coastguard Worker
3375*5e7646d2SAndroid Build Coastguard Worker for (; current; current = ippNextAttribute(ipp))
3376*5e7646d2SAndroid Build Coastguard Worker {
3377*5e7646d2SAndroid Build Coastguard Worker if (!ippGetName(current))
3378*5e7646d2SAndroid Build Coastguard Worker break;
3379*5e7646d2SAndroid Build Coastguard Worker
3380*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_displayed; i ++)
3381*5e7646d2SAndroid Build Coastguard Worker {
3382*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(ippGetName(current), displayed[i]))
3383*5e7646d2SAndroid Build Coastguard Worker {
3384*5e7646d2SAndroid Build Coastguard Worker if ((values[i] = (char *)calloc(1, maxlength)) != NULL)
3385*5e7646d2SAndroid Build Coastguard Worker ippAttributeString(current, values[i], maxlength);
3386*5e7646d2SAndroid Build Coastguard Worker break;
3387*5e7646d2SAndroid Build Coastguard Worker }
3388*5e7646d2SAndroid Build Coastguard Worker }
3389*5e7646d2SAndroid Build Coastguard Worker }
3390*5e7646d2SAndroid Build Coastguard Worker
3391*5e7646d2SAndroid Build Coastguard Worker // Output the line...
3392*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_displayed; i ++)
3393*5e7646d2SAndroid Build Coastguard Worker {
3394*5e7646d2SAndroid Build Coastguard Worker if (i)
3395*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, ',');
3396*5e7646d2SAndroid Build Coastguard Worker
3397*5e7646d2SAndroid Build Coastguard Worker if (!values[i])
3398*5e7646d2SAndroid Build Coastguard Worker continue;
3399*5e7646d2SAndroid Build Coastguard Worker
3400*5e7646d2SAndroid Build Coastguard Worker if (strchr(values[i], ',') != NULL || strchr(values[i], '\"') != NULL || strchr(values[i], '\\') != NULL)
3401*5e7646d2SAndroid Build Coastguard Worker {
3402*5e7646d2SAndroid Build Coastguard Worker // Quoted value...
3403*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, '\"');
3404*5e7646d2SAndroid Build Coastguard Worker for (valptr = values[i]; *valptr; valptr ++)
3405*5e7646d2SAndroid Build Coastguard Worker {
3406*5e7646d2SAndroid Build Coastguard Worker if (*valptr == '\\' || *valptr == '\"')
3407*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, '\\');
3408*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, *valptr);
3409*5e7646d2SAndroid Build Coastguard Worker }
3410*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, '\"');
3411*5e7646d2SAndroid Build Coastguard Worker }
3412*5e7646d2SAndroid Build Coastguard Worker else
3413*5e7646d2SAndroid Build Coastguard Worker {
3414*5e7646d2SAndroid Build Coastguard Worker // Unquoted value...
3415*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, values[i]);
3416*5e7646d2SAndroid Build Coastguard Worker }
3417*5e7646d2SAndroid Build Coastguard Worker
3418*5e7646d2SAndroid Build Coastguard Worker free(values[i]);
3419*5e7646d2SAndroid Build Coastguard Worker }
3420*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, '\n');
3421*5e7646d2SAndroid Build Coastguard Worker }
3422*5e7646d2SAndroid Build Coastguard Worker else
3423*5e7646d2SAndroid Build Coastguard Worker {
3424*5e7646d2SAndroid Build Coastguard Worker // Show column headings...
3425*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_displayed; i ++)
3426*5e7646d2SAndroid Build Coastguard Worker {
3427*5e7646d2SAndroid Build Coastguard Worker if (i)
3428*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, ',');
3429*5e7646d2SAndroid Build Coastguard Worker
3430*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, displayed[i]);
3431*5e7646d2SAndroid Build Coastguard Worker }
3432*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, '\n');
3433*5e7646d2SAndroid Build Coastguard Worker }
3434*5e7646d2SAndroid Build Coastguard Worker
3435*5e7646d2SAndroid Build Coastguard Worker return (current);
3436*5e7646d2SAndroid Build Coastguard Worker }
3437*5e7646d2SAndroid Build Coastguard Worker
3438*5e7646d2SAndroid Build Coastguard Worker
3439*5e7646d2SAndroid Build Coastguard Worker /*
3440*5e7646d2SAndroid Build Coastguard Worker * 'print_fatal_error()' - Print a fatal error message.
3441*5e7646d2SAndroid Build Coastguard Worker */
3442*5e7646d2SAndroid Build Coastguard Worker
3443*5e7646d2SAndroid Build Coastguard Worker static void
print_fatal_error(ipptool_test_t * data,const char * s,...)3444*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(
3445*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t *data, /* I - Test data */
3446*5e7646d2SAndroid Build Coastguard Worker const char *s, /* I - Printf-style format string */
3447*5e7646d2SAndroid Build Coastguard Worker ...) /* I - Additional arguments as needed */
3448*5e7646d2SAndroid Build Coastguard Worker {
3449*5e7646d2SAndroid Build Coastguard Worker char buffer[10240]; /* Format buffer */
3450*5e7646d2SAndroid Build Coastguard Worker va_list ap; /* Pointer to arguments */
3451*5e7646d2SAndroid Build Coastguard Worker
3452*5e7646d2SAndroid Build Coastguard Worker
3453*5e7646d2SAndroid Build Coastguard Worker /*
3454*5e7646d2SAndroid Build Coastguard Worker * Format the error message...
3455*5e7646d2SAndroid Build Coastguard Worker */
3456*5e7646d2SAndroid Build Coastguard Worker
3457*5e7646d2SAndroid Build Coastguard Worker va_start(ap, s);
3458*5e7646d2SAndroid Build Coastguard Worker vsnprintf(buffer, sizeof(buffer), s, ap);
3459*5e7646d2SAndroid Build Coastguard Worker va_end(ap);
3460*5e7646d2SAndroid Build Coastguard Worker
3461*5e7646d2SAndroid Build Coastguard Worker /*
3462*5e7646d2SAndroid Build Coastguard Worker * Then output it...
3463*5e7646d2SAndroid Build Coastguard Worker */
3464*5e7646d2SAndroid Build Coastguard Worker
3465*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_PLIST)
3466*5e7646d2SAndroid Build Coastguard Worker {
3467*5e7646d2SAndroid Build Coastguard Worker print_xml_header(data);
3468*5e7646d2SAndroid Build Coastguard Worker print_xml_trailer(data, 0, buffer);
3469*5e7646d2SAndroid Build Coastguard Worker }
3470*5e7646d2SAndroid Build Coastguard Worker
3471*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, "ipptool: %s", buffer);
3472*5e7646d2SAndroid Build Coastguard Worker }
3473*5e7646d2SAndroid Build Coastguard Worker
3474*5e7646d2SAndroid Build Coastguard Worker
3475*5e7646d2SAndroid Build Coastguard Worker /*
3476*5e7646d2SAndroid Build Coastguard Worker * 'print_ippserver_attr()' - Print a attribute suitable for use by ippserver.
3477*5e7646d2SAndroid Build Coastguard Worker */
3478*5e7646d2SAndroid Build Coastguard Worker
3479*5e7646d2SAndroid Build Coastguard Worker static void
print_ippserver_attr(ipptool_test_t * data,ipp_attribute_t * attr,int indent)3480*5e7646d2SAndroid Build Coastguard Worker print_ippserver_attr(
3481*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t *data, /* I - Test data */
3482*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr, /* I - Attribute to print */
3483*5e7646d2SAndroid Build Coastguard Worker int indent) /* I - Indentation level */
3484*5e7646d2SAndroid Build Coastguard Worker {
3485*5e7646d2SAndroid Build Coastguard Worker int i, /* Looping var */
3486*5e7646d2SAndroid Build Coastguard Worker count = ippGetCount(attr);
3487*5e7646d2SAndroid Build Coastguard Worker /* Number of values */
3488*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *colattr; /* Collection attribute */
3489*5e7646d2SAndroid Build Coastguard Worker
3490*5e7646d2SAndroid Build Coastguard Worker
3491*5e7646d2SAndroid Build Coastguard Worker if (indent == 0)
3492*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(data->outfile, "ATTR %s %s", ippTagString(ippGetValueTag(attr)), ippGetName(attr));
3493*5e7646d2SAndroid Build Coastguard Worker else
3494*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(data->outfile, "%*sMEMBER %s %s", indent, "", ippTagString(ippGetValueTag(attr)), ippGetName(attr));
3495*5e7646d2SAndroid Build Coastguard Worker
3496*5e7646d2SAndroid Build Coastguard Worker switch (ippGetValueTag(attr))
3497*5e7646d2SAndroid Build Coastguard Worker {
3498*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
3499*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
3500*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3501*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(data->outfile, "%s%d", i ? "," : " ", ippGetInteger(attr, i));
3502*5e7646d2SAndroid Build Coastguard Worker break;
3503*5e7646d2SAndroid Build Coastguard Worker
3504*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BOOLEAN :
3505*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, ippGetBoolean(attr, 0) ? " true" : " false");
3506*5e7646d2SAndroid Build Coastguard Worker
3507*5e7646d2SAndroid Build Coastguard Worker for (i = 1; i < count; i ++)
3508*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, ippGetBoolean(attr, 1) ? ",true" : ",false");
3509*5e7646d2SAndroid Build Coastguard Worker break;
3510*5e7646d2SAndroid Build Coastguard Worker
3511*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
3512*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3513*5e7646d2SAndroid Build Coastguard Worker {
3514*5e7646d2SAndroid Build Coastguard Worker int upper, lower = ippGetRange(attr, i, &upper);
3515*5e7646d2SAndroid Build Coastguard Worker
3516*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(data->outfile, "%s%d-%d", i ? "," : " ", lower, upper);
3517*5e7646d2SAndroid Build Coastguard Worker }
3518*5e7646d2SAndroid Build Coastguard Worker break;
3519*5e7646d2SAndroid Build Coastguard Worker
3520*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
3521*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3522*5e7646d2SAndroid Build Coastguard Worker {
3523*5e7646d2SAndroid Build Coastguard Worker ipp_res_t units;
3524*5e7646d2SAndroid Build Coastguard Worker int yres, xres = ippGetResolution(attr, i, &yres, &units);
3525*5e7646d2SAndroid Build Coastguard Worker
3526*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(data->outfile, "%s%dx%d%s", i ? "," : " ", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
3527*5e7646d2SAndroid Build Coastguard Worker }
3528*5e7646d2SAndroid Build Coastguard Worker break;
3529*5e7646d2SAndroid Build Coastguard Worker
3530*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_DATE :
3531*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3532*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(data->outfile, "%s%s", i ? "," : " ", iso_date(ippGetDate(attr, i)));
3533*5e7646d2SAndroid Build Coastguard Worker break;
3534*5e7646d2SAndroid Build Coastguard Worker
3535*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_STRING :
3536*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3537*5e7646d2SAndroid Build Coastguard Worker {
3538*5e7646d2SAndroid Build Coastguard Worker int len;
3539*5e7646d2SAndroid Build Coastguard Worker const char *s = (const char *)ippGetOctetString(attr, i, &len);
3540*5e7646d2SAndroid Build Coastguard Worker
3541*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, i ? "," : " ");
3542*5e7646d2SAndroid Build Coastguard Worker print_ippserver_string(data, s, (size_t)len);
3543*5e7646d2SAndroid Build Coastguard Worker }
3544*5e7646d2SAndroid Build Coastguard Worker break;
3545*5e7646d2SAndroid Build Coastguard Worker
3546*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
3547*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
3548*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
3549*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
3550*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
3551*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
3552*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
3553*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
3554*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
3555*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
3556*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3557*5e7646d2SAndroid Build Coastguard Worker {
3558*5e7646d2SAndroid Build Coastguard Worker const char *s = ippGetString(attr, i, NULL);
3559*5e7646d2SAndroid Build Coastguard Worker
3560*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, i ? "," : " ");
3561*5e7646d2SAndroid Build Coastguard Worker print_ippserver_string(data, s, strlen(s));
3562*5e7646d2SAndroid Build Coastguard Worker }
3563*5e7646d2SAndroid Build Coastguard Worker break;
3564*5e7646d2SAndroid Build Coastguard Worker
3565*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BEGIN_COLLECTION :
3566*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3567*5e7646d2SAndroid Build Coastguard Worker {
3568*5e7646d2SAndroid Build Coastguard Worker ipp_t *col = ippGetCollection(attr, i);
3569*5e7646d2SAndroid Build Coastguard Worker
3570*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, i ? ",{\n" : " {\n");
3571*5e7646d2SAndroid Build Coastguard Worker for (colattr = ippFirstAttribute(col); colattr; colattr = ippNextAttribute(col))
3572*5e7646d2SAndroid Build Coastguard Worker print_ippserver_attr(data, colattr, indent + 4);
3573*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(data->outfile, "%*s}", indent, "");
3574*5e7646d2SAndroid Build Coastguard Worker }
3575*5e7646d2SAndroid Build Coastguard Worker break;
3576*5e7646d2SAndroid Build Coastguard Worker
3577*5e7646d2SAndroid Build Coastguard Worker default :
3578*5e7646d2SAndroid Build Coastguard Worker /* Out-of-band value */
3579*5e7646d2SAndroid Build Coastguard Worker break;
3580*5e7646d2SAndroid Build Coastguard Worker }
3581*5e7646d2SAndroid Build Coastguard Worker
3582*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "\n");
3583*5e7646d2SAndroid Build Coastguard Worker }
3584*5e7646d2SAndroid Build Coastguard Worker
3585*5e7646d2SAndroid Build Coastguard Worker
3586*5e7646d2SAndroid Build Coastguard Worker /*
3587*5e7646d2SAndroid Build Coastguard Worker * 'print_ippserver_string()' - Print a string suitable for use by ippserver.
3588*5e7646d2SAndroid Build Coastguard Worker */
3589*5e7646d2SAndroid Build Coastguard Worker
3590*5e7646d2SAndroid Build Coastguard Worker static void
print_ippserver_string(ipptool_test_t * data,const char * s,size_t len)3591*5e7646d2SAndroid Build Coastguard Worker print_ippserver_string(
3592*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t *data, /* I - Test data */
3593*5e7646d2SAndroid Build Coastguard Worker const char *s, /* I - String to print */
3594*5e7646d2SAndroid Build Coastguard Worker size_t len) /* I - Length of string */
3595*5e7646d2SAndroid Build Coastguard Worker {
3596*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, '\"');
3597*5e7646d2SAndroid Build Coastguard Worker while (len > 0)
3598*5e7646d2SAndroid Build Coastguard Worker {
3599*5e7646d2SAndroid Build Coastguard Worker if (*s == '\"')
3600*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, '\\');
3601*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, *s);
3602*5e7646d2SAndroid Build Coastguard Worker
3603*5e7646d2SAndroid Build Coastguard Worker s ++;
3604*5e7646d2SAndroid Build Coastguard Worker len --;
3605*5e7646d2SAndroid Build Coastguard Worker }
3606*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, '\"');
3607*5e7646d2SAndroid Build Coastguard Worker }
3608*5e7646d2SAndroid Build Coastguard Worker
3609*5e7646d2SAndroid Build Coastguard Worker
3610*5e7646d2SAndroid Build Coastguard Worker /*
3611*5e7646d2SAndroid Build Coastguard Worker * 'print_line()' - Print a line of formatted or CSV text.
3612*5e7646d2SAndroid Build Coastguard Worker */
3613*5e7646d2SAndroid Build Coastguard Worker
3614*5e7646d2SAndroid Build Coastguard Worker static ipp_attribute_t * /* O - Next attribute */
print_line(ipptool_test_t * data,ipp_t * ipp,ipp_attribute_t * attr,int num_displayed,char ** displayed,size_t * widths)3615*5e7646d2SAndroid Build Coastguard Worker print_line(
3616*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t *data, /* I - Test data */
3617*5e7646d2SAndroid Build Coastguard Worker ipp_t *ipp, /* I - Response message */
3618*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr, /* I - First attribute for line */
3619*5e7646d2SAndroid Build Coastguard Worker int num_displayed, /* I - Number of attributes to display */
3620*5e7646d2SAndroid Build Coastguard Worker char **displayed, /* I - Attributes to display */
3621*5e7646d2SAndroid Build Coastguard Worker size_t *widths) /* I - Column widths */
3622*5e7646d2SAndroid Build Coastguard Worker {
3623*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
3624*5e7646d2SAndroid Build Coastguard Worker size_t maxlength; /* Max length of all columns */
3625*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *current = attr; /* Current attribute */
3626*5e7646d2SAndroid Build Coastguard Worker char *values[MAX_DISPLAY]; /* Strings to display */
3627*5e7646d2SAndroid Build Coastguard Worker
3628*5e7646d2SAndroid Build Coastguard Worker
3629*5e7646d2SAndroid Build Coastguard Worker /*
3630*5e7646d2SAndroid Build Coastguard Worker * Get the maximum string length we have to show and allocate...
3631*5e7646d2SAndroid Build Coastguard Worker */
3632*5e7646d2SAndroid Build Coastguard Worker
3633*5e7646d2SAndroid Build Coastguard Worker for (i = 1, maxlength = widths[0]; i < num_displayed; i ++)
3634*5e7646d2SAndroid Build Coastguard Worker if (widths[i] > maxlength)
3635*5e7646d2SAndroid Build Coastguard Worker maxlength = widths[i];
3636*5e7646d2SAndroid Build Coastguard Worker
3637*5e7646d2SAndroid Build Coastguard Worker maxlength += 2;
3638*5e7646d2SAndroid Build Coastguard Worker
3639*5e7646d2SAndroid Build Coastguard Worker /*
3640*5e7646d2SAndroid Build Coastguard Worker * Loop through the attributes to display...
3641*5e7646d2SAndroid Build Coastguard Worker */
3642*5e7646d2SAndroid Build Coastguard Worker
3643*5e7646d2SAndroid Build Coastguard Worker if (attr)
3644*5e7646d2SAndroid Build Coastguard Worker {
3645*5e7646d2SAndroid Build Coastguard Worker // Collect the values...
3646*5e7646d2SAndroid Build Coastguard Worker memset(values, 0, sizeof(values));
3647*5e7646d2SAndroid Build Coastguard Worker
3648*5e7646d2SAndroid Build Coastguard Worker for (; current; current = ippNextAttribute(ipp))
3649*5e7646d2SAndroid Build Coastguard Worker {
3650*5e7646d2SAndroid Build Coastguard Worker if (!ippGetName(current))
3651*5e7646d2SAndroid Build Coastguard Worker break;
3652*5e7646d2SAndroid Build Coastguard Worker
3653*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_displayed; i ++)
3654*5e7646d2SAndroid Build Coastguard Worker {
3655*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(ippGetName(current), displayed[i]))
3656*5e7646d2SAndroid Build Coastguard Worker {
3657*5e7646d2SAndroid Build Coastguard Worker if ((values[i] = (char *)calloc(1, maxlength)) != NULL)
3658*5e7646d2SAndroid Build Coastguard Worker ippAttributeString(current, values[i], maxlength);
3659*5e7646d2SAndroid Build Coastguard Worker break;
3660*5e7646d2SAndroid Build Coastguard Worker }
3661*5e7646d2SAndroid Build Coastguard Worker }
3662*5e7646d2SAndroid Build Coastguard Worker }
3663*5e7646d2SAndroid Build Coastguard Worker
3664*5e7646d2SAndroid Build Coastguard Worker // Output the line...
3665*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_displayed; i ++)
3666*5e7646d2SAndroid Build Coastguard Worker {
3667*5e7646d2SAndroid Build Coastguard Worker if (i)
3668*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, ' ');
3669*5e7646d2SAndroid Build Coastguard Worker
3670*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(data->outfile, "%*s", (int)-widths[i], values[i] ? values[i] : "");
3671*5e7646d2SAndroid Build Coastguard Worker free(values[i]);
3672*5e7646d2SAndroid Build Coastguard Worker }
3673*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, '\n');
3674*5e7646d2SAndroid Build Coastguard Worker }
3675*5e7646d2SAndroid Build Coastguard Worker else
3676*5e7646d2SAndroid Build Coastguard Worker {
3677*5e7646d2SAndroid Build Coastguard Worker // Show column headings...
3678*5e7646d2SAndroid Build Coastguard Worker char *buffer = (char *)malloc(maxlength);
3679*5e7646d2SAndroid Build Coastguard Worker // Buffer for separator lines
3680*5e7646d2SAndroid Build Coastguard Worker
3681*5e7646d2SAndroid Build Coastguard Worker if (!buffer)
3682*5e7646d2SAndroid Build Coastguard Worker return (current);
3683*5e7646d2SAndroid Build Coastguard Worker
3684*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_displayed; i ++)
3685*5e7646d2SAndroid Build Coastguard Worker {
3686*5e7646d2SAndroid Build Coastguard Worker if (i)
3687*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, ' ');
3688*5e7646d2SAndroid Build Coastguard Worker
3689*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(data->outfile, "%*s", (int)-widths[i], displayed[i]);
3690*5e7646d2SAndroid Build Coastguard Worker }
3691*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, '\n');
3692*5e7646d2SAndroid Build Coastguard Worker
3693*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_displayed; i ++)
3694*5e7646d2SAndroid Build Coastguard Worker {
3695*5e7646d2SAndroid Build Coastguard Worker if (i)
3696*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, ' ');
3697*5e7646d2SAndroid Build Coastguard Worker
3698*5e7646d2SAndroid Build Coastguard Worker memset(buffer, '-', widths[i]);
3699*5e7646d2SAndroid Build Coastguard Worker buffer[widths[i]] = '\0';
3700*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, buffer);
3701*5e7646d2SAndroid Build Coastguard Worker }
3702*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(data->outfile, '\n');
3703*5e7646d2SAndroid Build Coastguard Worker free(buffer);
3704*5e7646d2SAndroid Build Coastguard Worker }
3705*5e7646d2SAndroid Build Coastguard Worker
3706*5e7646d2SAndroid Build Coastguard Worker return (current);
3707*5e7646d2SAndroid Build Coastguard Worker }
3708*5e7646d2SAndroid Build Coastguard Worker
3709*5e7646d2SAndroid Build Coastguard Worker
3710*5e7646d2SAndroid Build Coastguard Worker /*
3711*5e7646d2SAndroid Build Coastguard Worker * 'print_xml_header()' - Print a standard XML plist header.
3712*5e7646d2SAndroid Build Coastguard Worker */
3713*5e7646d2SAndroid Build Coastguard Worker
3714*5e7646d2SAndroid Build Coastguard Worker static void
print_xml_header(ipptool_test_t * data)3715*5e7646d2SAndroid Build Coastguard Worker print_xml_header(ipptool_test_t *data)/* I - Test data */
3716*5e7646d2SAndroid Build Coastguard Worker {
3717*5e7646d2SAndroid Build Coastguard Worker if (!data->xml_header)
3718*5e7646d2SAndroid Build Coastguard Worker {
3719*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
3720*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n");
3721*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<plist version=\"1.0\">\n");
3722*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<dict>\n");
3723*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>ipptoolVersion</key>\n");
3724*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<string>" CUPS_SVERSION "</string>\n");
3725*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>Transfer</key>\n");
3726*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(data->outfile, "<string>%s</string>\n", data->transfer == IPPTOOL_TRANSFER_AUTO ? "auto" : data->transfer == IPPTOOL_TRANSFER_CHUNKED ? "chunked" : "length");
3727*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>Tests</key>\n");
3728*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<array>\n");
3729*5e7646d2SAndroid Build Coastguard Worker
3730*5e7646d2SAndroid Build Coastguard Worker data->xml_header = 1;
3731*5e7646d2SAndroid Build Coastguard Worker }
3732*5e7646d2SAndroid Build Coastguard Worker }
3733*5e7646d2SAndroid Build Coastguard Worker
3734*5e7646d2SAndroid Build Coastguard Worker
3735*5e7646d2SAndroid Build Coastguard Worker /*
3736*5e7646d2SAndroid Build Coastguard Worker * 'print_xml_string()' - Print an XML string with escaping.
3737*5e7646d2SAndroid Build Coastguard Worker */
3738*5e7646d2SAndroid Build Coastguard Worker
3739*5e7646d2SAndroid Build Coastguard Worker static void
print_xml_string(cups_file_t * outfile,const char * element,const char * s)3740*5e7646d2SAndroid Build Coastguard Worker print_xml_string(cups_file_t *outfile, /* I - Test data */
3741*5e7646d2SAndroid Build Coastguard Worker const char *element, /* I - Element name or NULL */
3742*5e7646d2SAndroid Build Coastguard Worker const char *s) /* I - String to print */
3743*5e7646d2SAndroid Build Coastguard Worker {
3744*5e7646d2SAndroid Build Coastguard Worker if (element)
3745*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(outfile, "<%s>", element);
3746*5e7646d2SAndroid Build Coastguard Worker
3747*5e7646d2SAndroid Build Coastguard Worker while (*s)
3748*5e7646d2SAndroid Build Coastguard Worker {
3749*5e7646d2SAndroid Build Coastguard Worker if (*s == '&')
3750*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(outfile, "&");
3751*5e7646d2SAndroid Build Coastguard Worker else if (*s == '<')
3752*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(outfile, "<");
3753*5e7646d2SAndroid Build Coastguard Worker else if (*s == '>')
3754*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(outfile, ">");
3755*5e7646d2SAndroid Build Coastguard Worker else if ((*s & 0xe0) == 0xc0)
3756*5e7646d2SAndroid Build Coastguard Worker {
3757*5e7646d2SAndroid Build Coastguard Worker /*
3758*5e7646d2SAndroid Build Coastguard Worker * Validate UTF-8 two-byte sequence...
3759*5e7646d2SAndroid Build Coastguard Worker */
3760*5e7646d2SAndroid Build Coastguard Worker
3761*5e7646d2SAndroid Build Coastguard Worker if ((s[1] & 0xc0) != 0x80)
3762*5e7646d2SAndroid Build Coastguard Worker {
3763*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(outfile, '?');
3764*5e7646d2SAndroid Build Coastguard Worker s ++;
3765*5e7646d2SAndroid Build Coastguard Worker }
3766*5e7646d2SAndroid Build Coastguard Worker else
3767*5e7646d2SAndroid Build Coastguard Worker {
3768*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(outfile, *s++);
3769*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(outfile, *s);
3770*5e7646d2SAndroid Build Coastguard Worker }
3771*5e7646d2SAndroid Build Coastguard Worker }
3772*5e7646d2SAndroid Build Coastguard Worker else if ((*s & 0xf0) == 0xe0)
3773*5e7646d2SAndroid Build Coastguard Worker {
3774*5e7646d2SAndroid Build Coastguard Worker /*
3775*5e7646d2SAndroid Build Coastguard Worker * Validate UTF-8 three-byte sequence...
3776*5e7646d2SAndroid Build Coastguard Worker */
3777*5e7646d2SAndroid Build Coastguard Worker
3778*5e7646d2SAndroid Build Coastguard Worker if ((s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80)
3779*5e7646d2SAndroid Build Coastguard Worker {
3780*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(outfile, '?');
3781*5e7646d2SAndroid Build Coastguard Worker s += 2;
3782*5e7646d2SAndroid Build Coastguard Worker }
3783*5e7646d2SAndroid Build Coastguard Worker else
3784*5e7646d2SAndroid Build Coastguard Worker {
3785*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(outfile, *s++);
3786*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(outfile, *s++);
3787*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(outfile, *s);
3788*5e7646d2SAndroid Build Coastguard Worker }
3789*5e7646d2SAndroid Build Coastguard Worker }
3790*5e7646d2SAndroid Build Coastguard Worker else if ((*s & 0xf8) == 0xf0)
3791*5e7646d2SAndroid Build Coastguard Worker {
3792*5e7646d2SAndroid Build Coastguard Worker /*
3793*5e7646d2SAndroid Build Coastguard Worker * Validate UTF-8 four-byte sequence...
3794*5e7646d2SAndroid Build Coastguard Worker */
3795*5e7646d2SAndroid Build Coastguard Worker
3796*5e7646d2SAndroid Build Coastguard Worker if ((s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 ||
3797*5e7646d2SAndroid Build Coastguard Worker (s[3] & 0xc0) != 0x80)
3798*5e7646d2SAndroid Build Coastguard Worker {
3799*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(outfile, '?');
3800*5e7646d2SAndroid Build Coastguard Worker s += 3;
3801*5e7646d2SAndroid Build Coastguard Worker }
3802*5e7646d2SAndroid Build Coastguard Worker else
3803*5e7646d2SAndroid Build Coastguard Worker {
3804*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(outfile, *s++);
3805*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(outfile, *s++);
3806*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(outfile, *s++);
3807*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(outfile, *s);
3808*5e7646d2SAndroid Build Coastguard Worker }
3809*5e7646d2SAndroid Build Coastguard Worker }
3810*5e7646d2SAndroid Build Coastguard Worker else if ((*s & 0x80) || (*s < ' ' && !isspace(*s & 255)))
3811*5e7646d2SAndroid Build Coastguard Worker {
3812*5e7646d2SAndroid Build Coastguard Worker /*
3813*5e7646d2SAndroid Build Coastguard Worker * Invalid control character...
3814*5e7646d2SAndroid Build Coastguard Worker */
3815*5e7646d2SAndroid Build Coastguard Worker
3816*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(outfile, '?');
3817*5e7646d2SAndroid Build Coastguard Worker }
3818*5e7646d2SAndroid Build Coastguard Worker else
3819*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(outfile, *s);
3820*5e7646d2SAndroid Build Coastguard Worker
3821*5e7646d2SAndroid Build Coastguard Worker s ++;
3822*5e7646d2SAndroid Build Coastguard Worker }
3823*5e7646d2SAndroid Build Coastguard Worker
3824*5e7646d2SAndroid Build Coastguard Worker if (element)
3825*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(outfile, "</%s>\n", element);
3826*5e7646d2SAndroid Build Coastguard Worker }
3827*5e7646d2SAndroid Build Coastguard Worker
3828*5e7646d2SAndroid Build Coastguard Worker
3829*5e7646d2SAndroid Build Coastguard Worker /*
3830*5e7646d2SAndroid Build Coastguard Worker * 'print_xml_trailer()' - Print the XML trailer with success/fail value.
3831*5e7646d2SAndroid Build Coastguard Worker */
3832*5e7646d2SAndroid Build Coastguard Worker
3833*5e7646d2SAndroid Build Coastguard Worker static void
print_xml_trailer(ipptool_test_t * data,int success,const char * message)3834*5e7646d2SAndroid Build Coastguard Worker print_xml_trailer(
3835*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t *data, /* I - Test data */
3836*5e7646d2SAndroid Build Coastguard Worker int success, /* I - 1 on success, 0 on failure */
3837*5e7646d2SAndroid Build Coastguard Worker const char *message) /* I - Error message or NULL */
3838*5e7646d2SAndroid Build Coastguard Worker {
3839*5e7646d2SAndroid Build Coastguard Worker if (data->xml_header)
3840*5e7646d2SAndroid Build Coastguard Worker {
3841*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "</array>\n");
3842*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>Successful</key>\n");
3843*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, success ? "<true />\n" : "<false />\n");
3844*5e7646d2SAndroid Build Coastguard Worker if (message)
3845*5e7646d2SAndroid Build Coastguard Worker {
3846*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "<key>ErrorMessage</key>\n");
3847*5e7646d2SAndroid Build Coastguard Worker print_xml_string(data->outfile, "string", message);
3848*5e7646d2SAndroid Build Coastguard Worker }
3849*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "</dict>\n");
3850*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(data->outfile, "</plist>\n");
3851*5e7646d2SAndroid Build Coastguard Worker
3852*5e7646d2SAndroid Build Coastguard Worker data->xml_header = 0;
3853*5e7646d2SAndroid Build Coastguard Worker }
3854*5e7646d2SAndroid Build Coastguard Worker }
3855*5e7646d2SAndroid Build Coastguard Worker
3856*5e7646d2SAndroid Build Coastguard Worker
3857*5e7646d2SAndroid Build Coastguard Worker #ifndef _WIN32
3858*5e7646d2SAndroid Build Coastguard Worker /*
3859*5e7646d2SAndroid Build Coastguard Worker * 'sigterm_handler()' - Handle SIGINT and SIGTERM.
3860*5e7646d2SAndroid Build Coastguard Worker */
3861*5e7646d2SAndroid Build Coastguard Worker
3862*5e7646d2SAndroid Build Coastguard Worker static void
sigterm_handler(int sig)3863*5e7646d2SAndroid Build Coastguard Worker sigterm_handler(int sig) /* I - Signal number (unused) */
3864*5e7646d2SAndroid Build Coastguard Worker {
3865*5e7646d2SAndroid Build Coastguard Worker (void)sig;
3866*5e7646d2SAndroid Build Coastguard Worker
3867*5e7646d2SAndroid Build Coastguard Worker Cancel = 1;
3868*5e7646d2SAndroid Build Coastguard Worker
3869*5e7646d2SAndroid Build Coastguard Worker signal(SIGINT, SIG_DFL);
3870*5e7646d2SAndroid Build Coastguard Worker signal(SIGTERM, SIG_DFL);
3871*5e7646d2SAndroid Build Coastguard Worker }
3872*5e7646d2SAndroid Build Coastguard Worker #endif /* !_WIN32 */
3873*5e7646d2SAndroid Build Coastguard Worker
3874*5e7646d2SAndroid Build Coastguard Worker
3875*5e7646d2SAndroid Build Coastguard Worker /*
3876*5e7646d2SAndroid Build Coastguard Worker * 'timeout_cb()' - Handle HTTP timeouts.
3877*5e7646d2SAndroid Build Coastguard Worker */
3878*5e7646d2SAndroid Build Coastguard Worker
3879*5e7646d2SAndroid Build Coastguard Worker static int /* O - 1 to continue, 0 to cancel */
timeout_cb(http_t * http,void * user_data)3880*5e7646d2SAndroid Build Coastguard Worker timeout_cb(http_t *http, /* I - Connection to server */
3881*5e7646d2SAndroid Build Coastguard Worker void *user_data) /* I - User data (unused) */
3882*5e7646d2SAndroid Build Coastguard Worker {
3883*5e7646d2SAndroid Build Coastguard Worker int buffered = 0; /* Bytes buffered but not yet sent */
3884*5e7646d2SAndroid Build Coastguard Worker
3885*5e7646d2SAndroid Build Coastguard Worker
3886*5e7646d2SAndroid Build Coastguard Worker (void)user_data;
3887*5e7646d2SAndroid Build Coastguard Worker
3888*5e7646d2SAndroid Build Coastguard Worker /*
3889*5e7646d2SAndroid Build Coastguard Worker * If the socket still have data waiting to be sent to the printer (as can
3890*5e7646d2SAndroid Build Coastguard Worker * happen if the printer runs out of paper), continue to wait until the output
3891*5e7646d2SAndroid Build Coastguard Worker * buffer is empty...
3892*5e7646d2SAndroid Build Coastguard Worker */
3893*5e7646d2SAndroid Build Coastguard Worker
3894*5e7646d2SAndroid Build Coastguard Worker #ifdef SO_NWRITE /* macOS and some versions of Linux */
3895*5e7646d2SAndroid Build Coastguard Worker socklen_t len = sizeof(buffered); /* Size of return value */
3896*5e7646d2SAndroid Build Coastguard Worker
3897*5e7646d2SAndroid Build Coastguard Worker if (getsockopt(httpGetFd(http), SOL_SOCKET, SO_NWRITE, &buffered, &len))
3898*5e7646d2SAndroid Build Coastguard Worker buffered = 0;
3899*5e7646d2SAndroid Build Coastguard Worker
3900*5e7646d2SAndroid Build Coastguard Worker #elif defined(SIOCOUTQ) /* Others except Windows */
3901*5e7646d2SAndroid Build Coastguard Worker if (ioctl(httpGetFd(http), SIOCOUTQ, &buffered))
3902*5e7646d2SAndroid Build Coastguard Worker buffered = 0;
3903*5e7646d2SAndroid Build Coastguard Worker
3904*5e7646d2SAndroid Build Coastguard Worker #else /* Windows (not possible) */
3905*5e7646d2SAndroid Build Coastguard Worker (void)http;
3906*5e7646d2SAndroid Build Coastguard Worker #endif /* SO_NWRITE */
3907*5e7646d2SAndroid Build Coastguard Worker
3908*5e7646d2SAndroid Build Coastguard Worker return (buffered > 0);
3909*5e7646d2SAndroid Build Coastguard Worker }
3910*5e7646d2SAndroid Build Coastguard Worker
3911*5e7646d2SAndroid Build Coastguard Worker
3912*5e7646d2SAndroid Build Coastguard Worker /*
3913*5e7646d2SAndroid Build Coastguard Worker * 'token_cb()' - Parse test file-specific tokens and run tests.
3914*5e7646d2SAndroid Build Coastguard Worker */
3915*5e7646d2SAndroid Build Coastguard Worker
3916*5e7646d2SAndroid Build Coastguard Worker static int /* O - 1 to continue, 0 to stop */
token_cb(_ipp_file_t * f,_ipp_vars_t * vars,ipptool_test_t * data,const char * token)3917*5e7646d2SAndroid Build Coastguard Worker token_cb(_ipp_file_t *f, /* I - IPP file data */
3918*5e7646d2SAndroid Build Coastguard Worker _ipp_vars_t *vars, /* I - IPP variables */
3919*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t *data, /* I - Test data */
3920*5e7646d2SAndroid Build Coastguard Worker const char *token) /* I - Current token */
3921*5e7646d2SAndroid Build Coastguard Worker {
3922*5e7646d2SAndroid Build Coastguard Worker char name[1024], /* Name string */
3923*5e7646d2SAndroid Build Coastguard Worker temp[1024], /* Temporary string */
3924*5e7646d2SAndroid Build Coastguard Worker value[1024], /* Value string */
3925*5e7646d2SAndroid Build Coastguard Worker *ptr; /* Pointer into value */
3926*5e7646d2SAndroid Build Coastguard Worker
3927*5e7646d2SAndroid Build Coastguard Worker
3928*5e7646d2SAndroid Build Coastguard Worker if (!token)
3929*5e7646d2SAndroid Build Coastguard Worker {
3930*5e7646d2SAndroid Build Coastguard Worker /*
3931*5e7646d2SAndroid Build Coastguard Worker * Initialize state as needed (nothing for now...)
3932*5e7646d2SAndroid Build Coastguard Worker */
3933*5e7646d2SAndroid Build Coastguard Worker
3934*5e7646d2SAndroid Build Coastguard Worker return (1);
3935*5e7646d2SAndroid Build Coastguard Worker }
3936*5e7646d2SAndroid Build Coastguard Worker else if (f->attrs)
3937*5e7646d2SAndroid Build Coastguard Worker {
3938*5e7646d2SAndroid Build Coastguard Worker /*
3939*5e7646d2SAndroid Build Coastguard Worker * Parse until we see a close brace...
3940*5e7646d2SAndroid Build Coastguard Worker */
3941*5e7646d2SAndroid Build Coastguard Worker
3942*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(token, "COUNT") &&
3943*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "DEFINE-MATCH") &&
3944*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "DEFINE-NO-MATCH") &&
3945*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "DEFINE-VALUE") &&
3946*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "DISPLAY-MATCH") &&
3947*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "IF-DEFINED") &&
3948*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "IF-NOT-DEFINED") &&
3949*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "IN-GROUP") &&
3950*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "OF-TYPE") &&
3951*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "REPEAT-LIMIT") &&
3952*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "REPEAT-MATCH") &&
3953*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "REPEAT-NO-MATCH") &&
3954*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "SAME-COUNT-AS") &&
3955*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "WITH-ALL-VALUES") &&
3956*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "WITH-ALL-HOSTNAMES") &&
3957*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "WITH-ALL-RESOURCES") &&
3958*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "WITH-ALL-SCHEMES") &&
3959*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "WITH-DISTINCT-VALUES") &&
3960*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "WITH-HOSTNAME") &&
3961*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "WITH-RESOURCE") &&
3962*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "WITH-SCHEME") &&
3963*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "WITH-VALUE") &&
3964*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "WITH-VALUE-FROM"))
3965*5e7646d2SAndroid Build Coastguard Worker data->last_expect = NULL;
3966*5e7646d2SAndroid Build Coastguard Worker
3967*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(token, "DEFINE-MATCH") &&
3968*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "DEFINE-NO-MATCH") &&
3969*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "IF-DEFINED") &&
3970*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "IF-NOT-DEFINED") &&
3971*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "REPEAT-LIMIT") &&
3972*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "REPEAT-MATCH") &&
3973*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(token, "REPEAT-NO-MATCH"))
3974*5e7646d2SAndroid Build Coastguard Worker data->last_status = NULL;
3975*5e7646d2SAndroid Build Coastguard Worker
3976*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(token, "}"))
3977*5e7646d2SAndroid Build Coastguard Worker {
3978*5e7646d2SAndroid Build Coastguard Worker return (do_test(f, data));
3979*5e7646d2SAndroid Build Coastguard Worker }
3980*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "MONITOR-PRINTER-STATE"))
3981*5e7646d2SAndroid Build Coastguard Worker {
3982*5e7646d2SAndroid Build Coastguard Worker if (data->monitor_uri)
3983*5e7646d2SAndroid Build Coastguard Worker {
3984*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Extra MONITOR-PRINTER-STATE seen on line %d of \"%s\".", f->linenum, f->filename);
3985*5e7646d2SAndroid Build Coastguard Worker return (0);
3986*5e7646d2SAndroid Build Coastguard Worker }
3987*5e7646d2SAndroid Build Coastguard Worker
3988*5e7646d2SAndroid Build Coastguard Worker return (parse_monitor_printer_state(f, data));
3989*5e7646d2SAndroid Build Coastguard Worker }
3990*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "COMPRESSION"))
3991*5e7646d2SAndroid Build Coastguard Worker {
3992*5e7646d2SAndroid Build Coastguard Worker /*
3993*5e7646d2SAndroid Build Coastguard Worker * COMPRESSION none
3994*5e7646d2SAndroid Build Coastguard Worker * COMPRESSION deflate
3995*5e7646d2SAndroid Build Coastguard Worker * COMPRESSION gzip
3996*5e7646d2SAndroid Build Coastguard Worker */
3997*5e7646d2SAndroid Build Coastguard Worker
3998*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, temp, sizeof(temp)))
3999*5e7646d2SAndroid Build Coastguard Worker {
4000*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(vars, data->compression, temp, sizeof(data->compression));
4001*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
4002*5e7646d2SAndroid Build Coastguard Worker if (strcmp(data->compression, "none") && strcmp(data->compression, "deflate") &&
4003*5e7646d2SAndroid Build Coastguard Worker strcmp(data->compression, "gzip"))
4004*5e7646d2SAndroid Build Coastguard Worker #else
4005*5e7646d2SAndroid Build Coastguard Worker if (strcmp(data->compression, "none"))
4006*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
4007*5e7646d2SAndroid Build Coastguard Worker {
4008*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Unsupported COMPRESSION value \"%s\" on line %d of \"%s\".", data->compression, f->linenum, f->filename);
4009*5e7646d2SAndroid Build Coastguard Worker return (0);
4010*5e7646d2SAndroid Build Coastguard Worker }
4011*5e7646d2SAndroid Build Coastguard Worker
4012*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(data->compression, "none"))
4013*5e7646d2SAndroid Build Coastguard Worker data->compression[0] = '\0';
4014*5e7646d2SAndroid Build Coastguard Worker }
4015*5e7646d2SAndroid Build Coastguard Worker else
4016*5e7646d2SAndroid Build Coastguard Worker {
4017*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing COMPRESSION value on line %d of \"%s\".", f->linenum, f->filename);
4018*5e7646d2SAndroid Build Coastguard Worker return (0);
4019*5e7646d2SAndroid Build Coastguard Worker }
4020*5e7646d2SAndroid Build Coastguard Worker }
4021*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "DEFINE"))
4022*5e7646d2SAndroid Build Coastguard Worker {
4023*5e7646d2SAndroid Build Coastguard Worker /*
4024*5e7646d2SAndroid Build Coastguard Worker * DEFINE name value
4025*5e7646d2SAndroid Build Coastguard Worker */
4026*5e7646d2SAndroid Build Coastguard Worker
4027*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, name, sizeof(name)) && _ippFileReadToken(f, temp, sizeof(temp)))
4028*5e7646d2SAndroid Build Coastguard Worker {
4029*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(vars, value, temp, sizeof(value));
4030*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(vars, name, value);
4031*5e7646d2SAndroid Build Coastguard Worker }
4032*5e7646d2SAndroid Build Coastguard Worker else
4033*5e7646d2SAndroid Build Coastguard Worker {
4034*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing DEFINE name and/or value on line %d of \"%s\".", f->linenum, f->filename);
4035*5e7646d2SAndroid Build Coastguard Worker return (0);
4036*5e7646d2SAndroid Build Coastguard Worker }
4037*5e7646d2SAndroid Build Coastguard Worker }
4038*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "IGNORE-ERRORS"))
4039*5e7646d2SAndroid Build Coastguard Worker {
4040*5e7646d2SAndroid Build Coastguard Worker /*
4041*5e7646d2SAndroid Build Coastguard Worker * IGNORE-ERRORS yes
4042*5e7646d2SAndroid Build Coastguard Worker * IGNORE-ERRORS no
4043*5e7646d2SAndroid Build Coastguard Worker */
4044*5e7646d2SAndroid Build Coastguard Worker
4045*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, temp, sizeof(temp)) && (!_cups_strcasecmp(temp, "yes") || !_cups_strcasecmp(temp, "no")))
4046*5e7646d2SAndroid Build Coastguard Worker {
4047*5e7646d2SAndroid Build Coastguard Worker data->ignore_errors = !_cups_strcasecmp(temp, "yes");
4048*5e7646d2SAndroid Build Coastguard Worker }
4049*5e7646d2SAndroid Build Coastguard Worker else
4050*5e7646d2SAndroid Build Coastguard Worker {
4051*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing IGNORE-ERRORS value on line %d of \"%s\".", f->linenum, f->filename);
4052*5e7646d2SAndroid Build Coastguard Worker return (0);
4053*5e7646d2SAndroid Build Coastguard Worker }
4054*5e7646d2SAndroid Build Coastguard Worker }
4055*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "NAME"))
4056*5e7646d2SAndroid Build Coastguard Worker {
4057*5e7646d2SAndroid Build Coastguard Worker /*
4058*5e7646d2SAndroid Build Coastguard Worker * Name of test...
4059*5e7646d2SAndroid Build Coastguard Worker */
4060*5e7646d2SAndroid Build Coastguard Worker
4061*5e7646d2SAndroid Build Coastguard Worker _ippFileReadToken(f, temp, sizeof(temp));
4062*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(vars, data->name, temp, sizeof(data->name));
4063*5e7646d2SAndroid Build Coastguard Worker }
4064*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "PAUSE"))
4065*5e7646d2SAndroid Build Coastguard Worker {
4066*5e7646d2SAndroid Build Coastguard Worker /*
4067*5e7646d2SAndroid Build Coastguard Worker * Pause with a message...
4068*5e7646d2SAndroid Build Coastguard Worker */
4069*5e7646d2SAndroid Build Coastguard Worker
4070*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, temp, sizeof(temp)))
4071*5e7646d2SAndroid Build Coastguard Worker {
4072*5e7646d2SAndroid Build Coastguard Worker strlcpy(data->pause, temp, sizeof(data->pause));
4073*5e7646d2SAndroid Build Coastguard Worker }
4074*5e7646d2SAndroid Build Coastguard Worker else
4075*5e7646d2SAndroid Build Coastguard Worker {
4076*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing PAUSE message on line %d of \"%s\".", f->linenum, f->filename);
4077*5e7646d2SAndroid Build Coastguard Worker return (0);
4078*5e7646d2SAndroid Build Coastguard Worker }
4079*5e7646d2SAndroid Build Coastguard Worker }
4080*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "REQUEST-ID"))
4081*5e7646d2SAndroid Build Coastguard Worker {
4082*5e7646d2SAndroid Build Coastguard Worker /*
4083*5e7646d2SAndroid Build Coastguard Worker * REQUEST-ID #
4084*5e7646d2SAndroid Build Coastguard Worker * REQUEST-ID random
4085*5e7646d2SAndroid Build Coastguard Worker */
4086*5e7646d2SAndroid Build Coastguard Worker
4087*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, temp, sizeof(temp)))
4088*5e7646d2SAndroid Build Coastguard Worker {
4089*5e7646d2SAndroid Build Coastguard Worker if (isdigit(temp[0] & 255))
4090*5e7646d2SAndroid Build Coastguard Worker {
4091*5e7646d2SAndroid Build Coastguard Worker data->request_id = atoi(temp) - 1;
4092*5e7646d2SAndroid Build Coastguard Worker }
4093*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(temp, "random"))
4094*5e7646d2SAndroid Build Coastguard Worker {
4095*5e7646d2SAndroid Build Coastguard Worker data->request_id = (CUPS_RAND() % 1000) * 137;
4096*5e7646d2SAndroid Build Coastguard Worker }
4097*5e7646d2SAndroid Build Coastguard Worker else
4098*5e7646d2SAndroid Build Coastguard Worker {
4099*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad REQUEST-ID value \"%s\" on line %d of \"%s\".", temp, f->linenum, f->filename);
4100*5e7646d2SAndroid Build Coastguard Worker return (0);
4101*5e7646d2SAndroid Build Coastguard Worker }
4102*5e7646d2SAndroid Build Coastguard Worker }
4103*5e7646d2SAndroid Build Coastguard Worker else
4104*5e7646d2SAndroid Build Coastguard Worker {
4105*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing REQUEST-ID value on line %d of \"%s\".", f->linenum, f->filename);
4106*5e7646d2SAndroid Build Coastguard Worker return (0);
4107*5e7646d2SAndroid Build Coastguard Worker }
4108*5e7646d2SAndroid Build Coastguard Worker }
4109*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "PASS-IF-DEFINED"))
4110*5e7646d2SAndroid Build Coastguard Worker {
4111*5e7646d2SAndroid Build Coastguard Worker /*
4112*5e7646d2SAndroid Build Coastguard Worker * PASS-IF-DEFINED variable
4113*5e7646d2SAndroid Build Coastguard Worker */
4114*5e7646d2SAndroid Build Coastguard Worker
4115*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, name, sizeof(name)))
4116*5e7646d2SAndroid Build Coastguard Worker {
4117*5e7646d2SAndroid Build Coastguard Worker if (_ippVarsGet(vars, name))
4118*5e7646d2SAndroid Build Coastguard Worker data->pass_test = 1;
4119*5e7646d2SAndroid Build Coastguard Worker }
4120*5e7646d2SAndroid Build Coastguard Worker else
4121*5e7646d2SAndroid Build Coastguard Worker {
4122*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing PASS-IF-DEFINED value on line %d of \"%s\".", f->linenum, f->filename);
4123*5e7646d2SAndroid Build Coastguard Worker return (0);
4124*5e7646d2SAndroid Build Coastguard Worker }
4125*5e7646d2SAndroid Build Coastguard Worker }
4126*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "PASS-IF-NOT-DEFINED"))
4127*5e7646d2SAndroid Build Coastguard Worker {
4128*5e7646d2SAndroid Build Coastguard Worker /*
4129*5e7646d2SAndroid Build Coastguard Worker * PASS-IF-NOT-DEFINED variable
4130*5e7646d2SAndroid Build Coastguard Worker */
4131*5e7646d2SAndroid Build Coastguard Worker
4132*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, name, sizeof(name)))
4133*5e7646d2SAndroid Build Coastguard Worker {
4134*5e7646d2SAndroid Build Coastguard Worker if (!_ippVarsGet(vars, name))
4135*5e7646d2SAndroid Build Coastguard Worker data->pass_test = 1;
4136*5e7646d2SAndroid Build Coastguard Worker }
4137*5e7646d2SAndroid Build Coastguard Worker else
4138*5e7646d2SAndroid Build Coastguard Worker {
4139*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing PASS-IF-NOT-DEFINED value on line %d of \"%s\".", f->linenum, f->filename);
4140*5e7646d2SAndroid Build Coastguard Worker return (0);
4141*5e7646d2SAndroid Build Coastguard Worker }
4142*5e7646d2SAndroid Build Coastguard Worker }
4143*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "SKIP-IF-DEFINED"))
4144*5e7646d2SAndroid Build Coastguard Worker {
4145*5e7646d2SAndroid Build Coastguard Worker /*
4146*5e7646d2SAndroid Build Coastguard Worker * SKIP-IF-DEFINED variable
4147*5e7646d2SAndroid Build Coastguard Worker */
4148*5e7646d2SAndroid Build Coastguard Worker
4149*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, name, sizeof(name)))
4150*5e7646d2SAndroid Build Coastguard Worker {
4151*5e7646d2SAndroid Build Coastguard Worker if (_ippVarsGet(vars, name))
4152*5e7646d2SAndroid Build Coastguard Worker data->skip_test = 1;
4153*5e7646d2SAndroid Build Coastguard Worker }
4154*5e7646d2SAndroid Build Coastguard Worker else
4155*5e7646d2SAndroid Build Coastguard Worker {
4156*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing SKIP-IF-DEFINED value on line %d of \"%s\".", f->linenum, f->filename);
4157*5e7646d2SAndroid Build Coastguard Worker return (0);
4158*5e7646d2SAndroid Build Coastguard Worker }
4159*5e7646d2SAndroid Build Coastguard Worker }
4160*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "SKIP-IF-MISSING"))
4161*5e7646d2SAndroid Build Coastguard Worker {
4162*5e7646d2SAndroid Build Coastguard Worker /*
4163*5e7646d2SAndroid Build Coastguard Worker * SKIP-IF-MISSING filename
4164*5e7646d2SAndroid Build Coastguard Worker */
4165*5e7646d2SAndroid Build Coastguard Worker
4166*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, temp, sizeof(temp)))
4167*5e7646d2SAndroid Build Coastguard Worker {
4168*5e7646d2SAndroid Build Coastguard Worker char filename[1024]; /* Filename */
4169*5e7646d2SAndroid Build Coastguard Worker
4170*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(vars, value, temp, sizeof(value));
4171*5e7646d2SAndroid Build Coastguard Worker get_filename(f->filename, filename, temp, sizeof(filename));
4172*5e7646d2SAndroid Build Coastguard Worker
4173*5e7646d2SAndroid Build Coastguard Worker if (access(filename, R_OK))
4174*5e7646d2SAndroid Build Coastguard Worker data->skip_test = 1;
4175*5e7646d2SAndroid Build Coastguard Worker }
4176*5e7646d2SAndroid Build Coastguard Worker else
4177*5e7646d2SAndroid Build Coastguard Worker {
4178*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing SKIP-IF-MISSING filename on line %d of \"%s\".", f->linenum, f->filename);
4179*5e7646d2SAndroid Build Coastguard Worker return (0);
4180*5e7646d2SAndroid Build Coastguard Worker }
4181*5e7646d2SAndroid Build Coastguard Worker }
4182*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "SKIP-IF-NOT-DEFINED"))
4183*5e7646d2SAndroid Build Coastguard Worker {
4184*5e7646d2SAndroid Build Coastguard Worker /*
4185*5e7646d2SAndroid Build Coastguard Worker * SKIP-IF-NOT-DEFINED variable
4186*5e7646d2SAndroid Build Coastguard Worker */
4187*5e7646d2SAndroid Build Coastguard Worker
4188*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, name, sizeof(name)))
4189*5e7646d2SAndroid Build Coastguard Worker {
4190*5e7646d2SAndroid Build Coastguard Worker if (!_ippVarsGet(vars, name))
4191*5e7646d2SAndroid Build Coastguard Worker data->skip_test = 1;
4192*5e7646d2SAndroid Build Coastguard Worker }
4193*5e7646d2SAndroid Build Coastguard Worker else
4194*5e7646d2SAndroid Build Coastguard Worker {
4195*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing SKIP-IF-NOT-DEFINED value on line %d of \"%s\".", f->linenum, f->filename);
4196*5e7646d2SAndroid Build Coastguard Worker return (0);
4197*5e7646d2SAndroid Build Coastguard Worker }
4198*5e7646d2SAndroid Build Coastguard Worker }
4199*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "SKIP-PREVIOUS-ERROR"))
4200*5e7646d2SAndroid Build Coastguard Worker {
4201*5e7646d2SAndroid Build Coastguard Worker /*
4202*5e7646d2SAndroid Build Coastguard Worker * SKIP-PREVIOUS-ERROR yes
4203*5e7646d2SAndroid Build Coastguard Worker * SKIP-PREVIOUS-ERROR no
4204*5e7646d2SAndroid Build Coastguard Worker */
4205*5e7646d2SAndroid Build Coastguard Worker
4206*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, temp, sizeof(temp)) && (!_cups_strcasecmp(temp, "yes") || !_cups_strcasecmp(temp, "no")))
4207*5e7646d2SAndroid Build Coastguard Worker {
4208*5e7646d2SAndroid Build Coastguard Worker data->skip_previous = !_cups_strcasecmp(temp, "yes");
4209*5e7646d2SAndroid Build Coastguard Worker }
4210*5e7646d2SAndroid Build Coastguard Worker else
4211*5e7646d2SAndroid Build Coastguard Worker {
4212*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing SKIP-PREVIOUS-ERROR value on line %d of \"%s\".", f->linenum, f->filename);
4213*5e7646d2SAndroid Build Coastguard Worker return (0);
4214*5e7646d2SAndroid Build Coastguard Worker }
4215*5e7646d2SAndroid Build Coastguard Worker }
4216*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "TEST-ID"))
4217*5e7646d2SAndroid Build Coastguard Worker {
4218*5e7646d2SAndroid Build Coastguard Worker /*
4219*5e7646d2SAndroid Build Coastguard Worker * TEST-ID "string"
4220*5e7646d2SAndroid Build Coastguard Worker */
4221*5e7646d2SAndroid Build Coastguard Worker
4222*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, temp, sizeof(temp)))
4223*5e7646d2SAndroid Build Coastguard Worker {
4224*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(vars, data->test_id, temp, sizeof(data->test_id));
4225*5e7646d2SAndroid Build Coastguard Worker }
4226*5e7646d2SAndroid Build Coastguard Worker else
4227*5e7646d2SAndroid Build Coastguard Worker {
4228*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing TEST-ID value on line %d of \"%s\".", f->linenum, f->filename);
4229*5e7646d2SAndroid Build Coastguard Worker return (0);
4230*5e7646d2SAndroid Build Coastguard Worker }
4231*5e7646d2SAndroid Build Coastguard Worker }
4232*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "TRANSFER"))
4233*5e7646d2SAndroid Build Coastguard Worker {
4234*5e7646d2SAndroid Build Coastguard Worker /*
4235*5e7646d2SAndroid Build Coastguard Worker * TRANSFER auto
4236*5e7646d2SAndroid Build Coastguard Worker * TRANSFER chunked
4237*5e7646d2SAndroid Build Coastguard Worker * TRANSFER length
4238*5e7646d2SAndroid Build Coastguard Worker */
4239*5e7646d2SAndroid Build Coastguard Worker
4240*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, temp, sizeof(temp)))
4241*5e7646d2SAndroid Build Coastguard Worker {
4242*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(temp, "auto"))
4243*5e7646d2SAndroid Build Coastguard Worker {
4244*5e7646d2SAndroid Build Coastguard Worker data->transfer = IPPTOOL_TRANSFER_AUTO;
4245*5e7646d2SAndroid Build Coastguard Worker }
4246*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(temp, "chunked"))
4247*5e7646d2SAndroid Build Coastguard Worker {
4248*5e7646d2SAndroid Build Coastguard Worker data->transfer = IPPTOOL_TRANSFER_CHUNKED;
4249*5e7646d2SAndroid Build Coastguard Worker }
4250*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(temp, "length"))
4251*5e7646d2SAndroid Build Coastguard Worker {
4252*5e7646d2SAndroid Build Coastguard Worker data->transfer = IPPTOOL_TRANSFER_LENGTH;
4253*5e7646d2SAndroid Build Coastguard Worker }
4254*5e7646d2SAndroid Build Coastguard Worker else
4255*5e7646d2SAndroid Build Coastguard Worker {
4256*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad TRANSFER value \"%s\" on line %d of \"%s\".", temp, f->linenum, f->filename);
4257*5e7646d2SAndroid Build Coastguard Worker return (0);
4258*5e7646d2SAndroid Build Coastguard Worker }
4259*5e7646d2SAndroid Build Coastguard Worker }
4260*5e7646d2SAndroid Build Coastguard Worker else
4261*5e7646d2SAndroid Build Coastguard Worker {
4262*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing TRANSFER value on line %d of \"%s\".", f->linenum, f->filename);
4263*5e7646d2SAndroid Build Coastguard Worker return (0);
4264*5e7646d2SAndroid Build Coastguard Worker }
4265*5e7646d2SAndroid Build Coastguard Worker }
4266*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "VERSION"))
4267*5e7646d2SAndroid Build Coastguard Worker {
4268*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, temp, sizeof(temp)))
4269*5e7646d2SAndroid Build Coastguard Worker {
4270*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(temp, "0.0"))
4271*5e7646d2SAndroid Build Coastguard Worker {
4272*5e7646d2SAndroid Build Coastguard Worker data->version = 0;
4273*5e7646d2SAndroid Build Coastguard Worker }
4274*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(temp, "1.0"))
4275*5e7646d2SAndroid Build Coastguard Worker {
4276*5e7646d2SAndroid Build Coastguard Worker data->version = 10;
4277*5e7646d2SAndroid Build Coastguard Worker }
4278*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(temp, "1.1"))
4279*5e7646d2SAndroid Build Coastguard Worker {
4280*5e7646d2SAndroid Build Coastguard Worker data->version = 11;
4281*5e7646d2SAndroid Build Coastguard Worker }
4282*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(temp, "2.0"))
4283*5e7646d2SAndroid Build Coastguard Worker {
4284*5e7646d2SAndroid Build Coastguard Worker data->version = 20;
4285*5e7646d2SAndroid Build Coastguard Worker }
4286*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(temp, "2.1"))
4287*5e7646d2SAndroid Build Coastguard Worker {
4288*5e7646d2SAndroid Build Coastguard Worker data->version = 21;
4289*5e7646d2SAndroid Build Coastguard Worker }
4290*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(temp, "2.2"))
4291*5e7646d2SAndroid Build Coastguard Worker {
4292*5e7646d2SAndroid Build Coastguard Worker data->version = 22;
4293*5e7646d2SAndroid Build Coastguard Worker }
4294*5e7646d2SAndroid Build Coastguard Worker else
4295*5e7646d2SAndroid Build Coastguard Worker {
4296*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad VERSION \"%s\" on line %d of \"%s\".", temp, f->linenum, f->filename);
4297*5e7646d2SAndroid Build Coastguard Worker return (0);
4298*5e7646d2SAndroid Build Coastguard Worker }
4299*5e7646d2SAndroid Build Coastguard Worker }
4300*5e7646d2SAndroid Build Coastguard Worker else
4301*5e7646d2SAndroid Build Coastguard Worker {
4302*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing VERSION number on line %d of \"%s\".", f->linenum, f->filename);
4303*5e7646d2SAndroid Build Coastguard Worker return (0);
4304*5e7646d2SAndroid Build Coastguard Worker }
4305*5e7646d2SAndroid Build Coastguard Worker }
4306*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "RESOURCE"))
4307*5e7646d2SAndroid Build Coastguard Worker {
4308*5e7646d2SAndroid Build Coastguard Worker /*
4309*5e7646d2SAndroid Build Coastguard Worker * Resource name...
4310*5e7646d2SAndroid Build Coastguard Worker */
4311*5e7646d2SAndroid Build Coastguard Worker
4312*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, data->resource, sizeof(data->resource)))
4313*5e7646d2SAndroid Build Coastguard Worker {
4314*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing RESOURCE path on line %d of \"%s\".", f->linenum, f->filename);
4315*5e7646d2SAndroid Build Coastguard Worker return (0);
4316*5e7646d2SAndroid Build Coastguard Worker }
4317*5e7646d2SAndroid Build Coastguard Worker }
4318*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "OPERATION"))
4319*5e7646d2SAndroid Build Coastguard Worker {
4320*5e7646d2SAndroid Build Coastguard Worker /*
4321*5e7646d2SAndroid Build Coastguard Worker * Operation...
4322*5e7646d2SAndroid Build Coastguard Worker */
4323*5e7646d2SAndroid Build Coastguard Worker
4324*5e7646d2SAndroid Build Coastguard Worker ipp_op_t op; /* Operation code */
4325*5e7646d2SAndroid Build Coastguard Worker
4326*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4327*5e7646d2SAndroid Build Coastguard Worker {
4328*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing OPERATION code on line %d of \"%s\".", f->linenum, f->filename);
4329*5e7646d2SAndroid Build Coastguard Worker return (0);
4330*5e7646d2SAndroid Build Coastguard Worker }
4331*5e7646d2SAndroid Build Coastguard Worker
4332*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(vars, value, temp, sizeof(value));
4333*5e7646d2SAndroid Build Coastguard Worker
4334*5e7646d2SAndroid Build Coastguard Worker if ((op = ippOpValue(value)) == (ipp_op_t)-1 && (op = (ipp_op_t)strtol(value, NULL, 0)) == 0)
4335*5e7646d2SAndroid Build Coastguard Worker {
4336*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad OPERATION code \"%s\" on line %d of \"%s\".", temp, f->linenum, f->filename);
4337*5e7646d2SAndroid Build Coastguard Worker return (0);
4338*5e7646d2SAndroid Build Coastguard Worker }
4339*5e7646d2SAndroid Build Coastguard Worker
4340*5e7646d2SAndroid Build Coastguard Worker ippSetOperation(f->attrs, op);
4341*5e7646d2SAndroid Build Coastguard Worker }
4342*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "GROUP"))
4343*5e7646d2SAndroid Build Coastguard Worker {
4344*5e7646d2SAndroid Build Coastguard Worker /*
4345*5e7646d2SAndroid Build Coastguard Worker * Attribute group...
4346*5e7646d2SAndroid Build Coastguard Worker */
4347*5e7646d2SAndroid Build Coastguard Worker
4348*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t group_tag; /* Group tag */
4349*5e7646d2SAndroid Build Coastguard Worker
4350*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4351*5e7646d2SAndroid Build Coastguard Worker {
4352*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing GROUP tag on line %d of \"%s\".", f->linenum, f->filename);
4353*5e7646d2SAndroid Build Coastguard Worker return (0);
4354*5e7646d2SAndroid Build Coastguard Worker }
4355*5e7646d2SAndroid Build Coastguard Worker
4356*5e7646d2SAndroid Build Coastguard Worker if ((group_tag = ippTagValue(temp)) == IPP_TAG_ZERO || group_tag >= IPP_TAG_UNSUPPORTED_VALUE)
4357*5e7646d2SAndroid Build Coastguard Worker {
4358*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad GROUP tag \"%s\" on line %d of \"%s\".", temp, f->linenum, f->filename);
4359*5e7646d2SAndroid Build Coastguard Worker return (0);
4360*5e7646d2SAndroid Build Coastguard Worker }
4361*5e7646d2SAndroid Build Coastguard Worker
4362*5e7646d2SAndroid Build Coastguard Worker if (group_tag == f->group_tag)
4363*5e7646d2SAndroid Build Coastguard Worker ippAddSeparator(f->attrs);
4364*5e7646d2SAndroid Build Coastguard Worker
4365*5e7646d2SAndroid Build Coastguard Worker f->group_tag = group_tag;
4366*5e7646d2SAndroid Build Coastguard Worker }
4367*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "DELAY"))
4368*5e7646d2SAndroid Build Coastguard Worker {
4369*5e7646d2SAndroid Build Coastguard Worker /*
4370*5e7646d2SAndroid Build Coastguard Worker * Delay before operation...
4371*5e7646d2SAndroid Build Coastguard Worker */
4372*5e7646d2SAndroid Build Coastguard Worker
4373*5e7646d2SAndroid Build Coastguard Worker double dval; /* Delay value */
4374*5e7646d2SAndroid Build Coastguard Worker
4375*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4376*5e7646d2SAndroid Build Coastguard Worker {
4377*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing DELAY value on line %d of \"%s\".", f->linenum, f->filename);
4378*5e7646d2SAndroid Build Coastguard Worker return (0);
4379*5e7646d2SAndroid Build Coastguard Worker }
4380*5e7646d2SAndroid Build Coastguard Worker
4381*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(vars, value, temp, sizeof(value));
4382*5e7646d2SAndroid Build Coastguard Worker
4383*5e7646d2SAndroid Build Coastguard Worker if ((dval = _cupsStrScand(value, &ptr, localeconv())) < 0.0 || (*ptr && *ptr != ','))
4384*5e7646d2SAndroid Build Coastguard Worker {
4385*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad DELAY value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename);
4386*5e7646d2SAndroid Build Coastguard Worker return (0);
4387*5e7646d2SAndroid Build Coastguard Worker }
4388*5e7646d2SAndroid Build Coastguard Worker
4389*5e7646d2SAndroid Build Coastguard Worker data->delay = (useconds_t)(1000000.0 * dval);
4390*5e7646d2SAndroid Build Coastguard Worker
4391*5e7646d2SAndroid Build Coastguard Worker if (*ptr == ',')
4392*5e7646d2SAndroid Build Coastguard Worker {
4393*5e7646d2SAndroid Build Coastguard Worker if ((dval = _cupsStrScand(ptr + 1, &ptr, localeconv())) <= 0.0 || *ptr)
4394*5e7646d2SAndroid Build Coastguard Worker {
4395*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad DELAY value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename);
4396*5e7646d2SAndroid Build Coastguard Worker return (0);
4397*5e7646d2SAndroid Build Coastguard Worker }
4398*5e7646d2SAndroid Build Coastguard Worker
4399*5e7646d2SAndroid Build Coastguard Worker data->repeat_interval = (useconds_t)(1000000.0 * dval);
4400*5e7646d2SAndroid Build Coastguard Worker }
4401*5e7646d2SAndroid Build Coastguard Worker else
4402*5e7646d2SAndroid Build Coastguard Worker data->repeat_interval = data->delay;
4403*5e7646d2SAndroid Build Coastguard Worker }
4404*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "FILE"))
4405*5e7646d2SAndroid Build Coastguard Worker {
4406*5e7646d2SAndroid Build Coastguard Worker /*
4407*5e7646d2SAndroid Build Coastguard Worker * File...
4408*5e7646d2SAndroid Build Coastguard Worker */
4409*5e7646d2SAndroid Build Coastguard Worker
4410*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4411*5e7646d2SAndroid Build Coastguard Worker {
4412*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing FILE filename on line %d of \"%s\".", f->linenum, f->filename);
4413*5e7646d2SAndroid Build Coastguard Worker return (0);
4414*5e7646d2SAndroid Build Coastguard Worker }
4415*5e7646d2SAndroid Build Coastguard Worker
4416*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(vars, value, temp, sizeof(value));
4417*5e7646d2SAndroid Build Coastguard Worker get_filename(f->filename, data->file, value, sizeof(data->file));
4418*5e7646d2SAndroid Build Coastguard Worker
4419*5e7646d2SAndroid Build Coastguard Worker if (access(data->file, R_OK))
4420*5e7646d2SAndroid Build Coastguard Worker {
4421*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Filename \"%s\" (mapped to \"%s\") on line %d of \"%s\" cannot be read.", value, data->file, f->linenum, f->filename);
4422*5e7646d2SAndroid Build Coastguard Worker return (0);
4423*5e7646d2SAndroid Build Coastguard Worker }
4424*5e7646d2SAndroid Build Coastguard Worker }
4425*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "STATUS"))
4426*5e7646d2SAndroid Build Coastguard Worker {
4427*5e7646d2SAndroid Build Coastguard Worker /*
4428*5e7646d2SAndroid Build Coastguard Worker * Status...
4429*5e7646d2SAndroid Build Coastguard Worker */
4430*5e7646d2SAndroid Build Coastguard Worker
4431*5e7646d2SAndroid Build Coastguard Worker if (data->num_statuses >= (int)(sizeof(data->statuses) / sizeof(data->statuses[0])))
4432*5e7646d2SAndroid Build Coastguard Worker {
4433*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Too many STATUS's on line %d of \"%s\".", f->linenum, f->filename);
4434*5e7646d2SAndroid Build Coastguard Worker return (0);
4435*5e7646d2SAndroid Build Coastguard Worker }
4436*5e7646d2SAndroid Build Coastguard Worker
4437*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4438*5e7646d2SAndroid Build Coastguard Worker {
4439*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing STATUS code on line %d of \"%s\".", f->linenum, f->filename);
4440*5e7646d2SAndroid Build Coastguard Worker return (0);
4441*5e7646d2SAndroid Build Coastguard Worker }
4442*5e7646d2SAndroid Build Coastguard Worker
4443*5e7646d2SAndroid Build Coastguard Worker if ((data->statuses[data->num_statuses].status = ippErrorValue(temp)) == (ipp_status_t)-1 && (data->statuses[data->num_statuses].status = (ipp_status_t)strtol(temp, NULL, 0)) == 0)
4444*5e7646d2SAndroid Build Coastguard Worker {
4445*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad STATUS code \"%s\" on line %d of \"%s\".", temp, f->linenum, f->filename);
4446*5e7646d2SAndroid Build Coastguard Worker return (0);
4447*5e7646d2SAndroid Build Coastguard Worker }
4448*5e7646d2SAndroid Build Coastguard Worker
4449*5e7646d2SAndroid Build Coastguard Worker data->last_status = data->statuses + data->num_statuses;
4450*5e7646d2SAndroid Build Coastguard Worker data->num_statuses ++;
4451*5e7646d2SAndroid Build Coastguard Worker
4452*5e7646d2SAndroid Build Coastguard Worker data->last_status->define_match = NULL;
4453*5e7646d2SAndroid Build Coastguard Worker data->last_status->define_no_match = NULL;
4454*5e7646d2SAndroid Build Coastguard Worker data->last_status->if_defined = NULL;
4455*5e7646d2SAndroid Build Coastguard Worker data->last_status->if_not_defined = NULL;
4456*5e7646d2SAndroid Build Coastguard Worker data->last_status->repeat_limit = 1000;
4457*5e7646d2SAndroid Build Coastguard Worker data->last_status->repeat_match = 0;
4458*5e7646d2SAndroid Build Coastguard Worker data->last_status->repeat_no_match = 0;
4459*5e7646d2SAndroid Build Coastguard Worker }
4460*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "EXPECT") || !_cups_strcasecmp(token, "EXPECT-ALL"))
4461*5e7646d2SAndroid Build Coastguard Worker {
4462*5e7646d2SAndroid Build Coastguard Worker /*
4463*5e7646d2SAndroid Build Coastguard Worker * Expected attributes...
4464*5e7646d2SAndroid Build Coastguard Worker */
4465*5e7646d2SAndroid Build Coastguard Worker
4466*5e7646d2SAndroid Build Coastguard Worker int expect_all = !_cups_strcasecmp(token, "EXPECT-ALL");
4467*5e7646d2SAndroid Build Coastguard Worker
4468*5e7646d2SAndroid Build Coastguard Worker if (data->num_expects >= (int)(sizeof(data->expects) / sizeof(data->expects[0])))
4469*5e7646d2SAndroid Build Coastguard Worker {
4470*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Too many EXPECT's on line %d of \"%s\".", f->linenum, f->filename);
4471*5e7646d2SAndroid Build Coastguard Worker return (0);
4472*5e7646d2SAndroid Build Coastguard Worker }
4473*5e7646d2SAndroid Build Coastguard Worker
4474*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, name, sizeof(name)))
4475*5e7646d2SAndroid Build Coastguard Worker {
4476*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing EXPECT name on line %d of \"%s\".", f->linenum, f->filename);
4477*5e7646d2SAndroid Build Coastguard Worker return (0);
4478*5e7646d2SAndroid Build Coastguard Worker }
4479*5e7646d2SAndroid Build Coastguard Worker
4480*5e7646d2SAndroid Build Coastguard Worker data->last_expect = data->expects + data->num_expects;
4481*5e7646d2SAndroid Build Coastguard Worker data->num_expects ++;
4482*5e7646d2SAndroid Build Coastguard Worker
4483*5e7646d2SAndroid Build Coastguard Worker memset(data->last_expect, 0, sizeof(ipptool_expect_t));
4484*5e7646d2SAndroid Build Coastguard Worker data->last_expect->repeat_limit = 1000;
4485*5e7646d2SAndroid Build Coastguard Worker data->last_expect->expect_all = expect_all;
4486*5e7646d2SAndroid Build Coastguard Worker
4487*5e7646d2SAndroid Build Coastguard Worker if (name[0] == '!')
4488*5e7646d2SAndroid Build Coastguard Worker {
4489*5e7646d2SAndroid Build Coastguard Worker data->last_expect->not_expect = 1;
4490*5e7646d2SAndroid Build Coastguard Worker data->last_expect->name = strdup(name + 1);
4491*5e7646d2SAndroid Build Coastguard Worker }
4492*5e7646d2SAndroid Build Coastguard Worker else if (name[0] == '?')
4493*5e7646d2SAndroid Build Coastguard Worker {
4494*5e7646d2SAndroid Build Coastguard Worker data->last_expect->optional = 1;
4495*5e7646d2SAndroid Build Coastguard Worker data->last_expect->name = strdup(name + 1);
4496*5e7646d2SAndroid Build Coastguard Worker }
4497*5e7646d2SAndroid Build Coastguard Worker else
4498*5e7646d2SAndroid Build Coastguard Worker data->last_expect->name = strdup(name);
4499*5e7646d2SAndroid Build Coastguard Worker }
4500*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "COUNT"))
4501*5e7646d2SAndroid Build Coastguard Worker {
4502*5e7646d2SAndroid Build Coastguard Worker int count; /* Count value */
4503*5e7646d2SAndroid Build Coastguard Worker
4504*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4505*5e7646d2SAndroid Build Coastguard Worker {
4506*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing COUNT number on line %d of \"%s\".", f->linenum, f->filename);
4507*5e7646d2SAndroid Build Coastguard Worker return (0);
4508*5e7646d2SAndroid Build Coastguard Worker }
4509*5e7646d2SAndroid Build Coastguard Worker
4510*5e7646d2SAndroid Build Coastguard Worker if ((count = atoi(temp)) <= 0)
4511*5e7646d2SAndroid Build Coastguard Worker {
4512*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad COUNT \"%s\" on line %d of \"%s\".", temp, f->linenum, f->filename);
4513*5e7646d2SAndroid Build Coastguard Worker return (0);
4514*5e7646d2SAndroid Build Coastguard Worker }
4515*5e7646d2SAndroid Build Coastguard Worker
4516*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
4517*5e7646d2SAndroid Build Coastguard Worker {
4518*5e7646d2SAndroid Build Coastguard Worker data->last_expect->count = count;
4519*5e7646d2SAndroid Build Coastguard Worker }
4520*5e7646d2SAndroid Build Coastguard Worker else
4521*5e7646d2SAndroid Build Coastguard Worker {
4522*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "COUNT without a preceding EXPECT on line %d of \"%s\".", f->linenum, f->filename);
4523*5e7646d2SAndroid Build Coastguard Worker return (0);
4524*5e7646d2SAndroid Build Coastguard Worker }
4525*5e7646d2SAndroid Build Coastguard Worker }
4526*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "DEFINE-MATCH"))
4527*5e7646d2SAndroid Build Coastguard Worker {
4528*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4529*5e7646d2SAndroid Build Coastguard Worker {
4530*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing DEFINE-MATCH variable on line %d of \"%s\".", f->linenum, f->filename);
4531*5e7646d2SAndroid Build Coastguard Worker return (0);
4532*5e7646d2SAndroid Build Coastguard Worker }
4533*5e7646d2SAndroid Build Coastguard Worker
4534*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
4535*5e7646d2SAndroid Build Coastguard Worker {
4536*5e7646d2SAndroid Build Coastguard Worker data->last_expect->define_match = strdup(temp);
4537*5e7646d2SAndroid Build Coastguard Worker }
4538*5e7646d2SAndroid Build Coastguard Worker else if (data->last_status)
4539*5e7646d2SAndroid Build Coastguard Worker {
4540*5e7646d2SAndroid Build Coastguard Worker data->last_status->define_match = strdup(temp);
4541*5e7646d2SAndroid Build Coastguard Worker }
4542*5e7646d2SAndroid Build Coastguard Worker else
4543*5e7646d2SAndroid Build Coastguard Worker {
4544*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "DEFINE-MATCH without a preceding EXPECT or STATUS on line %d of \"%s\".", f->linenum, f->filename);
4545*5e7646d2SAndroid Build Coastguard Worker return (0);
4546*5e7646d2SAndroid Build Coastguard Worker }
4547*5e7646d2SAndroid Build Coastguard Worker }
4548*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "DEFINE-NO-MATCH"))
4549*5e7646d2SAndroid Build Coastguard Worker {
4550*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4551*5e7646d2SAndroid Build Coastguard Worker {
4552*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing DEFINE-NO-MATCH variable on line %d of \"%s\".", f->linenum, f->filename);
4553*5e7646d2SAndroid Build Coastguard Worker return (0);
4554*5e7646d2SAndroid Build Coastguard Worker }
4555*5e7646d2SAndroid Build Coastguard Worker
4556*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
4557*5e7646d2SAndroid Build Coastguard Worker {
4558*5e7646d2SAndroid Build Coastguard Worker data->last_expect->define_no_match = strdup(temp);
4559*5e7646d2SAndroid Build Coastguard Worker }
4560*5e7646d2SAndroid Build Coastguard Worker else if (data->last_status)
4561*5e7646d2SAndroid Build Coastguard Worker {
4562*5e7646d2SAndroid Build Coastguard Worker data->last_status->define_no_match = strdup(temp);
4563*5e7646d2SAndroid Build Coastguard Worker }
4564*5e7646d2SAndroid Build Coastguard Worker else
4565*5e7646d2SAndroid Build Coastguard Worker {
4566*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "DEFINE-NO-MATCH without a preceding EXPECT or STATUS on line %d of \"%s\".", f->linenum, f->filename);
4567*5e7646d2SAndroid Build Coastguard Worker return (0);
4568*5e7646d2SAndroid Build Coastguard Worker }
4569*5e7646d2SAndroid Build Coastguard Worker }
4570*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "DEFINE-VALUE"))
4571*5e7646d2SAndroid Build Coastguard Worker {
4572*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4573*5e7646d2SAndroid Build Coastguard Worker {
4574*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing DEFINE-VALUE variable on line %d of \"%s\".", f->linenum, f->filename);
4575*5e7646d2SAndroid Build Coastguard Worker return (0);
4576*5e7646d2SAndroid Build Coastguard Worker }
4577*5e7646d2SAndroid Build Coastguard Worker
4578*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
4579*5e7646d2SAndroid Build Coastguard Worker {
4580*5e7646d2SAndroid Build Coastguard Worker data->last_expect->define_value = strdup(temp);
4581*5e7646d2SAndroid Build Coastguard Worker }
4582*5e7646d2SAndroid Build Coastguard Worker else
4583*5e7646d2SAndroid Build Coastguard Worker {
4584*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "DEFINE-VALUE without a preceding EXPECT on line %d of \"%s\".", f->linenum, f->filename);
4585*5e7646d2SAndroid Build Coastguard Worker return (0);
4586*5e7646d2SAndroid Build Coastguard Worker }
4587*5e7646d2SAndroid Build Coastguard Worker }
4588*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "DISPLAY-MATCH"))
4589*5e7646d2SAndroid Build Coastguard Worker {
4590*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4591*5e7646d2SAndroid Build Coastguard Worker {
4592*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing DISPLAY-MATCH mesaage on line %d of \"%s\".", f->linenum, f->filename);
4593*5e7646d2SAndroid Build Coastguard Worker return (0);
4594*5e7646d2SAndroid Build Coastguard Worker }
4595*5e7646d2SAndroid Build Coastguard Worker
4596*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
4597*5e7646d2SAndroid Build Coastguard Worker {
4598*5e7646d2SAndroid Build Coastguard Worker data->last_expect->display_match = strdup(temp);
4599*5e7646d2SAndroid Build Coastguard Worker }
4600*5e7646d2SAndroid Build Coastguard Worker else
4601*5e7646d2SAndroid Build Coastguard Worker {
4602*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "DISPLAY-MATCH without a preceding EXPECT on line %d of \"%s\".", f->linenum, f->filename);
4603*5e7646d2SAndroid Build Coastguard Worker return (0);
4604*5e7646d2SAndroid Build Coastguard Worker }
4605*5e7646d2SAndroid Build Coastguard Worker }
4606*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "OF-TYPE"))
4607*5e7646d2SAndroid Build Coastguard Worker {
4608*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4609*5e7646d2SAndroid Build Coastguard Worker {
4610*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing OF-TYPE value tag(s) on line %d of \"%s\".", f->linenum, f->filename);
4611*5e7646d2SAndroid Build Coastguard Worker return (0);
4612*5e7646d2SAndroid Build Coastguard Worker }
4613*5e7646d2SAndroid Build Coastguard Worker
4614*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
4615*5e7646d2SAndroid Build Coastguard Worker {
4616*5e7646d2SAndroid Build Coastguard Worker data->last_expect->of_type = strdup(temp);
4617*5e7646d2SAndroid Build Coastguard Worker }
4618*5e7646d2SAndroid Build Coastguard Worker else
4619*5e7646d2SAndroid Build Coastguard Worker {
4620*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "OF-TYPE without a preceding EXPECT on line %d of \"%s\".", f->linenum, f->filename);
4621*5e7646d2SAndroid Build Coastguard Worker return (0);
4622*5e7646d2SAndroid Build Coastguard Worker }
4623*5e7646d2SAndroid Build Coastguard Worker }
4624*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "IN-GROUP"))
4625*5e7646d2SAndroid Build Coastguard Worker {
4626*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t in_group; /* IN-GROUP value */
4627*5e7646d2SAndroid Build Coastguard Worker
4628*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4629*5e7646d2SAndroid Build Coastguard Worker {
4630*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing IN-GROUP group tag on line %d of \"%s\".", f->linenum, f->filename);
4631*5e7646d2SAndroid Build Coastguard Worker return (0);
4632*5e7646d2SAndroid Build Coastguard Worker }
4633*5e7646d2SAndroid Build Coastguard Worker
4634*5e7646d2SAndroid Build Coastguard Worker if ((in_group = ippTagValue(temp)) == IPP_TAG_ZERO || in_group >= IPP_TAG_UNSUPPORTED_VALUE)
4635*5e7646d2SAndroid Build Coastguard Worker {
4636*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad IN-GROUP group tag \"%s\" on line %d of \"%s\".", temp, f->linenum, f->filename);
4637*5e7646d2SAndroid Build Coastguard Worker return (0);
4638*5e7646d2SAndroid Build Coastguard Worker }
4639*5e7646d2SAndroid Build Coastguard Worker else if (data->last_expect)
4640*5e7646d2SAndroid Build Coastguard Worker {
4641*5e7646d2SAndroid Build Coastguard Worker data->last_expect->in_group = in_group;
4642*5e7646d2SAndroid Build Coastguard Worker }
4643*5e7646d2SAndroid Build Coastguard Worker else
4644*5e7646d2SAndroid Build Coastguard Worker {
4645*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "IN-GROUP without a preceding EXPECT on line %d of \"%s\".", f->linenum, f->filename);
4646*5e7646d2SAndroid Build Coastguard Worker return (0);
4647*5e7646d2SAndroid Build Coastguard Worker }
4648*5e7646d2SAndroid Build Coastguard Worker }
4649*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "REPEAT-LIMIT"))
4650*5e7646d2SAndroid Build Coastguard Worker {
4651*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4652*5e7646d2SAndroid Build Coastguard Worker {
4653*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing REPEAT-LIMIT value on line %d of \"%s\".", f->linenum, f->filename);
4654*5e7646d2SAndroid Build Coastguard Worker return (0);
4655*5e7646d2SAndroid Build Coastguard Worker }
4656*5e7646d2SAndroid Build Coastguard Worker else if (atoi(temp) <= 0)
4657*5e7646d2SAndroid Build Coastguard Worker {
4658*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad REPEAT-LIMIT value on line %d of \"%s\".", f->linenum, f->filename);
4659*5e7646d2SAndroid Build Coastguard Worker return (0);
4660*5e7646d2SAndroid Build Coastguard Worker }
4661*5e7646d2SAndroid Build Coastguard Worker
4662*5e7646d2SAndroid Build Coastguard Worker if (data->last_status)
4663*5e7646d2SAndroid Build Coastguard Worker {
4664*5e7646d2SAndroid Build Coastguard Worker data->last_status->repeat_limit = atoi(temp);
4665*5e7646d2SAndroid Build Coastguard Worker }
4666*5e7646d2SAndroid Build Coastguard Worker else if (data->last_expect)
4667*5e7646d2SAndroid Build Coastguard Worker {
4668*5e7646d2SAndroid Build Coastguard Worker data->last_expect->repeat_limit = atoi(temp);
4669*5e7646d2SAndroid Build Coastguard Worker }
4670*5e7646d2SAndroid Build Coastguard Worker else
4671*5e7646d2SAndroid Build Coastguard Worker {
4672*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "REPEAT-LIMIT without a preceding EXPECT or STATUS on line %d of \"%s\".", f->linenum, f->filename);
4673*5e7646d2SAndroid Build Coastguard Worker return (0);
4674*5e7646d2SAndroid Build Coastguard Worker }
4675*5e7646d2SAndroid Build Coastguard Worker }
4676*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "REPEAT-MATCH"))
4677*5e7646d2SAndroid Build Coastguard Worker {
4678*5e7646d2SAndroid Build Coastguard Worker if (data->last_status)
4679*5e7646d2SAndroid Build Coastguard Worker {
4680*5e7646d2SAndroid Build Coastguard Worker data->last_status->repeat_match = 1;
4681*5e7646d2SAndroid Build Coastguard Worker }
4682*5e7646d2SAndroid Build Coastguard Worker else if (data->last_expect)
4683*5e7646d2SAndroid Build Coastguard Worker {
4684*5e7646d2SAndroid Build Coastguard Worker data->last_expect->repeat_match = 1;
4685*5e7646d2SAndroid Build Coastguard Worker }
4686*5e7646d2SAndroid Build Coastguard Worker else
4687*5e7646d2SAndroid Build Coastguard Worker {
4688*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "REPEAT-MATCH without a preceding EXPECT or STATUS on line %d of \"%s\".", f->linenum, f->filename);
4689*5e7646d2SAndroid Build Coastguard Worker return (0);
4690*5e7646d2SAndroid Build Coastguard Worker }
4691*5e7646d2SAndroid Build Coastguard Worker }
4692*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "REPEAT-NO-MATCH"))
4693*5e7646d2SAndroid Build Coastguard Worker {
4694*5e7646d2SAndroid Build Coastguard Worker if (data->last_status)
4695*5e7646d2SAndroid Build Coastguard Worker {
4696*5e7646d2SAndroid Build Coastguard Worker data->last_status->repeat_no_match = 1;
4697*5e7646d2SAndroid Build Coastguard Worker }
4698*5e7646d2SAndroid Build Coastguard Worker else if (data->last_expect)
4699*5e7646d2SAndroid Build Coastguard Worker {
4700*5e7646d2SAndroid Build Coastguard Worker data->last_expect->repeat_no_match = 1;
4701*5e7646d2SAndroid Build Coastguard Worker }
4702*5e7646d2SAndroid Build Coastguard Worker else
4703*5e7646d2SAndroid Build Coastguard Worker {
4704*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "REPEAT-NO-MATCH without a preceding EXPECT or STATUS on line %d of \"%s\".", f->linenum, f->filename);
4705*5e7646d2SAndroid Build Coastguard Worker return (0);
4706*5e7646d2SAndroid Build Coastguard Worker }
4707*5e7646d2SAndroid Build Coastguard Worker }
4708*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "SAME-COUNT-AS"))
4709*5e7646d2SAndroid Build Coastguard Worker {
4710*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4711*5e7646d2SAndroid Build Coastguard Worker {
4712*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing SAME-COUNT-AS name on line %d of \"%s\".", f->linenum, f->filename);
4713*5e7646d2SAndroid Build Coastguard Worker return (0);
4714*5e7646d2SAndroid Build Coastguard Worker }
4715*5e7646d2SAndroid Build Coastguard Worker
4716*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
4717*5e7646d2SAndroid Build Coastguard Worker {
4718*5e7646d2SAndroid Build Coastguard Worker data->last_expect->same_count_as = strdup(temp);
4719*5e7646d2SAndroid Build Coastguard Worker }
4720*5e7646d2SAndroid Build Coastguard Worker else
4721*5e7646d2SAndroid Build Coastguard Worker {
4722*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "SAME-COUNT-AS without a preceding EXPECT on line %d of \"%s\".", f->linenum, f->filename);
4723*5e7646d2SAndroid Build Coastguard Worker return (0);
4724*5e7646d2SAndroid Build Coastguard Worker }
4725*5e7646d2SAndroid Build Coastguard Worker }
4726*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "IF-DEFINED"))
4727*5e7646d2SAndroid Build Coastguard Worker {
4728*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4729*5e7646d2SAndroid Build Coastguard Worker {
4730*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing IF-DEFINED name on line %d of \"%s\".", f->linenum, f->filename);
4731*5e7646d2SAndroid Build Coastguard Worker return (0);
4732*5e7646d2SAndroid Build Coastguard Worker }
4733*5e7646d2SAndroid Build Coastguard Worker
4734*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
4735*5e7646d2SAndroid Build Coastguard Worker {
4736*5e7646d2SAndroid Build Coastguard Worker data->last_expect->if_defined = strdup(temp);
4737*5e7646d2SAndroid Build Coastguard Worker }
4738*5e7646d2SAndroid Build Coastguard Worker else if (data->last_status)
4739*5e7646d2SAndroid Build Coastguard Worker {
4740*5e7646d2SAndroid Build Coastguard Worker data->last_status->if_defined = strdup(temp);
4741*5e7646d2SAndroid Build Coastguard Worker }
4742*5e7646d2SAndroid Build Coastguard Worker else
4743*5e7646d2SAndroid Build Coastguard Worker {
4744*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "IF-DEFINED without a preceding EXPECT or STATUS on line %d of \"%s\".", f->linenum, f->filename);
4745*5e7646d2SAndroid Build Coastguard Worker return (0);
4746*5e7646d2SAndroid Build Coastguard Worker }
4747*5e7646d2SAndroid Build Coastguard Worker }
4748*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "IF-NOT-DEFINED"))
4749*5e7646d2SAndroid Build Coastguard Worker {
4750*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4751*5e7646d2SAndroid Build Coastguard Worker {
4752*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing IF-NOT-DEFINED name on line %d of \"%s\".", f->linenum, f->filename);
4753*5e7646d2SAndroid Build Coastguard Worker return (0);
4754*5e7646d2SAndroid Build Coastguard Worker }
4755*5e7646d2SAndroid Build Coastguard Worker
4756*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
4757*5e7646d2SAndroid Build Coastguard Worker {
4758*5e7646d2SAndroid Build Coastguard Worker data->last_expect->if_not_defined = strdup(temp);
4759*5e7646d2SAndroid Build Coastguard Worker }
4760*5e7646d2SAndroid Build Coastguard Worker else if (data->last_status)
4761*5e7646d2SAndroid Build Coastguard Worker {
4762*5e7646d2SAndroid Build Coastguard Worker data->last_status->if_not_defined = strdup(temp);
4763*5e7646d2SAndroid Build Coastguard Worker }
4764*5e7646d2SAndroid Build Coastguard Worker else
4765*5e7646d2SAndroid Build Coastguard Worker {
4766*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "IF-NOT-DEFINED without a preceding EXPECT or STATUS on line %d of \"%s\".", f->linenum, f->filename);
4767*5e7646d2SAndroid Build Coastguard Worker return (0);
4768*5e7646d2SAndroid Build Coastguard Worker }
4769*5e7646d2SAndroid Build Coastguard Worker }
4770*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "WITH-DISTINCT-VALUES"))
4771*5e7646d2SAndroid Build Coastguard Worker {
4772*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
4773*5e7646d2SAndroid Build Coastguard Worker {
4774*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_distinct = 1;
4775*5e7646d2SAndroid Build Coastguard Worker }
4776*5e7646d2SAndroid Build Coastguard Worker else
4777*5e7646d2SAndroid Build Coastguard Worker {
4778*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "%s without a preceding EXPECT on line %d of \"%s\".", token, f->linenum, f->filename);
4779*5e7646d2SAndroid Build Coastguard Worker return (0);
4780*5e7646d2SAndroid Build Coastguard Worker }
4781*5e7646d2SAndroid Build Coastguard Worker }
4782*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "WITH-ALL-VALUES") ||
4783*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(token, "WITH-ALL-HOSTNAMES") ||
4784*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(token, "WITH-ALL-RESOURCES") ||
4785*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(token, "WITH-ALL-SCHEMES") ||
4786*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(token, "WITH-HOSTNAME") ||
4787*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(token, "WITH-RESOURCE") ||
4788*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(token, "WITH-SCHEME") ||
4789*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(token, "WITH-VALUE"))
4790*5e7646d2SAndroid Build Coastguard Worker {
4791*5e7646d2SAndroid Build Coastguard Worker off_t lastpos; /* Last file position */
4792*5e7646d2SAndroid Build Coastguard Worker int lastline; /* Last line number */
4793*5e7646d2SAndroid Build Coastguard Worker
4794*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
4795*5e7646d2SAndroid Build Coastguard Worker {
4796*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(token, "WITH-ALL-HOSTNAMES") || !_cups_strcasecmp(token, "WITH-HOSTNAME"))
4797*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_flags = IPPTOOL_WITH_HOSTNAME;
4798*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "WITH-ALL-RESOURCES") || !_cups_strcasecmp(token, "WITH-RESOURCE"))
4799*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_flags = IPPTOOL_WITH_RESOURCE;
4800*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "WITH-ALL-SCHEMES") || !_cups_strcasecmp(token, "WITH-SCHEME"))
4801*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_flags = IPPTOOL_WITH_SCHEME;
4802*5e7646d2SAndroid Build Coastguard Worker
4803*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(token, "WITH-ALL-", 9))
4804*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_flags |= IPPTOOL_WITH_ALL;
4805*5e7646d2SAndroid Build Coastguard Worker }
4806*5e7646d2SAndroid Build Coastguard Worker
4807*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4808*5e7646d2SAndroid Build Coastguard Worker {
4809*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing %s value on line %d of \"%s\".", token, f->linenum, f->filename);
4810*5e7646d2SAndroid Build Coastguard Worker return (0);
4811*5e7646d2SAndroid Build Coastguard Worker }
4812*5e7646d2SAndroid Build Coastguard Worker
4813*5e7646d2SAndroid Build Coastguard Worker /*
4814*5e7646d2SAndroid Build Coastguard Worker * Read additional comma-delimited values - needed since legacy test files
4815*5e7646d2SAndroid Build Coastguard Worker * will have unquoted WITH-VALUE values with commas...
4816*5e7646d2SAndroid Build Coastguard Worker */
4817*5e7646d2SAndroid Build Coastguard Worker
4818*5e7646d2SAndroid Build Coastguard Worker ptr = temp + strlen(temp);
4819*5e7646d2SAndroid Build Coastguard Worker
4820*5e7646d2SAndroid Build Coastguard Worker for (;;)
4821*5e7646d2SAndroid Build Coastguard Worker {
4822*5e7646d2SAndroid Build Coastguard Worker lastpos = cupsFileTell(f->fp);
4823*5e7646d2SAndroid Build Coastguard Worker lastline = f->linenum;
4824*5e7646d2SAndroid Build Coastguard Worker ptr += strlen(ptr);
4825*5e7646d2SAndroid Build Coastguard Worker
4826*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, ptr, (sizeof(temp) - (size_t)(ptr - temp))))
4827*5e7646d2SAndroid Build Coastguard Worker break;
4828*5e7646d2SAndroid Build Coastguard Worker
4829*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(ptr, ","))
4830*5e7646d2SAndroid Build Coastguard Worker {
4831*5e7646d2SAndroid Build Coastguard Worker /*
4832*5e7646d2SAndroid Build Coastguard Worker * Append a value...
4833*5e7646d2SAndroid Build Coastguard Worker */
4834*5e7646d2SAndroid Build Coastguard Worker
4835*5e7646d2SAndroid Build Coastguard Worker ptr += strlen(ptr);
4836*5e7646d2SAndroid Build Coastguard Worker
4837*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, ptr, (sizeof(temp) - (size_t)(ptr - temp))))
4838*5e7646d2SAndroid Build Coastguard Worker break;
4839*5e7646d2SAndroid Build Coastguard Worker }
4840*5e7646d2SAndroid Build Coastguard Worker else
4841*5e7646d2SAndroid Build Coastguard Worker {
4842*5e7646d2SAndroid Build Coastguard Worker /*
4843*5e7646d2SAndroid Build Coastguard Worker * Not another value, stop here...
4844*5e7646d2SAndroid Build Coastguard Worker */
4845*5e7646d2SAndroid Build Coastguard Worker
4846*5e7646d2SAndroid Build Coastguard Worker cupsFileSeek(f->fp, lastpos);
4847*5e7646d2SAndroid Build Coastguard Worker f->linenum = lastline;
4848*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
4849*5e7646d2SAndroid Build Coastguard Worker break;
4850*5e7646d2SAndroid Build Coastguard Worker }
4851*5e7646d2SAndroid Build Coastguard Worker }
4852*5e7646d2SAndroid Build Coastguard Worker
4853*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
4854*5e7646d2SAndroid Build Coastguard Worker {
4855*5e7646d2SAndroid Build Coastguard Worker /*
4856*5e7646d2SAndroid Build Coastguard Worker * Expand any variables in the value and then save it.
4857*5e7646d2SAndroid Build Coastguard Worker */
4858*5e7646d2SAndroid Build Coastguard Worker
4859*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(vars, value, temp, sizeof(value));
4860*5e7646d2SAndroid Build Coastguard Worker
4861*5e7646d2SAndroid Build Coastguard Worker ptr = value + strlen(value) - 1;
4862*5e7646d2SAndroid Build Coastguard Worker
4863*5e7646d2SAndroid Build Coastguard Worker if (value[0] == '/' && ptr > value && *ptr == '/')
4864*5e7646d2SAndroid Build Coastguard Worker {
4865*5e7646d2SAndroid Build Coastguard Worker /*
4866*5e7646d2SAndroid Build Coastguard Worker * WITH-VALUE is a POSIX extended regular expression.
4867*5e7646d2SAndroid Build Coastguard Worker */
4868*5e7646d2SAndroid Build Coastguard Worker
4869*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_value = calloc(1, (size_t)(ptr - value));
4870*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_flags |= IPPTOOL_WITH_REGEX;
4871*5e7646d2SAndroid Build Coastguard Worker
4872*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect->with_value)
4873*5e7646d2SAndroid Build Coastguard Worker memcpy(data->last_expect->with_value, value + 1, (size_t)(ptr - value - 1));
4874*5e7646d2SAndroid Build Coastguard Worker }
4875*5e7646d2SAndroid Build Coastguard Worker else
4876*5e7646d2SAndroid Build Coastguard Worker {
4877*5e7646d2SAndroid Build Coastguard Worker /*
4878*5e7646d2SAndroid Build Coastguard Worker * WITH-VALUE is a literal value...
4879*5e7646d2SAndroid Build Coastguard Worker */
4880*5e7646d2SAndroid Build Coastguard Worker
4881*5e7646d2SAndroid Build Coastguard Worker for (ptr = value; *ptr; ptr ++)
4882*5e7646d2SAndroid Build Coastguard Worker {
4883*5e7646d2SAndroid Build Coastguard Worker if (*ptr == '\\' && ptr[1])
4884*5e7646d2SAndroid Build Coastguard Worker {
4885*5e7646d2SAndroid Build Coastguard Worker /*
4886*5e7646d2SAndroid Build Coastguard Worker * Remove \ from \foo...
4887*5e7646d2SAndroid Build Coastguard Worker */
4888*5e7646d2SAndroid Build Coastguard Worker
4889*5e7646d2SAndroid Build Coastguard Worker _cups_strcpy(ptr, ptr + 1);
4890*5e7646d2SAndroid Build Coastguard Worker }
4891*5e7646d2SAndroid Build Coastguard Worker }
4892*5e7646d2SAndroid Build Coastguard Worker
4893*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_value = strdup(value);
4894*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_flags |= IPPTOOL_WITH_LITERAL;
4895*5e7646d2SAndroid Build Coastguard Worker }
4896*5e7646d2SAndroid Build Coastguard Worker }
4897*5e7646d2SAndroid Build Coastguard Worker else
4898*5e7646d2SAndroid Build Coastguard Worker {
4899*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "%s without a preceding EXPECT on line %d of \"%s\".", token, f->linenum, f->filename);
4900*5e7646d2SAndroid Build Coastguard Worker return (0);
4901*5e7646d2SAndroid Build Coastguard Worker }
4902*5e7646d2SAndroid Build Coastguard Worker }
4903*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "WITH-VALUE-FROM"))
4904*5e7646d2SAndroid Build Coastguard Worker {
4905*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4906*5e7646d2SAndroid Build Coastguard Worker {
4907*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing %s value on line %d of \"%s\".", token, f->linenum, f->filename);
4908*5e7646d2SAndroid Build Coastguard Worker return (0);
4909*5e7646d2SAndroid Build Coastguard Worker }
4910*5e7646d2SAndroid Build Coastguard Worker
4911*5e7646d2SAndroid Build Coastguard Worker if (data->last_expect)
4912*5e7646d2SAndroid Build Coastguard Worker {
4913*5e7646d2SAndroid Build Coastguard Worker /*
4914*5e7646d2SAndroid Build Coastguard Worker * Expand any variables in the value and then save it.
4915*5e7646d2SAndroid Build Coastguard Worker */
4916*5e7646d2SAndroid Build Coastguard Worker
4917*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(vars, value, temp, sizeof(value));
4918*5e7646d2SAndroid Build Coastguard Worker
4919*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_value_from = strdup(value);
4920*5e7646d2SAndroid Build Coastguard Worker data->last_expect->with_flags = IPPTOOL_WITH_LITERAL;
4921*5e7646d2SAndroid Build Coastguard Worker }
4922*5e7646d2SAndroid Build Coastguard Worker else
4923*5e7646d2SAndroid Build Coastguard Worker {
4924*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "%s without a preceding EXPECT on line %d of \"%s\".", token, f->linenum, f->filename);
4925*5e7646d2SAndroid Build Coastguard Worker return (0);
4926*5e7646d2SAndroid Build Coastguard Worker }
4927*5e7646d2SAndroid Build Coastguard Worker }
4928*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(token, "DISPLAY"))
4929*5e7646d2SAndroid Build Coastguard Worker {
4930*5e7646d2SAndroid Build Coastguard Worker /*
4931*5e7646d2SAndroid Build Coastguard Worker * Display attributes...
4932*5e7646d2SAndroid Build Coastguard Worker */
4933*5e7646d2SAndroid Build Coastguard Worker
4934*5e7646d2SAndroid Build Coastguard Worker if (data->num_displayed >= (int)(sizeof(data->displayed) / sizeof(data->displayed[0])))
4935*5e7646d2SAndroid Build Coastguard Worker {
4936*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Too many DISPLAY's on line %d of \"%s\".", f->linenum, f->filename);
4937*5e7646d2SAndroid Build Coastguard Worker return (0);
4938*5e7646d2SAndroid Build Coastguard Worker }
4939*5e7646d2SAndroid Build Coastguard Worker
4940*5e7646d2SAndroid Build Coastguard Worker if (!_ippFileReadToken(f, temp, sizeof(temp)))
4941*5e7646d2SAndroid Build Coastguard Worker {
4942*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing DISPLAY name on line %d of \"%s\".", f->linenum, f->filename);
4943*5e7646d2SAndroid Build Coastguard Worker return (0);
4944*5e7646d2SAndroid Build Coastguard Worker }
4945*5e7646d2SAndroid Build Coastguard Worker
4946*5e7646d2SAndroid Build Coastguard Worker data->displayed[data->num_displayed] = strdup(temp);
4947*5e7646d2SAndroid Build Coastguard Worker data->num_displayed ++;
4948*5e7646d2SAndroid Build Coastguard Worker }
4949*5e7646d2SAndroid Build Coastguard Worker else
4950*5e7646d2SAndroid Build Coastguard Worker {
4951*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Unexpected token %s seen on line %d of \"%s\".", token, f->linenum, f->filename);
4952*5e7646d2SAndroid Build Coastguard Worker return (0);
4953*5e7646d2SAndroid Build Coastguard Worker }
4954*5e7646d2SAndroid Build Coastguard Worker }
4955*5e7646d2SAndroid Build Coastguard Worker else
4956*5e7646d2SAndroid Build Coastguard Worker {
4957*5e7646d2SAndroid Build Coastguard Worker /*
4958*5e7646d2SAndroid Build Coastguard Worker * Scan for the start of a test (open brace)...
4959*5e7646d2SAndroid Build Coastguard Worker */
4960*5e7646d2SAndroid Build Coastguard Worker
4961*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(token, "{"))
4962*5e7646d2SAndroid Build Coastguard Worker {
4963*5e7646d2SAndroid Build Coastguard Worker /*
4964*5e7646d2SAndroid Build Coastguard Worker * Start new test...
4965*5e7646d2SAndroid Build Coastguard Worker */
4966*5e7646d2SAndroid Build Coastguard Worker
4967*5e7646d2SAndroid Build Coastguard Worker if (data->show_header)
4968*5e7646d2SAndroid Build Coastguard Worker {
4969*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_PLIST)
4970*5e7646d2SAndroid Build Coastguard Worker print_xml_header(data);
4971*5e7646d2SAndroid Build Coastguard Worker
4972*5e7646d2SAndroid Build Coastguard Worker if (data->output == IPPTOOL_OUTPUT_TEST || (data->output == IPPTOOL_OUTPUT_PLIST && data->outfile != cupsFileStdout()))
4973*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(cupsFileStdout(), "\"%s\":\n", f->filename);
4974*5e7646d2SAndroid Build Coastguard Worker
4975*5e7646d2SAndroid Build Coastguard Worker data->show_header = 0;
4976*5e7646d2SAndroid Build Coastguard Worker }
4977*5e7646d2SAndroid Build Coastguard Worker
4978*5e7646d2SAndroid Build Coastguard Worker data->compression[0] = '\0';
4979*5e7646d2SAndroid Build Coastguard Worker data->delay = 0;
4980*5e7646d2SAndroid Build Coastguard Worker data->num_expects = 0;
4981*5e7646d2SAndroid Build Coastguard Worker data->last_expect = NULL;
4982*5e7646d2SAndroid Build Coastguard Worker data->file[0] = '\0';
4983*5e7646d2SAndroid Build Coastguard Worker data->ignore_errors = data->def_ignore_errors;
4984*5e7646d2SAndroid Build Coastguard Worker strlcpy(data->name, f->filename, sizeof(data->name));
4985*5e7646d2SAndroid Build Coastguard Worker if ((ptr = strrchr(data->name, '.')) != NULL)
4986*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
4987*5e7646d2SAndroid Build Coastguard Worker data->repeat_interval = 5000000;
4988*5e7646d2SAndroid Build Coastguard Worker strlcpy(data->resource, data->vars->resource, sizeof(data->resource));
4989*5e7646d2SAndroid Build Coastguard Worker data->skip_previous = 0;
4990*5e7646d2SAndroid Build Coastguard Worker data->pass_test = 0;
4991*5e7646d2SAndroid Build Coastguard Worker data->skip_test = 0;
4992*5e7646d2SAndroid Build Coastguard Worker data->num_statuses = 0;
4993*5e7646d2SAndroid Build Coastguard Worker data->last_status = NULL;
4994*5e7646d2SAndroid Build Coastguard Worker data->test_id[0] = '\0';
4995*5e7646d2SAndroid Build Coastguard Worker data->transfer = data->def_transfer;
4996*5e7646d2SAndroid Build Coastguard Worker data->version = data->def_version;
4997*5e7646d2SAndroid Build Coastguard Worker
4998*5e7646d2SAndroid Build Coastguard Worker free(data->monitor_uri);
4999*5e7646d2SAndroid Build Coastguard Worker data->monitor_uri = NULL;
5000*5e7646d2SAndroid Build Coastguard Worker data->monitor_delay = 0;
5001*5e7646d2SAndroid Build Coastguard Worker data->monitor_interval = 5000000;
5002*5e7646d2SAndroid Build Coastguard Worker data->num_monitor_expects = 0;
5003*5e7646d2SAndroid Build Coastguard Worker
5004*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(vars, "date-current", iso_date(ippTimeToDate(time(NULL))));
5005*5e7646d2SAndroid Build Coastguard Worker
5006*5e7646d2SAndroid Build Coastguard Worker f->attrs = ippNew();
5007*5e7646d2SAndroid Build Coastguard Worker f->group_tag = IPP_TAG_ZERO;
5008*5e7646d2SAndroid Build Coastguard Worker }
5009*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "DEFINE"))
5010*5e7646d2SAndroid Build Coastguard Worker {
5011*5e7646d2SAndroid Build Coastguard Worker /*
5012*5e7646d2SAndroid Build Coastguard Worker * DEFINE name value
5013*5e7646d2SAndroid Build Coastguard Worker */
5014*5e7646d2SAndroid Build Coastguard Worker
5015*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, name, sizeof(name)) && _ippFileReadToken(f, temp, sizeof(temp)))
5016*5e7646d2SAndroid Build Coastguard Worker {
5017*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(vars, "date-current", iso_date(ippTimeToDate(time(NULL))));
5018*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(vars, value, temp, sizeof(value));
5019*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(vars, name, value);
5020*5e7646d2SAndroid Build Coastguard Worker }
5021*5e7646d2SAndroid Build Coastguard Worker else
5022*5e7646d2SAndroid Build Coastguard Worker {
5023*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing DEFINE name and/or value on line %d of \"%s\".", f->linenum, f->filename);
5024*5e7646d2SAndroid Build Coastguard Worker return (0);
5025*5e7646d2SAndroid Build Coastguard Worker }
5026*5e7646d2SAndroid Build Coastguard Worker }
5027*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "DEFINE-DEFAULT"))
5028*5e7646d2SAndroid Build Coastguard Worker {
5029*5e7646d2SAndroid Build Coastguard Worker /*
5030*5e7646d2SAndroid Build Coastguard Worker * DEFINE-DEFAULT name value
5031*5e7646d2SAndroid Build Coastguard Worker */
5032*5e7646d2SAndroid Build Coastguard Worker
5033*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, name, sizeof(name)) && _ippFileReadToken(f, temp, sizeof(temp)))
5034*5e7646d2SAndroid Build Coastguard Worker {
5035*5e7646d2SAndroid Build Coastguard Worker if (!_ippVarsGet(vars, name))
5036*5e7646d2SAndroid Build Coastguard Worker {
5037*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(vars, "date-current", iso_date(ippTimeToDate(time(NULL))));
5038*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(vars, value, temp, sizeof(value));
5039*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(vars, name, value);
5040*5e7646d2SAndroid Build Coastguard Worker }
5041*5e7646d2SAndroid Build Coastguard Worker }
5042*5e7646d2SAndroid Build Coastguard Worker else
5043*5e7646d2SAndroid Build Coastguard Worker {
5044*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing DEFINE-DEFAULT name and/or value on line %d of \"%s\".", f->linenum, f->filename);
5045*5e7646d2SAndroid Build Coastguard Worker return (0);
5046*5e7646d2SAndroid Build Coastguard Worker }
5047*5e7646d2SAndroid Build Coastguard Worker }
5048*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "FILE-ID"))
5049*5e7646d2SAndroid Build Coastguard Worker {
5050*5e7646d2SAndroid Build Coastguard Worker /*
5051*5e7646d2SAndroid Build Coastguard Worker * FILE-ID "string"
5052*5e7646d2SAndroid Build Coastguard Worker */
5053*5e7646d2SAndroid Build Coastguard Worker
5054*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, temp, sizeof(temp)))
5055*5e7646d2SAndroid Build Coastguard Worker {
5056*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(vars, "date-current", iso_date(ippTimeToDate(time(NULL))));
5057*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(vars, data->file_id, temp, sizeof(data->file_id));
5058*5e7646d2SAndroid Build Coastguard Worker }
5059*5e7646d2SAndroid Build Coastguard Worker else
5060*5e7646d2SAndroid Build Coastguard Worker {
5061*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing FILE-ID value on line %d of \"%s\".", f->linenum, f->filename);
5062*5e7646d2SAndroid Build Coastguard Worker return (0);
5063*5e7646d2SAndroid Build Coastguard Worker }
5064*5e7646d2SAndroid Build Coastguard Worker }
5065*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "IGNORE-ERRORS"))
5066*5e7646d2SAndroid Build Coastguard Worker {
5067*5e7646d2SAndroid Build Coastguard Worker /*
5068*5e7646d2SAndroid Build Coastguard Worker * IGNORE-ERRORS yes
5069*5e7646d2SAndroid Build Coastguard Worker * IGNORE-ERRORS no
5070*5e7646d2SAndroid Build Coastguard Worker */
5071*5e7646d2SAndroid Build Coastguard Worker
5072*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, temp, sizeof(temp)) && (!_cups_strcasecmp(temp, "yes") || !_cups_strcasecmp(temp, "no")))
5073*5e7646d2SAndroid Build Coastguard Worker {
5074*5e7646d2SAndroid Build Coastguard Worker data->def_ignore_errors = !_cups_strcasecmp(temp, "yes");
5075*5e7646d2SAndroid Build Coastguard Worker }
5076*5e7646d2SAndroid Build Coastguard Worker else
5077*5e7646d2SAndroid Build Coastguard Worker {
5078*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing IGNORE-ERRORS value on line %d of \"%s\".", f->linenum, f->filename);
5079*5e7646d2SAndroid Build Coastguard Worker return (0);
5080*5e7646d2SAndroid Build Coastguard Worker }
5081*5e7646d2SAndroid Build Coastguard Worker }
5082*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "INCLUDE"))
5083*5e7646d2SAndroid Build Coastguard Worker {
5084*5e7646d2SAndroid Build Coastguard Worker /*
5085*5e7646d2SAndroid Build Coastguard Worker * INCLUDE "filename"
5086*5e7646d2SAndroid Build Coastguard Worker * INCLUDE <filename>
5087*5e7646d2SAndroid Build Coastguard Worker */
5088*5e7646d2SAndroid Build Coastguard Worker
5089*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, temp, sizeof(temp)))
5090*5e7646d2SAndroid Build Coastguard Worker {
5091*5e7646d2SAndroid Build Coastguard Worker /*
5092*5e7646d2SAndroid Build Coastguard Worker * Map the filename to and then run the tests...
5093*5e7646d2SAndroid Build Coastguard Worker */
5094*5e7646d2SAndroid Build Coastguard Worker
5095*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t inc_data; /* Data for included file */
5096*5e7646d2SAndroid Build Coastguard Worker char filename[1024]; /* Mapped filename */
5097*5e7646d2SAndroid Build Coastguard Worker
5098*5e7646d2SAndroid Build Coastguard Worker memcpy(&inc_data, data, sizeof(inc_data));
5099*5e7646d2SAndroid Build Coastguard Worker inc_data.http = NULL;
5100*5e7646d2SAndroid Build Coastguard Worker inc_data.pass = 1;
5101*5e7646d2SAndroid Build Coastguard Worker inc_data.prev_pass = 1;
5102*5e7646d2SAndroid Build Coastguard Worker inc_data.show_header = 1;
5103*5e7646d2SAndroid Build Coastguard Worker
5104*5e7646d2SAndroid Build Coastguard Worker if (!do_tests(get_filename(f->filename, filename, temp, sizeof(filename)), &inc_data) && data->stop_after_include_error)
5105*5e7646d2SAndroid Build Coastguard Worker {
5106*5e7646d2SAndroid Build Coastguard Worker data->pass = data->prev_pass = 0;
5107*5e7646d2SAndroid Build Coastguard Worker return (0);
5108*5e7646d2SAndroid Build Coastguard Worker }
5109*5e7646d2SAndroid Build Coastguard Worker }
5110*5e7646d2SAndroid Build Coastguard Worker else
5111*5e7646d2SAndroid Build Coastguard Worker {
5112*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing INCLUDE filename on line %d of \"%s\".", f->linenum, f->filename);
5113*5e7646d2SAndroid Build Coastguard Worker return (0);
5114*5e7646d2SAndroid Build Coastguard Worker }
5115*5e7646d2SAndroid Build Coastguard Worker
5116*5e7646d2SAndroid Build Coastguard Worker data->show_header = 1;
5117*5e7646d2SAndroid Build Coastguard Worker }
5118*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "INCLUDE-IF-DEFINED"))
5119*5e7646d2SAndroid Build Coastguard Worker {
5120*5e7646d2SAndroid Build Coastguard Worker /*
5121*5e7646d2SAndroid Build Coastguard Worker * INCLUDE-IF-DEFINED name "filename"
5122*5e7646d2SAndroid Build Coastguard Worker * INCLUDE-IF-DEFINED name <filename>
5123*5e7646d2SAndroid Build Coastguard Worker */
5124*5e7646d2SAndroid Build Coastguard Worker
5125*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, name, sizeof(name)) && _ippFileReadToken(f, temp, sizeof(temp)))
5126*5e7646d2SAndroid Build Coastguard Worker {
5127*5e7646d2SAndroid Build Coastguard Worker /*
5128*5e7646d2SAndroid Build Coastguard Worker * Map the filename to and then run the tests...
5129*5e7646d2SAndroid Build Coastguard Worker */
5130*5e7646d2SAndroid Build Coastguard Worker
5131*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t inc_data; /* Data for included file */
5132*5e7646d2SAndroid Build Coastguard Worker char filename[1024]; /* Mapped filename */
5133*5e7646d2SAndroid Build Coastguard Worker
5134*5e7646d2SAndroid Build Coastguard Worker memcpy(&inc_data, data, sizeof(inc_data));
5135*5e7646d2SAndroid Build Coastguard Worker inc_data.http = NULL;
5136*5e7646d2SAndroid Build Coastguard Worker inc_data.pass = 1;
5137*5e7646d2SAndroid Build Coastguard Worker inc_data.prev_pass = 1;
5138*5e7646d2SAndroid Build Coastguard Worker inc_data.show_header = 1;
5139*5e7646d2SAndroid Build Coastguard Worker
5140*5e7646d2SAndroid Build Coastguard Worker if (!do_tests(get_filename(f->filename, filename, temp, sizeof(filename)), &inc_data) && data->stop_after_include_error)
5141*5e7646d2SAndroid Build Coastguard Worker {
5142*5e7646d2SAndroid Build Coastguard Worker data->pass = data->prev_pass = 0;
5143*5e7646d2SAndroid Build Coastguard Worker return (0);
5144*5e7646d2SAndroid Build Coastguard Worker }
5145*5e7646d2SAndroid Build Coastguard Worker }
5146*5e7646d2SAndroid Build Coastguard Worker else
5147*5e7646d2SAndroid Build Coastguard Worker {
5148*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing INCLUDE-IF-DEFINED name or filename on line %d of \"%s\".", f->linenum, f->filename);
5149*5e7646d2SAndroid Build Coastguard Worker return (0);
5150*5e7646d2SAndroid Build Coastguard Worker }
5151*5e7646d2SAndroid Build Coastguard Worker
5152*5e7646d2SAndroid Build Coastguard Worker data->show_header = 1;
5153*5e7646d2SAndroid Build Coastguard Worker }
5154*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "INCLUDE-IF-NOT-DEFINED"))
5155*5e7646d2SAndroid Build Coastguard Worker {
5156*5e7646d2SAndroid Build Coastguard Worker /*
5157*5e7646d2SAndroid Build Coastguard Worker * INCLUDE-IF-NOT-DEFINED name "filename"
5158*5e7646d2SAndroid Build Coastguard Worker * INCLUDE-IF-NOT-DEFINED name <filename>
5159*5e7646d2SAndroid Build Coastguard Worker */
5160*5e7646d2SAndroid Build Coastguard Worker
5161*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, name, sizeof(name)) && _ippFileReadToken(f, temp, sizeof(temp)))
5162*5e7646d2SAndroid Build Coastguard Worker {
5163*5e7646d2SAndroid Build Coastguard Worker /*
5164*5e7646d2SAndroid Build Coastguard Worker * Map the filename to and then run the tests...
5165*5e7646d2SAndroid Build Coastguard Worker */
5166*5e7646d2SAndroid Build Coastguard Worker
5167*5e7646d2SAndroid Build Coastguard Worker ipptool_test_t inc_data; /* Data for included file */
5168*5e7646d2SAndroid Build Coastguard Worker char filename[1024]; /* Mapped filename */
5169*5e7646d2SAndroid Build Coastguard Worker
5170*5e7646d2SAndroid Build Coastguard Worker memcpy(&inc_data, data, sizeof(inc_data));
5171*5e7646d2SAndroid Build Coastguard Worker inc_data.http = NULL;
5172*5e7646d2SAndroid Build Coastguard Worker inc_data.pass = 1;
5173*5e7646d2SAndroid Build Coastguard Worker inc_data.prev_pass = 1;
5174*5e7646d2SAndroid Build Coastguard Worker inc_data.show_header = 1;
5175*5e7646d2SAndroid Build Coastguard Worker
5176*5e7646d2SAndroid Build Coastguard Worker if (!do_tests(get_filename(f->filename, filename, temp, sizeof(filename)), &inc_data) && data->stop_after_include_error)
5177*5e7646d2SAndroid Build Coastguard Worker {
5178*5e7646d2SAndroid Build Coastguard Worker data->pass = data->prev_pass = 0;
5179*5e7646d2SAndroid Build Coastguard Worker return (0);
5180*5e7646d2SAndroid Build Coastguard Worker }
5181*5e7646d2SAndroid Build Coastguard Worker }
5182*5e7646d2SAndroid Build Coastguard Worker else
5183*5e7646d2SAndroid Build Coastguard Worker {
5184*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing INCLUDE-IF-NOT-DEFINED name or filename on line %d of \"%s\".", f->linenum, f->filename);
5185*5e7646d2SAndroid Build Coastguard Worker return (0);
5186*5e7646d2SAndroid Build Coastguard Worker }
5187*5e7646d2SAndroid Build Coastguard Worker
5188*5e7646d2SAndroid Build Coastguard Worker data->show_header = 1;
5189*5e7646d2SAndroid Build Coastguard Worker }
5190*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "SKIP-IF-DEFINED"))
5191*5e7646d2SAndroid Build Coastguard Worker {
5192*5e7646d2SAndroid Build Coastguard Worker /*
5193*5e7646d2SAndroid Build Coastguard Worker * SKIP-IF-DEFINED variable
5194*5e7646d2SAndroid Build Coastguard Worker */
5195*5e7646d2SAndroid Build Coastguard Worker
5196*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, name, sizeof(name)))
5197*5e7646d2SAndroid Build Coastguard Worker {
5198*5e7646d2SAndroid Build Coastguard Worker if (_ippVarsGet(vars, name))
5199*5e7646d2SAndroid Build Coastguard Worker data->skip_test = 1;
5200*5e7646d2SAndroid Build Coastguard Worker }
5201*5e7646d2SAndroid Build Coastguard Worker else
5202*5e7646d2SAndroid Build Coastguard Worker {
5203*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing SKIP-IF-DEFINED variable on line %d of \"%s\".", f->linenum, f->filename);
5204*5e7646d2SAndroid Build Coastguard Worker return (0);
5205*5e7646d2SAndroid Build Coastguard Worker }
5206*5e7646d2SAndroid Build Coastguard Worker }
5207*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "SKIP-IF-NOT-DEFINED"))
5208*5e7646d2SAndroid Build Coastguard Worker {
5209*5e7646d2SAndroid Build Coastguard Worker /*
5210*5e7646d2SAndroid Build Coastguard Worker * SKIP-IF-NOT-DEFINED variable
5211*5e7646d2SAndroid Build Coastguard Worker */
5212*5e7646d2SAndroid Build Coastguard Worker
5213*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, name, sizeof(name)))
5214*5e7646d2SAndroid Build Coastguard Worker {
5215*5e7646d2SAndroid Build Coastguard Worker if (!_ippVarsGet(vars, name))
5216*5e7646d2SAndroid Build Coastguard Worker data->skip_test = 1;
5217*5e7646d2SAndroid Build Coastguard Worker }
5218*5e7646d2SAndroid Build Coastguard Worker else
5219*5e7646d2SAndroid Build Coastguard Worker {
5220*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing SKIP-IF-NOT-DEFINED variable on line %d of \"%s\".", f->linenum, f->filename);
5221*5e7646d2SAndroid Build Coastguard Worker return (0);
5222*5e7646d2SAndroid Build Coastguard Worker }
5223*5e7646d2SAndroid Build Coastguard Worker }
5224*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "STOP-AFTER-INCLUDE-ERROR"))
5225*5e7646d2SAndroid Build Coastguard Worker {
5226*5e7646d2SAndroid Build Coastguard Worker /*
5227*5e7646d2SAndroid Build Coastguard Worker * STOP-AFTER-INCLUDE-ERROR yes
5228*5e7646d2SAndroid Build Coastguard Worker * STOP-AFTER-INCLUDE-ERROR no
5229*5e7646d2SAndroid Build Coastguard Worker */
5230*5e7646d2SAndroid Build Coastguard Worker
5231*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, temp, sizeof(temp)) && (!_cups_strcasecmp(temp, "yes") || !_cups_strcasecmp(temp, "no")))
5232*5e7646d2SAndroid Build Coastguard Worker {
5233*5e7646d2SAndroid Build Coastguard Worker data->stop_after_include_error = !_cups_strcasecmp(temp, "yes");
5234*5e7646d2SAndroid Build Coastguard Worker }
5235*5e7646d2SAndroid Build Coastguard Worker else
5236*5e7646d2SAndroid Build Coastguard Worker {
5237*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing STOP-AFTER-INCLUDE-ERROR value on line %d of \"%s\".", f->linenum, f->filename);
5238*5e7646d2SAndroid Build Coastguard Worker return (0);
5239*5e7646d2SAndroid Build Coastguard Worker }
5240*5e7646d2SAndroid Build Coastguard Worker }
5241*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "TRANSFER"))
5242*5e7646d2SAndroid Build Coastguard Worker {
5243*5e7646d2SAndroid Build Coastguard Worker /*
5244*5e7646d2SAndroid Build Coastguard Worker * TRANSFER auto
5245*5e7646d2SAndroid Build Coastguard Worker * TRANSFER chunked
5246*5e7646d2SAndroid Build Coastguard Worker * TRANSFER length
5247*5e7646d2SAndroid Build Coastguard Worker */
5248*5e7646d2SAndroid Build Coastguard Worker
5249*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, temp, sizeof(temp)))
5250*5e7646d2SAndroid Build Coastguard Worker {
5251*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(temp, "auto"))
5252*5e7646d2SAndroid Build Coastguard Worker data->def_transfer = IPPTOOL_TRANSFER_AUTO;
5253*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(temp, "chunked"))
5254*5e7646d2SAndroid Build Coastguard Worker data->def_transfer = IPPTOOL_TRANSFER_CHUNKED;
5255*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(temp, "length"))
5256*5e7646d2SAndroid Build Coastguard Worker data->def_transfer = IPPTOOL_TRANSFER_LENGTH;
5257*5e7646d2SAndroid Build Coastguard Worker else
5258*5e7646d2SAndroid Build Coastguard Worker {
5259*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad TRANSFER value \"%s\" on line %d of \"%s\".", temp, f->linenum, f->filename);
5260*5e7646d2SAndroid Build Coastguard Worker return (0);
5261*5e7646d2SAndroid Build Coastguard Worker }
5262*5e7646d2SAndroid Build Coastguard Worker }
5263*5e7646d2SAndroid Build Coastguard Worker else
5264*5e7646d2SAndroid Build Coastguard Worker {
5265*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing TRANSFER value on line %d of \"%s\".", f->linenum, f->filename);
5266*5e7646d2SAndroid Build Coastguard Worker return (0);
5267*5e7646d2SAndroid Build Coastguard Worker }
5268*5e7646d2SAndroid Build Coastguard Worker }
5269*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(token, "VERSION"))
5270*5e7646d2SAndroid Build Coastguard Worker {
5271*5e7646d2SAndroid Build Coastguard Worker if (_ippFileReadToken(f, temp, sizeof(temp)))
5272*5e7646d2SAndroid Build Coastguard Worker {
5273*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(temp, "1.0"))
5274*5e7646d2SAndroid Build Coastguard Worker data->def_version = 10;
5275*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(temp, "1.1"))
5276*5e7646d2SAndroid Build Coastguard Worker data->def_version = 11;
5277*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(temp, "2.0"))
5278*5e7646d2SAndroid Build Coastguard Worker data->def_version = 20;
5279*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(temp, "2.1"))
5280*5e7646d2SAndroid Build Coastguard Worker data->def_version = 21;
5281*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(temp, "2.2"))
5282*5e7646d2SAndroid Build Coastguard Worker data->def_version = 22;
5283*5e7646d2SAndroid Build Coastguard Worker else
5284*5e7646d2SAndroid Build Coastguard Worker {
5285*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad VERSION \"%s\" on line %d of \"%s\".", temp, f->linenum, f->filename);
5286*5e7646d2SAndroid Build Coastguard Worker return (0);
5287*5e7646d2SAndroid Build Coastguard Worker }
5288*5e7646d2SAndroid Build Coastguard Worker }
5289*5e7646d2SAndroid Build Coastguard Worker else
5290*5e7646d2SAndroid Build Coastguard Worker {
5291*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Missing VERSION number on line %d of \"%s\".", f->linenum, f->filename);
5292*5e7646d2SAndroid Build Coastguard Worker return (0);
5293*5e7646d2SAndroid Build Coastguard Worker }
5294*5e7646d2SAndroid Build Coastguard Worker }
5295*5e7646d2SAndroid Build Coastguard Worker else
5296*5e7646d2SAndroid Build Coastguard Worker {
5297*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Unexpected token %s seen on line %d of \"%s\".", token, f->linenum, f->filename);
5298*5e7646d2SAndroid Build Coastguard Worker return (0);
5299*5e7646d2SAndroid Build Coastguard Worker }
5300*5e7646d2SAndroid Build Coastguard Worker }
5301*5e7646d2SAndroid Build Coastguard Worker
5302*5e7646d2SAndroid Build Coastguard Worker return (1);
5303*5e7646d2SAndroid Build Coastguard Worker }
5304*5e7646d2SAndroid Build Coastguard Worker
5305*5e7646d2SAndroid Build Coastguard Worker
5306*5e7646d2SAndroid Build Coastguard Worker /*
5307*5e7646d2SAndroid Build Coastguard Worker * 'usage()' - Show program usage.
5308*5e7646d2SAndroid Build Coastguard Worker */
5309*5e7646d2SAndroid Build Coastguard Worker
5310*5e7646d2SAndroid Build Coastguard Worker static void
usage(void)5311*5e7646d2SAndroid Build Coastguard Worker usage(void)
5312*5e7646d2SAndroid Build Coastguard Worker {
5313*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("Usage: ipptool [options] URI filename [ ... filenameN ]"));
5314*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("Options:"));
5315*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("--ippserver filename Produce ippserver attribute file"));
5316*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("--stop-after-include-error\n"
5317*5e7646d2SAndroid Build Coastguard Worker " Stop tests after a failed INCLUDE"));
5318*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("--version Show version"));
5319*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-4 Connect using IPv4"));
5320*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-6 Connect using IPv6"));
5321*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-C Send requests using chunking (default)"));
5322*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-E Test with encryption using HTTP Upgrade to TLS"));
5323*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-I Ignore errors"));
5324*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-L Send requests using content-length"));
5325*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-P filename.plist Produce XML plist to a file and test report to standard output"));
5326*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-R Repeat tests on server-error-busy"));
5327*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-S Test with encryption using HTTPS"));
5328*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-T seconds Set the receive/send timeout in seconds"));
5329*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-V version Set default IPP version"));
5330*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-X Produce XML plist instead of plain text"));
5331*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-c Produce CSV output"));
5332*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-d name=value Set named variable to value"));
5333*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-f filename Set default request filename"));
5334*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-h Validate HTTP response headers"));
5335*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-i seconds Repeat the last file with the given time interval"));
5336*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-l Produce plain text output"));
5337*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-n count Repeat the last file the given number of times"));
5338*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-q Run silently"));
5339*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-t Produce a test report"));
5340*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("-v Be verbose"));
5341*5e7646d2SAndroid Build Coastguard Worker
5342*5e7646d2SAndroid Build Coastguard Worker exit(1);
5343*5e7646d2SAndroid Build Coastguard Worker }
5344*5e7646d2SAndroid Build Coastguard Worker
5345*5e7646d2SAndroid Build Coastguard Worker
5346*5e7646d2SAndroid Build Coastguard Worker /*
5347*5e7646d2SAndroid Build Coastguard Worker * 'with_distinct_values()' - Verify that an attribute contains unique values.
5348*5e7646d2SAndroid Build Coastguard Worker */
5349*5e7646d2SAndroid Build Coastguard Worker
5350*5e7646d2SAndroid Build Coastguard Worker static int // O - 1 if distinct, 0 if duplicate
with_distinct_values(cups_array_t * errors,ipp_attribute_t * attr)5351*5e7646d2SAndroid Build Coastguard Worker with_distinct_values(
5352*5e7646d2SAndroid Build Coastguard Worker cups_array_t *errors, // I - Array of errors
5353*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr) // I - Attribute to test
5354*5e7646d2SAndroid Build Coastguard Worker {
5355*5e7646d2SAndroid Build Coastguard Worker int i, // Looping var
5356*5e7646d2SAndroid Build Coastguard Worker count; // Number of values
5357*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag; // Value syntax
5358*5e7646d2SAndroid Build Coastguard Worker const char *value; // Current value
5359*5e7646d2SAndroid Build Coastguard Worker char buffer[8192]; // Temporary buffer
5360*5e7646d2SAndroid Build Coastguard Worker cups_array_t *values; // Array of values as strings
5361*5e7646d2SAndroid Build Coastguard Worker
5362*5e7646d2SAndroid Build Coastguard Worker
5363*5e7646d2SAndroid Build Coastguard Worker // If there is only 1 value, it must be distinct
5364*5e7646d2SAndroid Build Coastguard Worker if ((count = ippGetCount(attr)) == 1)
5365*5e7646d2SAndroid Build Coastguard Worker return (1);
5366*5e7646d2SAndroid Build Coastguard Worker
5367*5e7646d2SAndroid Build Coastguard Worker // Only check integers, enums, rangeOfInteger, resolution, and nul-terminated
5368*5e7646d2SAndroid Build Coastguard Worker // strings...
5369*5e7646d2SAndroid Build Coastguard Worker switch (value_tag = ippGetValueTag(attr))
5370*5e7646d2SAndroid Build Coastguard Worker {
5371*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
5372*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
5373*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
5374*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
5375*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
5376*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
5377*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
5378*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
5379*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
5380*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BEGIN_COLLECTION :
5381*5e7646d2SAndroid Build Coastguard Worker break;
5382*5e7646d2SAndroid Build Coastguard Worker
5383*5e7646d2SAndroid Build Coastguard Worker default :
5384*5e7646d2SAndroid Build Coastguard Worker add_stringf(errors, "WITH-DISTINCT-VALUES %s not supported for 1setOf %s", ippGetName(attr), ippTagString(value_tag));
5385*5e7646d2SAndroid Build Coastguard Worker return (0);
5386*5e7646d2SAndroid Build Coastguard Worker }
5387*5e7646d2SAndroid Build Coastguard Worker
5388*5e7646d2SAndroid Build Coastguard Worker // Collect values and determine they are all unique...
5389*5e7646d2SAndroid Build Coastguard Worker values = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
5390*5e7646d2SAndroid Build Coastguard Worker
5391*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
5392*5e7646d2SAndroid Build Coastguard Worker {
5393*5e7646d2SAndroid Build Coastguard Worker switch (value_tag)
5394*5e7646d2SAndroid Build Coastguard Worker {
5395*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
5396*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
5397*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "%d", ippGetInteger(attr, i));
5398*5e7646d2SAndroid Build Coastguard Worker value = buffer;
5399*5e7646d2SAndroid Build Coastguard Worker break;
5400*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
5401*5e7646d2SAndroid Build Coastguard Worker {
5402*5e7646d2SAndroid Build Coastguard Worker int upper, lower = ippGetRange(attr, i, &upper);
5403*5e7646d2SAndroid Build Coastguard Worker // Range values
5404*5e7646d2SAndroid Build Coastguard Worker
5405*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "%d-%d", lower, upper);
5406*5e7646d2SAndroid Build Coastguard Worker value = buffer;
5407*5e7646d2SAndroid Build Coastguard Worker }
5408*5e7646d2SAndroid Build Coastguard Worker break;
5409*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
5410*5e7646d2SAndroid Build Coastguard Worker {
5411*5e7646d2SAndroid Build Coastguard Worker ipp_res_t units; // Resolution units
5412*5e7646d2SAndroid Build Coastguard Worker int yres, xres = ippGetResolution(attr, i, &yres, &units);
5413*5e7646d2SAndroid Build Coastguard Worker // Resolution values
5414*5e7646d2SAndroid Build Coastguard Worker
5415*5e7646d2SAndroid Build Coastguard Worker if (xres == yres)
5416*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "%d%s", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
5417*5e7646d2SAndroid Build Coastguard Worker else
5418*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "%dx%d%s", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
5419*5e7646d2SAndroid Build Coastguard Worker value = buffer;
5420*5e7646d2SAndroid Build Coastguard Worker }
5421*5e7646d2SAndroid Build Coastguard Worker break;
5422*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
5423*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
5424*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
5425*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
5426*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
5427*5e7646d2SAndroid Build Coastguard Worker value = ippGetString(attr, i, NULL);
5428*5e7646d2SAndroid Build Coastguard Worker break;
5429*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BEGIN_COLLECTION :
5430*5e7646d2SAndroid Build Coastguard Worker {
5431*5e7646d2SAndroid Build Coastguard Worker ipp_t *col = ippGetCollection(attr, i);
5432*5e7646d2SAndroid Build Coastguard Worker // Collection value
5433*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *member; // Member attribute
5434*5e7646d2SAndroid Build Coastguard Worker char *bufptr, // Pointer into buffer
5435*5e7646d2SAndroid Build Coastguard Worker *bufend, // End of buffer
5436*5e7646d2SAndroid Build Coastguard Worker prefix; // Prefix character
5437*5e7646d2SAndroid Build Coastguard Worker
5438*5e7646d2SAndroid Build Coastguard Worker for (prefix = '{', bufptr = buffer, bufend = buffer + sizeof(buffer) - 2, member = ippFirstAttribute(col); member && bufptr < bufend; member = ippNextAttribute(col))
5439*5e7646d2SAndroid Build Coastguard Worker {
5440*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = prefix;
5441*5e7646d2SAndroid Build Coastguard Worker prefix = ' ';
5442*5e7646d2SAndroid Build Coastguard Worker
5443*5e7646d2SAndroid Build Coastguard Worker ippAttributeString(member, bufptr, (size_t)(bufend - bufptr));
5444*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
5445*5e7646d2SAndroid Build Coastguard Worker }
5446*5e7646d2SAndroid Build Coastguard Worker
5447*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '}';
5448*5e7646d2SAndroid Build Coastguard Worker *bufptr = '\0';
5449*5e7646d2SAndroid Build Coastguard Worker value = buffer;
5450*5e7646d2SAndroid Build Coastguard Worker }
5451*5e7646d2SAndroid Build Coastguard Worker break;
5452*5e7646d2SAndroid Build Coastguard Worker default : // Should never happen
5453*5e7646d2SAndroid Build Coastguard Worker value = "unsupported";
5454*5e7646d2SAndroid Build Coastguard Worker break;
5455*5e7646d2SAndroid Build Coastguard Worker }
5456*5e7646d2SAndroid Build Coastguard Worker
5457*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayFind(values, (void *)value))
5458*5e7646d2SAndroid Build Coastguard Worker add_stringf(errors, "DUPLICATE: %s=%s", ippGetName(attr), value);
5459*5e7646d2SAndroid Build Coastguard Worker else
5460*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(values, (void *)value);
5461*5e7646d2SAndroid Build Coastguard Worker }
5462*5e7646d2SAndroid Build Coastguard Worker
5463*5e7646d2SAndroid Build Coastguard Worker // Cleanup...
5464*5e7646d2SAndroid Build Coastguard Worker i = cupsArrayCount(values) == count;
5465*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(values);
5466*5e7646d2SAndroid Build Coastguard Worker
5467*5e7646d2SAndroid Build Coastguard Worker return (i);
5468*5e7646d2SAndroid Build Coastguard Worker }
5469*5e7646d2SAndroid Build Coastguard Worker
5470*5e7646d2SAndroid Build Coastguard Worker
5471*5e7646d2SAndroid Build Coastguard Worker /*
5472*5e7646d2SAndroid Build Coastguard Worker * 'with_flags_string()' - Return the "WITH-xxx" predicate that corresponds to
5473*5e7646d2SAndroid Build Coastguard Worker * the flags.
5474*5e7646d2SAndroid Build Coastguard Worker */
5475*5e7646d2SAndroid Build Coastguard Worker
5476*5e7646d2SAndroid Build Coastguard Worker static const char * /* O - WITH-xxx string */
with_flags_string(int flags)5477*5e7646d2SAndroid Build Coastguard Worker with_flags_string(int flags) /* I - WITH flags */
5478*5e7646d2SAndroid Build Coastguard Worker {
5479*5e7646d2SAndroid Build Coastguard Worker if (flags & IPPTOOL_WITH_ALL)
5480*5e7646d2SAndroid Build Coastguard Worker {
5481*5e7646d2SAndroid Build Coastguard Worker if (flags & IPPTOOL_WITH_HOSTNAME)
5482*5e7646d2SAndroid Build Coastguard Worker return ("WITH-ALL-HOSTNAMES");
5483*5e7646d2SAndroid Build Coastguard Worker else if (flags & IPPTOOL_WITH_RESOURCE)
5484*5e7646d2SAndroid Build Coastguard Worker return ("WITH-ALL-RESOURCES");
5485*5e7646d2SAndroid Build Coastguard Worker else if (flags & IPPTOOL_WITH_SCHEME)
5486*5e7646d2SAndroid Build Coastguard Worker return ("WITH-ALL-SCHEMES");
5487*5e7646d2SAndroid Build Coastguard Worker else
5488*5e7646d2SAndroid Build Coastguard Worker return ("WITH-ALL-VALUES");
5489*5e7646d2SAndroid Build Coastguard Worker }
5490*5e7646d2SAndroid Build Coastguard Worker else if (flags & IPPTOOL_WITH_HOSTNAME)
5491*5e7646d2SAndroid Build Coastguard Worker return ("WITH-HOSTNAME");
5492*5e7646d2SAndroid Build Coastguard Worker else if (flags & IPPTOOL_WITH_RESOURCE)
5493*5e7646d2SAndroid Build Coastguard Worker return ("WITH-RESOURCE");
5494*5e7646d2SAndroid Build Coastguard Worker else if (flags & IPPTOOL_WITH_SCHEME)
5495*5e7646d2SAndroid Build Coastguard Worker return ("WITH-SCHEME");
5496*5e7646d2SAndroid Build Coastguard Worker else
5497*5e7646d2SAndroid Build Coastguard Worker return ("WITH-VALUE");
5498*5e7646d2SAndroid Build Coastguard Worker }
5499*5e7646d2SAndroid Build Coastguard Worker
5500*5e7646d2SAndroid Build Coastguard Worker
5501*5e7646d2SAndroid Build Coastguard Worker /*
5502*5e7646d2SAndroid Build Coastguard Worker * 'with_value()' - Test a WITH-VALUE predicate.
5503*5e7646d2SAndroid Build Coastguard Worker */
5504*5e7646d2SAndroid Build Coastguard Worker
5505*5e7646d2SAndroid Build Coastguard Worker static int /* O - 1 on match, 0 on non-match */
with_value(ipptool_test_t * data,cups_array_t * errors,char * value,int flags,ipp_attribute_t * attr,char * matchbuf,size_t matchlen)5506*5e7646d2SAndroid Build Coastguard Worker with_value(ipptool_test_t *data, /* I - Test data */
5507*5e7646d2SAndroid Build Coastguard Worker cups_array_t *errors, /* I - Errors array */
5508*5e7646d2SAndroid Build Coastguard Worker char *value, /* I - Value string */
5509*5e7646d2SAndroid Build Coastguard Worker int flags, /* I - Flags for match */
5510*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr, /* I - Attribute to compare */
5511*5e7646d2SAndroid Build Coastguard Worker char *matchbuf, /* I - Buffer to hold matching value */
5512*5e7646d2SAndroid Build Coastguard Worker size_t matchlen) /* I - Length of match buffer */
5513*5e7646d2SAndroid Build Coastguard Worker {
5514*5e7646d2SAndroid Build Coastguard Worker int i, /* Looping var */
5515*5e7646d2SAndroid Build Coastguard Worker count, /* Number of values */
5516*5e7646d2SAndroid Build Coastguard Worker match; /* Match? */
5517*5e7646d2SAndroid Build Coastguard Worker char temp[1024], /* Temporary value string */
5518*5e7646d2SAndroid Build Coastguard Worker *valptr; /* Pointer into value */
5519*5e7646d2SAndroid Build Coastguard Worker const char *name; /* Attribute name */
5520*5e7646d2SAndroid Build Coastguard Worker
5521*5e7646d2SAndroid Build Coastguard Worker
5522*5e7646d2SAndroid Build Coastguard Worker *matchbuf = '\0';
5523*5e7646d2SAndroid Build Coastguard Worker match = (flags & IPPTOOL_WITH_ALL) ? 1 : 0;
5524*5e7646d2SAndroid Build Coastguard Worker
5525*5e7646d2SAndroid Build Coastguard Worker /*
5526*5e7646d2SAndroid Build Coastguard Worker * NULL matches everything.
5527*5e7646d2SAndroid Build Coastguard Worker */
5528*5e7646d2SAndroid Build Coastguard Worker
5529*5e7646d2SAndroid Build Coastguard Worker if (!value || !*value)
5530*5e7646d2SAndroid Build Coastguard Worker return (1);
5531*5e7646d2SAndroid Build Coastguard Worker
5532*5e7646d2SAndroid Build Coastguard Worker /*
5533*5e7646d2SAndroid Build Coastguard Worker * Compare the value string to the attribute value.
5534*5e7646d2SAndroid Build Coastguard Worker */
5535*5e7646d2SAndroid Build Coastguard Worker
5536*5e7646d2SAndroid Build Coastguard Worker name = ippGetName(attr);
5537*5e7646d2SAndroid Build Coastguard Worker count = ippGetCount(attr);
5538*5e7646d2SAndroid Build Coastguard Worker
5539*5e7646d2SAndroid Build Coastguard Worker switch (ippGetValueTag(attr))
5540*5e7646d2SAndroid Build Coastguard Worker {
5541*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
5542*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
5543*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
5544*5e7646d2SAndroid Build Coastguard Worker {
5545*5e7646d2SAndroid Build Coastguard Worker char op, /* Comparison operator */
5546*5e7646d2SAndroid Build Coastguard Worker *nextptr; /* Next pointer */
5547*5e7646d2SAndroid Build Coastguard Worker int intvalue, /* Integer value */
5548*5e7646d2SAndroid Build Coastguard Worker attrvalue = ippGetInteger(attr, i),
5549*5e7646d2SAndroid Build Coastguard Worker /* Attribute value */
5550*5e7646d2SAndroid Build Coastguard Worker valmatch = 0; /* Does the current value match? */
5551*5e7646d2SAndroid Build Coastguard Worker
5552*5e7646d2SAndroid Build Coastguard Worker valptr = value;
5553*5e7646d2SAndroid Build Coastguard Worker
5554*5e7646d2SAndroid Build Coastguard Worker while (isspace(*valptr & 255) || isdigit(*valptr & 255) ||
5555*5e7646d2SAndroid Build Coastguard Worker *valptr == '-' || *valptr == ',' || *valptr == '<' ||
5556*5e7646d2SAndroid Build Coastguard Worker *valptr == '=' || *valptr == '>')
5557*5e7646d2SAndroid Build Coastguard Worker {
5558*5e7646d2SAndroid Build Coastguard Worker op = '=';
5559*5e7646d2SAndroid Build Coastguard Worker while (*valptr && !isdigit(*valptr & 255) && *valptr != '-')
5560*5e7646d2SAndroid Build Coastguard Worker {
5561*5e7646d2SAndroid Build Coastguard Worker if (*valptr == '<' || *valptr == '>' || *valptr == '=')
5562*5e7646d2SAndroid Build Coastguard Worker op = *valptr;
5563*5e7646d2SAndroid Build Coastguard Worker valptr ++;
5564*5e7646d2SAndroid Build Coastguard Worker }
5565*5e7646d2SAndroid Build Coastguard Worker
5566*5e7646d2SAndroid Build Coastguard Worker if (!*valptr)
5567*5e7646d2SAndroid Build Coastguard Worker break;
5568*5e7646d2SAndroid Build Coastguard Worker
5569*5e7646d2SAndroid Build Coastguard Worker intvalue = (int)strtol(valptr, &nextptr, 0);
5570*5e7646d2SAndroid Build Coastguard Worker if (nextptr == valptr)
5571*5e7646d2SAndroid Build Coastguard Worker break;
5572*5e7646d2SAndroid Build Coastguard Worker valptr = nextptr;
5573*5e7646d2SAndroid Build Coastguard Worker
5574*5e7646d2SAndroid Build Coastguard Worker if ((op == '=' && attrvalue == intvalue) ||
5575*5e7646d2SAndroid Build Coastguard Worker (op == '<' && attrvalue < intvalue) ||
5576*5e7646d2SAndroid Build Coastguard Worker (op == '>' && attrvalue > intvalue))
5577*5e7646d2SAndroid Build Coastguard Worker {
5578*5e7646d2SAndroid Build Coastguard Worker if (!matchbuf[0])
5579*5e7646d2SAndroid Build Coastguard Worker snprintf(matchbuf, matchlen, "%d", attrvalue);
5580*5e7646d2SAndroid Build Coastguard Worker
5581*5e7646d2SAndroid Build Coastguard Worker valmatch = 1;
5582*5e7646d2SAndroid Build Coastguard Worker break;
5583*5e7646d2SAndroid Build Coastguard Worker }
5584*5e7646d2SAndroid Build Coastguard Worker }
5585*5e7646d2SAndroid Build Coastguard Worker
5586*5e7646d2SAndroid Build Coastguard Worker if (flags & IPPTOOL_WITH_ALL)
5587*5e7646d2SAndroid Build Coastguard Worker {
5588*5e7646d2SAndroid Build Coastguard Worker if (!valmatch)
5589*5e7646d2SAndroid Build Coastguard Worker {
5590*5e7646d2SAndroid Build Coastguard Worker match = 0;
5591*5e7646d2SAndroid Build Coastguard Worker break;
5592*5e7646d2SAndroid Build Coastguard Worker }
5593*5e7646d2SAndroid Build Coastguard Worker }
5594*5e7646d2SAndroid Build Coastguard Worker else if (valmatch)
5595*5e7646d2SAndroid Build Coastguard Worker {
5596*5e7646d2SAndroid Build Coastguard Worker match = 1;
5597*5e7646d2SAndroid Build Coastguard Worker break;
5598*5e7646d2SAndroid Build Coastguard Worker }
5599*5e7646d2SAndroid Build Coastguard Worker }
5600*5e7646d2SAndroid Build Coastguard Worker
5601*5e7646d2SAndroid Build Coastguard Worker if (!match && errors)
5602*5e7646d2SAndroid Build Coastguard Worker {
5603*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
5604*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "GOT: %s=%d", name, ippGetInteger(attr, i));
5605*5e7646d2SAndroid Build Coastguard Worker }
5606*5e7646d2SAndroid Build Coastguard Worker break;
5607*5e7646d2SAndroid Build Coastguard Worker
5608*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
5609*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
5610*5e7646d2SAndroid Build Coastguard Worker {
5611*5e7646d2SAndroid Build Coastguard Worker char op, /* Comparison operator */
5612*5e7646d2SAndroid Build Coastguard Worker *nextptr; /* Next pointer */
5613*5e7646d2SAndroid Build Coastguard Worker int intvalue, /* Integer value */
5614*5e7646d2SAndroid Build Coastguard Worker lower, /* Lower range */
5615*5e7646d2SAndroid Build Coastguard Worker upper, /* Upper range */
5616*5e7646d2SAndroid Build Coastguard Worker valmatch = 0; /* Does the current value match? */
5617*5e7646d2SAndroid Build Coastguard Worker
5618*5e7646d2SAndroid Build Coastguard Worker lower = ippGetRange(attr, i, &upper);
5619*5e7646d2SAndroid Build Coastguard Worker valptr = value;
5620*5e7646d2SAndroid Build Coastguard Worker
5621*5e7646d2SAndroid Build Coastguard Worker while (isspace(*valptr & 255) || isdigit(*valptr & 255) ||
5622*5e7646d2SAndroid Build Coastguard Worker *valptr == '-' || *valptr == ',' || *valptr == '<' ||
5623*5e7646d2SAndroid Build Coastguard Worker *valptr == '=' || *valptr == '>')
5624*5e7646d2SAndroid Build Coastguard Worker {
5625*5e7646d2SAndroid Build Coastguard Worker op = '=';
5626*5e7646d2SAndroid Build Coastguard Worker while (*valptr && !isdigit(*valptr & 255) && *valptr != '-')
5627*5e7646d2SAndroid Build Coastguard Worker {
5628*5e7646d2SAndroid Build Coastguard Worker if (*valptr == '<' || *valptr == '>' || *valptr == '=')
5629*5e7646d2SAndroid Build Coastguard Worker op = *valptr;
5630*5e7646d2SAndroid Build Coastguard Worker valptr ++;
5631*5e7646d2SAndroid Build Coastguard Worker }
5632*5e7646d2SAndroid Build Coastguard Worker
5633*5e7646d2SAndroid Build Coastguard Worker if (!*valptr)
5634*5e7646d2SAndroid Build Coastguard Worker break;
5635*5e7646d2SAndroid Build Coastguard Worker
5636*5e7646d2SAndroid Build Coastguard Worker intvalue = (int)strtol(valptr, &nextptr, 0);
5637*5e7646d2SAndroid Build Coastguard Worker if (nextptr == valptr)
5638*5e7646d2SAndroid Build Coastguard Worker break;
5639*5e7646d2SAndroid Build Coastguard Worker valptr = nextptr;
5640*5e7646d2SAndroid Build Coastguard Worker
5641*5e7646d2SAndroid Build Coastguard Worker if ((op == '=' && (lower == intvalue || upper == intvalue)) ||
5642*5e7646d2SAndroid Build Coastguard Worker (op == '<' && upper < intvalue) ||
5643*5e7646d2SAndroid Build Coastguard Worker (op == '>' && upper > intvalue))
5644*5e7646d2SAndroid Build Coastguard Worker {
5645*5e7646d2SAndroid Build Coastguard Worker if (!matchbuf[0])
5646*5e7646d2SAndroid Build Coastguard Worker snprintf(matchbuf, matchlen, "%d-%d", lower, upper);
5647*5e7646d2SAndroid Build Coastguard Worker
5648*5e7646d2SAndroid Build Coastguard Worker valmatch = 1;
5649*5e7646d2SAndroid Build Coastguard Worker break;
5650*5e7646d2SAndroid Build Coastguard Worker }
5651*5e7646d2SAndroid Build Coastguard Worker }
5652*5e7646d2SAndroid Build Coastguard Worker
5653*5e7646d2SAndroid Build Coastguard Worker if (flags & IPPTOOL_WITH_ALL)
5654*5e7646d2SAndroid Build Coastguard Worker {
5655*5e7646d2SAndroid Build Coastguard Worker if (!valmatch)
5656*5e7646d2SAndroid Build Coastguard Worker {
5657*5e7646d2SAndroid Build Coastguard Worker match = 0;
5658*5e7646d2SAndroid Build Coastguard Worker break;
5659*5e7646d2SAndroid Build Coastguard Worker }
5660*5e7646d2SAndroid Build Coastguard Worker }
5661*5e7646d2SAndroid Build Coastguard Worker else if (valmatch)
5662*5e7646d2SAndroid Build Coastguard Worker {
5663*5e7646d2SAndroid Build Coastguard Worker match = 1;
5664*5e7646d2SAndroid Build Coastguard Worker break;
5665*5e7646d2SAndroid Build Coastguard Worker }
5666*5e7646d2SAndroid Build Coastguard Worker }
5667*5e7646d2SAndroid Build Coastguard Worker
5668*5e7646d2SAndroid Build Coastguard Worker if (!match && errors)
5669*5e7646d2SAndroid Build Coastguard Worker {
5670*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
5671*5e7646d2SAndroid Build Coastguard Worker {
5672*5e7646d2SAndroid Build Coastguard Worker int lower, upper; /* Range values */
5673*5e7646d2SAndroid Build Coastguard Worker
5674*5e7646d2SAndroid Build Coastguard Worker lower = ippGetRange(attr, i, &upper);
5675*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "GOT: %s=%d-%d", name, lower, upper);
5676*5e7646d2SAndroid Build Coastguard Worker }
5677*5e7646d2SAndroid Build Coastguard Worker }
5678*5e7646d2SAndroid Build Coastguard Worker break;
5679*5e7646d2SAndroid Build Coastguard Worker
5680*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BOOLEAN :
5681*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
5682*5e7646d2SAndroid Build Coastguard Worker {
5683*5e7646d2SAndroid Build Coastguard Worker if ((!strcmp(value, "true") || !strcmp(value, "1")) == ippGetBoolean(attr, i))
5684*5e7646d2SAndroid Build Coastguard Worker {
5685*5e7646d2SAndroid Build Coastguard Worker if (!matchbuf[0])
5686*5e7646d2SAndroid Build Coastguard Worker strlcpy(matchbuf, value, matchlen);
5687*5e7646d2SAndroid Build Coastguard Worker
5688*5e7646d2SAndroid Build Coastguard Worker if (!(flags & IPPTOOL_WITH_ALL))
5689*5e7646d2SAndroid Build Coastguard Worker {
5690*5e7646d2SAndroid Build Coastguard Worker match = 1;
5691*5e7646d2SAndroid Build Coastguard Worker break;
5692*5e7646d2SAndroid Build Coastguard Worker }
5693*5e7646d2SAndroid Build Coastguard Worker }
5694*5e7646d2SAndroid Build Coastguard Worker else if (flags & IPPTOOL_WITH_ALL)
5695*5e7646d2SAndroid Build Coastguard Worker {
5696*5e7646d2SAndroid Build Coastguard Worker match = 0;
5697*5e7646d2SAndroid Build Coastguard Worker break;
5698*5e7646d2SAndroid Build Coastguard Worker }
5699*5e7646d2SAndroid Build Coastguard Worker }
5700*5e7646d2SAndroid Build Coastguard Worker
5701*5e7646d2SAndroid Build Coastguard Worker if (!match && errors)
5702*5e7646d2SAndroid Build Coastguard Worker {
5703*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
5704*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "GOT: %s=%s", name, ippGetBoolean(attr, i) ? "true" : "false");
5705*5e7646d2SAndroid Build Coastguard Worker }
5706*5e7646d2SAndroid Build Coastguard Worker break;
5707*5e7646d2SAndroid Build Coastguard Worker
5708*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
5709*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
5710*5e7646d2SAndroid Build Coastguard Worker {
5711*5e7646d2SAndroid Build Coastguard Worker int xres, yres; /* Resolution values */
5712*5e7646d2SAndroid Build Coastguard Worker ipp_res_t units; /* Resolution units */
5713*5e7646d2SAndroid Build Coastguard Worker
5714*5e7646d2SAndroid Build Coastguard Worker xres = ippGetResolution(attr, i, &yres, &units);
5715*5e7646d2SAndroid Build Coastguard Worker if (xres == yres)
5716*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), "%d%s", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
5717*5e7646d2SAndroid Build Coastguard Worker else
5718*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), "%dx%d%s", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
5719*5e7646d2SAndroid Build Coastguard Worker
5720*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(value, temp))
5721*5e7646d2SAndroid Build Coastguard Worker {
5722*5e7646d2SAndroid Build Coastguard Worker if (!matchbuf[0])
5723*5e7646d2SAndroid Build Coastguard Worker strlcpy(matchbuf, value, matchlen);
5724*5e7646d2SAndroid Build Coastguard Worker
5725*5e7646d2SAndroid Build Coastguard Worker if (!(flags & IPPTOOL_WITH_ALL))
5726*5e7646d2SAndroid Build Coastguard Worker {
5727*5e7646d2SAndroid Build Coastguard Worker match = 1;
5728*5e7646d2SAndroid Build Coastguard Worker break;
5729*5e7646d2SAndroid Build Coastguard Worker }
5730*5e7646d2SAndroid Build Coastguard Worker }
5731*5e7646d2SAndroid Build Coastguard Worker else if (flags & IPPTOOL_WITH_ALL)
5732*5e7646d2SAndroid Build Coastguard Worker {
5733*5e7646d2SAndroid Build Coastguard Worker match = 0;
5734*5e7646d2SAndroid Build Coastguard Worker break;
5735*5e7646d2SAndroid Build Coastguard Worker }
5736*5e7646d2SAndroid Build Coastguard Worker }
5737*5e7646d2SAndroid Build Coastguard Worker
5738*5e7646d2SAndroid Build Coastguard Worker if (!match && errors)
5739*5e7646d2SAndroid Build Coastguard Worker {
5740*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
5741*5e7646d2SAndroid Build Coastguard Worker {
5742*5e7646d2SAndroid Build Coastguard Worker int xres, yres; /* Resolution values */
5743*5e7646d2SAndroid Build Coastguard Worker ipp_res_t units; /* Resolution units */
5744*5e7646d2SAndroid Build Coastguard Worker
5745*5e7646d2SAndroid Build Coastguard Worker xres = ippGetResolution(attr, i, &yres, &units);
5746*5e7646d2SAndroid Build Coastguard Worker if (xres == yres)
5747*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), "%d%s", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
5748*5e7646d2SAndroid Build Coastguard Worker else
5749*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), "%dx%d%s", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
5750*5e7646d2SAndroid Build Coastguard Worker
5751*5e7646d2SAndroid Build Coastguard Worker if (strcmp(value, temp))
5752*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "GOT: %s=%s", name, temp);
5753*5e7646d2SAndroid Build Coastguard Worker }
5754*5e7646d2SAndroid Build Coastguard Worker }
5755*5e7646d2SAndroid Build Coastguard Worker break;
5756*5e7646d2SAndroid Build Coastguard Worker
5757*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NOVALUE :
5758*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNKNOWN :
5759*5e7646d2SAndroid Build Coastguard Worker return (1);
5760*5e7646d2SAndroid Build Coastguard Worker
5761*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
5762*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
5763*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
5764*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
5765*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
5766*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
5767*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
5768*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
5769*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
5770*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
5771*5e7646d2SAndroid Build Coastguard Worker if (flags & IPPTOOL_WITH_REGEX)
5772*5e7646d2SAndroid Build Coastguard Worker {
5773*5e7646d2SAndroid Build Coastguard Worker /*
5774*5e7646d2SAndroid Build Coastguard Worker * Value is an extended, case-sensitive POSIX regular expression...
5775*5e7646d2SAndroid Build Coastguard Worker */
5776*5e7646d2SAndroid Build Coastguard Worker
5777*5e7646d2SAndroid Build Coastguard Worker regex_t re; /* Regular expression */
5778*5e7646d2SAndroid Build Coastguard Worker
5779*5e7646d2SAndroid Build Coastguard Worker if ((i = regcomp(&re, value, REG_EXTENDED | REG_NOSUB)) != 0)
5780*5e7646d2SAndroid Build Coastguard Worker {
5781*5e7646d2SAndroid Build Coastguard Worker regerror(i, &re, temp, sizeof(temp));
5782*5e7646d2SAndroid Build Coastguard Worker
5783*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Unable to compile WITH-VALUE regular expression \"%s\" - %s", value, temp);
5784*5e7646d2SAndroid Build Coastguard Worker return (0);
5785*5e7646d2SAndroid Build Coastguard Worker }
5786*5e7646d2SAndroid Build Coastguard Worker
5787*5e7646d2SAndroid Build Coastguard Worker /*
5788*5e7646d2SAndroid Build Coastguard Worker * See if ALL of the values match the given regular expression.
5789*5e7646d2SAndroid Build Coastguard Worker */
5790*5e7646d2SAndroid Build Coastguard Worker
5791*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
5792*5e7646d2SAndroid Build Coastguard Worker {
5793*5e7646d2SAndroid Build Coastguard Worker if (!regexec(&re, get_string(attr, i, flags, temp, sizeof(temp)),
5794*5e7646d2SAndroid Build Coastguard Worker 0, NULL, 0))
5795*5e7646d2SAndroid Build Coastguard Worker {
5796*5e7646d2SAndroid Build Coastguard Worker if (!matchbuf[0])
5797*5e7646d2SAndroid Build Coastguard Worker strlcpy(matchbuf, get_string(attr, i, flags, temp, sizeof(temp)), matchlen);
5798*5e7646d2SAndroid Build Coastguard Worker
5799*5e7646d2SAndroid Build Coastguard Worker if (!(flags & IPPTOOL_WITH_ALL))
5800*5e7646d2SAndroid Build Coastguard Worker {
5801*5e7646d2SAndroid Build Coastguard Worker match = 1;
5802*5e7646d2SAndroid Build Coastguard Worker break;
5803*5e7646d2SAndroid Build Coastguard Worker }
5804*5e7646d2SAndroid Build Coastguard Worker }
5805*5e7646d2SAndroid Build Coastguard Worker else if (flags & IPPTOOL_WITH_ALL)
5806*5e7646d2SAndroid Build Coastguard Worker {
5807*5e7646d2SAndroid Build Coastguard Worker match = 0;
5808*5e7646d2SAndroid Build Coastguard Worker break;
5809*5e7646d2SAndroid Build Coastguard Worker }
5810*5e7646d2SAndroid Build Coastguard Worker }
5811*5e7646d2SAndroid Build Coastguard Worker
5812*5e7646d2SAndroid Build Coastguard Worker regfree(&re);
5813*5e7646d2SAndroid Build Coastguard Worker }
5814*5e7646d2SAndroid Build Coastguard Worker else if (ippGetValueTag(attr) == IPP_TAG_URI && !(flags & (IPPTOOL_WITH_SCHEME | IPPTOOL_WITH_HOSTNAME | IPPTOOL_WITH_RESOURCE)))
5815*5e7646d2SAndroid Build Coastguard Worker {
5816*5e7646d2SAndroid Build Coastguard Worker /*
5817*5e7646d2SAndroid Build Coastguard Worker * Value is a literal URI string, see if the value(s) match...
5818*5e7646d2SAndroid Build Coastguard Worker */
5819*5e7646d2SAndroid Build Coastguard Worker
5820*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
5821*5e7646d2SAndroid Build Coastguard Worker {
5822*5e7646d2SAndroid Build Coastguard Worker if (!compare_uris(value, get_string(attr, i, flags, temp, sizeof(temp))))
5823*5e7646d2SAndroid Build Coastguard Worker {
5824*5e7646d2SAndroid Build Coastguard Worker if (!matchbuf[0])
5825*5e7646d2SAndroid Build Coastguard Worker strlcpy(matchbuf, get_string(attr, i, flags, temp, sizeof(temp)), matchlen);
5826*5e7646d2SAndroid Build Coastguard Worker
5827*5e7646d2SAndroid Build Coastguard Worker if (!(flags & IPPTOOL_WITH_ALL))
5828*5e7646d2SAndroid Build Coastguard Worker {
5829*5e7646d2SAndroid Build Coastguard Worker match = 1;
5830*5e7646d2SAndroid Build Coastguard Worker break;
5831*5e7646d2SAndroid Build Coastguard Worker }
5832*5e7646d2SAndroid Build Coastguard Worker }
5833*5e7646d2SAndroid Build Coastguard Worker else if (flags & IPPTOOL_WITH_ALL)
5834*5e7646d2SAndroid Build Coastguard Worker {
5835*5e7646d2SAndroid Build Coastguard Worker match = 0;
5836*5e7646d2SAndroid Build Coastguard Worker break;
5837*5e7646d2SAndroid Build Coastguard Worker }
5838*5e7646d2SAndroid Build Coastguard Worker }
5839*5e7646d2SAndroid Build Coastguard Worker }
5840*5e7646d2SAndroid Build Coastguard Worker else
5841*5e7646d2SAndroid Build Coastguard Worker {
5842*5e7646d2SAndroid Build Coastguard Worker /*
5843*5e7646d2SAndroid Build Coastguard Worker * Value is a literal string, see if the value(s) match...
5844*5e7646d2SAndroid Build Coastguard Worker */
5845*5e7646d2SAndroid Build Coastguard Worker
5846*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
5847*5e7646d2SAndroid Build Coastguard Worker {
5848*5e7646d2SAndroid Build Coastguard Worker int result;
5849*5e7646d2SAndroid Build Coastguard Worker
5850*5e7646d2SAndroid Build Coastguard Worker switch (ippGetValueTag(attr))
5851*5e7646d2SAndroid Build Coastguard Worker {
5852*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
5853*5e7646d2SAndroid Build Coastguard Worker /*
5854*5e7646d2SAndroid Build Coastguard Worker * Some URI components are case-sensitive, some not...
5855*5e7646d2SAndroid Build Coastguard Worker */
5856*5e7646d2SAndroid Build Coastguard Worker
5857*5e7646d2SAndroid Build Coastguard Worker if (flags & (IPPTOOL_WITH_SCHEME | IPPTOOL_WITH_HOSTNAME))
5858*5e7646d2SAndroid Build Coastguard Worker result = _cups_strcasecmp(value, get_string(attr, i, flags, temp, sizeof(temp)));
5859*5e7646d2SAndroid Build Coastguard Worker else
5860*5e7646d2SAndroid Build Coastguard Worker result = strcmp(value, get_string(attr, i, flags, temp, sizeof(temp)));
5861*5e7646d2SAndroid Build Coastguard Worker break;
5862*5e7646d2SAndroid Build Coastguard Worker
5863*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
5864*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
5865*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
5866*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
5867*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
5868*5e7646d2SAndroid Build Coastguard Worker /*
5869*5e7646d2SAndroid Build Coastguard Worker * mimeMediaType, nameWithoutLanguage, nameWithLanguage,
5870*5e7646d2SAndroid Build Coastguard Worker * textWithoutLanguage, and textWithLanguage are defined to
5871*5e7646d2SAndroid Build Coastguard Worker * be case-insensitive strings...
5872*5e7646d2SAndroid Build Coastguard Worker */
5873*5e7646d2SAndroid Build Coastguard Worker
5874*5e7646d2SAndroid Build Coastguard Worker result = _cups_strcasecmp(value, get_string(attr, i, flags, temp, sizeof(temp)));
5875*5e7646d2SAndroid Build Coastguard Worker break;
5876*5e7646d2SAndroid Build Coastguard Worker
5877*5e7646d2SAndroid Build Coastguard Worker default :
5878*5e7646d2SAndroid Build Coastguard Worker /*
5879*5e7646d2SAndroid Build Coastguard Worker * Other string syntaxes are defined as lowercased so we use
5880*5e7646d2SAndroid Build Coastguard Worker * case-sensitive comparisons to catch problems...
5881*5e7646d2SAndroid Build Coastguard Worker */
5882*5e7646d2SAndroid Build Coastguard Worker
5883*5e7646d2SAndroid Build Coastguard Worker result = strcmp(value, get_string(attr, i, flags, temp, sizeof(temp)));
5884*5e7646d2SAndroid Build Coastguard Worker break;
5885*5e7646d2SAndroid Build Coastguard Worker }
5886*5e7646d2SAndroid Build Coastguard Worker
5887*5e7646d2SAndroid Build Coastguard Worker if (!result)
5888*5e7646d2SAndroid Build Coastguard Worker {
5889*5e7646d2SAndroid Build Coastguard Worker if (!matchbuf[0])
5890*5e7646d2SAndroid Build Coastguard Worker strlcpy(matchbuf, get_string(attr, i, flags, temp, sizeof(temp)), matchlen);
5891*5e7646d2SAndroid Build Coastguard Worker
5892*5e7646d2SAndroid Build Coastguard Worker if (!(flags & IPPTOOL_WITH_ALL))
5893*5e7646d2SAndroid Build Coastguard Worker {
5894*5e7646d2SAndroid Build Coastguard Worker match = 1;
5895*5e7646d2SAndroid Build Coastguard Worker break;
5896*5e7646d2SAndroid Build Coastguard Worker }
5897*5e7646d2SAndroid Build Coastguard Worker }
5898*5e7646d2SAndroid Build Coastguard Worker else if (flags & IPPTOOL_WITH_ALL)
5899*5e7646d2SAndroid Build Coastguard Worker {
5900*5e7646d2SAndroid Build Coastguard Worker match = 0;
5901*5e7646d2SAndroid Build Coastguard Worker break;
5902*5e7646d2SAndroid Build Coastguard Worker }
5903*5e7646d2SAndroid Build Coastguard Worker }
5904*5e7646d2SAndroid Build Coastguard Worker }
5905*5e7646d2SAndroid Build Coastguard Worker
5906*5e7646d2SAndroid Build Coastguard Worker if (!match && errors)
5907*5e7646d2SAndroid Build Coastguard Worker {
5908*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
5909*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "GOT: %s=\"%s\"", name, ippGetString(attr, i, NULL));
5910*5e7646d2SAndroid Build Coastguard Worker }
5911*5e7646d2SAndroid Build Coastguard Worker break;
5912*5e7646d2SAndroid Build Coastguard Worker
5913*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_STRING :
5914*5e7646d2SAndroid Build Coastguard Worker if (flags & IPPTOOL_WITH_REGEX)
5915*5e7646d2SAndroid Build Coastguard Worker {
5916*5e7646d2SAndroid Build Coastguard Worker /*
5917*5e7646d2SAndroid Build Coastguard Worker * Value is an extended, case-sensitive POSIX regular expression...
5918*5e7646d2SAndroid Build Coastguard Worker */
5919*5e7646d2SAndroid Build Coastguard Worker
5920*5e7646d2SAndroid Build Coastguard Worker void *adata; /* Pointer to octetString data */
5921*5e7646d2SAndroid Build Coastguard Worker int adatalen; /* Length of octetString */
5922*5e7646d2SAndroid Build Coastguard Worker regex_t re; /* Regular expression */
5923*5e7646d2SAndroid Build Coastguard Worker
5924*5e7646d2SAndroid Build Coastguard Worker if ((i = regcomp(&re, value, REG_EXTENDED | REG_NOSUB)) != 0)
5925*5e7646d2SAndroid Build Coastguard Worker {
5926*5e7646d2SAndroid Build Coastguard Worker regerror(i, &re, temp, sizeof(temp));
5927*5e7646d2SAndroid Build Coastguard Worker
5928*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Unable to compile WITH-VALUE regular expression \"%s\" - %s", value, temp);
5929*5e7646d2SAndroid Build Coastguard Worker return (0);
5930*5e7646d2SAndroid Build Coastguard Worker }
5931*5e7646d2SAndroid Build Coastguard Worker
5932*5e7646d2SAndroid Build Coastguard Worker /*
5933*5e7646d2SAndroid Build Coastguard Worker * See if ALL of the values match the given regular expression.
5934*5e7646d2SAndroid Build Coastguard Worker */
5935*5e7646d2SAndroid Build Coastguard Worker
5936*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
5937*5e7646d2SAndroid Build Coastguard Worker {
5938*5e7646d2SAndroid Build Coastguard Worker if ((adata = ippGetOctetString(attr, i, &adatalen)) == NULL || adatalen >= (int)sizeof(temp))
5939*5e7646d2SAndroid Build Coastguard Worker {
5940*5e7646d2SAndroid Build Coastguard Worker match = 0;
5941*5e7646d2SAndroid Build Coastguard Worker break;
5942*5e7646d2SAndroid Build Coastguard Worker }
5943*5e7646d2SAndroid Build Coastguard Worker memcpy(temp, adata, (size_t)adatalen);
5944*5e7646d2SAndroid Build Coastguard Worker temp[adatalen] = '\0';
5945*5e7646d2SAndroid Build Coastguard Worker
5946*5e7646d2SAndroid Build Coastguard Worker if (!regexec(&re, temp, 0, NULL, 0))
5947*5e7646d2SAndroid Build Coastguard Worker {
5948*5e7646d2SAndroid Build Coastguard Worker if (!matchbuf[0])
5949*5e7646d2SAndroid Build Coastguard Worker strlcpy(matchbuf, temp, matchlen);
5950*5e7646d2SAndroid Build Coastguard Worker
5951*5e7646d2SAndroid Build Coastguard Worker if (!(flags & IPPTOOL_WITH_ALL))
5952*5e7646d2SAndroid Build Coastguard Worker {
5953*5e7646d2SAndroid Build Coastguard Worker match = 1;
5954*5e7646d2SAndroid Build Coastguard Worker break;
5955*5e7646d2SAndroid Build Coastguard Worker }
5956*5e7646d2SAndroid Build Coastguard Worker }
5957*5e7646d2SAndroid Build Coastguard Worker else if (flags & IPPTOOL_WITH_ALL)
5958*5e7646d2SAndroid Build Coastguard Worker {
5959*5e7646d2SAndroid Build Coastguard Worker match = 0;
5960*5e7646d2SAndroid Build Coastguard Worker break;
5961*5e7646d2SAndroid Build Coastguard Worker }
5962*5e7646d2SAndroid Build Coastguard Worker }
5963*5e7646d2SAndroid Build Coastguard Worker
5964*5e7646d2SAndroid Build Coastguard Worker regfree(&re);
5965*5e7646d2SAndroid Build Coastguard Worker
5966*5e7646d2SAndroid Build Coastguard Worker if (!match && errors)
5967*5e7646d2SAndroid Build Coastguard Worker {
5968*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
5969*5e7646d2SAndroid Build Coastguard Worker {
5970*5e7646d2SAndroid Build Coastguard Worker adata = ippGetOctetString(attr, i, &adatalen);
5971*5e7646d2SAndroid Build Coastguard Worker copy_hex_string(temp, adata, adatalen, sizeof(temp));
5972*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "GOT: %s=\"%s\"", name, temp);
5973*5e7646d2SAndroid Build Coastguard Worker }
5974*5e7646d2SAndroid Build Coastguard Worker }
5975*5e7646d2SAndroid Build Coastguard Worker }
5976*5e7646d2SAndroid Build Coastguard Worker else
5977*5e7646d2SAndroid Build Coastguard Worker {
5978*5e7646d2SAndroid Build Coastguard Worker /*
5979*5e7646d2SAndroid Build Coastguard Worker * Value is a literal or hex-encoded string...
5980*5e7646d2SAndroid Build Coastguard Worker */
5981*5e7646d2SAndroid Build Coastguard Worker
5982*5e7646d2SAndroid Build Coastguard Worker unsigned char withdata[1023], /* WITH-VALUE data */
5983*5e7646d2SAndroid Build Coastguard Worker *adata; /* Pointer to octetString data */
5984*5e7646d2SAndroid Build Coastguard Worker int withlen, /* Length of WITH-VALUE data */
5985*5e7646d2SAndroid Build Coastguard Worker adatalen; /* Length of octetString */
5986*5e7646d2SAndroid Build Coastguard Worker
5987*5e7646d2SAndroid Build Coastguard Worker if (*value == '<')
5988*5e7646d2SAndroid Build Coastguard Worker {
5989*5e7646d2SAndroid Build Coastguard Worker /*
5990*5e7646d2SAndroid Build Coastguard Worker * Grab hex-encoded value...
5991*5e7646d2SAndroid Build Coastguard Worker */
5992*5e7646d2SAndroid Build Coastguard Worker
5993*5e7646d2SAndroid Build Coastguard Worker if ((withlen = (int)strlen(value)) & 1 || withlen > (int)(2 * (sizeof(withdata) + 1)))
5994*5e7646d2SAndroid Build Coastguard Worker {
5995*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad WITH-VALUE hex value.");
5996*5e7646d2SAndroid Build Coastguard Worker return (0);
5997*5e7646d2SAndroid Build Coastguard Worker }
5998*5e7646d2SAndroid Build Coastguard Worker
5999*5e7646d2SAndroid Build Coastguard Worker withlen = withlen / 2 - 1;
6000*5e7646d2SAndroid Build Coastguard Worker
6001*5e7646d2SAndroid Build Coastguard Worker for (valptr = value + 1, adata = withdata; *valptr; valptr += 2)
6002*5e7646d2SAndroid Build Coastguard Worker {
6003*5e7646d2SAndroid Build Coastguard Worker int ch; /* Current character/byte */
6004*5e7646d2SAndroid Build Coastguard Worker
6005*5e7646d2SAndroid Build Coastguard Worker if (isdigit(valptr[0]))
6006*5e7646d2SAndroid Build Coastguard Worker ch = (valptr[0] - '0') << 4;
6007*5e7646d2SAndroid Build Coastguard Worker else if (isalpha(valptr[0]))
6008*5e7646d2SAndroid Build Coastguard Worker ch = (tolower(valptr[0]) - 'a' + 10) << 4;
6009*5e7646d2SAndroid Build Coastguard Worker else
6010*5e7646d2SAndroid Build Coastguard Worker break;
6011*5e7646d2SAndroid Build Coastguard Worker
6012*5e7646d2SAndroid Build Coastguard Worker if (isdigit(valptr[1]))
6013*5e7646d2SAndroid Build Coastguard Worker ch |= valptr[1] - '0';
6014*5e7646d2SAndroid Build Coastguard Worker else if (isalpha(valptr[1]))
6015*5e7646d2SAndroid Build Coastguard Worker ch |= tolower(valptr[1]) - 'a' + 10;
6016*5e7646d2SAndroid Build Coastguard Worker else
6017*5e7646d2SAndroid Build Coastguard Worker break;
6018*5e7646d2SAndroid Build Coastguard Worker
6019*5e7646d2SAndroid Build Coastguard Worker *adata++ = (unsigned char)ch;
6020*5e7646d2SAndroid Build Coastguard Worker }
6021*5e7646d2SAndroid Build Coastguard Worker
6022*5e7646d2SAndroid Build Coastguard Worker if (*valptr)
6023*5e7646d2SAndroid Build Coastguard Worker {
6024*5e7646d2SAndroid Build Coastguard Worker print_fatal_error(data, "Bad WITH-VALUE hex value.");
6025*5e7646d2SAndroid Build Coastguard Worker return (0);
6026*5e7646d2SAndroid Build Coastguard Worker }
6027*5e7646d2SAndroid Build Coastguard Worker }
6028*5e7646d2SAndroid Build Coastguard Worker else
6029*5e7646d2SAndroid Build Coastguard Worker {
6030*5e7646d2SAndroid Build Coastguard Worker /*
6031*5e7646d2SAndroid Build Coastguard Worker * Copy literal string value...
6032*5e7646d2SAndroid Build Coastguard Worker */
6033*5e7646d2SAndroid Build Coastguard Worker
6034*5e7646d2SAndroid Build Coastguard Worker withlen = (int)strlen(value);
6035*5e7646d2SAndroid Build Coastguard Worker
6036*5e7646d2SAndroid Build Coastguard Worker memcpy(withdata, value, (size_t)withlen);
6037*5e7646d2SAndroid Build Coastguard Worker }
6038*5e7646d2SAndroid Build Coastguard Worker
6039*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
6040*5e7646d2SAndroid Build Coastguard Worker {
6041*5e7646d2SAndroid Build Coastguard Worker adata = ippGetOctetString(attr, i, &adatalen);
6042*5e7646d2SAndroid Build Coastguard Worker
6043*5e7646d2SAndroid Build Coastguard Worker if (withlen == adatalen && !memcmp(withdata, adata, (size_t)withlen))
6044*5e7646d2SAndroid Build Coastguard Worker {
6045*5e7646d2SAndroid Build Coastguard Worker if (!matchbuf[0])
6046*5e7646d2SAndroid Build Coastguard Worker copy_hex_string(matchbuf, adata, adatalen, matchlen);
6047*5e7646d2SAndroid Build Coastguard Worker
6048*5e7646d2SAndroid Build Coastguard Worker if (!(flags & IPPTOOL_WITH_ALL))
6049*5e7646d2SAndroid Build Coastguard Worker {
6050*5e7646d2SAndroid Build Coastguard Worker match = 1;
6051*5e7646d2SAndroid Build Coastguard Worker break;
6052*5e7646d2SAndroid Build Coastguard Worker }
6053*5e7646d2SAndroid Build Coastguard Worker }
6054*5e7646d2SAndroid Build Coastguard Worker else if (flags & IPPTOOL_WITH_ALL)
6055*5e7646d2SAndroid Build Coastguard Worker {
6056*5e7646d2SAndroid Build Coastguard Worker match = 0;
6057*5e7646d2SAndroid Build Coastguard Worker break;
6058*5e7646d2SAndroid Build Coastguard Worker }
6059*5e7646d2SAndroid Build Coastguard Worker }
6060*5e7646d2SAndroid Build Coastguard Worker
6061*5e7646d2SAndroid Build Coastguard Worker if (!match && errors)
6062*5e7646d2SAndroid Build Coastguard Worker {
6063*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
6064*5e7646d2SAndroid Build Coastguard Worker {
6065*5e7646d2SAndroid Build Coastguard Worker adata = ippGetOctetString(attr, i, &adatalen);
6066*5e7646d2SAndroid Build Coastguard Worker copy_hex_string(temp, adata, adatalen, sizeof(temp));
6067*5e7646d2SAndroid Build Coastguard Worker add_stringf(data->errors, "GOT: %s=\"%s\"", name, temp);
6068*5e7646d2SAndroid Build Coastguard Worker }
6069*5e7646d2SAndroid Build Coastguard Worker }
6070*5e7646d2SAndroid Build Coastguard Worker }
6071*5e7646d2SAndroid Build Coastguard Worker break;
6072*5e7646d2SAndroid Build Coastguard Worker
6073*5e7646d2SAndroid Build Coastguard Worker default :
6074*5e7646d2SAndroid Build Coastguard Worker break;
6075*5e7646d2SAndroid Build Coastguard Worker }
6076*5e7646d2SAndroid Build Coastguard Worker
6077*5e7646d2SAndroid Build Coastguard Worker return (match);
6078*5e7646d2SAndroid Build Coastguard Worker }
6079*5e7646d2SAndroid Build Coastguard Worker
6080*5e7646d2SAndroid Build Coastguard Worker
6081*5e7646d2SAndroid Build Coastguard Worker /*
6082*5e7646d2SAndroid Build Coastguard Worker * 'with_value_from()' - Test a WITH-VALUE-FROM predicate.
6083*5e7646d2SAndroid Build Coastguard Worker */
6084*5e7646d2SAndroid Build Coastguard Worker
6085*5e7646d2SAndroid Build Coastguard Worker static int /* O - 1 on match, 0 on non-match */
with_value_from(cups_array_t * errors,ipp_attribute_t * fromattr,ipp_attribute_t * attr,char * matchbuf,size_t matchlen)6086*5e7646d2SAndroid Build Coastguard Worker with_value_from(
6087*5e7646d2SAndroid Build Coastguard Worker cups_array_t *errors, /* I - Errors array */
6088*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *fromattr, /* I - "From" attribute */
6089*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr, /* I - Attribute to compare */
6090*5e7646d2SAndroid Build Coastguard Worker char *matchbuf, /* I - Buffer to hold matching value */
6091*5e7646d2SAndroid Build Coastguard Worker size_t matchlen) /* I - Length of match buffer */
6092*5e7646d2SAndroid Build Coastguard Worker {
6093*5e7646d2SAndroid Build Coastguard Worker int i, j, /* Looping vars */
6094*5e7646d2SAndroid Build Coastguard Worker count = ippGetCount(attr), /* Number of attribute values */
6095*5e7646d2SAndroid Build Coastguard Worker match = 1; /* Match? */
6096*5e7646d2SAndroid Build Coastguard Worker
6097*5e7646d2SAndroid Build Coastguard Worker
6098*5e7646d2SAndroid Build Coastguard Worker *matchbuf = '\0';
6099*5e7646d2SAndroid Build Coastguard Worker
6100*5e7646d2SAndroid Build Coastguard Worker /*
6101*5e7646d2SAndroid Build Coastguard Worker * Compare the from value(s) to the attribute value(s)...
6102*5e7646d2SAndroid Build Coastguard Worker */
6103*5e7646d2SAndroid Build Coastguard Worker
6104*5e7646d2SAndroid Build Coastguard Worker switch (ippGetValueTag(attr))
6105*5e7646d2SAndroid Build Coastguard Worker {
6106*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
6107*5e7646d2SAndroid Build Coastguard Worker if (ippGetValueTag(fromattr) != IPP_TAG_INTEGER && ippGetValueTag(fromattr) != IPP_TAG_RANGE)
6108*5e7646d2SAndroid Build Coastguard Worker goto wrong_value_tag;
6109*5e7646d2SAndroid Build Coastguard Worker
6110*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
6111*5e7646d2SAndroid Build Coastguard Worker {
6112*5e7646d2SAndroid Build Coastguard Worker int value = ippGetInteger(attr, i);
6113*5e7646d2SAndroid Build Coastguard Worker /* Current integer value */
6114*5e7646d2SAndroid Build Coastguard Worker
6115*5e7646d2SAndroid Build Coastguard Worker if (ippContainsInteger(fromattr, value))
6116*5e7646d2SAndroid Build Coastguard Worker {
6117*5e7646d2SAndroid Build Coastguard Worker if (!matchbuf[0])
6118*5e7646d2SAndroid Build Coastguard Worker snprintf(matchbuf, matchlen, "%d", value);
6119*5e7646d2SAndroid Build Coastguard Worker }
6120*5e7646d2SAndroid Build Coastguard Worker else
6121*5e7646d2SAndroid Build Coastguard Worker {
6122*5e7646d2SAndroid Build Coastguard Worker add_stringf(errors, "GOT: %s=%d", ippGetName(attr), value);
6123*5e7646d2SAndroid Build Coastguard Worker match = 0;
6124*5e7646d2SAndroid Build Coastguard Worker }
6125*5e7646d2SAndroid Build Coastguard Worker }
6126*5e7646d2SAndroid Build Coastguard Worker break;
6127*5e7646d2SAndroid Build Coastguard Worker
6128*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
6129*5e7646d2SAndroid Build Coastguard Worker if (ippGetValueTag(fromattr) != IPP_TAG_ENUM)
6130*5e7646d2SAndroid Build Coastguard Worker goto wrong_value_tag;
6131*5e7646d2SAndroid Build Coastguard Worker
6132*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
6133*5e7646d2SAndroid Build Coastguard Worker {
6134*5e7646d2SAndroid Build Coastguard Worker int value = ippGetInteger(attr, i);
6135*5e7646d2SAndroid Build Coastguard Worker /* Current integer value */
6136*5e7646d2SAndroid Build Coastguard Worker
6137*5e7646d2SAndroid Build Coastguard Worker if (ippContainsInteger(fromattr, value))
6138*5e7646d2SAndroid Build Coastguard Worker {
6139*5e7646d2SAndroid Build Coastguard Worker if (!matchbuf[0])
6140*5e7646d2SAndroid Build Coastguard Worker snprintf(matchbuf, matchlen, "%d", value);
6141*5e7646d2SAndroid Build Coastguard Worker }
6142*5e7646d2SAndroid Build Coastguard Worker else
6143*5e7646d2SAndroid Build Coastguard Worker {
6144*5e7646d2SAndroid Build Coastguard Worker add_stringf(errors, "GOT: %s=%d", ippGetName(attr), value);
6145*5e7646d2SAndroid Build Coastguard Worker match = 0;
6146*5e7646d2SAndroid Build Coastguard Worker }
6147*5e7646d2SAndroid Build Coastguard Worker }
6148*5e7646d2SAndroid Build Coastguard Worker break;
6149*5e7646d2SAndroid Build Coastguard Worker
6150*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
6151*5e7646d2SAndroid Build Coastguard Worker if (ippGetValueTag(fromattr) != IPP_TAG_RESOLUTION)
6152*5e7646d2SAndroid Build Coastguard Worker goto wrong_value_tag;
6153*5e7646d2SAndroid Build Coastguard Worker
6154*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
6155*5e7646d2SAndroid Build Coastguard Worker {
6156*5e7646d2SAndroid Build Coastguard Worker int xres, yres;
6157*5e7646d2SAndroid Build Coastguard Worker ipp_res_t units;
6158*5e7646d2SAndroid Build Coastguard Worker int fromcount = ippGetCount(fromattr);
6159*5e7646d2SAndroid Build Coastguard Worker int fromxres, fromyres;
6160*5e7646d2SAndroid Build Coastguard Worker ipp_res_t fromunits;
6161*5e7646d2SAndroid Build Coastguard Worker
6162*5e7646d2SAndroid Build Coastguard Worker xres = ippGetResolution(attr, i, &yres, &units);
6163*5e7646d2SAndroid Build Coastguard Worker
6164*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < fromcount; j ++)
6165*5e7646d2SAndroid Build Coastguard Worker {
6166*5e7646d2SAndroid Build Coastguard Worker fromxres = ippGetResolution(fromattr, j, &fromyres, &fromunits);
6167*5e7646d2SAndroid Build Coastguard Worker if (fromxres == xres && fromyres == yres && fromunits == units)
6168*5e7646d2SAndroid Build Coastguard Worker break;
6169*5e7646d2SAndroid Build Coastguard Worker }
6170*5e7646d2SAndroid Build Coastguard Worker
6171*5e7646d2SAndroid Build Coastguard Worker if (j < fromcount)
6172*5e7646d2SAndroid Build Coastguard Worker {
6173*5e7646d2SAndroid Build Coastguard Worker if (!matchbuf[0])
6174*5e7646d2SAndroid Build Coastguard Worker {
6175*5e7646d2SAndroid Build Coastguard Worker if (xres == yres)
6176*5e7646d2SAndroid Build Coastguard Worker snprintf(matchbuf, matchlen, "%d%s", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
6177*5e7646d2SAndroid Build Coastguard Worker else
6178*5e7646d2SAndroid Build Coastguard Worker snprintf(matchbuf, matchlen, "%dx%d%s", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
6179*5e7646d2SAndroid Build Coastguard Worker }
6180*5e7646d2SAndroid Build Coastguard Worker }
6181*5e7646d2SAndroid Build Coastguard Worker else
6182*5e7646d2SAndroid Build Coastguard Worker {
6183*5e7646d2SAndroid Build Coastguard Worker if (xres == yres)
6184*5e7646d2SAndroid Build Coastguard Worker add_stringf(errors, "GOT: %s=%d%s", ippGetName(attr), xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
6185*5e7646d2SAndroid Build Coastguard Worker else
6186*5e7646d2SAndroid Build Coastguard Worker add_stringf(errors, "GOT: %s=%dx%d%s", ippGetName(attr), xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
6187*5e7646d2SAndroid Build Coastguard Worker
6188*5e7646d2SAndroid Build Coastguard Worker match = 0;
6189*5e7646d2SAndroid Build Coastguard Worker }
6190*5e7646d2SAndroid Build Coastguard Worker }
6191*5e7646d2SAndroid Build Coastguard Worker break;
6192*5e7646d2SAndroid Build Coastguard Worker
6193*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NOVALUE :
6194*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_UNKNOWN :
6195*5e7646d2SAndroid Build Coastguard Worker return (1);
6196*5e7646d2SAndroid Build Coastguard Worker
6197*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
6198*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
6199*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
6200*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_MIMETYPE :
6201*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
6202*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAMELANG :
6203*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
6204*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXTLANG :
6205*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URISCHEME :
6206*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
6207*5e7646d2SAndroid Build Coastguard Worker {
6208*5e7646d2SAndroid Build Coastguard Worker const char *value = ippGetString(attr, i, NULL);
6209*5e7646d2SAndroid Build Coastguard Worker /* Current string value */
6210*5e7646d2SAndroid Build Coastguard Worker
6211*5e7646d2SAndroid Build Coastguard Worker if (ippContainsString(fromattr, value))
6212*5e7646d2SAndroid Build Coastguard Worker {
6213*5e7646d2SAndroid Build Coastguard Worker if (!matchbuf[0])
6214*5e7646d2SAndroid Build Coastguard Worker strlcpy(matchbuf, value, matchlen);
6215*5e7646d2SAndroid Build Coastguard Worker }
6216*5e7646d2SAndroid Build Coastguard Worker else
6217*5e7646d2SAndroid Build Coastguard Worker {
6218*5e7646d2SAndroid Build Coastguard Worker add_stringf(errors, "GOT: %s='%s'", ippGetName(attr), value);
6219*5e7646d2SAndroid Build Coastguard Worker match = 0;
6220*5e7646d2SAndroid Build Coastguard Worker }
6221*5e7646d2SAndroid Build Coastguard Worker }
6222*5e7646d2SAndroid Build Coastguard Worker break;
6223*5e7646d2SAndroid Build Coastguard Worker
6224*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
6225*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
6226*5e7646d2SAndroid Build Coastguard Worker {
6227*5e7646d2SAndroid Build Coastguard Worker const char *value = ippGetString(attr, i, NULL);
6228*5e7646d2SAndroid Build Coastguard Worker /* Current string value */
6229*5e7646d2SAndroid Build Coastguard Worker int fromcount = ippGetCount(fromattr);
6230*5e7646d2SAndroid Build Coastguard Worker
6231*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < fromcount; j ++)
6232*5e7646d2SAndroid Build Coastguard Worker {
6233*5e7646d2SAndroid Build Coastguard Worker if (!compare_uris(value, ippGetString(fromattr, j, NULL)))
6234*5e7646d2SAndroid Build Coastguard Worker {
6235*5e7646d2SAndroid Build Coastguard Worker if (!matchbuf[0])
6236*5e7646d2SAndroid Build Coastguard Worker strlcpy(matchbuf, value, matchlen);
6237*5e7646d2SAndroid Build Coastguard Worker break;
6238*5e7646d2SAndroid Build Coastguard Worker }
6239*5e7646d2SAndroid Build Coastguard Worker }
6240*5e7646d2SAndroid Build Coastguard Worker
6241*5e7646d2SAndroid Build Coastguard Worker if (j >= fromcount)
6242*5e7646d2SAndroid Build Coastguard Worker {
6243*5e7646d2SAndroid Build Coastguard Worker add_stringf(errors, "GOT: %s='%s'", ippGetName(attr), value);
6244*5e7646d2SAndroid Build Coastguard Worker match = 0;
6245*5e7646d2SAndroid Build Coastguard Worker }
6246*5e7646d2SAndroid Build Coastguard Worker }
6247*5e7646d2SAndroid Build Coastguard Worker break;
6248*5e7646d2SAndroid Build Coastguard Worker
6249*5e7646d2SAndroid Build Coastguard Worker default :
6250*5e7646d2SAndroid Build Coastguard Worker match = 0;
6251*5e7646d2SAndroid Build Coastguard Worker break;
6252*5e7646d2SAndroid Build Coastguard Worker }
6253*5e7646d2SAndroid Build Coastguard Worker
6254*5e7646d2SAndroid Build Coastguard Worker return (match);
6255*5e7646d2SAndroid Build Coastguard Worker
6256*5e7646d2SAndroid Build Coastguard Worker /* value tag mismatch between fromattr and attr */
6257*5e7646d2SAndroid Build Coastguard Worker wrong_value_tag :
6258*5e7646d2SAndroid Build Coastguard Worker
6259*5e7646d2SAndroid Build Coastguard Worker add_stringf(errors, "GOT: %s OF-TYPE %s", ippGetName(attr), ippTagString(ippGetValueTag(attr)));
6260*5e7646d2SAndroid Build Coastguard Worker
6261*5e7646d2SAndroid Build Coastguard Worker return (0);
6262*5e7646d2SAndroid Build Coastguard Worker }
6263