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