xref: /titanic_51/usr/src/lib/print/libpapi-dynamic/common/service.c (revision a18dc42fc967d11feba9b8be61c6727dc6c56b48)
1355b4669Sjacobs /*
2355b4669Sjacobs  * CDDL HEADER START
3355b4669Sjacobs  *
4355b4669Sjacobs  * The contents of this file are subject to the terms of the
5355b4669Sjacobs  * Common Development and Distribution License (the "License").
6355b4669Sjacobs  * You may not use this file except in compliance with the License.
7355b4669Sjacobs  *
8355b4669Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9355b4669Sjacobs  * or http://www.opensolaris.org/os/licensing.
10355b4669Sjacobs  * See the License for the specific language governing permissions
11355b4669Sjacobs  * and limitations under the License.
12355b4669Sjacobs  *
13355b4669Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
14355b4669Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15355b4669Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
16355b4669Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
17355b4669Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
18355b4669Sjacobs  *
19355b4669Sjacobs  * CDDL HEADER END
20355b4669Sjacobs  */
21355b4669Sjacobs 
22355b4669Sjacobs /*
23*a18dc42fSps29005  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24355b4669Sjacobs  * Use is subject to license terms.
25355b4669Sjacobs  *
26355b4669Sjacobs  */
27355b4669Sjacobs 
28355b4669Sjacobs /* $Id: service.c 172 2006-05-24 20:54:00Z njacobs $ */
29355b4669Sjacobs 
30355b4669Sjacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
31355b4669Sjacobs 
32355b4669Sjacobs /*LINTLIBRARY*/
33355b4669Sjacobs 
34355b4669Sjacobs #include <stdlib.h>
35355b4669Sjacobs #include <stdio.h>
36355b4669Sjacobs #include <stdarg.h>
37*a18dc42fSps29005 #include <sys/types.h>
38*a18dc42fSps29005 #include <unistd.h>
39355b4669Sjacobs #include <string.h>
40355b4669Sjacobs #include <alloca.h>
41355b4669Sjacobs #include <libintl.h>
42355b4669Sjacobs #include <papi_impl.h>
43355b4669Sjacobs #include <config-site.h>
44355b4669Sjacobs 
45355b4669Sjacobs static int
46355b4669Sjacobs interposed_auth_callback(papi_service_t handle, void *app_data)
47355b4669Sjacobs {
48355b4669Sjacobs 	int result = -1;
49355b4669Sjacobs 	service_t *svc = app_data;
50355b4669Sjacobs 
51355b4669Sjacobs 	if (svc != NULL)
52355b4669Sjacobs 		result = svc->authCB(svc, svc->app_data);
53355b4669Sjacobs 
54355b4669Sjacobs 	return (result);
55355b4669Sjacobs }
56355b4669Sjacobs 
57355b4669Sjacobs static char *
58355b4669Sjacobs default_service_uri(char *fallback)
59355b4669Sjacobs {
60355b4669Sjacobs 	char *result = NULL;
61355b4669Sjacobs 
62*a18dc42fSps29005 	if (getuid() == geteuid())
63*a18dc42fSps29005 		result = getenv("PAPI_SERVICE_URI");
64*a18dc42fSps29005 
65*a18dc42fSps29005 	if (result == NULL) {
66355b4669Sjacobs 		char *cups;
67355b4669Sjacobs 
68355b4669Sjacobs 		if ((cups = getenv("CUPS_SERVER")) != NULL) {
69355b4669Sjacobs 			char buf[BUFSIZ];
70355b4669Sjacobs 
71355b4669Sjacobs 			snprintf(buf, sizeof (buf), "ipp://%s/printers/", cups);
72355b4669Sjacobs 			result = strdup(buf);
73355b4669Sjacobs 		}
74355b4669Sjacobs 	}
75355b4669Sjacobs 
76355b4669Sjacobs 	if (result == NULL)
77355b4669Sjacobs 		result = fallback;
78355b4669Sjacobs 
79355b4669Sjacobs 	return (result);
80355b4669Sjacobs }
81355b4669Sjacobs 
82355b4669Sjacobs static char *
83355b4669Sjacobs default_print_service()
84355b4669Sjacobs {
85355b4669Sjacobs 	static char *result = NULL;
86355b4669Sjacobs 
87355b4669Sjacobs 	if (result == NULL) {
88355b4669Sjacobs 		char *service_uri = default_service_uri(DEFAULT_SERVICE_URI);
89355b4669Sjacobs 		uri_t *uri = NULL;
90355b4669Sjacobs 
91355b4669Sjacobs 		if (uri_from_string(service_uri, &uri) != -1)
92355b4669Sjacobs 			result = strdup(uri->scheme);
93355b4669Sjacobs 
94355b4669Sjacobs 		if (uri != NULL)
95355b4669Sjacobs 			uri_free(uri);
96355b4669Sjacobs 	}
97355b4669Sjacobs 
98355b4669Sjacobs 	return (result);
99355b4669Sjacobs }
100355b4669Sjacobs 
101355b4669Sjacobs static papi_status_t
102355b4669Sjacobs service_load(service_t *svc, char *name)
103355b4669Sjacobs {
104355b4669Sjacobs 	papi_status_t result;
105355b4669Sjacobs 	char *scheme = default_print_service();
106355b4669Sjacobs 
107355b4669Sjacobs 	if (svc->so_handle != NULL)	/* already loaded */
108355b4669Sjacobs 		return (PAPI_OK);
109355b4669Sjacobs 
110355b4669Sjacobs 	if (name == NULL)		/* no info, can't load yet */
111355b4669Sjacobs 		return (PAPI_OK);
112355b4669Sjacobs 
113355b4669Sjacobs 	/* Lookup the printer in the configuration DB */
114355b4669Sjacobs 	svc->attributes = getprinterbyname((char *)name, NULL);
115355b4669Sjacobs 
116355b4669Sjacobs 	if (svc->attributes != NULL) {
117355b4669Sjacobs 		char *tmp = NULL;
118355b4669Sjacobs 
119355b4669Sjacobs 		/* Printer found (or was a URI), use the attribute data */
120355b4669Sjacobs 		papiAttributeListGetString(svc->attributes, NULL,
121355b4669Sjacobs 					"printer-uri-supported", &tmp);
122355b4669Sjacobs 		if (tmp != NULL)
123355b4669Sjacobs 			svc->name = strdup(tmp);
124355b4669Sjacobs 
125355b4669Sjacobs 		/* parse the URI and set the scheme(print service) */
126355b4669Sjacobs 		if (uri_from_string(svc->name, &svc->uri) != -1)
127355b4669Sjacobs 			scheme = (svc->uri)->scheme;
128355b4669Sjacobs 
129355b4669Sjacobs 		/* override the scheme if it was in the attributes */
130355b4669Sjacobs 		papiAttributeListGetString(svc->attributes, NULL,
131355b4669Sjacobs 					"print-service-module", &scheme);
132355b4669Sjacobs 
133355b4669Sjacobs 	} else	/* not found, assume it is the actual print service name */
134355b4669Sjacobs 		scheme = name;
135355b4669Sjacobs 
136355b4669Sjacobs 	result = psm_open(svc, scheme);
137355b4669Sjacobs 	switch (result) {
138355b4669Sjacobs 	case PAPI_OK:
139355b4669Sjacobs 		break;	/* no error */
140355b4669Sjacobs 	case PAPI_URI_SCHEME:
141355b4669Sjacobs 		result = PAPI_NOT_FOUND;
142355b4669Sjacobs #ifdef DEBUG
143355b4669Sjacobs 		detailed_error(svc, "Unable to load service for: %s", name);
144355b4669Sjacobs #endif
145355b4669Sjacobs 		break;
146355b4669Sjacobs 	default:	/* set the detailed message */
147355b4669Sjacobs 		detailed_error(svc, "Unable to load service (%s) for: %s",
148355b4669Sjacobs 				scheme, name);
149355b4669Sjacobs 	}
150355b4669Sjacobs 
151355b4669Sjacobs 	return (result);
152355b4669Sjacobs }
153355b4669Sjacobs 
154355b4669Sjacobs static papi_status_t
155355b4669Sjacobs service_send_peer(service_t *svc)
156355b4669Sjacobs {
157355b4669Sjacobs 	papi_status_t result = PAPI_OK;
158355b4669Sjacobs 
159355b4669Sjacobs 	if ((svc->peer_fd != -1) && (svc->so_handle != NULL) &&
160355b4669Sjacobs 	    (svc->svc_handle != NULL)) {
161355b4669Sjacobs 		papi_status_t (*f)();
162355b4669Sjacobs 
163355b4669Sjacobs 		f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetPeer");
164355b4669Sjacobs 
165355b4669Sjacobs 		if (f != NULL)
166355b4669Sjacobs 			result = f(svc->svc_handle, svc->peer_fd);
167355b4669Sjacobs 	}
168355b4669Sjacobs 
169355b4669Sjacobs 	return (result);
170355b4669Sjacobs }
171355b4669Sjacobs 
172355b4669Sjacobs papi_status_t
173355b4669Sjacobs service_connect(service_t *svc, char *name)
174355b4669Sjacobs {
175355b4669Sjacobs 	papi_status_t result = PAPI_NOT_POSSIBLE;
176355b4669Sjacobs 
177355b4669Sjacobs 	/* if there is no print service module loaded, try and load one. */
178355b4669Sjacobs 	if (svc->so_handle == NULL)
179355b4669Sjacobs 		result = service_load(svc, name);
180355b4669Sjacobs 	else if ((svc->name == NULL) && (name != NULL))
181355b4669Sjacobs 		svc->name = strdup(name);
182355b4669Sjacobs 
183355b4669Sjacobs 	/*
184355b4669Sjacobs 	 * the print service module is loaded, but we don't have a service
185355b4669Sjacobs 	 * handle.
186355b4669Sjacobs 	 */
187355b4669Sjacobs 	if (svc->so_handle != NULL) {
188355b4669Sjacobs 		papi_status_t (*f)();
189355b4669Sjacobs 
19062d876e7Sjacobs 		if (svc->svc_handle != NULL)	/* already connected? */
19162d876e7Sjacobs 			return (PAPI_OK);
19262d876e7Sjacobs 
193355b4669Sjacobs 		f = (papi_status_t (*)())psm_sym(svc, "papiServiceCreate");
194355b4669Sjacobs 
195355b4669Sjacobs 		if (f != NULL) {
196355b4669Sjacobs 			char *user = svc->user;
197355b4669Sjacobs 			char *password = svc->password;
198355b4669Sjacobs 
199355b4669Sjacobs 			/* if no API user, try the URI user */
200355b4669Sjacobs 			if ((user == NULL) && (svc->uri != NULL))
201355b4669Sjacobs 				user = (svc->uri)->user;
202355b4669Sjacobs 			/* if no API password, try the URI password */
203355b4669Sjacobs 			if ((password == NULL) && (svc->uri != NULL))
204355b4669Sjacobs 				password = (svc->uri)->password;
205355b4669Sjacobs 
206355b4669Sjacobs 			result = f(&svc->svc_handle, svc->name, user, password,
207355b4669Sjacobs 					(svc->authCB ? interposed_auth_callback
208355b4669Sjacobs 						: NULL),
209355b4669Sjacobs 					svc->encryption, svc);
210355b4669Sjacobs 			(void) service_send_peer(svc);
211355b4669Sjacobs 		}
212355b4669Sjacobs 	}
213355b4669Sjacobs 
214355b4669Sjacobs 	return (result);
215355b4669Sjacobs }
216355b4669Sjacobs 
217355b4669Sjacobs papi_status_t
218355b4669Sjacobs papiServiceCreate(papi_service_t *handle, char *service_name, char *user_name,
219355b4669Sjacobs 		char *password,
220355b4669Sjacobs 		int (*authCB)(papi_service_t svc, void *app_data),
221355b4669Sjacobs 		papi_encryption_t encryption, void *app_data)
222355b4669Sjacobs {
223355b4669Sjacobs 	papi_status_t result = PAPI_NOT_POSSIBLE;
224355b4669Sjacobs 	service_t *svc = NULL;
225355b4669Sjacobs 	uri_t *u = NULL;
226355b4669Sjacobs 
227355b4669Sjacobs 	if (handle == NULL)
228355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
229355b4669Sjacobs 
230355b4669Sjacobs 	if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL)
231355b4669Sjacobs 		return (PAPI_TEMPORARY_ERROR);
232355b4669Sjacobs 
233355b4669Sjacobs 	svc->peer_fd = -1;
234355b4669Sjacobs 
235355b4669Sjacobs 	if (user_name != NULL)
236355b4669Sjacobs 		svc->user = strdup(user_name);
237355b4669Sjacobs 
238355b4669Sjacobs 	if (password != NULL)
239355b4669Sjacobs 		svc->password = strdup(password);
240355b4669Sjacobs 
241355b4669Sjacobs 	svc->encryption = encryption;
242355b4669Sjacobs 
243355b4669Sjacobs 	if (authCB != NULL)
244355b4669Sjacobs 		svc->authCB = authCB;
245355b4669Sjacobs 
246355b4669Sjacobs 	if (app_data != NULL)
247355b4669Sjacobs 		svc->app_data = app_data;
248355b4669Sjacobs 
249355b4669Sjacobs 	/* If not specified, get a "default" service from the environment */
250355b4669Sjacobs 	if (service_name == NULL)
251355b4669Sjacobs 		service_name = default_service_uri(NULL);
252355b4669Sjacobs 
253355b4669Sjacobs 	if (service_name != NULL) {
254355b4669Sjacobs 		result = service_load(svc, service_name);
255355b4669Sjacobs 		/* if the psm loaded and the svc contains a URI, connect */
256355b4669Sjacobs 		if ((result == PAPI_OK) && (svc->uri != NULL))
257355b4669Sjacobs 			result = service_connect(svc, service_name);
258355b4669Sjacobs 	} else
259355b4669Sjacobs 		result = PAPI_OK;
260355b4669Sjacobs 
261355b4669Sjacobs 	return (result);
262355b4669Sjacobs }
263355b4669Sjacobs 
264355b4669Sjacobs void
265355b4669Sjacobs papiServiceDestroy(papi_service_t handle)
266355b4669Sjacobs {
267355b4669Sjacobs 	if (handle != NULL) {
268355b4669Sjacobs 		service_t *svc = handle;
269355b4669Sjacobs 
270355b4669Sjacobs 		if (svc->so_handle != NULL) {
271355b4669Sjacobs 			if (svc->svc_handle != NULL) {
272355b4669Sjacobs 				void (*f)();
273355b4669Sjacobs 
274355b4669Sjacobs 				f = (void (*)())psm_sym(svc,
275355b4669Sjacobs 							"papiServiceDestroy");
276355b4669Sjacobs 				f(svc->svc_handle);
277355b4669Sjacobs 			}
278355b4669Sjacobs 			psm_close(svc->so_handle);
279355b4669Sjacobs 		}
280355b4669Sjacobs 		if (svc->attributes != NULL)
281355b4669Sjacobs 			papiAttributeListFree(svc->attributes);
282355b4669Sjacobs 		if (svc->name != NULL)
283355b4669Sjacobs 			free(svc->name);
284355b4669Sjacobs 		if (svc->user != NULL)
285355b4669Sjacobs 			free(svc->user);
286355b4669Sjacobs 		if (svc->password != NULL)
287355b4669Sjacobs 			free(svc->password);
288355b4669Sjacobs 		if (svc->uri != NULL)
289355b4669Sjacobs 			uri_free(svc->uri);
290355b4669Sjacobs 
291355b4669Sjacobs 		free(handle);
292355b4669Sjacobs 	}
293355b4669Sjacobs }
294355b4669Sjacobs 
295355b4669Sjacobs papi_status_t
296355b4669Sjacobs papiServiceSetPeer(papi_service_t handle, int fd)
297355b4669Sjacobs {
298355b4669Sjacobs 	papi_status_t result = PAPI_OK;
299355b4669Sjacobs 
300355b4669Sjacobs 	if (handle != NULL) {
301355b4669Sjacobs 		service_t *svc = handle;
302355b4669Sjacobs 
303355b4669Sjacobs 		svc->peer_fd = fd;
304355b4669Sjacobs 		result = service_send_peer(svc);
305355b4669Sjacobs 	} else
306355b4669Sjacobs 		result = PAPI_BAD_ARGUMENT;
307355b4669Sjacobs 
308355b4669Sjacobs 	return (result);
309355b4669Sjacobs }
310355b4669Sjacobs 
311355b4669Sjacobs papi_status_t
312355b4669Sjacobs papiServiceSetUserName(papi_service_t handle, char *user_name)
313355b4669Sjacobs {
314355b4669Sjacobs 	papi_status_t result = PAPI_OK;
315355b4669Sjacobs 
316355b4669Sjacobs 	if (handle != NULL) {
317355b4669Sjacobs 		service_t *svc = handle;
318355b4669Sjacobs 		papi_status_t (*f)();
319355b4669Sjacobs 
320355b4669Sjacobs 		if (svc->user != NULL)
321355b4669Sjacobs 			free(svc->user);
322355b4669Sjacobs 		if (user_name != NULL)
323355b4669Sjacobs 			svc->user = strdup(user_name);
324355b4669Sjacobs 		f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetUserName");
325355b4669Sjacobs 		if (f != NULL)
326355b4669Sjacobs 			result = f(svc->svc_handle, user_name);
327355b4669Sjacobs 	} else
328355b4669Sjacobs 		result = PAPI_BAD_ARGUMENT;
329355b4669Sjacobs 
330355b4669Sjacobs 	return (result);
331355b4669Sjacobs }
332355b4669Sjacobs 
333355b4669Sjacobs papi_status_t
334355b4669Sjacobs papiServiceSetPassword(papi_service_t handle, char *password)
335355b4669Sjacobs {
336355b4669Sjacobs 	papi_status_t result = PAPI_OK;
337355b4669Sjacobs 
338355b4669Sjacobs 	if (handle != NULL) {
339355b4669Sjacobs 		service_t *svc = handle;
340355b4669Sjacobs 		papi_status_t (*f)();
341355b4669Sjacobs 
342355b4669Sjacobs 		if (svc->password != NULL)
343355b4669Sjacobs 			free(svc->password);
344355b4669Sjacobs 		if (password != NULL)
345355b4669Sjacobs 			svc->password = strdup(password);
346355b4669Sjacobs 		f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetPassword");
347355b4669Sjacobs 		if (f != NULL)
348355b4669Sjacobs 			result = f(svc->svc_handle, password);
349355b4669Sjacobs 	} else
350355b4669Sjacobs 		result = PAPI_BAD_ARGUMENT;
351355b4669Sjacobs 
352355b4669Sjacobs 	return (result);
353355b4669Sjacobs }
354355b4669Sjacobs 
355355b4669Sjacobs papi_status_t
356355b4669Sjacobs papiServiceSetEncryption(papi_service_t handle, papi_encryption_t encryption)
357355b4669Sjacobs {
358355b4669Sjacobs 	papi_status_t result = PAPI_OK;
359355b4669Sjacobs 
360355b4669Sjacobs 	if (handle != NULL) {
361355b4669Sjacobs 		service_t *svc = handle;
362355b4669Sjacobs 		papi_status_t (*f)();
363355b4669Sjacobs 
364355b4669Sjacobs 		svc->encryption = encryption;
365355b4669Sjacobs 		f = (papi_status_t (*)())psm_sym(svc,
366355b4669Sjacobs 						"papiServiceSetEncryption");
367355b4669Sjacobs 		if (f != NULL)
368355b4669Sjacobs 			result = f(svc->svc_handle, encryption);
369355b4669Sjacobs 	} else
370355b4669Sjacobs 		result = PAPI_BAD_ARGUMENT;
371355b4669Sjacobs 
372355b4669Sjacobs 	return (result);
373355b4669Sjacobs }
374355b4669Sjacobs 
375355b4669Sjacobs papi_status_t
376355b4669Sjacobs papiServiceSetAuthCB(papi_service_t handle,
377355b4669Sjacobs 		int (*authCB)(papi_service_t svc, void *app_data))
378355b4669Sjacobs {
379355b4669Sjacobs 	papi_status_t result = PAPI_OK;
380355b4669Sjacobs 
381355b4669Sjacobs 	if (handle != NULL) {
382355b4669Sjacobs 		service_t *svc = handle;
383355b4669Sjacobs 		papi_status_t (*f)();
384355b4669Sjacobs 
385355b4669Sjacobs 		svc->authCB = authCB;
386355b4669Sjacobs 		f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetAuthCB");
387355b4669Sjacobs 		if (f != NULL)
388355b4669Sjacobs 			result = f(svc->svc_handle, interposed_auth_callback);
389355b4669Sjacobs 	} else
390355b4669Sjacobs 		result = PAPI_BAD_ARGUMENT;
391355b4669Sjacobs 
392355b4669Sjacobs 	return (result);
393355b4669Sjacobs }
394355b4669Sjacobs 
395355b4669Sjacobs 
396355b4669Sjacobs papi_status_t
397355b4669Sjacobs papiServiceSetAppData(papi_service_t handle, void *app_data)
398355b4669Sjacobs {
399355b4669Sjacobs 	papi_status_t result = PAPI_OK;
400355b4669Sjacobs 
401355b4669Sjacobs 	if (handle != NULL) {
402355b4669Sjacobs 		service_t *svc = handle;
403355b4669Sjacobs 		papi_status_t (*f)();
404355b4669Sjacobs 
405355b4669Sjacobs 		svc->app_data = (void *)app_data;
406355b4669Sjacobs 	} else
407355b4669Sjacobs 		result = PAPI_BAD_ARGUMENT;
408355b4669Sjacobs 
409355b4669Sjacobs 	return (result);
410355b4669Sjacobs }
411355b4669Sjacobs 
412355b4669Sjacobs char *
413355b4669Sjacobs papiServiceGetServiceName(papi_service_t handle)
414355b4669Sjacobs {
415355b4669Sjacobs 	char *result = NULL;
416355b4669Sjacobs 
417355b4669Sjacobs 	if (handle != NULL) {
418355b4669Sjacobs 		service_t *svc = handle;
419355b4669Sjacobs 		char *(*f)();
420355b4669Sjacobs 
421355b4669Sjacobs 		f = (char *(*)())psm_sym(svc, "papiServiceGetServiceName");
422355b4669Sjacobs 		if (f != NULL)
423355b4669Sjacobs 			result = f(svc->svc_handle);
424355b4669Sjacobs 		if (result == NULL)
425355b4669Sjacobs 			result = svc->name;
426355b4669Sjacobs 	}
427355b4669Sjacobs 
428355b4669Sjacobs 	return (result);
429355b4669Sjacobs }
430355b4669Sjacobs 
431355b4669Sjacobs char *
432355b4669Sjacobs papiServiceGetUserName(papi_service_t handle)
433355b4669Sjacobs {
434355b4669Sjacobs 	char *result = NULL;
435355b4669Sjacobs 
436355b4669Sjacobs 	if (handle != NULL) {
437355b4669Sjacobs 		service_t *svc = handle;
438355b4669Sjacobs 		char *(*f)();
439355b4669Sjacobs 
440355b4669Sjacobs 		f = (char *(*)())psm_sym(svc, "papiServiceGetUserName");
441355b4669Sjacobs 		if (f != NULL)
442355b4669Sjacobs 			result = f(svc->svc_handle);
443355b4669Sjacobs 		if (result == NULL)
444355b4669Sjacobs 			result = svc->user;
445355b4669Sjacobs 	}
446355b4669Sjacobs 
447355b4669Sjacobs 	return (result);
448355b4669Sjacobs }
449355b4669Sjacobs 
450355b4669Sjacobs char *
451355b4669Sjacobs papiServiceGetPassword(papi_service_t handle)
452355b4669Sjacobs {
453355b4669Sjacobs 	char *result = NULL;
454355b4669Sjacobs 
455355b4669Sjacobs 	if (handle != NULL) {
456355b4669Sjacobs 		service_t *svc = handle;
457355b4669Sjacobs 		char *(*f)();
458355b4669Sjacobs 
459355b4669Sjacobs 		f = (char *(*)())psm_sym(svc, "papiServiceGetPassword");
460355b4669Sjacobs 		if (f != NULL)
461355b4669Sjacobs 			result = f(svc->svc_handle);
462355b4669Sjacobs 		if (result == NULL)
463355b4669Sjacobs 			result = svc->password;
464355b4669Sjacobs 	}
465355b4669Sjacobs 
466355b4669Sjacobs 	return (result);
467355b4669Sjacobs }
468355b4669Sjacobs 
469355b4669Sjacobs papi_encryption_t
470355b4669Sjacobs papiServiceGetEncryption(papi_service_t handle)
471355b4669Sjacobs {
472355b4669Sjacobs 	papi_encryption_t result = PAPI_ENCRYPT_NEVER;
473355b4669Sjacobs 
474355b4669Sjacobs 	if (handle != NULL) {
475355b4669Sjacobs 		service_t *svc = handle;
476355b4669Sjacobs 		papi_encryption_t (*f)();
477355b4669Sjacobs 
478355b4669Sjacobs 		f = (papi_encryption_t (*)())psm_sym(svc,
479355b4669Sjacobs 						"papiServiceGetEncryption");
480355b4669Sjacobs 		if (f != NULL)
481355b4669Sjacobs 			result = f(svc->svc_handle);
482355b4669Sjacobs 		if (result == PAPI_ENCRYPT_NEVER)
483355b4669Sjacobs 			result = svc->encryption;
484355b4669Sjacobs 	}
485355b4669Sjacobs 
486355b4669Sjacobs 	return (result);
487355b4669Sjacobs }
488355b4669Sjacobs 
489355b4669Sjacobs void *
490355b4669Sjacobs papiServiceGetAppData(papi_service_t handle)
491355b4669Sjacobs {
492355b4669Sjacobs 	void *result = NULL;
493355b4669Sjacobs 	service_t *svc = handle;
494355b4669Sjacobs 
495355b4669Sjacobs 	if (handle != NULL)
496355b4669Sjacobs 		result = svc->app_data;
497355b4669Sjacobs 
498355b4669Sjacobs 	return (result);
499355b4669Sjacobs }
500355b4669Sjacobs 
501355b4669Sjacobs papi_attribute_t **
502355b4669Sjacobs papiServiceGetAttributeList(papi_service_t handle)
503355b4669Sjacobs {
504355b4669Sjacobs 	papi_attribute_t **result = NULL;
505355b4669Sjacobs 	service_t *svc = handle;
506355b4669Sjacobs 
507355b4669Sjacobs 	if (handle != NULL) {
508355b4669Sjacobs 		papi_attribute_t **(*f)();
509355b4669Sjacobs 
510355b4669Sjacobs 		if (svc->so_handle == NULL) {
511355b4669Sjacobs 			char *uri = default_service_uri(DEFAULT_SERVICE_URI);
512355b4669Sjacobs 
513355b4669Sjacobs 			if (service_connect(svc, uri) != PAPI_OK)
514355b4669Sjacobs 				return (NULL);
515355b4669Sjacobs 		}
516355b4669Sjacobs 
517355b4669Sjacobs 		f = (papi_attribute_t **(*)())psm_sym(svc,
518355b4669Sjacobs 					"papiServiceGetAttributeList");
519355b4669Sjacobs 		if (f != NULL)
520355b4669Sjacobs 			result = f(svc->svc_handle);
521355b4669Sjacobs 	} else
522355b4669Sjacobs 		result = svc->attributes;
523355b4669Sjacobs 
524355b4669Sjacobs 	return (result);
525355b4669Sjacobs }
526355b4669Sjacobs 
527355b4669Sjacobs char *
528355b4669Sjacobs papiServiceGetStatusMessage(papi_service_t handle)
529355b4669Sjacobs {
530355b4669Sjacobs 	char *result = NULL;
531355b4669Sjacobs 	service_t *svc = handle;
532355b4669Sjacobs 
533355b4669Sjacobs 	if (handle != NULL) {
534355b4669Sjacobs 		char *(*f)();
535355b4669Sjacobs 
536355b4669Sjacobs 		f = (char *(*)())psm_sym(svc, "papiServiceGetStatusMessage");
537355b4669Sjacobs 		if (f != NULL)
538355b4669Sjacobs 			result = f(svc->svc_handle);
539355b4669Sjacobs 	}
540355b4669Sjacobs 	if (result == NULL) {
541355b4669Sjacobs 		papiAttributeListGetString(svc->attributes, NULL,
542355b4669Sjacobs 					"detailed-status-message", &result);
543355b4669Sjacobs 	}
544355b4669Sjacobs 
545355b4669Sjacobs 	return (result);
546355b4669Sjacobs }
547355b4669Sjacobs 
548355b4669Sjacobs void
549355b4669Sjacobs detailed_error(service_t *svc, char *fmt, ...)
550355b4669Sjacobs {
551355b4669Sjacobs 	if ((svc != NULL) && (fmt != NULL)) {
552355b4669Sjacobs 		va_list ap;
553355b4669Sjacobs 		size_t size;
554355b4669Sjacobs 		char *message = alloca(BUFSIZ);
555355b4669Sjacobs 
556355b4669Sjacobs 		va_start(ap, fmt);
557355b4669Sjacobs 		/*
558355b4669Sjacobs 		 * fill in the message.  If the buffer is too small, allocate
559355b4669Sjacobs 		 * one that is large enough and fill it in.
560355b4669Sjacobs 		 */
561355b4669Sjacobs 		if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ)
562355b4669Sjacobs 			if ((message = alloca(size)) != NULL)
563355b4669Sjacobs 				vsnprintf(message, size, fmt, ap);
564355b4669Sjacobs 		va_end(ap);
565355b4669Sjacobs 
566355b4669Sjacobs 		papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND,
567355b4669Sjacobs 					"detailed-status-message", message);
568355b4669Sjacobs #ifdef DEBUG
569355b4669Sjacobs 		fprintf(stderr, "detailed_error(%s)\n", message);
570355b4669Sjacobs #endif
571355b4669Sjacobs 	}
572355b4669Sjacobs }
573