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 44 http_encryption_t 45 http_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 63 papi_status_t 64 service_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 123 papi_status_t 124 papiServiceCreate(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 166 void 167 papiServiceDestroy(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 191 papi_status_t 192 papiServiceSetUserName(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 210 papi_status_t 211 papiServiceSetPassword(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 229 papi_status_t 230 papiServiceSetEncryption(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 247 papi_status_t 248 papiServiceSetAuthCB(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 264 papi_status_t 265 papiServiceSetAppData(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 279 char * 280 papiServiceGetServiceName(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 293 char * 294 papiServiceGetUserName(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 307 char * 308 papiServiceGetPassword(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 321 papi_encryption_t 322 papiServiceGetEncryption(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 335 void * 336 papiServiceGetAppData(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 349 papi_attribute_t ** 350 papiServiceGetAttributeList(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 361 char * 362 papiServiceGetStatusMessage(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 373 void 374 detailed_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