11/*
22 * ipptool command for CUPS.
33 *
4- * Copyright © 2021-2022 by OpenPrinting.
4+ * Copyright © 2021-2023 by OpenPrinting.
55 * Copyright © 2020 by The Printer Working Group.
66 * Copyright © 2007-2021 by Apple Inc.
77 * Copyright © 1997-2007 by Easy Software Products.
4545 * Types...
4646 */
4747
48- typedef enum ipptool_transfer_e /**** How to send request data ****/
48+ typedef enum ipptool_content_e /**** Content Validation ****/
4949{
50- IPPTOOL_TRANSFER_AUTO , /* Chunk for files, length for static */
51- IPPTOOL_TRANSFER_CHUNKED , /* Chunk always */
52- IPPTOOL_TRANSFER_LENGTH /* Length always */
53- } ipptool_transfer_t ;
50+ IPPTOOL_CONTENT_NONE , /* No content validation */
51+ IPPTOOL_CONTENT_AVAILABLE , /* Accessible resource */
52+ IPPTOOL_CONTENT_VALID , /* Valid resource */
53+ IPPTOOL_CONTENT_VALID_ICON /* Valid icon resource */
54+ } ipptool_content_t ;
5455
5556typedef enum ipptool_output_e /**** Output mode ****/
5657{
@@ -63,6 +64,13 @@ typedef enum ipptool_output_e /**** Output mode ****/
6364 IPPTOOL_OUTPUT_JSON /* JSON output */
6465} ipptool_output_t ;
6566
67+ typedef enum ipptool_transfer_e /**** How to send request data ****/
68+ {
69+ IPPTOOL_TRANSFER_AUTO , /* Chunk for files, length for static */
70+ IPPTOOL_TRANSFER_CHUNKED , /* Chunk always */
71+ IPPTOOL_TRANSFER_LENGTH /* Length always */
72+ } ipptool_transfer_t ;
73+
6674typedef enum ipptool_with_e /**** WITH flags ****/
6775{
6876 IPPTOOL_WITH_LITERAL = 0 , /* Match string is a literal value */
@@ -89,6 +97,9 @@ typedef struct ipptool_expect_s /**** Expected attribute info ****/
8997 * define_no_match , /* Variable to define on no-match */
9098 * define_value , /* Variable to define with value */
9199 * display_match ; /* Message to display on a match */
100+ ipptool_content_t with_content ; /* WITH-*-CONTENT value */
101+ cups_array_t * with_mime_types ; /* WITH-*-MIME-TYPES value(s) */
102+ char * save_filespec ; /* SAVE-*-CONTENT filespec */
92103 int repeat_limit ; /* Maximum number of times to repeat */
93104 bool repeat_match , /* Repeat test on match */
94105 repeat_no_match , /* Repeat test on no match */
@@ -246,6 +257,7 @@ static void sigterm_handler(int sig);
246257static bool timeout_cb (http_t * http , void * user_data );
247258static bool token_cb (ipp_file_t * f , ipptool_test_t * data , const char * token );
248259static void usage (void ) _CUPS_NORETURN ;
260+ static bool with_content (cups_array_t * errors , ipp_attribute_t * attr , ipptool_content_t content , cups_array_t * mime_types , const char * filespec );
249261static bool with_distinct_values (cups_array_t * errors , ipp_attribute_t * attr );
250262static const char * with_flags_string (int flags );
251263static bool with_value (ipptool_test_t * data , cups_array_t * errors , char * value , int flags , ipp_attribute_t * attr , char * matchbuf , size_t matchlen );
@@ -848,6 +860,8 @@ clear_data(ipptool_test_t *data) // I - Test data
848860 free (expect -> define_no_match );
849861 free (expect -> define_value );
850862 free (expect -> display_match );
863+ cupsArrayDelete (expect -> with_mime_types );
864+ free (expect -> save_filespec );
851865 }
852866 data -> num_expects = 0 ;
853867
@@ -1926,12 +1940,22 @@ do_test(ipp_file_t *f, /* I - IPP data file */
19261940
19271941 if (expect -> repeat_no_match && repeat_count < expect -> repeat_limit )
19281942 repeat_test = true;
1929- break ;
1943+
1944+ continue ;
19301945 }
19311946
19321947 if (found )
19331948 ippAttributeString (found , data -> buffer , sizeof (data -> buffer ));
19341949
1950+ if (found && (expect -> with_content || expect -> with_mime_types || expect -> save_filespec ) && !with_content (exp_errors , found , expect -> with_content , expect -> with_mime_types , expect -> save_filespec ))
1951+ {
1952+ if (expect -> define_no_match )
1953+ {
1954+ ippFileSetVar (data -> parent , expect -> define_no_match , "1" );
1955+ exp_pass = true;
1956+ }
1957+ }
1958+
19351959 if (found && expect -> with_value_from && !with_value_from (NULL , ippFindAttribute (response , expect -> with_value_from , IPP_TAG_ZERO ), found , data -> buffer , sizeof (data -> buffer )))
19361960 {
19371961 if (expect -> define_no_match )
@@ -1949,7 +1973,7 @@ do_test(ipp_file_t *f, /* I - IPP data file */
19491973 if (expect -> repeat_no_match && repeat_count < expect -> repeat_limit )
19501974 repeat_test = true;
19511975
1952- break ;
1976+ continue ;
19531977 }
19541978 else if (found && !with_value (data , NULL , expect -> with_value , expect -> with_flags , found , data -> buffer , sizeof (data -> buffer )))
19551979 {
@@ -1972,7 +1996,7 @@ do_test(ipp_file_t *f, /* I - IPP data file */
19721996 if (expect -> repeat_no_match && repeat_count < expect -> repeat_limit )
19731997 repeat_test = true;
19741998
1975- break ;
1999+ continue ;
19762000 }
19772001 else if (expect -> with_value )
19782002 {
@@ -1994,7 +2018,7 @@ do_test(ipp_file_t *f, /* I - IPP data file */
19942018 if (expect -> repeat_no_match && repeat_count < expect -> repeat_limit )
19952019 repeat_test = true;
19962020
1997- break ;
2021+ continue ;
19982022 }
19992023
20002024 if (found && expect -> same_count_as )
@@ -2020,7 +2044,7 @@ do_test(ipp_file_t *f, /* I - IPP data file */
20202044 if (expect -> repeat_no_match && repeat_count < expect -> repeat_limit )
20212045 repeat_test = true;
20222046
2023- break ;
2047+ continue ;
20242048 }
20252049 }
20262050
@@ -5131,13 +5155,19 @@ token_cb(ipp_file_t *f, /* I - IPP file data */
51315155 _cups_strcasecmp (token , "REPEAT-MATCH" ) &&
51325156 _cups_strcasecmp (token , "REPEAT-NO-MATCH" ) &&
51335157 _cups_strcasecmp (token , "SAME-COUNT-AS" ) &&
5158+ _cups_strcasecmp (token , "SAVE-ALL-CONTENT" ) &&
5159+ _cups_strcasecmp (token , "SAVE-CONTENT" ) &&
5160+ _cups_strcasecmp (token , "WITH-ALL-CONTENT" ) &&
5161+ _cups_strcasecmp (token , "WITH-ALL-MIME-TYPES" ) &&
51345162 _cups_strcasecmp (token , "WITH-ALL-VALUES" ) &&
51355163 _cups_strcasecmp (token , "WITH-ALL-VALUES-FROM" ) &&
51365164 _cups_strcasecmp (token , "WITH-ALL-HOSTNAMES" ) &&
51375165 _cups_strcasecmp (token , "WITH-ALL-RESOURCES" ) &&
51385166 _cups_strcasecmp (token , "WITH-ALL-SCHEMES" ) &&
5167+ _cups_strcasecmp (token , "WITH-CONTENT" ) &&
51395168 _cups_strcasecmp (token , "WITH-DISTINCT-VALUES" ) &&
51405169 _cups_strcasecmp (token , "WITH-HOSTNAME" ) &&
5170+ _cups_strcasecmp (token , "WITH-MIME-TYPES" ) &&
51415171 _cups_strcasecmp (token , "WITH-RESOURCE" ) &&
51425172 _cups_strcasecmp (token , "WITH-SCHEME" ) &&
51435173 _cups_strcasecmp (token , "WITH-VALUE" ) &&
@@ -5906,6 +5936,24 @@ token_cb(ipp_file_t *f, /* I - IPP file data */
59065936 return (false);
59075937 }
59085938 }
5939+ else if (!_cups_strcasecmp (token , "SAVE-ALL-CONTENT" ) || !_cups_strcasecmp (token , "SAVE-CONTENT" ))
5940+ {
5941+ if (!ippFileReadToken (f , temp , sizeof (temp )))
5942+ {
5943+ print_fatal_error (data , "Missing %s filespec on line %d of '%s'." , token , ippFileGetLineNumber (f ), ippFileGetFilename (f ));
5944+ return (false);
5945+ }
5946+
5947+ if (data -> last_expect )
5948+ {
5949+ data -> last_expect -> save_filespec = strdup (temp );
5950+ }
5951+ else
5952+ {
5953+ print_fatal_error (data , "%s without a preceding EXPECT on line %d of '%s'." , token , ippFileGetLineNumber (f ), ippFileGetFilename (f ));
5954+ return (false);
5955+ }
5956+ }
59095957 else if (!_cups_strcasecmp (token , "IF-DEFINED" ))
59105958 {
59115959 if (!ippFileReadToken (f , temp , sizeof (temp )))
@@ -5950,6 +5998,58 @@ token_cb(ipp_file_t *f, /* I - IPP file data */
59505998 return (false);
59515999 }
59526000 }
6001+ else if (!_cups_strcasecmp (token , "WITH-ALL-CONTENT" ) || !_cups_strcasecmp (token , "WITH-CONTENT" ))
6002+ {
6003+ if (!ippFileReadToken (f , temp , sizeof (temp )))
6004+ {
6005+ print_fatal_error (data , "Missing %s condition on line %d of '%s'." , token , ippFileGetLineNumber (f ), ippFileGetFilename (f ));
6006+ return (false);
6007+ }
6008+
6009+ if (data -> last_expect )
6010+ {
6011+ if (!_cups_strcasecmp (temp , "available" ))
6012+ {
6013+ data -> last_expect -> with_content = IPPTOOL_CONTENT_AVAILABLE ;
6014+ }
6015+ else if (!_cups_strcasecmp (temp , "valid" ))
6016+ {
6017+ data -> last_expect -> with_content = IPPTOOL_CONTENT_VALID ;
6018+ }
6019+ else if (!_cups_strcasecmp (temp , "valid-icon" ))
6020+ {
6021+ data -> last_expect -> with_content = IPPTOOL_CONTENT_VALID_ICON ;
6022+ }
6023+ else
6024+ {
6025+ print_fatal_error (data , "Unsupported %s %s on line %d of '%s'." , token , temp , ippFileGetLineNumber (f ), ippFileGetFilename (f ));
6026+ return (false);
6027+ }
6028+ }
6029+ else
6030+ {
6031+ print_fatal_error (data , "%s without a preceding EXPECT on line %d of '%s'." , token , ippFileGetLineNumber (f ), ippFileGetFilename (f ));
6032+ return (false);
6033+ }
6034+ }
6035+ else if (!_cups_strcasecmp (token , "WITH-ALL-MIME-TYPES" ) || !_cups_strcasecmp (token , "WITH-MIME-TYPES" ))
6036+ {
6037+ if (!ippFileReadToken (f , temp , sizeof (temp )))
6038+ {
6039+ print_fatal_error (data , "Missing %s MIME media type(s) on line %d of '%s'." , token , ippFileGetLineNumber (f ), ippFileGetFilename (f ));
6040+ return (false);
6041+ }
6042+
6043+ if (data -> last_expect )
6044+ {
6045+ data -> last_expect -> with_mime_types = cupsArrayNewStrings (temp , ',' );
6046+ }
6047+ else
6048+ {
6049+ print_fatal_error (data , "%s without a preceding EXPECT on line %d of '%s'." , token , ippFileGetLineNumber (f ), ippFileGetFilename (f ));
6050+ return (false);
6051+ }
6052+ }
59536053 else if (!_cups_strcasecmp (token , "WITH-DISTINCT-VALUES" ))
59546054 {
59556055 if (data -> last_expect )
@@ -6566,6 +6666,30 @@ usage(void)
65666666}
65676667
65686668
6669+ /*
6670+ * 'with_content()' - Verify that URIs meet content/MIME media type requirements
6671+ * and save as needed.
6672+ */
6673+
6674+ static bool // O - `true` if valid, `false` otherwise
6675+ with_content (
6676+ cups_array_t * errors , // I - Array of errors
6677+ ipp_attribute_t * attr , // I - Attribute
6678+ ipptool_content_t content , // I - Content validation rule
6679+ cups_array_t * mime_types , // I - Comma-delimited list of MIME media types
6680+ const char * filespec ) // I - Output filename specification
6681+ {
6682+ // TODO: Implement me
6683+ (void )errors ;
6684+ (void )attr ;
6685+ (void )content ;
6686+ (void )mime_types ;
6687+ (void )filespec ;
6688+
6689+ return (true);
6690+ }
6691+
6692+
65696693/*
65706694 * 'with_distinct_values()' - Verify that an attribute contains unique values.
65716695 */
0 commit comments