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: service.c 171 2006-05-20 06:00:32Z njacobs $ */ 29 30 #include <stdlib.h> 31 #include <stdio.h> 32 #include <stdarg.h> 33 #include <string.h> 34 #include <libintl.h> 35 #include <papi_impl.h> 36 37 #include <config-site.h> 38 39 http_encryption_t 40 http_encryption_type(papi_encryption_t encryption) 41 { 42 switch (encryption) { 43 case PAPI_ENCRYPT_IF_REQUESTED: 44 return (HTTP_ENCRYPT_IF_REQUESTED); 45 case PAPI_ENCRYPT_REQUIRED: 46 return (HTTP_ENCRYPT_REQUIRED); 47 case PAPI_ENCRYPT_ALWAYS: 48 return (HTTP_ENCRYPT_ALWAYS); 49 case PAPI_ENCRYPT_NEVER: 50 return (HTTP_ENCRYPT_NEVER); 51 default: 52 ; /* this should log an error */ 53 } 54 55 return (HTTP_ENCRYPT_NEVER); /* should never get here */ 56 } 57 58 papi_status_t 59 service_connect(service_t *svc, char *service_name) 60 { 61 papi_status_t result = PAPI_OK; 62 int port = 631; 63 64 if (svc == NULL) 65 return (PAPI_BAD_ARGUMENT); 66 67 if (svc->connection != NULL) /* alread connected ? */ 68 return (PAPI_OK); 69 70 if (svc->uri == NULL) 71 uri_from_string(service_name, &svc->uri); 72 73 if ((service_name != NULL) && (svc->uri == NULL)) { 74 /* 75 * a name was supplied and it's not in URI form, we will 76 * try to use a "default" IPP service under the assumption 77 * that this is most likely a short-form printer name from 78 * from a papiPrinter*() or papiJob*() call and not from a 79 * papiServiceCreate() call. 80 */ 81 if ((service_name = getenv("PAPI_SERVICE_URI")) == NULL) { 82 char *cups; 83 84 if ((cups = getenv("CUPS_SERVER")) != NULL) { 85 char buf[BUFSIZ]; 86 87 snprintf(buf, sizeof (buf), 88 "ipp://%s/printers/", cups); 89 service_name = strdup(buf); 90 } 91 } 92 if (service_name == NULL) 93 service_name = DEFAULT_IPP_SERVICE_URI; 94 95 uri_from_string(service_name, &svc->uri); 96 } 97 98 if (svc->uri == NULL) 99 return (PAPI_NOT_POSSIBLE); 100 101 if (svc->uri->port != NULL) 102 port = strtol(svc->uri->port, NULL, 10); 103 104 svc->connection = httpConnectEncrypt(svc->uri->host, port, 105 http_encryption_type(svc->encryption)); 106 if (svc->connection == NULL) { 107 if (svc->uri != NULL) { 108 uri_free(svc->uri); 109 svc->uri = NULL; 110 } 111 result = PAPI_SERVICE_UNAVAILABLE; 112 } else if (service_name != NULL) 113 svc->name = strdup(service_name); 114 115 return (result); 116 } 117 118 papi_status_t 119 papiServiceCreate(papi_service_t *handle, char *service_name, 120 char *user_name, char *password, 121 int (*authCB)(papi_service_t svc, void *app_data), 122 papi_encryption_t encryption, void *app_data) 123 { 124 papi_status_t result = PAPI_NOT_POSSIBLE; 125 service_t *svc = NULL; 126 char *encoding = getenv("HTTP_TRANSFER_ENCODING"); 127 128 if (handle == NULL) 129 return (PAPI_BAD_ARGUMENT); 130 131 if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL) 132 return (PAPI_TEMPORARY_ERROR); 133 134 if (user_name != NULL) 135 svc->user = strdup(user_name); 136 137 if (password != NULL) 138 svc->password = strdup(password); 139 140 svc->encryption = encryption; 141 142 if (authCB != NULL) 143 svc->authCB = authCB; 144 145 if (app_data != NULL) 146 svc->app_data = app_data; 147 148 if ((encoding != NULL) && (strcasecmp(encoding, "content-length") == 0)) 149 svc->transfer_encoding = TRANSFER_ENCODING_LENGTH; 150 else 151 svc->transfer_encoding = TRANSFER_ENCODING_CHUNKED; 152 153 if (service_name != NULL) { 154 result = service_connect(svc, service_name); 155 } else 156 result = PAPI_OK; 157 158 return (result); 159 } 160 161 void 162 papiServiceDestroy(papi_service_t handle) 163 { 164 if (handle != NULL) { 165 service_t *svc = handle; 166 167 if (svc->attributes != NULL) 168 papiAttributeListFree(svc->attributes); 169 if (svc->name != NULL) 170 free(svc->name); 171 if (svc->user != NULL) 172 free(svc->user); 173 if (svc->password != NULL) 174 free(svc->password); 175 if (svc->uri != NULL) 176 uri_free(svc->uri); 177 if (svc->post != NULL) 178 free(svc->post); 179 if (svc->connection != NULL) 180 httpClose(svc->connection); 181 182 free(handle); 183 } 184 } 185 186 papi_status_t 187 papiServiceSetUserName(papi_service_t handle, char *user_name) 188 { 189 papi_status_t result = PAPI_OK; 190 191 if (handle != NULL) { 192 service_t *svc = handle; 193 194 if (svc->user != NULL) 195 free(svc->user); 196 svc->user = NULL; 197 if (user_name != NULL) 198 svc->user = strdup(user_name); 199 } else 200 result = PAPI_BAD_ARGUMENT; 201 202 return (result); 203 } 204 205 papi_status_t 206 papiServiceSetPassword(papi_service_t handle, char *password) 207 { 208 papi_status_t result = PAPI_OK; 209 210 if (handle != NULL) { 211 service_t *svc = handle; 212 213 if (svc->password != NULL) 214 free(svc->password); 215 svc->password = NULL; 216 if (password != NULL) 217 svc->password = strdup(password); 218 } else 219 result = PAPI_BAD_ARGUMENT; 220 221 return (result); 222 } 223 224 papi_status_t 225 papiServiceSetEncryption(papi_service_t handle, 226 papi_encryption_t encryption) 227 { 228 papi_status_t result = PAPI_OK; 229 230 if (handle != NULL) { 231 service_t *svc = handle; 232 233 svc->encryption = encryption; 234 httpEncryption(svc->connection, 235 (http_encryption_t)svc->encryption); 236 } else 237 result = PAPI_BAD_ARGUMENT; 238 239 return (result); 240 } 241 242 papi_status_t 243 papiServiceSetAuthCB(papi_service_t handle, 244 int (*authCB)(papi_service_t svc, void *app_data)) 245 { 246 papi_status_t result = PAPI_OK; 247 248 if (handle != NULL) { 249 service_t *svc = handle; 250 251 svc->authCB = authCB; 252 } else 253 result = PAPI_BAD_ARGUMENT; 254 255 return (result); 256 } 257 258 259 papi_status_t 260 papiServiceSetAppData(papi_service_t handle, void *app_data) 261 { 262 papi_status_t result = PAPI_OK; 263 264 if (handle != NULL) { 265 service_t *svc = handle; 266 267 svc->app_data = (void *)app_data; 268 } else 269 result = PAPI_BAD_ARGUMENT; 270 271 return (result); 272 } 273 274 char * 275 papiServiceGetServiceName(papi_service_t handle) 276 { 277 char *result = NULL; 278 279 if (handle != NULL) { 280 service_t *svc = handle; 281 282 result = svc->name; 283 } 284 285 return (result); 286 } 287 288 char * 289 papiServiceGetUserName(papi_service_t handle) 290 { 291 char *result = NULL; 292 293 if (handle != NULL) { 294 service_t *svc = handle; 295 296 result = svc->user; 297 } 298 299 return (result); 300 } 301 302 char * 303 papiServiceGetPassword(papi_service_t handle) 304 { 305 char *result = NULL; 306 307 if (handle != NULL) { 308 service_t *svc = handle; 309 310 result = svc->password; 311 } 312 313 return (result); 314 } 315 316 papi_encryption_t 317 papiServiceGetEncryption(papi_service_t handle) 318 { 319 papi_encryption_t result = PAPI_ENCRYPT_NEVER; 320 321 if (handle != NULL) { 322 service_t *svc = handle; 323 324 result = svc->encryption; 325 } 326 327 return (result); 328 } 329 330 void * 331 papiServiceGetAppData(papi_service_t handle) 332 { 333 void *result = NULL; 334 335 if (handle != NULL) { 336 service_t *svc = handle; 337 338 result = svc->app_data; 339 } 340 341 return (result); 342 } 343 344 papi_attribute_t ** 345 papiServiceGetAttributeList(papi_service_t handle) 346 { 347 papi_attribute_t **result = NULL; 348 service_t *svc = handle; 349 350 if (handle != NULL) 351 result = svc->attributes; 352 353 return (result); 354 } 355 356 char * 357 papiServiceGetStatusMessage(papi_service_t handle) 358 { 359 char *result = NULL; 360 service_t *svc = handle; 361 362 papiAttributeListGetString(svc->attributes, NULL, 363 "detailed-status-message", &result); 364 365 return (result); 366 } 367 368 void 369 detailed_error(service_t *svc, char *fmt, ...) 370 { 371 if ((svc != NULL) && (fmt != NULL)) { 372 va_list ap; 373 char *message; 374 int rv; 375 376 va_start(ap, fmt); 377 rv = vasprintf(&message, fmt, ap); 378 va_end(ap); 379 380 if (rv >= 0) { 381 papiAttributeListAddString(&svc->attributes, 382 PAPI_ATTR_APPEND, "detailed-status-message", 383 message); 384 free(message); 385 } 386 } 387 } 388