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