1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*LINTLIBRARY*/
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate #include <stdlib.h>
32*0Sstevel@tonic-gate #include <stdio.h>
33*0Sstevel@tonic-gate #include <stdarg.h>
34*0Sstevel@tonic-gate #include <string.h>
35*0Sstevel@tonic-gate #include <alloca.h>
36*0Sstevel@tonic-gate #include <libintl.h>
37*0Sstevel@tonic-gate #include <papi_impl.h>
38*0Sstevel@tonic-gate 
39*0Sstevel@tonic-gate papi_status_t
40*0Sstevel@tonic-gate papiServiceCreate(papi_service_t *handle, const char *service_name,
41*0Sstevel@tonic-gate 		const char *user_name, const char *password,
42*0Sstevel@tonic-gate 		const int (*authCB)(papi_service_t svc),
43*0Sstevel@tonic-gate 		const papi_encryption_t encryption, void *app_data)
44*0Sstevel@tonic-gate {
45*0Sstevel@tonic-gate 	service_t *svc = NULL;
46*0Sstevel@tonic-gate 	char *path = Lp_FIFO;
47*0Sstevel@tonic-gate 
48*0Sstevel@tonic-gate 	if (handle == NULL)
49*0Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate 	if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL)
52*0Sstevel@tonic-gate 		return (PAPI_TEMPORARY_ERROR);
53*0Sstevel@tonic-gate 
54*0Sstevel@tonic-gate 	svc->md = mconnect(path, 0, 0);
55*0Sstevel@tonic-gate 	if (svc->md == NULL) {
56*0Sstevel@tonic-gate 		detailed_error(svc,
57*0Sstevel@tonic-gate 			gettext("can't connect to spooler for %s: %s"),
58*0Sstevel@tonic-gate 			(service_name ? service_name : ""), strerror(errno));
59*0Sstevel@tonic-gate 		return (PAPI_SERVICE_UNAVAILABLE);
60*0Sstevel@tonic-gate 	}
61*0Sstevel@tonic-gate 
62*0Sstevel@tonic-gate 	svc->msgbuf_size = MSGMAX;
63*0Sstevel@tonic-gate 	if ((svc->msgbuf = calloc(1, svc->msgbuf_size)) == NULL)
64*0Sstevel@tonic-gate 		return (PAPI_TEMPORARY_ERROR);
65*0Sstevel@tonic-gate 
66*0Sstevel@tonic-gate 	if (service_name != NULL)
67*0Sstevel@tonic-gate 		papiAttributeListAddString(&svc->attributes, PAPI_ATTR_EXCL,
68*0Sstevel@tonic-gate 				"service-name", service_name);
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate 	(void) papiServiceSetUserName(svc, user_name);
71*0Sstevel@tonic-gate 	(void) papiServiceSetPassword(svc, password);
72*0Sstevel@tonic-gate 	(void) papiServiceSetAuthCB(svc, authCB);
73*0Sstevel@tonic-gate 	(void) papiServiceSetAppData(svc, app_data);
74*0Sstevel@tonic-gate 	(void) papiServiceSetEncryption(svc, encryption);
75*0Sstevel@tonic-gate 
76*0Sstevel@tonic-gate 	return (PAPI_OK);
77*0Sstevel@tonic-gate }
78*0Sstevel@tonic-gate 
79*0Sstevel@tonic-gate void
80*0Sstevel@tonic-gate papiServiceDestroy(papi_service_t handle)
81*0Sstevel@tonic-gate {
82*0Sstevel@tonic-gate 	service_t *svc = handle;
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate 	if (svc != NULL) {
85*0Sstevel@tonic-gate 		if (svc->md != NULL)
86*0Sstevel@tonic-gate 			mdisconnect(svc->md);
87*0Sstevel@tonic-gate 		if (svc->msgbuf != NULL)
88*0Sstevel@tonic-gate 			free(svc->msgbuf);
89*0Sstevel@tonic-gate 		papiAttributeListFree(svc->attributes);
90*0Sstevel@tonic-gate 		free(svc);
91*0Sstevel@tonic-gate 	}
92*0Sstevel@tonic-gate }
93*0Sstevel@tonic-gate 
94*0Sstevel@tonic-gate papi_status_t
95*0Sstevel@tonic-gate papiServiceSetUserName(papi_service_t handle, const char *user_name)
96*0Sstevel@tonic-gate {
97*0Sstevel@tonic-gate 	service_t *svc = handle;
98*0Sstevel@tonic-gate 
99*0Sstevel@tonic-gate 	if (svc == NULL)
100*0Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
101*0Sstevel@tonic-gate 
102*0Sstevel@tonic-gate 	return (papiAttributeListAddString(&svc->attributes, PAPI_ATTR_REPLACE,
103*0Sstevel@tonic-gate 				"user-name", user_name));
104*0Sstevel@tonic-gate }
105*0Sstevel@tonic-gate 
106*0Sstevel@tonic-gate papi_status_t
107*0Sstevel@tonic-gate papiServiceSetPassword(papi_service_t handle, const char *password)
108*0Sstevel@tonic-gate {
109*0Sstevel@tonic-gate 	service_t *svc = handle;
110*0Sstevel@tonic-gate 
111*0Sstevel@tonic-gate 	if (svc == NULL)
112*0Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
113*0Sstevel@tonic-gate 
114*0Sstevel@tonic-gate 	return (papiAttributeListAddString(&svc->attributes, PAPI_ATTR_REPLACE,
115*0Sstevel@tonic-gate 				"password", password));
116*0Sstevel@tonic-gate }
117*0Sstevel@tonic-gate 
118*0Sstevel@tonic-gate papi_status_t
119*0Sstevel@tonic-gate papiServiceSetEncryption(papi_service_t handle,
120*0Sstevel@tonic-gate 			const papi_encryption_t encryption)
121*0Sstevel@tonic-gate {
122*0Sstevel@tonic-gate 	service_t *svc = handle;
123*0Sstevel@tonic-gate 
124*0Sstevel@tonic-gate 	if (svc == NULL)
125*0Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
126*0Sstevel@tonic-gate 
127*0Sstevel@tonic-gate 	return (papiAttributeListAddInteger(&svc->attributes, PAPI_ATTR_REPLACE,
128*0Sstevel@tonic-gate 				"encryption", (int)encryption));
129*0Sstevel@tonic-gate }
130*0Sstevel@tonic-gate 
131*0Sstevel@tonic-gate papi_status_t
132*0Sstevel@tonic-gate papiServiceSetAuthCB(papi_service_t handle,
133*0Sstevel@tonic-gate 			const int (*authCB)(papi_service_t svc))
134*0Sstevel@tonic-gate {
135*0Sstevel@tonic-gate 	service_t *svc = handle;
136*0Sstevel@tonic-gate 
137*0Sstevel@tonic-gate 	if (svc == NULL)
138*0Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate 	svc->authCB = (int (*)(papi_service_t svc))authCB;
141*0Sstevel@tonic-gate 
142*0Sstevel@tonic-gate 	return (PAPI_OK);
143*0Sstevel@tonic-gate }
144*0Sstevel@tonic-gate 
145*0Sstevel@tonic-gate papi_status_t
146*0Sstevel@tonic-gate papiServiceSetAppData(papi_service_t handle, const void *app_data)
147*0Sstevel@tonic-gate {
148*0Sstevel@tonic-gate 	service_t *svc = handle;
149*0Sstevel@tonic-gate 
150*0Sstevel@tonic-gate 	if (svc == NULL)
151*0Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
152*0Sstevel@tonic-gate 
153*0Sstevel@tonic-gate 	svc->app_data = (void *)app_data;
154*0Sstevel@tonic-gate 
155*0Sstevel@tonic-gate 	return (PAPI_OK);
156*0Sstevel@tonic-gate }
157*0Sstevel@tonic-gate 
158*0Sstevel@tonic-gate char *
159*0Sstevel@tonic-gate papiServiceGetServiceName(papi_service_t handle)
160*0Sstevel@tonic-gate {
161*0Sstevel@tonic-gate 	service_t *svc = handle;
162*0Sstevel@tonic-gate 	char *result = NULL;
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate 	if (svc != NULL)
165*0Sstevel@tonic-gate 		papiAttributeListGetString(svc->attributes, NULL,
166*0Sstevel@tonic-gate 					"service-name", &result);
167*0Sstevel@tonic-gate 
168*0Sstevel@tonic-gate 	return (result);
169*0Sstevel@tonic-gate }
170*0Sstevel@tonic-gate 
171*0Sstevel@tonic-gate char *
172*0Sstevel@tonic-gate papiServiceGetUserName(papi_service_t handle)
173*0Sstevel@tonic-gate {
174*0Sstevel@tonic-gate 	service_t *svc = handle;
175*0Sstevel@tonic-gate 	char *result = NULL;
176*0Sstevel@tonic-gate 
177*0Sstevel@tonic-gate 	if (svc != NULL)
178*0Sstevel@tonic-gate 		papiAttributeListGetString(svc->attributes, NULL,
179*0Sstevel@tonic-gate 					"user-name", &result);
180*0Sstevel@tonic-gate 
181*0Sstevel@tonic-gate 	return (result);
182*0Sstevel@tonic-gate }
183*0Sstevel@tonic-gate 
184*0Sstevel@tonic-gate char *
185*0Sstevel@tonic-gate papiServiceGetPassword(papi_service_t handle)
186*0Sstevel@tonic-gate {
187*0Sstevel@tonic-gate 	service_t *svc = handle;
188*0Sstevel@tonic-gate 	char *result = NULL;
189*0Sstevel@tonic-gate 
190*0Sstevel@tonic-gate 	if (svc != NULL)
191*0Sstevel@tonic-gate 		papiAttributeListGetString(svc->attributes, NULL,
192*0Sstevel@tonic-gate 					"password", &result);
193*0Sstevel@tonic-gate 
194*0Sstevel@tonic-gate 	return (result);
195*0Sstevel@tonic-gate }
196*0Sstevel@tonic-gate 
197*0Sstevel@tonic-gate papi_encryption_t
198*0Sstevel@tonic-gate papiServiceGetEncryption(papi_service_t handle)
199*0Sstevel@tonic-gate {
200*0Sstevel@tonic-gate 	service_t *svc = handle;
201*0Sstevel@tonic-gate 	papi_encryption_t result = PAPI_ENCRYPT_NEVER;
202*0Sstevel@tonic-gate 
203*0Sstevel@tonic-gate 	if (svc != NULL)
204*0Sstevel@tonic-gate 		papiAttributeListGetInteger(svc->attributes, NULL,
205*0Sstevel@tonic-gate 					"encryption", (int *)&result);
206*0Sstevel@tonic-gate 
207*0Sstevel@tonic-gate 	return (result);
208*0Sstevel@tonic-gate }
209*0Sstevel@tonic-gate 
210*0Sstevel@tonic-gate void *
211*0Sstevel@tonic-gate papiServiceGetAppData(papi_service_t handle)
212*0Sstevel@tonic-gate {
213*0Sstevel@tonic-gate 	service_t *svc = handle;
214*0Sstevel@tonic-gate 	void *result = NULL;
215*0Sstevel@tonic-gate 
216*0Sstevel@tonic-gate 	if (svc != NULL)
217*0Sstevel@tonic-gate 		result = svc->app_data;
218*0Sstevel@tonic-gate 
219*0Sstevel@tonic-gate 	return (result);
220*0Sstevel@tonic-gate }
221*0Sstevel@tonic-gate 
222*0Sstevel@tonic-gate char *
223*0Sstevel@tonic-gate papiServiceGetStatusMessage(papi_service_t handle)
224*0Sstevel@tonic-gate {
225*0Sstevel@tonic-gate 	service_t *svc = handle;
226*0Sstevel@tonic-gate 	char *result = NULL;
227*0Sstevel@tonic-gate 
228*0Sstevel@tonic-gate 	if (svc != NULL)
229*0Sstevel@tonic-gate 		papiAttributeListGetString(svc->attributes, NULL,
230*0Sstevel@tonic-gate 					"detailed-status-message", &result);
231*0Sstevel@tonic-gate 
232*0Sstevel@tonic-gate 	return (result);
233*0Sstevel@tonic-gate }
234*0Sstevel@tonic-gate 
235*0Sstevel@tonic-gate void
236*0Sstevel@tonic-gate detailed_error(service_t *svc, char *fmt, ...)
237*0Sstevel@tonic-gate {
238*0Sstevel@tonic-gate 	if ((svc != NULL) && (fmt != NULL)) {
239*0Sstevel@tonic-gate 		va_list ap;
240*0Sstevel@tonic-gate 		size_t size;
241*0Sstevel@tonic-gate 		char *message = alloca(BUFSIZ);
242*0Sstevel@tonic-gate 
243*0Sstevel@tonic-gate 		va_start(ap, fmt);
244*0Sstevel@tonic-gate 		/*
245*0Sstevel@tonic-gate 		 * fill in the message.  If the buffer is too small, allocate
246*0Sstevel@tonic-gate 		 * one that is large enough and fill it in.
247*0Sstevel@tonic-gate 		 */
248*0Sstevel@tonic-gate 		if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ)
249*0Sstevel@tonic-gate 			if ((message = alloca(size)) != NULL)
250*0Sstevel@tonic-gate 				vsnprintf(message, size, fmt, ap);
251*0Sstevel@tonic-gate 		va_end(ap);
252*0Sstevel@tonic-gate 
253*0Sstevel@tonic-gate 		papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND,
254*0Sstevel@tonic-gate 					"detailed-status-message", message);
255*0Sstevel@tonic-gate 	}
256*0Sstevel@tonic-gate }
257