1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  *
26  */
27 
28 /* $Id: ipp_types.c 146 2006-03-24 00:26:54Z njacobs $ */
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <stdarg.h>
33 #include <string.h>
34 #include <ipp.h>
35 #include <errno.h>
36 #include <values.h>
37 
38 #ifndef MININT
39 #define	MININT	(-MAXINT - 1)
40 #endif
41 
42 typedef struct {
43 	char *name;
44 	int8_t ipp_type;
45 	int min;
46 	int max;
47 } attr_info_list_t;
48 
49 static attr_info_list_t attr_list[] = {
50 	{"operation-attribute-group", DTAG_OPERATION_ATTRIBUTES, 0, 0},
51 	{"job-attribute-group", DTAG_JOB_ATTRIBUTES, 0, 0},
52 	{"printer-attribute-group", DTAG_PRINTER_ATTRIBUTES, 0, 0},
53 	{"unsupported-attribute-group", DTAG_UNSUPPORTED_ATTRIBUTES, 0, 0},
54 	{"subscription-attribute-group", DTAG_SUBSCRIPTION_ATTRIBUTES, 0, 0},
55 	{"even-notificaton-attribute-group",
56 		DTAG_EVENT_NOTIFICATION_ATTRIBUTES, 0, 0},
57 	{"attributes-charset", VTAG_CHARSET, 0, 255},
58 	{"attributes-natural-language", VTAG_NATURAL_LANGUAGE, 0, 255},
59 	{"charset-configured", VTAG_CHARSET, 0, 255},
60 	{"charset-supported", VTAG_CHARSET, 0, 255},
61 	{"color-supported", VTAG_BOOLEAN, 0, 1},
62 	{"compression", VTAG_KEYWORD, 1, 255},
63 	{"compression-supported", VTAG_KEYWORD, 1, 255},
64 	{"copies", VTAG_INTEGER, 1, MAXINT},
65 	{"copies-default", VTAG_INTEGER, 1, MAXINT},
66 	{"copies-supported", VTAG_RANGE_OF_INTEGER, 1, MAXINT},
67 	{"date-at-completed", VTAG_DATE_TIME, 0, 0},
68 	{"date-at-creation", VTAG_DATE_TIME, 0, 0},
69 	{"date-at-processing", VTAG_DATE_TIME, 0, 0},
70 	{"detailed-status-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
71 	{"document-access-error", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
72 	{"document-format", VTAG_MIME_MEDIA_TYPE, 0, 255},
73 	{"document-format-default", VTAG_MIME_MEDIA_TYPE, 0, 255},
74 	{"document-format-supported", VTAG_MIME_MEDIA_TYPE, 0, 255},
75 	{"document-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
76 	{"document-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
77 	{"document-natural-language", VTAG_NATURAL_LANGUAGE, 0, 255},
78 	{"finishing", VTAG_ENUM, 3, 31},
79 	{"finishing-default", VTAG_ENUM, 3, 31},
80 	{"finishing-supported", VTAG_ENUM, 3, 31},
81 	{"generated-natural-language-supported", VTAG_NATURAL_LANGUAGE, 0, 255},
82 	{"ipp-attribute-fidelity", VTAG_BOOLEAN, 0, 1},
83 	{"ipp-versions-supported", VTAG_KEYWORD, 1, 255},
84 	{"job-detailed-status-messages", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
85 	{"job-document-access-errors", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
86 	{"job-hold-until", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
87 	{"job-hold-until-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
88 	{"job-hold-until-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
89 	{"job-id", VTAG_INTEGER, 1, MAXINT},
90 	{"job-impressions", VTAG_INTEGER, 0, MAXINT},
91 	{"job-impressions-completed", VTAG_INTEGER, 0, MAXINT},
92 	{"job-impressions-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT},
93 	{"job-k-octets", VTAG_INTEGER, 0, MAXINT},
94 	{"job-k-octets-processed", VTAG_INTEGER, 0, MAXINT},
95 	{"job-k-octets-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT},
96 	{"job-media-sheets", VTAG_INTEGER, 0, MAXINT},
97 	{"job-media-sheets-completed", VTAG_INTEGER, 0, MAXINT},
98 	{"job-media-sheets-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT},
99 	{"job-message-from-operator", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
100 	{"job-more-info", VTAG_URI, 0, 1023},
101 	{"job-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
102 	{"job-originating-user-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
103 	{"job-printer-up-time", VTAG_INTEGER, 1, MAXINT},
104 	{"job-printer-uri", VTAG_URI, 0, 1023},
105 	{"job-priority", VTAG_INTEGER, 1, 100},
106 	{"job-priority-default", VTAG_INTEGER, 1, 100},
107 	{"job-priority-supported", VTAG_INTEGER, 1, 100},
108 	{"job-sheets", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
109 	{"job-sheets-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
110 	{"job-sheets-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
111 	{"job-state", VTAG_ENUM, 3, 9},
112 	{"job-state-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
113 	{"job-state-reasons", VTAG_KEYWORD, 1, 255},
114 	{"job-uri", VTAG_URI, 0, 1023},
115 	{"last-document", VTAG_BOOLEAN, 0, 1},
116 	{"limit", VTAG_INTEGER, 1, MAXINT},
117 	{"media", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
118 	{"media-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
119 	{"media-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
120 	{"message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
121 	{"multiple-document-handling", VTAG_KEYWORD, 1, 255},
122 	{"multiple-document-handling-default", VTAG_KEYWORD, 1, 255},
123 	{"multiple-document-handling-supported", VTAG_KEYWORD, 1, 255},
124 	{"multiple-document-jobs-supported", VTAG_BOOLEAN, 0, 1},
125 	{"multiple-operation-time-out", VTAG_INTEGER, 1, MAXINT},
126 	{"my-jobs", VTAG_BOOLEAN, 0, 1},
127 	{"natural-language-configured", VTAG_NATURAL_LANGUAGE, 0, 255},
128 	{"number-of-documents", VTAG_INTEGER, 0, MAXINT},
129 	{"number-of-intervening-jobs", VTAG_INTEGER, 0, MAXINT},
130 	{"number-up", VTAG_INTEGER, 1, MAXINT},
131 	{"number-up-default", VTAG_INTEGER, 1, MAXINT},
132 	{"number-up-supported", VTAG_INTEGER, 1, MAXINT},
133 	{"operations-supported", VTAG_ENUM, 1, 0x8FFF},
134 	{"orientation-requested", VTAG_ENUM, 3, 6},
135 	{"orientation-requested-default", VTAG_ENUM, 3, 6},
136 	{"orientation-requested-supported", VTAG_ENUM, 3, 6},
137 	{"output-device-assigned", VTAG_NAME_WITHOUT_LANGUAGE, 0, 127},
138 	{"page-ranges", VTAG_RANGE_OF_INTEGER, 1, MAXINT},
139 	{"page-ranges-supported", VTAG_BOOLEAN, 0, 1},
140 	{"pages-per-minute", VTAG_INTEGER, 0, MAXINT},
141 	{"pages-per-minute-color", VTAG_INTEGER, 0, MAXINT},
142 	{"pdl-override-supported", VTAG_KEYWORD, 1, 255},
143 	{"print-quality", VTAG_ENUM, 3, 5},
144 	{"print-quality-default", VTAG_ENUM, 3, 5},
145 	{"print-quality-supported", VTAG_ENUM, 3, 5},
146 	{"printer-current-time", VTAG_DATE_TIME, 0, 1},
147 	{"printer-driver-installer", VTAG_URI, 0, 1023},
148 	{"printer-id", VTAG_INTEGER, 1, MAXINT},
149 	{"printer-info", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
150 	{"printer-is-accepting-jobs", VTAG_BOOLEAN, 0, 1},
151 	{"printer-location", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
152 	{"printer-make-and-model", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
153 	{"printer-message-from-operator", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
154 	{"printer-more-info", VTAG_URI, 0, 1023},
155 	{"printer-more-info-manufacturer", VTAG_URI, 0, 1023},
156 	{"printer-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 127},
157 	{"printer-resolution", VTAG_RESOLUTION, 0, 0},
158 	{"printer-resolution-default", VTAG_RESOLUTION, 0, 0},
159 	{"printer-resolution-supported", VTAG_RESOLUTION, 0, 0},
160 	{"printer-state", VTAG_ENUM, 3, 5},
161 	{"printer-state-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
162 	{"printer-state-reasons", VTAG_KEYWORD, 1, 255},
163 	{"printer-up-time", VTAG_INTEGER, 1, MAXINT},
164 	{"printer-uri", VTAG_URI, 0, 1023},
165 	{"printer-uri-supported", VTAG_URI, 0, 1023},
166 	{"queued-job-count", VTAG_INTEGER, 0, MAXINT},
167 	{"reference-uri-schemes-supported", VTAG_URI_SCHEME, 0, 63},
168 	{"requested-attributes", VTAG_KEYWORD, 1, 255},
169 	{"requesting-user-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
170 	{"sides", VTAG_KEYWORD, 1, 255},
171 	{"sides-default", VTAG_KEYWORD, 1, 255},
172 	{"sides-supported", VTAG_KEYWORD, 1, 255},
173 	{"status-code", VTAG_ENUM, 1, 0x7FFF},
174 	{"status-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 255},
175 	{"time-at-completed", VTAG_INTEGER, MININT, MAXINT},
176 	{"time-at-creation", VTAG_INTEGER, MININT, MAXINT},
177 	{"time-at-processing", VTAG_INTEGER, MININT, MAXINT},
178 	{"uri-authentication-supported", VTAG_KEYWORD, 1, 255},
179 	{"uri-security-supported", VTAG_KEYWORD, 1, 255},
180 	{"which-jobs", VTAG_KEYWORD, 1, 255},
181 	{NULL, 0, 0, 0}
182 };
183 
184 
185 static attr_info_list_t *
get_attr_info_by_name(char * name)186 get_attr_info_by_name(char *name)
187 {
188 	if (name != NULL) {
189 		int i;
190 
191 		for (i = 0; attr_list[i].name != NULL; i++)
192 			if (strcasecmp(attr_list[i].name, name) == 0)
193 				return (&attr_list[i]);
194 	}
195 
196 	return (NULL);
197 }
198 
199 size_t
max_val_len(int8_t type,char * name)200 max_val_len(int8_t type, char *name)
201 {
202 	attr_info_list_t *t;
203 	int result;
204 
205 	switch (type) {
206 	case VTAG_INTEGER:
207 	case VTAG_RANGE_OF_INTEGER:
208 	case VTAG_ENUM:
209 		result = MAXINT;
210 		break;
211 	case VTAG_URI:
212 	case VTAG_OCTET_STRING:
213 	case VTAG_TEXT_WITHOUT_LANGUAGE:
214 		result = 1023;
215 		break;
216 	case VTAG_NATURAL_LANGUAGE:
217 	case VTAG_URI_SCHEME:
218 	case VTAG_CHARSET:
219 		result = 63;
220 		break;
221 	case VTAG_NAME_WITHOUT_LANGUAGE:
222 	case VTAG_MIME_MEDIA_TYPE:
223 	case VTAG_KEYWORD:
224 		result = 255;
225 		break;
226 	default:
227 		result = MAXINT;
228 	}
229 
230 #define	min(a, b)	((a < b) ? a : b)
231 	if ((t = get_attr_info_by_name(name)) != NULL)
232 		result = min(t->max, result);
233 #undef min
234 
235 	return (result);
236 }
237 
238 size_t
min_val_len(int8_t type,char * name)239 min_val_len(int8_t type, char *name)
240 {
241 	attr_info_list_t *t;
242 	int result;
243 
244 	switch (type) {
245 	case VTAG_INTEGER:
246 	case VTAG_RANGE_OF_INTEGER:
247 		result = MININT;
248 		break;
249 	case VTAG_ENUM:
250 		result = 1;
251 		break;
252 	case VTAG_URI:
253 	case VTAG_OCTET_STRING:
254 	case VTAG_TEXT_WITHOUT_LANGUAGE:
255 	case VTAG_MIME_MEDIA_TYPE:
256 	case VTAG_NAME_WITHOUT_LANGUAGE:
257 	case VTAG_URI_SCHEME:
258 	case VTAG_CHARSET:
259 	case VTAG_NATURAL_LANGUAGE:
260 		result = 0;
261 		break;
262 	case VTAG_KEYWORD:
263 		result = 1;
264 		break;
265 	default:
266 		result = MININT;
267 	}
268 
269 #define	max(a, b)	((a > b) ? a : b)
270 	if ((t = get_attr_info_by_name(name)) != NULL)
271 		result = max(t->min, result);
272 #undef max
273 
274 	return (result);
275 }
276 
277 int
is_keyword(char * k)278 is_keyword(char *k)
279 {
280 	/* [a-z][a-z0-9._-]* */
281 	if (*k < 'a' && *k > 'z')
282 		return (0);
283 	while (*(++k) != '\0')
284 		if (*k < 'a' && *k > 'z' && *k < '0' && *k > '9' &&
285 			*k != '.' && *k != '_' && *k != '-')
286 			return (0);
287 	return (1);
288 }
289 
290 int8_t
name_to_ipp_type(char * name)291 name_to_ipp_type(char *name)
292 {
293 	int i;
294 
295 	if (name != NULL)
296 		for (i = 0; attr_list[i].name != NULL; i++)
297 			if (strcasecmp(attr_list[i].name, name) == 0)
298 				return (attr_list[i].ipp_type);
299 
300 	return (0);
301 }
302