12264Sjacobs /* 22264Sjacobs * CDDL HEADER START 32264Sjacobs * 42264Sjacobs * The contents of this file are subject to the terms of the 52264Sjacobs * Common Development and Distribution License (the "License"). 62264Sjacobs * You may not use this file except in compliance with the License. 72264Sjacobs * 82264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 92264Sjacobs * or http://www.opensolaris.org/os/licensing. 102264Sjacobs * See the License for the specific language governing permissions 112264Sjacobs * and limitations under the License. 122264Sjacobs * 132264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 142264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 152264Sjacobs * If applicable, add the following below this CDDL HEADER, with the 162264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 172264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 182264Sjacobs * 192264Sjacobs * CDDL HEADER END 202264Sjacobs */ 212264Sjacobs 222264Sjacobs /* 23*7132Sps29005 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 242264Sjacobs * Use is subject to license terms. 252264Sjacobs * 262264Sjacobs */ 272264Sjacobs 282264Sjacobs /* $Id: service.c 172 2006-05-24 20:54:00Z njacobs $ */ 292264Sjacobs 302264Sjacobs #pragma ident "%Z%%M% %I% %E% SMI" 312264Sjacobs 322264Sjacobs /*LINTLIBRARY*/ 332264Sjacobs 342264Sjacobs #include <stdlib.h> 352264Sjacobs #include <stdio.h> 362264Sjacobs #include <stdarg.h> 37*7132Sps29005 #include <sys/types.h> 38*7132Sps29005 #include <unistd.h> 392264Sjacobs #include <string.h> 402264Sjacobs #include <alloca.h> 412264Sjacobs #include <libintl.h> 422264Sjacobs #include <papi_impl.h> 432264Sjacobs #include <config-site.h> 442264Sjacobs 452264Sjacobs static int 462264Sjacobs interposed_auth_callback(papi_service_t handle, void *app_data) 472264Sjacobs { 482264Sjacobs int result = -1; 492264Sjacobs service_t *svc = app_data; 502264Sjacobs 512264Sjacobs if (svc != NULL) 522264Sjacobs result = svc->authCB(svc, svc->app_data); 532264Sjacobs 542264Sjacobs return (result); 552264Sjacobs } 562264Sjacobs 572264Sjacobs static char * 582264Sjacobs default_service_uri(char *fallback) 592264Sjacobs { 602264Sjacobs char *result = NULL; 612264Sjacobs 62*7132Sps29005 if (getuid() == geteuid()) 63*7132Sps29005 result = getenv("PAPI_SERVICE_URI"); 64*7132Sps29005 65*7132Sps29005 if (result == NULL) { 662264Sjacobs char *cups; 672264Sjacobs 682264Sjacobs if ((cups = getenv("CUPS_SERVER")) != NULL) { 692264Sjacobs char buf[BUFSIZ]; 702264Sjacobs 712264Sjacobs snprintf(buf, sizeof (buf), "ipp://%s/printers/", cups); 722264Sjacobs result = strdup(buf); 732264Sjacobs } 742264Sjacobs } 752264Sjacobs 762264Sjacobs if (result == NULL) 772264Sjacobs result = fallback; 782264Sjacobs 792264Sjacobs return (result); 802264Sjacobs } 812264Sjacobs 822264Sjacobs static char * 832264Sjacobs default_print_service() 842264Sjacobs { 852264Sjacobs static char *result = NULL; 862264Sjacobs 872264Sjacobs if (result == NULL) { 882264Sjacobs char *service_uri = default_service_uri(DEFAULT_SERVICE_URI); 892264Sjacobs uri_t *uri = NULL; 902264Sjacobs 912264Sjacobs if (uri_from_string(service_uri, &uri) != -1) 922264Sjacobs result = strdup(uri->scheme); 932264Sjacobs 942264Sjacobs if (uri != NULL) 952264Sjacobs uri_free(uri); 962264Sjacobs } 972264Sjacobs 982264Sjacobs return (result); 992264Sjacobs } 1002264Sjacobs 1012264Sjacobs static papi_status_t 1022264Sjacobs service_load(service_t *svc, char *name) 1032264Sjacobs { 1042264Sjacobs papi_status_t result; 1052264Sjacobs char *scheme = default_print_service(); 1062264Sjacobs 1072264Sjacobs if (svc->so_handle != NULL) /* already loaded */ 1082264Sjacobs return (PAPI_OK); 1092264Sjacobs 1102264Sjacobs if (name == NULL) /* no info, can't load yet */ 1112264Sjacobs return (PAPI_OK); 1122264Sjacobs 1132264Sjacobs /* Lookup the printer in the configuration DB */ 1142264Sjacobs svc->attributes = getprinterbyname((char *)name, NULL); 1152264Sjacobs 1162264Sjacobs if (svc->attributes != NULL) { 1172264Sjacobs char *tmp = NULL; 1182264Sjacobs 1192264Sjacobs /* Printer found (or was a URI), use the attribute data */ 1202264Sjacobs papiAttributeListGetString(svc->attributes, NULL, 1212264Sjacobs "printer-uri-supported", &tmp); 1222264Sjacobs if (tmp != NULL) 1232264Sjacobs svc->name = strdup(tmp); 1242264Sjacobs 1252264Sjacobs /* parse the URI and set the scheme(print service) */ 1262264Sjacobs if (uri_from_string(svc->name, &svc->uri) != -1) 1272264Sjacobs scheme = (svc->uri)->scheme; 1282264Sjacobs 1292264Sjacobs /* override the scheme if it was in the attributes */ 1302264Sjacobs papiAttributeListGetString(svc->attributes, NULL, 1312264Sjacobs "print-service-module", &scheme); 1322264Sjacobs 1332264Sjacobs } else /* not found, assume it is the actual print service name */ 1342264Sjacobs scheme = name; 1352264Sjacobs 1362264Sjacobs result = psm_open(svc, scheme); 1372264Sjacobs switch (result) { 1382264Sjacobs case PAPI_OK: 1392264Sjacobs break; /* no error */ 1402264Sjacobs case PAPI_URI_SCHEME: 1412264Sjacobs result = PAPI_NOT_FOUND; 1422264Sjacobs #ifdef DEBUG 1432264Sjacobs detailed_error(svc, "Unable to load service for: %s", name); 1442264Sjacobs #endif 1452264Sjacobs break; 1462264Sjacobs default: /* set the detailed message */ 1472264Sjacobs detailed_error(svc, "Unable to load service (%s) for: %s", 1482264Sjacobs scheme, name); 1492264Sjacobs } 1502264Sjacobs 1512264Sjacobs return (result); 1522264Sjacobs } 1532264Sjacobs 1542264Sjacobs static papi_status_t 1552264Sjacobs service_send_peer(service_t *svc) 1562264Sjacobs { 1572264Sjacobs papi_status_t result = PAPI_OK; 1582264Sjacobs 1592264Sjacobs if ((svc->peer_fd != -1) && (svc->so_handle != NULL) && 1602264Sjacobs (svc->svc_handle != NULL)) { 1612264Sjacobs papi_status_t (*f)(); 1622264Sjacobs 1632264Sjacobs f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetPeer"); 1642264Sjacobs 1652264Sjacobs if (f != NULL) 1662264Sjacobs result = f(svc->svc_handle, svc->peer_fd); 1672264Sjacobs } 1682264Sjacobs 1692264Sjacobs return (result); 1702264Sjacobs } 1712264Sjacobs 1722264Sjacobs papi_status_t 1732264Sjacobs service_connect(service_t *svc, char *name) 1742264Sjacobs { 1752264Sjacobs papi_status_t result = PAPI_NOT_POSSIBLE; 1762264Sjacobs 1772264Sjacobs /* if there is no print service module loaded, try and load one. */ 1782264Sjacobs if (svc->so_handle == NULL) 1792264Sjacobs result = service_load(svc, name); 1802264Sjacobs else if ((svc->name == NULL) && (name != NULL)) 1812264Sjacobs svc->name = strdup(name); 1822264Sjacobs 1832264Sjacobs /* 1842264Sjacobs * the print service module is loaded, but we don't have a service 1852264Sjacobs * handle. 1862264Sjacobs */ 1872264Sjacobs if (svc->so_handle != NULL) { 1882264Sjacobs papi_status_t (*f)(); 1892264Sjacobs 1902928Sjacobs if (svc->svc_handle != NULL) /* already connected? */ 1912928Sjacobs return (PAPI_OK); 1922928Sjacobs 1932264Sjacobs f = (papi_status_t (*)())psm_sym(svc, "papiServiceCreate"); 1942264Sjacobs 1952264Sjacobs if (f != NULL) { 1962264Sjacobs char *user = svc->user; 1972264Sjacobs char *password = svc->password; 1982264Sjacobs 1992264Sjacobs /* if no API user, try the URI user */ 2002264Sjacobs if ((user == NULL) && (svc->uri != NULL)) 2012264Sjacobs user = (svc->uri)->user; 2022264Sjacobs /* if no API password, try the URI password */ 2032264Sjacobs if ((password == NULL) && (svc->uri != NULL)) 2042264Sjacobs password = (svc->uri)->password; 2052264Sjacobs 2062264Sjacobs result = f(&svc->svc_handle, svc->name, user, password, 2072264Sjacobs (svc->authCB ? interposed_auth_callback 2082264Sjacobs : NULL), 2092264Sjacobs svc->encryption, svc); 2102264Sjacobs (void) service_send_peer(svc); 2112264Sjacobs } 2122264Sjacobs } 2132264Sjacobs 2142264Sjacobs return (result); 2152264Sjacobs } 2162264Sjacobs 2172264Sjacobs papi_status_t 2182264Sjacobs papiServiceCreate(papi_service_t *handle, char *service_name, char *user_name, 2192264Sjacobs char *password, 2202264Sjacobs int (*authCB)(papi_service_t svc, void *app_data), 2212264Sjacobs papi_encryption_t encryption, void *app_data) 2222264Sjacobs { 2232264Sjacobs papi_status_t result = PAPI_NOT_POSSIBLE; 2242264Sjacobs service_t *svc = NULL; 2252264Sjacobs uri_t *u = NULL; 2262264Sjacobs 2272264Sjacobs if (handle == NULL) 2282264Sjacobs return (PAPI_BAD_ARGUMENT); 2292264Sjacobs 2302264Sjacobs if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL) 2312264Sjacobs return (PAPI_TEMPORARY_ERROR); 2322264Sjacobs 2332264Sjacobs svc->peer_fd = -1; 2342264Sjacobs 2352264Sjacobs if (user_name != NULL) 2362264Sjacobs svc->user = strdup(user_name); 2372264Sjacobs 2382264Sjacobs if (password != NULL) 2392264Sjacobs svc->password = strdup(password); 2402264Sjacobs 2412264Sjacobs svc->encryption = encryption; 2422264Sjacobs 2432264Sjacobs if (authCB != NULL) 2442264Sjacobs svc->authCB = authCB; 2452264Sjacobs 2462264Sjacobs if (app_data != NULL) 2472264Sjacobs svc->app_data = app_data; 2482264Sjacobs 2492264Sjacobs /* If not specified, get a "default" service from the environment */ 2502264Sjacobs if (service_name == NULL) 2512264Sjacobs service_name = default_service_uri(NULL); 2522264Sjacobs 2532264Sjacobs if (service_name != NULL) { 2542264Sjacobs result = service_load(svc, service_name); 2552264Sjacobs /* if the psm loaded and the svc contains a URI, connect */ 2562264Sjacobs if ((result == PAPI_OK) && (svc->uri != NULL)) 2572264Sjacobs result = service_connect(svc, service_name); 2582264Sjacobs } else 2592264Sjacobs result = PAPI_OK; 2602264Sjacobs 2612264Sjacobs return (result); 2622264Sjacobs } 2632264Sjacobs 2642264Sjacobs void 2652264Sjacobs papiServiceDestroy(papi_service_t handle) 2662264Sjacobs { 2672264Sjacobs if (handle != NULL) { 2682264Sjacobs service_t *svc = handle; 2692264Sjacobs 2702264Sjacobs if (svc->so_handle != NULL) { 2712264Sjacobs if (svc->svc_handle != NULL) { 2722264Sjacobs void (*f)(); 2732264Sjacobs 2742264Sjacobs f = (void (*)())psm_sym(svc, 2752264Sjacobs "papiServiceDestroy"); 2762264Sjacobs f(svc->svc_handle); 2772264Sjacobs } 2782264Sjacobs psm_close(svc->so_handle); 2792264Sjacobs } 2802264Sjacobs if (svc->attributes != NULL) 2812264Sjacobs papiAttributeListFree(svc->attributes); 2822264Sjacobs if (svc->name != NULL) 2832264Sjacobs free(svc->name); 2842264Sjacobs if (svc->user != NULL) 2852264Sjacobs free(svc->user); 2862264Sjacobs if (svc->password != NULL) 2872264Sjacobs free(svc->password); 2882264Sjacobs if (svc->uri != NULL) 2892264Sjacobs uri_free(svc->uri); 2902264Sjacobs 2912264Sjacobs free(handle); 2922264Sjacobs } 2932264Sjacobs } 2942264Sjacobs 2952264Sjacobs papi_status_t 2962264Sjacobs papiServiceSetPeer(papi_service_t handle, int fd) 2972264Sjacobs { 2982264Sjacobs papi_status_t result = PAPI_OK; 2992264Sjacobs 3002264Sjacobs if (handle != NULL) { 3012264Sjacobs service_t *svc = handle; 3022264Sjacobs 3032264Sjacobs svc->peer_fd = fd; 3042264Sjacobs result = service_send_peer(svc); 3052264Sjacobs } else 3062264Sjacobs result = PAPI_BAD_ARGUMENT; 3072264Sjacobs 3082264Sjacobs return (result); 3092264Sjacobs } 3102264Sjacobs 3112264Sjacobs papi_status_t 3122264Sjacobs papiServiceSetUserName(papi_service_t handle, char *user_name) 3132264Sjacobs { 3142264Sjacobs papi_status_t result = PAPI_OK; 3152264Sjacobs 3162264Sjacobs if (handle != NULL) { 3172264Sjacobs service_t *svc = handle; 3182264Sjacobs papi_status_t (*f)(); 3192264Sjacobs 3202264Sjacobs if (svc->user != NULL) 3212264Sjacobs free(svc->user); 3222264Sjacobs if (user_name != NULL) 3232264Sjacobs svc->user = strdup(user_name); 3242264Sjacobs f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetUserName"); 3252264Sjacobs if (f != NULL) 3262264Sjacobs result = f(svc->svc_handle, user_name); 3272264Sjacobs } else 3282264Sjacobs result = PAPI_BAD_ARGUMENT; 3292264Sjacobs 3302264Sjacobs return (result); 3312264Sjacobs } 3322264Sjacobs 3332264Sjacobs papi_status_t 3342264Sjacobs papiServiceSetPassword(papi_service_t handle, char *password) 3352264Sjacobs { 3362264Sjacobs papi_status_t result = PAPI_OK; 3372264Sjacobs 3382264Sjacobs if (handle != NULL) { 3392264Sjacobs service_t *svc = handle; 3402264Sjacobs papi_status_t (*f)(); 3412264Sjacobs 3422264Sjacobs if (svc->password != NULL) 3432264Sjacobs free(svc->password); 3442264Sjacobs if (password != NULL) 3452264Sjacobs svc->password = strdup(password); 3462264Sjacobs f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetPassword"); 3472264Sjacobs if (f != NULL) 3482264Sjacobs result = f(svc->svc_handle, password); 3492264Sjacobs } else 3502264Sjacobs result = PAPI_BAD_ARGUMENT; 3512264Sjacobs 3522264Sjacobs return (result); 3532264Sjacobs } 3542264Sjacobs 3552264Sjacobs papi_status_t 3562264Sjacobs papiServiceSetEncryption(papi_service_t handle, papi_encryption_t encryption) 3572264Sjacobs { 3582264Sjacobs papi_status_t result = PAPI_OK; 3592264Sjacobs 3602264Sjacobs if (handle != NULL) { 3612264Sjacobs service_t *svc = handle; 3622264Sjacobs papi_status_t (*f)(); 3632264Sjacobs 3642264Sjacobs svc->encryption = encryption; 3652264Sjacobs f = (papi_status_t (*)())psm_sym(svc, 3662264Sjacobs "papiServiceSetEncryption"); 3672264Sjacobs if (f != NULL) 3682264Sjacobs result = f(svc->svc_handle, encryption); 3692264Sjacobs } else 3702264Sjacobs result = PAPI_BAD_ARGUMENT; 3712264Sjacobs 3722264Sjacobs return (result); 3732264Sjacobs } 3742264Sjacobs 3752264Sjacobs papi_status_t 3762264Sjacobs papiServiceSetAuthCB(papi_service_t handle, 3772264Sjacobs int (*authCB)(papi_service_t svc, void *app_data)) 3782264Sjacobs { 3792264Sjacobs papi_status_t result = PAPI_OK; 3802264Sjacobs 3812264Sjacobs if (handle != NULL) { 3822264Sjacobs service_t *svc = handle; 3832264Sjacobs papi_status_t (*f)(); 3842264Sjacobs 3852264Sjacobs svc->authCB = authCB; 3862264Sjacobs f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetAuthCB"); 3872264Sjacobs if (f != NULL) 3882264Sjacobs result = f(svc->svc_handle, interposed_auth_callback); 3892264Sjacobs } else 3902264Sjacobs result = PAPI_BAD_ARGUMENT; 3912264Sjacobs 3922264Sjacobs return (result); 3932264Sjacobs } 3942264Sjacobs 3952264Sjacobs 3962264Sjacobs papi_status_t 3972264Sjacobs papiServiceSetAppData(papi_service_t handle, void *app_data) 3982264Sjacobs { 3992264Sjacobs papi_status_t result = PAPI_OK; 4002264Sjacobs 4012264Sjacobs if (handle != NULL) { 4022264Sjacobs service_t *svc = handle; 4032264Sjacobs papi_status_t (*f)(); 4042264Sjacobs 4052264Sjacobs svc->app_data = (void *)app_data; 4062264Sjacobs } else 4072264Sjacobs result = PAPI_BAD_ARGUMENT; 4082264Sjacobs 4092264Sjacobs return (result); 4102264Sjacobs } 4112264Sjacobs 4122264Sjacobs char * 4132264Sjacobs papiServiceGetServiceName(papi_service_t handle) 4142264Sjacobs { 4152264Sjacobs char *result = NULL; 4162264Sjacobs 4172264Sjacobs if (handle != NULL) { 4182264Sjacobs service_t *svc = handle; 4192264Sjacobs char *(*f)(); 4202264Sjacobs 4212264Sjacobs f = (char *(*)())psm_sym(svc, "papiServiceGetServiceName"); 4222264Sjacobs if (f != NULL) 4232264Sjacobs result = f(svc->svc_handle); 4242264Sjacobs if (result == NULL) 4252264Sjacobs result = svc->name; 4262264Sjacobs } 4272264Sjacobs 4282264Sjacobs return (result); 4292264Sjacobs } 4302264Sjacobs 4312264Sjacobs char * 4322264Sjacobs papiServiceGetUserName(papi_service_t handle) 4332264Sjacobs { 4342264Sjacobs char *result = NULL; 4352264Sjacobs 4362264Sjacobs if (handle != NULL) { 4372264Sjacobs service_t *svc = handle; 4382264Sjacobs char *(*f)(); 4392264Sjacobs 4402264Sjacobs f = (char *(*)())psm_sym(svc, "papiServiceGetUserName"); 4412264Sjacobs if (f != NULL) 4422264Sjacobs result = f(svc->svc_handle); 4432264Sjacobs if (result == NULL) 4442264Sjacobs result = svc->user; 4452264Sjacobs } 4462264Sjacobs 4472264Sjacobs return (result); 4482264Sjacobs } 4492264Sjacobs 4502264Sjacobs char * 4512264Sjacobs papiServiceGetPassword(papi_service_t handle) 4522264Sjacobs { 4532264Sjacobs char *result = NULL; 4542264Sjacobs 4552264Sjacobs if (handle != NULL) { 4562264Sjacobs service_t *svc = handle; 4572264Sjacobs char *(*f)(); 4582264Sjacobs 4592264Sjacobs f = (char *(*)())psm_sym(svc, "papiServiceGetPassword"); 4602264Sjacobs if (f != NULL) 4612264Sjacobs result = f(svc->svc_handle); 4622264Sjacobs if (result == NULL) 4632264Sjacobs result = svc->password; 4642264Sjacobs } 4652264Sjacobs 4662264Sjacobs return (result); 4672264Sjacobs } 4682264Sjacobs 4692264Sjacobs papi_encryption_t 4702264Sjacobs papiServiceGetEncryption(papi_service_t handle) 4712264Sjacobs { 4722264Sjacobs papi_encryption_t result = PAPI_ENCRYPT_NEVER; 4732264Sjacobs 4742264Sjacobs if (handle != NULL) { 4752264Sjacobs service_t *svc = handle; 4762264Sjacobs papi_encryption_t (*f)(); 4772264Sjacobs 4782264Sjacobs f = (papi_encryption_t (*)())psm_sym(svc, 4792264Sjacobs "papiServiceGetEncryption"); 4802264Sjacobs if (f != NULL) 4812264Sjacobs result = f(svc->svc_handle); 4822264Sjacobs if (result == PAPI_ENCRYPT_NEVER) 4832264Sjacobs result = svc->encryption; 4842264Sjacobs } 4852264Sjacobs 4862264Sjacobs return (result); 4872264Sjacobs } 4882264Sjacobs 4892264Sjacobs void * 4902264Sjacobs papiServiceGetAppData(papi_service_t handle) 4912264Sjacobs { 4922264Sjacobs void *result = NULL; 4932264Sjacobs service_t *svc = handle; 4942264Sjacobs 4952264Sjacobs if (handle != NULL) 4962264Sjacobs result = svc->app_data; 4972264Sjacobs 4982264Sjacobs return (result); 4992264Sjacobs } 5002264Sjacobs 5012264Sjacobs papi_attribute_t ** 5022264Sjacobs papiServiceGetAttributeList(papi_service_t handle) 5032264Sjacobs { 5042264Sjacobs papi_attribute_t **result = NULL; 5052264Sjacobs service_t *svc = handle; 5062264Sjacobs 5072264Sjacobs if (handle != NULL) { 5082264Sjacobs papi_attribute_t **(*f)(); 5092264Sjacobs 5102264Sjacobs if (svc->so_handle == NULL) { 5112264Sjacobs char *uri = default_service_uri(DEFAULT_SERVICE_URI); 5122264Sjacobs 5132264Sjacobs if (service_connect(svc, uri) != PAPI_OK) 5142264Sjacobs return (NULL); 5152264Sjacobs } 5162264Sjacobs 5172264Sjacobs f = (papi_attribute_t **(*)())psm_sym(svc, 5182264Sjacobs "papiServiceGetAttributeList"); 5192264Sjacobs if (f != NULL) 5202264Sjacobs result = f(svc->svc_handle); 5212264Sjacobs } else 5222264Sjacobs result = svc->attributes; 5232264Sjacobs 5242264Sjacobs return (result); 5252264Sjacobs } 5262264Sjacobs 5272264Sjacobs char * 5282264Sjacobs papiServiceGetStatusMessage(papi_service_t handle) 5292264Sjacobs { 5302264Sjacobs char *result = NULL; 5312264Sjacobs service_t *svc = handle; 5322264Sjacobs 5332264Sjacobs if (handle != NULL) { 5342264Sjacobs char *(*f)(); 5352264Sjacobs 5362264Sjacobs f = (char *(*)())psm_sym(svc, "papiServiceGetStatusMessage"); 5372264Sjacobs if (f != NULL) 5382264Sjacobs result = f(svc->svc_handle); 5392264Sjacobs } 5402264Sjacobs if (result == NULL) { 5412264Sjacobs papiAttributeListGetString(svc->attributes, NULL, 5422264Sjacobs "detailed-status-message", &result); 5432264Sjacobs } 5442264Sjacobs 5452264Sjacobs return (result); 5462264Sjacobs } 5472264Sjacobs 5482264Sjacobs void 5492264Sjacobs detailed_error(service_t *svc, char *fmt, ...) 5502264Sjacobs { 5512264Sjacobs if ((svc != NULL) && (fmt != NULL)) { 5522264Sjacobs va_list ap; 5532264Sjacobs size_t size; 5542264Sjacobs char *message = alloca(BUFSIZ); 5552264Sjacobs 5562264Sjacobs va_start(ap, fmt); 5572264Sjacobs /* 5582264Sjacobs * fill in the message. If the buffer is too small, allocate 5592264Sjacobs * one that is large enough and fill it in. 5602264Sjacobs */ 5612264Sjacobs if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ) 5622264Sjacobs if ((message = alloca(size)) != NULL) 5632264Sjacobs vsnprintf(message, size, fmt, ap); 5642264Sjacobs va_end(ap); 5652264Sjacobs 5662264Sjacobs papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, 5672264Sjacobs "detailed-status-message", message); 5682264Sjacobs #ifdef DEBUG 5692264Sjacobs fprintf(stderr, "detailed_error(%s)\n", message); 5702264Sjacobs #endif 5712264Sjacobs } 5722264Sjacobs } 573