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 /*
23355b4669Sjacobs  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24355b4669Sjacobs  * Use is subject to license terms.
25355b4669Sjacobs  *
26355b4669Sjacobs  */
27355b4669Sjacobs 
28355b4669Sjacobs /* $Id: service.c 171 2006-05-20 06:00:32Z njacobs $ */
29355b4669Sjacobs 
30355b4669Sjacobs #include <stdlib.h>
31355b4669Sjacobs #include <stdio.h>
32355b4669Sjacobs #include <stdarg.h>
33355b4669Sjacobs #include <string.h>
34355b4669Sjacobs #include <libintl.h>
35355b4669Sjacobs #include <papi_impl.h>
36355b4669Sjacobs 
37355b4669Sjacobs #include <config-site.h>
38355b4669Sjacobs 
39355b4669Sjacobs http_encryption_t
http_encryption_type(papi_encryption_t encryption)40355b4669Sjacobs http_encryption_type(papi_encryption_t encryption)
41355b4669Sjacobs {
42355b4669Sjacobs 	switch (encryption) {
43355b4669Sjacobs 	case PAPI_ENCRYPT_IF_REQUESTED:
44355b4669Sjacobs 		return (HTTP_ENCRYPT_IF_REQUESTED);
45355b4669Sjacobs 	case PAPI_ENCRYPT_REQUIRED:
46355b4669Sjacobs 		return (HTTP_ENCRYPT_REQUIRED);
47355b4669Sjacobs 	case PAPI_ENCRYPT_ALWAYS:
48355b4669Sjacobs 		return (HTTP_ENCRYPT_ALWAYS);
49355b4669Sjacobs 	case PAPI_ENCRYPT_NEVER:
50355b4669Sjacobs 		return (HTTP_ENCRYPT_NEVER);
51355b4669Sjacobs 	default:
52355b4669Sjacobs 		; /* this should log an error */
53355b4669Sjacobs 	}
54355b4669Sjacobs 
55355b4669Sjacobs 	return (HTTP_ENCRYPT_NEVER);	/* should never get here */
56355b4669Sjacobs }
57355b4669Sjacobs 
58355b4669Sjacobs papi_status_t
service_connect(service_t * svc,char * service_name)59355b4669Sjacobs service_connect(service_t *svc, char *service_name)
60355b4669Sjacobs {
61355b4669Sjacobs 	papi_status_t result = PAPI_OK;
62355b4669Sjacobs 	int port = 631;
63355b4669Sjacobs 
64355b4669Sjacobs 	if (svc == NULL)
65355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
66355b4669Sjacobs 
67355b4669Sjacobs 	if (svc->connection != NULL)	/* alread connected ? */
68355b4669Sjacobs 		return (PAPI_OK);
69355b4669Sjacobs 
70355b4669Sjacobs 	if (svc->uri == NULL)
71355b4669Sjacobs 		uri_from_string(service_name, &svc->uri);
72355b4669Sjacobs 
73355b4669Sjacobs 	if ((service_name != NULL) && (svc->uri == NULL)) {
74355b4669Sjacobs 		/*
75355b4669Sjacobs 		 * a name was supplied and it's not in URI form, we will
76355b4669Sjacobs 		 * try to use a "default" IPP service under the assumption
77355b4669Sjacobs 		 * that this is most likely a short-form printer name from
78355b4669Sjacobs 		 * from a papiPrinter*() or papiJob*() call and not from a
79355b4669Sjacobs 		 * papiServiceCreate() call.
80355b4669Sjacobs 		 */
81355b4669Sjacobs 		if ((service_name = getenv("PAPI_SERVICE_URI")) == NULL) {
82355b4669Sjacobs 			char *cups;
83355b4669Sjacobs 
84355b4669Sjacobs 			if ((cups = getenv("CUPS_SERVER")) != NULL) {
85355b4669Sjacobs 				char buf[BUFSIZ];
86355b4669Sjacobs 
87355b4669Sjacobs 				snprintf(buf, sizeof (buf),
88355b4669Sjacobs 					"ipp://%s/printers/", cups);
89355b4669Sjacobs 				service_name = strdup(buf);
90355b4669Sjacobs 			}
91355b4669Sjacobs 		}
92355b4669Sjacobs 		if (service_name == NULL)
93355b4669Sjacobs 			service_name = DEFAULT_IPP_SERVICE_URI;
94355b4669Sjacobs 
95355b4669Sjacobs 		uri_from_string(service_name, &svc->uri);
96355b4669Sjacobs 	}
97355b4669Sjacobs 
98355b4669Sjacobs 	if (svc->uri == NULL)
99355b4669Sjacobs 		return (PAPI_NOT_POSSIBLE);
100355b4669Sjacobs 
101355b4669Sjacobs 	if (svc->uri->port != NULL)
102355b4669Sjacobs 		port = strtol(svc->uri->port, NULL, 10);
103355b4669Sjacobs 
104355b4669Sjacobs 	svc->connection = httpConnectEncrypt(svc->uri->host, port,
105355b4669Sjacobs 					http_encryption_type(svc->encryption));
106355b4669Sjacobs 	if (svc->connection == NULL) {
107355b4669Sjacobs 		if (svc->uri != NULL) {
108355b4669Sjacobs 			uri_free(svc->uri);
109355b4669Sjacobs 			svc->uri = NULL;
110355b4669Sjacobs 		}
111355b4669Sjacobs 		result = PAPI_SERVICE_UNAVAILABLE;
112355b4669Sjacobs 	} else if (service_name != NULL)
113355b4669Sjacobs 		svc->name = strdup(service_name);
114355b4669Sjacobs 
115355b4669Sjacobs 	return (result);
116355b4669Sjacobs }
117355b4669Sjacobs 
118355b4669Sjacobs 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)119355b4669Sjacobs papiServiceCreate(papi_service_t *handle, char *service_name,
120355b4669Sjacobs 		char *user_name, char *password,
121355b4669Sjacobs 		int (*authCB)(papi_service_t svc, void *app_data),
122355b4669Sjacobs 		papi_encryption_t encryption, void *app_data)
123355b4669Sjacobs {
124355b4669Sjacobs 	papi_status_t result = PAPI_NOT_POSSIBLE;
125355b4669Sjacobs 	service_t *svc = NULL;
126355b4669Sjacobs 	char *encoding = getenv("HTTP_TRANSFER_ENCODING");
127355b4669Sjacobs 
128355b4669Sjacobs 	if (handle == NULL)
129355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
130355b4669Sjacobs 
131355b4669Sjacobs 	if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL)
132355b4669Sjacobs 		return (PAPI_TEMPORARY_ERROR);
133355b4669Sjacobs 
134355b4669Sjacobs 	if (user_name != NULL)
135355b4669Sjacobs 		svc->user = strdup(user_name);
136355b4669Sjacobs 
137355b4669Sjacobs 	if (password != NULL)
138355b4669Sjacobs 		svc->password = strdup(password);
139355b4669Sjacobs 
140355b4669Sjacobs 	svc->encryption = encryption;
141355b4669Sjacobs 
142355b4669Sjacobs 	if (authCB != NULL)
143355b4669Sjacobs 		svc->authCB = authCB;
144355b4669Sjacobs 
145355b4669Sjacobs 	if (app_data != NULL)
146355b4669Sjacobs 		svc->app_data = app_data;
147355b4669Sjacobs 
148355b4669Sjacobs 	if ((encoding != NULL) && (strcasecmp(encoding, "content-length") == 0))
149355b4669Sjacobs 		svc->transfer_encoding = TRANSFER_ENCODING_LENGTH;
150355b4669Sjacobs 	else
151355b4669Sjacobs 		svc->transfer_encoding = TRANSFER_ENCODING_CHUNKED;
152355b4669Sjacobs 
153355b4669Sjacobs 	if (service_name != NULL) {
154355b4669Sjacobs 		result = service_connect(svc, service_name);
155355b4669Sjacobs 	} else
156355b4669Sjacobs 		result = PAPI_OK;
157355b4669Sjacobs 
158355b4669Sjacobs 	return (result);
159355b4669Sjacobs }
160355b4669Sjacobs 
161355b4669Sjacobs void
papiServiceDestroy(papi_service_t handle)162355b4669Sjacobs papiServiceDestroy(papi_service_t handle)
163355b4669Sjacobs {
164355b4669Sjacobs 	if (handle != NULL) {
165355b4669Sjacobs 		service_t *svc = handle;
166355b4669Sjacobs 
167355b4669Sjacobs 		if (svc->attributes != NULL)
168355b4669Sjacobs 			papiAttributeListFree(svc->attributes);
169355b4669Sjacobs 		if (svc->name != NULL)
170355b4669Sjacobs 			free(svc->name);
171355b4669Sjacobs 		if (svc->user != NULL)
172355b4669Sjacobs 			free(svc->user);
173355b4669Sjacobs 		if (svc->password != NULL)
174355b4669Sjacobs 			free(svc->password);
175355b4669Sjacobs 		if (svc->uri != NULL)
176355b4669Sjacobs 			uri_free(svc->uri);
177355b4669Sjacobs 		if (svc->post != NULL)
178355b4669Sjacobs 			free(svc->post);
179355b4669Sjacobs 		if (svc->connection != NULL)
180355b4669Sjacobs 			httpClose(svc->connection);
181355b4669Sjacobs 
182355b4669Sjacobs 		free(handle);
183355b4669Sjacobs 	}
184355b4669Sjacobs }
185355b4669Sjacobs 
186355b4669Sjacobs papi_status_t
papiServiceSetUserName(papi_service_t handle,char * user_name)187355b4669Sjacobs papiServiceSetUserName(papi_service_t handle, char *user_name)
188355b4669Sjacobs {
189355b4669Sjacobs 	papi_status_t result = PAPI_OK;
190355b4669Sjacobs 
191355b4669Sjacobs 	if (handle != NULL) {
192355b4669Sjacobs 		service_t *svc = handle;
193355b4669Sjacobs 
194355b4669Sjacobs 		if (svc->user != NULL)
195355b4669Sjacobs 			free(svc->user);
196355b4669Sjacobs 		svc->user = NULL;
197355b4669Sjacobs 		if (user_name != NULL)
198355b4669Sjacobs 			svc->user = strdup(user_name);
199355b4669Sjacobs 	} else
200355b4669Sjacobs 		result = PAPI_BAD_ARGUMENT;
201355b4669Sjacobs 
202355b4669Sjacobs 	return (result);
203355b4669Sjacobs }
204355b4669Sjacobs 
205355b4669Sjacobs papi_status_t
papiServiceSetPassword(papi_service_t handle,char * password)206355b4669Sjacobs papiServiceSetPassword(papi_service_t handle, char *password)
207355b4669Sjacobs {
208355b4669Sjacobs 	papi_status_t result = PAPI_OK;
209355b4669Sjacobs 
210355b4669Sjacobs 	if (handle != NULL) {
211355b4669Sjacobs 		service_t *svc = handle;
212355b4669Sjacobs 
213355b4669Sjacobs 		if (svc->password != NULL)
214355b4669Sjacobs 			free(svc->password);
215355b4669Sjacobs 		svc->password = NULL;
216355b4669Sjacobs 		if (password != NULL)
217355b4669Sjacobs 			svc->password = strdup(password);
218355b4669Sjacobs 	} else
219355b4669Sjacobs 		result = PAPI_BAD_ARGUMENT;
220355b4669Sjacobs 
221355b4669Sjacobs 	return (result);
222355b4669Sjacobs }
223355b4669Sjacobs 
224355b4669Sjacobs papi_status_t
papiServiceSetEncryption(papi_service_t handle,papi_encryption_t encryption)225355b4669Sjacobs papiServiceSetEncryption(papi_service_t handle,
226355b4669Sjacobs 			papi_encryption_t encryption)
227355b4669Sjacobs {
228355b4669Sjacobs 	papi_status_t result = PAPI_OK;
229355b4669Sjacobs 
230355b4669Sjacobs 	if (handle != NULL) {
231355b4669Sjacobs 		service_t *svc = handle;
232355b4669Sjacobs 
233355b4669Sjacobs 		svc->encryption = encryption;
234355b4669Sjacobs 		httpEncryption(svc->connection,
235355b4669Sjacobs 				(http_encryption_t)svc->encryption);
236355b4669Sjacobs 	} else
237355b4669Sjacobs 		result = PAPI_BAD_ARGUMENT;
238355b4669Sjacobs 
239355b4669Sjacobs 	return (result);
240355b4669Sjacobs }
241355b4669Sjacobs 
242355b4669Sjacobs papi_status_t
papiServiceSetAuthCB(papi_service_t handle,int (* authCB)(papi_service_t svc,void * app_data))243355b4669Sjacobs papiServiceSetAuthCB(papi_service_t handle,
244355b4669Sjacobs 			int (*authCB)(papi_service_t svc, void *app_data))
245355b4669Sjacobs {
246355b4669Sjacobs 	papi_status_t result = PAPI_OK;
247355b4669Sjacobs 
248355b4669Sjacobs 	if (handle != NULL) {
249355b4669Sjacobs 		service_t *svc = handle;
250355b4669Sjacobs 
251355b4669Sjacobs 		svc->authCB = authCB;
252355b4669Sjacobs 	} else
253355b4669Sjacobs 		result = PAPI_BAD_ARGUMENT;
254355b4669Sjacobs 
255355b4669Sjacobs 	return (result);
256355b4669Sjacobs }
257355b4669Sjacobs 
258355b4669Sjacobs 
259355b4669Sjacobs papi_status_t
papiServiceSetAppData(papi_service_t handle,void * app_data)260355b4669Sjacobs papiServiceSetAppData(papi_service_t handle, void *app_data)
261355b4669Sjacobs {
262355b4669Sjacobs 	papi_status_t result = PAPI_OK;
263355b4669Sjacobs 
264355b4669Sjacobs 	if (handle != NULL) {
265355b4669Sjacobs 		service_t *svc = handle;
266355b4669Sjacobs 
267355b4669Sjacobs 		svc->app_data = (void *)app_data;
268355b4669Sjacobs 	} else
269355b4669Sjacobs 		result = PAPI_BAD_ARGUMENT;
270355b4669Sjacobs 
271355b4669Sjacobs 	return (result);
272355b4669Sjacobs }
273355b4669Sjacobs 
274355b4669Sjacobs char *
papiServiceGetServiceName(papi_service_t handle)275355b4669Sjacobs papiServiceGetServiceName(papi_service_t handle)
276355b4669Sjacobs {
277355b4669Sjacobs 	char *result = NULL;
278355b4669Sjacobs 
279355b4669Sjacobs 	if (handle != NULL) {
280355b4669Sjacobs 		service_t *svc = handle;
281355b4669Sjacobs 
282355b4669Sjacobs 		result = svc->name;
283355b4669Sjacobs 	}
284355b4669Sjacobs 
285355b4669Sjacobs 	return (result);
286355b4669Sjacobs }
287355b4669Sjacobs 
288355b4669Sjacobs char *
papiServiceGetUserName(papi_service_t handle)289355b4669Sjacobs papiServiceGetUserName(papi_service_t handle)
290355b4669Sjacobs {
291355b4669Sjacobs 	char *result = NULL;
292355b4669Sjacobs 
293355b4669Sjacobs 	if (handle != NULL) {
294355b4669Sjacobs 		service_t *svc = handle;
295355b4669Sjacobs 
296355b4669Sjacobs 		result = svc->user;
297355b4669Sjacobs 	}
298355b4669Sjacobs 
299355b4669Sjacobs 	return (result);
300355b4669Sjacobs }
301355b4669Sjacobs 
302355b4669Sjacobs char *
papiServiceGetPassword(papi_service_t handle)303355b4669Sjacobs papiServiceGetPassword(papi_service_t handle)
304355b4669Sjacobs {
305355b4669Sjacobs 	char *result = NULL;
306355b4669Sjacobs 
307355b4669Sjacobs 	if (handle != NULL) {
308355b4669Sjacobs 		service_t *svc = handle;
309355b4669Sjacobs 
310355b4669Sjacobs 		result = svc->password;
311355b4669Sjacobs 	}
312355b4669Sjacobs 
313355b4669Sjacobs 	return (result);
314355b4669Sjacobs }
315355b4669Sjacobs 
316355b4669Sjacobs papi_encryption_t
papiServiceGetEncryption(papi_service_t handle)317355b4669Sjacobs papiServiceGetEncryption(papi_service_t handle)
318355b4669Sjacobs {
319355b4669Sjacobs 	papi_encryption_t result = PAPI_ENCRYPT_NEVER;
320355b4669Sjacobs 
321355b4669Sjacobs 	if (handle != NULL) {
322355b4669Sjacobs 		service_t *svc = handle;
323355b4669Sjacobs 
324355b4669Sjacobs 		result = svc->encryption;
325355b4669Sjacobs 	}
326355b4669Sjacobs 
327355b4669Sjacobs 	return (result);
328355b4669Sjacobs }
329355b4669Sjacobs 
330355b4669Sjacobs void *
papiServiceGetAppData(papi_service_t handle)331355b4669Sjacobs papiServiceGetAppData(papi_service_t handle)
332355b4669Sjacobs {
333355b4669Sjacobs 	void *result = NULL;
334355b4669Sjacobs 
335355b4669Sjacobs 	if (handle != NULL) {
336355b4669Sjacobs 		service_t *svc = handle;
337355b4669Sjacobs 
338355b4669Sjacobs 		result = svc->app_data;
339355b4669Sjacobs 	}
340355b4669Sjacobs 
341355b4669Sjacobs 	return (result);
342355b4669Sjacobs }
343355b4669Sjacobs 
344355b4669Sjacobs papi_attribute_t **
papiServiceGetAttributeList(papi_service_t handle)345355b4669Sjacobs papiServiceGetAttributeList(papi_service_t handle)
346355b4669Sjacobs {
347355b4669Sjacobs 	papi_attribute_t **result = NULL;
348355b4669Sjacobs 	service_t *svc = handle;
349355b4669Sjacobs 
350355b4669Sjacobs 	if (handle != NULL)
351355b4669Sjacobs 		result = svc->attributes;
352355b4669Sjacobs 
353355b4669Sjacobs 	return (result);
354355b4669Sjacobs }
355355b4669Sjacobs 
356355b4669Sjacobs char *
papiServiceGetStatusMessage(papi_service_t handle)357355b4669Sjacobs papiServiceGetStatusMessage(papi_service_t handle)
358355b4669Sjacobs {
359355b4669Sjacobs 	char *result = NULL;
360355b4669Sjacobs 	service_t *svc = handle;
361355b4669Sjacobs 
362355b4669Sjacobs 	papiAttributeListGetString(svc->attributes, NULL,
363355b4669Sjacobs 					"detailed-status-message", &result);
364355b4669Sjacobs 
365355b4669Sjacobs 	return (result);
366355b4669Sjacobs }
367355b4669Sjacobs 
368355b4669Sjacobs void
detailed_error(service_t * svc,char * fmt,...)369355b4669Sjacobs detailed_error(service_t *svc, char *fmt, ...)
370355b4669Sjacobs {
371355b4669Sjacobs 	if ((svc != NULL) && (fmt != NULL)) {
372355b4669Sjacobs 		va_list ap;
373*b666b5beSToomas Soome 		char *message;
374*b666b5beSToomas Soome 		int rv;
375355b4669Sjacobs 
376355b4669Sjacobs 		va_start(ap, fmt);
377*b666b5beSToomas Soome 		rv = vasprintf(&message, fmt, ap);
378355b4669Sjacobs 		va_end(ap);
379355b4669Sjacobs 
380*b666b5beSToomas Soome 		if (rv >= 0) {
381*b666b5beSToomas Soome 			papiAttributeListAddString(&svc->attributes,
382*b666b5beSToomas Soome 			    PAPI_ATTR_APPEND, "detailed-status-message",
383*b666b5beSToomas Soome 			    message);
384*b666b5beSToomas Soome 			free(message);
385*b666b5beSToomas Soome 		}
386355b4669Sjacobs 	}
387355b4669Sjacobs }
388