From: msweet Date: Wed, 28 Sep 2011 22:40:47 +0000 (+0000) Subject: Merge changes from CUPS 1.6svn-r10024. X-Git-Tag: release-1.6.3~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b66acc5997aef82618b7333c4df665fbea9ba90;p=thirdparty%2Fcups.git Merge changes from CUPS 1.6svn-r10024. git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@3438 a1ca3aef-8c08-0410-bb20-df032aa958be --- diff --git a/CHANGES-IPPTOOL.txt b/CHANGES-IPPTOOL.txt new file mode 100644 index 0000000000..e107c3cff6 --- /dev/null +++ b/CHANGES-IPPTOOL.txt @@ -0,0 +1,53 @@ +CHANGES-IPPTOOL.txt - 2011-09-28 +-------------------------------- + +This file provides a list of changes to the ipptool binary distribution posted +on cups.org. + + +2011-09-28 + + - Test output now includes a summary and overall score at the end. + - The MATCH-VALUE predicate now correctly deals with a failed EXPECT + condition. + - The IPP/1.1 test suite now looks for legacy media names and uses them + if the corresponding PWG standard names are not present. + - The IPP/1.1 test suite now tests the Print-Job+Release-Job when the + printer supports the job-hold-until attribute, Hold-Job operation, and + Release-Job operation. + + +2011-09-21 + + - Fixes for HTTP chunking, timeout, and encryption issues reported by + various users. + - Greatly improved IPP tests with added IPP/2.2 tests. + - New test documents - 1-page and 4-page mixed A4/Letter PDF/PS and a + couple JPEGs. + - New REPEAT directives to programmatically repeat tests as needed. + + +2011-08-16 + + - The Windows version no longer requires Visual Studio to be installed. + - The Windows version now supports SSL. + - Added "ipps" URI support. + - Added a new "-T" option. + - Added support for fractional seconds for the -i option and DELAY + directive. + - Added support for authentication. + - Added DEFINE-MATCH, DEFINE-NO-MATCH, DEFINE-VALUE, IF-NOT-DEFINED, + IGNORE-ERRORS, SKIP-IF-DEFINED, SKIP-IF-NOT-DEFINED, + SKIP-PREVIOUS-ERROR directives. + - WITH-VALUE now supports variable expansion. + - Updated the IPP/1.1 conformance test to skip the "my-jobs different + user" test if the printer URI contains a username. + - Updated the IPP conformance tests to validate media, media-default, + and media-supported values. + - No longer error out if a Printer returns a different version number in + the response when the request contains the version 0.0. + + +2010-10-16 + + - Initial release of standalone binary. diff --git a/IPPTOOL.txt b/IPPTOOL.txt index 5e84ebf014..b0c671c2b5 100644 --- a/IPPTOOL.txt +++ b/IPPTOOL.txt @@ -1,6 +1,8 @@ -IPPTOOL.txt - 2011-09-14 +IPPTOOL.txt - 2011-09-28 ------------------------ +See the file CHANGES-IPPTOOL.txt for a list of changes to this software. + INTRODUCTION @@ -50,10 +52,10 @@ CONFORMANCE TESTS IPP/2.2. For a given printer URI, the following commands perform tests at each level: - ipptool -tf filename [options] printer-uri ipp-1.1.test - ipptool -tf filename [options] -V 2.0 printer-uri ipp-2.0.test - ipptool -tf filename [options] -V 2.1 printer-uri ipp-2.1.test - ipptool -tf filename [options] -V 2.2 printer-uri ipp-2.2.test + ipptool -tf filename [options] -I printer-uri ipp-1.1.test + ipptool -tf filename [options] -I -V 2.0 printer-uri ipp-2.0.test + ipptool -tf filename [options] -I -V 2.1 printer-uri ipp-2.1.test + ipptool -tf filename [options] -I -V 2.2 printer-uri ipp-2.2.test The filename must use a format supported by the printer; ipptool will guess the MIME media type using the extension, otherwise application/octet stream @@ -73,13 +75,17 @@ CONFORMANCE TESTS Print-by-reference (URL) printing can be tested by defining the document-uri variable to a URL, for example: - ipptool -tf filename -d document-uri=your-url printer-uri ipp-1.1.test + ipptool -tf filename -d document-uri=url -I printer-uri ipp-1.1.test The standard test files are available on cups.org under the "test" directory, for example: http://www.cups.org/test/document-a4.pdf + The "document" test files contain 4 pages each. Doing the IPP conformance + tests will will produce up to 90 pages on various media, depending on the + printer. + READING THE DOCUMENTATION @@ -97,6 +103,34 @@ GETTING SUPPORT AND OTHER RESOURCES See the CUPS web site at "http://www.cups.org/" for other resources. +REPORTING BUGS + + If you believe you have discovered a bug in ipptool, please fill out the + bug form at: + + http://www.cups.org/str.php + + Be sure to identify the version of CUPS and ipptool (if you downloaded the + standalone version) you are using, the printer (if any) and firmware + version, and include any files that apply. + + If you downloaded the standalone version of ipptool, please also re-run the + test with debug logging enabled. Run the following commands on Windows to + enable debug logging: + + set CUPS_DEBUG_LOG=ipptool.log + set CUPS_DEBUG_LEVEL=6 + + For Linux and Mac OS X use: + + CUPS_DEBUG_LOG=ipptool.log; export CUPS_DEBUG_LOG + CUPS_DEBUG_LEVEL=6; export CUPS_DEBUG_LEVEL + + Then when you run the ipptool command a new "ipptool.log" file will be + created with detailed information - attach this file to the bug you file + as well. + + LEGAL STUFF CUPS is Copyright 2007-2011 by Apple Inc. CUPS and the CUPS logo are @@ -104,8 +138,6 @@ LEGAL STUFF The MD5 Digest code is Copyright 1999 Aladdin Enterprises. - This software is based in part on the work of the Independent JPEG Group. - CUPS is provided under the terms of version 2 of the GNU General Public License and GNU Library General Public License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even diff --git a/backend/dnssd.c b/backend/dnssd.c index e8de61c254..fd86e08148 100644 --- a/backend/dnssd.c +++ b/backend/dnssd.c @@ -774,7 +774,7 @@ query_callback( datalen = *data++; - if (!datalen || (data + datalen) >= dataend) + if (!datalen || (data + datalen) > dataend) break; datanext = data + datalen; diff --git a/cups/http-support.c b/cups/http-support.c index 7c30f4d9f0..0d1f2b211f 100644 --- a/cups/http-support.c +++ b/cups/http-support.c @@ -1823,17 +1823,36 @@ http_resolve_cb( if ((value = TXTRecordGetValuePtr(txtLen, txtRecord, "rp", &valueLen)) != NULL) + { + if (((char *)value)[0] == '/') + { + /* + * "rp" value (incorrectly) has a leading slash already... + */ + + memcpy(rp, value, valueLen); + rp[valueLen] = '\0'; + } + else + { + /* + * Convert to resource by concatenating with a leading "/"... + */ + + rp[0] = '/'; + memcpy(rp + 1, value, valueLen); + rp[valueLen + 1] = '\0'; + } + } + else { /* - * Convert to resource by concatenating with a leading "/"... + * Default "rp" value is blank, mapping to a path of "/"... */ rp[0] = '/'; - memcpy(rp + 1, value, valueLen); - rp[valueLen + 1] = '\0'; + rp[1] = '\0'; } - else - rp[0] = '\0'; /* * Lookup the FQDN if needed... diff --git a/cups/http.c b/cups/http.c index d5dfd71e09..33307db463 100644 --- a/cups/http.c +++ b/cups/http.c @@ -3768,6 +3768,7 @@ http_set_credentials(http_t *http) /* I - Connection to server */ return (error); } # endif /* HAVE_CDSASSL && HAVE_SECCERTIFICATECOPYDATA */ +#endif /* HAVE_SSL */ /* @@ -3816,6 +3817,7 @@ http_set_wait(http_t *http) /* I - Connection to server */ } +#ifdef HAVE_SSL /* * 'http_setup_ssl()' - Set up SSL/TLS support on a connection. */ @@ -4263,10 +4265,8 @@ http_setup_ssl(http_t *http) /* I - Connection to server */ return (0); } -#endif /* HAVE_SSL */ -#ifdef HAVE_SSL /* * 'http_shutdown_ssl()' - Shut down SSL/TLS on a connection. */ diff --git a/cups/ipp-support.c b/cups/ipp-support.c index cbf144dbb7..a6c23f5556 100644 --- a/cups/ipp-support.c +++ b/cups/ipp-support.c @@ -371,6 +371,16 @@ _ippAttrString(ipp_attribute_t *attr, /* I - Attribute */ bufptr += strlen(ptr); break; } + else if (!strcmp(attr->name, "operations-supported")) + { + ptr = ippOpString(val->integer); + + if (buffer && bufptr < bufend) + strlcpy(bufptr, ptr, bufend - bufptr + 1); + + bufptr += strlen(ptr); + break; + } case IPP_TAG_INTEGER : if (buffer && bufptr < bufend) @@ -621,7 +631,7 @@ ippOpString(ipp_op_t op) /* I - Operation ID */ * No, build an "unknown-xxxx" operation string... */ - sprintf(cg->ipp_unknown, "unknown-%04x", op); + sprintf(cg->ipp_unknown, "0x%04x", op); return (cg->ipp_unknown); } @@ -639,6 +649,9 @@ ippOpValue(const char *name) /* I - Textual name */ int i; + if (!strncmp(name, "0x", 2)) + return ((ipp_op_t)strtol(name + 2, NULL, 16)); + for (i = 0; i < (sizeof(ipp_std_ops) / sizeof(ipp_std_ops[0])); i ++) if (!_cups_strcasecmp(name, ipp_std_ops[i])) return ((ipp_op_t)i); diff --git a/cups/request.c b/cups/request.c index 1f87e77f65..9d004c39b3 100644 --- a/cups/request.c +++ b/cups/request.c @@ -476,6 +476,8 @@ cupsGetResponse(http_t *http, /* I - Connection to server or @code CUPS_HTTP attr ? attr->values[0].string.text : ippErrorString(response->request.status.status_code), 0); } + else if (status == HTTP_ERROR) + _cupsSetError(IPP_INTERNAL_ERROR, strerror(http->error), 0); else if (status != HTTP_OK) _cupsSetHTTPError(status); diff --git a/man/ipptoolfile.man b/man/ipptoolfile.man index 6f65989106..c379c0477b 100644 --- a/man/ipptoolfile.man +++ b/man/ipptoolfile.man @@ -11,7 +11,7 @@ .\" 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/". .\" -.TH ipptoolfile 5 "CUPS" "13 September 2011" "Apple Inc." +.TH ipptoolfile 5 "CUPS" "28 September 2011" "Apple Inc." .SH NAME ipptoolfile \- ipptool file format @@ -251,7 +251,7 @@ effect of this predicate is that this EXPECT will never fail a test. .TP 5 DEFINE-VALUE variable-name Defines the variable to the value of the attribute when the EXPECT condition -matches. +matches. A side-effect of this predicate is that this EXPECT will never fail a test. .TP 5 IF-DEFINED variable-name Makes the EXPECT conditions apply only if the specified variable is defined. diff --git a/test/Dependencies b/test/Dependencies index 32891447ef..63cc5bd703 100644 --- a/test/Dependencies +++ b/test/Dependencies @@ -18,3 +18,5 @@ ipptool.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h ipptool.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h ipptool.o: ../cups/transcode.h ../cups/thread-private.h ipptool.o: ../cups/file-private.h ../cups/cups-private.h +xmltotest.o: ../cups/cups.h ../cups/file.h ../cups/versioning.h ../cups/ipp.h +xmltotest.o: ../cups/http.h ../cups/array.h ../cups/language.h diff --git a/test/Makefile b/test/Makefile index d4073abc10..f66b5dc659 100644 --- a/test/Makefile +++ b/test/Makefile @@ -44,7 +44,8 @@ TESTFILES = \ testfile.txt OBJS = \ ippserver.o \ - ipptool.o + ipptool.o \ + xmltotest.o TARGETS = \ ippserver \ ipptool \ @@ -180,6 +181,17 @@ ipptool-static: ipptool.o ../cups/$(LIBCUPSSTATIC) $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) +# +# xmltotest +# + +xmltotest: xmltotest.o ../cups/$(LIBUPSSTATIC) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ xmltotest.o ../cups/$(LIBCUPSSTATIC) \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) \ + -lmxml + + # # Dependencies... # diff --git a/test/ipp-1.1.test b/test/ipp-1.1.test index 5b56771812..12d6ea674a 100644 --- a/test/ipp-1.1.test +++ b/test/ipp-1.1.test @@ -203,6 +203,22 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" STATUS successful-ok + # Display some useful information to identify the test + DISPLAY printer-name + DISPLAY printer-make-and-model + DISPLAY color-supported + DISPLAY pages-per-minute + DISPLAY pages-per-minute-color + DISPLAY document-format-supported + DISPLAY finishings-supported + DISPLAY job-sheets-supported + DISPLAY media-supported + DISPLAY number-up-supported + DISPLAY operations-supported + DISPLAY print-quality-supported + DISPLAY reference-uri-schemes-supported + DISPLAY sizes-supported + # Job template attributes EXPECT ?copies-default OF-TYPE integer IN-GROUP printer-attributes-tag COUNT 1 WITH-VALUE >0 EXPECT ?copies-supported OF-TYPE rangeOfInteger IN-GROUP printer-attributes-tag @@ -238,9 +254,9 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" EXPECT document-format-supported WITH-VALUE "application/postscript" DEFINE-MATCH OPTIONAL_POSTSCRIPT EXPECT document-format-supported WITH-VALUE "image/jpeg" DEFINE-MATCH OPTIONAL_JPEG EXPECT job-sheets-supported WITH-VALUE "standard" DEFINE-MATCH OPTIONAL_STANDARD_SHEET - EXPECT media-supported WITH-VALUE "iso_a4_210x297mm" DEFINE-MATCH OPTIONAL_A4_MEDIA - EXPECT media-supported WITH-VALUE "na_letter_8.5x11in" DEFINE-MATCH OPTIONAL_LETTER_MEDIA - EXPECT media-supported WITH-VALUE "na_index-4x6_4x6in" DEFINE-MATCH OPTIONAL_4X6_MEDIA + EXPECT media-supported WITH-VALUE "/^(a4|iso-a4|iso_a4_210x297mm)$$/" DEFINE-VALUE OPTIONAL_A4_MEDIA + EXPECT media-supported WITH-VALUE "/^(letter|na-letter|na_letter_8.5x11in)$$/" DEFINE-VALUE OPTIONAL_LETTER_MEDIA + EXPECT media-supported WITH-VALUE "/^(index-4x6|na_index-4x6_4x6in)$$/" DEFINE-VALUE OPTIONAL_4X6_MEDIA EXPECT number-up-supported WITH-VALUE 2 DEFINE-MATCH OPTIONAL_2UP EXPECT print-quality WITH-VALUE 3 DEFINE-MATCH OPTIONAL_DRAFT_QUALITY EXPECT print-quality WITH-VALUE 4 DEFINE-MATCH OPTIONAL_NORMAL_QUALITY @@ -972,6 +988,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" { SKIP-IF-NOT-DEFINED OPTIONAL_CREATE_JOB SKIP-IF-NOT-DEFINED OPTIONAL_SEND_DOCUMENT + SKIP-PREVIOUS-ERROR yes NAME "RFC 2911 section 3.3.1: Send-Document Operation" OPERATION Send-Document @@ -1025,6 +1042,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" { SKIP-IF-NOT-DEFINED OPTIONAL_CREATE_JOB SKIP-IF-NOT-DEFINED OPTIONAL_SEND_DOCUMENT + SKIP-PREVIOUS-ERROR yes NAME "Send-Document missing last-document: Send-Document Operation" OPERATION Send-Document @@ -1045,6 +1063,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" { SKIP-IF-NOT-DEFINED OPTIONAL_CREATE_JOB SKIP-IF-NOT-DEFINED OPTIONAL_SEND_DOCUMENT + SKIP-PREVIOUS-ERROR yes NAME "RFC 2911 section 3.3.3: Cancel-Job Operation" OPERATION Cancel-Job @@ -1094,6 +1113,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" SKIP-IF-NOT-DEFINED OPTIONAL_CREATE_JOB SKIP-IF-NOT-DEFINED OPTIONAL_SEND_URI SKIP-IF-NOT-DEFINED document-uri + SKIP-PREVIOUS-ERROR yes NAME "RFC 2911 section 3.3.2: Send-URI Operation" OPERATION Send-URI @@ -1146,6 +1166,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" { SKIP-IF-NOT-DEFINED OPTIONAL_CREATE_JOB SKIP-IF-NOT-DEFINED OPTIONAL_SEND_URI + SKIP-PREVIOUS-ERROR yes NAME "Send-URI with bad URI: Send-URI Operation (bad URI)" OPERATION Send-URI @@ -1167,6 +1188,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" { SKIP-IF-NOT-DEFINED OPTIONAL_CREATE_JOB SKIP-IF-NOT-DEFINED OPTIONAL_SEND_URI + SKIP-PREVIOUS-ERROR yes NAME "Send-URI with bad URI: Cancel-Job Operation" OPERATION Cancel-Job @@ -1237,7 +1259,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/pdf GROUP job-attributes-tag - ATTR keyword media iso_a4_210x297mm + ATTR keyword media $OPTIONAL_A4_MEDIA FILE document-a4.pdf STATUS successful-ok @@ -1273,7 +1295,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/pdf GROUP job-attributes-tag - ATTR keyword media iso_a4_210x297mm + ATTR keyword media $OPTIONAL_A4_MEDIA ATTR keyword sides two-sided-long-edge FILE document-a4.pdf @@ -1309,7 +1331,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/pdf GROUP job-attributes-tag - ATTR keyword media na_letter_8.5x11in + ATTR keyword media $OPTIONAL_LETTER_MEDIA FILE document-letter.pdf STATUS successful-ok @@ -1345,7 +1367,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/pdf GROUP job-attributes-tag - ATTR keyword media na_letter_8.5x11in + ATTR keyword media $OPTIONAL_LETTER_MEDIA ATTR keyword sides two-sided-long-edge FILE document-letter.pdf @@ -1383,7 +1405,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/postscript GROUP job-attributes-tag - ATTR keyword media iso_a4_210x297mm + ATTR keyword media $OPTIONAL_LETTER_MEDIA FILE document-a4.ps STATUS successful-ok @@ -1419,7 +1441,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/postscript GROUP job-attributes-tag - ATTR keyword media iso_a4_210x297mm + ATTR keyword media $OPTIONAL_A4_MEDIA ATTR keyword sides two-sided-long-edge FILE document-a4.ps @@ -1455,7 +1477,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/postscript GROUP job-attributes-tag - ATTR keyword media na_letter_8.5x11in + ATTR keyword media $OPTIONAL_LETTER_MEDIA FILE document-letter.ps STATUS successful-ok @@ -1491,7 +1513,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/postscript GROUP job-attributes-tag - ATTR keyword media na_letter_8.5x11in + ATTR keyword media $OPTIONAL_LETTER_MEDIA ATTR keyword sides two-sided-long-edge FILE document-letter.ps @@ -1529,7 +1551,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format image/jpeg GROUP job-attributes-tag - ATTR keyword media iso_a4_210x297mm + ATTR keyword media $OPTIONAL_A4_MEDIA FILE color.jpg STATUS successful-ok @@ -1564,7 +1586,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format image/jpeg GROUP job-attributes-tag - ATTR keyword media na_letter_8.5x11in + ATTR keyword media $OPTIONAL_LETTER_MEDIA FILE color.jpg STATUS successful-ok @@ -1599,7 +1621,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format image/jpeg GROUP job-attributes-tag - ATTR keyword media na_index-4x6_4x6in + ATTR keyword media $OPTIONAL_4X6_MEDIA FILE color.jpg STATUS successful-ok @@ -1634,7 +1656,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format image/jpeg GROUP job-attributes-tag - ATTR keyword media iso_a4_210x297mm + ATTR keyword media $OPTIONAL_A4_MEDIA FILE gray.jpg STATUS successful-ok @@ -1669,7 +1691,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format image/jpeg GROUP job-attributes-tag - ATTR keyword media na_letter_8.5x11in + ATTR keyword media $OPTIONAL_LETTER_MEDIA FILE gray.jpg STATUS successful-ok @@ -1704,7 +1726,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format image/jpeg GROUP job-attributes-tag - ATTR keyword media na_index-4x6_4x6in + ATTR keyword media $OPTIONAL_4X6_MEDIA FILE gray.jpg STATUS successful-ok @@ -1742,7 +1764,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/pdf GROUP job-attributes-tag - ATTR keyword media iso_a4_210x297mm + ATTR keyword media $OPTIONAL_A4_MEDIA ATTR keyword job-sheets standard FILE document-a4.pdf @@ -1779,7 +1801,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/pdf GROUP job-attributes-tag - ATTR keyword media na_letter_8.5x11in + ATTR keyword media $OPTIONAL_LETTER_MEDIA ATTR keyword job-sheets standard FILE document-a4.pdf @@ -1816,7 +1838,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/postscript GROUP job-attributes-tag - ATTR keyword media iso_a4_210x297mm + ATTR keyword media $OPTIONAL_A4_MEDIA ATTR keyword job-sheets standard FILE document-a4.ps @@ -1853,7 +1875,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/postscript GROUP job-attributes-tag - ATTR keyword media na_letter_8.5x11in + ATTR keyword media $OPTIONAL_LETTER_MEDIA ATTR keyword job-sheets standard FILE document-a4.ps @@ -1892,7 +1914,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/pdf GROUP job-attributes-tag - ATTR keyword media iso_a4_210x297mm + ATTR keyword media $OPTIONAL_A4_MEDIA ATTR integer number-up 2 FILE document-a4.pdf @@ -1929,7 +1951,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/pdf GROUP job-attributes-tag - ATTR keyword media na_letter_8.5x11in + ATTR keyword media $OPTIONAL_LETTER_MEDIA ATTR integer number-up 2 FILE document-letter.pdf @@ -1966,7 +1988,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/postscript GROUP job-attributes-tag - ATTR keyword media iso_a4_210x297mm + ATTR keyword media $OPTIONAL_A4_MEDIA ATTR integer number-up 2 FILE document-a4.ps @@ -2003,7 +2025,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/postscript GROUP job-attributes-tag - ATTR keyword media na_letter_8.5x11in + ATTR keyword media $OPTIONAL_LETTER_MEDIA ATTR integer number-up 2 FILE document-letter.ps @@ -2042,7 +2064,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format image/jpeg GROUP job-attributes-tag - ATTR keyword media na_index-4x6_4x6in + ATTR keyword media $OPTIONAL_4X6_MEDIA ATTR enum print-quality 3 FILE color.jpeg @@ -2079,7 +2101,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format image/jpeg GROUP job-attributes-tag - ATTR keyword media na_index-4x6_4x6in + ATTR keyword media $OPTIONAL_4X6_MEDIA ATTR enum print-quality 4 FILE color.jpeg @@ -2116,7 +2138,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format image/jpeg GROUP job-attributes-tag - ATTR keyword media na_index-4x6_4x6in + ATTR keyword media $OPTIONAL_4X6_MEDIA ATTR enum print-quality 5 FILE color.jpeg @@ -2153,7 +2175,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/pdf GROUP job-attributes-tag - ATTR keyword media iso_a4_210x297mm + ATTR keyword media $OPTIONAL_A4_MEDIA ATTR enum print-quality 3 FILE document-a4.pdf @@ -2190,7 +2212,7 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" ATTR keyword compression none ATTR mimeMediaType document-format application/pdf GROUP job-attributes-tag - ATTR keyword media na_letter_8.5x11in + ATTR keyword media $OPTIONAL_LETTER_MEDIA ATTR enum print-quality 3 FILE document-letter.pdf @@ -2210,6 +2232,57 @@ DEFINE IPP_URI_SCHEME "/^ipps?://.+$$/" } +# Test hold/release in the context of Print-Job w/job-hold-until + Release-Job +{ + SKIP-IF-NOT-DEFINED OPTIONAL_HOLD_JOB + + NAME "Print-Job with job-hold-until" + OPERATION Print-Job + GROUP operation-attributes-tag + ATTR charset attributes-charset utf-8 + ATTR naturalLanguage attributes-natural-language en + ATTR uri printer-uri $uri + ATTR name requesting-user-name $user + ATTR name job-name "Test Document w/Hold" + ATTR name document-name $filename + ATTR keyword compression none + ATTR mimeMediaType document-format $filetype + GROUP job-attributes-tag + ATTR keyword job-hold-until indefinite + FILE $filename + + STATUS successful-ok + STATUS server-error-job-canceled + STATUS server-error-busy REPEAT-MATCH + + EXPECT job-uri OF-TYPE uri COUNT 1 IN-GROUP job-attributes-tag WITH-VALUE "$IPP_URI_SCHEME" + EXPECT job-id OF-TYPE integer COUNT 1 IN-GROUP job-attributes-tag + WITH-VALUE >0 + EXPECT job-state OF-TYPE enum COUNT 1 IN-GROUP job-attributes-tag + WITH-VALUE 3,4,5,6,7,8,9 + EXPECT job-state-reasons OF-TYPE keyword IN-GROUP job-attributes-tag + EXPECT ?job-state-message OF-TYPE text IN-GROUP job-attributes-tag + EXPECT ?number-of-intervening-jobs OF-TYPE integer + IN-GROUP job-attributes-tag WITH-VALUE >-1 +} + +{ + SKIP-IF-NOT-DEFINED OPTIONAL_HOLD_JOB + + NAME "Release-Job" + OPERATION Release-Job + GROUP operation-attributes-tag + ATTR charset attributes-charset utf-8 + ATTR naturalLanguage attributes-natural-language en + ATTR uri printer-uri $uri + ATTR integer job-id $job-id + ATTR name requesting-user-name $user + + STATUS successful-ok + STATUS client-error-not-possible +} + + # # End of "$Id$". # diff --git a/test/ipp-2.1.test b/test/ipp-2.1.test index 4993831fba..e8ddae4d11 100644 --- a/test/ipp-2.1.test +++ b/test/ipp-2.1.test @@ -14,7 +14,7 @@ # # Usage: # -# ./ipptool -V 2.1 {-d PRINTER_IS_COLOR=1} -f filename -t printer-uri ipp-2.1.test +# ./ipptool -V 2.1 -f filename -t printer-uri ipp-2.1.test # # Do all of the IPP/1.1 and IPP/2.0 tests as an IPP/2.1 client diff --git a/test/ipp-2.2.test b/test/ipp-2.2.test index d910c8be93..935a62da91 100644 --- a/test/ipp-2.2.test +++ b/test/ipp-2.2.test @@ -14,7 +14,7 @@ # # Usage: # -# ./ipptool -V 2.2 {-d PRINTER_IS_COLOR=1} -f filename -t printer-uri ipp-2.2.test +# ./ipptool -V 2.2 -f filename -t printer-uri ipp-2.2.test # # Do all of the IPP/1.1, IPP/2.0, and IPP/2.1 tests as an IPP/2.2 client diff --git a/test/ipptool.c b/test/ipptool.c index dbd847e7cb..de47d8fe5b 100644 --- a/test/ipptool.c +++ b/test/ipptool.c @@ -144,7 +144,11 @@ int Cancel = 0, /* Cancel test? */ IgnoreErrors = 0, /* Ignore errors? */ Verbosity = 0, /* Show all attributes? */ Version = 11, /* Default IPP version */ - XMLHeader = 0; /* 1 if header is written */ + 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 */ char *Password = NULL; /* Password from URI */ const char * const URIStatusStrings[] = /* URI status strings */ { @@ -202,7 +206,7 @@ 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); + int report, char *matchbuf, size_t matchlen); /* @@ -398,15 +402,30 @@ main(int argc, /* I - Number of command-line args */ if (vars.filename) free(vars.filename); - if (access(argv[i], 0) && argv[i][0] != '/') + if (access(argv[i], 0)) { - snprintf(filename, sizeof(filename), "%s/ipptool/%s", - cg->cups_datadir, argv[i]); - if (access(argv[i], 0)) - vars.filename = strdup(argv[i]); - else - vars.filename = strdup(filename); - } + /* + * Try filename.gz... + */ + + snprintf(filename, sizeof(filename), "%s.gz", argv[i]); + if (access(filename, 0) && filename[0] != '/') + { + 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(argv[i]); @@ -419,7 +438,9 @@ main(int argc, /* I - Number of command-line args */ if (!_cups_strcasecmp(ext, ".gif")) set_variable(&vars, "filetype", "image/gif"); else if (!_cups_strcasecmp(ext, ".htm") || - !_cups_strcasecmp(ext, ".html")) + !_cups_strcasecmp(ext, ".htm.gz") || + !_cups_strcasecmp(ext, ".html") || + !_cups_strcasecmp(ext, ".html.gz")) set_variable(&vars, "filetype", "text/html"); else if (!_cups_strcasecmp(ext, ".jpg")) set_variable(&vars, "filetype", "image/jpeg"); @@ -427,11 +448,14 @@ main(int argc, /* I - Number of command-line args */ set_variable(&vars, "filetype", "application/pdf"); else if (!_cups_strcasecmp(ext, ".png")) set_variable(&vars, "filetype", "image/png"); - else if (!_cups_strcasecmp(ext, ".ps")) + 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, ".ras") || + !_cups_strcasecmp(ext, ".ras.gz")) set_variable(&vars, "filetype", "image/pwg-raster"); - else if (!_cups_strcasecmp(ext, ".txt")) + else if (!_cups_strcasecmp(ext, ".txt") || + !_cups_strcasecmp(ext, ".txt.gz")) set_variable(&vars, "filetype", "text/plain"); else if (!_cups_strcasecmp(ext, ".xps")) set_variable(&vars, "filetype", "application/openxps"); @@ -627,6 +651,16 @@ main(int argc, /* I - Number of command-line args */ do_tests(&vars, testfile); } } + else if (Output == _CUPS_OUTPUT_TEST && 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... @@ -676,7 +710,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ *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 */ @@ -1054,6 +1088,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ last_expect = NULL; last_status = NULL; filename[0] = '\0'; + skip_previous = 0; skip_test = 0; version = Version; transfer = Transfer; @@ -2036,6 +2071,8 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ * Submit the IPP request... */ + TestCount ++; + request->request.op.version[0] = version / 10; request->request.op.version[1] = version % 10; request->request.op.operation_id = op; @@ -2077,6 +2114,8 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ if ((skip_previous && !prev_pass) || skip_test) { + SkipCount ++; + ippDelete(request); request = NULL; @@ -2117,20 +2156,16 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ length = ippLength(request); - if (filename[0]) + if (filename[0] && (reqfile = cupsFileOpen(filename, "r")) != NULL) { - struct stat fileinfo; /* File information */ + /* + * Read the file to get the uncompressed file size... + */ - if (stat(filename, &fileinfo)) - { - snprintf(buffer, sizeof(buffer), "%s: %s", filename, - strerror(errno)); - _cupsSetError(IPP_INTERNAL_ERROR, buffer, 0); + while ((bytes = cupsFileRead(reqfile, buffer, sizeof(buffer))) > 0) + length += bytes; - status = HTTP_ERROR; - } - else - length += fileinfo.st_size; + cupsFileClose(reqfile); } } @@ -2138,23 +2173,29 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ * Send the request... */ - response = NULL; + response = NULL; + repeat_test = 0; + prev_pass = 1; if (status != HTTP_ERROR) { - while (!response && !Cancel) + while (!response && !Cancel && prev_pass) { 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) + if ((reqfile = cupsFileOpen(filename, "r")) != NULL) { - while (!Cancel && (bytes = read(fd, buffer, sizeof(buffer))) > 0) + while (!Cancel && + (bytes = cupsFileRead(reqfile, buffer, + sizeof(buffer))) > 0) if ((status = cupsWriteRequestData(http, buffer, bytes)) != HTTP_CONTINUE) break; + + cupsFileClose(reqfile); } else { @@ -2184,13 +2225,14 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ #endif /* WIN32 */ { 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; - } + prev_pass = 0; + } + else if (status == HTTP_ERROR) + { + if (!Cancel) + httpReconnect(http); + + prev_pass = 0; } } } @@ -2199,9 +2241,6 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ * Check results of request... */ - repeat_test = 0; - prev_pass = 1; - if (!response) prev_pass = pass = 0; else @@ -2345,12 +2384,16 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ continue; } + if (found) + _ippAttrString(found, buffer, sizeof(buffer)); + if (found && - !with_value(expect->with_value, expect->with_regex, found, 0)) + !with_value(expect->with_value, expect->with_regex, found, 0, + buffer, sizeof(buffer))) { if (expect->define_no_match) set_variable(vars, expect->define_no_match, "1"); - else if (!expect->define_match) + else if (!expect->define_match && !expect->define_value) prev_pass = pass = 0; if (expect->repeat_no_match) @@ -2364,7 +2407,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ { if (expect->define_no_match) set_variable(vars, expect->define_no_match, "1"); - else if (!expect->define_match) + else if (!expect->define_match && !expect->define_value) prev_pass = pass = 0; if (expect->repeat_no_match) @@ -2382,7 +2425,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ { if (expect->define_no_match) set_variable(vars, expect->define_no_match, "1"); - else if (!expect->define_match) + else if (!expect->define_match && !expect->define_value) prev_pass = pass = 0; if (expect->repeat_no_match) @@ -2396,10 +2439,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ set_variable(vars, expect->define_match, "1"); if (found && expect->define_value) - { - _ippAttrString(found, token, sizeof(token)); - set_variable(vars, expect->define_value, token); - } + set_variable(vars, expect->define_value, buffer); if (found && expect->repeat_match) repeat_test = 1; @@ -2419,7 +2459,12 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ ippDelete(request); - request = NULL; + request = NULL; + + if (prev_pass) + PassCount ++; + else + FailCount ++; if (Output == _CUPS_OUTPUT_PLIST) { @@ -2701,7 +2746,8 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ for (i = num_expects, expect = expects; i > 0; i --, expect ++) { - if (expect->define_match || expect->define_no_match) + if (expect->define_match || expect->define_no_match || + expect->define_value) continue; if (expect->if_defined && !get_variable(vars, expect->if_defined)) @@ -2729,7 +2775,8 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ expect->name, ippTagString(expect->in_group), ippTagString(found->group_tag)); - if (!with_value(expect->with_value, expect->with_regex, found, 0)) + if (!with_value(expect->with_value, expect->with_regex, found, 0, + buffer, sizeof(buffer))) { if (expect->with_regex) print_test_error("EXPECTED: %s WITH-VALUE /%s/", @@ -2738,7 +2785,8 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ print_test_error("EXPECTED: %s WITH-VALUE \"%s\"", expect->name, expect->with_value); - with_value(expect->with_value, expect->with_regex, found, 1); + with_value(expect->with_value, expect->with_regex, found, 1, + buffer, sizeof(buffer)); } if (expect->count > 0 && found->num_values != expect->count) @@ -3509,146 +3557,149 @@ print_attr(ipp_attribute_t *attr, /* I - Attribute to print */ print_xml_string("key", attr->name); if (attr->num_values > 1) puts(""); - } - 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("%d\n", attr->values[i].integer); + else + printf("%d ", attr->values[i].integer); + break; - 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("%d\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 ? "" : ""); + else if (attr->values[i].boolean) + fputs("true ", stdout); + else + fputs("false ", stdout); + break; - case IPP_TAG_BOOLEAN : - for (i = 0; i < attr->num_values; i ++) - if (Output == _CUPS_OUTPUT_PLIST) - puts(attr->values[i].boolean ? "" : ""); - else if (attr->values[i].boolean) - fputs("true ", stdout); - else - fputs("false ", stdout); - break; + case IPP_TAG_RANGE : + for (i = 0; i < attr->num_values; i ++) + if (Output == _CUPS_OUTPUT_PLIST) + printf("lower%d" + "upper%d\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_RANGE : - for (i = 0; i < attr->num_values; i ++) - if (Output == _CUPS_OUTPUT_PLIST) - printf("lower%d" - "upper%d\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("xres%d" + "yres%d" + "units%s\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_RESOLUTION : - for (i = 0; i < attr->num_values; i ++) - if (Output == _CUPS_OUTPUT_PLIST) - printf("xres%d" - "yres%d" - "units%s\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("%s\n", iso_date(attr->values[i].date)); + else + printf("%s ", iso_date(attr->values[i].date)); + break; - case IPP_TAG_DATE : - for (i = 0; i < attr->num_values; i ++) - if (Output == _CUPS_OUTPUT_PLIST) - printf("%s\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; - 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; + case IPP_TAG_TEXTLANG : + case IPP_TAG_NAMELANG : + for (i = 0; i < attr->num_values; i ++) + if (Output == _CUPS_OUTPUT_PLIST) + { + fputs("language", stdout); + print_xml_string(NULL, attr->values[i].string.charset); + fputs("string", stdout); + print_xml_string(NULL, attr->values[i].string.text); + puts(""); + } + else + printf("\"%s\"(%s) ", attr->values[i].string.text, + attr->values[i].string.charset); + break; - case IPP_TAG_TEXTLANG : - case IPP_TAG_NAMELANG : - for (i = 0; i < attr->num_values; i ++) - if (Output == _CUPS_OUTPUT_PLIST) + case IPP_TAG_BEGIN_COLLECTION : + for (i = 0; i < attr->num_values; i ++) { - fputs("language", stdout); - print_xml_string(NULL, attr->values[i].string.charset); - fputs("string", stdout); - print_xml_string(NULL, attr->values[i].string.text); - puts(""); + if (Output == _CUPS_OUTPUT_PLIST) + { + puts(""); + for (colattr = attr->values[i].collection->attrs; + colattr; + colattr = colattr->next) + print_attr(colattr, NULL); + puts(""); + } + else + { + if (i) + putchar(' '); + + print_col(attr->values[i].collection); + } } - else - printf("\"%s\"(%s) ", attr->values[i].string.text, - attr->values[i].string.charset); - break; + break; - case IPP_TAG_BEGIN_COLLECTION : - for (i = 0; i < attr->num_values; i ++) - { + default : if (Output == _CUPS_OUTPUT_PLIST) - { - puts(""); - for (colattr = attr->values[i].collection->attrs; - colattr; - colattr = colattr->next) - print_attr(colattr, NULL); - puts(""); - } + printf("<<%s>>\n", + ippTagString(attr->value_tag)); else - { - if (i) - putchar(' '); - - print_col(attr->values[i].collection); - } - } - break; - - default : - if (Output == _CUPS_OUTPUT_PLIST) - printf("<<%s>>\n", - ippTagString(attr->value_tag)); - else - fputs(ippTagString(attr->value_tag), stdout); - break; - } + fputs(ippTagString(attr->value_tag), stdout); + break; + } - if (Output == _CUPS_OUTPUT_PLIST) - { if (attr->num_values > 1) puts(""); } else - putchar('\n'); + { + char buffer[8192]; /* Value buffer */ + + 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)); + } + + _ippAttrString(attr, buffer, sizeof(buffer)); + puts(buffer); + } } @@ -4176,6 +4227,9 @@ sigterm_handler(int sig) /* I - Signal number (unused) */ (void)sig; Cancel = 1; + + signal(SIGINT, SIG_DFL); + signal(SIGTERM, SIG_DFL); } #endif /* !WIN32 */ @@ -4969,12 +5023,16 @@ 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 */ ipp_attribute_t *attr, /* I - Attribute to compare */ - int report) /* I - 1 = report failures */ + 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 */ + *matchbuf = '\0'; + /* * NULL matches everything. */ @@ -5025,15 +5083,24 @@ with_value(char *value, /* I - Value string */ { case '=' : if (attr->values[i].integer == intvalue) + { + snprintf(matchbuf, matchlen, "%d", attr->values[i].integer); return (1); + } break; case '<' : if (attr->values[i].integer < intvalue) + { + snprintf(matchbuf, matchlen, "%d", attr->values[i].integer); return (1); + } break; case '>' : if (attr->values[i].integer > intvalue) + { + snprintf(matchbuf, matchlen, "%d", attr->values[i].integer); return (1); + } break; } } @@ -5083,15 +5150,30 @@ with_value(char *value, /* I - Value string */ case '=' : if (attr->values[i].range.lower == intvalue || attr->values[i].range.upper == intvalue) + { + snprintf(matchbuf, matchlen, "%d-%d", + attr->values[i].range.lower, + attr->values[i].range.upper); return (1); + } break; case '<' : if (attr->values[i].range.upper < intvalue) + { + snprintf(matchbuf, matchlen, "%d-%d", + attr->values[i].range.lower, + attr->values[i].range.upper); return (1); + } break; case '>' : - if (attr->values[i].range.upper > intvalue) + if (attr->values[i].range.lower > intvalue) + { + snprintf(matchbuf, matchlen, "%d-%d", + attr->values[i].range.lower, + attr->values[i].range.upper); return (1); + } break; } } @@ -5110,7 +5192,10 @@ with_value(char *value, /* I - Value string */ for (i = 0; i < attr->num_values; i ++) { if (!strcmp(value, "true") == attr->values[i].boolean) + { + strlcpy(matchbuf, value, matchlen); return (1); + } } if (report) @@ -5122,7 +5207,13 @@ with_value(char *value, /* I - Value string */ break; case IPP_TAG_NOVALUE : - return (!strcmp(value, "no-value") || !strncmp(value, "no-value,", 9)); + if (!strcmp(value, "no-value") || !strncmp(value, "no-value,", 9)) + { + strlcpy(matchbuf, "no-value", matchlen); + return (1); + } + else + return (0); case IPP_TAG_CHARSET : case IPP_TAG_KEYWORD : @@ -5171,6 +5262,9 @@ with_value(char *value, /* I - Value string */ regfree(&re); + if (i == attr->num_values) + strlcpy(matchbuf, attr->values[0].string.text, matchlen); + return (i == attr->num_values); } else @@ -5183,7 +5277,10 @@ with_value(char *value, /* I - Value string */ for (i = 0; i < attr->num_values; i ++) { if (!strcmp(value, attr->values[i].string.text)) + { + strlcpy(matchbuf, attr->values[i].string.text, matchlen); return (1); + } } if (report) diff --git a/test/xmltotest.c b/test/xmltotest.c new file mode 100644 index 0000000000..14ecf5748f --- /dev/null +++ b/test/xmltotest.c @@ -0,0 +1,518 @@ +/* + * "$Id$" + * + * IANA XML registration to test file generator for CUPS. + * + * Copyright 2011 by Apple Inc. + * + * 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. + * + * Usage: + * + * ./xmltotest [--ref standard] {--job|--printer} [XML file/URL] >file.test + * + * If not specified, loads the XML registrations from: + * + * http://www.iana.org/assignments/ipp-registrations/ipp-registrations.xml + * + * "Standard" is of the form "rfcNNNN" or "pwgNNNN.N". + * + * Contents: + * + * main() - Process command-line arguments. + * compare_reg() - Compare two registrations. + * load_xml() - Load the XML registration file or URL. + * match_xref() - Compare the xref against the named standard. + * new_reg() - Create a new registration record. + * usage() - Show usage message. + * write_expect() - Write an EXPECT test for an attribute. + */ + +#include +#include +#include +#include + + +/* + * Local types... + */ + +typedef struct _cups_reg_s /**** Registration data ****/ +{ + char *name, /* Attribute name */ + *member, /* Member attribute name */ + *sub_member, /* Sub-member attribute name */ + *syntax; /* Attribute syntax */ +} _cups_reg_t; + + +/* + * Local functions... + */ + +static int compare_reg(_cups_reg_t *a, _cups_reg_t *b); +static mxml_node_t *load_xml(const char *reg_file); +static int match_xref(mxml_node_t *xref, const char *standard); +static _cups_reg_t *new_reg(mxml_node_t *name, mxml_node_t *member, + mxml_node_t *sub_member, mxml_node_t *syntax); +static int usage(void); +static void write_expect(_cups_reg_t *reg, ipp_tag_t group); + + +/* + * 'main()' - Process command-line arguments. + */ + +int +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + const char *reg_file = NULL, /* Registration file/URL to use */ + *reg_standard = NULL; /* Which standard to extract */ + mxml_node_t *reg_xml, /* Registration XML data */ + *reg_2, /* ipp-registrations-2 */ + *reg_record, /* */ + *reg_collection, /* */ + *reg_name, /* */ + *reg_member, /* */ + *reg_sub_member, /* */ + *reg_syntax, /* */ + *reg_xref; /* */ + cups_array_t *attrs; /* Attribute registrations */ + _cups_reg_t *current; /* Current attribute registration */ + ipp_tag_t group = IPP_TAG_ZERO, /* Which attributes to test */ + reg_group; /* Group for registration */ + + + /* + * Parse command-line... + */ + + for (i = 1; i < argc; i ++) + { + if (!strcmp(argv[i], "--job") && group == IPP_TAG_ZERO) + group = IPP_TAG_JOB; + else if (!strcmp(argv[i], "--ref")) + { + i ++; + if (i >= argc) + return (usage()); + + reg_standard = argv[i]; + } + else if (!strcmp(argv[i], "--printer") && group == IPP_TAG_ZERO) + group = IPP_TAG_PRINTER; + else if (argv[i][0] == '-' || reg_file) + return (usage()); + else + reg_file = argv[i]; + } + + if (group == IPP_TAG_ZERO) + return (usage()); + + /* + * Read registrations... + */ + + if (!reg_file) + reg_file = "http://www.iana.org/assignments/ipp-registrations/" + "ipp-registrations.xml"; + + if ((reg_xml = load_xml(reg_file)) == NULL) + return (1); + + /* + * Scan registrations for attributes... + */ + + if ((reg_2 = mxmlFindElement(reg_xml, reg_xml, "registry", "id", + "ipp-registrations-2", + MXML_DESCEND)) == NULL) + { + fprintf(stderr, "xmltotest: No IPP attribute registrations in \"%s\".\n", + reg_file); + return (1); + } + + attrs = cupsArrayNew((cups_array_func_t)compare_reg, NULL); + + for (reg_record = mxmlFindElement(reg_2, reg_2, "record", NULL, NULL, + MXML_DESCEND); + reg_record; + reg_record = mxmlFindElement(reg_record, reg_2, "record", NULL, NULL, + MXML_NO_DESCEND)) + { + /* + * Get the values from the current record... + */ + + reg_collection = mxmlFindElement(reg_record, reg_record, "collection", + NULL, NULL, MXML_DESCEND); + reg_name = mxmlFindElement(reg_record, reg_record, "name", NULL, NULL, + MXML_DESCEND); + reg_member = mxmlFindElement(reg_record, reg_record, "member_attribute", + NULL, NULL, MXML_DESCEND); + reg_sub_member = mxmlFindElement(reg_record, reg_record, + "sub-member_attribute", NULL, NULL, + MXML_DESCEND); + reg_syntax = mxmlFindElement(reg_record, reg_record, "syntax", NULL, + NULL, MXML_DESCEND); + reg_xref = mxmlFindElement(reg_record, reg_record, "xref", NULL, NULL, + MXML_DESCEND); + + if (!reg_collection || !reg_name || !reg_syntax || !reg_xref) + continue; + + /* + * Filter based on group and standard... + */ + + if (!strcmp(reg_collection->child->value.opaque, "Printer Description")) + reg_group = IPP_TAG_PRINTER; + else if (!strcmp(reg_collection->child->value.opaque, "Job Description")) + reg_group = IPP_TAG_JOB; + else if (!strcmp(reg_collection->child->value.opaque, "Job Template")) + { + if (strstr(reg_name->child->value.opaque, "-default") || + strstr(reg_name->child->value.opaque, "-supported")) + reg_group = IPP_TAG_PRINTER; + else + reg_group = IPP_TAG_JOB; + } + else + reg_group = IPP_TAG_ZERO; + + if (reg_group != group) + continue; + + if (reg_standard && !match_xref(reg_xref, reg_standard)) + continue; + + /* + * Add the record to the array... + */ + + if ((current = new_reg(reg_name, reg_member, reg_sub_member, + reg_syntax)) != NULL) + cupsArrayAdd(attrs, current); + } + + /* + * Write out a test for all of the selected attributes... + */ + + puts("{"); + + if (group == IPP_TAG_PRINTER) + { + puts("\tOPERATION Get-Printer-Attributes"); + puts("\tGROUP operation-attributes-tag"); + puts("\tATTR charset attributes-charset utf-8"); + puts("\tATTR naturalLanguage attributes-natural-language en"); + puts("\tATTR uri printer-uri $uri"); + puts("\tATTR name requesting-user-name $user"); + puts("\tATTR keyword requested-attributes all,media-col-database"); + puts(""); + puts("\tSTATUS successful-ok"); + puts("\tSTATUS successful-ok-ignored-or-substituted-attributes"); + puts(""); + } + else + { + puts("\tOPERATION Get-Job-Attributes"); + puts("\tGROUP operation-attributes-tag"); + puts("\tATTR charset attributes-charset utf-8"); + puts("\tATTR naturalLanguage attributes-natural-language en"); + puts("\tATTR uri printer-uri $uri"); + puts("\tATTR integer job-id $job-id"); + puts("\tATTR name requesting-user-name $user"); + puts(""); + puts("\tSTATUS successful-ok"); + puts(""); + } + + for (current = cupsArrayFirst(attrs); + current; + current = cupsArrayNext(attrs)) + write_expect(current, group); + + puts("}"); + + return (0); +} + + +/* + * 'compare_reg()' - Compare two registrations. + */ + +static int /* O - Result of comparison */ +compare_reg(_cups_reg_t *a, /* I - First registration */ + _cups_reg_t *b) /* I - Second registration */ +{ + int retval; /* Return value */ + + + if ((retval = strcmp(a->name, b->name)) != 0) + return (retval); + + if (a->member && b->member) + retval = strcmp(a->member, b->member); + else if (a->member) + retval = 1; + else if (b->member) + retval = -1; + + if (retval) + return (retval); + + if (a->sub_member && b->sub_member) + retval = strcmp(a->sub_member, b->sub_member); + else if (a->sub_member) + retval = 1; + else if (b->sub_member) + retval = -1; + + return (retval); +} + + +/* + * 'load_xml()' - Load the XML registration file or URL. + */ + +static mxml_node_t * /* O - XML file or NULL */ +load_xml(const char *reg_file) /* I - Filename or URL */ +{ + mxml_node_t *xml; /* XML file */ + char scheme[256], /* Scheme */ + userpass[256], /* Username and password */ + hostname[256], /* Hostname */ + resource[1024], /* Resource path */ + filename[1024]; /* Temporary file */ + int port, /* Port number */ + fd; /* File descriptor */ + + + if (httpSeparateURI(HTTP_URI_CODING_ALL, reg_file, scheme, sizeof(scheme), + userpass, sizeof(userpass), hostname, sizeof(hostname), + &port, resource, sizeof(resource)) < HTTP_URI_OK) + { + fprintf(stderr, "xmltotest: Bad URI or filename \"%s\".\n", reg_file); + return (NULL); + } + + if (!strcmp(scheme, "file")) + { + /* + * Local file... + */ + + if ((fd = open(resource, O_RDONLY)) < 0) + { + fprintf(stderr, "xmltotest: Unable to open \"%s\": %s\n", resource, + strerror(errno)); + return (NULL); + } + + filename[0] = '\0'; + } + else if (strcmp(scheme, "http") && strcmp(scheme, "https")) + { + fprintf(stderr, "xmltotest: Unsupported URI scheme \"%s\".\n", scheme); + return (NULL); + } + else + { + http_t *http; /* HTTP connection */ + http_encryption_t encryption; /* Encryption to use */ + http_status_t status; /* Status of HTTP GET */ + + if (!strcmp(scheme, "https") || port == 443) + encryption = HTTP_ENCRYPT_ALWAYS; + else + encryption = HTTP_ENCRYPT_IF_REQUESTED; + + if ((http = httpConnectEncrypt(hostname, port, encryption)) == NULL) + { + fprintf(stderr, "xmltotest: Unable to connect to \"%s\": %s\n", hostname, + cupsLastErrorString()); + return (NULL); + } + + if ((fd = cupsTempFd(filename, sizeof(filename))) < 0) + { + fprintf(stderr, "xmltotest: Unable to create temporary file: %s\n", + strerror(errno)); + httpClose(http); + return (NULL); + } + + status = cupsGetFd(http, resource, fd); + httpClose(http); + + if (status != HTTP_OK) + { + fprintf(stderr, "mxmltotest: Unable to get \"%s\": %d\n", reg_file, + status); + close(fd); + unlink(filename); + return (NULL); + } + + lseek(fd, 0, SEEK_SET); + } + + /* + * Load the XML file... + */ + + xml = mxmlLoadFd(NULL, fd, MXML_OPAQUE_CALLBACK); + + close(fd); + + if (filename[0]) + unlink(filename); + + return (xml); +} + + +/* + * 'match_xref()' - Compare the xref against the named standard. + */ + +static int /* O - 1 if match, 0 if not */ +match_xref(mxml_node_t *xref, /* I - node */ + const char *standard) /* I - Name of standard */ +{ + const char *data; /* "data" attribute */ + char s[256]; /* String to look for */ + + + if ((data = mxmlElementGetAttr(xref, "data")) == NULL) + return (1); + + if (!strcmp(data, standard)) + return (1); + + if (!strncmp(standard, "pwg", 3)) + { + snprintf(s, sizeof(s), "-%s.pdf", standard + 3); + return (strstr(data, s) != NULL); + } + else + return (0); +} + + +/* + * 'new_reg()' - Create a new registration record. + */ + +static _cups_reg_t * /* O - New record */ +new_reg(mxml_node_t *name, /* I - Attribute name */ + mxml_node_t *member, /* I - Member attribute, if any */ + mxml_node_t *sub_member, /* I - Sub-member attribute, if any */ + mxml_node_t *syntax) /* I - Syntax */ +{ + _cups_reg_t *reg; /* New record */ + + + if ((reg = calloc(1, sizeof(_cups_reg_t))) != NULL) + { + reg->name = name->child->value.opaque; + reg->syntax = syntax->child->value.opaque; + + if (member) + reg->member = member->child->value.opaque; + + if (sub_member) + reg->sub_member = sub_member->child->value.opaque; + } + + return (reg); +} + + +/* + * 'usage()' - Show usage message. + */ + +static int /* O - Exit status */ +usage(void) +{ + puts("Usage ./xmltotest [--ref standard] {--job|--printer} [XML file/URL] " + ">file.test"); + return (1); +} + + +/* + * 'write_expect()' - Write an EXPECT test for an attribute. + */ + +static void +write_expect(_cups_reg_t *reg, /* I - Registration information */ + ipp_tag_t group) /* I - Attribute group tag */ +{ + const char *syntax; /* Pointer into syntax string */ + int single = 1, /* Single valued? */ + skip = 0; /* Skip characters? */ + + + printf("\tEXPECT ?%s OF-TYPE ", reg->name); + + syntax = reg->syntax; + + while (*syntax) + { + if (!strncmp(syntax, "1setOf", 6)) + { + single = 0; + syntax += 6; + + while (isspace(*syntax & 255)) + syntax ++; + + if (*syntax == '(') + syntax ++; + } + else if (!strncmp(syntax, "type1", 5) || !strncmp(syntax, "type2", 5) || + !strncmp(syntax, "type3", 5)) + syntax += 5; + else if (*syntax == '(') + { + skip = 1; + syntax ++; + } + else if (*syntax == ')') + { + skip = 0; + syntax ++; + } + else if (!skip && (*syntax == '|' || isalpha(*syntax & 255))) + putchar(*syntax++); + else + syntax ++; + } + + if (single) + printf(" IN-GROUP %s COUNT 1\n", ippTagString(group)); + else + printf(" IN-GROUP %s\n", ippTagString(group)); +} + + +/* + * End of "$Id$". + */ diff --git a/tools/makeipptoolpkg b/tools/makeipptoolpkg index 46fdf2fa6e..ba471ca066 100644 --- a/tools/makeipptoolpkg +++ b/tools/makeipptoolpkg @@ -27,11 +27,9 @@ if test $# = 0; then echo Updating to get snapshot version... svn up rev=`svnversion . | sed -e '1,$s/[a-zA-Z]//g'` - fileversion="1.5svn-r$rev" - version=snapshots + fileversion="`date '+%Y%m%d'`-r$rev" else fileversion=$1 - version=$1 fi if (svn st | grep -qv '^\?'); then @@ -47,13 +45,19 @@ test -d $pkgdir && rm -r $pkgdir mkdir $pkgdir || exit 1 echo Copying package files -cp IPPTOOL.txt LICENSE.txt $pkgdir +cp CHANGES-IPPTOOL.txt IPPTOOL.txt LICENSE.txt $pkgdir cp doc/help/man-ipptool*.html $pkgdir +cp test/color.jpg $pkgdir cp test/create-printer-subscription.test $pkgdir +cp test/document-*.pdf $pkgdir +cp test/document-*.ps $pkgdir cp test/get-completed-jobs.test test/get-jobs.test $pkgdir cp test/get-printer-attributes.test $pkgdir +cp test/gray.jpg $pkgdir cp test/ipp-[12].*.test $pkgdir cp test/ipptool-static $pkgdir/ipptool +cp test/onepage-*.pdf $pkgdir +cp test/onepage-*.ps $pkgdir cp test/testfile.* $pkgdir if test `uname` = Darwin; then @@ -69,9 +73,9 @@ else fi if test -x /usr/bin/md5sum; then - (md5sum $pkgfile | awk '{print $1, "'$fileversion' cups/'$version'/" $2}') + (md5sum $pkgfile | awk '{print $1, "'$fileversion' cups/ipptool/" $2}') elif test -x /sbin/md5; then - (md5 $pkgfile | awk '{print $4, "'$fileversion' cups/'$version'/" substr($2, 2, length($2) - 2)}') + (md5 $pkgfile | awk '{print $4, "'$fileversion' cups/ipptool/" substr($2, 2, length($2) - 2)}') fi echo Removing temporary files...