xref: /onnv-gate/usr/src/lib/print/libpapi-dynamic/common/service.c (revision 7132:0ecd69ca6e32)
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
interposed_auth_callback(papi_service_t handle,void * app_data)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 *
default_service_uri(char * fallback)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 *
default_print_service()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
service_load(service_t * svc,char * name)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
service_send_peer(service_t * svc)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
service_connect(service_t * svc,char * name)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
papiServiceCreate(papi_service_t * handle,char * service_name,char * user_name,char * password,int (* authCB)(papi_service_t svc,void * app_data),papi_encryption_t encryption,void * app_data)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
papiServiceDestroy(papi_service_t handle)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
papiServiceSetPeer(papi_service_t handle,int fd)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
papiServiceSetUserName(papi_service_t handle,char * user_name)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
papiServiceSetPassword(papi_service_t handle,char * password)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
papiServiceSetEncryption(papi_service_t handle,papi_encryption_t encryption)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
papiServiceSetAuthCB(papi_service_t handle,int (* authCB)(papi_service_t svc,void * app_data))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
papiServiceSetAppData(papi_service_t handle,void * app_data)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 *
papiServiceGetServiceName(papi_service_t handle)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 *
papiServiceGetUserName(papi_service_t handle)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 *
papiServiceGetPassword(papi_service_t handle)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
papiServiceGetEncryption(papi_service_t handle)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 *
papiServiceGetAppData(papi_service_t handle)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 **
papiServiceGetAttributeList(papi_service_t handle)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 *
papiServiceGetStatusMessage(papi_service_t handle)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
detailed_error(service_t * svc,char * fmt,...)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