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