1*2264Sjacobs /* 2*2264Sjacobs * CDDL HEADER START 3*2264Sjacobs * 4*2264Sjacobs * The contents of this file are subject to the terms of the 5*2264Sjacobs * Common Development and Distribution License (the "License"). 6*2264Sjacobs * You may not use this file except in compliance with the License. 7*2264Sjacobs * 8*2264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*2264Sjacobs * or http://www.opensolaris.org/os/licensing. 10*2264Sjacobs * See the License for the specific language governing permissions 11*2264Sjacobs * and limitations under the License. 12*2264Sjacobs * 13*2264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 14*2264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*2264Sjacobs * If applicable, add the following below this CDDL HEADER, with the 16*2264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 17*2264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 18*2264Sjacobs * 19*2264Sjacobs * CDDL HEADER END 20*2264Sjacobs */ 21*2264Sjacobs 22*2264Sjacobs /* 23*2264Sjacobs * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*2264Sjacobs * Use is subject to license terms. 25*2264Sjacobs * 26*2264Sjacobs */ 27*2264Sjacobs 28*2264Sjacobs /* $Id: service.c 172 2006-05-24 20:54:00Z njacobs $ */ 29*2264Sjacobs 30*2264Sjacobs #pragma ident "%Z%%M% %I% %E% SMI" 31*2264Sjacobs 32*2264Sjacobs /*LINTLIBRARY*/ 33*2264Sjacobs 34*2264Sjacobs #include <stdlib.h> 35*2264Sjacobs #include <stdio.h> 36*2264Sjacobs #include <stdarg.h> 37*2264Sjacobs #include <string.h> 38*2264Sjacobs #include <alloca.h> 39*2264Sjacobs #include <libintl.h> 40*2264Sjacobs #include <papi_impl.h> 41*2264Sjacobs #include <config-site.h> 42*2264Sjacobs 43*2264Sjacobs static int 44*2264Sjacobs interposed_auth_callback(papi_service_t handle, void *app_data) 45*2264Sjacobs { 46*2264Sjacobs int result = -1; 47*2264Sjacobs service_t *svc = app_data; 48*2264Sjacobs 49*2264Sjacobs if (svc != NULL) 50*2264Sjacobs result = svc->authCB(svc, svc->app_data); 51*2264Sjacobs 52*2264Sjacobs return (result); 53*2264Sjacobs } 54*2264Sjacobs 55*2264Sjacobs static char * 56*2264Sjacobs default_service_uri(char *fallback) 57*2264Sjacobs { 58*2264Sjacobs char *result = NULL; 59*2264Sjacobs 60*2264Sjacobs if ((result = getenv("PAPI_SERVICE_URI")) == NULL) { 61*2264Sjacobs char *cups; 62*2264Sjacobs 63*2264Sjacobs if ((cups = getenv("CUPS_SERVER")) != NULL) { 64*2264Sjacobs char buf[BUFSIZ]; 65*2264Sjacobs 66*2264Sjacobs snprintf(buf, sizeof (buf), "ipp://%s/printers/", cups); 67*2264Sjacobs result = strdup(buf); 68*2264Sjacobs } 69*2264Sjacobs } 70*2264Sjacobs 71*2264Sjacobs if (result == NULL) 72*2264Sjacobs result = fallback; 73*2264Sjacobs 74*2264Sjacobs return (result); 75*2264Sjacobs } 76*2264Sjacobs 77*2264Sjacobs static char * 78*2264Sjacobs default_print_service() 79*2264Sjacobs { 80*2264Sjacobs static char *result = NULL; 81*2264Sjacobs 82*2264Sjacobs if (result == NULL) { 83*2264Sjacobs char *service_uri = default_service_uri(DEFAULT_SERVICE_URI); 84*2264Sjacobs uri_t *uri = NULL; 85*2264Sjacobs 86*2264Sjacobs if (uri_from_string(service_uri, &uri) != -1) 87*2264Sjacobs result = strdup(uri->scheme); 88*2264Sjacobs 89*2264Sjacobs if (uri != NULL) 90*2264Sjacobs uri_free(uri); 91*2264Sjacobs } 92*2264Sjacobs 93*2264Sjacobs return (result); 94*2264Sjacobs } 95*2264Sjacobs 96*2264Sjacobs static papi_status_t 97*2264Sjacobs service_load(service_t *svc, char *name) 98*2264Sjacobs { 99*2264Sjacobs papi_status_t result; 100*2264Sjacobs char *scheme = default_print_service(); 101*2264Sjacobs 102*2264Sjacobs if (svc->so_handle != NULL) /* already loaded */ 103*2264Sjacobs return (PAPI_OK); 104*2264Sjacobs 105*2264Sjacobs if (name == NULL) /* no info, can't load yet */ 106*2264Sjacobs return (PAPI_OK); 107*2264Sjacobs 108*2264Sjacobs /* Lookup the printer in the configuration DB */ 109*2264Sjacobs svc->attributes = getprinterbyname((char *)name, NULL); 110*2264Sjacobs 111*2264Sjacobs if (svc->attributes != NULL) { 112*2264Sjacobs char *tmp = NULL; 113*2264Sjacobs 114*2264Sjacobs /* Printer found (or was a URI), use the attribute data */ 115*2264Sjacobs papiAttributeListGetString(svc->attributes, NULL, 116*2264Sjacobs "printer-uri-supported", &tmp); 117*2264Sjacobs if (tmp != NULL) 118*2264Sjacobs svc->name = strdup(tmp); 119*2264Sjacobs 120*2264Sjacobs /* parse the URI and set the scheme(print service) */ 121*2264Sjacobs if (uri_from_string(svc->name, &svc->uri) != -1) 122*2264Sjacobs scheme = (svc->uri)->scheme; 123*2264Sjacobs 124*2264Sjacobs /* override the scheme if it was in the attributes */ 125*2264Sjacobs papiAttributeListGetString(svc->attributes, NULL, 126*2264Sjacobs "print-service-module", &scheme); 127*2264Sjacobs 128*2264Sjacobs } else /* not found, assume it is the actual print service name */ 129*2264Sjacobs scheme = name; 130*2264Sjacobs 131*2264Sjacobs result = psm_open(svc, scheme); 132*2264Sjacobs switch (result) { 133*2264Sjacobs case PAPI_OK: 134*2264Sjacobs break; /* no error */ 135*2264Sjacobs case PAPI_URI_SCHEME: 136*2264Sjacobs result = PAPI_NOT_FOUND; 137*2264Sjacobs #ifdef DEBUG 138*2264Sjacobs detailed_error(svc, "Unable to load service for: %s", name); 139*2264Sjacobs #endif 140*2264Sjacobs break; 141*2264Sjacobs default: /* set the detailed message */ 142*2264Sjacobs detailed_error(svc, "Unable to load service (%s) for: %s", 143*2264Sjacobs scheme, name); 144*2264Sjacobs } 145*2264Sjacobs 146*2264Sjacobs return (result); 147*2264Sjacobs } 148*2264Sjacobs 149*2264Sjacobs static papi_status_t 150*2264Sjacobs service_send_peer(service_t *svc) 151*2264Sjacobs { 152*2264Sjacobs papi_status_t result = PAPI_OK; 153*2264Sjacobs 154*2264Sjacobs if ((svc->peer_fd != -1) && (svc->so_handle != NULL) && 155*2264Sjacobs (svc->svc_handle != NULL)) { 156*2264Sjacobs papi_status_t (*f)(); 157*2264Sjacobs 158*2264Sjacobs f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetPeer"); 159*2264Sjacobs 160*2264Sjacobs if (f != NULL) 161*2264Sjacobs result = f(svc->svc_handle, svc->peer_fd); 162*2264Sjacobs } 163*2264Sjacobs 164*2264Sjacobs return (result); 165*2264Sjacobs } 166*2264Sjacobs 167*2264Sjacobs papi_status_t 168*2264Sjacobs service_connect(service_t *svc, char *name) 169*2264Sjacobs { 170*2264Sjacobs papi_status_t result = PAPI_NOT_POSSIBLE; 171*2264Sjacobs 172*2264Sjacobs /* if there is no print service module loaded, try and load one. */ 173*2264Sjacobs if (svc->so_handle == NULL) 174*2264Sjacobs result = service_load(svc, name); 175*2264Sjacobs else if ((svc->name == NULL) && (name != NULL)) 176*2264Sjacobs svc->name = strdup(name); 177*2264Sjacobs 178*2264Sjacobs /* 179*2264Sjacobs * the print service module is loaded, but we don't have a service 180*2264Sjacobs * handle. 181*2264Sjacobs */ 182*2264Sjacobs if (svc->so_handle != NULL) { 183*2264Sjacobs papi_status_t (*f)(); 184*2264Sjacobs 185*2264Sjacobs f = (papi_status_t (*)())psm_sym(svc, "papiServiceCreate"); 186*2264Sjacobs 187*2264Sjacobs if (f != NULL) { 188*2264Sjacobs char *user = svc->user; 189*2264Sjacobs char *password = svc->password; 190*2264Sjacobs 191*2264Sjacobs /* if no API user, try the URI user */ 192*2264Sjacobs if ((user == NULL) && (svc->uri != NULL)) 193*2264Sjacobs user = (svc->uri)->user; 194*2264Sjacobs /* if no API password, try the URI password */ 195*2264Sjacobs if ((password == NULL) && (svc->uri != NULL)) 196*2264Sjacobs password = (svc->uri)->password; 197*2264Sjacobs 198*2264Sjacobs result = f(&svc->svc_handle, svc->name, user, password, 199*2264Sjacobs (svc->authCB ? interposed_auth_callback 200*2264Sjacobs : NULL), 201*2264Sjacobs svc->encryption, svc); 202*2264Sjacobs (void) service_send_peer(svc); 203*2264Sjacobs } 204*2264Sjacobs } 205*2264Sjacobs 206*2264Sjacobs return (result); 207*2264Sjacobs } 208*2264Sjacobs 209*2264Sjacobs papi_status_t 210*2264Sjacobs papiServiceCreate(papi_service_t *handle, char *service_name, char *user_name, 211*2264Sjacobs char *password, 212*2264Sjacobs int (*authCB)(papi_service_t svc, void *app_data), 213*2264Sjacobs papi_encryption_t encryption, void *app_data) 214*2264Sjacobs { 215*2264Sjacobs papi_status_t result = PAPI_NOT_POSSIBLE; 216*2264Sjacobs service_t *svc = NULL; 217*2264Sjacobs uri_t *u = NULL; 218*2264Sjacobs 219*2264Sjacobs if (handle == NULL) 220*2264Sjacobs return (PAPI_BAD_ARGUMENT); 221*2264Sjacobs 222*2264Sjacobs if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL) 223*2264Sjacobs return (PAPI_TEMPORARY_ERROR); 224*2264Sjacobs 225*2264Sjacobs svc->peer_fd = -1; 226*2264Sjacobs 227*2264Sjacobs if (user_name != NULL) 228*2264Sjacobs svc->user = strdup(user_name); 229*2264Sjacobs 230*2264Sjacobs if (password != NULL) 231*2264Sjacobs svc->password = strdup(password); 232*2264Sjacobs 233*2264Sjacobs svc->encryption = encryption; 234*2264Sjacobs 235*2264Sjacobs if (authCB != NULL) 236*2264Sjacobs svc->authCB = authCB; 237*2264Sjacobs 238*2264Sjacobs if (app_data != NULL) 239*2264Sjacobs svc->app_data = app_data; 240*2264Sjacobs 241*2264Sjacobs /* If not specified, get a "default" service from the environment */ 242*2264Sjacobs if (service_name == NULL) 243*2264Sjacobs service_name = default_service_uri(NULL); 244*2264Sjacobs 245*2264Sjacobs if (service_name != NULL) { 246*2264Sjacobs result = service_load(svc, service_name); 247*2264Sjacobs /* if the psm loaded and the svc contains a URI, connect */ 248*2264Sjacobs if ((result == PAPI_OK) && (svc->uri != NULL)) 249*2264Sjacobs result = service_connect(svc, service_name); 250*2264Sjacobs } else 251*2264Sjacobs result = PAPI_OK; 252*2264Sjacobs 253*2264Sjacobs return (result); 254*2264Sjacobs } 255*2264Sjacobs 256*2264Sjacobs void 257*2264Sjacobs papiServiceDestroy(papi_service_t handle) 258*2264Sjacobs { 259*2264Sjacobs if (handle != NULL) { 260*2264Sjacobs service_t *svc = handle; 261*2264Sjacobs 262*2264Sjacobs if (svc->so_handle != NULL) { 263*2264Sjacobs if (svc->svc_handle != NULL) { 264*2264Sjacobs void (*f)(); 265*2264Sjacobs 266*2264Sjacobs f = (void (*)())psm_sym(svc, 267*2264Sjacobs "papiServiceDestroy"); 268*2264Sjacobs f(svc->svc_handle); 269*2264Sjacobs } 270*2264Sjacobs psm_close(svc->so_handle); 271*2264Sjacobs } 272*2264Sjacobs if (svc->attributes != NULL) 273*2264Sjacobs papiAttributeListFree(svc->attributes); 274*2264Sjacobs if (svc->name != NULL) 275*2264Sjacobs free(svc->name); 276*2264Sjacobs if (svc->user != NULL) 277*2264Sjacobs free(svc->user); 278*2264Sjacobs if (svc->password != NULL) 279*2264Sjacobs free(svc->password); 280*2264Sjacobs if (svc->uri != NULL) 281*2264Sjacobs uri_free(svc->uri); 282*2264Sjacobs 283*2264Sjacobs free(handle); 284*2264Sjacobs } 285*2264Sjacobs } 286*2264Sjacobs 287*2264Sjacobs papi_status_t 288*2264Sjacobs papiServiceSetPeer(papi_service_t handle, int fd) 289*2264Sjacobs { 290*2264Sjacobs papi_status_t result = PAPI_OK; 291*2264Sjacobs 292*2264Sjacobs if (handle != NULL) { 293*2264Sjacobs service_t *svc = handle; 294*2264Sjacobs 295*2264Sjacobs svc->peer_fd = fd; 296*2264Sjacobs result = service_send_peer(svc); 297*2264Sjacobs } else 298*2264Sjacobs result = PAPI_BAD_ARGUMENT; 299*2264Sjacobs 300*2264Sjacobs return (result); 301*2264Sjacobs } 302*2264Sjacobs 303*2264Sjacobs papi_status_t 304*2264Sjacobs papiServiceSetUserName(papi_service_t handle, char *user_name) 305*2264Sjacobs { 306*2264Sjacobs papi_status_t result = PAPI_OK; 307*2264Sjacobs 308*2264Sjacobs if (handle != NULL) { 309*2264Sjacobs service_t *svc = handle; 310*2264Sjacobs papi_status_t (*f)(); 311*2264Sjacobs 312*2264Sjacobs if (svc->user != NULL) 313*2264Sjacobs free(svc->user); 314*2264Sjacobs if (user_name != NULL) 315*2264Sjacobs svc->user = strdup(user_name); 316*2264Sjacobs f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetUserName"); 317*2264Sjacobs if (f != NULL) 318*2264Sjacobs result = f(svc->svc_handle, user_name); 319*2264Sjacobs } else 320*2264Sjacobs result = PAPI_BAD_ARGUMENT; 321*2264Sjacobs 322*2264Sjacobs return (result); 323*2264Sjacobs } 324*2264Sjacobs 325*2264Sjacobs papi_status_t 326*2264Sjacobs papiServiceSetPassword(papi_service_t handle, char *password) 327*2264Sjacobs { 328*2264Sjacobs papi_status_t result = PAPI_OK; 329*2264Sjacobs 330*2264Sjacobs if (handle != NULL) { 331*2264Sjacobs service_t *svc = handle; 332*2264Sjacobs papi_status_t (*f)(); 333*2264Sjacobs 334*2264Sjacobs if (svc->password != NULL) 335*2264Sjacobs free(svc->password); 336*2264Sjacobs if (password != NULL) 337*2264Sjacobs svc->password = strdup(password); 338*2264Sjacobs f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetPassword"); 339*2264Sjacobs if (f != NULL) 340*2264Sjacobs result = f(svc->svc_handle, password); 341*2264Sjacobs } else 342*2264Sjacobs result = PAPI_BAD_ARGUMENT; 343*2264Sjacobs 344*2264Sjacobs return (result); 345*2264Sjacobs } 346*2264Sjacobs 347*2264Sjacobs papi_status_t 348*2264Sjacobs papiServiceSetEncryption(papi_service_t handle, papi_encryption_t encryption) 349*2264Sjacobs { 350*2264Sjacobs papi_status_t result = PAPI_OK; 351*2264Sjacobs 352*2264Sjacobs if (handle != NULL) { 353*2264Sjacobs service_t *svc = handle; 354*2264Sjacobs papi_status_t (*f)(); 355*2264Sjacobs 356*2264Sjacobs svc->encryption = encryption; 357*2264Sjacobs f = (papi_status_t (*)())psm_sym(svc, 358*2264Sjacobs "papiServiceSetEncryption"); 359*2264Sjacobs if (f != NULL) 360*2264Sjacobs result = f(svc->svc_handle, encryption); 361*2264Sjacobs } else 362*2264Sjacobs result = PAPI_BAD_ARGUMENT; 363*2264Sjacobs 364*2264Sjacobs return (result); 365*2264Sjacobs } 366*2264Sjacobs 367*2264Sjacobs papi_status_t 368*2264Sjacobs papiServiceSetAuthCB(papi_service_t handle, 369*2264Sjacobs int (*authCB)(papi_service_t svc, void *app_data)) 370*2264Sjacobs { 371*2264Sjacobs papi_status_t result = PAPI_OK; 372*2264Sjacobs 373*2264Sjacobs if (handle != NULL) { 374*2264Sjacobs service_t *svc = handle; 375*2264Sjacobs papi_status_t (*f)(); 376*2264Sjacobs 377*2264Sjacobs svc->authCB = authCB; 378*2264Sjacobs f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetAuthCB"); 379*2264Sjacobs if (f != NULL) 380*2264Sjacobs result = f(svc->svc_handle, interposed_auth_callback); 381*2264Sjacobs } else 382*2264Sjacobs result = PAPI_BAD_ARGUMENT; 383*2264Sjacobs 384*2264Sjacobs return (result); 385*2264Sjacobs } 386*2264Sjacobs 387*2264Sjacobs 388*2264Sjacobs papi_status_t 389*2264Sjacobs papiServiceSetAppData(papi_service_t handle, void *app_data) 390*2264Sjacobs { 391*2264Sjacobs papi_status_t result = PAPI_OK; 392*2264Sjacobs 393*2264Sjacobs if (handle != NULL) { 394*2264Sjacobs service_t *svc = handle; 395*2264Sjacobs papi_status_t (*f)(); 396*2264Sjacobs 397*2264Sjacobs svc->app_data = (void *)app_data; 398*2264Sjacobs } else 399*2264Sjacobs result = PAPI_BAD_ARGUMENT; 400*2264Sjacobs 401*2264Sjacobs return (result); 402*2264Sjacobs } 403*2264Sjacobs 404*2264Sjacobs char * 405*2264Sjacobs papiServiceGetServiceName(papi_service_t handle) 406*2264Sjacobs { 407*2264Sjacobs char *result = NULL; 408*2264Sjacobs 409*2264Sjacobs if (handle != NULL) { 410*2264Sjacobs service_t *svc = handle; 411*2264Sjacobs char *(*f)(); 412*2264Sjacobs 413*2264Sjacobs f = (char *(*)())psm_sym(svc, "papiServiceGetServiceName"); 414*2264Sjacobs if (f != NULL) 415*2264Sjacobs result = f(svc->svc_handle); 416*2264Sjacobs if (result == NULL) 417*2264Sjacobs result = svc->name; 418*2264Sjacobs } 419*2264Sjacobs 420*2264Sjacobs return (result); 421*2264Sjacobs } 422*2264Sjacobs 423*2264Sjacobs char * 424*2264Sjacobs papiServiceGetUserName(papi_service_t handle) 425*2264Sjacobs { 426*2264Sjacobs char *result = NULL; 427*2264Sjacobs 428*2264Sjacobs if (handle != NULL) { 429*2264Sjacobs service_t *svc = handle; 430*2264Sjacobs char *(*f)(); 431*2264Sjacobs 432*2264Sjacobs f = (char *(*)())psm_sym(svc, "papiServiceGetUserName"); 433*2264Sjacobs if (f != NULL) 434*2264Sjacobs result = f(svc->svc_handle); 435*2264Sjacobs if (result == NULL) 436*2264Sjacobs result = svc->user; 437*2264Sjacobs } 438*2264Sjacobs 439*2264Sjacobs return (result); 440*2264Sjacobs } 441*2264Sjacobs 442*2264Sjacobs char * 443*2264Sjacobs papiServiceGetPassword(papi_service_t handle) 444*2264Sjacobs { 445*2264Sjacobs char *result = NULL; 446*2264Sjacobs 447*2264Sjacobs if (handle != NULL) { 448*2264Sjacobs service_t *svc = handle; 449*2264Sjacobs char *(*f)(); 450*2264Sjacobs 451*2264Sjacobs f = (char *(*)())psm_sym(svc, "papiServiceGetPassword"); 452*2264Sjacobs if (f != NULL) 453*2264Sjacobs result = f(svc->svc_handle); 454*2264Sjacobs if (result == NULL) 455*2264Sjacobs result = svc->password; 456*2264Sjacobs } 457*2264Sjacobs 458*2264Sjacobs return (result); 459*2264Sjacobs } 460*2264Sjacobs 461*2264Sjacobs papi_encryption_t 462*2264Sjacobs papiServiceGetEncryption(papi_service_t handle) 463*2264Sjacobs { 464*2264Sjacobs papi_encryption_t result = PAPI_ENCRYPT_NEVER; 465*2264Sjacobs 466*2264Sjacobs if (handle != NULL) { 467*2264Sjacobs service_t *svc = handle; 468*2264Sjacobs papi_encryption_t (*f)(); 469*2264Sjacobs 470*2264Sjacobs f = (papi_encryption_t (*)())psm_sym(svc, 471*2264Sjacobs "papiServiceGetEncryption"); 472*2264Sjacobs if (f != NULL) 473*2264Sjacobs result = f(svc->svc_handle); 474*2264Sjacobs if (result == PAPI_ENCRYPT_NEVER) 475*2264Sjacobs result = svc->encryption; 476*2264Sjacobs } 477*2264Sjacobs 478*2264Sjacobs return (result); 479*2264Sjacobs } 480*2264Sjacobs 481*2264Sjacobs void * 482*2264Sjacobs papiServiceGetAppData(papi_service_t handle) 483*2264Sjacobs { 484*2264Sjacobs void *result = NULL; 485*2264Sjacobs service_t *svc = handle; 486*2264Sjacobs 487*2264Sjacobs if (handle != NULL) 488*2264Sjacobs result = svc->app_data; 489*2264Sjacobs 490*2264Sjacobs return (result); 491*2264Sjacobs } 492*2264Sjacobs 493*2264Sjacobs papi_attribute_t ** 494*2264Sjacobs papiServiceGetAttributeList(papi_service_t handle) 495*2264Sjacobs { 496*2264Sjacobs papi_attribute_t **result = NULL; 497*2264Sjacobs service_t *svc = handle; 498*2264Sjacobs 499*2264Sjacobs if (handle != NULL) { 500*2264Sjacobs papi_attribute_t **(*f)(); 501*2264Sjacobs 502*2264Sjacobs if (svc->so_handle == NULL) { 503*2264Sjacobs char *uri = default_service_uri(DEFAULT_SERVICE_URI); 504*2264Sjacobs 505*2264Sjacobs if (service_connect(svc, uri) != PAPI_OK) 506*2264Sjacobs return (NULL); 507*2264Sjacobs } 508*2264Sjacobs 509*2264Sjacobs f = (papi_attribute_t **(*)())psm_sym(svc, 510*2264Sjacobs "papiServiceGetAttributeList"); 511*2264Sjacobs if (f != NULL) 512*2264Sjacobs result = f(svc->svc_handle); 513*2264Sjacobs } else 514*2264Sjacobs result = svc->attributes; 515*2264Sjacobs 516*2264Sjacobs return (result); 517*2264Sjacobs } 518*2264Sjacobs 519*2264Sjacobs char * 520*2264Sjacobs papiServiceGetStatusMessage(papi_service_t handle) 521*2264Sjacobs { 522*2264Sjacobs char *result = NULL; 523*2264Sjacobs service_t *svc = handle; 524*2264Sjacobs 525*2264Sjacobs if (handle != NULL) { 526*2264Sjacobs char *(*f)(); 527*2264Sjacobs 528*2264Sjacobs f = (char *(*)())psm_sym(svc, "papiServiceGetStatusMessage"); 529*2264Sjacobs if (f != NULL) 530*2264Sjacobs result = f(svc->svc_handle); 531*2264Sjacobs } 532*2264Sjacobs if (result == NULL) { 533*2264Sjacobs papiAttributeListGetString(svc->attributes, NULL, 534*2264Sjacobs "detailed-status-message", &result); 535*2264Sjacobs } 536*2264Sjacobs 537*2264Sjacobs return (result); 538*2264Sjacobs } 539*2264Sjacobs 540*2264Sjacobs void 541*2264Sjacobs detailed_error(service_t *svc, char *fmt, ...) 542*2264Sjacobs { 543*2264Sjacobs if ((svc != NULL) && (fmt != NULL)) { 544*2264Sjacobs va_list ap; 545*2264Sjacobs size_t size; 546*2264Sjacobs char *message = alloca(BUFSIZ); 547*2264Sjacobs 548*2264Sjacobs va_start(ap, fmt); 549*2264Sjacobs /* 550*2264Sjacobs * fill in the message. If the buffer is too small, allocate 551*2264Sjacobs * one that is large enough and fill it in. 552*2264Sjacobs */ 553*2264Sjacobs if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ) 554*2264Sjacobs if ((message = alloca(size)) != NULL) 555*2264Sjacobs vsnprintf(message, size, fmt, ap); 556*2264Sjacobs va_end(ap); 557*2264Sjacobs 558*2264Sjacobs papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, 559*2264Sjacobs "detailed-status-message", message); 560*2264Sjacobs #ifdef DEBUG 561*2264Sjacobs fprintf(stderr, "detailed_error(%s)\n", message); 562*2264Sjacobs #endif 563*2264Sjacobs } 564*2264Sjacobs } 565