xref: /illumos-gate/usr/src/lib/print/libipp-listener/common/common.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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: common.c 155 2006-04-26 02:34:54Z ktou $ */
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include <errno.h>
37 #include <sys/types.h>
38 #include <unistd.h>
39 #include <papi.h>
40 #include <ipp-listener.h>
41 
42 char *
43 ipp_svc_status_mesg(papi_service_t svc, papi_status_t status)
44 {
45 	char *mesg =  papiServiceGetStatusMessage(svc);
46 
47 	if (mesg == NULL)
48 		mesg = papiStatusString(status);
49 
50 	return (mesg);
51 }
52 
53 char *
54 destination_from_printer_uri(char *uri)
55 {
56 	static char buf[64];
57 	char *result = NULL;
58 
59 	if (uri != NULL)
60 		result = strrchr(uri, '/');
61 
62 	if (result == NULL)
63 		result = uri;
64 	else
65 		result++;
66 
67 #ifdef FORCE_LPSCHED_URI
68 	snprintf(buf, sizeof (buf), "lpsched://localhost/printers/%s", result);
69 	result = buf;
70 #endif /* FORCE_LPSCHED_URI */
71 
72 	return (result);
73 }
74 
75 void
76 get_printer_id(papi_attribute_t **attributes, char **printer, int *id)
77 {
78 	papi_status_t result;
79 	char *job = NULL;
80 	char *fodder;
81 	int junk;
82 
83 	if (printer == NULL)
84 		printer = &fodder;
85 	if (id == NULL)
86 		id = &junk;
87 
88 	*printer = NULL;
89 	*id = -1;
90 
91 	result = papiAttributeListGetString(attributes, NULL, "job-uri", &job);
92 	if (result != PAPI_OK) {
93 		result = papiAttributeListGetString(attributes, NULL,
94 						"printer-uri", printer);
95 		if (result == PAPI_OK)
96 			papiAttributeListGetInteger(attributes, NULL,
97 						"job-id", id);
98 	} else {
99 		*printer = job;
100 		if ((job = strrchr(*printer, '/')) != NULL) {
101 			*job = '\0';
102 			*id = atoi(++job);
103 		}
104 	}
105 }
106 
107 void
108 get_string_list(papi_attribute_t **attributes, char *name, char ***values)
109 {
110 	papi_status_t result;
111 
112 	void *iterator = NULL;
113 	char *value = NULL;
114 
115 	for (result = papiAttributeListGetString(attributes, &iterator,
116 					name, &value);
117 	    result == PAPI_OK;
118 	    result = papiAttributeListGetString(attributes, &iterator,
119 					NULL, &value))
120 		list_append(values, value);
121 }
122 
123 void
124 add_default_attributes(papi_attribute_t ***attributes)
125 {
126 
127 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_APPEND,
128 			"ipp-versions-supported", "1.0");
129 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_APPEND,
130 			"ipp-versions-supported", "1.1");
131 	(void) papiAttributeListAddBoolean(attributes, PAPI_ATTR_EXCL,
132 			"multiple-document-jobs-supported", 0);
133 	/*
134 	 * Should be able to ask the web server if it supports SSL or TLS, but
135 	 * for now, we pick only "none"
136 	 */
137 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
138 			"uri-security-supported", "none");
139 
140 	/*
141 	 * For now, we only "none".  As we support more authentication methods,
142 	 * we will need to add the associated uri for each.  Valid values would
143 	 * be:
144 	 *	"none", "requesting-user-name", "basic", "digest", "certificate"
145 	 * See RFC2911 page 127 for more information.
146 	 */
147 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
148 			"uri-authentication-supported", "requesting-user-name");
149 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
150 			"uri-security-supported", "none");
151 	/* printer-uri-supported is added in the service based attributes */
152 
153 	(void) papiAttributeListAddInteger(attributes, PAPI_ATTR_EXCL,
154 			"multiple-operation-time-out", 60);
155 
156 	/* I18N related */
157 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
158 			"charset-configured", "utf-8");
159 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
160 			"charset-supported", "utf-8");
161 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
162 			"natural-language-configured", "en-us");
163 }
164 
165 static void
166 massage_printer_attributes_group(papi_attribute_t **group, char *printer_uri)
167 {
168 	if (papiAttributeListFind(group, "printer-uri-supported") != NULL)
169 		papiAttributeListAddString(&group, PAPI_ATTR_REPLACE,
170 				"printer-uri-supported", printer_uri);
171 }
172 
173 static void
174 massage_job_attributes_group(papi_attribute_t **group, char *printer_uri)
175 {
176 	if (papiAttributeListFind(group, "job-printer-uri") != NULL)
177 		papiAttributeListAddString(&group, PAPI_ATTR_REPLACE,
178 				"job-printer-uri", printer_uri);
179 
180 	if (papiAttributeListFind(group, "job-printer-uri") != NULL) {
181 		char buf[BUFSIZ];
182 		int32_t id = -1;
183 
184 		papiAttributeListGetInteger(group, NULL, "job-id", &id);
185 		snprintf(buf, sizeof (buf), "%s/%d", printer_uri, id);
186 		papiAttributeListAddString(&group, PAPI_ATTR_REPLACE,
187 				"job-uri", buf);
188 	}
189 }
190 
191 /*
192  * This function will replace the job/printer URIs with the requested
193  * uri because the print service may return a URI that isn't IPP based.
194  */
195 void
196 massage_response(papi_attribute_t **request, papi_attribute_t **response)
197 {
198 	papi_status_t status;
199 	papi_attribute_t **group = NULL;
200 	void *iter = NULL;
201 	char *host = "localhost";
202 	char *path = "/printers/";
203 	int port = 631;
204 	char buf[BUFSIZ];
205 
206 	(void) papiAttributeListGetString(request, NULL, "uri-host", &host);
207 	(void) papiAttributeListGetString(request, NULL, "uri-path", &path);
208 	(void) papiAttributeListGetInteger(request, NULL, "uri-port", &port);
209 
210 	if (port == 631)
211 		snprintf(buf, sizeof (buf), "ipp://%s%s", host, path);
212 	else
213 		snprintf(buf, sizeof (buf), "http://%s:%d%s", host, port, path);
214 
215 	for (status = papiAttributeListGetCollection(response, &iter,
216 				"printer-attributes-group", &group);
217 	     status == PAPI_OK;
218 	     status = papiAttributeListGetCollection(NULL, &iter,
219 				NULL, &group))
220 		massage_printer_attributes_group(group, buf);
221 
222 	iter = NULL;
223 	for (status = papiAttributeListGetCollection(response, &iter,
224 				"job-attributes-group", &group);
225 	     status == PAPI_OK;
226 	     status = papiAttributeListGetCollection(NULL, &iter,
227 				NULL, &group))
228 		massage_job_attributes_group(group, buf);
229 }
230 
231 /*
232  * This walks through the locale tab and returns the installed
233  * locales.  There must be a better way.
234  */
235 void
236 add_supported_locales(papi_attribute_t ***attributes)
237 {
238 	FILE *fp;
239 
240 	papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
241 			"generated-natural-language-supported", "en-us");
242 
243 #ifndef __linux__	/* this is Solaris specific */
244 	if ((fp = fopen("/usr/lib/locale/lcttab", "r")) != NULL) {
245 		char buf[1024];
246 
247 		while (fgets(buf, sizeof (buf), fp) != NULL) {
248 			char *name, *file;
249 			int i, passed = 1;
250 
251 			name = strtok(buf, " \t\n");
252 
253 			for (i = 0; ((passed == 1) && (name[i] != NULL)); i++)
254 				if (isalpha(name[i]) != 0)
255 					name[i] = tolower(name[i]);
256 				else if ((name[i] == '_') || (name[i] == '-'))
257 					name[i] = '-';
258 				else
259 					passed = 0;
260 
261 			if ((passed == 1) &&
262 			    ((file = strtok(NULL, " \t\n")) != NULL)) {
263 					char path[1024];
264 
265 				snprintf(path, sizeof (path),
266 					"/usr/lib/locale/%s", file);
267 
268 				if (access(path, F_OK) == 0)
269 					papiAttributeListAddString(attributes,
270 						PAPI_ATTR_APPEND,
271 					"generated-natural-language-supported",
272 					name);
273 			}
274 		}
275 	}
276 #endif
277 }
278 
279 void
280 papi_to_ipp_printer_group(papi_attribute_t ***response,
281 		papi_attribute_t **request, int flags, papi_printer_t p)
282 {
283 	papi_attribute_t **ipp_group = NULL;
284 
285 	copy_attributes(&ipp_group, papiPrinterGetAttributeList(p));
286 
287 	/* Windows clients appear to have a problem with very large values */
288 	papiAttributeListDelete(&ipp_group, "lpsched-printer-ppd-contents");
289 
290 	add_default_attributes(&ipp_group);
291 	ipp_operations_supported(&ipp_group, request);
292 
293 	(void) papiAttributeListAddCollection(response, flags,
294 			"printer-attributes-group", ipp_group);
295 	papiAttributeListFree(ipp_group);
296 }
297 
298 void
299 papi_to_ipp_job_group(papi_attribute_t ***response,
300 			papi_attribute_t **request, int flags, papi_job_t j)
301 {
302 	papi_attribute_t **ipp_group = NULL;
303 
304 	copy_attributes(&ipp_group, papiJobGetAttributeList(j));
305 
306 	(void) papiAttributeListAddCollection(response, flags,
307 			"job-attributes-group", ipp_group);
308 	papiAttributeListFree(ipp_group);
309 }
310