typedef struct ipptool_test_s /**** Test Data ****/
{
/* Global Options */
+ _ipp_vars_t vars; /* Variables */
http_encryption_t encryption; /* Encryption for connection */
int family; /* Address family */
ipptool_output_t output; /* Output mode */
static int compare_uris(const char *a, const char *b);
static void copy_hex_string(char *buffer, unsigned char *data, int datalen, size_t bufsize);
static void *do_monitor_test(ipptool_test_t *data);
-static int do_test(_ipp_file_t *f, _ipp_vars_t *vars, ipptool_test_t *data);
-static int do_tests(const char *testfile, _ipp_vars_t *vars, ipptool_test_t *data);
+static int do_test(_ipp_file_t *f, ipptool_test_t *data);
+static int do_tests(const char *testfile, ipptool_test_t *data);
static int error_cb(_ipp_file_t *f, ipptool_test_t *data, const char *error);
static int expect_matches(ipptool_expect_t *expect, ipp_tag_t value_tag);
static char *get_filename(const char *testfile, char *dst, const char *src, size_t dstsize);
static const char *get_string(ipp_attribute_t *attr, int element, int flags, char *buffer, size_t bufsize);
static void init_data(ipptool_test_t *data);
static char *iso_date(const ipp_uchar_t *date);
-static int parse_monitor_printer_state(_ipp_file_t *f, _ipp_vars_t *vars, ipptool_test_t *data);
+static int parse_monitor_printer_state(_ipp_file_t *f, ipptool_test_t *data);
static void pause_message(const char *message);
static void print_attr(cups_file_t *outfile, ipptool_output_t output, ipp_attribute_t *attr, ipp_tag_t *group);
static void print_csv(ipptool_test_t *data, ipp_t *ipp, ipp_attribute_t *attr, int num_displayed, char **displayed, size_t *widths);
init_data(&data);
- _ippVarsInit(&vars, NULL, (_ipp_ferror_cb_t)error_cb, (_ipp_ftoken_cb_t)token_cb);
+ _ippVarsInit(&data.vars, NULL, (_ipp_ferror_cb_t)error_cb, (_ipp_ftoken_cb_t)token_cb);
- _ippVarsSet(&vars, "date-start", iso_date(ippTimeToDate(time(NULL))));
+ _ippVarsSet(&data.vars, "date-start", iso_date(ippTimeToDate(time(NULL))));
/*
* We need at least:
else
testfile = argv[i];
- if (!do_tests(testfile, &vars, &data))
+ if (!do_tests(testfile, &data))
status = 1;
}
}
while (repeat > 1)
{
usleep((useconds_t)interval);
- do_tests(testfile, &vars, &data);
+ do_tests(testfile, &data);
repeat --;
}
}
for (;;)
{
usleep((useconds_t)interval);
- do_tests(testfile, &vars, &data);
+ do_tests(testfile, &data);
}
}
do_monitor_printer_state(
ipptool_test_t *data) // I - Test data
{
+ int i; // Looping var
char scheme[32], // URI scheme
userpass[32], // URI username:password
host[256], // URI hostname/IP address
http_encryption_t encryption; // Encryption to use
http_t *http; // Connection to printer
ipp_t *request, // IPP request
- *response; // IPP response
- ipp_attribute_t *attr; // Current attribute
+ *response = NULL; // IPP response
+ http_status_t status; // Request status
+ ipp_attribute_t *found; // Found attribute
ipptool_expect_t *expect; // Current EXPECT test
+ char buffer[131072]; // Copy buffer
static const char *pattrs[] = // List of attributes we care about
{
"marker-change-time", // "marker-xxx" are a CUPS/AirPrint extension
while (!data->monitor_done && !Cancel)
{
// Poll the printer state...
+ if ((status = cupsSendRequest(http, request, resource, ippLength(request))) != HTTP_STATUS_ERROR)
+ {
+ response = cupsGetResponse(http, resource);
+ status = httpGetStatus(http);
+ }
+
+ if (!data->monitor_done && !Cancel && status == HTTP_STATUS_ERROR && httpError(data->http) != EINVAL &&
+#ifdef _WIN32
+ httpError(data->http) != WSAETIMEDOUT)
+#else
+ httpError(data->http) != ETIMEDOUT)
+#endif // _WIN32
+ {
+ if (httpReconnect2(http, 30000, NULL))
+ break;
+ }
+ else if (status == HTTP_STATUS_ERROR || status == HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED)
+ {
+ break;
+ }
+ else if (status != HTTP_STATUS_OK)
+ {
+ httpFlush(http);
+
+ if (status == HTTP_STATUS_UNAUTHORIZED)
+ continue;
+
+ break;
+ }
+
+ for (i = data->num_monitor_expects, expect = data->monitor_expects; i > 0; i --, expect ++)
+ {
+ if (expect->if_defined && !_ippVarsGet(&data->vars, expect->if_defined))
+ continue;
+
+ if (expect->if_not_defined && _ippVarsGet(&data->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, ippGetValueTag(found))) ||
+ (expect->in_group && ippGetGroupTag(found) != expect->in_group))
+ {
+ if (expect->define_no_match)
+ {
+ _ippVarsSet(&data->vars, expect->define_no_match, "1");
+ data->monitor_done = 1;
+ }
+ break;
+ }
+
+ if (found)
+ ippAttributeString(found, buffer, sizeof(buffer));
+
+ if (found && !with_value(data, NULL, expect->with_value, expect->with_flags, found, buffer, sizeof(buffer)))
+ {
+ if (expect->define_no_match)
+ {
+ _ippVarsSet(&data->vars, expect->define_no_match, "1");
+ data->monitor_done = 1;
+ }
+ break;
+ }
+
+ if (found && expect->count > 0 && ippGetCount(found) != expect->count)
+ {
+ if (expect->define_no_match)
+ {
+ _ippVarsSet(&data->vars, expect->define_no_match, "1");
+ data->monitor_done = 1;
+ }
+ break;
+ }
+
+ if (found && expect->define_match)
+ {
+ _ippVarsSet(&data->vars, expect->define_match, "1");
+ data->monitor_done = 1;
+ }
+
+ if (found && expect->define_value)
+ {
+ if (!expect->with_value)
+ {
+ int last = ippGetCount(found) - 1;
+ // Last element in attribute
+ switch (ippGetValueTag(found))
+ {
+ case IPP_TAG_ENUM :
+ case IPP_TAG_INTEGER :
+ snprintf(buffer, sizeof(buffer), "%d", ippGetInteger(found, last));
+ break;
+ case IPP_TAG_BOOLEAN :
+ if (ippGetBoolean(found, last))
+ strlcpy(buffer, "true", sizeof(buffer));
+ else
+ strlcpy(buffer, "false", sizeof(buffer));
+ break;
+
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_LANGUAGE :
+ case IPP_TAG_MIMETYPE :
+ case IPP_TAG_NAME :
+ case IPP_TAG_NAMELANG :
+ case IPP_TAG_TEXT :
+ case IPP_TAG_TEXTLANG :
+ case IPP_TAG_URI :
+ case IPP_TAG_URISCHEME :
+ strlcpy(buffer, ippGetString(found, last, NULL), sizeof(buffer));
+ break;
+ default :
+ ippAttributeString(found, buffer, sizeof(buffer));
+ break;
+ }
+ }
+
+ _ippVarsSet(&data->vars, expect->define_value, buffer);
+ data->monitor_done = 1;
+ }
+ }
+
+ ippDelete(response);
+ response = NULL;
// Sleep between requests...
if (data->monitor_done || Cancel)
// Close the connection to the printer and return...
httpClose(http);
ippDelete(request);
+ ippDelete(response);
return (NULL);
}
static int /* O - 1 on success, 0 on failure */
do_test(_ipp_file_t *f, /* I - IPP data file */
- _ipp_vars_t *vars, /* I - IPP variables */
ipptool_test_t *data) /* I - Test data */
{
goto skip_error;
}
- vars->password_tries = 0;
+ data->vars.password_tries = 0;
do
{
if ((attrptr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL)
{
snprintf(temp, sizeof(temp), "%d", ippGetInteger(attrptr, 0));
- _ippVarsSet(vars, "job-id", temp);
+ _ippVarsSet(&data->vars, "job-id", temp);
}
if ((attrptr = ippFindAttribute(response, "job-uri", IPP_TAG_URI)) != NULL)
- _ippVarsSet(vars, "job-uri", ippGetString(attrptr, 0, NULL));
+ _ippVarsSet(&data->vars, "job-uri", ippGetString(attrptr, 0, NULL));
if ((attrptr = ippFindAttribute(response, "notify-subscription-id", IPP_TAG_INTEGER)) != NULL)
{
snprintf(temp, sizeof(temp), "%d", ippGetInteger(attrptr, 0));
- _ippVarsSet(vars, "notify-subscription-id", temp);
+ _ippVarsSet(&data->vars, "notify-subscription-id", temp);
}
/*
for (i = 0, status_ok = 0; i < data->num_statuses; i ++)
{
if (data->statuses[i].if_defined &&
- !_ippVarsGet(vars, data->statuses[i].if_defined))
+ !_ippVarsGet(&data->vars, data->statuses[i].if_defined))
continue;
if (data->statuses[i].if_not_defined &&
- _ippVarsGet(vars, data->statuses[i].if_not_defined))
+ _ippVarsGet(&data->vars, data->statuses[i].if_not_defined))
continue;
if (ippGetStatusCode(response) == data->statuses[i].status)
repeat_test = 1;
if (data->statuses[i].define_match)
- _ippVarsSet(vars, data->statuses[i].define_match, "1");
+ _ippVarsSet(&data->vars, data->statuses[i].define_match, "1");
}
else
{
if (data->statuses[i].define_no_match)
{
- _ippVarsSet(vars, data->statuses[i].define_no_match, "1");
+ _ippVarsSet(&data->vars, data->statuses[i].define_no_match, "1");
status_ok = 1;
}
}
for (i = 0; i < data->num_statuses; i ++)
{
if (data->statuses[i].if_defined &&
- !_ippVarsGet(vars, data->statuses[i].if_defined))
+ !_ippVarsGet(&data->vars, data->statuses[i].if_defined))
continue;
if (data->statuses[i].if_not_defined &&
- _ippVarsGet(vars, data->statuses[i].if_not_defined))
+ _ippVarsGet(&data->vars, data->statuses[i].if_not_defined))
continue;
if (!data->statuses[i].repeat_match || repeat_count >= data->statuses[i].repeat_limit)
{
ipp_attribute_t *group_found; /* Found parent attribute for group tests */
- if (expect->if_defined && !_ippVarsGet(vars, expect->if_defined))
+ if (expect->if_defined && !_ippVarsGet(&data->vars, expect->if_defined))
continue;
if (expect->if_not_defined &&
- _ippVarsGet(vars, expect->if_not_defined))
+ _ippVarsGet(&data->vars, expect->if_not_defined))
continue;
if ((found = ippFindAttribute(response, expect->name, IPP_TAG_ZERO)) != NULL && expect->in_group && expect->in_group != ippGetGroupTag(found))
(group_found && expect->in_group && ippGetGroupTag(group_found) != expect->in_group))
{
if (expect->define_no_match)
- _ippVarsSet(vars, expect->define_no_match, "1");
+ _ippVarsSet(&data->vars, expect->define_no_match, "1");
else if (!expect->define_match && !expect->define_value)
{
if (found && expect->not_expect && !expect->with_value && !expect->with_value_from)
if (found && expect->with_value_from && !with_value_from(NULL, ippFindAttribute(response, expect->with_value_from, IPP_TAG_ZERO), found, buffer, sizeof(buffer)))
{
if (expect->define_no_match)
- _ippVarsSet(vars, expect->define_no_match, "1");
+ _ippVarsSet(&data->vars, expect->define_no_match, "1");
else if (!expect->define_match && !expect->define_value && ((!expect->repeat_match && !expect->repeat_no_match) || repeat_count >= expect->repeat_limit))
{
add_stringf(data->errors, "EXPECTED: %s WITH-VALUES-FROM %s", expect->name, expect->with_value_from);
else if (found && !with_value(data, NULL, expect->with_value, expect->with_flags, found, buffer, sizeof(buffer)))
{
if (expect->define_no_match)
- _ippVarsSet(vars, expect->define_no_match, "1");
+ _ippVarsSet(&data->vars, expect->define_no_match, "1");
else if (!expect->define_match && !expect->define_value &&
!expect->repeat_match && (!expect->repeat_no_match || repeat_count >= expect->repeat_limit))
{
if (found && expect->count > 0 && ippGetCount(found) != expect->count)
{
if (expect->define_no_match)
- _ippVarsSet(vars, expect->define_no_match, "1");
+ _ippVarsSet(&data->vars, expect->define_no_match, "1");
else if (!expect->define_match && !expect->define_value)
{
add_stringf(data->errors, "EXPECTED: %s COUNT %d (got %d)", expect->name,
if (!attrptr || ippGetCount(attrptr) != ippGetCount(found))
{
if (expect->define_no_match)
- _ippVarsSet(vars, expect->define_no_match, "1");
+ _ippVarsSet(&data->vars, expect->define_no_match, "1");
else if (!expect->define_match && !expect->define_value)
{
if (!attrptr)
}
if (found && expect->define_match)
- _ippVarsSet(vars, expect->define_match, "1");
+ _ippVarsSet(&data->vars, expect->define_match, "1");
if (found && expect->define_value)
{
}
}
- _ippVarsSet(vars, expect->define_value, buffer);
+ _ippVarsSet(&data->vars, expect->define_value, buffer);
}
if (found && expect->repeat_match &&
static int /* O - 1 on success, 0 on failure */
do_tests(const char *testfile, /* I - Test file to use */
- _ipp_vars_t *vars, /* I - Variables */
ipptool_test_t *data) /* I - Test data */
{
http_encryption_t encryption; /* Encryption mode */
* Connect to the printer/server...
*/
- if (!_cups_strcasecmp(vars->scheme, "https") || !_cups_strcasecmp(vars->scheme, "ipps") || vars->port == 443)
+ if (!_cups_strcasecmp(data->vars.scheme, "https") || !_cups_strcasecmp(data->vars.scheme, "ipps") || data->vars.port == 443)
encryption = HTTP_ENCRYPTION_ALWAYS;
else
encryption = data->encryption;
- if ((data->http = httpConnect2(vars->host, vars->port, NULL, data->family, encryption, 1, 30000, NULL)) == NULL)
+ if ((data->http = httpConnect2(data->vars.host, data->vars.port, NULL, data->family, encryption, 1, 30000, NULL)) == NULL)
{
- print_fatal_error(data, "Unable to connect to \"%s\" on port %d - %s", vars->host, vars->port, cupsLastErrorString());
+ print_fatal_error(data, "Unable to connect to \"%s\" on port %d - %s", data->vars.host, data->vars.port, cupsLastErrorString());
return (0);
}
* Run tests...
*/
- _ippFileParse(vars, testfile, (void *)data);
+ _ippFileParse(&data->vars, testfile, (void *)data);
/*
* Close connection and return...
static int /* O - 1 to continue, 0 to stop */
parse_monitor_printer_state(
_ipp_file_t *f, /* I - IPP file data */
- _ipp_vars_t *vars, /* I - IPP variables */
ipptool_test_t *data) /* I - Test data */
{
char token[256], /* Token string */
else
{
// Use the default printer URI...
- data->monitor_uri = strdup(vars->uri);
+ data->monitor_uri = strdup(data->vars.uri);
}
// Loop until we get a closing brace...
return (0);
}
- _ippVarsExpand(vars, value, temp, sizeof(value));
+ _ippVarsExpand(&data->vars, value, temp, sizeof(value));
if ((dval = _cupsStrScand(value, &ptr, localeconv())) < 0.0 || (*ptr && *ptr != ','))
{
* Expand any variables in the value and then save it.
*/
- _ippVarsExpand(vars, value, temp, sizeof(value));
+ _ippVarsExpand(&data->vars, value, temp, sizeof(value));
ptr = value + strlen(value) - 1;
if (!strcmp(token, "}"))
{
- return (do_test(f, vars, data));
+ return (do_test(f, data));
}
else if (!strcmp(token, "MONITOR-PRINTER-STATE"))
{
return (0);
}
- return (parse_monitor_printer_state(f, vars, data));
+ return (parse_monitor_printer_state(f, data));
}
else if (!strcmp(token, "COMPRESSION"))
{
*ptr = '\0';
data->repeat_interval = 5000000;
data->request_id ++;
- strlcpy(data->resource, vars->resource, sizeof(data->resource));
+ strlcpy(data->resource, data->vars.resource, sizeof(data->resource));
data->skip_previous = 0;
data->skip_test = 0;
data->num_statuses = 0;
inc_data.prev_pass = 1;
inc_data.show_header = 1;
- if (!do_tests(get_filename(f->filename, filename, temp, sizeof(filename)), vars, &inc_data) && data->stop_after_include_error)
+ if (!do_tests(get_filename(f->filename, filename, temp, sizeof(filename)), &inc_data) && data->stop_after_include_error)
{
data->pass = data->prev_pass = 0;
return (0);
inc_data.prev_pass = 1;
inc_data.show_header = 1;
- if (!do_tests(get_filename(f->filename, filename, temp, sizeof(filename)), vars, &inc_data) && data->stop_after_include_error)
+ if (!do_tests(get_filename(f->filename, filename, temp, sizeof(filename)), &inc_data) && data->stop_after_include_error)
{
data->pass = data->prev_pass = 0;
return (0);
inc_data.prev_pass = 1;
inc_data.show_header = 1;
- if (!do_tests(get_filename(f->filename, filename, temp, sizeof(filename)), vars, &inc_data) && data->stop_after_include_error)
+ if (!do_tests(get_filename(f->filename, filename, temp, sizeof(filename)), &inc_data) && data->stop_after_include_error)
{
data->pass = data->prev_pass = 0;
return (0);