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#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <stdarg.h>
35#include <string.h>
36#include <ipp.h>
37#include <errno.h>
38#include <values.h>
39
40#ifndef MININT
41#define	MININT	(-MAXINT - 1)
42#endif
43
44typedef struct {
45	char *name;
46	int8_t ipp_type;
47	int min;
48	int max;
49} attr_info_list_t;
50
51static attr_info_list_t attr_list[] = {
52	{"operation-attribute-group", DTAG_OPERATION_ATTRIBUTES, 0, 0},
53	{"job-attribute-group", DTAG_JOB_ATTRIBUTES, 0, 0},
54	{"printer-attribute-group", DTAG_PRINTER_ATTRIBUTES, 0, 0},
55	{"unsupported-attribute-group", DTAG_UNSUPPORTED_ATTRIBUTES, 0, 0},
56	{"subscription-attribute-group", DTAG_SUBSCRIPTION_ATTRIBUTES, 0, 0},
57	{"even-notificaton-attribute-group",
58		DTAG_EVENT_NOTIFICATION_ATTRIBUTES, 0, 0},
59	{"attributes-charset", VTAG_CHARSET, 0, 255},
60	{"attributes-natural-language", VTAG_NATURAL_LANGUAGE, 0, 255},
61	{"charset-configured", VTAG_CHARSET, 0, 255},
62	{"charset-supported", VTAG_CHARSET, 0, 255},
63	{"color-supported", VTAG_BOOLEAN, 0, 1},
64	{"compression", VTAG_KEYWORD, 1, 255},
65	{"compression-supported", VTAG_KEYWORD, 1, 255},
66	{"copies", VTAG_INTEGER, 1, MAXINT},
67	{"copies-default", VTAG_INTEGER, 1, MAXINT},
68	{"copies-supported", VTAG_RANGE_OF_INTEGER, 1, MAXINT},
69	{"date-at-completed", VTAG_DATE_TIME, 0, 0},
70	{"date-at-creation", VTAG_DATE_TIME, 0, 0},
71	{"date-at-processing", VTAG_DATE_TIME, 0, 0},
72	{"detailed-status-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
73	{"document-access-error", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
74	{"document-format", VTAG_MIME_MEDIA_TYPE, 0, 255},
75	{"document-format-default", VTAG_MIME_MEDIA_TYPE, 0, 255},
76	{"document-format-supported", VTAG_MIME_MEDIA_TYPE, 0, 255},
77	{"document-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
78	{"document-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
79	{"document-natural-language", VTAG_NATURAL_LANGUAGE, 0, 255},
80	{"finishing", VTAG_ENUM, 3, 31},
81	{"finishing-default", VTAG_ENUM, 3, 31},
82	{"finishing-supported", VTAG_ENUM, 3, 31},
83	{"generated-natural-language-supported", VTAG_NATURAL_LANGUAGE, 0, 255},
84	{"ipp-attribute-fidelity", VTAG_BOOLEAN, 0, 1},
85	{"ipp-versions-supported", VTAG_KEYWORD, 1, 255},
86	{"job-detailed-status-messages", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
87	{"job-document-access-errors", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
88	{"job-hold-until", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
89	{"job-hold-until-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
90	{"job-hold-until-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
91	{"job-id", VTAG_INTEGER, 1, MAXINT},
92	{"job-impressions", VTAG_INTEGER, 0, MAXINT},
93	{"job-impressions-completed", VTAG_INTEGER, 0, MAXINT},
94	{"job-impressions-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT},
95	{"job-k-octets", VTAG_INTEGER, 0, MAXINT},
96	{"job-k-octets-processed", VTAG_INTEGER, 0, MAXINT},
97	{"job-k-octets-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT},
98	{"job-media-sheets", VTAG_INTEGER, 0, MAXINT},
99	{"job-media-sheets-completed", VTAG_INTEGER, 0, MAXINT},
100	{"job-media-sheets-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT},
101	{"job-message-from-operator", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
102	{"job-more-info", VTAG_URI, 0, 1023},
103	{"job-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
104	{"job-originating-user-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
105	{"job-printer-up-time", VTAG_INTEGER, 1, MAXINT},
106	{"job-printer-uri", VTAG_URI, 0, 1023},
107	{"job-priority", VTAG_INTEGER, 1, 100},
108	{"job-priority-default", VTAG_INTEGER, 1, 100},
109	{"job-priority-supported", VTAG_INTEGER, 1, 100},
110	{"job-sheets", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
111	{"job-sheets-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
112	{"job-sheets-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
113	{"job-state", VTAG_ENUM, 3, 9},
114	{"job-state-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
115	{"job-state-reasons", VTAG_KEYWORD, 1, 255},
116	{"job-uri", VTAG_URI, 0, 1023},
117	{"last-document", VTAG_BOOLEAN, 0, 1},
118	{"limit", VTAG_INTEGER, 1, MAXINT},
119	{"media", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
120	{"media-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
121	{"media-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
122	{"message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
123	{"multiple-document-handling", VTAG_KEYWORD, 1, 255},
124	{"multiple-document-handling-default", VTAG_KEYWORD, 1, 255},
125	{"multiple-document-handling-supported", VTAG_KEYWORD, 1, 255},
126	{"multiple-document-jobs-supported", VTAG_BOOLEAN, 0, 1},
127	{"multiple-operation-time-out", VTAG_INTEGER, 1, MAXINT},
128	{"my-jobs", VTAG_BOOLEAN, 0, 1},
129	{"natural-language-configured", VTAG_NATURAL_LANGUAGE, 0, 255},
130	{"number-of-documents", VTAG_INTEGER, 0, MAXINT},
131	{"number-of-intervening-jobs", VTAG_INTEGER, 0, MAXINT},
132	{"number-up", VTAG_INTEGER, 1, MAXINT},
133	{"number-up-default", VTAG_INTEGER, 1, MAXINT},
134	{"number-up-supported", VTAG_INTEGER, 1, MAXINT},
135	{"operations-supported", VTAG_ENUM, 1, 0x8FFF},
136	{"orientation-requested", VTAG_ENUM, 3, 6},
137	{"orientation-requested-default", VTAG_ENUM, 3, 6},
138	{"orientation-requested-supported", VTAG_ENUM, 3, 6},
139	{"output-device-assigned", VTAG_NAME_WITHOUT_LANGUAGE, 0, 127},
140	{"page-ranges", VTAG_RANGE_OF_INTEGER, 1, MAXINT},
141	{"page-ranges-supported", VTAG_BOOLEAN, 0, 1},
142	{"pages-per-minute", VTAG_INTEGER, 0, MAXINT},
143	{"pages-per-minute-color", VTAG_INTEGER, 0, MAXINT},
144	{"pdl-override-supported", VTAG_KEYWORD, 1, 255},
145	{"print-quality", VTAG_ENUM, 3, 5},
146	{"print-quality-default", VTAG_ENUM, 3, 5},
147	{"print-quality-supported", VTAG_ENUM, 3, 5},
148	{"printer-current-time", VTAG_DATE_TIME, 0, 1},
149	{"printer-driver-installer", VTAG_URI, 0, 1023},
150	{"printer-id", VTAG_INTEGER, 1, MAXINT},
151	{"printer-info", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
152	{"printer-is-accepting-jobs", VTAG_BOOLEAN, 0, 1},
153	{"printer-location", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
154	{"printer-make-and-model", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
155	{"printer-message-from-operator", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
156	{"printer-more-info", VTAG_URI, 0, 1023},
157	{"printer-more-info-manufacturer", VTAG_URI, 0, 1023},
158	{"printer-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 127},
159	{"printer-resolution", VTAG_RESOLUTION, 0, 0},
160	{"printer-resolution-default", VTAG_RESOLUTION, 0, 0},
161	{"printer-resolution-supported", VTAG_RESOLUTION, 0, 0},
162	{"printer-state", VTAG_ENUM, 3, 5},
163	{"printer-state-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
164	{"printer-state-reasons", VTAG_KEYWORD, 1, 255},
165	{"printer-up-time", VTAG_INTEGER, 1, MAXINT},
166	{"printer-uri", VTAG_URI, 0, 1023},
167	{"printer-uri-supported", VTAG_URI, 0, 1023},
168	{"queued-job-count", VTAG_INTEGER, 0, MAXINT},
169	{"reference-uri-schemes-supported", VTAG_URI_SCHEME, 0, 63},
170	{"requested-attributes", VTAG_KEYWORD, 1, 255},
171	{"requesting-user-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
172	{"sides", VTAG_KEYWORD, 1, 255},
173	{"sides-default", VTAG_KEYWORD, 1, 255},
174	{"sides-supported", VTAG_KEYWORD, 1, 255},
175	{"status-code", VTAG_ENUM, 1, 0x7FFF},
176	{"status-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 255},
177	{"time-at-completed", VTAG_INTEGER, MININT, MAXINT},
178	{"time-at-creation", VTAG_INTEGER, MININT, MAXINT},
179	{"time-at-processing", VTAG_INTEGER, MININT, MAXINT},
180	{"uri-authentication-supported", VTAG_KEYWORD, 1, 255},
181	{"uri-security-supported", VTAG_KEYWORD, 1, 255},
182	{"which-jobs", VTAG_KEYWORD, 1, 255},
183	{NULL, 0, 0, 0}
184};
185
186
187static attr_info_list_t *
188get_attr_info_by_name(char *name)
189{
190	if (name != NULL) {
191		int i;
192
193		for (i = 0; attr_list[i].name != NULL; i++)
194			if (strcasecmp(attr_list[i].name, name) == 0)
195				return (&attr_list[i]);
196	}
197
198	return (NULL);
199}
200
201size_t
202max_val_len(int8_t type, char *name)
203{
204	attr_info_list_t *t;
205	int result;
206
207	switch (type) {
208	case VTAG_INTEGER:
209	case VTAG_RANGE_OF_INTEGER:
210	case VTAG_ENUM:
211		result = MAXINT;
212		break;
213	case VTAG_URI:
214	case VTAG_OCTET_STRING:
215	case VTAG_TEXT_WITHOUT_LANGUAGE:
216		result = 1023;
217		break;
218	case VTAG_NATURAL_LANGUAGE:
219	case VTAG_URI_SCHEME:
220	case VTAG_CHARSET:
221		result = 63;
222		break;
223	case VTAG_NAME_WITHOUT_LANGUAGE:
224	case VTAG_MIME_MEDIA_TYPE:
225	case VTAG_KEYWORD:
226		result = 255;
227		break;
228	default:
229		result = MAXINT;
230	}
231
232#define	min(a, b)	((a < b) ? a : b)
233	if ((t = get_attr_info_by_name(name)) != NULL)
234		result = min(t->max, result);
235#undef min
236
237	return (result);
238}
239
240size_t
241min_val_len(int8_t type, char *name)
242{
243	attr_info_list_t *t;
244	int result;
245
246	switch (type) {
247	case VTAG_INTEGER:
248	case VTAG_RANGE_OF_INTEGER:
249		result = MININT;
250		break;
251	case VTAG_ENUM:
252		result = 1;
253		break;
254	case VTAG_URI:
255	case VTAG_OCTET_STRING:
256	case VTAG_TEXT_WITHOUT_LANGUAGE:
257	case VTAG_MIME_MEDIA_TYPE:
258	case VTAG_NAME_WITHOUT_LANGUAGE:
259	case VTAG_URI_SCHEME:
260	case VTAG_CHARSET:
261	case VTAG_NATURAL_LANGUAGE:
262		result = 0;
263		break;
264	case VTAG_KEYWORD:
265		result = 1;
266		break;
267	default:
268		result = MININT;
269	}
270
271#define	max(a, b)	((a > b) ? a : b)
272	if ((t = get_attr_info_by_name(name)) != NULL)
273		result = max(t->min, result);
274#undef max
275
276	return (result);
277}
278
279int
280is_keyword(char *k)
281{
282	/* [a-z][a-z0-9._-]* */
283	if (*k < 'a' && *k > 'z')
284		return (0);
285	while (*(++k) != '\0')
286		if (*k < 'a' && *k > 'z' && *k < '0' && *k > '9' &&
287			*k != '.' && *k != '_' && *k != '-')
288			return (0);
289	return (1);
290}
291
292int8_t
293name_to_ipp_type(char *name)
294{
295	int i;
296
297	if (name != NULL)
298		for (i = 0; attr_list[i].name != NULL; i++)
299			if (strcasecmp(attr_list[i].name, name) == 0)
300				return (attr_list[i].ipp_type);
301
302	return (0);
303}
304