1355b4669Sjacobs /*
2355b4669Sjacobs  * CDDL HEADER START
3355b4669Sjacobs  *
4355b4669Sjacobs  * The contents of this file are subject to the terms of the
5355b4669Sjacobs  * Common Development and Distribution License (the "License").
6355b4669Sjacobs  * You may not use this file except in compliance with the License.
7355b4669Sjacobs  *
8355b4669Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9355b4669Sjacobs  * or http://www.opensolaris.org/os/licensing.
10355b4669Sjacobs  * See the License for the specific language governing permissions
11355b4669Sjacobs  * and limitations under the License.
12355b4669Sjacobs  *
13355b4669Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
14355b4669Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15355b4669Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
16355b4669Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
17355b4669Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
18355b4669Sjacobs  *
19355b4669Sjacobs  * CDDL HEADER END
20355b4669Sjacobs  */
21355b4669Sjacobs 
22355b4669Sjacobs /*
23355b4669Sjacobs  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24355b4669Sjacobs  * Use is subject to license terms.
25355b4669Sjacobs  *
26355b4669Sjacobs  */
27355b4669Sjacobs 
28355b4669Sjacobs #include <stdio.h>
29355b4669Sjacobs #include <stdlib.h>
30355b4669Sjacobs #include <string.h>
31355b4669Sjacobs #include <ctype.h>
32355b4669Sjacobs #include <errno.h>
33355b4669Sjacobs #include <sys/types.h>
34355b4669Sjacobs #include <unistd.h>
35355b4669Sjacobs #include <papi.h>
36355b4669Sjacobs #include <ipp-listener.h>
37355b4669Sjacobs 
38355b4669Sjacobs char *
ipp_svc_status_mesg(papi_service_t svc,papi_status_t status)39355b4669Sjacobs ipp_svc_status_mesg(papi_service_t svc, papi_status_t status)
40355b4669Sjacobs {
41355b4669Sjacobs 	char *mesg =  papiServiceGetStatusMessage(svc);
42355b4669Sjacobs 
43355b4669Sjacobs 	if (mesg == NULL)
44355b4669Sjacobs 		mesg = papiStatusString(status);
45355b4669Sjacobs 
46355b4669Sjacobs 	return (mesg);
47355b4669Sjacobs }
48355b4669Sjacobs 
49355b4669Sjacobs char *
destination_from_printer_uri(char * uri)50355b4669Sjacobs destination_from_printer_uri(char *uri)
51355b4669Sjacobs {
52355b4669Sjacobs 	char *result = NULL;
53355b4669Sjacobs 
54355b4669Sjacobs 	if (uri != NULL)
55355b4669Sjacobs 		result = strrchr(uri, '/');
56355b4669Sjacobs 
57355b4669Sjacobs 	if (result == NULL)
58355b4669Sjacobs 		result = uri;
59355b4669Sjacobs 	else
60355b4669Sjacobs 		result++;
61355b4669Sjacobs 
62355b4669Sjacobs 	return (result);
63355b4669Sjacobs }
64355b4669Sjacobs 
65355b4669Sjacobs void
get_printer_id(papi_attribute_t ** attributes,char ** printer,int * id)66355b4669Sjacobs get_printer_id(papi_attribute_t **attributes, char **printer, int *id)
67355b4669Sjacobs {
68355b4669Sjacobs 	papi_status_t result;
69355b4669Sjacobs 	char *job = NULL;
70355b4669Sjacobs 	char *fodder;
71355b4669Sjacobs 	int junk;
72355b4669Sjacobs 
73355b4669Sjacobs 	if (printer == NULL)
74355b4669Sjacobs 		printer = &fodder;
75355b4669Sjacobs 	if (id == NULL)
76355b4669Sjacobs 		id = &junk;
77355b4669Sjacobs 
78355b4669Sjacobs 	*printer = NULL;
79355b4669Sjacobs 	*id = -1;
80355b4669Sjacobs 
81355b4669Sjacobs 	result = papiAttributeListGetString(attributes, NULL, "job-uri", &job);
82355b4669Sjacobs 	if (result != PAPI_OK) {
83355b4669Sjacobs 		result = papiAttributeListGetString(attributes, NULL,
84*f4593de7SToomas Soome 		    "printer-uri", printer);
85355b4669Sjacobs 		if (result == PAPI_OK)
86355b4669Sjacobs 			papiAttributeListGetInteger(attributes, NULL,
87*f4593de7SToomas Soome 			    "job-id", id);
88355b4669Sjacobs 	} else {
89355b4669Sjacobs 		*printer = job;
90355b4669Sjacobs 		if ((job = strrchr(*printer, '/')) != NULL) {
91355b4669Sjacobs 			*job = '\0';
92355b4669Sjacobs 			*id = atoi(++job);
93355b4669Sjacobs 		}
94355b4669Sjacobs 	}
95355b4669Sjacobs }
96355b4669Sjacobs 
97355b4669Sjacobs void
get_string_list(papi_attribute_t ** attributes,char * name,char *** values)98355b4669Sjacobs get_string_list(papi_attribute_t **attributes, char *name, char ***values)
99355b4669Sjacobs {
100355b4669Sjacobs 	papi_status_t result;
101355b4669Sjacobs 
102355b4669Sjacobs 	void *iterator = NULL;
103355b4669Sjacobs 	char *value = NULL;
104355b4669Sjacobs 
105355b4669Sjacobs 	for (result = papiAttributeListGetString(attributes, &iterator,
106*f4593de7SToomas Soome 	    name, &value);
107355b4669Sjacobs 	    result == PAPI_OK;
108355b4669Sjacobs 	    result = papiAttributeListGetString(attributes, &iterator,
109*f4593de7SToomas Soome 	    NULL, &value))
110355b4669Sjacobs 		list_append(values, value);
111355b4669Sjacobs }
112355b4669Sjacobs 
113355b4669Sjacobs void
add_default_attributes(papi_attribute_t *** attributes)114355b4669Sjacobs add_default_attributes(papi_attribute_t ***attributes)
115355b4669Sjacobs {
116355b4669Sjacobs 
117355b4669Sjacobs 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_APPEND,
118*f4593de7SToomas Soome 	    "ipp-versions-supported", "1.0");
119355b4669Sjacobs 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_APPEND,
120*f4593de7SToomas Soome 	    "ipp-versions-supported", "1.1");
121355b4669Sjacobs 	(void) papiAttributeListAddBoolean(attributes, PAPI_ATTR_EXCL,
122*f4593de7SToomas Soome 	    "multiple-document-jobs-supported", 0);
123355b4669Sjacobs 	/*
124355b4669Sjacobs 	 * Should be able to ask the web server if it supports SSL or TLS, but
125355b4669Sjacobs 	 * for now, we pick only "none"
126355b4669Sjacobs 	 */
127355b4669Sjacobs 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
128*f4593de7SToomas Soome 	    "uri-security-supported", "none");
129355b4669Sjacobs 
130355b4669Sjacobs 	/*
131355b4669Sjacobs 	 * For now, we only "none".  As we support more authentication methods,
132355b4669Sjacobs 	 * we will need to add the associated uri for each.  Valid values would
133355b4669Sjacobs 	 * be:
134355b4669Sjacobs 	 *	"none", "requesting-user-name", "basic", "digest", "certificate"
135355b4669Sjacobs 	 * See RFC2911 page 127 for more information.
136355b4669Sjacobs 	 */
137355b4669Sjacobs 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
138*f4593de7SToomas Soome 	    "uri-authentication-supported", "requesting-user-name");
139355b4669Sjacobs 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
140*f4593de7SToomas Soome 	    "uri-security-supported", "none");
141355b4669Sjacobs 	/* printer-uri-supported is added in the service based attributes */
142355b4669Sjacobs 
143355b4669Sjacobs 	(void) papiAttributeListAddInteger(attributes, PAPI_ATTR_EXCL,
144*f4593de7SToomas Soome 	    "multiple-operation-time-out", 60);
145355b4669Sjacobs 
146355b4669Sjacobs 	/* I18N related */
147355b4669Sjacobs 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
148*f4593de7SToomas Soome 	    "charset-configured", "utf-8");
149355b4669Sjacobs 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
150*f4593de7SToomas Soome 	    "charset-supported", "utf-8");
151355b4669Sjacobs 	(void) papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
152*f4593de7SToomas Soome 	    "natural-language-configured", "en-us");
153355b4669Sjacobs }
154355b4669Sjacobs 
155355b4669Sjacobs static void
massage_printer_attributes_group(papi_attribute_t ** group,char * printer_uri)156355b4669Sjacobs massage_printer_attributes_group(papi_attribute_t **group, char *printer_uri)
157355b4669Sjacobs {
158355b4669Sjacobs 	if (papiAttributeListFind(group, "printer-uri-supported") != NULL)
159355b4669Sjacobs 		papiAttributeListAddString(&group, PAPI_ATTR_REPLACE,
160*f4593de7SToomas Soome 		    "printer-uri-supported", printer_uri);
161355b4669Sjacobs }
162355b4669Sjacobs 
163355b4669Sjacobs static void
massage_job_attributes_group(papi_attribute_t ** group,char * printer_uri)164355b4669Sjacobs massage_job_attributes_group(papi_attribute_t **group, char *printer_uri)
165355b4669Sjacobs {
166355b4669Sjacobs 	if (papiAttributeListFind(group, "job-printer-uri") != NULL)
167355b4669Sjacobs 		papiAttributeListAddString(&group, PAPI_ATTR_REPLACE,
168*f4593de7SToomas Soome 		    "job-printer-uri", printer_uri);
169355b4669Sjacobs 
170355b4669Sjacobs 	if (papiAttributeListFind(group, "job-printer-uri") != NULL) {
171355b4669Sjacobs 		char buf[BUFSIZ];
172355b4669Sjacobs 		int32_t id = -1;
173355b4669Sjacobs 
174355b4669Sjacobs 		papiAttributeListGetInteger(group, NULL, "job-id", &id);
175355b4669Sjacobs 		snprintf(buf, sizeof (buf), "%s/%d", printer_uri, id);
176355b4669Sjacobs 		papiAttributeListAddString(&group, PAPI_ATTR_REPLACE,
177*f4593de7SToomas Soome 		    "job-uri", buf);
178355b4669Sjacobs 	}
179355b4669Sjacobs }
180355b4669Sjacobs 
181355b4669Sjacobs /*
182355b4669Sjacobs  * This function will replace the job/printer URIs with the requested
183355b4669Sjacobs  * uri because the print service may return a URI that isn't IPP based.
184355b4669Sjacobs  */
185355b4669Sjacobs void
massage_response(papi_attribute_t ** request,papi_attribute_t ** response)186355b4669Sjacobs massage_response(papi_attribute_t **request, papi_attribute_t **response)
187355b4669Sjacobs {
188355b4669Sjacobs 	papi_status_t status;
189355b4669Sjacobs 	papi_attribute_t **group = NULL;
190355b4669Sjacobs 	void *iter = NULL;
191355b4669Sjacobs 	char *host = "localhost";
192355b4669Sjacobs 	char *path = "/printers/";
193355b4669Sjacobs 	int port = 631;
194355b4669Sjacobs 	char buf[BUFSIZ];
195355b4669Sjacobs 
196355b4669Sjacobs 	(void) papiAttributeListGetString(request, NULL, "uri-host", &host);
197355b4669Sjacobs 	(void) papiAttributeListGetString(request, NULL, "uri-path", &path);
198355b4669Sjacobs 	(void) papiAttributeListGetInteger(request, NULL, "uri-port", &port);
199355b4669Sjacobs 
200355b4669Sjacobs 	if (port == 631)
201355b4669Sjacobs 		snprintf(buf, sizeof (buf), "ipp://%s%s", host, path);
202355b4669Sjacobs 	else
203355b4669Sjacobs 		snprintf(buf, sizeof (buf), "http://%s:%d%s", host, port, path);
204355b4669Sjacobs 
205355b4669Sjacobs 	for (status = papiAttributeListGetCollection(response, &iter,
206*f4593de7SToomas Soome 	    "printer-attributes-group", &group);
207*f4593de7SToomas Soome 	    status == PAPI_OK;
208*f4593de7SToomas Soome 	    status = papiAttributeListGetCollection(NULL, &iter, NULL, &group))
209355b4669Sjacobs 		massage_printer_attributes_group(group, buf);
210355b4669Sjacobs 
211355b4669Sjacobs 	iter = NULL;
212355b4669Sjacobs 	for (status = papiAttributeListGetCollection(response, &iter,
213*f4593de7SToomas Soome 	    "job-attributes-group", &group);
214*f4593de7SToomas Soome 	    status == PAPI_OK;
215*f4593de7SToomas Soome 	    status = papiAttributeListGetCollection(NULL, &iter, NULL, &group))
216355b4669Sjacobs 		massage_job_attributes_group(group, buf);
217355b4669Sjacobs }
218355b4669Sjacobs 
219355b4669Sjacobs /*
220355b4669Sjacobs  * This walks through the locale tab and returns the installed
221355b4669Sjacobs  * locales.  There must be a better way.
222355b4669Sjacobs  */
223355b4669Sjacobs void
add_supported_locales(papi_attribute_t *** attributes)224355b4669Sjacobs add_supported_locales(papi_attribute_t ***attributes)
225355b4669Sjacobs {
226355b4669Sjacobs 	FILE *fp;
227355b4669Sjacobs 
228355b4669Sjacobs 	papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
229*f4593de7SToomas Soome 	    "generated-natural-language-supported", "en-us");
230355b4669Sjacobs 
231355b4669Sjacobs 	if ((fp = fopen("/usr/lib/locale/lcttab", "r")) != NULL) {
232355b4669Sjacobs 		char buf[1024];
233355b4669Sjacobs 
234355b4669Sjacobs 		while (fgets(buf, sizeof (buf), fp) != NULL) {
235355b4669Sjacobs 			char *name, *file;
236355b4669Sjacobs 			int i, passed = 1;
237355b4669Sjacobs 
238355b4669Sjacobs 			name = strtok(buf, " \t\n");
239082e8485SToomas Soome 			if (name == NULL)
240082e8485SToomas Soome 				continue;
241355b4669Sjacobs 
242*f4593de7SToomas Soome 			for (i = 0; ((passed == 1) && (name[i] != '\0')); i++) {
243355b4669Sjacobs 				if (isalpha(name[i]) != 0)
244355b4669Sjacobs 					name[i] = tolower(name[i]);
245355b4669Sjacobs 				else if ((name[i] == '_') || (name[i] == '-'))
246355b4669Sjacobs 					name[i] = '-';
247355b4669Sjacobs 				else
248355b4669Sjacobs 					passed = 0;
249*f4593de7SToomas Soome 			}
250355b4669Sjacobs 
251355b4669Sjacobs 			if ((passed == 1) &&
252355b4669Sjacobs 			    ((file = strtok(NULL, " \t\n")) != NULL)) {
253355b4669Sjacobs 					char path[1024];
254355b4669Sjacobs 
255355b4669Sjacobs 				snprintf(path, sizeof (path),
256*f4593de7SToomas Soome 				    "/usr/lib/locale/%s", file);
257*f4593de7SToomas Soome 
258*f4593de7SToomas Soome 				if (access(path, F_OK) != 0)
259*f4593de7SToomas Soome 					continue;
260355b4669Sjacobs 
261*f4593de7SToomas Soome 				papiAttributeListAddString(attributes,
262*f4593de7SToomas Soome 				    PAPI_ATTR_APPEND,
263*f4593de7SToomas Soome 				    "generated-natural-language-supported",
264*f4593de7SToomas Soome 				    name);
265355b4669Sjacobs 			}
266355b4669Sjacobs 		}
267082e8485SToomas Soome 		(void) fclose(fp);
268355b4669Sjacobs 	}
269355b4669Sjacobs }
270355b4669Sjacobs 
271355b4669Sjacobs void
papi_to_ipp_printer_group(papi_attribute_t *** response,papi_attribute_t ** request,int flags,papi_printer_t p)272355b4669Sjacobs papi_to_ipp_printer_group(papi_attribute_t ***response,
273*f4593de7SToomas Soome     papi_attribute_t **request, int flags, papi_printer_t p)
274355b4669Sjacobs {
275355b4669Sjacobs 	papi_attribute_t **ipp_group = NULL;
276355b4669Sjacobs 
277355b4669Sjacobs 	copy_attributes(&ipp_group, papiPrinterGetAttributeList(p));
278355b4669Sjacobs 
279355b4669Sjacobs 	/* Windows clients appear to have a problem with very large values */
280355b4669Sjacobs 	papiAttributeListDelete(&ipp_group, "lpsched-printer-ppd-contents");
281355b4669Sjacobs 
282355b4669Sjacobs 	add_default_attributes(&ipp_group);
283355b4669Sjacobs 	ipp_operations_supported(&ipp_group, request);
284355b4669Sjacobs 
285355b4669Sjacobs 	(void) papiAttributeListAddCollection(response, flags,
286*f4593de7SToomas Soome 	    "printer-attributes-group", ipp_group);
287355b4669Sjacobs 	papiAttributeListFree(ipp_group);
288355b4669Sjacobs }
289355b4669Sjacobs 
290355b4669Sjacobs void
papi_to_ipp_job_group(papi_attribute_t *** response,papi_attribute_t ** request,int flags,papi_job_t j)291355b4669Sjacobs papi_to_ipp_job_group(papi_attribute_t ***response,
292*f4593de7SToomas Soome     papi_attribute_t **request, int flags, papi_job_t j)
293355b4669Sjacobs {
294355b4669Sjacobs 	papi_attribute_t **ipp_group = NULL;
295355b4669Sjacobs 
296355b4669Sjacobs 	copy_attributes(&ipp_group, papiJobGetAttributeList(j));
297355b4669Sjacobs 
298355b4669Sjacobs 	(void) papiAttributeListAddCollection(response, flags,
299*f4593de7SToomas Soome 	    "job-attributes-group", ipp_group);
300355b4669Sjacobs 	papiAttributeListFree(ipp_group);
301355b4669Sjacobs }
302