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