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