/*
* "$Id$"
*
- * ipptool command for CUPS.
+ * ipptool command for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*
- * This file is subject to the Apple OS-Developed Software exception.
- *
- * Contents:
- *
- * main() - Parse options and do tests.
- * compare_vars() - Compare two variables.
- * do_tests() - Do tests as specified in the test file.
- * expand_variables() - Expand variables in a string.
- * expect_matches() - Return true if the tag matches the specification.
- * get_collection() - Get a collection value from the current test file.
- * get_filename() - Get a filename based on the current test file.
- * get_token() - Get a token from a file.
- * get_variable() - Get the value of a variable.
- * iso_date() - Return an ISO 8601 date/time string for the given IPP
- * dateTime value.
- * password_cb() - Password callback for authenticated tests.
- * print_attr() - Print an attribute on the screen.
- * print_col() - Print a collection attribute on the screen.
- * print_csv() - Print a line of CSV text.
- * print_fatal_error() - Print a fatal error message.
- * print_line() - Print a line of formatted or CSV text.
- * print_test_error() - Print a test error message.
- * print_xml_header() - Print a standard XML plist header.
- * print_xml_string() - Print an XML string with escaping.
- * print_xml_trailer() - Print the XML trailer with success/fail value.
- * set_variable() - Set a variable value.
- * sigterm_handler() - Handle SIGINT and SIGTERM.
- * timeout_cb() - Handle HTTP timeouts.
- * usage() - Show program usage.
- * validate_attr() - Determine whether an attribute is valid.
- * with_value() - Test a WITH-VALUE predicate.
+ * This file is subject to the Apple OS-Developed Software exception.
*/
/*
#include <cups/file-private.h>
#include <regex.h>
#include <sys/stat.h>
-
+#ifdef WIN32
+# include <windows.h>
+# ifndef R_OK
+# define R_OK 0
+# endif /* !R_OK */
+#else
+# include <signal.h>
+# include <termios.h>
+#endif /* WIN32 */
#ifndef O_BINARY
# define O_BINARY 0
#endif /* !O_BINARY */
_CUPS_OUTPUT_CSV /* Comma-separated values output */
} _cups_output_t;
+typedef enum _cups_with_e /**** WITH flags ****/
+{
+ _CUPS_WITH_LITERAL = 0, /* Match string is a literal value */
+ _CUPS_WITH_ALL = 1, /* Must match all values */
+ _CUPS_WITH_REGEX = 2, /* Match string is a regular expression */
+ _CUPS_WITH_HOSTNAME = 4, /* Match string is a URI hostname */
+ _CUPS_WITH_RESOURCE = 8, /* Match string is a URI resource */
+ _CUPS_WITH_SCHEME = 16 /* Match string is a URI scheme */
+} _cups_with_t;
+
typedef struct _cups_expect_s /**** Expected attribute info ****/
{
int optional, /* Optional attribute? */
*define_match, /* Variable to define on match */
*define_no_match, /* Variable to define on no-match */
*define_value; /* Variable to define with value */
- int with_regex, /* WITH-VALUE is a regular expression */
+ int repeat_limit, /* Maximum number of times to repeat */
+ repeat_match, /* Repeat test on match */
+ repeat_no_match, /* Repeat test on no match */
+ with_flags, /* WITH flags */
count; /* Expected count if > 0 */
ipp_tag_t in_group; /* IN-GROUP value */
} _cups_expect_t;
{
ipp_status_t status; /* Expected status code */
char *if_defined, /* Only if variable is defined */
- *if_not_defined; /* Only if variable is not defined */
+ *if_not_defined, /* Only if variable is not defined */
+ *define_match, /* Variable to define on match */
+ *define_no_match, /* Variable to define on no-match */
+ *define_value; /* Variable to define with value */
+ int repeat_limit, /* Maximum number of times to repeat */
+ repeat_match, /* Repeat the test when it does not match */
+ repeat_no_match; /* Repeat the test when it matches */
} _cups_status_t;
typedef struct _cups_var_s /**** Variable ****/
typedef struct _cups_vars_s /**** Set of variables ****/
{
- const char *uri, /* URI for printer */
- *filename; /* Filename */
- char scheme[64], /* Scheme from URI */
+ char *uri, /* URI for printer */
+ *filename, /* Filename */
+ scheme[64], /* Scheme from URI */
userpass[256], /* Username/password from URI */
hostname[256], /* Hostname from URI */
resource[1024]; /* Resource path from URI */
* Globals...
*/
-_cups_transfer_t Transfer = _CUPS_TRANSFER_AUTO;
+static _cups_transfer_t Transfer = _CUPS_TRANSFER_AUTO;
/* How to transfer requests */
-_cups_output_t Output = _CUPS_OUTPUT_LIST;
+static _cups_output_t Output = _CUPS_OUTPUT_LIST;
/* Output mode */
-int Cancel = 0, /* Cancel test? */
+static int Cancel = 0, /* Cancel test? */
IgnoreErrors = 0, /* Ignore errors? */
+ StopAfterIncludeError = 0,
+ /* Stop after include errors? */
Verbosity = 0, /* Show all attributes? */
Version = 11, /* Default IPP version */
- XMLHeader = 0; /* 1 if header is written */
-char *Password = NULL; /* Password from URI */
-const char * const URIStatusStrings[] = /* URI status strings */
-{
- "URI too large",
- "Bad arguments to function",
- "Bad resource in URI",
- "Bad port number in URI",
- "Bad hostname/address in URI",
- "Bad username in URI",
- "Bad scheme in URI",
- "Bad/empty URI",
- "OK",
- "Missing scheme in URI",
- "Unknown scheme in URI",
- "Missing resource in URI"
-};
+ XMLHeader = 0, /* 1 if header is written */
+ TestCount = 0, /* Number of tests run */
+ PassCount = 0, /* Number of passing tests */
+ FailCount = 0, /* Number of failing tests */
+ SkipCount = 0; /* Number of skipped tests */
+static char *Username = NULL, /* Username from URI */
+ *Password = NULL; /* Password from URI */
+static int PasswordTries = 0; /* Number of tries with password */
/*
* Local functions...
*/
+static void add_stringf(cups_array_t *a, const char *s, ...)
+ __attribute__ ((__format__ (__printf__, 2, 3)));
static int compare_vars(_cups_var_t *a, _cups_var_t *b);
-static int do_tests(_cups_vars_t *vars, const char *testfile);
+static int do_tests(FILE *outfile, _cups_vars_t *vars, const char *testfile);
static void expand_variables(_cups_vars_t *vars, char *dst, const char *src,
- size_t dstsize) __attribute((nonnull(1,2,3)));
+ size_t dstsize) __attribute__((nonnull(1,2,3)));
static int expect_matches(_cups_expect_t *expect, ipp_tag_t value_tag);
-static ipp_t *get_collection(_cups_vars_t *vars, FILE *fp, int *linenum);
+static ipp_t *get_collection(FILE *outfile, _cups_vars_t *vars, FILE *fp, int *linenum);
static char *get_filename(const char *testfile, char *dst, const char *src,
size_t dstsize);
+static char *get_string(ipp_attribute_t *attr, int element, int flags,
+ char *buffer, size_t bufsize);
static char *get_token(FILE *fp, char *buf, int buflen,
int *linenum);
static char *get_variable(_cups_vars_t *vars, const char *name);
static char *iso_date(ipp_uchar_t *date);
static const char *password_cb(const char *prompt);
-static void print_attr(ipp_attribute_t *attr, ipp_tag_t *group);
-static void print_col(ipp_t *col);
-static void print_csv(ipp_attribute_t *attr, int num_displayed,
+static void pause_message(const char *message);
+static void print_attr(FILE *outfile, int format, ipp_attribute_t *attr, ipp_tag_t *group);
+static void print_csv(FILE *outfile, ipp_attribute_t *attr, int num_displayed,
char **displayed, size_t *widths);
-static void print_fatal_error(const char *s, ...)
- __attribute__ ((__format__ (__printf__, 1, 2)));
-static void print_line(ipp_attribute_t *attr, int num_displayed,
+static void print_fatal_error(FILE *outfile, const char *s, ...)
+ __attribute__ ((__format__ (__printf__, 2, 3)));
+static void print_line(FILE *outfile, ipp_attribute_t *attr, int num_displayed,
char **displayed, size_t *widths);
-static void print_test_error(const char *s, ...)
- __attribute__ ((__format__ (__printf__, 1, 2)));
-static void print_xml_header(void);
-static void print_xml_string(const char *element, const char *s);
-static void print_xml_trailer(int success, const char *message);
-static void set_variable(_cups_vars_t *vars, const char *name,
- const char *value);
+static void print_xml_header(FILE *outfile);
+static void print_xml_string(FILE *outfile, const char *element, const char *s);
+static void print_xml_trailer(FILE *outfile, int success, const char *message);
+static void set_variable(FILE *outfile, _cups_vars_t *vars, const char *name, const char *value);
+#ifndef WIN32
static void sigterm_handler(int sig);
+#endif /* WIN32 */
static int timeout_cb(http_t *http, void *user_data);
static void usage(void) __attribute__((noreturn));
-static int validate_attr(ipp_attribute_t *attr, int print);
-static int with_value(char *value, int regex, ipp_attribute_t *attr,
- int report);
+static int validate_attr(FILE *outfile, cups_array_t *errors, ipp_attribute_t *attr);
+static int with_value(FILE *outfile, cups_array_t *errors, char *value, int flags,
+ ipp_attribute_t *attr, char *matchbuf,
+ size_t matchlen);
/*
{
int i; /* Looping var */
int status; /* Status of tests... */
+ FILE *outfile = stdout;
+ /* Output file */
char *opt, /* Current option */
name[1024], /* Name/value buffer */
*value, /* Pointer to value */
filename[1024], /* Real filename */
- testname[1024]; /* Real test filename */
- const char *testfile; /* Test file to use */
+ testname[1024], /* Real test filename */
+ uri[1024]; /* Copy of printer URI */
+ const char *ext, /* Extension on filename */
+ *testfile; /* Test file to use */
int interval, /* Test interval in microseconds */
repeat; /* Repeat count */
_cups_vars_t vars; /* Variables */
/* Global data */
+#ifndef WIN32
/*
* Catch SIGINT and SIGTERM...
*/
signal(SIGINT, sigterm_handler);
signal(SIGTERM, sigterm_handler);
+#endif /* !WIN32 */
/*
* Initialize the locale and variables...
for (i = 1; i < argc; i ++)
{
- if (argv[i][0] == '-')
+ if (!strcmp(argv[i], "--help"))
+ {
+ usage();
+ }
+ else if (!strcmp(argv[i], "--stop-after-include-error"))
+ {
+ StopAfterIncludeError = 1;
+ }
+ else if (!strcmp(argv[i], "--version"))
+ {
+ puts(CUPS_SVERSION);
+ return (0);
+ }
+ else if (argv[i][0] == '-')
{
for (opt = argv[i] + 1; *opt; opt ++)
{
Transfer = _CUPS_TRANSFER_LENGTH;
break;
+ case 'P' : /* Output to plist file */
+ i ++;
+
+ if (i >= argc)
+ {
+ _cupsLangPrintf(stderr, _("%s: Missing filename for \"-P\"."), "ipptool");
+ usage();
+ }
+
+ if (outfile != stdout)
+ usage();
+
+ if ((outfile = fopen(argv[i], "w")) == NULL)
+ {
+ _cupsLangPrintf(stderr, _("%s: Unable to open \"%s\": %s"), "ipptool", argv[i], strerror(errno));
+ exit(1);
+ }
+
+ Output = _CUPS_OUTPUT_PLIST;
+
+ if (interval || repeat)
+ {
+ _cupsLangPuts(stderr, _("ipptool: \"-i\" and \"-n\" are incompatible with \"-P\" and \"-X\"."));
+ usage();
+ }
+ break;
+
case 'S' : /* Encrypt with SSL */
#ifdef HAVE_SSL
vars.encryption = HTTP_ENCRYPT_ALWAYS;
if (i >= argc)
{
- _cupsLangPuts(stderr,
- _("ipptool: Missing timeout for \"-T\"."));
+ _cupsLangPrintf(stderr,
+ _("%s: Missing timeout for \"-T\"."),
+ "ipptool");
usage();
}
if (i >= argc)
{
- _cupsLangPuts(stderr,
- _("ipptool: Missing version for \"-V\"."));
+ _cupsLangPrintf(stderr,
+ _("%s: Missing version for \"-V\"."),
+ "ipptool");
usage();
}
else
{
_cupsLangPrintf(stderr,
- _("ipptool: Bad version %s for \"-V\"."),
- argv[i]);
+ _("%s: Bad version %s for \"-V\"."),
+ "ipptool", argv[i]);
usage();
}
break;
if (interval || repeat)
{
- _cupsLangPuts(stderr, _("ipptool: \"-i\" and \"-n\" are "
- "incompatible with -X\"."));
+ _cupsLangPuts(stderr, _("ipptool: \"-i\" and \"-n\" are incompatible with \"-P\" and \"-X\"."));
usage();
}
break;
else
value = name + strlen(name);
- set_variable(&vars, name, value);
+ set_variable(outfile, &vars, name, value);
break;
case 'f' : /* Set the default test filename */
usage();
}
- if (access(argv[i], 0) && argv[i][0] != '/')
+ if (vars.filename)
+ {
+ free(vars.filename);
+ vars.filename = NULL;
+ }
+
+ if (access(argv[i], 0))
+ {
+ /*
+ * Try filename.gz...
+ */
+
+ snprintf(filename, sizeof(filename), "%s.gz", argv[i]);
+ if (access(filename, 0) && filename[0] != '/'
+#ifdef WIN32
+ && (!isalpha(filename[0] & 255) || filename[1] != ':')
+#endif /* WIN32 */
+ )
+ {
+ snprintf(filename, sizeof(filename), "%s/ipptool/%s",
+ cg->cups_datadir, argv[i]);
+ if (access(filename, 0))
+ {
+ snprintf(filename, sizeof(filename), "%s/ipptool/%s.gz",
+ cg->cups_datadir, argv[i]);
+ if (access(filename, 0))
+ vars.filename = strdup(argv[i]);
+ else
+ vars.filename = strdup(filename);
+ }
+ else
+ vars.filename = strdup(filename);
+ }
+ else
+ vars.filename = strdup(filename);
+ }
+ else
+ vars.filename = strdup(argv[i]);
+
+ if ((ext = strrchr(vars.filename, '.')) != NULL)
{
- snprintf(filename, sizeof(filename), "%s/ipptool/%s",
- cg->cups_datadir, argv[i]);
- if (access(argv[i], 0))
- vars.filename = argv[i];
+ /*
+ * Guess the MIME media type based on the extension...
+ */
+
+ if (!_cups_strcasecmp(ext, ".gif"))
+ set_variable(outfile, &vars, "filetype", "image/gif");
+ else if (!_cups_strcasecmp(ext, ".htm") ||
+ !_cups_strcasecmp(ext, ".htm.gz") ||
+ !_cups_strcasecmp(ext, ".html") ||
+ !_cups_strcasecmp(ext, ".html.gz"))
+ set_variable(outfile, &vars, "filetype", "text/html");
+ else if (!_cups_strcasecmp(ext, ".jpg") ||
+ !_cups_strcasecmp(ext, ".jpeg"))
+ set_variable(outfile, &vars, "filetype", "image/jpeg");
+ else if (!_cups_strcasecmp(ext, ".pcl") ||
+ !_cups_strcasecmp(ext, ".pcl.gz"))
+ set_variable(outfile, &vars, "filetype", "application/vnd.hp-PCL");
+ else if (!_cups_strcasecmp(ext, ".pdf"))
+ set_variable(outfile, &vars, "filetype", "application/pdf");
+ else if (!_cups_strcasecmp(ext, ".png"))
+ set_variable(outfile, &vars, "filetype", "image/png");
+ else if (!_cups_strcasecmp(ext, ".ps") ||
+ !_cups_strcasecmp(ext, ".ps.gz"))
+ set_variable(outfile, &vars, "filetype", "application/postscript");
+ else if (!_cups_strcasecmp(ext, ".pwg") ||
+ !_cups_strcasecmp(ext, ".pwg.gz") ||
+ !_cups_strcasecmp(ext, ".ras") ||
+ !_cups_strcasecmp(ext, ".ras.gz"))
+ set_variable(outfile, &vars, "filetype", "image/pwg-raster");
+ else if (!_cups_strcasecmp(ext, ".tif") ||
+ !_cups_strcasecmp(ext, ".tiff"))
+ set_variable(outfile, &vars, "filetype", "image/tiff");
+ else if (!_cups_strcasecmp(ext, ".txt") ||
+ !_cups_strcasecmp(ext, ".txt.gz"))
+ set_variable(outfile, &vars, "filetype", "text/plain");
+ else if (!_cups_strcasecmp(ext, ".urf") ||
+ !_cups_strcasecmp(ext, ".urf.gz"))
+ set_variable(outfile, &vars, "filetype", "image/urf");
+ else if (!_cups_strcasecmp(ext, ".xps"))
+ set_variable(outfile, &vars, "filetype", "application/openxps");
else
- vars.filename = filename;
+ set_variable(outfile, &vars, "filetype", "application/octet-stream");
}
else
- vars.filename = argv[i];
+ {
+ /*
+ * Use the "auto-type" MIME media type...
+ */
+
+ set_variable(outfile, &vars, "filetype", "application/octet-stream");
+ }
break;
case 'i' : /* Test every N seconds */
if (Output == _CUPS_OUTPUT_PLIST && interval)
{
- _cupsLangPuts(stderr, _("ipptool: \"-i\" is incompatible with "
- "\"-X\"."));
+ _cupsLangPuts(stderr, _("ipptool: \"-i\" and \"-n\" are incompatible with \"-P\" and \"-X\"."));
usage();
}
break;
if (Output == _CUPS_OUTPUT_PLIST && repeat)
{
- _cupsLangPuts(stderr, _("ipptool: \"-n\" is incompatible with "
- "\"-X\"."));
+ _cupsLangPuts(stderr, _("ipptool: \"-i\" and \"-n\" are incompatible with \"-P\" and \"-X\"."));
usage();
}
break;
_cupsLangPrintf(stderr, _("ipptool: Unknown option \"-%c\"."),
*opt);
usage();
- break;
}
}
}
if (uri_status != HTTP_URI_OK)
{
- _cupsLangPrintf(stderr, _("ipptool: Bad URI - %s."),
- URIStatusStrings[uri_status - HTTP_URI_OVERFLOW]);
+ _cupsLangPrintf(stderr, _("ipptool: Bad URI - %s."), httpURIStatusString(uri_status));
return (1);
}
if ((Password = strchr(vars.userpass, ':')) != NULL)
*Password++ = '\0';
- cupsSetUser(vars.userpass);
+ Username = vars.userpass;
cupsSetPasswordCB(password_cb);
- set_variable(&vars, "uriuser", vars.userpass);
+ set_variable(outfile, &vars, "uriuser", vars.userpass);
}
+
+ httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), vars.scheme, NULL,
+ vars.hostname, vars.port, vars.resource);
+ vars.uri = uri;
}
else
{
usage();
}
- if (access(argv[i], 0) && argv[i][0] != '/')
+ if (access(argv[i], 0) && argv[i][0] != '/'
+#ifdef WIN32
+ && (!isalpha(argv[i][0] & 255) || argv[i][1] != ':')
+#endif /* WIN32 */
+ )
{
snprintf(testname, sizeof(testname), "%s/ipptool/%s", cg->cups_datadir,
argv[i]);
else
testfile = argv[i];
- if (!do_tests(&vars, testfile))
+ if (!do_tests(outfile, &vars, testfile))
status = 1;
}
}
*/
if (Output == _CUPS_OUTPUT_PLIST)
- print_xml_trailer(!status, NULL);
+ print_xml_trailer(outfile, !status, NULL);
else if (interval > 0 && repeat > 0)
{
while (repeat > 1)
{
- usleep(interval);
- do_tests(&vars, testfile);
+ usleep((useconds_t)interval);
+ do_tests(outfile, &vars, testfile);
repeat --;
}
}
{
for (;;)
{
- usleep(interval);
- do_tests(&vars, testfile);
+ usleep((useconds_t)interval);
+ do_tests(outfile, &vars, testfile);
}
}
+ if ((Output == _CUPS_OUTPUT_TEST || (Output == _CUPS_OUTPUT_PLIST && outfile)) && TestCount > 1)
+ {
+ /*
+ * Show a summary report if there were multiple tests...
+ */
+
+ printf("\nSummary: %d tests, %d passed, %d failed, %d skipped\n"
+ "Score: %d%%\n", TestCount, PassCount, FailCount, SkipCount,
+ 100 * (PassCount + SkipCount) / TestCount);
+ }
+
/*
* Exit...
*/
}
+/*
+ * 'add_stringf()' - Add a formatted string to an array.
+ */
+
+static void
+add_stringf(cups_array_t *a, /* I - Array */
+ const char *s, /* I - Printf-style format string */
+ ...) /* I - Additional args as needed */
+{
+ char buffer[10240]; /* Format buffer */
+ va_list ap; /* Argument pointer */
+
+
+ /*
+ * Don't bother is the array is NULL...
+ */
+
+ if (!a)
+ return;
+
+ /*
+ * Format the message...
+ */
+
+ va_start(ap, s);
+ vsnprintf(buffer, sizeof(buffer), s, ap);
+ va_end(ap);
+
+ /*
+ * Add it to the array...
+ */
+
+ cupsArrayAdd(a, buffer);
+}
+
+
/*
* 'compare_vars()' - Compare two variables.
*/
*/
static int /* 1 = success, 0 = failure */
-do_tests(_cups_vars_t *vars, /* I - Variables */
+do_tests(FILE *outfile, /* I - Output file */
+ _cups_vars_t *vars, /* I - Variables */
const char *testfile) /* I - Test file to use */
{
int i, /* Looping var */
request_id, /* Current request ID */
show_header = 1, /* Show the test header? */
ignore_errors, /* Ignore test failures? */
- skip_previous = 0; /* Skip on previous test failure? */
+ skip_previous = 0, /* Skip on previous test failure? */
+ repeat_count, /* Repeat count */
+ repeat_interval, /* Repeat interval */
+ repeat_prev, /* Previous repeat interval */
+ repeat_test; /* Repeat a test? */
http_t *http = NULL; /* HTTP connection to server */
FILE *fp = NULL; /* Test file */
char resource[512], /* Resource for request */
token[1024], /* Token from file */
*tokenptr, /* Pointer into token */
temp[1024], /* Temporary string */
- buffer[8192]; /* Copy buffer */
+ buffer[8192], /* Copy buffer */
+ compression[16]; /* COMPRESSION value */
ipp_t *request = NULL, /* IPP request */
*response = NULL; /* IPP response */
size_t length; /* Length of IPP request */
http_status_t status; /* HTTP status */
- int fd; /* File to send */
+ cups_file_t *reqfile; /* File to send */
ssize_t bytes; /* Bytes read/written */
char attr[128]; /* Attribute name */
ipp_op_t op; /* Operation */
ipp_attribute_t *attrptr, /* Attribute pointer */
*found, /* Found attribute */
*lastcol = NULL; /* Last collection attribute */
- char name[1024]; /* Name of test */
+ char name[1024], /* Name of test */
+ file_id[1024], /* File identifier */
+ test_id[1024]; /* Test identifier */
char filename[1024]; /* Filename */
_cups_transfer_t transfer; /* To chunk or not to chunk */
int version, /* IPP version number to use */
int num_displayed = 0; /* Number of displayed attributes */
char *displayed[200]; /* Displayed attributes */
size_t widths[200]; /* Width of columns */
+ cups_array_t *a, /* Duplicate attribute array */
+ *errors = NULL; /* Errors array */
+ const char *error; /* Current error */
/*
if ((fp = fopen(testfile, "r")) == NULL)
{
- print_fatal_error("Unable to open test file %s - %s", testfile,
+ print_fatal_error(outfile, "Unable to open test file %s - %s", testfile,
strerror(errno));
pass = 0;
goto test_exit;
* Connect to the server...
*/
- if ((http = _httpCreate(vars->hostname, vars->port, NULL, vars->encryption,
- vars->family)) == NULL)
+ if ((http = httpConnect2(vars->hostname, vars->port, NULL, vars->family,
+ vars->encryption, 1, 30000, NULL)) == NULL)
{
- print_fatal_error("Unable to connect to %s on port %d - %s", vars->hostname,
+ print_fatal_error(outfile, "Unable to connect to %s on port %d - %s", vars->hostname,
vars->port, cupsLastErrorString());
pass = 0;
goto test_exit;
}
- if (httpReconnect(http))
- {
- print_fatal_error("Unable to connect to %s on port %d - %s", vars->hostname,
- vars->port, cupsLastErrorString());
- pass = 0;
- goto test_exit;
- }
+#ifdef HAVE_LIBZ
+ httpSetDefaultField(http, HTTP_FIELD_ACCEPT_ENCODING,
+ "deflate, gzip, identity");
+#else
+ httpSetDefaultField(http, HTTP_FIELD_ACCEPT_ENCODING, "identity");
+#endif /* HAVE_LIBZ */
if (vars->timeout > 0.0)
httpSetTimeout(http, vars->timeout, timeout_cb, NULL);
CUPS_SRAND(time(NULL));
+ errors = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free);
+ file_id[0] = '\0';
pass = 1;
linenum = 1;
request_id = (CUPS_RAND() % 1000) * 137 + 1;
get_token(fp, temp, sizeof(temp), &linenum))
{
expand_variables(vars, token, temp, sizeof(token));
- set_variable(vars, attr, token);
+ set_variable(outfile, vars, attr, token);
}
else
{
- print_fatal_error("Missing DEFINE name and/or value on line %d.",
+ print_fatal_error(outfile, "Missing DEFINE name and/or value on line %d.",
linenum);
pass = 0;
goto test_exit;
{
expand_variables(vars, token, temp, sizeof(token));
if (!get_variable(vars, attr))
- set_variable(vars, attr, token);
+ set_variable(outfile, vars, attr, token);
}
else
{
- print_fatal_error("Missing DEFINE-DEFAULT name and/or value on line "
+ print_fatal_error(outfile, "Missing DEFINE-DEFAULT name and/or value on line "
"%d.", linenum);
pass = 0;
goto test_exit;
continue;
}
+ else if (!strcmp(token, "FILE-ID"))
+ {
+ /*
+ * FILE-ID "string"
+ */
+
+ if (get_token(fp, temp, sizeof(temp), &linenum))
+ {
+ expand_variables(vars, file_id, temp, sizeof(file_id));
+ }
+ else
+ {
+ print_fatal_error(outfile, "Missing FILE-ID value on line %d.", linenum);
+ pass = 0;
+ goto test_exit;
+ }
+
+ continue;
+ }
else if (!strcmp(token, "IGNORE-ERRORS"))
{
/*
}
else
{
- print_fatal_error("Missing IGNORE-ERRORS value on line %d.", linenum);
+ print_fatal_error(outfile, "Missing IGNORE-ERRORS value on line %d.", linenum);
pass = 0;
goto test_exit;
}
* Map the filename to and then run the tests...
*/
- if (!do_tests(vars, get_filename(testfile, filename, temp,
- sizeof(filename))))
+ if (!do_tests(outfile, vars, get_filename(testfile, filename, temp, sizeof(filename))))
{
pass = 0;
- if (!IgnoreErrors)
+ if (StopAfterIncludeError)
goto test_exit;
}
}
else
{
- print_fatal_error("Missing INCLUDE filename on line %d.", linenum);
+ print_fatal_error(outfile, "Missing INCLUDE filename on line %d.", linenum);
pass = 0;
goto test_exit;
}
*/
if (get_variable(vars, attr) &&
- !do_tests(vars, get_filename(testfile, filename, temp,
- sizeof(filename))))
+ !do_tests(outfile, vars, get_filename(testfile, filename, temp, sizeof(filename))))
{
pass = 0;
- if (!IgnoreErrors)
+ if (StopAfterIncludeError)
goto test_exit;
}
}
else
{
- print_fatal_error("Missing INCLUDE-IF-DEFINED name or filename on line "
+ print_fatal_error(outfile, "Missing INCLUDE-IF-DEFINED name or filename on line "
"%d.", linenum);
pass = 0;
goto test_exit;
*/
if (!get_variable(vars, attr) &&
- !do_tests(vars, get_filename(testfile, filename, temp,
- sizeof(filename))))
+ !do_tests(outfile, vars, get_filename(testfile, filename, temp, sizeof(filename))))
{
pass = 0;
- if (!IgnoreErrors)
+ if (StopAfterIncludeError)
goto test_exit;
}
}
else
{
- print_fatal_error("Missing INCLUDE-IF-NOT-DEFINED name or filename on "
+ print_fatal_error(outfile, "Missing INCLUDE-IF-NOT-DEFINED name or filename on "
"line %d.", linenum);
pass = 0;
goto test_exit;
}
else
{
- print_fatal_error("Missing SKIP-IF-DEFINED variable on line %d.",
+ print_fatal_error(outfile, "Missing SKIP-IF-DEFINED variable on line %d.",
linenum);
pass = 0;
goto test_exit;
}
else
{
- print_fatal_error("Missing SKIP-IF-NOT-DEFINED variable on line %d.",
+ print_fatal_error(outfile, "Missing SKIP-IF-NOT-DEFINED variable on line %d.",
linenum);
pass = 0;
goto test_exit;
}
}
+ else if (!strcmp(token, "STOP-AFTER-INCLUDE-ERROR"))
+ {
+ /*
+ * STOP-AFTER-INCLUDE-ERROR yes
+ * STOP-AFTER-INCLUDE-ERROR no
+ */
+
+ if (get_token(fp, temp, sizeof(temp), &linenum) &&
+ (!_cups_strcasecmp(temp, "yes") || !_cups_strcasecmp(temp, "no")))
+ {
+ StopAfterIncludeError = !_cups_strcasecmp(temp, "yes");
+ }
+ else
+ {
+ print_fatal_error(outfile, "Missing STOP-AFTER-INCLUDE-ERROR value on line %d.",
+ linenum);
+ pass = 0;
+ goto test_exit;
+ }
+
+ continue;
+ }
else if (!strcmp(token, "TRANSFER"))
{
/*
Transfer = _CUPS_TRANSFER_LENGTH;
else
{
- print_fatal_error("Bad TRANSFER value \"%s\" on line %d.", temp,
+ print_fatal_error(outfile, "Bad TRANSFER value \"%s\" on line %d.", temp,
linenum);
pass = 0;
goto test_exit;
}
else
{
- print_fatal_error("Missing TRANSFER value on line %d.", linenum);
+ print_fatal_error(outfile, "Missing TRANSFER value on line %d.", linenum);
pass = 0;
goto test_exit;
}
Version = 22;
else
{
- print_fatal_error("Bad VERSION \"%s\" on line %d.", temp, linenum);
+ print_fatal_error(outfile, "Bad VERSION \"%s\" on line %d.", temp, linenum);
pass = 0;
goto test_exit;
}
}
else
{
- print_fatal_error("Missing VERSION number on line %d.", linenum);
+ print_fatal_error(outfile, "Missing VERSION number on line %d.", linenum);
pass = 0;
goto test_exit;
}
}
else if (strcmp(token, "{"))
{
- print_fatal_error("Unexpected token %s seen on line %d.", token, linenum);
+ print_fatal_error(outfile, "Unexpected token %s seen on line %d.", token, linenum);
pass = 0;
goto test_exit;
}
if (show_header)
{
if (Output == _CUPS_OUTPUT_PLIST)
- print_xml_header();
- else if (Output == _CUPS_OUTPUT_TEST)
+ print_xml_header(outfile);
+ if (Output == _CUPS_OUTPUT_TEST || (Output == _CUPS_OUTPUT_PLIST && outfile != stdout))
printf("\"%s\":\n", testfile);
show_header = 0;
strlcpy(resource, vars->resource, sizeof(resource));
request_id ++;
- request = ippNew();
- op = (ipp_op_t)0;
- group = IPP_TAG_ZERO;
- ignore_errors = IgnoreErrors;
- last_expect = NULL;
- last_status = NULL;
- filename[0] = '\0';
- skip_test = 0;
- version = Version;
- transfer = Transfer;
+ request = ippNew();
+ op = (ipp_op_t)0;
+ group = IPP_TAG_ZERO;
+ ignore_errors = IgnoreErrors;
+ last_expect = NULL;
+ last_status = NULL;
+ filename[0] = '\0';
+ skip_previous = 0;
+ skip_test = 0;
+ test_id[0] = '\0';
+ version = Version;
+ transfer = Transfer;
+ compression[0] = '\0';
strlcpy(name, testfile, sizeof(name));
if (strrchr(name, '.') != NULL)
_cups_strcasecmp(token, "IF-NOT-DEFINED") &&
_cups_strcasecmp(token, "IN-GROUP") &&
_cups_strcasecmp(token, "OF-TYPE") &&
+ _cups_strcasecmp(token, "REPEAT-LIMIT") &&
+ _cups_strcasecmp(token, "REPEAT-MATCH") &&
+ _cups_strcasecmp(token, "REPEAT-NO-MATCH") &&
_cups_strcasecmp(token, "SAME-COUNT-AS") &&
+ _cups_strcasecmp(token, "WITH-ALL-VALUES") &&
+ _cups_strcasecmp(token, "WITH-ALL-HOSTNAMES") &&
+ _cups_strcasecmp(token, "WITH-ALL-RESOURCES") &&
+ _cups_strcasecmp(token, "WITH-ALL-SCHEMES") &&
+ _cups_strcasecmp(token, "WITH-HOSTNAME") &&
+ _cups_strcasecmp(token, "WITH-RESOURCE") &&
+ _cups_strcasecmp(token, "WITH-SCHEME") &&
_cups_strcasecmp(token, "WITH-VALUE"))
last_expect = NULL;
- if (_cups_strcasecmp(token, "IF-DEFINED") &&
- _cups_strcasecmp(token, "IF-NOT-DEFINED"))
+ if (_cups_strcasecmp(token, "DEFINE-MATCH") &&
+ _cups_strcasecmp(token, "DEFINE-NO-MATCH") &&
+ _cups_strcasecmp(token, "IF-DEFINED") &&
+ _cups_strcasecmp(token, "IF-NOT-DEFINED") &&
+ _cups_strcasecmp(token, "REPEAT-LIMIT") &&
+ _cups_strcasecmp(token, "REPEAT-MATCH") &&
+ _cups_strcasecmp(token, "REPEAT-NO-MATCH"))
last_status = NULL;
if (!strcmp(token, "}"))
* Another collection value
*/
- ipp_t *col = get_collection(vars, fp, &linenum);
+ ipp_t *col = get_collection(outfile, vars, fp, &linenum);
/* Collection value */
if (col)
{
- ipp_attribute_t *tempcol; /* Pointer to new buffer */
-
-
- /*
- * Reallocate memory...
- */
+ ippSetCollection(request, &lastcol, ippGetCount(lastcol), col);
+ }
+ else
+ {
+ pass = 0;
+ goto test_exit;
+ }
+ }
+ else if (!strcmp(token, "COMPRESSION"))
+ {
+ /*
+ * COMPRESSION none
+ * COMPRESSION deflate
+ * COMPRESSION gzip
+ */
- if ((tempcol = realloc(lastcol, sizeof(ipp_attribute_t) +
- (lastcol->num_values + 1) *
- sizeof(ipp_value_t))) == NULL)
- {
- print_fatal_error("Unable to allocate memory on line %d.", linenum);
+ if (get_token(fp, temp, sizeof(temp), &linenum))
+ {
+ expand_variables(vars, compression, temp, sizeof(compression));
+#ifdef HAVE_LIBZ
+ if (strcmp(compression, "none") && strcmp(compression, "deflate") &&
+ strcmp(compression, "gzip"))
+#else
+ if (strcmp(compression, "none"))
+#endif /* HAVE_LIBZ */
+ {
+ print_fatal_error(outfile, "Unsupported COMPRESSION value '%s' on line %d.",
+ compression, linenum);
pass = 0;
goto test_exit;
- }
-
- if (tempcol != lastcol)
- {
- /*
- * Reset pointers in the list...
- */
-
- if (request->prev)
- request->prev->next = tempcol;
- else
- request->attrs = tempcol;
-
- lastcol = request->current = request->last = tempcol;
- }
+ }
- lastcol->values[lastcol->num_values].collection = col;
- lastcol->num_values ++;
+ if (!strcmp(compression, "none"))
+ compression[0] = '\0';
}
else
{
+ print_fatal_error(outfile, "Missing COMPRESSION value on line %d.", linenum);
pass = 0;
goto test_exit;
}
get_token(fp, temp, sizeof(temp), &linenum))
{
expand_variables(vars, token, temp, sizeof(token));
- set_variable(vars, attr, token);
+ set_variable(outfile, vars, attr, token);
}
else
{
- print_fatal_error("Missing DEFINE name and/or value on line %d.",
+ print_fatal_error(outfile, "Missing DEFINE name and/or value on line %d.",
linenum);
pass = 0;
goto test_exit;
}
else
{
- print_fatal_error("Missing IGNORE-ERRORS value on line %d.", linenum);
+ print_fatal_error(outfile, "Missing IGNORE-ERRORS value on line %d.", linenum);
pass = 0;
goto test_exit;
}
get_token(fp, name, sizeof(name), &linenum);
}
+ else if (!_cups_strcasecmp(token, "PAUSE"))
+ {
+ /*
+ * Pause with a message...
+ */
+
+ get_token(fp, token, sizeof(token), &linenum);
+ pause_message(token);
+ }
else if (!strcmp(token, "REQUEST-ID"))
{
/*
request_id = (CUPS_RAND() % 1000) * 137 + 1;
else
{
- print_fatal_error("Bad REQUEST-ID value \"%s\" on line %d.", temp,
+ print_fatal_error(outfile, "Bad REQUEST-ID value \"%s\" on line %d.", temp,
linenum);
pass = 0;
goto test_exit;
}
else
{
- print_fatal_error("Missing REQUEST-ID value on line %d.", linenum);
+ print_fatal_error(outfile, "Missing REQUEST-ID value on line %d.", linenum);
pass = 0;
goto test_exit;
}
}
else
{
- print_fatal_error("Missing SKIP-IF-DEFINED value on line %d.",
+ print_fatal_error(outfile, "Missing SKIP-IF-DEFINED value on line %d.",
linenum);
pass = 0;
goto test_exit;
}
}
+ else if (!strcmp(token, "SKIP-IF-MISSING"))
+ {
+ /*
+ * SKIP-IF-MISSING filename
+ */
+
+ if (get_token(fp, temp, sizeof(temp), &linenum))
+ {
+ expand_variables(vars, token, temp, sizeof(token));
+ get_filename(testfile, filename, token, sizeof(filename));
+
+ if (access(filename, R_OK))
+ skip_test = 1;
+ }
+ else
+ {
+ print_fatal_error(outfile, "Missing SKIP-IF-MISSING filename on line %d.",
+ linenum);
+ pass = 0;
+ goto test_exit;
+ }
+ }
else if (!strcmp(token, "SKIP-IF-NOT-DEFINED"))
{
/*
}
else
{
- print_fatal_error("Missing SKIP-IF-NOT-DEFINED value on line %d.",
+ print_fatal_error(outfile, "Missing SKIP-IF-NOT-DEFINED value on line %d.",
linenum);
pass = 0;
goto test_exit;
}
else
{
- print_fatal_error("Missing SKIP-PREVIOUS-ERROR value on line %d.", linenum);
+ print_fatal_error(outfile, "Missing SKIP-PREVIOUS-ERROR value on line %d.", linenum);
+ pass = 0;
+ goto test_exit;
+ }
+
+ continue;
+ }
+ else if (!strcmp(token, "TEST-ID"))
+ {
+ /*
+ * TEST-ID "string"
+ */
+
+ if (get_token(fp, temp, sizeof(temp), &linenum))
+ {
+ expand_variables(vars, test_id, temp, sizeof(test_id));
+ }
+ else
+ {
+ print_fatal_error(outfile, "Missing TEST-ID value on line %d.", linenum);
pass = 0;
goto test_exit;
}
transfer = _CUPS_TRANSFER_LENGTH;
else
{
- print_fatal_error("Bad TRANSFER value \"%s\" on line %d.", temp,
+ print_fatal_error(outfile, "Bad TRANSFER value \"%s\" on line %d.", temp,
linenum);
pass = 0;
goto test_exit;
}
else
{
- print_fatal_error("Missing TRANSFER value on line %d.", linenum);
+ print_fatal_error(outfile, "Missing TRANSFER value on line %d.", linenum);
pass = 0;
goto test_exit;
}
version = 22;
else
{
- print_fatal_error("Bad VERSION \"%s\" on line %d.", temp, linenum);
+ print_fatal_error(outfile, "Bad VERSION \"%s\" on line %d.", temp, linenum);
pass = 0;
goto test_exit;
}
}
else
{
- print_fatal_error("Missing VERSION number on line %d.", linenum);
+ print_fatal_error(outfile, "Missing VERSION number on line %d.", linenum);
pass = 0;
goto test_exit;
}
if (!get_token(fp, resource, sizeof(resource), &linenum))
{
- print_fatal_error("Missing RESOURCE path on line %d.", linenum);
+ print_fatal_error(outfile, "Missing RESOURCE path on line %d.", linenum);
pass = 0;
goto test_exit;
}
* Operation...
*/
- if (!get_token(fp, token, sizeof(token), &linenum))
+ if (!get_token(fp, temp, sizeof(temp), &linenum))
{
- print_fatal_error("Missing OPERATION code on line %d.", linenum);
+ print_fatal_error(outfile, "Missing OPERATION code on line %d.", linenum);
pass = 0;
goto test_exit;
}
+ expand_variables(vars, token, temp, sizeof(token));
+
if ((op = ippOpValue(token)) == (ipp_op_t)-1 &&
- (op = strtol(token, NULL, 0)) == 0)
+ (op = (ipp_op_t)strtol(token, NULL, 0)) == 0)
{
- print_fatal_error("Bad OPERATION code \"%s\" on line %d.", token,
+ print_fatal_error(outfile, "Bad OPERATION code \"%s\" on line %d.", token,
linenum);
pass = 0;
goto test_exit;
if (!get_token(fp, token, sizeof(token), &linenum))
{
- print_fatal_error("Missing GROUP tag on line %d.", linenum);
+ print_fatal_error(outfile, "Missing GROUP tag on line %d.", linenum);
pass = 0;
goto test_exit;
}
if ((value = ippTagValue(token)) < 0)
{
- print_fatal_error("Bad GROUP tag \"%s\" on line %d.", token, linenum);
+ print_fatal_error(outfile, "Bad GROUP tag \"%s\" on line %d.", token, linenum);
pass = 0;
goto test_exit;
}
double delay;
- if (!get_token(fp, token, sizeof(token), &linenum))
+ if (!get_token(fp, temp, sizeof(temp), &linenum))
{
- print_fatal_error("Missing DELAY value on line %d.", linenum);
+ print_fatal_error(outfile, "Missing DELAY value on line %d.", linenum);
pass = 0;
goto test_exit;
}
+ expand_variables(vars, token, temp, sizeof(token));
+
if ((delay = _cupsStrScand(token, NULL, localeconv())) <= 0.0)
{
- print_fatal_error("Bad DELAY value \"%s\" on line %d.", token,
+ print_fatal_error(outfile, "Bad DELAY value \"%s\" on line %d.", token,
linenum);
pass = 0;
goto test_exit;
if (Output == _CUPS_OUTPUT_TEST)
printf(" [%g second delay]\n", delay);
- usleep((int)(1000000.0 * delay));
+ usleep((useconds_t)(1000000.0 * delay));
}
}
else if (!_cups_strcasecmp(token, "ATTR"))
if (!get_token(fp, token, sizeof(token), &linenum))
{
- print_fatal_error("Missing ATTR value tag on line %d.", linenum);
+ print_fatal_error(outfile, "Missing ATTR value tag on line %d.", linenum);
pass = 0;
goto test_exit;
}
if ((value = ippTagValue(token)) == IPP_TAG_ZERO)
{
- print_fatal_error("Bad ATTR value tag \"%s\" on line %d.", token,
+ print_fatal_error(outfile, "Bad ATTR value tag \"%s\" on line %d.", token,
linenum);
pass = 0;
goto test_exit;
if (!get_token(fp, attr, sizeof(attr), &linenum))
{
- print_fatal_error("Missing ATTR name on line %d.", linenum);
+ print_fatal_error(outfile, "Missing ATTR name on line %d.", linenum);
pass = 0;
goto test_exit;
}
if (!get_token(fp, temp, sizeof(temp), &linenum))
{
- print_fatal_error("Missing ATTR value on line %d.", linenum);
+ print_fatal_error(outfile, "Missing ATTR value on line %d.", linenum);
pass = 0;
goto test_exit;
}
expand_variables(vars, token, temp, sizeof(token));
+ attrptr = NULL;
switch (value)
{
case IPP_TAG_BOOLEAN :
if (!_cups_strcasecmp(token, "true"))
- ippAddBoolean(request, group, attr, 1);
+ attrptr = ippAddBoolean(request, group, attr, 1);
else
- ippAddBoolean(request, group, attr, atoi(token));
+ attrptr = ippAddBoolean(request, group, attr, (char)atoi(token));
break;
case IPP_TAG_INTEGER :
case IPP_TAG_ENUM :
if (!strchr(token, ','))
- ippAddInteger(request, group, value, attr,
- strtol(token, &tokenptr, 0));
+ attrptr = ippAddInteger(request, group, value, attr, (int)strtol(token, &tokenptr, 0));
else
{
int values[100], /* Values */
num_values = 1; /* Number of values */
- values[0] = strtol(token, &tokenptr, 10);
+ values[0] = (int)strtol(token, &tokenptr, 10);
while (tokenptr && *tokenptr &&
num_values < (int)(sizeof(values) / sizeof(values[0])))
{
else if (!isdigit(*tokenptr & 255) && *tokenptr != '-')
break;
- values[num_values] = strtol(tokenptr, &tokenptr, 0);
+ values[num_values] = (int)strtol(tokenptr, &tokenptr, 0);
num_values ++;
}
- ippAddIntegers(request, group, value, attr, num_values, values);
+ attrptr = ippAddIntegers(request, group, value, attr, num_values, values);
}
if (!tokenptr || *tokenptr)
{
- print_fatal_error("Bad %s value \"%s\" on line %d.",
+ print_fatal_error(outfile, "Bad %s value \"%s\" on line %d.",
ippTagString(value), token, linenum);
pass = 0;
goto test_exit;
yres; /* Y resolution */
char *ptr; /* Pointer into value */
- xres = yres = strtol(token, (char **)&ptr, 10);
+ xres = yres = (int)strtol(token, (char **)&ptr, 10);
if (ptr > token && xres > 0)
{
if (*ptr == 'x')
- yres = strtol(ptr + 1, (char **)&ptr, 10);
+ yres = (int)strtol(ptr + 1, (char **)&ptr, 10);
}
if (ptr <= token || xres <= 0 || yres <= 0 || !ptr ||
- (_cups_strcasecmp(ptr, "dpi") && _cups_strcasecmp(ptr, "dpc") &&
+ (_cups_strcasecmp(ptr, "dpi") &&
+ _cups_strcasecmp(ptr, "dpc") &&
+ _cups_strcasecmp(ptr, "dpcm") &&
_cups_strcasecmp(ptr, "other")))
{
- print_fatal_error("Bad resolution value \"%s\" on line %d.",
+ print_fatal_error(outfile, "Bad resolution value \"%s\" on line %d.",
token, linenum);
pass = 0;
goto test_exit;
}
if (!_cups_strcasecmp(ptr, "dpi"))
- ippAddResolution(request, group, attr, IPP_RES_PER_INCH,
- xres, yres);
- else if (!_cups_strcasecmp(ptr, "dpc"))
- ippAddResolution(request, group, attr, IPP_RES_PER_CM,
- xres, yres);
+ attrptr = ippAddResolution(request, group, attr, IPP_RES_PER_INCH, xres, yres);
+ else if (!_cups_strcasecmp(ptr, "dpc") ||
+ !_cups_strcasecmp(ptr, "dpcm"))
+ attrptr = ippAddResolution(request, group, attr, IPP_RES_PER_CM, xres, yres);
else
- ippAddResolution(request, group, attr, (ipp_res_t)0,
- xres, yres);
+ attrptr = ippAddResolution(request, group, attr, (ipp_res_t)0, xres, yres);
}
break;
if ((num_vals & 1) || num_vals == 0)
{
- print_fatal_error("Bad rangeOfInteger value \"%s\" on line "
+ print_fatal_error(outfile, "Bad rangeOfInteger value \"%s\" on line "
"%d.", token, linenum);
pass = 0;
goto test_exit;
}
- ippAddRanges(request, group, attr, num_vals / 2, lowers,
- uppers);
+ attrptr = ippAddRanges(request, group, attr, num_vals / 2, lowers,
+ uppers);
}
break;
case IPP_TAG_BEGIN_COLLECTION :
if (!strcmp(token, "{"))
{
- ipp_t *col = get_collection(vars, fp, &linenum);
+ ipp_t *col = get_collection(outfile, vars, fp, &linenum);
/* Collection value */
if (col)
{
- lastcol = ippAddCollection(request, group, attr, col);
+ attrptr = lastcol = ippAddCollection(request, group, attr, col);
ippDelete(col);
}
else
}
else
{
- print_fatal_error("Bad ATTR collection value on line %d.",
+ print_fatal_error(outfile, "Bad ATTR collection value on line %d.",
linenum);
pass = 0;
goto test_exit;
}
+
+ do
+ {
+ ipp_t *col; /* Collection value */
+ long pos = ftell(fp); /* Save position of file */
+
+ if (!get_token(fp, token, sizeof(token), &linenum))
+ break;
+
+ if (strcmp(token, ","))
+ {
+ fseek(fp, pos, SEEK_SET);
+ break;
+ }
+
+ if (!get_token(fp, token, sizeof(token), &linenum) || strcmp(token, "{"))
+ {
+ print_fatal_error(outfile, "Unexpected \"%s\" on line %d.", token, linenum);
+ pass = 0;
+ goto test_exit;
+ break;
+ }
+
+ if ((col = get_collection(outfile, vars, fp, &linenum)) == NULL)
+ break;
+
+ ippSetCollection(request, &attrptr, ippGetCount(attrptr), col);
+ lastcol = attrptr;
+ }
+ while (!strcmp(token, "{"));
+ break;
+
+ case IPP_TAG_STRING :
+ attrptr = ippAddOctetString(request, group, attr, token, (int)strlen(token));
break;
default :
- print_fatal_error("Unsupported ATTR value tag %s on line %d.",
+ print_fatal_error(outfile, "Unsupported ATTR value tag %s on line %d.",
ippTagString(value), linenum);
pass = 0;
goto test_exit;
case IPP_TAG_LANGUAGE :
case IPP_TAG_MIMETYPE :
if (!strchr(token, ','))
- ippAddString(request, group, value, attr, NULL, token);
+ attrptr = ippAddString(request, group, value, attr, NULL, token);
else
{
/*
for (ptr = strchr(token, ','); ptr; ptr = strchr(ptr, ','))
{
- *ptr++ = '\0';
- values[num_values] = ptr;
- num_values ++;
+ if (ptr > token && ptr[-1] == '\\')
+ _cups_strcpy(ptr - 1, ptr);
+ else
+ {
+ *ptr++ = '\0';
+ values[num_values] = ptr;
+ num_values ++;
+ }
}
- ippAddStrings(request, group, value, attr, num_values,
- NULL, (const char **)values);
+ attrptr = ippAddStrings(request, group, value, attr, num_values,
+ NULL, (const char **)values);
}
break;
}
+
+ if (!attrptr)
+ {
+ print_fatal_error(outfile, "Unable to add attribute on line %d: %s", linenum,
+ cupsLastErrorString());
+ pass = 0;
+ goto test_exit;
+ }
}
else if (!_cups_strcasecmp(token, "FILE"))
{
if (!get_token(fp, temp, sizeof(temp), &linenum))
{
- print_fatal_error("Missing FILE filename on line %d.", linenum);
+ print_fatal_error(outfile, "Missing FILE filename on line %d.", linenum);
pass = 0;
goto test_exit;
}
expand_variables(vars, token, temp, sizeof(token));
get_filename(testfile, filename, token, sizeof(filename));
+
+ if (access(filename, R_OK))
+ {
+ print_fatal_error(outfile, "Filename \"%s\" on line %d cannot be read.",
+ temp, linenum);
+ print_fatal_error(outfile, "Filename mapped to \"%s\".", filename);
+ pass = 0;
+ goto test_exit;
+ }
}
else if (!_cups_strcasecmp(token, "STATUS"))
{
if (num_statuses >= (int)(sizeof(statuses) / sizeof(statuses[0])))
{
- print_fatal_error("Too many STATUS's on line %d.", linenum);
+ print_fatal_error(outfile, "Too many STATUS's on line %d.", linenum);
pass = 0;
goto test_exit;
}
if (!get_token(fp, token, sizeof(token), &linenum))
{
- print_fatal_error("Missing STATUS code on line %d.", linenum);
+ print_fatal_error(outfile, "Missing STATUS code on line %d.", linenum);
pass = 0;
goto test_exit;
}
if ((statuses[num_statuses].status = ippErrorValue(token))
== (ipp_status_t)-1 &&
- (statuses[num_statuses].status = strtol(token, NULL, 0)) == 0)
+ (statuses[num_statuses].status = (ipp_status_t)strtol(token, NULL, 0)) == 0)
{
- print_fatal_error("Bad STATUS code \"%s\" on line %d.", token,
+ print_fatal_error(outfile, "Bad STATUS code \"%s\" on line %d.", token,
linenum);
pass = 0;
goto test_exit;
last_status = statuses + num_statuses;
num_statuses ++;
- last_status->if_defined = NULL;
- last_status->if_not_defined = NULL;
+ last_status->define_match = NULL;
+ last_status->define_no_match = NULL;
+ last_status->if_defined = NULL;
+ last_status->if_not_defined = NULL;
+ last_status->repeat_limit = 1000;
+ last_status->repeat_match = 0;
+ last_status->repeat_no_match = 0;
}
else if (!_cups_strcasecmp(token, "EXPECT"))
{
if (num_expects >= (int)(sizeof(expects) / sizeof(expects[0])))
{
- print_fatal_error("Too many EXPECT's on line %d.", linenum);
+ print_fatal_error(outfile, "Too many EXPECT's on line %d.", linenum);
pass = 0;
goto test_exit;
}
if (!get_token(fp, token, sizeof(token), &linenum))
{
- print_fatal_error("Missing EXPECT name on line %d.", linenum);
+ print_fatal_error(outfile, "Missing EXPECT name on line %d.", linenum);
pass = 0;
goto test_exit;
}
num_expects ++;
memset(last_expect, 0, sizeof(_cups_expect_t));
+ last_expect->repeat_limit = 1000;
if (token[0] == '!')
{
{
if (!get_token(fp, token, sizeof(token), &linenum))
{
- print_fatal_error("Missing COUNT number on line %d.", linenum);
+ print_fatal_error(outfile, "Missing COUNT number on line %d.", linenum);
pass = 0;
goto test_exit;
}
if ((i = atoi(token)) <= 0)
{
- print_fatal_error("Bad COUNT \"%s\" on line %d.", token, linenum);
+ print_fatal_error(outfile, "Bad COUNT \"%s\" on line %d.", token, linenum);
pass = 0;
goto test_exit;
}
last_expect->count = i;
else
{
- print_fatal_error("COUNT without a preceding EXPECT on line %d.",
+ print_fatal_error(outfile, "COUNT without a preceding EXPECT on line %d.",
linenum);
pass = 0;
goto test_exit;
{
if (!get_token(fp, token, sizeof(token), &linenum))
{
- print_fatal_error("Missing DEFINE-MATCH variable on line %d.",
+ print_fatal_error(outfile, "Missing DEFINE-MATCH variable on line %d.",
linenum);
pass = 0;
goto test_exit;
if (last_expect)
last_expect->define_match = strdup(token);
+ else if (last_status)
+ last_status->define_match = strdup(token);
else
{
- print_fatal_error("DEFINE-MATCH without a preceding EXPECT on line "
- "%d.", linenum);
+ print_fatal_error(outfile, "DEFINE-MATCH without a preceding EXPECT or STATUS "
+ "on line %d.", linenum);
pass = 0;
goto test_exit;
}
{
if (!get_token(fp, token, sizeof(token), &linenum))
{
- print_fatal_error("Missing DEFINE-NO-MATCH variable on line %d.",
+ print_fatal_error(outfile, "Missing DEFINE-NO-MATCH variable on line %d.",
linenum);
pass = 0;
goto test_exit;
if (last_expect)
last_expect->define_no_match = strdup(token);
+ else if (last_status)
+ last_status->define_no_match = strdup(token);
else
{
- print_fatal_error("DEFINE-NO-MATCH without a preceding EXPECT on "
- "line %d.", linenum);
+ print_fatal_error(outfile, "DEFINE-NO-MATCH without a preceding EXPECT or "
+ "STATUS on line %d.", linenum);
pass = 0;
goto test_exit;
}
{
if (!get_token(fp, token, sizeof(token), &linenum))
{
- print_fatal_error("Missing DEFINE-VALUE variable on line %d.",
+ print_fatal_error(outfile, "Missing DEFINE-VALUE variable on line %d.",
linenum);
pass = 0;
goto test_exit;
last_expect->define_value = strdup(token);
else
{
- print_fatal_error("DEFINE-VALUE without a preceding EXPECT on line "
- "%d.", linenum);
+ print_fatal_error(outfile, "DEFINE-VALUE without a preceding EXPECT on "
+ "line %d.", linenum);
pass = 0;
goto test_exit;
}
{
if (!get_token(fp, token, sizeof(token), &linenum))
{
- print_fatal_error("Missing OF-TYPE value tag(s) on line %d.",
+ print_fatal_error(outfile, "Missing OF-TYPE value tag(s) on line %d.",
linenum);
pass = 0;
goto test_exit;
last_expect->of_type = strdup(token);
else
{
- print_fatal_error("OF-TYPE without a preceding EXPECT on line %d.",
+ print_fatal_error(outfile, "OF-TYPE without a preceding EXPECT on line %d.",
linenum);
pass = 0;
goto test_exit;
if (!get_token(fp, token, sizeof(token), &linenum))
{
- print_fatal_error("Missing IN-GROUP group tag on line %d.", linenum);
+ print_fatal_error(outfile, "Missing IN-GROUP group tag on line %d.", linenum);
pass = 0;
goto test_exit;
}
last_expect->in_group = in_group;
else
{
- print_fatal_error("IN-GROUP without a preceding EXPECT on line %d.",
+ print_fatal_error(outfile, "IN-GROUP without a preceding EXPECT on line %d.",
linenum);
pass = 0;
goto test_exit;
}
}
- else if (!_cups_strcasecmp(token, "SAME-COUNT-AS"))
+ else if (!_cups_strcasecmp(token, "REPEAT-LIMIT"))
{
if (!get_token(fp, token, sizeof(token), &linenum))
{
- print_fatal_error("Missing SAME-COUNT-AS name on line %d.", linenum);
- pass = 0;
- goto test_exit;
- }
-
- if (last_expect)
- last_expect->same_count_as = strdup(token);
- else
- {
- print_fatal_error("SAME-COUNT-AS without a preceding EXPECT on line "
- "%d.", linenum);
+ print_fatal_error(outfile, "Missing REPEAT-LIMIT value on line %d.", linenum);
pass = 0;
goto test_exit;
}
- }
- else if (!_cups_strcasecmp(token, "IF-DEFINED"))
- {
- if (!get_token(fp, token, sizeof(token), &linenum))
+ else if (atoi(token) <= 0)
{
- print_fatal_error("Missing IF-DEFINED name on line %d.", linenum);
+ print_fatal_error(outfile, "Bad REPEAT-LIMIT value on line %d.", linenum);
pass = 0;
goto test_exit;
}
- if (last_expect)
- last_expect->if_defined = strdup(token);
- else if (last_status)
- last_status->if_defined = strdup(token);
+ if (last_status)
+ last_status->repeat_limit = atoi(token);
+ else if (last_expect)
+ last_expect->repeat_limit = atoi(token);
else
{
- print_fatal_error("IF-DEFINED without a preceding EXPECT or STATUS "
+ print_fatal_error(outfile, "REPEAT-LIMIT without a preceding EXPECT or STATUS "
"on line %d.", linenum);
pass = 0;
goto test_exit;
}
}
- else if (!_cups_strcasecmp(token, "IF-NOT-DEFINED"))
+ else if (!_cups_strcasecmp(token, "REPEAT-MATCH"))
+ {
+ if (last_status)
+ last_status->repeat_match = 1;
+ else if (last_expect)
+ last_expect->repeat_match = 1;
+ else
+ {
+ print_fatal_error(outfile, "REPEAT-MATCH without a preceding EXPECT or STATUS "
+ "on line %d.", linenum);
+ pass = 0;
+ goto test_exit;
+ }
+ }
+ else if (!_cups_strcasecmp(token, "REPEAT-NO-MATCH"))
+ {
+ if (last_status)
+ last_status->repeat_no_match = 1;
+ else if (last_expect)
+ last_expect->repeat_no_match = 1;
+ else
+ {
+ print_fatal_error(outfile, "REPEAT-NO-MATCH without a preceding EXPECT or "
+ "STATUS on ine %d.", linenum);
+ pass = 0;
+ goto test_exit;
+ }
+ }
+ else if (!_cups_strcasecmp(token, "SAME-COUNT-AS"))
+ {
+ if (!get_token(fp, token, sizeof(token), &linenum))
+ {
+ print_fatal_error(outfile, "Missing SAME-COUNT-AS name on line %d.", linenum);
+ pass = 0;
+ goto test_exit;
+ }
+
+ if (last_expect)
+ last_expect->same_count_as = strdup(token);
+ else
+ {
+ print_fatal_error(outfile, "SAME-COUNT-AS without a preceding EXPECT on line "
+ "%d.", linenum);
+ pass = 0;
+ goto test_exit;
+ }
+ }
+ else if (!_cups_strcasecmp(token, "IF-DEFINED"))
+ {
+ if (!get_token(fp, token, sizeof(token), &linenum))
+ {
+ print_fatal_error(outfile, "Missing IF-DEFINED name on line %d.", linenum);
+ pass = 0;
+ goto test_exit;
+ }
+
+ if (last_expect)
+ last_expect->if_defined = strdup(token);
+ else if (last_status)
+ last_status->if_defined = strdup(token);
+ else
+ {
+ print_fatal_error(outfile, "IF-DEFINED without a preceding EXPECT or STATUS "
+ "on line %d.", linenum);
+ pass = 0;
+ goto test_exit;
+ }
+ }
+ else if (!_cups_strcasecmp(token, "IF-NOT-DEFINED"))
{
if (!get_token(fp, token, sizeof(token), &linenum))
{
- print_fatal_error("Missing IF-NOT-DEFINED name on line %d.", linenum);
+ print_fatal_error(outfile, "Missing IF-NOT-DEFINED name on line %d.", linenum);
pass = 0;
goto test_exit;
}
last_status->if_not_defined = strdup(token);
else
{
- print_fatal_error("IF-NOT-DEFINED without a preceding EXPECT or STATUS "
+ print_fatal_error(outfile, "IF-NOT-DEFINED without a preceding EXPECT or STATUS "
"on line %d.", linenum);
pass = 0;
goto test_exit;
}
}
- else if (!_cups_strcasecmp(token, "WITH-VALUE"))
+ else if (!_cups_strcasecmp(token, "WITH-ALL-VALUES") ||
+ !_cups_strcasecmp(token, "WITH-ALL-HOSTNAMES") ||
+ !_cups_strcasecmp(token, "WITH-ALL-RESOURCES") ||
+ !_cups_strcasecmp(token, "WITH-ALL-SCHEMES") ||
+ !_cups_strcasecmp(token, "WITH-HOSTNAME") ||
+ !_cups_strcasecmp(token, "WITH-RESOURCE") ||
+ !_cups_strcasecmp(token, "WITH-SCHEME") ||
+ !_cups_strcasecmp(token, "WITH-VALUE"))
{
+ if (last_expect)
+ {
+ if (!_cups_strcasecmp(token, "WITH-ALL-HOSTNAMES") ||
+ !_cups_strcasecmp(token, "WITH-HOSTNAME"))
+ last_expect->with_flags = _CUPS_WITH_HOSTNAME;
+ else if (!_cups_strcasecmp(token, "WITH-ALL-RESOURCES") ||
+ !_cups_strcasecmp(token, "WITH-RESOURCE"))
+ last_expect->with_flags = _CUPS_WITH_RESOURCE;
+ else if (!_cups_strcasecmp(token, "WITH-ALL-SCHEMES") ||
+ !_cups_strcasecmp(token, "WITH-SCHEME"))
+ last_expect->with_flags = _CUPS_WITH_SCHEME;
+
+ if (!_cups_strncasecmp(token, "WITH-ALL-", 9))
+ last_expect->with_flags |= _CUPS_WITH_ALL;
+ }
+
if (!get_token(fp, temp, sizeof(temp), &linenum))
{
- print_fatal_error("Missing WITH-VALUE value on line %d.", linenum);
+ print_fatal_error(outfile, "Missing %s value on line %d.", token, linenum);
pass = 0;
goto test_exit;
}
* WITH-VALUE is a POSIX extended regular expression.
*/
- last_expect->with_value = calloc(1, tokenptr - token);
- last_expect->with_regex = 1;
+ last_expect->with_value = calloc(1, (size_t)(tokenptr - token));
+ last_expect->with_flags |= _CUPS_WITH_REGEX;
if (last_expect->with_value)
- memcpy(last_expect->with_value, token + 1, tokenptr - token - 1);
+ memcpy(last_expect->with_value, token + 1, (size_t)(tokenptr - token - 1));
}
else
{
* WITH-VALUE is a literal value...
*/
+ char *ptr; /* Pointer into value */
+
+ for (ptr = token; *ptr; ptr ++)
+ {
+ if (*ptr == '\\' && ptr[1])
+ {
+ /*
+ * Remove \ from \foo...
+ */
+
+ _cups_strcpy(ptr, ptr + 1);
+ }
+ }
+
last_expect->with_value = strdup(token);
+ last_expect->with_flags |= _CUPS_WITH_LITERAL;
}
}
else
{
- print_fatal_error("WITH-VALUE without a preceding EXPECT on line %d.",
+ print_fatal_error(outfile, "%s without a preceding EXPECT on line %d.", token,
linenum);
pass = 0;
goto test_exit;
if (num_displayed >= (int)(sizeof(displayed) / sizeof(displayed[0])))
{
- print_fatal_error("Too many DISPLAY's on line %d", linenum);
+ print_fatal_error(outfile, "Too many DISPLAY's on line %d", linenum);
pass = 0;
goto test_exit;
}
if (!get_token(fp, token, sizeof(token), &linenum))
{
- print_fatal_error("Missing DISPLAY name on line %d.", linenum);
+ print_fatal_error(outfile, "Missing DISPLAY name on line %d.", linenum);
pass = 0;
goto test_exit;
}
}
else
{
- print_fatal_error("Unexpected token %s seen on line %d.", token,
+ print_fatal_error(outfile, "Unexpected token %s seen on line %d.", token,
linenum);
pass = 0;
goto test_exit;
* Submit the IPP request...
*/
- request->request.op.version[0] = version / 10;
- request->request.op.version[1] = version % 10;
- request->request.op.operation_id = op;
- request->request.op.request_id = request_id;
+ TestCount ++;
+
+ ippSetVersion(request, version / 10, version % 10);
+ ippSetOperation(request, op);
+ ippSetRequestId(request, request_id);
if (Output == _CUPS_OUTPUT_PLIST)
{
- puts("<dict>");
- puts("<key>Name</key>");
- print_xml_string("string", name);
- puts("<key>Operation</key>");
- print_xml_string("string", ippOpString(op));
- puts("<key>RequestAttributes</key>");
- puts("<array>");
+ fputs("<dict>\n", outfile);
+ fputs("<key>Name</key>\n", outfile);
+ print_xml_string(outfile, "string", name);
+ if (file_id[0])
+ {
+ fputs("<key>FileId</key>\n", outfile);
+ print_xml_string(outfile, "string", file_id);
+ }
+ if (test_id[0])
+ {
+ fputs("<key>TestId</key>\n", outfile);
+ print_xml_string(outfile, "string", test_id);
+ }
+ fputs("<key>Version</key>\n", outfile);
+ fprintf(outfile, "<string>%d.%d</string>\n", version / 10, version % 10);
+ fputs("<key>Operation</key>\n", outfile);
+ print_xml_string(outfile, "string", ippOpString(op));
+ fputs("<key>RequestId</key>\n", outfile);
+ fprintf(outfile, "<integer>%d</integer>\n", request_id);
+ fputs("<key>RequestAttributes</key>\n", outfile);
+ fputs("<array>\n", outfile);
if (request->attrs)
{
- puts("<dict>");
- for (attrptr = request->attrs, group = attrptr->group_tag;
+ fputs("<dict>\n", outfile);
+ for (attrptr = request->attrs,
+ group = attrptr ? attrptr->group_tag : IPP_TAG_ZERO;
attrptr;
attrptr = attrptr->next)
- print_attr(attrptr, &group);
- puts("</dict>");
+ print_attr(outfile, Output, attrptr, &group);
+ fputs("</dict>\n", outfile);
}
- puts("</array>");
+ fputs("</array>\n", outfile);
}
- else if (Output == _CUPS_OUTPUT_TEST)
+
+ if (Output == _CUPS_OUTPUT_TEST || (Output == _CUPS_OUTPUT_PLIST && outfile != stdout))
{
if (Verbosity)
{
- printf(" %s:\n", ippOpString(op));
+ printf(" %s:\n", ippOpString(op));
- for (attrptr = request->attrs; attrptr; attrptr = attrptr->next)
- print_attr(attrptr, NULL);
+ for (attrptr = request->attrs; attrptr; attrptr = attrptr->next)
+ print_attr(stdout, _CUPS_OUTPUT_TEST, attrptr, NULL);
}
- printf(" %-69.69s [", name);
+ printf(" %-68.68s [", name);
fflush(stdout);
}
if ((skip_previous && !prev_pass) || skip_test)
{
+ SkipCount ++;
+
ippDelete(request);
request = NULL;
if (Output == _CUPS_OUTPUT_PLIST)
{
- puts("<key>Successful</key>");
- puts("<true />");
- puts("<key>StatusCode</key>");
- print_xml_string("string", "skip");
- puts("<key>ResponseAttributes</key>");
- puts("<dict>");
- puts("</dict>");
+ fputs("<key>Successful</key>\n", outfile);
+ fputs("<true />\n", outfile);
+ fputs("<key>StatusCode</key>\n", outfile);
+ print_xml_string(outfile, "string", "skip");
+ fputs("<key>ResponseAttributes</key>\n", outfile);
+ fputs("<dict />\n", outfile);
}
- else if (Output == _CUPS_OUTPUT_TEST)
+
+ if (Output == _CUPS_OUTPUT_TEST || (Output == _CUPS_OUTPUT_PLIST && outfile != stdout))
puts("SKIP]");
goto skip_error;
}
- status = HTTP_OK;
+ PasswordTries = 0;
+ repeat_count = 0;
+ repeat_interval = 1;
+ repeat_prev = 1;
- if (transfer == _CUPS_TRANSFER_CHUNKED ||
- (transfer == _CUPS_TRANSFER_AUTO && filename[0]))
+ do
{
- /*
- * Send request using chunking - a 0 length means "chunk".
- */
+ repeat_count ++;
- length = 0;
- }
- else
- {
- /*
- * Send request using content length...
- */
+ status = HTTP_STATUS_OK;
- length = ippLength(request);
-
- if (filename[0])
+ if (transfer == _CUPS_TRANSFER_CHUNKED ||
+ (transfer == _CUPS_TRANSFER_AUTO && filename[0]))
{
- struct stat fileinfo; /* File information */
-
- if (stat(filename, &fileinfo))
- {
- snprintf(buffer, sizeof(buffer), "%s: %s", filename, strerror(errno));
- _cupsSetError(IPP_INTERNAL_ERROR, buffer, 0);
+ /*
+ * Send request using chunking - a 0 length means "chunk".
+ */
- status = HTTP_ERROR;
- }
- else
- length += fileinfo.st_size;
+ length = 0;
}
- }
-
- /*
- * Send the request...
- */
-
- response = NULL;
-
- if (status != HTTP_ERROR)
- {
- while (!response && !Cancel)
+ else
{
- status = cupsSendRequest(http, request, resource, length);
-
- if (!Cancel && status == HTTP_CONTINUE && request->state == IPP_DATA &&
- filename[0])
- {
- if ((fd = open(filename, O_RDONLY | O_BINARY)) >= 0)
- {
- while (!Cancel && (bytes = read(fd, buffer, sizeof(buffer))) > 0)
- if ((status = cupsWriteRequestData(http, buffer,
- bytes)) != HTTP_CONTINUE)
- break;
- }
- else
- {
- snprintf(buffer, sizeof(buffer), "%s: %s", filename,
- strerror(errno));
- _cupsSetError(IPP_INTERNAL_ERROR, buffer, 0);
-
- status = HTTP_ERROR;
- }
- }
-
/*
- * Get the server's response...
+ * Send request using content length...
*/
- if (!Cancel && (status == HTTP_CONTINUE || status == HTTP_OK))
- {
- response = cupsGetResponse(http, resource);
- status = http->status;
- }
- else
- httpFlush(http);
-
- if ((status == HTTP_ERROR && cupsLastError() != IPP_INTERNAL_ERROR) ||
- (status >= HTTP_BAD_REQUEST && status != HTTP_UNAUTHORIZED &&
- status != HTTP_UPGRADE_REQUIRED))
- {
- _cupsSetHTTPError(status);
- break;
- }
+ length = ippLength(request);
- if (http->state != HTTP_WAITING)
+ if (filename[0] && (reqfile = cupsFileOpen(filename, "r")) != NULL)
{
/*
- * Flush any remaining data...
+ * Read the file to get the uncompressed file size...
*/
- httpFlush(http);
- }
- }
- }
-
- ippDelete(request);
+ while ((bytes = cupsFileRead(reqfile, buffer, sizeof(buffer))) > 0)
+ length += (size_t)bytes;
- request = NULL;
- prev_pass = 1;
-
- if (!response)
- prev_pass = pass = 0;
- else
- {
- if (http->version != HTTP_1_1)
- prev_pass = pass = 0;
-
- if (response->request.status.request_id != request_id)
- prev_pass = pass = 0;
-
- if (version &&
- (response->request.status.version[0] != (version / 10) ||
- response->request.status.version[1] != (version % 10)))
- prev_pass = pass = 0;
-
- if ((attrptr = ippFindAttribute(response, "job-id",
- IPP_TAG_INTEGER)) != NULL)
- {
- snprintf(temp, sizeof(temp), "%d", attrptr->values[0].integer);
- set_variable(vars, "job-id", temp);
- }
-
- if ((attrptr = ippFindAttribute(response, "job-uri",
- IPP_TAG_URI)) != NULL)
- set_variable(vars, "job-uri", attrptr->values[0].string.text);
-
- if ((attrptr = ippFindAttribute(response, "notify-subscription-id",
- IPP_TAG_INTEGER)) != NULL)
- {
- snprintf(temp, sizeof(temp), "%d", attrptr->values[0].integer);
- set_variable(vars, "notify-subscription-id", temp);
- }
-
- attrptr = response->attrs;
- if (!attrptr || !attrptr->name ||
- attrptr->value_tag != IPP_TAG_CHARSET ||
- attrptr->group_tag != IPP_TAG_OPERATION ||
- attrptr->num_values != 1 ||
- strcmp(attrptr->name, "attributes-charset"))
- prev_pass = pass = 0;
-
- if (attrptr)
- {
- attrptr = attrptr->next;
- if (!attrptr || !attrptr->name ||
- attrptr->value_tag != IPP_TAG_LANGUAGE ||
- attrptr->group_tag != IPP_TAG_OPERATION ||
- attrptr->num_values != 1 ||
- strcmp(attrptr->name, "attributes-natural-language"))
- prev_pass = pass = 0;
- }
-
- if ((attrptr = ippFindAttribute(response, "status-message",
- IPP_TAG_ZERO)) != NULL &&
- (attrptr->value_tag != IPP_TAG_TEXT ||
- attrptr->group_tag != IPP_TAG_OPERATION ||
- attrptr->num_values != 1 ||
- (attrptr->value_tag == IPP_TAG_TEXT &&
- strlen(attrptr->values[0].string.text) > 255)))
- prev_pass = pass = 0;
-
- if ((attrptr = ippFindAttribute(response, "detailed-status-message",
- IPP_TAG_ZERO)) != NULL &&
- (attrptr->value_tag != IPP_TAG_TEXT ||
- attrptr->group_tag != IPP_TAG_OPERATION ||
- attrptr->num_values != 1 ||
- (attrptr->value_tag == IPP_TAG_TEXT &&
- strlen(attrptr->values[0].string.text) > 1023)))
- prev_pass = pass = 0;
-
- for (attrptr = response->attrs, group = attrptr->group_tag;
- attrptr;
- attrptr = attrptr->next)
- {
- if (attrptr->group_tag < group && attrptr->group_tag != IPP_TAG_ZERO)
- {
- prev_pass = pass = 0;
- break;
- }
-
- if (!validate_attr(attrptr, 0))
- {
- prev_pass = pass = 0;
- break;
+ cupsFileClose(reqfile);
}
}
- for (i = 0; i < num_statuses; i ++)
- {
- if (statuses[i].if_defined &&
- !get_variable(vars, statuses[i].if_defined))
- continue;
-
- if (statuses[i].if_not_defined &&
- get_variable(vars, statuses[i].if_not_defined))
- continue;
+ /*
+ * Send the request...
+ */
- if (response->request.status.status_code == statuses[i].status)
- break;
- }
+ response = NULL;
+ repeat_test = 0;
+ prev_pass = 1;
- if (i == num_statuses && num_statuses > 0)
- prev_pass = pass = 0;
- else
+ if (status != HTTP_STATUS_ERROR)
{
- for (i = num_expects, expect = expects; i > 0; i --, expect ++)
- {
- if (expect->if_defined && !get_variable(vars, expect->if_defined))
- continue;
-
- if (expect->if_not_defined &&
- get_variable(vars, expect->if_not_defined))
- continue;
+ while (!response && !Cancel && prev_pass)
+ {
+ status = cupsSendRequest(http, request, resource, length);
- found = ippFindAttribute(response, expect->name, IPP_TAG_ZERO);
+#ifdef HAVE_LIBZ
+ if (compression[0])
+ httpSetField(http, HTTP_FIELD_CONTENT_ENCODING, compression);
+#endif /* HAVE_LIBZ */
- if ((found && expect->not_expect) ||
- (!found && !(expect->not_expect || expect->optional)) ||
- (found && !expect_matches(expect, found->value_tag)) ||
- (found && expect->in_group &&
- found->group_tag != expect->in_group))
- {
- if (expect->define_no_match)
- set_variable(vars, expect->define_no_match, "1");
- else if (!expect->define_match)
- prev_pass = pass = 0;
+ if (!Cancel && status == HTTP_STATUS_CONTINUE &&
+ request->state == IPP_DATA && filename[0])
+ {
+ if ((reqfile = cupsFileOpen(filename, "r")) != NULL)
+ {
+ while (!Cancel &&
+ (bytes = cupsFileRead(reqfile, buffer, sizeof(buffer))) > 0)
+ if ((status = cupsWriteRequestData(http, buffer, (size_t)bytes)) != HTTP_STATUS_CONTINUE)
+ break;
- continue;
- }
+ cupsFileClose(reqfile);
+ }
+ else
+ {
+ snprintf(buffer, sizeof(buffer), "%s: %s", filename,
+ strerror(errno));
+ _cupsSetError(IPP_INTERNAL_ERROR, buffer, 0);
- if (found &&
- !with_value(expect->with_value, expect->with_regex, found, 0))
- {
- if (expect->define_no_match)
- set_variable(vars, expect->define_no_match, "1");
- else if (!expect->define_match)
- prev_pass = pass = 0;
+ status = HTTP_STATUS_ERROR;
+ }
+ }
- continue;
- }
+ /*
+ * Get the server's response...
+ */
- if (found && expect->count > 0 && found->num_values != expect->count)
+ if (!Cancel && status != HTTP_STATUS_ERROR)
{
- if (expect->define_no_match)
- set_variable(vars, expect->define_no_match, "1");
- else if (!expect->define_match)
- prev_pass = pass = 0;
-
- continue;
+ response = cupsGetResponse(http, resource);
+ status = httpGetStatus(http);
}
- if (found && expect->same_count_as)
- {
- attrptr = ippFindAttribute(response, expect->same_count_as,
- IPP_TAG_ZERO);
-
- if (!attrptr || attrptr->num_values != found->num_values)
- {
- if (expect->define_no_match)
- set_variable(vars, expect->define_no_match, "1");
- else if (!expect->define_match)
- prev_pass = pass = 0;
-
- continue;
- }
- }
-
- if (found && expect->define_match)
- set_variable(vars, expect->define_match, "1");
-
- if (found && expect->define_value)
+ if (!Cancel && status == HTTP_STATUS_ERROR && http->error != EINVAL &&
+#ifdef WIN32
+ http->error != WSAETIMEDOUT)
+#else
+ http->error != ETIMEDOUT)
+#endif /* WIN32 */
{
- _ippAttrString(found, token, sizeof(token));
- set_variable(vars, expect->define_value, token);
+ if (httpReconnect(http))
+ prev_pass = 0;
}
- }
- }
- }
-
- if (Output == _CUPS_OUTPUT_PLIST)
- {
- puts("<key>Successful</key>");
- puts(prev_pass ? "<true />" : "<false />");
- puts("<key>StatusCode</key>");
- print_xml_string("string", ippErrorString(cupsLastError()));
- puts("<key>ResponseAttributes</key>");
- puts("<array>");
- puts("<dict>");
- for (attrptr = response ? response->attrs : NULL,
- group = attrptr ? attrptr->group_tag : IPP_TAG_ZERO;
- attrptr;
- attrptr = attrptr->next)
- print_attr(attrptr, &group);
- puts("</dict>");
- puts("</array>");
- }
- else if (Output == _CUPS_OUTPUT_TEST)
- {
- puts(prev_pass ? "PASS]" : "FAIL]");
+ else if (status == HTTP_STATUS_ERROR || status == HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED)
+ {
+ prev_pass = 0;
+ break;
+ }
+ else if (status != HTTP_STATUS_OK)
+ {
+ httpFlush(http);
- if (Verbosity && response)
- {
- printf(" RECEIVED: %lu bytes in response\n",
- (unsigned long)ippLength(response));
- printf(" status-code = %x (%s)\n", cupsLastError(),
- ippErrorString(cupsLastError()));
+ if (status == HTTP_STATUS_UNAUTHORIZED)
+ continue;
- for (attrptr = response->attrs;
- attrptr != NULL;
- attrptr = attrptr->next)
- {
- print_attr(attrptr, NULL);
+ break;
+ }
}
}
- }
- else if (!prev_pass)
- fprintf(stderr, "%s\n", cupsLastErrorString());
- if (prev_pass && Output != _CUPS_OUTPUT_PLIST &&
- Output != _CUPS_OUTPUT_QUIET && !Verbosity && num_displayed > 0)
- {
- if (Output >= _CUPS_OUTPUT_LIST)
+ if (!Cancel && status == HTTP_STATUS_ERROR && http->error != EINVAL &&
+#ifdef WIN32
+ http->error != WSAETIMEDOUT)
+#else
+ http->error != ETIMEDOUT)
+#endif /* WIN32 */
{
- size_t width; /* Length of value */
-
-
- for (i = 0; i < num_displayed; i ++)
- {
- widths[i] = strlen(displayed[i]);
+ if (httpReconnect(http))
+ prev_pass = 0;
+ }
+ else if (status == HTTP_STATUS_ERROR)
+ {
+ if (!Cancel)
+ httpReconnect(http);
- for (attrptr = ippFindAttribute(response, displayed[i], IPP_TAG_ZERO);
- attrptr;
- attrptr = ippFindNextAttribute(response, displayed[i],
- IPP_TAG_ZERO))
- {
- width = _ippAttrString(attrptr, NULL, 0);
- if (width > widths[i])
- widths[i] = width;
- }
- }
+ prev_pass = 0;
+ }
+ else if (status != HTTP_STATUS_OK)
+ {
+ httpFlush(http);
+ prev_pass = 0;
+ }
- if (Output == _CUPS_OUTPUT_CSV)
- print_csv(NULL, num_displayed, displayed, widths);
- else
- print_line(NULL, num_displayed, displayed, widths);
+ /*
+ * Check results of request...
+ */
- attrptr = response->attrs;
+ cupsArrayClear(errors);
- while (attrptr)
- {
- while (attrptr && attrptr->group_tag <= IPP_TAG_OPERATION)
- attrptr = attrptr->next;
+ if (http->version != HTTP_1_1)
+ add_stringf(errors, "Bad HTTP version (%d.%d)", http->version / 100,
+ http->version % 100);
- if (attrptr)
- {
- if (Output == _CUPS_OUTPUT_CSV)
- print_csv(attrptr, num_displayed, displayed, widths);
- else
- print_line(attrptr, num_displayed, displayed, widths);
+ if (!response)
+ {
+ /*
+ * No response, log error...
+ */
- while (attrptr && attrptr->group_tag > IPP_TAG_OPERATION)
- attrptr = attrptr->next;
- }
- }
+ add_stringf(errors, "IPP request failed with status %s (%s)",
+ ippErrorString(cupsLastError()),
+ cupsLastErrorString());
}
else
{
- for (attrptr = response->attrs;
- attrptr != NULL;
- attrptr = attrptr->next)
+ /*
+ * Collect common attribute values...
+ */
+
+ if ((attrptr = ippFindAttribute(response, "job-id",
+ IPP_TAG_INTEGER)) != NULL)
{
- if (attrptr->name)
- {
- for (i = 0; i < num_displayed; i ++)
- {
- if (!strcmp(displayed[i], attrptr->name))
- {
- print_attr(attrptr, NULL);
- break;
- }
- }
- }
+ snprintf(temp, sizeof(temp), "%d", attrptr->values[0].integer);
+ set_variable(outfile, vars, "job-id", temp);
}
- }
- }
- else if (!prev_pass)
- {
- if (Output == _CUPS_OUTPUT_PLIST)
- {
- puts("<key>Errors</key>");
- puts("<array>");
- }
- if (http->version != HTTP_1_1)
- print_test_error("Bad HTTP version (%d.%d)", http->version / 100,
- http->version % 100);
+ if ((attrptr = ippFindAttribute(response, "job-uri",
+ IPP_TAG_URI)) != NULL)
+ set_variable(outfile, vars, "job-uri", attrptr->values[0].string.text);
+
+ if ((attrptr = ippFindAttribute(response, "notify-subscription-id",
+ IPP_TAG_INTEGER)) != NULL)
+ {
+ snprintf(temp, sizeof(temp), "%d", attrptr->values[0].integer);
+ set_variable(outfile, vars, "notify-subscription-id", temp);
+ }
+
+ /*
+ * Check response, validating groups and attributes and logging errors
+ * as needed...
+ */
+
+ if (response->state != IPP_DATA)
+ add_stringf(errors,
+ "Missing end-of-attributes-tag in response "
+ "(RFC 2910 section 3.5.1)");
- if (!response)
- print_test_error("IPP request failed with status %s (%s)",
- ippErrorString(cupsLastError()),
- cupsLastErrorString());
- else
- {
if (version &&
(response->request.status.version[0] != (version / 10) ||
response->request.status.version[1] != (version % 10)))
- print_test_error("Bad version %d.%d in response - expected %d.%d "
- "(RFC 2911 section 3.1.8).",
- response->request.status.version[0],
- response->request.status.version[1],
- version / 10, version % 10);
+ add_stringf(errors,
+ "Bad version %d.%d in response - expected %d.%d "
+ "(RFC 2911 section 3.1.8).",
+ response->request.status.version[0],
+ response->request.status.version[1],
+ version / 10, version % 10);
if (response->request.status.request_id != request_id)
- print_test_error("Bad request ID %d in response - expected %d "
- "(RFC 2911 section 3.1.1)",
- response->request.status.request_id, request_id);
+ add_stringf(errors,
+ "Bad request ID %d in response - expected %d "
+ "(RFC 2911 section 3.1.1)",
+ response->request.status.request_id, request_id);
attrptr = response->attrs;
if (!attrptr)
- print_test_error("Missing first attribute \"attributes-charset "
- "(charset)\" in group operation-attributes-tag "
- "(RFC 2911 section 3.1.4).");
+ add_stringf(errors,
+ "Missing first attribute \"attributes-charset "
+ "(charset)\" in group operation-attributes-tag "
+ "(RFC 2911 section 3.1.4).");
else
{
if (!attrptr->name ||
attrptr->group_tag != IPP_TAG_OPERATION ||
attrptr->num_values != 1 ||
strcmp(attrptr->name, "attributes-charset"))
- print_test_error("Bad first attribute \"%s (%s%s)\" in group %s, "
- "expected \"attributes-charset (charset)\" in "
- "group operation-attributes-tag (RFC 2911 section "
- "3.1.4).",
- attrptr->name ? attrptr->name : "(null)",
- attrptr->num_values > 1 ? "1setOf " : "",
- ippTagString(attrptr->value_tag),
- ippTagString(attrptr->group_tag));
+ add_stringf(errors,
+ "Bad first attribute \"%s (%s%s)\" in group %s, "
+ "expected \"attributes-charset (charset)\" in "
+ "group operation-attributes-tag (RFC 2911 section "
+ "3.1.4).",
+ attrptr->name ? attrptr->name : "(null)",
+ attrptr->num_values > 1 ? "1setOf " : "",
+ ippTagString(attrptr->value_tag),
+ ippTagString(attrptr->group_tag));
attrptr = attrptr->next;
if (!attrptr)
- print_test_error("Missing second attribute \"attributes-natural-"
- "language (naturalLanguage)\" in group "
- "operation-attributes-tag (RFC 2911 section "
- "3.1.4).");
+ add_stringf(errors,
+ "Missing second attribute \"attributes-natural-"
+ "language (naturalLanguage)\" in group "
+ "operation-attributes-tag (RFC 2911 section "
+ "3.1.4).");
else if (!attrptr->name ||
attrptr->value_tag != IPP_TAG_LANGUAGE ||
attrptr->group_tag != IPP_TAG_OPERATION ||
attrptr->num_values != 1 ||
strcmp(attrptr->name, "attributes-natural-language"))
- print_test_error("Bad first attribute \"%s (%s%s)\" in group %s, "
- "expected \"attributes-natural-language "
- "(naturalLanguage)\" in group "
- "operation-attributes-tag (RFC 2911 section "
- "3.1.4).",
- attrptr->name ? attrptr->name : "(null)",
- attrptr->num_values > 1 ? "1setOf " : "",
- ippTagString(attrptr->value_tag),
- ippTagString(attrptr->group_tag));
+ add_stringf(errors,
+ "Bad first attribute \"%s (%s%s)\" in group %s, "
+ "expected \"attributes-natural-language "
+ "(naturalLanguage)\" in group "
+ "operation-attributes-tag (RFC 2911 section "
+ "3.1.4).",
+ attrptr->name ? attrptr->name : "(null)",
+ attrptr->num_values > 1 ? "1setOf " : "",
+ ippTagString(attrptr->value_tag),
+ ippTagString(attrptr->group_tag));
}
if ((attrptr = ippFindAttribute(response, "status-message",
IPP_TAG_ZERO)) != NULL)
{
if (attrptr->value_tag != IPP_TAG_TEXT)
- print_test_error("status-message (text(255)) has wrong value tag "
- "%s (RFC 2911 section 3.1.6.2).",
- ippTagString(attrptr->value_tag));
+ add_stringf(errors,
+ "status-message (text(255)) has wrong value tag "
+ "%s (RFC 2911 section 3.1.6.2).",
+ ippTagString(attrptr->value_tag));
if (attrptr->group_tag != IPP_TAG_OPERATION)
- print_test_error("status-message (text(255)) has wrong group tag "
- "%s (RFC 2911 section 3.1.6.2).",
- ippTagString(attrptr->group_tag));
+ add_stringf(errors,
+ "status-message (text(255)) has wrong group tag "
+ "%s (RFC 2911 section 3.1.6.2).",
+ ippTagString(attrptr->group_tag));
if (attrptr->num_values != 1)
- print_test_error("status-message (text(255)) has %d values "
- "(RFC 2911 section 3.1.6.2).",
- attrptr->num_values);
+ add_stringf(errors,
+ "status-message (text(255)) has %d values "
+ "(RFC 2911 section 3.1.6.2).",
+ attrptr->num_values);
if (attrptr->value_tag == IPP_TAG_TEXT &&
strlen(attrptr->values[0].string.text) > 255)
- print_test_error("status-message (text(255)) has bad length %d"
- " (RFC 2911 section 3.1.6.2).",
- (int)strlen(attrptr->values[0].string.text));
+ add_stringf(errors,
+ "status-message (text(255)) has bad length %d"
+ " (RFC 2911 section 3.1.6.2).",
+ (int)strlen(attrptr->values[0].string.text));
+ }
+
+ if ((attrptr = ippFindAttribute(response, "detailed-status-message",
+ IPP_TAG_ZERO)) != NULL)
+ {
+ if (attrptr->value_tag != IPP_TAG_TEXT)
+ add_stringf(errors,
+ "detailed-status-message (text(MAX)) has wrong "
+ "value tag %s (RFC 2911 section 3.1.6.3).",
+ ippTagString(attrptr->value_tag));
+ if (attrptr->group_tag != IPP_TAG_OPERATION)
+ add_stringf(errors,
+ "detailed-status-message (text(MAX)) has wrong "
+ "group tag %s (RFC 2911 section 3.1.6.3).",
+ ippTagString(attrptr->group_tag));
+ if (attrptr->num_values != 1)
+ add_stringf(errors,
+ "detailed-status-message (text(MAX)) has %d values"
+ " (RFC 2911 section 3.1.6.3).",
+ attrptr->num_values);
+ if (attrptr->value_tag == IPP_TAG_TEXT &&
+ strlen(attrptr->values[0].string.text) > 1023)
+ add_stringf(errors,
+ "detailed-status-message (text(MAX)) has bad "
+ "length %d (RFC 2911 section 3.1.6.3).",
+ (int)strlen(attrptr->values[0].string.text));
}
- if ((attrptr = ippFindAttribute(response, "detailed-status-message",
- IPP_TAG_ZERO)) != NULL)
- {
- if (attrptr->value_tag != IPP_TAG_TEXT)
- print_test_error("detailed-status-message (text(MAX)) has wrong "
- "value tag %s (RFC 2911 section 3.1.6.3).",
- ippTagString(attrptr->value_tag));
- if (attrptr->group_tag != IPP_TAG_OPERATION)
- print_test_error("detailed-status-message (text(MAX)) has wrong "
- "group tag %s (RFC 2911 section 3.1.6.3).",
- ippTagString(attrptr->group_tag));
- if (attrptr->num_values != 1)
- print_test_error("detailed-status-message (text(MAX)) has %d values"
- " (RFC 2911 section 3.1.6.3).",
- attrptr->num_values);
- if (attrptr->value_tag == IPP_TAG_TEXT &&
- strlen(attrptr->values[0].string.text) > 1023)
- print_test_error("detailed-status-message (text(MAX)) has bad "
- "length %d (RFC 2911 section 3.1.6.3).",
- (int)strlen(attrptr->values[0].string.text));
+ a = cupsArrayNew((cups_array_func_t)strcmp, NULL);
+
+ for (attrptr = response->attrs,
+ group = attrptr ? attrptr->group_tag : IPP_TAG_ZERO;
+ attrptr;
+ attrptr = attrptr->next)
+ {
+ if (attrptr->group_tag != group)
+ {
+ int out_of_order = 0; /* Are attribute groups out-of-order? */
+ cupsArrayClear(a);
+
+ switch (attrptr->group_tag)
+ {
+ case IPP_TAG_ZERO :
+ break;
+
+ case IPP_TAG_OPERATION :
+ out_of_order = 1;
+ break;
+
+ case IPP_TAG_UNSUPPORTED_GROUP :
+ if (group != IPP_TAG_OPERATION)
+ out_of_order = 1;
+ break;
+
+ case IPP_TAG_JOB :
+ case IPP_TAG_PRINTER :
+ if (group != IPP_TAG_OPERATION &&
+ group != IPP_TAG_UNSUPPORTED_GROUP)
+ out_of_order = 1;
+ break;
+
+ case IPP_TAG_SUBSCRIPTION :
+ if (group > attrptr->group_tag &&
+ group != IPP_TAG_DOCUMENT)
+ out_of_order = 1;
+ break;
+
+ default :
+ if (group > attrptr->group_tag)
+ out_of_order = 1;
+ break;
+ }
+
+ if (out_of_order)
+ add_stringf(errors, "Attribute groups out of order (%s < %s)",
+ ippTagString(attrptr->group_tag),
+ ippTagString(group));
+
+ if (attrptr->group_tag != IPP_TAG_ZERO)
+ group = attrptr->group_tag;
+ }
+
+ validate_attr(outfile, errors, attrptr);
+
+ if (attrptr->name)
+ {
+ if (cupsArrayFind(a, attrptr->name))
+ add_stringf(errors, "Duplicate \"%s\" attribute in %s group",
+ attrptr->name, ippTagString(group));
+
+ cupsArrayAdd(a, attrptr->name);
+ }
+ }
+
+ cupsArrayDelete(a);
+
+ /*
+ * Now check the test-defined expected status-code and attribute
+ * values...
+ */
+
+ for (i = 0; i < num_statuses; i ++)
+ {
+ if (statuses[i].if_defined &&
+ !get_variable(vars, statuses[i].if_defined))
+ continue;
+
+ if (statuses[i].if_not_defined &&
+ get_variable(vars, statuses[i].if_not_defined))
+ continue;
+
+ if (response->request.status.status_code == statuses[i].status)
+ {
+ if (statuses[i].repeat_match &&
+ repeat_count < statuses[i].repeat_limit)
+ repeat_test = 1;
+
+ if (statuses[i].define_match)
+ set_variable(outfile, vars, statuses[i].define_match, "1");
+
+ break;
+ }
+ else
+ {
+ if (statuses[i].repeat_no_match &&
+ repeat_count < statuses[i].repeat_limit)
+ repeat_test = 1;
+
+ if (statuses[i].define_no_match)
+ {
+ set_variable(outfile, vars, statuses[i].define_no_match, "1");
+ break;
+ }
+ }
+ }
+
+ if (i == num_statuses && num_statuses > 0)
+ {
+ for (i = 0; i < num_statuses; i ++)
+ {
+ if (statuses[i].if_defined &&
+ !get_variable(vars, statuses[i].if_defined))
+ continue;
+
+ if (statuses[i].if_not_defined &&
+ get_variable(vars, statuses[i].if_not_defined))
+ continue;
+
+ if (!statuses[i].repeat_match)
+ add_stringf(errors, "EXPECTED: STATUS %s (got %s)",
+ ippErrorString(statuses[i].status),
+ ippErrorString(cupsLastError()));
+ }
+
+ if ((attrptr = ippFindAttribute(response, "status-message",
+ IPP_TAG_TEXT)) != NULL)
+ add_stringf(errors, "status-message=\"%s\"",
+ attrptr->values[0].string.text);
+ }
+
+ for (i = num_expects, expect = expects; i > 0; i --, expect ++)
+ {
+ if (expect->if_defined && !get_variable(vars, expect->if_defined))
+ continue;
+
+ if (expect->if_not_defined &&
+ get_variable(vars, expect->if_not_defined))
+ continue;
+
+ found = ippFindAttribute(response, expect->name, IPP_TAG_ZERO);
+
+ if ((found && expect->not_expect) ||
+ (!found && !(expect->not_expect || expect->optional)) ||
+ (found && !expect_matches(expect, found->value_tag)) ||
+ (found && expect->in_group &&
+ found->group_tag != expect->in_group))
+ {
+ if (expect->define_no_match)
+ set_variable(outfile, vars, expect->define_no_match, "1");
+ else if (!expect->define_match && !expect->define_value)
+ {
+ if (found && expect->not_expect)
+ add_stringf(errors, "NOT EXPECTED: %s", expect->name);
+ else if (!found && !(expect->not_expect || expect->optional))
+ add_stringf(errors, "EXPECTED: %s", expect->name);
+ else if (found)
+ {
+ if (!expect_matches(expect, found->value_tag))
+ add_stringf(errors, "EXPECTED: %s OF-TYPE %s (got %s)",
+ expect->name, expect->of_type,
+ ippTagString(found->value_tag));
+
+ if (expect->in_group && found->group_tag != expect->in_group)
+ add_stringf(errors, "EXPECTED: %s IN-GROUP %s (got %s).",
+ expect->name, ippTagString(expect->in_group),
+ ippTagString(found->group_tag));
+ }
+ }
+
+ if (expect->repeat_no_match &&
+ repeat_count < expect->repeat_limit)
+ repeat_test = 1;
+
+ continue;
+ }
+
+ if (found)
+ ippAttributeString(found, buffer, sizeof(buffer));
+
+ if (found &&
+ !with_value(outfile, NULL, expect->with_value, expect->with_flags, found,
+ buffer, sizeof(buffer)))
+ {
+ if (expect->define_no_match)
+ set_variable(outfile, vars, expect->define_no_match, "1");
+ else if (!expect->define_match && !expect->define_value &&
+ !expect->repeat_match && !expect->repeat_no_match)
+ {
+ if (expect->with_flags & _CUPS_WITH_REGEX)
+ add_stringf(errors, "EXPECTED: %s %s /%s/",
+ expect->name,
+ (expect->with_flags & _CUPS_WITH_ALL) ?
+ "WITH-ALL-VALUES" : "WITH-VALUE",
+ expect->with_value);
+ else
+ add_stringf(errors, "EXPECTED: %s %s \"%s\"",
+ expect->name,
+ (expect->with_flags & _CUPS_WITH_ALL) ?
+ "WITH-ALL-VALUES" : "WITH-VALUE",
+ expect->with_value);
+
+ with_value(outfile, errors, expect->with_value, expect->with_flags, found,
+ buffer, sizeof(buffer));
+ }
+
+ if (expect->repeat_no_match &&
+ repeat_count < expect->repeat_limit)
+ repeat_test = 1;
+
+ continue;
+ }
+
+ if (found && expect->count > 0 &&
+ found->num_values != expect->count)
+ {
+ if (expect->define_no_match)
+ set_variable(outfile, vars, expect->define_no_match, "1");
+ else if (!expect->define_match && !expect->define_value)
+ {
+ add_stringf(errors, "EXPECTED: %s COUNT %d (got %d)", expect->name,
+ expect->count, found->num_values);
+ }
+
+ if (expect->repeat_no_match &&
+ repeat_count < expect->repeat_limit)
+ repeat_test = 1;
+
+ continue;
+ }
+
+ if (found && expect->same_count_as)
+ {
+ attrptr = ippFindAttribute(response, expect->same_count_as,
+ IPP_TAG_ZERO);
+
+ if (!attrptr || attrptr->num_values != found->num_values)
+ {
+ if (expect->define_no_match)
+ set_variable(outfile, vars, expect->define_no_match, "1");
+ else if (!expect->define_match && !expect->define_value)
+ {
+ if (!attrptr)
+ add_stringf(errors,
+ "EXPECTED: %s (%d values) SAME-COUNT-AS %s "
+ "(not returned)", expect->name,
+ found->num_values, expect->same_count_as);
+ else if (attrptr->num_values != found->num_values)
+ add_stringf(errors,
+ "EXPECTED: %s (%d values) SAME-COUNT-AS %s "
+ "(%d values)", expect->name, found->num_values,
+ expect->same_count_as, attrptr->num_values);
+ }
+
+ if (expect->repeat_no_match &&
+ repeat_count < expect->repeat_limit)
+ repeat_test = 1;
+
+ continue;
+ }
+ }
+
+ if (found && expect->define_match)
+ set_variable(outfile, vars, expect->define_match, "1");
+
+ if (found && expect->define_value)
+ set_variable(outfile, vars, expect->define_value, buffer);
+
+ if (found && expect->repeat_match &&
+ repeat_count < expect->repeat_limit)
+ repeat_test = 1;
+ }
+ }
+
+ /*
+ * If we are going to repeat this test, sleep 1 second so we don't flood
+ * the printer with requests...
+ */
+
+ if (repeat_test)
+ {
+ if (Output == _CUPS_OUTPUT_TEST || (Output == _CUPS_OUTPUT_PLIST && outfile != stdout))
+ {
+ printf("%04d]\n", repeat_count);
+ fflush(stdout);
}
- for (attrptr = response->attrs, group = attrptr->group_tag;
- attrptr;
- attrptr = attrptr->next)
- {
- if (attrptr->group_tag < group && attrptr->group_tag != IPP_TAG_ZERO)
- print_test_error("Attribute groups out of order (%s < %s)",
- ippTagString(attrptr->group_tag),
- ippTagString(group));
+ sleep((unsigned)repeat_interval);
+ repeat_interval = _cupsNextDelay(repeat_interval, &repeat_prev);
- validate_attr(attrptr, 1);
+ if (Output == _CUPS_OUTPUT_TEST || (Output == _CUPS_OUTPUT_PLIST && outfile != stdout))
+ {
+ printf(" %-68.68s [", name);
+ fflush(stdout);
}
+ }
+ }
+ while (repeat_test);
- for (i = 0; i < num_statuses; i ++)
- {
- if (statuses[i].if_defined &&
- !get_variable(vars, statuses[i].if_defined))
- continue;
+ ippDelete(request);
- if (statuses[i].if_not_defined &&
- get_variable(vars, statuses[i].if_not_defined))
- continue;
+ request = NULL;
- if (response->request.status.status_code == statuses[i].status)
- break;
- }
+ if (cupsArrayCount(errors) > 0)
+ prev_pass = pass = 0;
- if (i == num_statuses && num_statuses > 0)
- {
- for (i = 0; i < num_statuses; i ++)
- {
- if (statuses[i].if_defined &&
- !get_variable(vars, statuses[i].if_defined))
- continue;
+ if (prev_pass)
+ PassCount ++;
+ else
+ FailCount ++;
- if (statuses[i].if_not_defined &&
- get_variable(vars, statuses[i].if_not_defined))
- continue;
+ if (Output == _CUPS_OUTPUT_PLIST)
+ {
+ fputs("<key>Successful</key>\n", outfile);
+ fputs(prev_pass ? "<true />\n" : "<false />\n", outfile);
+ fputs("<key>StatusCode</key>\n", outfile);
+ print_xml_string(outfile, "string", ippErrorString(cupsLastError()));
+ fputs("<key>ResponseAttributes</key>\n", outfile);
+ fputs("<array>\n", outfile);
+ fputs("<dict>\n", outfile);
+ for (attrptr = response ? response->attrs : NULL,
+ group = attrptr ? attrptr->group_tag : IPP_TAG_ZERO;
+ attrptr;
+ attrptr = attrptr->next)
+ print_attr(outfile, Output, attrptr, &group);
+ fputs("</dict>\n", outfile);
+ fputs("</array>\n", outfile);
+ }
- print_test_error("EXPECTED: STATUS %s (got %s)",
- ippErrorString(statuses[i].status),
- ippErrorString(cupsLastError()));
- }
+ if (Output == _CUPS_OUTPUT_TEST || (Output == _CUPS_OUTPUT_PLIST && outfile != stdout))
+ {
+ puts(prev_pass ? "PASS]" : "FAIL]");
- if ((attrptr = ippFindAttribute(response, "status-message",
- IPP_TAG_TEXT)) != NULL)
- print_test_error("status-message=\"%s\"",
- attrptr->values[0].string.text);
- }
+ if (!prev_pass || (Verbosity && response))
+ {
+ printf(" RECEIVED: %lu bytes in response\n",
+ (unsigned long)ippLength(response));
+ printf(" status-code = %s (%s)\n", ippErrorString(cupsLastError()),
+ cupsLastErrorString());
- for (i = num_expects, expect = expects; i > 0; i --, expect ++)
+ if (response)
+ {
+ for (attrptr = response->attrs;
+ attrptr != NULL;
+ attrptr = attrptr->next)
+ print_attr(stdout, _CUPS_OUTPUT_TEST, attrptr, NULL);
+ }
+ }
+ }
+ else if (!prev_pass)
+ fprintf(stderr, "%s\n", cupsLastErrorString());
+
+ if (prev_pass && Output >= _CUPS_OUTPUT_LIST && !Verbosity &&
+ num_displayed > 0)
+ {
+ size_t width; /* Length of value */
+
+ for (i = 0; i < num_displayed; i ++)
+ {
+ widths[i] = strlen(displayed[i]);
+
+ for (attrptr = ippFindAttribute(response, displayed[i], IPP_TAG_ZERO);
+ attrptr;
+ attrptr = ippFindNextAttribute(response, displayed[i],
+ IPP_TAG_ZERO))
{
- if (expect->define_match || expect->define_no_match)
- continue;
+ width = ippAttributeString(attrptr, NULL, 0);
+ if (width > widths[i])
+ widths[i] = width;
+ }
+ }
- if (expect->if_defined && !get_variable(vars, expect->if_defined))
- continue;
+ if (Output == _CUPS_OUTPUT_CSV)
+ print_csv(outfile, NULL, num_displayed, displayed, widths);
+ else
+ print_line(outfile, NULL, num_displayed, displayed, widths);
- if (expect->if_not_defined &&
- get_variable(vars, expect->if_not_defined))
- continue;
+ attrptr = response->attrs;
- found = ippFindAttribute(response, expect->name, IPP_TAG_ZERO);
+ while (attrptr)
+ {
+ while (attrptr && attrptr->group_tag <= IPP_TAG_OPERATION)
+ attrptr = attrptr->next;
- if (found && expect->not_expect)
- print_test_error("NOT EXPECTED: %s", expect->name);
- else if (!found && !(expect->not_expect || expect->optional))
- print_test_error("EXPECTED: %s", expect->name);
- else if (found)
- {
- if (!expect_matches(expect, found->value_tag))
- print_test_error("EXPECTED: %s OF-TYPE %s (got %s)",
- expect->name, expect->of_type,
- ippTagString(found->value_tag));
+ if (attrptr)
+ {
+ if (Output == _CUPS_OUTPUT_CSV)
+ print_csv(outfile, attrptr, num_displayed, displayed, widths);
+ else
+ print_line(outfile, attrptr, num_displayed, displayed, widths);
- if (expect->in_group && found->group_tag != expect->in_group)
- print_test_error("EXPECTED: %s IN-GROUP %s (got %s).",
- expect->name, ippTagString(expect->in_group),
- ippTagString(found->group_tag));
+ while (attrptr && attrptr->group_tag > IPP_TAG_OPERATION)
+ attrptr = attrptr->next;
+ }
+ }
+ }
+ else if (!prev_pass)
+ {
+ if (Output == _CUPS_OUTPUT_PLIST)
+ {
+ fputs("<key>Errors</key>\n", outfile);
+ fputs("<array>\n", outfile);
- if (!with_value(expect->with_value, expect->with_regex, found, 0))
- {
- if (expect->with_regex)
- print_test_error("EXPECTED: %s WITH-VALUE /%s/",
- expect->name, expect->with_value);
- else
- print_test_error("EXPECTED: %s WITH-VALUE \"%s\"",
- expect->name, expect->with_value);
+ for (error = (char *)cupsArrayFirst(errors);
+ error;
+ error = (char *)cupsArrayNext(errors))
+ print_xml_string(outfile, "string", error);
- with_value(expect->with_value, expect->with_regex, found, 1);
- }
+ fputs("</array>\n", outfile);
+ }
- if (expect->count > 0 && found->num_values != expect->count)
- {
- print_test_error("EXPECTED: %s COUNT %d (got %d)", expect->name,
- expect->count, found->num_values);
- }
+ if (Output == _CUPS_OUTPUT_TEST || (Output == _CUPS_OUTPUT_PLIST && outfile != stdout))
+ {
+ for (error = (char *)cupsArrayFirst(errors);
+ error;
+ error = (char *)cupsArrayNext(errors))
+ printf(" %s\n", error);
+ }
+ }
- if (expect->same_count_as)
+ if (num_displayed > 0 && !Verbosity && response && Output == _CUPS_OUTPUT_TEST)
+ {
+ for (attrptr = response->attrs;
+ attrptr != NULL;
+ attrptr = attrptr->next)
+ {
+ if (attrptr->name)
+ {
+ for (i = 0; i < num_displayed; i ++)
+ {
+ if (!strcmp(displayed[i], attrptr->name))
{
- attrptr = ippFindAttribute(response, expect->same_count_as,
- IPP_TAG_ZERO);
-
- if (!attrptr)
- print_test_error("EXPECTED: %s (%d values) SAME-COUNT-AS %s "
- "(not returned)", expect->name,
- found->num_values, expect->same_count_as);
- else if (attrptr->num_values != found->num_values)
- print_test_error("EXPECTED: %s (%d values) SAME-COUNT-AS %s "
- "(%d values)", expect->name, found->num_values,
- expect->same_count_as, attrptr->num_values);
+ print_attr(outfile, Output, attrptr, NULL);
+ break;
}
}
}
}
-
- if (Output == _CUPS_OUTPUT_PLIST)
- puts("</array>");
}
skip_error:
if (Output == _CUPS_OUTPUT_PLIST)
- puts("</dict>");
+ fputs("</dict>\n", outfile);
+
+ fflush(stdout);
ippDelete(response);
response = NULL;
free(statuses[i].if_defined);
if (statuses[i].if_not_defined)
free(statuses[i].if_not_defined);
+ if (statuses[i].define_match)
+ free(statuses[i].define_match);
+ if (statuses[i].define_no_match)
+ free(statuses[i].define_no_match);
}
num_statuses = 0;
test_exit:
+ cupsArrayDelete(errors);
+
if (fp)
fclose(fp);
free(statuses[i].if_defined);
if (statuses[i].if_not_defined)
free(statuses[i].if_not_defined);
+ if (statuses[i].define_match)
+ free(statuses[i].define_match);
+ if (statuses[i].define_no_match)
+ free(statuses[i].define_no_match);
}
for (i = num_expects, expect = expects; i > 0; i --, expect ++)
if (value)
{
- strlcpy(dstptr, value, dstend - dstptr + 1);
+ strlcpy(dstptr, value, (size_t)(dstend - dstptr + 1));
dstptr += strlen(dstptr);
}
}
*/
static ipp_t * /* O - Collection value */
-get_collection(_cups_vars_t *vars, /* I - Variables */
+get_collection(FILE *outfile, /* I - Output file */
+ _cups_vars_t *vars, /* I - Variables */
FILE *fp, /* I - File to read from */
int *linenum) /* IO - Line number */
{
* Another collection value
*/
- ipp_t *subcol = get_collection(vars, fp, linenum);
+ ipp_t *subcol = get_collection(outfile, vars, fp, linenum);
/* Collection value */
if (subcol)
- {
- ipp_attribute_t *tempcol; /* Pointer to new buffer */
-
-
- /*
- * Reallocate memory...
- */
-
- if ((tempcol = realloc(lastcol, sizeof(ipp_attribute_t) +
- (lastcol->num_values + 1) *
- sizeof(ipp_value_t))) == NULL)
- {
- print_fatal_error("Unable to allocate memory on line %d.", *linenum);
- goto col_error;
- }
-
- if (tempcol != lastcol)
- {
- /*
- * Reset pointers in the list...
- */
-
- if (col->prev)
- col->prev->next = tempcol;
- else
- col->attrs = tempcol;
-
- lastcol = col->current = col->last = tempcol;
- }
-
- lastcol->values[lastcol->num_values].collection = subcol;
- lastcol->num_values ++;
- }
+ ippSetCollection(col, &lastcol, ippGetCount(lastcol), subcol);
else
goto col_error;
}
if (!get_token(fp, token, sizeof(token), linenum))
{
- print_fatal_error("Missing MEMBER value tag on line %d.", *linenum);
+ print_fatal_error(outfile, "Missing MEMBER value tag on line %d.", *linenum);
goto col_error;
}
if ((value = ippTagValue(token)) == IPP_TAG_ZERO)
{
- print_fatal_error("Bad MEMBER value tag \"%s\" on line %d.", token,
+ print_fatal_error(outfile, "Bad MEMBER value tag \"%s\" on line %d.", token,
*linenum);
goto col_error;
}
if (!get_token(fp, attr, sizeof(attr), linenum))
{
- print_fatal_error("Missing MEMBER name on line %d.", *linenum);
+ print_fatal_error(outfile, "Missing MEMBER name on line %d.", *linenum);
goto col_error;
}
if (!get_token(fp, temp, sizeof(temp), linenum))
{
- print_fatal_error("Missing MEMBER value on line %d.", *linenum);
+ print_fatal_error(outfile, "Missing MEMBER value on line %d.", *linenum);
goto col_error;
}
if (!_cups_strcasecmp(token, "true"))
ippAddBoolean(col, IPP_TAG_ZERO, attr, 1);
else
- ippAddBoolean(col, IPP_TAG_ZERO, attr, atoi(token));
+ ippAddBoolean(col, IPP_TAG_ZERO, attr, (char)atoi(token));
break;
case IPP_TAG_INTEGER :
char units[6]; /* Units */
if (sscanf(token, "%dx%d%5s", &xres, &yres, units) != 3 ||
- (_cups_strcasecmp(units, "dpi") && _cups_strcasecmp(units, "dpc") &&
+ (_cups_strcasecmp(units, "dpi") &&
+ _cups_strcasecmp(units, "dpc") &&
+ _cups_strcasecmp(units, "dpcm") &&
_cups_strcasecmp(units, "other")))
{
- print_fatal_error("Bad resolution value \"%s\" on line %d.",
+ print_fatal_error(outfile, "Bad resolution value \"%s\" on line %d.",
token, *linenum);
goto col_error;
}
if (!_cups_strcasecmp(units, "dpi"))
- ippAddResolution(col, IPP_TAG_ZERO, attr, xres, yres,
- IPP_RES_PER_INCH);
- else if (!_cups_strcasecmp(units, "dpc"))
- ippAddResolution(col, IPP_TAG_ZERO, attr, xres, yres,
- IPP_RES_PER_CM);
+ ippAddResolution(col, IPP_TAG_ZERO, attr, IPP_RES_PER_INCH, xres, yres);
+ else if (!_cups_strcasecmp(units, "dpc") ||
+ !_cups_strcasecmp(units, "dpcm"))
+ ippAddResolution(col, IPP_TAG_ZERO, attr, IPP_RES_PER_CM, xres, yres);
else
- ippAddResolution(col, IPP_TAG_ZERO, attr, xres, yres,
- (ipp_res_t)0);
+ ippAddResolution(col, IPP_TAG_ZERO, attr, (ipp_res_t)0, xres, yres);
}
break;
if ((num_vals & 1) || num_vals == 0)
{
- print_fatal_error("Bad rangeOfInteger value \"%s\" on line %d.",
+ print_fatal_error(outfile, "Bad rangeOfInteger value \"%s\" on line %d.",
token, *linenum);
goto col_error;
}
case IPP_TAG_BEGIN_COLLECTION :
if (!strcmp(token, "{"))
{
- ipp_t *subcol = get_collection(vars, fp, linenum);
+ ipp_t *subcol = get_collection(outfile, vars, fp, linenum);
/* Collection value */
if (subcol)
}
else
{
- print_fatal_error("Bad collection value on line %d.", *linenum);
+ print_fatal_error(outfile, "Bad collection value on line %d.", *linenum);
goto col_error;
}
break;
+ case IPP_TAG_STRING :
+ ippAddOctetString(col, IPP_TAG_ZERO, attr, token, (int)strlen(token));
+ break;
default :
if (!strchr(token, ','))
if (*dstptr == '>')
*dstptr = '\0';
}
- else if (*src == '/' || !strchr(testfile, '/'))
+ else if (*src == '/' || !strchr(testfile, '/')
+#ifdef WIN32
+ || (isalpha(*src & 255) && src[1] == ':')
+#endif /* WIN32 */
+ )
{
/*
* Use the path as-is...
else
dstptr = dst; /* Should never happen */
- strlcpy(dstptr, src, dstsize - (dstptr - dst));
+ strlcpy(dstptr, src, dstsize - (size_t)(dstptr - dst));
}
return (dst);
}
+/*
+ * 'get_string()' - Get a pointer to a string value or the portion of interest.
+ */
+
+static char * /* O - Pointer to string */
+get_string(ipp_attribute_t *attr, /* I - IPP attribute */
+ int element, /* I - Element to fetch */
+ int flags, /* I - Value ("with") flags */
+ char *buffer, /* I - Temporary buffer */
+ size_t bufsize) /* I - Size of temporary buffer */
+{
+ char *ptr, /* Value */
+ scheme[256], /* URI scheme */
+ userpass[256], /* Username/password */
+ hostname[256], /* Hostname */
+ resource[1024]; /* Resource */
+ int port; /* Port number */
+
+
+ ptr = attr->values[element].string.text;
+
+ if (flags & _CUPS_WITH_HOSTNAME)
+ {
+ if (httpSeparateURI(HTTP_URI_CODING_ALL, ptr, scheme, sizeof(scheme), userpass, sizeof(userpass), buffer, (int)bufsize, &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
+ buffer[0] = '\0';
+
+ return (buffer);
+ }
+ else if (flags & _CUPS_WITH_RESOURCE)
+ {
+ if (httpSeparateURI(HTTP_URI_CODING_ALL, ptr, scheme, sizeof(scheme), userpass, sizeof(userpass), hostname, sizeof(hostname), &port, buffer, (int)bufsize) < HTTP_URI_STATUS_OK)
+ buffer[0] = '\0';
+
+ return (buffer);
+ }
+ else if (flags & _CUPS_WITH_SCHEME)
+ {
+ if (httpSeparateURI(HTTP_URI_CODING_ALL, ptr, buffer, (int)bufsize, userpass, sizeof(userpass), hostname, sizeof(hostname), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
+ buffer[0] = '\0';
+
+ return (buffer);
+ }
+ else
+ return (ptr);
+}
+
+
/*
* 'get_token()' - Get a token from a file.
*/
*/
if (bufptr < bufend)
- *bufptr++ = ch;
+ *bufptr++ = (char)ch;
if ((ch = getc(fp)) != EOF && bufptr < bufend)
- *bufptr++ = ch;
+ *bufptr++ = (char)ch;
}
else if (ch == quote)
break;
else if (bufptr < bufend)
- *bufptr++ = ch;
+ *bufptr++ = (char)ch;
}
*bufptr = '\0';
(*linenum) ++;
}
+ else if (ch == '{' || ch == '}' || ch == ',')
+ {
+ buf[0] = (char)ch;
+ buf[1] = '\0';
+
+ return (buf);
+ }
else
{
/*
if (isspace(ch) || ch == '#')
break;
else if (bufptr < bufend)
- *bufptr++ = ch;
+ *bufptr++ = (char)ch;
if (ch == '#')
ungetc(ch, fp);
{
(void)prompt;
- return (Password);
+ if (PasswordTries < 3)
+ {
+ PasswordTries ++;
+
+ cupsSetUser(Username);
+
+ return (Password);
+ }
+ else
+ return (NULL);
}
/*
- * 'print_attr()' - Print an attribute on the screen.
+ * 'pause_message()' - Display the message and pause until the user presses a key.
*/
static void
-print_attr(ipp_attribute_t *attr, /* I - Attribute to print */
- ipp_tag_t *group) /* IO - Current group */
+pause_message(const char *message) /* I - Message */
{
- int i; /* Looping var */
- ipp_attribute_t *colattr; /* Collection attribute */
-
-
- if (Output == _CUPS_OUTPUT_PLIST)
- {
- if (!attr->name || (group && *group != attr->group_tag))
- {
- puts("</dict>");
- puts("<dict>");
-
- if (group)
- *group = attr->group_tag;
- }
-
- if (!attr->name)
- return;
-
- print_xml_string("key", attr->name);
- if (attr->num_values > 1)
- puts("<array>");
- }
- else if (Output == _CUPS_OUTPUT_TEST)
- {
- if (!attr->name)
- {
- puts(" -- separator --");
- return;
- }
-
- printf(" %s (%s%s) = ", attr->name,
- attr->num_values > 1 ? "1setOf " : "",
- ippTagString(attr->value_tag));
- }
-
- switch (attr->value_tag)
- {
- case IPP_TAG_INTEGER :
- case IPP_TAG_ENUM :
- for (i = 0; i < attr->num_values; i ++)
- if (Output == _CUPS_OUTPUT_PLIST)
- printf("<integer>%d</integer>\n", attr->values[i].integer);
- else
- printf("%d ", attr->values[i].integer);
- break;
-
- case IPP_TAG_BOOLEAN :
- for (i = 0; i < attr->num_values; i ++)
- if (Output == _CUPS_OUTPUT_PLIST)
- puts(attr->values[i].boolean ? "<true />" : "<false />");
- else if (attr->values[i].boolean)
- fputs("true ", stdout);
- else
- fputs("false ", stdout);
- break;
+#ifdef WIN32
+ HANDLE tty; /* Console handle */
+ DWORD mode; /* Console mode */
+ char key; /* Key press */
+ DWORD bytes; /* Bytes read for key press */
- case IPP_TAG_RANGE :
- for (i = 0; i < attr->num_values; i ++)
- if (Output == _CUPS_OUTPUT_PLIST)
- printf("<dict><key>lower</key><integer>%d</integer>"
- "<key>upper</key><integer>%d</integer></dict>\n",
- attr->values[i].range.lower, attr->values[i].range.upper);
- else
- printf("%d-%d ", attr->values[i].range.lower,
- attr->values[i].range.upper);
- break;
-
- case IPP_TAG_RESOLUTION :
- for (i = 0; i < attr->num_values; i ++)
- if (Output == _CUPS_OUTPUT_PLIST)
- printf("<dict><key>xres</key><integer>%d</integer>"
- "<key>yres</key><integer>%d</integer>"
- "<key>units</key><string>%s</string></dict>\n",
- attr->values[i].resolution.xres,
- attr->values[i].resolution.yres,
- attr->values[i].resolution.units == IPP_RES_PER_INCH ?
- "dpi" : "dpc");
- else
- printf("%dx%d%s ", attr->values[i].resolution.xres,
- attr->values[i].resolution.yres,
- attr->values[i].resolution.units == IPP_RES_PER_INCH ?
- "dpi" : "dpc");
- break;
-
- case IPP_TAG_DATE :
- for (i = 0; i < attr->num_values; i ++)
- if (Output == _CUPS_OUTPUT_PLIST)
- printf("<date>%s</date>\n", iso_date(attr->values[i].date));
- else
- printf("%s ", iso_date(attr->values[i].date));
- break;
- case IPP_TAG_STRING :
- case IPP_TAG_TEXT :
- case IPP_TAG_NAME :
- case IPP_TAG_KEYWORD :
- case IPP_TAG_CHARSET :
- case IPP_TAG_URI :
- case IPP_TAG_MIMETYPE :
- case IPP_TAG_LANGUAGE :
- for (i = 0; i < attr->num_values; i ++)
- if (Output == _CUPS_OUTPUT_PLIST)
- print_xml_string("string", attr->values[i].string.text);
- else
- printf("\"%s\" ", attr->values[i].string.text);
- break;
+ /*
+ * Disable input echo and set raw input...
+ */
- case IPP_TAG_TEXTLANG :
- case IPP_TAG_NAMELANG :
- for (i = 0; i < attr->num_values; i ++)
- if (Output == _CUPS_OUTPUT_PLIST)
- {
- fputs("<dict><key>language</key><string>", stdout);
- print_xml_string(NULL, attr->values[i].string.charset);
- fputs("</string><key>string</key><string>", stdout);
- print_xml_string(NULL, attr->values[i].string.text);
- puts("</string></dict>");
- }
- else
- printf("\"%s\"(%s) ", attr->values[i].string.text,
- attr->values[i].string.charset);
- break;
+ if ((tty = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE)
+ return;
- case IPP_TAG_BEGIN_COLLECTION :
- for (i = 0; i < attr->num_values; i ++)
- {
- if (Output == _CUPS_OUTPUT_PLIST)
- {
- puts("<dict>");
- for (colattr = attr->values[i].collection->attrs;
- colattr;
- colattr = colattr->next)
- print_attr(colattr, NULL);
- puts("</dict>");
- }
- else
- {
- if (i)
- putchar(' ');
+ if (!GetConsoleMode(tty, &mode))
+ return;
- print_col(attr->values[i].collection);
- }
- }
- break;
+ if (!SetConsoleMode(tty, 0))
+ return;
- default :
- if (Output == _CUPS_OUTPUT_PLIST)
- printf("<string><<%s>></string>\n",
- ippTagString(attr->value_tag));
- else
- fputs(ippTagString(attr->value_tag), stdout);
- break;
+#else
+ int tty; /* /dev/tty - never read from stdin */
+ struct termios original, /* Original input mode */
+ noecho; /* No echo input mode */
+ char key; /* Current key press */
+
+
+ /*
+ * Disable input echo and set raw input...
+ */
+
+ if ((tty = open("/dev/tty", O_RDONLY)) < 0)
+ return;
+
+ if (tcgetattr(tty, &original))
+ {
+ close(tty);
+ return;
}
- if (Output == _CUPS_OUTPUT_PLIST)
+ noecho = original;
+ noecho.c_lflag &= (tcflag_t)~(ICANON | ECHO | ECHOE | ISIG);
+
+ if (tcsetattr(tty, TCSAFLUSH, &noecho))
{
- if (attr->num_values > 1)
- puts("</array>");
+ close(tty);
+ return;
}
- else
- putchar('\n');
+#endif /* WIN32 */
+
+ /*
+ * Display the prompt...
+ */
+
+ printf("%s\n---- PRESS ANY KEY ----", message);
+ fflush(stdout);
+
+#ifdef WIN32
+ /*
+ * Read a key...
+ */
+
+ ReadFile(tty, &key, 1, &bytes, NULL);
+
+ /*
+ * Cleanup...
+ */
+
+ SetConsoleMode(tty, mode);
+
+#else
+ /*
+ * Read a key...
+ */
+
+ read(tty, &key, 1);
+
+ /*
+ * Cleanup...
+ */
+
+ tcsetattr(tty, TCSAFLUSH, &original);
+ close(tty);
+#endif /* WIN32 */
+
+ /*
+ * Erase the "press any key" prompt...
+ */
+
+ fputs("\r \r", stdout);
+ fflush(stdout);
}
/*
- * 'print_col()' - Print a collection attribute on the screen.
+ * 'print_attr()' - Print an attribute on the screen.
*/
static void
-print_col(ipp_t *col) /* I - Collection attribute to print */
+print_attr(FILE *outfile, /* I - Output file */
+ int format, /* I - Output format */
+ ipp_attribute_t *attr, /* I - Attribute to print */
+ ipp_tag_t *group) /* IO - Current group */
{
int i; /* Looping var */
- ipp_attribute_t *attr; /* Current attribute in collection */
+ ipp_attribute_t *colattr; /* Collection attribute */
- fputs("{ ", stdout);
- for (attr = col->attrs; attr; attr = attr->next)
+ if (format == _CUPS_OUTPUT_PLIST)
{
- printf("%s (%s%s) = ", attr->name, attr->num_values > 1 ? "1setOf " : "",
- ippTagString(attr->value_tag));
+ if (!attr->name || (group && *group != attr->group_tag))
+ {
+ if (attr->group_tag != IPP_TAG_ZERO)
+ {
+ fputs("</dict>\n", outfile);
+ fputs("<dict>\n", outfile);
+ }
+
+ if (group)
+ *group = attr->group_tag;
+ }
+
+ if (!attr->name)
+ return;
+
+ print_xml_string(outfile, "key", attr->name);
+ if (attr->num_values > 1)
+ fputs("<array>\n", outfile);
switch (attr->value_tag)
{
case IPP_TAG_INTEGER :
case IPP_TAG_ENUM :
for (i = 0; i < attr->num_values; i ++)
- printf("%d ", attr->values[i].integer);
+ fprintf(outfile, "<integer>%d</integer>\n", attr->values[i].integer);
break;
case IPP_TAG_BOOLEAN :
for (i = 0; i < attr->num_values; i ++)
- if (attr->values[i].boolean)
- printf("true ");
- else
- printf("false ");
- break;
-
- case IPP_TAG_NOVALUE :
- printf("novalue");
+ fputs(attr->values[i].boolean ? "<true />\n" : "<false />\n", outfile);
break;
case IPP_TAG_RANGE :
for (i = 0; i < attr->num_values; i ++)
- printf("%d-%d ", attr->values[i].range.lower,
- attr->values[i].range.upper);
+ fprintf(outfile, "<dict><key>lower</key><integer>%d</integer>"
+ "<key>upper</key><integer>%d</integer></dict>\n",
+ attr->values[i].range.lower, attr->values[i].range.upper);
break;
case IPP_TAG_RESOLUTION :
for (i = 0; i < attr->num_values; i ++)
- printf("%dx%d%s ", attr->values[i].resolution.xres,
+ fprintf(outfile, "<dict><key>xres</key><integer>%d</integer>"
+ "<key>yres</key><integer>%d</integer>"
+ "<key>units</key><string>%s</string></dict>\n",
+ attr->values[i].resolution.xres,
attr->values[i].resolution.yres,
attr->values[i].resolution.units == IPP_RES_PER_INCH ?
- "dpi" : "dpc");
+ "dpi" : "dpcm");
+ break;
+
+ case IPP_TAG_DATE :
+ for (i = 0; i < attr->num_values; i ++)
+ fprintf(outfile, "<date>%s</date>\n", iso_date(attr->values[i].date));
break;
case IPP_TAG_STRING :
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ char buffer[IPP_MAX_LENGTH * 5 / 4 + 1];
+ /* Output buffer */
+
+ fprintf(outfile, "<data>%s</data>\n",
+ httpEncode64_2(buffer, sizeof(buffer),
+ attr->values[i].unknown.data,
+ attr->values[i].unknown.length));
+ }
+ break;
+
case IPP_TAG_TEXT :
case IPP_TAG_NAME :
case IPP_TAG_KEYWORD :
case IPP_TAG_MIMETYPE :
case IPP_TAG_LANGUAGE :
for (i = 0; i < attr->num_values; i ++)
- printf("\"%s\" ", attr->values[i].string.text);
+ print_xml_string(outfile, "string", attr->values[i].string.text);
break;
case IPP_TAG_TEXTLANG :
case IPP_TAG_NAMELANG :
for (i = 0; i < attr->num_values; i ++)
- printf("\"%s\",%s ", attr->values[i].string.text,
- attr->values[i].string.charset);
+ {
+ fputs("<dict><key>language</key><string>", outfile);
+ print_xml_string(outfile, NULL, attr->values[i].string.language);
+ fputs("</string><key>string</key><string>", outfile);
+ print_xml_string(outfile, NULL, attr->values[i].string.text);
+ fputs("</string></dict>\n", outfile);
+ }
break;
case IPP_TAG_BEGIN_COLLECTION :
for (i = 0; i < attr->num_values; i ++)
{
- print_col(attr->values[i].collection);
- putchar(' ');
+ fputs("<dict>\n", outfile);
+ for (colattr = attr->values[i].collection->attrs;
+ colattr;
+ colattr = colattr->next)
+ print_attr(outfile, format, colattr, NULL);
+ fputs("</dict>\n", outfile);
}
break;
default :
- break; /* anti-compiler-warning-code */
+ fprintf(outfile, "<string><<%s>></string>\n", ippTagString(attr->value_tag));
+ break;
}
+
+ if (attr->num_values > 1)
+ fputs("</array>\n", outfile);
}
+ else
+ {
+ char buffer[8192]; /* Value buffer */
+
+ if (format == _CUPS_OUTPUT_TEST)
+ {
+ if (!attr->name)
+ {
+ fputs(" -- separator --\n", outfile);
+ return;
+ }
+
+ fprintf(outfile, " %s (%s%s) = ", attr->name, attr->num_values > 1 ? "1setOf " : "", ippTagString(attr->value_tag));
+ }
- putchar('}');
+ ippAttributeString(attr, buffer, sizeof(buffer));
+ fprintf(outfile, "%s\n", buffer);
+ }
}
static void
print_csv(
+ FILE *outfile, /* I - Output file */
ipp_attribute_t *attr, /* I - First attribute for line */
int num_displayed, /* I - Number of attributes to display */
char **displayed, /* I - Attributes to display */
for (i = 0; i < num_displayed; i ++)
{
if (i)
- putchar(',');
+ fputc(',', outfile);
buffer[0] = '\0';
break;
else if (!strcmp(current->name, displayed[i]))
{
- _ippAttrString(current, buffer, maxlength);
+ ippAttributeString(current, buffer, maxlength);
break;
}
}
if (strchr(buffer, ',') != NULL || strchr(buffer, '\"') != NULL ||
strchr(buffer, '\\') != NULL)
{
- putchar('\"');
+ putc('\"', outfile);
for (bufptr = buffer; *bufptr; bufptr ++)
{
if (*bufptr == '\\' || *bufptr == '\"')
- putchar('\\');
- putchar(*bufptr);
+ putc('\\', outfile);
+ putc(*bufptr, outfile);
}
- putchar('\"');
+ putc('\"', outfile);
}
else
- fputs(buffer, stdout);
+ fputs(buffer, outfile);
}
- putchar('\n');
+ putc('\n', outfile);
}
else
{
for (i = 0; i < num_displayed; i ++)
{
if (i)
- putchar(',');
+ putc(',', outfile);
- fputs(displayed[i], stdout);
+ fputs(displayed[i], outfile);
}
- putchar('\n');
+ putc('\n', outfile);
}
free(buffer);
*/
static void
-print_fatal_error(const char *s, /* I - Printf-style format string */
+print_fatal_error(FILE *outfile, /* I - Output file */
+ const char *s, /* I - Printf-style format string */
...) /* I - Additional arguments as needed */
{
char buffer[10240]; /* Format buffer */
if (Output == _CUPS_OUTPUT_PLIST)
{
- print_xml_header();
- print_xml_trailer(0, buffer);
+ print_xml_header(outfile);
+ print_xml_trailer(outfile, 0, buffer);
}
- else
- _cupsLangPrintf(stderr, "ipptool: %s", buffer);
+
+ _cupsLangPrintf(stderr, "ipptool: %s", buffer);
}
static void
print_line(
+ FILE *outfile, /* I - Output file */
ipp_attribute_t *attr, /* I - First attribute for line */
int num_displayed, /* I - Number of attributes to display */
char **displayed, /* I - Attributes to display */
for (i = 0; i < num_displayed; i ++)
{
if (i)
- putchar(' ');
+ putc(' ', outfile);
buffer[0] = '\0';
break;
else if (!strcmp(current->name, displayed[i]))
{
- _ippAttrString(current, buffer, maxlength);
+ ippAttributeString(current, buffer, maxlength);
break;
}
}
- printf("%*s", (int)-widths[i], buffer);
+ fprintf(outfile, "%*s", (int)-widths[i], buffer);
}
- putchar('\n');
+ putc('\n', outfile);
}
else
{
for (i = 0; i < num_displayed; i ++)
{
if (i)
- putchar(' ');
+ putc(' ', outfile);
- printf("%*s", (int)-widths[i], displayed[i]);
+ fprintf(outfile, "%*s", (int)-widths[i], displayed[i]);
}
- putchar('\n');
+ putc('\n', outfile);
for (i = 0; i < num_displayed; i ++)
{
if (i)
- putchar(' ');
+ putc(' ', outfile);
memset(buffer, '-', widths[i]);
buffer[widths[i]] = '\0';
- fputs(buffer, stdout);
+ fputs(buffer, outfile);
}
- putchar('\n');
+ putc('\n', outfile);
}
free(buffer);
}
-/*
- * 'print_test_error()' - Print a test error message.
- */
-
-static void
-print_test_error(const char *s, /* I - Printf-style format string */
- ...) /* I - Additional arguments as needed */
-{
- char buffer[10240]; /* Format buffer */
- va_list ap; /* Pointer to arguments */
-
-
- /*
- * Format the error message...
- */
-
- va_start(ap, s);
- vsnprintf(buffer, sizeof(buffer), s, ap);
- va_end(ap);
-
- /*
- * Then output it...
- */
-
- if (Output == _CUPS_OUTPUT_PLIST)
- print_xml_string("string", buffer);
- else
- printf(" %s\n", buffer);
-}
-
-
/*
* 'print_xml_header()' - Print a standard XML plist header.
*/
static void
-print_xml_header(void)
+print_xml_header(FILE *outfile) /* I - Output file */
{
if (!XMLHeader)
{
- puts("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- puts("<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
- "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
- puts("<plist version=\"1.0\">");
- puts("<dict>");
- puts("<key>Transfer</key>");
- printf("<string>%s</string>\n",
- Transfer == _CUPS_TRANSFER_AUTO ? "auto" :
- Transfer == _CUPS_TRANSFER_CHUNKED ? "chunked" : "length");
- puts("<key>Tests</key>");
- puts("<array>");
+ fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", outfile);
+ fputs("<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
+ "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n", outfile);
+ fputs("<plist version=\"1.0\">\n", outfile);
+ fputs("<dict>\n", outfile);
+ fputs("<key>ipptoolVersion</key>\n", outfile);
+ fputs("<string>" CUPS_SVERSION "</string>\n", outfile);
+ fputs("<key>Transfer</key>\n", outfile);
+ fprintf(outfile, "<string>%s</string>\n",
+ Transfer == _CUPS_TRANSFER_AUTO ? "auto" :
+ Transfer == _CUPS_TRANSFER_CHUNKED ? "chunked" : "length");
+ fputs("<key>Tests</key>\n", outfile);
+ fputs("<array>\n", outfile);
XMLHeader = 1;
}
*/
static void
-print_xml_string(const char *element, /* I - Element name or NULL */
+print_xml_string(FILE *outfile, /* I - Output file */
+ const char *element, /* I - Element name or NULL */
const char *s) /* I - String to print */
{
if (element)
- printf("<%s>", element);
+ fprintf(outfile, "<%s>", element);
while (*s)
{
if (*s == '&')
- fputs("&", stdout);
+ fputs("&", outfile);
else if (*s == '<')
- fputs("<", stdout);
+ fputs("<", outfile);
else if (*s == '>')
- fputs(">", stdout);
+ fputs(">", outfile);
else if ((*s & 0xe0) == 0xc0)
{
/*
if ((s[1] & 0xc0) != 0x80)
{
- putchar('?');
+ putc('?', outfile);
s ++;
}
else
{
- putchar(*s++);
- putchar(*s);
+ putc(*s++, outfile);
+ putc(*s, outfile);
}
}
else if ((*s & 0xf0) == 0xe0)
if ((s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80)
{
- putchar('?');
+ putc('?', outfile);
s += 2;
}
else
{
- putchar(*s++);
- putchar(*s++);
- putchar(*s);
+ putc(*s++, outfile);
+ putc(*s++, outfile);
+ putc(*s, outfile);
}
}
else if ((*s & 0xf8) == 0xf0)
if ((s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 ||
(s[3] & 0xc0) != 0x80)
{
- putchar('?');
+ putc('?', outfile);
s += 3;
}
else
{
- putchar(*s++);
- putchar(*s++);
- putchar(*s++);
- putchar(*s);
+ putc(*s++, outfile);
+ putc(*s++, outfile);
+ putc(*s++, outfile);
+ putc(*s, outfile);
}
}
else if ((*s & 0x80) || (*s < ' ' && !isspace(*s & 255)))
* Invalid control character...
*/
- putchar('?');
+ putc('?', outfile);
}
else
- putchar(*s);
+ putc(*s, outfile);
s ++;
}
if (element)
- printf("</%s>\n", element);
+ fprintf(outfile, "</%s>\n", element);
}
*/
static void
-print_xml_trailer(int success, /* I - 1 on success, 0 on failure */
+print_xml_trailer(FILE *outfile, /* I - Output file */
+ int success, /* I - 1 on success, 0 on failure */
const char *message) /* I - Error message or NULL */
{
if (XMLHeader)
{
- puts("</array>");
- puts("<key>Successful</key>");
- puts(success ? "<true />" : "<false />");
+ fputs("</array>\n", outfile);
+ fputs("<key>Successful</key>\n", outfile);
+ fputs(success ? "<true />\n" : "<false />\n", outfile);
if (message)
{
- puts("<key>ErrorMessage</key>");
- print_xml_string("string", message);
+ fputs("<key>ErrorMessage</key>\n", outfile);
+ print_xml_string(outfile, "string", message);
}
- puts("</dict>");
- puts("</plist>");
+ fputs("</dict>\n", outfile);
+ fputs("</plist>\n", outfile);
XMLHeader = 0;
}
*/
static void
-set_variable(_cups_vars_t *vars, /* I - Variables */
+set_variable(FILE *outfile, /* I - Output file */
+ _cups_vars_t *vars, /* I - Variables */
const char *name, /* I - Variable name */
const char *value) /* I - Value string */
{
*var; /* New variable */
+ if (!_cups_strcasecmp(name, "filename"))
+ {
+ if (vars->filename)
+ free(vars->filename);
+
+ vars->filename = strdup(value);
+ return;
+ }
+
key.name = (char *)name;
if ((var = cupsArrayFind(vars->vars, &key)) != NULL)
{
}
else if ((var = malloc(sizeof(_cups_var_t))) == NULL)
{
- print_fatal_error("Unable to allocate memory for variable \"%s\".", name);
+ print_fatal_error(outfile, "Unable to allocate memory for variable \"%s\".", name);
exit(1);
}
else
}
+#ifndef WIN32
/*
* 'sigterm_handler()' - Handle SIGINT and SIGTERM.
*/
(void)sig;
Cancel = 1;
+
+ signal(SIGINT, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
}
+#endif /* !WIN32 */
/*
*/
static int /* O - 1 to continue, 0 to cancel */
-timeout_cb(http_t *http, /* I - Connection to server (unused) */
+timeout_cb(http_t *http, /* I - Connection to server */
void *user_data) /* I - User data (unused) */
{
- (void)http;
+ int buffered = 0; /* Bytes buffered but not yet sent */
+
+
(void)user_data;
- /* Always cancel on timeout */
- return (0);
+ /*
+ * If the socket still have data waiting to be sent to the printer (as can
+ * happen if the printer runs out of paper), continue to wait until the output
+ * buffer is empty...
+ */
+
+#ifdef SO_NWRITE /* OS X and some versions of Linux */
+ socklen_t len = sizeof(buffered); /* Size of return value */
+
+ if (getsockopt(httpGetFd(http), SOL_SOCKET, SO_NWRITE, &buffered, &len))
+ buffered = 0;
+
+#elif defined(SIOCOUTQ) /* Others except Windows */
+ if (ioctl(httpGetFd(http), SIOCOUTQ, &buffered))
+ buffered = 0;
+
+#else /* Windows (not possible) */
+ (void)http;
+#endif /* SO_NWRITE */
+
+ return (buffered > 0);
}
_cupsLangPuts(stderr, _(" -6 Connect using IPv6."));
_cupsLangPuts(stderr, _(" -C Send requests using "
"chunking (default)."));
- _cupsLangPuts(stderr, _(" -E Test with TLS "
- "encryption."));
+ _cupsLangPuts(stdout, _(" -E Test with HTTP Upgrade to "
+ "TLS."));
_cupsLangPuts(stderr, _(" -I Ignore errors."));
_cupsLangPuts(stderr, _(" -L Send requests using "
"content-length."));
_cupsLangPuts(stderr, _(" -S Test with SSL "
"encryption."));
- _cupsLangPuts(stderr, _(" -T Set the receive/send "
+ _cupsLangPuts(stderr, _(" -T seconds Set the receive/send "
"timeout in seconds."));
_cupsLangPuts(stderr, _(" -V version Set default IPP "
"version."));
"the given time interval."));
_cupsLangPuts(stderr, _(" -n count Repeat the last file the "
"given number of times."));
- _cupsLangPuts(stderr, _(" -q Be quiet - no output "
- "except errors."));
+ _cupsLangPuts(stderr, _(" -q Run silently."));
_cupsLangPuts(stderr, _(" -t Produce a test report."));
- _cupsLangPuts(stderr, _(" -v Show all attributes sent "
- "and received."));
+ _cupsLangPuts(stderr, _(" -v Be verbose."));
exit(1);
}
*/
static int /* O - 1 if valid, 0 otherwise */
-validate_attr(ipp_attribute_t *attr, /* I - Attribute to validate */
- int print) /* I - 1 = report issues to stdout */
+validate_attr(FILE *outfile, /* I - Output file */
+ cups_array_t *errors, /* I - Errors array */
+ ipp_attribute_t *attr) /* I - Attribute to validate */
{
int i; /* Looping var */
char scheme[64], /* Scheme from URI */
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad attribute name - invalid character (RFC "
- "2911 section 4.1.3).", attr->name);
+ add_stringf(errors,
+ "\"%s\": Bad attribute name - invalid character "
+ "(RFC 2911 section 4.1.3).", attr->name);
}
if ((ptr - attr->name) > 255)
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad attribute name - bad length (RFC 2911 "
- "section 4.1.3).", attr->name);
+ add_stringf(errors,
+ "\"%s\": Bad attribute name - bad length "
+ "(RFC 2911 section 4.1.3).", attr->name);
}
switch (attr->value_tag)
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad boolen value %d (RFC 2911 section "
- "4.1.10).", attr->name, attr->values[i].boolean);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad boolen value %d "
+ "(RFC 2911 section 4.1.11).", attr->name,
+ attr->values[i].boolean);
}
}
break;
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad enum value %d - out of range "
- "(RFC 2911 section 4.1.4).", attr->name,
- attr->values[i].integer);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad enum value %d - out of range "
+ "(RFC 2911 section 4.1.4).", attr->name,
+ attr->values[i].integer);
}
}
break;
case IPP_TAG_STRING :
for (i = 0; i < attr->num_values; i ++)
{
- if (attr->values[i].unknown.length > 1023)
+ if (attr->values[i].unknown.length > IPP_MAX_OCTETSTRING)
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad octetString value - bad length %d "
- "(RFC 2911 section 4.1.10).", attr->name,
- attr->values[i].unknown.length);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad octetString value - bad length %d "
+ "(RFC 2911 section 4.1.10).", attr->name,
+ attr->values[i].unknown.length);
}
}
break;
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad dateTime month %u (RFC 2911 "
- "section 4.1.13).", attr->name, date[2]);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad dateTime month %u "
+ "(RFC 2911 section 4.1.14).", attr->name, date[2]);
}
if (date[3] < 1 || date[3] > 31)
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad dateTime day %u (RFC 2911 "
- "section 4.1.13).", attr->name, date[3]);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad dateTime day %u "
+ "(RFC 2911 section 4.1.14).", attr->name, date[3]);
}
if (date[4] > 23)
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad dateTime hours %u (RFC 2911 "
- "section 4.1.13).", attr->name, date[4]);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad dateTime hours %u "
+ "(RFC 2911 section 4.1.14).", attr->name, date[4]);
}
if (date[5] > 59)
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad dateTime minutes %u (RFC 2911 "
- "section 4.1.13).", attr->name, date[5]);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad dateTime minutes %u "
+ "(RFC 2911 section 4.1.14).", attr->name, date[5]);
}
if (date[6] > 60)
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad dateTime seconds %u (RFC 2911 "
- "section 4.1.13).", attr->name, date[6]);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad dateTime seconds %u "
+ "(RFC 2911 section 4.1.14).", attr->name, date[6]);
}
if (date[7] > 9)
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad dateTime deciseconds %u (RFC 2911 "
- "section 4.1.13).", attr->name, date[7]);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad dateTime deciseconds %u "
+ "(RFC 2911 section 4.1.14).", attr->name, date[7]);
}
if (date[8] != '-' && date[8] != '+')
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad dateTime UTC sign '%c' (RFC 2911 "
- "section 4.1.13).", attr->name, date[8]);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad dateTime UTC sign '%c' "
+ "(RFC 2911 section 4.1.14).", attr->name, date[8]);
}
if (date[9] > 11)
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad dateTime UTC hours %u (RFC 2911 "
- "section 4.1.13).", attr->name, date[9]);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad dateTime UTC hours %u "
+ "(RFC 2911 section 4.1.14).", attr->name, date[9]);
}
if (date[10] > 59)
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad dateTime UTC minutes %u (RFC 2911 "
- "section 4.1.13).", attr->name, date[10]);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad dateTime UTC minutes %u "
+ "(RFC 2911 section 4.1.14).", attr->name, date[10]);
}
}
break;
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad resolution value %dx%d%s - cross "
- "feed resolution must be positive (RFC 2911 "
- "section 4.1.13).", attr->name,
- attr->values[i].resolution.xres,
- attr->values[i].resolution.yres,
- attr->values[i].resolution.units ==
- IPP_RES_PER_INCH ? "dpi" :
- attr->values[i].resolution.units ==
- IPP_RES_PER_CM ? "dpc" : "unknown");
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad resolution value %dx%d%s - cross "
+ "feed resolution must be positive "
+ "(RFC 2911 section 4.1.15).", attr->name,
+ attr->values[i].resolution.xres,
+ attr->values[i].resolution.yres,
+ attr->values[i].resolution.units ==
+ IPP_RES_PER_INCH ? "dpi" :
+ attr->values[i].resolution.units ==
+ IPP_RES_PER_CM ? "dpcm" : "unknown");
}
if (attr->values[i].resolution.yres <= 0)
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad resolution value %dx%d%s - feed "
- "resolution must be positive (RFC 2911 section "
- "4.1.13).", attr->name,
- attr->values[i].resolution.xres,
- attr->values[i].resolution.yres,
- attr->values[i].resolution.units ==
- IPP_RES_PER_INCH ? "dpi" :
- attr->values[i].resolution.units ==
- IPP_RES_PER_CM ? "dpc" : "unknown");
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad resolution value %dx%d%s - feed "
+ "resolution must be positive "
+ "(RFC 2911 section 4.1.15).", attr->name,
+ attr->values[i].resolution.xres,
+ attr->values[i].resolution.yres,
+ attr->values[i].resolution.units ==
+ IPP_RES_PER_INCH ? "dpi" :
+ attr->values[i].resolution.units ==
+ IPP_RES_PER_CM ? "dpcm" : "unknown");
}
if (attr->values[i].resolution.units != IPP_RES_PER_INCH &&
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad resolution value %dx%d%s - bad "
- "units value (RFC 2911 section 4.1.13).",
- attr->name, attr->values[i].resolution.xres,
- attr->values[i].resolution.yres,
- attr->values[i].resolution.units ==
- IPP_RES_PER_INCH ? "dpi" :
- attr->values[i].resolution.units ==
- IPP_RES_PER_CM ? "dpc" : "unknown");
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad resolution value %dx%d%s - bad "
+ "units value (RFC 2911 section 4.1.15).",
+ attr->name, attr->values[i].resolution.xres,
+ attr->values[i].resolution.yres,
+ attr->values[i].resolution.units ==
+ IPP_RES_PER_INCH ? "dpi" :
+ attr->values[i].resolution.units ==
+ IPP_RES_PER_CM ? "dpcm" : "unknown");
}
}
break;
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad rangeOfInteger value %d-%d - lower "
- "greater than upper (RFC 2911 section 4.1.13).",
- attr->name, attr->values[i].range.lower,
- attr->values[i].range.upper);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad rangeOfInteger value %d-%d - lower "
+ "greater than upper (RFC 2911 section 4.1.13).",
+ attr->name, attr->values[i].range.lower,
+ attr->values[i].range.upper);
}
}
break;
colattr;
colattr = colattr->next)
{
- if (!validate_attr(colattr, 0))
+ if (!validate_attr(outfile, NULL, colattr))
{
valid = 0;
break;
}
}
- if (colattr && print)
+ if (colattr && errors)
{
- print_test_error("\"%s\": Bad collection value.", attr->name);
+ add_stringf(errors, "\"%s\": Bad collection value.", attr->name);
while (colattr)
{
- validate_attr(colattr, print);
+ validate_attr(outfile, errors, colattr);
colattr = colattr->next;
}
}
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad text value \"%s\" - bad UTF-8 "
- "sequence (RFC 2911 section 4.1.1).", attr->name,
- attr->values[i].string.text);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad text value \"%s\" - bad UTF-8 "
+ "sequence (RFC 2911 section 4.1.1).", attr->name,
+ attr->values[i].string.text);
}
- if ((ptr - attr->values[i].string.text) > 1023)
+ if ((ptr - attr->values[i].string.text) > (IPP_MAX_TEXT - 1))
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad text value \"%s\" - bad length %d "
- "(RFC 2911 section 4.1.1).", attr->name,
- attr->values[i].string.text,
- (int)strlen(attr->values[i].string.text));
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad text value \"%s\" - bad length %d "
+ "(RFC 2911 section 4.1.1).", attr->name,
+ attr->values[i].string.text,
+ (int)strlen(attr->values[i].string.text));
}
}
break;
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad name value \"%s\" - bad UTF-8 "
- "sequence (RFC 2911 section 4.1.2).", attr->name,
- attr->values[i].string.text);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad name value \"%s\" - bad UTF-8 "
+ "sequence (RFC 2911 section 4.1.2).", attr->name,
+ attr->values[i].string.text);
}
- if ((ptr - attr->values[i].string.text) > 1023)
+ if ((ptr - attr->values[i].string.text) > (IPP_MAX_NAME - 1))
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad name value \"%s\" - bad length %d "
- "(RFC 2911 section 4.1.2).", attr->name,
- attr->values[i].string.text,
- (int)strlen(attr->values[i].string.text));
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad name value \"%s\" - bad length %d "
+ "(RFC 2911 section 4.1.2).", attr->name,
+ attr->values[i].string.text,
+ (int)strlen(attr->values[i].string.text));
}
}
break;
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad keyword value \"%s\" - invalid "
- "character (RFC 2911 section 4.1.3).",
- attr->name, attr->values[i].string.text);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad keyword value \"%s\" - invalid "
+ "character (RFC 2911 section 4.1.3).",
+ attr->name, attr->values[i].string.text);
}
- if ((ptr - attr->values[i].string.text) > 255)
+ if ((ptr - attr->values[i].string.text) > (IPP_MAX_KEYWORD - 1))
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad keyword value \"%s\" - bad "
- "length %d (RFC 2911 section 4.1.3).",
- attr->name, attr->values[i].string.text,
- (int)strlen(attr->values[i].string.text));
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad keyword value \"%s\" - bad "
+ "length %d (RFC 2911 section 4.1.3).",
+ attr->name, attr->values[i].string.text,
+ (int)strlen(attr->values[i].string.text));
}
}
break;
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad URI value \"%s\" - %s "
- "(RFC 2911 section 4.1.5).", attr->name,
- attr->values[i].string.text,
- URIStatusStrings[uri_status -
- HTTP_URI_OVERFLOW]);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad URI value \"%s\" - %s "
+ "(RFC 2911 section 4.1.5).", attr->name,
+ attr->values[i].string.text,
+ httpURIStatusString(uri_status));
}
- if (strlen(attr->values[i].string.text) > 1023)
+ if (strlen(attr->values[i].string.text) > (IPP_MAX_URI - 1))
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad URI value \"%s\" - bad length %d "
- "(RFC 2911 section 4.1.5).", attr->name,
- attr->values[i].string.text,
- (int)strlen(attr->values[i].string.text));
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad URI value \"%s\" - bad length %d "
+ "(RFC 2911 section 4.1.5).", attr->name,
+ attr->values[i].string.text,
+ (int)strlen(attr->values[i].string.text));
}
}
break;
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad uriScheme value \"%s\" - bad "
- "characters (RFC 2911 section 4.1.6).",
- attr->name, attr->values[i].string.text);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad uriScheme value \"%s\" - bad "
+ "characters (RFC 2911 section 4.1.6).",
+ attr->name, attr->values[i].string.text);
}
- if ((ptr - attr->values[i].string.text) > 63)
+ if ((ptr - attr->values[i].string.text) > (IPP_MAX_URISCHEME - 1))
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad uriScheme value \"%s\" - bad "
- "length %d (RFC 2911 section 4.1.6).",
- attr->name, attr->values[i].string.text,
- (int)strlen(attr->values[i].string.text));
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad uriScheme value \"%s\" - bad "
+ "length %d (RFC 2911 section 4.1.6).",
+ attr->name, attr->values[i].string.text,
+ (int)strlen(attr->values[i].string.text));
}
}
break;
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad charset value \"%s\" - bad "
- "characters (RFC 2911 section 4.1.7).",
- attr->name, attr->values[i].string.text);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad charset value \"%s\" - bad "
+ "characters (RFC 2911 section 4.1.7).",
+ attr->name, attr->values[i].string.text);
}
- if ((ptr - attr->values[i].string.text) > 40)
+ if ((ptr - attr->values[i].string.text) > (IPP_MAX_CHARSET - 1))
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad charset value \"%s\" - bad "
- "length %d (RFC 2911 section 4.1.7).",
- attr->name, attr->values[i].string.text,
- (int)strlen(attr->values[i].string.text));
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad charset value \"%s\" - bad "
+ "length %d (RFC 2911 section 4.1.7).",
+ attr->name, attr->values[i].string.text,
+ (int)strlen(attr->values[i].string.text));
}
}
break;
char temp[256]; /* Temporary error string */
regerror(i, &re, temp, sizeof(temp));
- print_fatal_error("Unable to compile naturalLanguage regular "
+ print_fatal_error(outfile, "Unable to compile naturalLanguage regular "
"expression: %s.", temp);
+ break;
}
for (i = 0; i < attr->num_values; i ++)
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad naturalLanguage value \"%s\" - bad "
- "characters (RFC 2911 section 4.1.8).",
- attr->name, attr->values[i].string.text);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad naturalLanguage value \"%s\" - bad "
+ "characters (RFC 2911 section 4.1.8).",
+ attr->name, attr->values[i].string.text);
}
- if (strlen(attr->values[i].string.text) > 63)
+ if (strlen(attr->values[i].string.text) > (IPP_MAX_LANGUAGE - 1))
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad naturalLanguage value \"%s\" - bad "
- "length %d (RFC 2911 section 4.1.8).",
- attr->name, attr->values[i].string.text,
- (int)strlen(attr->values[i].string.text));
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad naturalLanguage value \"%s\" - bad "
+ "length %d (RFC 2911 section 4.1.8).",
+ attr->name, attr->values[i].string.text,
+ (int)strlen(attr->values[i].string.text));
}
}
char temp[256]; /* Temporary error string */
regerror(i, &re, temp, sizeof(temp));
- print_fatal_error("Unable to compile mimeMediaType regular "
+ print_fatal_error(outfile, "Unable to compile mimeMediaType regular "
"expression: %s.", temp);
+ break;
}
for (i = 0; i < attr->num_values; i ++)
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad mimeMediaType value \"%s\" - bad "
- "characters (RFC 2911 section 4.1.9).",
- attr->name, attr->values[i].string.text);
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad mimeMediaType value \"%s\" - bad "
+ "characters (RFC 2911 section 4.1.9).",
+ attr->name, attr->values[i].string.text);
}
- if (strlen(attr->values[i].string.text) > 255)
+ if (strlen(attr->values[i].string.text) > (IPP_MAX_MIMETYPE - 1))
{
valid = 0;
- if (print)
- print_test_error("\"%s\": Bad mimeMediaType value \"%s\" - bad "
- "length %d (RFC 2911 section 4.1.9).",
- attr->name, attr->values[i].string.text,
- (int)strlen(attr->values[i].string.text));
- else
- break;
+ add_stringf(errors,
+ "\"%s\": Bad mimeMediaType value \"%s\" - bad "
+ "length %d (RFC 2911 section 4.1.9).",
+ attr->name, attr->values[i].string.text,
+ (int)strlen(attr->values[i].string.text));
}
}
+
+ regfree(&re);
break;
default :
*/
static int /* O - 1 on match, 0 on non-match */
-with_value(char *value, /* I - Value string */
- int regex, /* I - Value is a regular expression */
+with_value(FILE *outfile, /* I - Output file */
+ cups_array_t *errors, /* I - Errors array */
+ char *value, /* I - Value string */
+ int flags, /* I - Flags for match */
ipp_attribute_t *attr, /* I - Attribute to compare */
- int report) /* I - 1 = report failures */
+ char *matchbuf, /* I - Buffer to hold matching value */
+ size_t matchlen) /* I - Length of match buffer */
{
- int i; /* Looping var */
- char *valptr; /* Pointer into value */
+ int i, /* Looping var */
+ match; /* Match? */
+ char temp[1024], /* Temporary value string */
+ *valptr; /* Pointer into value */
+ *matchbuf = '\0';
+ match = (flags & _CUPS_WITH_ALL) ? 1 : 0;
+
/*
* NULL matches everything.
*/
{
char op, /* Comparison operator */
*nextptr; /* Next pointer */
- int intvalue; /* Integer value */
-
+ int intvalue, /* Integer value */
+ valmatch = 0; /* Does the current value match? */
valptr = value;
- if (!strncmp(valptr, "no-value,", 9))
- valptr += 9;
while (isspace(*valptr & 255) || isdigit(*valptr & 255) ||
*valptr == '-' || *valptr == ',' || *valptr == '<' ||
if (!*valptr)
break;
- intvalue = strtol(valptr, &nextptr, 0);
+ intvalue = (int)strtol(valptr, &nextptr, 0);
if (nextptr == valptr)
break;
valptr = nextptr;
- switch (op)
+ if ((op == '=' && attr->values[i].integer == intvalue) ||
+ (op == '<' && attr->values[i].integer < intvalue) ||
+ (op == '>' && attr->values[i].integer > intvalue))
{
- case '=' :
- if (attr->values[i].integer == intvalue)
- return (1);
- break;
- case '<' :
- if (attr->values[i].integer < intvalue)
- return (1);
- break;
- case '>' :
- if (attr->values[i].integer > intvalue)
- return (1);
- break;
+ if (!matchbuf[0])
+ snprintf(matchbuf, matchlen, "%d", attr->values[i].integer);
+
+ valmatch = 1;
+ break;
}
}
+
+ if (flags & _CUPS_WITH_ALL)
+ {
+ if (!valmatch)
+ {
+ match = 0;
+ break;
+ }
+ }
+ else if (valmatch)
+ {
+ match = 1;
+ break;
+ }
}
- if (report)
+ if (!match && errors)
{
for (i = 0; i < attr->num_values; i ++)
- print_test_error("GOT: %s=%d", attr->name, attr->values[i].integer);
+ add_stringf(errors, "GOT: %s=%d", attr->name,
+ attr->values[i].integer);
}
break;
{
char op, /* Comparison operator */
*nextptr; /* Next pointer */
- int intvalue; /* Integer value */
-
+ int intvalue, /* Integer value */
+ valmatch = 0; /* Does the current value match? */
valptr = value;
- if (!strncmp(valptr, "no-value,", 9))
- valptr += 9;
while (isspace(*valptr & 255) || isdigit(*valptr & 255) ||
*valptr == '-' || *valptr == ',' || *valptr == '<' ||
if (!*valptr)
break;
- intvalue = strtol(valptr, &nextptr, 0);
+ intvalue = (int)strtol(valptr, &nextptr, 0);
if (nextptr == valptr)
break;
valptr = nextptr;
- switch (op)
+ if ((op == '=' && (attr->values[i].range.lower == intvalue ||
+ attr->values[i].range.upper == intvalue)) ||
+ (op == '<' && attr->values[i].range.upper < intvalue) ||
+ (op == '>' && attr->values[i].range.upper > intvalue))
{
- case '=' :
- if (attr->values[i].range.lower == intvalue ||
- attr->values[i].range.upper == intvalue)
- return (1);
- break;
- case '<' :
- if (attr->values[i].range.upper < intvalue)
- return (1);
- break;
- case '>' :
- if (attr->values[i].range.upper > intvalue)
- return (1);
- break;
+ if (!matchbuf[0])
+ snprintf(matchbuf, matchlen, "%d-%d",
+ attr->values[0].range.lower,
+ attr->values[0].range.upper);
+
+ valmatch = 1;
+ break;
}
}
+
+ if (flags & _CUPS_WITH_ALL)
+ {
+ if (!valmatch)
+ {
+ match = 0;
+ break;
+ }
+ }
+ else if (valmatch)
+ {
+ match = 1;
+ break;
+ }
}
- if (report)
+ if (!match && errors)
{
for (i = 0; i < attr->num_values; i ++)
- print_test_error("GOT: %s=%d-%d", attr->name,
+ add_stringf(errors, "GOT: %s=%d-%d", attr->name,
attr->values[i].range.lower,
attr->values[i].range.upper);
}
for (i = 0; i < attr->num_values; i ++)
{
if (!strcmp(value, "true") == attr->values[i].boolean)
- return (1);
+ {
+ if (!matchbuf[0])
+ strlcpy(matchbuf, value, matchlen);
+
+ if (!(flags & _CUPS_WITH_ALL))
+ {
+ match = 1;
+ break;
+ }
+ }
+ else if (flags & _CUPS_WITH_ALL)
+ {
+ match = 0;
+ break;
+ }
}
- if (report)
+ if (!match && errors)
{
for (i = 0; i < attr->num_values; i ++)
- print_test_error("GOT: %s=%s", attr->name,
+ add_stringf(errors, "GOT: %s=%s", attr->name,
attr->values[i].boolean ? "true" : "false");
}
break;
+ case IPP_TAG_RESOLUTION :
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ if (attr->values[i].resolution.xres ==
+ attr->values[i].resolution.yres)
+ snprintf(temp, sizeof(temp), "%d%s",
+ attr->values[i].resolution.xres,
+ attr->values[i].resolution.units == IPP_RES_PER_INCH ?
+ "dpi" : "dpcm");
+ else
+ snprintf(temp, sizeof(temp), "%dx%d%s",
+ attr->values[i].resolution.xres,
+ attr->values[i].resolution.yres,
+ attr->values[i].resolution.units == IPP_RES_PER_INCH ?
+ "dpi" : "dpcm");
+
+ if (!strcmp(value, temp))
+ {
+ if (!matchbuf[0])
+ strlcpy(matchbuf, value, matchlen);
+
+ if (!(flags & _CUPS_WITH_ALL))
+ {
+ match = 1;
+ break;
+ }
+ }
+ else if (flags & _CUPS_WITH_ALL)
+ {
+ match = 0;
+ break;
+ }
+ }
+
+ if (!match && errors)
+ {
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ if (attr->values[i].resolution.xres ==
+ attr->values[i].resolution.yres)
+ snprintf(temp, sizeof(temp), "%d%s",
+ attr->values[i].resolution.xres,
+ attr->values[i].resolution.units == IPP_RES_PER_INCH ?
+ "dpi" : "dpcm");
+ else
+ snprintf(temp, sizeof(temp), "%dx%d%s",
+ attr->values[i].resolution.xres,
+ attr->values[i].resolution.yres,
+ attr->values[i].resolution.units == IPP_RES_PER_INCH ?
+ "dpi" : "dpcm");
+
+ if (strcmp(value, temp))
+ add_stringf(errors, "GOT: %s=%s", attr->name, temp);
+ }
+ }
+ break;
+
case IPP_TAG_NOVALUE :
- return (!strcmp(value, "no-value") || !strncmp(value, "no-value,", 9));
+ case IPP_TAG_UNKNOWN :
+ return (1);
case IPP_TAG_CHARSET :
case IPP_TAG_KEYWORD :
case IPP_TAG_TEXTLANG :
case IPP_TAG_URI :
case IPP_TAG_URISCHEME :
- if (regex)
+ if (flags & _CUPS_WITH_REGEX)
{
/*
* Value is an extended, case-sensitive POSIX regular expression...
if ((i = regcomp(&re, value, REG_EXTENDED | REG_NOSUB)) != 0)
{
- char temp[256]; /* Temporary string */
-
regerror(i, &re, temp, sizeof(temp));
- print_fatal_error("Unable to compile WITH-VALUE regular expression "
+ print_fatal_error(outfile, "Unable to compile WITH-VALUE regular expression "
"\"%s\" - %s", value, temp);
return (0);
}
for (i = 0; i < attr->num_values; i ++)
{
- if (regexec(&re, attr->values[i].string.text, 0, NULL, 0))
+ if (!regexec(&re, get_string(attr, i, flags, temp, sizeof(temp)),
+ 0, NULL, 0))
{
- if (report)
- print_test_error("GOT: %s=\"%s\"", attr->name,
- attr->values[i].string.text);
- else
+ if (!matchbuf[0])
+ strlcpy(matchbuf,
+ get_string(attr, i, flags, temp, sizeof(temp)),
+ matchlen);
+
+ if (!(flags & _CUPS_WITH_ALL))
+ {
+ match = 1;
break;
+ }
+ }
+ else if (flags & _CUPS_WITH_ALL)
+ {
+ match = 0;
+ break;
}
}
regfree(&re);
-
- return (i == attr->num_values);
}
else
{
/*
- * Value is a literal string, see if at least one value matches the
- * literal string...
+ * Value is a literal string, see if the value(s) match...
*/
for (i = 0; i < attr->num_values; i ++)
{
- if (!strcmp(value, attr->values[i].string.text))
- return (1);
- }
+ if (!strcmp(value, get_string(attr, i, flags, temp, sizeof(temp))))
+ {
+ if (!matchbuf[0])
+ strlcpy(matchbuf,
+ get_string(attr, i, flags, temp, sizeof(temp)),
+ matchlen);
- if (report)
- {
- for (i = 0; i < attr->num_values; i ++)
- print_test_error("GOT: %s=\"%s\"", attr->name,
- attr->values[i].string.text);
+ if (!(flags & _CUPS_WITH_ALL))
+ {
+ match = 1;
+ break;
+ }
+ }
+ else if (flags & _CUPS_WITH_ALL)
+ {
+ match = 0;
+ break;
+ }
}
}
+
+ if (!match && errors)
+ {
+ for (i = 0; i < attr->num_values; i ++)
+ add_stringf(errors, "GOT: %s=\"%s\"", attr->name,
+ attr->values[i].string.text);
+ }
break;
default :
break;
}
- return (0);
+ return (match);
}