/*
* "$Id$"
*
- * ipptool command for CUPS.
+ * ipptool command for CUPS.
*
- * Copyright 2007-2012 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.
- * add_stringf() - Add a formatted string to an array.
- * 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_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>
-#ifndef WIN32
+#ifdef WIN32
+# define R_OK 0
+#else
# include <signal.h>
#endif /* WIN32 */
#ifndef O_BINARY
{
_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_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 ****/
{
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 */
* 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 */
PassCount = 0, /* Number of passing tests */
FailCount = 0, /* Number of failing tests */
SkipCount = 0; /* Number of skipped tests */
-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"
-};
+static char *Password = NULL; /* Password from URI */
/*
static ipp_t *get_collection(_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);
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 ++)
{
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 (vars.filename)
+ {
free(vars.filename);
+ vars.filename = NULL;
+ }
if (access(argv[i], 0))
{
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 if (!_cups_strcasecmp(ext, ".ps") ||
!_cups_strcasecmp(ext, ".ps.gz"))
set_variable(&vars, "filetype", "application/postscript");
- else if (!_cups_strcasecmp(ext, ".ras") ||
+ else if (!_cups_strcasecmp(ext, ".pwg") ||
+ !_cups_strcasecmp(ext, ".pwg.gz") ||
+ !_cups_strcasecmp(ext, ".ras") ||
!_cups_strcasecmp(ext, ".ras.gz"))
set_variable(&vars, "filetype", "image/pwg-raster");
else if (!_cups_strcasecmp(ext, ".txt") ||
_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);
}
{
while (repeat > 1)
{
- usleep(interval);
+ usleep((useconds_t)interval);
do_tests(&vars, testfile);
repeat --;
}
{
for (;;)
{
- usleep(interval);
+ usleep((useconds_t)interval);
do_tests(&vars, testfile);
}
}
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 */
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;
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("Missing FILE-ID value on line %d.", linenum);
+ pass = 0;
+ goto test_exit;
+ }
+
+ continue;
+ }
else if (!strcmp(token, "IGNORE-ERRORS"))
{
/*
{
pass = 0;
- if (!IgnoreErrors)
+ if (StopAfterIncludeError)
goto test_exit;
}
}
{
pass = 0;
- if (!IgnoreErrors)
+ if (StopAfterIncludeError)
goto test_exit;
}
}
{
pass = 0;
- if (!IgnoreErrors)
+ if (StopAfterIncludeError)
goto test_exit;
}
}
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("Missing STOP-AFTER-INCLUDE-ERROR value on line %d.",
+ linenum);
+ pass = 0;
+ goto test_exit;
+ }
+
+ continue;
+ }
else if (!strcmp(token, "TRANSFER"))
{
/*
filename[0] = '\0';
skip_previous = 0;
skip_test = 0;
+ test_id[0] = '\0';
version = Version;
transfer = Transfer;
compression[0] = '\0';
_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") &&
+ 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") &&
if (col)
{
- 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);
- 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 ++;
- }
+ ippSetCollection(request, &lastcol, ippGetCount(lastcol), col);
+ }
else
{
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("Missing SKIP-IF-MISSING filename on line %d.",
+ linenum);
+ pass = 0;
+ goto test_exit;
+ }
+ }
else if (!strcmp(token, "SKIP-IF-NOT-DEFINED"))
{
/*
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("Missing TEST-ID value on line %d.", linenum);
+ pass = 0;
+ goto test_exit;
+ }
+
+ continue;
+ }
else if (!strcmp(token, "TRANSFER"))
{
/*
* 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);
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,
linenum);
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);
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,
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 (!_cups_strcasecmp(token, "true"))
attrptr = ippAddBoolean(request, group, attr, 1);
else
- attrptr = 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, ','))
- attrptr = 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 ++;
}
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 ||
}
if (!_cups_strcasecmp(ptr, "dpi"))
- attrptr = ippAddResolution(request, group, attr, IPP_RES_PER_INCH,
- 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);
+ attrptr = ippAddResolution(request, group, attr, IPP_RES_PER_CM, xres, yres);
else
- attrptr = ippAddResolution(request, group, attr, (ipp_res_t)0,
- xres, yres);
+ attrptr = ippAddResolution(request, group, attr, (ipp_res_t)0, xres, yres);
}
break;
break;
case IPP_TAG_STRING :
- attrptr = ippAddOctetString(request, group, attr, token,
- strlen(token));
+ attrptr = ippAddOctetString(request, group, attr, token, (int)strlen(token));
break;
default :
expand_variables(vars, token, temp, sizeof(token));
get_filename(testfile, filename, token, sizeof(filename));
+
+ if (access(filename, R_OK))
+ {
+ print_fatal_error("Filename \"%s\" on line %d cannot be read.",
+ temp, linenum);
+ print_fatal_error("Filename mapped to \"%s\".", filename);
+ pass = 0;
+ goto test_exit;
+ }
}
else if (!_cups_strcasecmp(token, "STATUS"))
{
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,
linenum);
last_status = statuses + num_statuses;
num_statuses ++;
+ 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;
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("DEFINE-MATCH without a preceding EXPECT or STATUS "
+ "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("DEFINE-NO-MATCH without a preceding EXPECT or "
+ "STATUS 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("DEFINE-VALUE without a preceding EXPECT on "
+ "line %d.", linenum);
pass = 0;
goto test_exit;
}
}
}
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 (!_cups_strcasecmp(token, "WITH-ALL-VALUES") && last_expect)
- last_expect->with_flags = _CUPS_WITH_ALL;
+ 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))
{
* WITH-VALUE is a POSIX extended regular expression.
*/
- last_expect->with_value = calloc(1, tokenptr - token);
+ 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
{
TestCount ++;
- 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;
+ 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);
+ if (file_id[0])
+ {
+ puts("<key>FileId</key>");
+ print_xml_string("string", file_id);
+ }
+ if (test_id[0])
+ {
+ puts("<key>TestId</key>");
+ print_xml_string("string", test_id);
+ }
+ puts("<key>Version</key>");
+ printf("<string>%d.%d</string>\n", version / 10, version % 10);
puts("<key>Operation</key>");
print_xml_string("string", ippOpString(op));
+ puts("<key>RequestId</key>");
+ printf("<integer>%d</integer>\n", request_id);
puts("<key>RequestAttributes</key>");
puts("<array>");
if (request->attrs)
{
puts("<dict>");
- for (attrptr = request->attrs, group = attrptr->group_tag;
+ for (attrptr = request->attrs,
+ group = attrptr ? attrptr->group_tag : IPP_TAG_ZERO;
attrptr;
attrptr = attrptr->next)
print_attr(attrptr, &group);
*/
while ((bytes = cupsFileRead(reqfile, buffer, sizeof(buffer))) > 0)
- length += bytes;
+ length += (size_t)bytes;
cupsFileClose(reqfile);
}
if ((reqfile = cupsFileOpen(filename, "r")) != NULL)
{
while (!Cancel &&
- (bytes = cupsFileRead(reqfile, buffer,
- sizeof(buffer))) > 0)
- if ((status = cupsWriteRequestData(http, buffer,
- bytes)) != HTTP_CONTINUE)
+ (bytes = cupsFileRead(reqfile, buffer, sizeof(buffer))) > 0)
+ if ((status = cupsWriteRequestData(http, buffer, (size_t)bytes)) != HTTP_CONTINUE)
break;
cupsFileClose(reqfile);
else if (status != HTTP_OK)
{
httpFlush(http);
+
+ if (status == HTTP_STATUS_UNAUTHORIZED)
+ continue;
+
break;
}
}
a = cupsArrayNew((cups_array_func_t)strcmp, NULL);
- for (attrptr = response->attrs, group = attrptr->group_tag;
+ for (attrptr = response->attrs,
+ group = attrptr ? attrptr->group_tag : IPP_TAG_ZERO;
attrptr;
attrptr = attrptr->next)
{
repeat_count < statuses[i].repeat_limit)
repeat_test = 1;
- break;
+ if (statuses[i].define_match)
+ set_variable(vars, statuses[i].define_match, "1");
+
+ break;
}
- else if (statuses[i].repeat_no_match &&
- repeat_count < statuses[i].repeat_limit)
- repeat_test = 1;
+ else
+ {
+ if (statuses[i].repeat_no_match &&
+ repeat_count < statuses[i].repeat_limit)
+ repeat_test = 1;
+
+ if (statuses[i].define_no_match)
+ {
+ set_variable(vars, statuses[i].define_no_match, "1");
+ break;
+ }
+ }
}
if (i == num_statuses && num_statuses > 0)
fflush(stdout);
}
- sleep(repeat_interval);
+ sleep((unsigned)repeat_interval);
repeat_interval = _cupsNextDelay(repeat_interval, &repeat_prev);
if (Output == _CUPS_OUTPUT_TEST)
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;
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);
}
}
/* 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 (!_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 :
}
if (!_cups_strcasecmp(units, "dpi"))
- ippAddResolution(col, IPP_TAG_ZERO, attr, xres, yres,
- IPP_RES_PER_INCH);
+ 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, xres, yres,
- IPP_RES_PER_CM);
+ 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;
}
break;
case IPP_TAG_STRING :
- ippAddOctetString(col, IPP_TAG_ZERO, attr, token, strlen(token));
+ ippAddOctetString(col, IPP_TAG_ZERO, attr, token, (int)strlen(token));
break;
default :
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';
if (isspace(ch) || ch == '#')
break;
else if (bufptr < bufend)
- *bufptr++ = ch;
+ *bufptr++ = (char)ch;
if (ch == '#')
ungetc(ch, fp);
"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
puts("<plist version=\"1.0\">");
puts("<dict>");
+ puts("<key>ipptoolVersion</key>");
+ puts("<string>" CUPS_SVERSION "</string>");
puts("<key>Transfer</key>");
printf("<string>%s</string>\n",
Transfer == _CUPS_TRANSFER_AUTO ? "auto" :
*/
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);
}
"\"%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]);
+ httpURIStatusString(uri_status));
}
if (strlen(attr->values[i].string.text) > (IPP_MAX_URI - 1))
{
int i, /* Looping var */
match; /* Match? */
- char *valptr; /* Pointer into value */
+ char temp[1024], /* Temporary value string */
+ *valptr; /* Pointer into value */
*matchbuf = '\0';
if (!*valptr)
break;
- intvalue = strtol(valptr, &nextptr, 0);
+ intvalue = (int)strtol(valptr, &nextptr, 0);
if (nextptr == valptr)
break;
valptr = nextptr;
(op == '>' && attr->values[i].integer > intvalue))
{
if (!matchbuf[0])
- snprintf(matchbuf, matchlen, "%d",
- attr->values[i].integer);
+ snprintf(matchbuf, matchlen, "%d", attr->values[i].integer);
valmatch = 1;
break;
if (!*valptr)
break;
- intvalue = strtol(valptr, &nextptr, 0);
+ intvalue = (int)strtol(valptr, &nextptr, 0);
if (nextptr == valptr)
break;
valptr = nextptr;
}
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 :
case IPP_TAG_UNKNOWN :
return (1);
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 "
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 (!matchbuf[0])
- strlcpy(matchbuf, attr->values[i].string.text, matchlen);
+ strlcpy(matchbuf,
+ get_string(attr, i, flags, temp, sizeof(temp)),
+ matchlen);
if (!(flags & _CUPS_WITH_ALL))
{
for (i = 0; i < attr->num_values; i ++)
{
- if (!strcmp(value, attr->values[i].string.text))
+ if (!strcmp(value, get_string(attr, i, flags, temp, sizeof(temp))))
{
if (!matchbuf[0])
- strlcpy(matchbuf, attr->values[i].string.text, matchlen);
+ strlcpy(matchbuf,
+ get_string(attr, i, flags, temp, sizeof(temp)),
+ matchlen);
if (!(flags & _CUPS_WITH_ALL))
{
{
for (i = 0; i < attr->num_values; i ++)
add_stringf(errors, "GOT: %s=\"%s\"", attr->name,
- attr->values[i].string.text);
+ attr->values[i].string.text);
}
break;