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 * 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 * 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 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 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 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 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 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 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 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 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 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