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 *
ipp_svc_status_mesg(papi_service_t svc,papi_status_t status)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 *
destination_from_printer_uri(char * uri)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
get_printer_id(papi_attribute_t ** attributes,char ** printer,int * id)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
get_string_list(papi_attribute_t ** attributes,char * name,char *** values)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
add_default_attributes(papi_attribute_t *** attributes)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
massage_printer_attributes_group(papi_attribute_t ** group,char * printer_uri)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
massage_job_attributes_group(papi_attribute_t ** group,char * printer_uri)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
massage_response(papi_attribute_t ** request,papi_attribute_t ** response)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
add_supported_locales(papi_attribute_t *** attributes)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
papi_to_ipp_printer_group(papi_attribute_t *** response,papi_attribute_t ** request,int flags,papi_printer_t p)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
papi_to_ipp_job_group(papi_attribute_t *** response,papi_attribute_t ** request,int flags,papi_job_t j)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