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