xref: /onnv-gate/usr/src/lib/print/libpapi-ipp/common/service.c (revision 2264:b2b9267d002d)
1*2264Sjacobs /*
2*2264Sjacobs  * CDDL HEADER START
3*2264Sjacobs  *
4*2264Sjacobs  * The contents of this file are subject to the terms of the
5*2264Sjacobs  * Common Development and Distribution License (the "License").
6*2264Sjacobs  * You may not use this file except in compliance with the License.
7*2264Sjacobs  *
8*2264Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*2264Sjacobs  * or http://www.opensolaris.org/os/licensing.
10*2264Sjacobs  * See the License for the specific language governing permissions
11*2264Sjacobs  * and limitations under the License.
12*2264Sjacobs  *
13*2264Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
14*2264Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*2264Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
16*2264Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
17*2264Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
18*2264Sjacobs  *
19*2264Sjacobs  * CDDL HEADER END
20*2264Sjacobs  */
21*2264Sjacobs 
22*2264Sjacobs /*
23*2264Sjacobs  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24*2264Sjacobs  * Use is subject to license terms.
25*2264Sjacobs  *
26*2264Sjacobs  */
27*2264Sjacobs 
28*2264Sjacobs /* $Id: service.c 171 2006-05-20 06:00:32Z njacobs $ */
29*2264Sjacobs 
30*2264Sjacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*2264Sjacobs 
32*2264Sjacobs /*LINTLIBRARY*/
33*2264Sjacobs 
34*2264Sjacobs #include <stdlib.h>
35*2264Sjacobs #include <stdio.h>
36*2264Sjacobs #include <stdarg.h>
37*2264Sjacobs #include <string.h>
38*2264Sjacobs #include <alloca.h>
39*2264Sjacobs #include <libintl.h>
40*2264Sjacobs #include <papi_impl.h>
41*2264Sjacobs 
42*2264Sjacobs #include <config-site.h>
43*2264Sjacobs 
44*2264Sjacobs http_encryption_t
http_encryption_type(papi_encryption_t encryption)45*2264Sjacobs http_encryption_type(papi_encryption_t encryption)
46*2264Sjacobs {
47*2264Sjacobs 	switch (encryption) {
48*2264Sjacobs 	case PAPI_ENCRYPT_IF_REQUESTED:
49*2264Sjacobs 		return (HTTP_ENCRYPT_IF_REQUESTED);
50*2264Sjacobs 	case PAPI_ENCRYPT_REQUIRED:
51*2264Sjacobs 		return (HTTP_ENCRYPT_REQUIRED);
52*2264Sjacobs 	case PAPI_ENCRYPT_ALWAYS:
53*2264Sjacobs 		return (HTTP_ENCRYPT_ALWAYS);
54*2264Sjacobs 	case PAPI_ENCRYPT_NEVER:
55*2264Sjacobs 		return (HTTP_ENCRYPT_NEVER);
56*2264Sjacobs 	default:
57*2264Sjacobs 		; /* this should log an error */
58*2264Sjacobs 	}
59*2264Sjacobs 
60*2264Sjacobs 	return (HTTP_ENCRYPT_NEVER);	/* should never get here */
61*2264Sjacobs }
62*2264Sjacobs 
63*2264Sjacobs papi_status_t
service_connect(service_t * svc,char * service_name)64*2264Sjacobs service_connect(service_t *svc, char *service_name)
65*2264Sjacobs {
66*2264Sjacobs 	papi_status_t result = PAPI_OK;
67*2264Sjacobs 	int port = 631;
68*2264Sjacobs 
69*2264Sjacobs 	if (svc == NULL)
70*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
71*2264Sjacobs 
72*2264Sjacobs 	if (svc->connection != NULL)	/* alread connected ? */
73*2264Sjacobs 		return (PAPI_OK);
74*2264Sjacobs 
75*2264Sjacobs 	if (svc->uri == NULL)
76*2264Sjacobs 		uri_from_string(service_name, &svc->uri);
77*2264Sjacobs 
78*2264Sjacobs 	if ((service_name != NULL) && (svc->uri == NULL)) {
79*2264Sjacobs 		/*
80*2264Sjacobs 		 * a name was supplied and it's not in URI form, we will
81*2264Sjacobs 		 * try to use a "default" IPP service under the assumption
82*2264Sjacobs 		 * that this is most likely a short-form printer name from
83*2264Sjacobs 		 * from a papiPrinter*() or papiJob*() call and not from a
84*2264Sjacobs 		 * papiServiceCreate() call.
85*2264Sjacobs 		 */
86*2264Sjacobs 		if ((service_name = getenv("PAPI_SERVICE_URI")) == NULL) {
87*2264Sjacobs 			char *cups;
88*2264Sjacobs 
89*2264Sjacobs 			if ((cups = getenv("CUPS_SERVER")) != NULL) {
90*2264Sjacobs 				char buf[BUFSIZ];
91*2264Sjacobs 
92*2264Sjacobs 				snprintf(buf, sizeof (buf),
93*2264Sjacobs 					"ipp://%s/printers/", cups);
94*2264Sjacobs 				service_name = strdup(buf);
95*2264Sjacobs 			}
96*2264Sjacobs 		}
97*2264Sjacobs 		if (service_name == NULL)
98*2264Sjacobs 			service_name = DEFAULT_IPP_SERVICE_URI;
99*2264Sjacobs 
100*2264Sjacobs 		uri_from_string(service_name, &svc->uri);
101*2264Sjacobs 	}
102*2264Sjacobs 
103*2264Sjacobs 	if (svc->uri == NULL)
104*2264Sjacobs 		return (PAPI_NOT_POSSIBLE);
105*2264Sjacobs 
106*2264Sjacobs 	if (svc->uri->port != NULL)
107*2264Sjacobs 		port = strtol(svc->uri->port, NULL, 10);
108*2264Sjacobs 
109*2264Sjacobs 	svc->connection = httpConnectEncrypt(svc->uri->host, port,
110*2264Sjacobs 					http_encryption_type(svc->encryption));
111*2264Sjacobs 	if (svc->connection == NULL) {
112*2264Sjacobs 		if (svc->uri != NULL) {
113*2264Sjacobs 			uri_free(svc->uri);
114*2264Sjacobs 			svc->uri = NULL;
115*2264Sjacobs 		}
116*2264Sjacobs 		result = PAPI_SERVICE_UNAVAILABLE;
117*2264Sjacobs 	} else if (service_name != NULL)
118*2264Sjacobs 		svc->name = strdup(service_name);
119*2264Sjacobs 
120*2264Sjacobs 	return (result);
121*2264Sjacobs }
122*2264Sjacobs 
123*2264Sjacobs 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)124*2264Sjacobs papiServiceCreate(papi_service_t *handle, char *service_name,
125*2264Sjacobs 		char *user_name, char *password,
126*2264Sjacobs 		int (*authCB)(papi_service_t svc, void *app_data),
127*2264Sjacobs 		papi_encryption_t encryption, void *app_data)
128*2264Sjacobs {
129*2264Sjacobs 	papi_status_t result = PAPI_NOT_POSSIBLE;
130*2264Sjacobs 	service_t *svc = NULL;
131*2264Sjacobs 	char *encoding = getenv("HTTP_TRANSFER_ENCODING");
132*2264Sjacobs 
133*2264Sjacobs 	if (handle == NULL)
134*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
135*2264Sjacobs 
136*2264Sjacobs 	if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL)
137*2264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
138*2264Sjacobs 
139*2264Sjacobs 	if (user_name != NULL)
140*2264Sjacobs 		svc->user = strdup(user_name);
141*2264Sjacobs 
142*2264Sjacobs 	if (password != NULL)
143*2264Sjacobs 		svc->password = strdup(password);
144*2264Sjacobs 
145*2264Sjacobs 	svc->encryption = encryption;
146*2264Sjacobs 
147*2264Sjacobs 	if (authCB != NULL)
148*2264Sjacobs 		svc->authCB = authCB;
149*2264Sjacobs 
150*2264Sjacobs 	if (app_data != NULL)
151*2264Sjacobs 		svc->app_data = app_data;
152*2264Sjacobs 
153*2264Sjacobs 	if ((encoding != NULL) && (strcasecmp(encoding, "content-length") == 0))
154*2264Sjacobs 		svc->transfer_encoding = TRANSFER_ENCODING_LENGTH;
155*2264Sjacobs 	else
156*2264Sjacobs 		svc->transfer_encoding = TRANSFER_ENCODING_CHUNKED;
157*2264Sjacobs 
158*2264Sjacobs 	if (service_name != NULL) {
159*2264Sjacobs 		result = service_connect(svc, service_name);
160*2264Sjacobs 	} else
161*2264Sjacobs 		result = PAPI_OK;
162*2264Sjacobs 
163*2264Sjacobs 	return (result);
164*2264Sjacobs }
165*2264Sjacobs 
166*2264Sjacobs void
papiServiceDestroy(papi_service_t handle)167*2264Sjacobs papiServiceDestroy(papi_service_t handle)
168*2264Sjacobs {
169*2264Sjacobs 	if (handle != NULL) {
170*2264Sjacobs 		service_t *svc = handle;
171*2264Sjacobs 
172*2264Sjacobs 		if (svc->attributes != NULL)
173*2264Sjacobs 			papiAttributeListFree(svc->attributes);
174*2264Sjacobs 		if (svc->name != NULL)
175*2264Sjacobs 			free(svc->name);
176*2264Sjacobs 		if (svc->user != NULL)
177*2264Sjacobs 			free(svc->user);
178*2264Sjacobs 		if (svc->password != NULL)
179*2264Sjacobs 			free(svc->password);
180*2264Sjacobs 		if (svc->uri != NULL)
181*2264Sjacobs 			uri_free(svc->uri);
182*2264Sjacobs 		if (svc->post != NULL)
183*2264Sjacobs 			free(svc->post);
184*2264Sjacobs 		if (svc->connection != NULL)
185*2264Sjacobs 			httpClose(svc->connection);
186*2264Sjacobs 
187*2264Sjacobs 		free(handle);
188*2264Sjacobs 	}
189*2264Sjacobs }
190*2264Sjacobs 
191*2264Sjacobs papi_status_t
papiServiceSetUserName(papi_service_t handle,char * user_name)192*2264Sjacobs papiServiceSetUserName(papi_service_t handle, char *user_name)
193*2264Sjacobs {
194*2264Sjacobs 	papi_status_t result = PAPI_OK;
195*2264Sjacobs 
196*2264Sjacobs 	if (handle != NULL) {
197*2264Sjacobs 		service_t *svc = handle;
198*2264Sjacobs 
199*2264Sjacobs 		if (svc->user != NULL)
200*2264Sjacobs 			free(svc->user);
201*2264Sjacobs 		svc->user = NULL;
202*2264Sjacobs 		if (user_name != NULL)
203*2264Sjacobs 			svc->user = strdup(user_name);
204*2264Sjacobs 	} else
205*2264Sjacobs 		result = PAPI_BAD_ARGUMENT;
206*2264Sjacobs 
207*2264Sjacobs 	return (result);
208*2264Sjacobs }
209*2264Sjacobs 
210*2264Sjacobs papi_status_t
papiServiceSetPassword(papi_service_t handle,char * password)211*2264Sjacobs papiServiceSetPassword(papi_service_t handle, char *password)
212*2264Sjacobs {
213*2264Sjacobs 	papi_status_t result = PAPI_OK;
214*2264Sjacobs 
215*2264Sjacobs 	if (handle != NULL) {
216*2264Sjacobs 		service_t *svc = handle;
217*2264Sjacobs 
218*2264Sjacobs 		if (svc->password != NULL)
219*2264Sjacobs 			free(svc->password);
220*2264Sjacobs 		svc->password = NULL;
221*2264Sjacobs 		if (password != NULL)
222*2264Sjacobs 			svc->password = strdup(password);
223*2264Sjacobs 	} else
224*2264Sjacobs 		result = PAPI_BAD_ARGUMENT;
225*2264Sjacobs 
226*2264Sjacobs 	return (result);
227*2264Sjacobs }
228*2264Sjacobs 
229*2264Sjacobs papi_status_t
papiServiceSetEncryption(papi_service_t handle,papi_encryption_t encryption)230*2264Sjacobs papiServiceSetEncryption(papi_service_t handle,
231*2264Sjacobs 			papi_encryption_t encryption)
232*2264Sjacobs {
233*2264Sjacobs 	papi_status_t result = PAPI_OK;
234*2264Sjacobs 
235*2264Sjacobs 	if (handle != NULL) {
236*2264Sjacobs 		service_t *svc = handle;
237*2264Sjacobs 
238*2264Sjacobs 		svc->encryption = encryption;
239*2264Sjacobs 		httpEncryption(svc->connection,
240*2264Sjacobs 				(http_encryption_t)svc->encryption);
241*2264Sjacobs 	} else
242*2264Sjacobs 		result = PAPI_BAD_ARGUMENT;
243*2264Sjacobs 
244*2264Sjacobs 	return (result);
245*2264Sjacobs }
246*2264Sjacobs 
247*2264Sjacobs papi_status_t
papiServiceSetAuthCB(papi_service_t handle,int (* authCB)(papi_service_t svc,void * app_data))248*2264Sjacobs papiServiceSetAuthCB(papi_service_t handle,
249*2264Sjacobs 			int (*authCB)(papi_service_t svc, void *app_data))
250*2264Sjacobs {
251*2264Sjacobs 	papi_status_t result = PAPI_OK;
252*2264Sjacobs 
253*2264Sjacobs 	if (handle != NULL) {
254*2264Sjacobs 		service_t *svc = handle;
255*2264Sjacobs 
256*2264Sjacobs 		svc->authCB = authCB;
257*2264Sjacobs 	} else
258*2264Sjacobs 		result = PAPI_BAD_ARGUMENT;
259*2264Sjacobs 
260*2264Sjacobs 	return (result);
261*2264Sjacobs }
262*2264Sjacobs 
263*2264Sjacobs 
264*2264Sjacobs papi_status_t
papiServiceSetAppData(papi_service_t handle,void * app_data)265*2264Sjacobs papiServiceSetAppData(papi_service_t handle, void *app_data)
266*2264Sjacobs {
267*2264Sjacobs 	papi_status_t result = PAPI_OK;
268*2264Sjacobs 
269*2264Sjacobs 	if (handle != NULL) {
270*2264Sjacobs 		service_t *svc = handle;
271*2264Sjacobs 
272*2264Sjacobs 		svc->app_data = (void *)app_data;
273*2264Sjacobs 	} else
274*2264Sjacobs 		result = PAPI_BAD_ARGUMENT;
275*2264Sjacobs 
276*2264Sjacobs 	return (result);
277*2264Sjacobs }
278*2264Sjacobs 
279*2264Sjacobs char *
papiServiceGetServiceName(papi_service_t handle)280*2264Sjacobs papiServiceGetServiceName(papi_service_t handle)
281*2264Sjacobs {
282*2264Sjacobs 	char *result = NULL;
283*2264Sjacobs 
284*2264Sjacobs 	if (handle != NULL) {
285*2264Sjacobs 		service_t *svc = handle;
286*2264Sjacobs 
287*2264Sjacobs 		result = svc->name;
288*2264Sjacobs 	}
289*2264Sjacobs 
290*2264Sjacobs 	return (result);
291*2264Sjacobs }
292*2264Sjacobs 
293*2264Sjacobs char *
papiServiceGetUserName(papi_service_t handle)294*2264Sjacobs papiServiceGetUserName(papi_service_t handle)
295*2264Sjacobs {
296*2264Sjacobs 	char *result = NULL;
297*2264Sjacobs 
298*2264Sjacobs 	if (handle != NULL) {
299*2264Sjacobs 		service_t *svc = handle;
300*2264Sjacobs 
301*2264Sjacobs 		result = svc->user;
302*2264Sjacobs 	}
303*2264Sjacobs 
304*2264Sjacobs 	return (result);
305*2264Sjacobs }
306*2264Sjacobs 
307*2264Sjacobs char *
papiServiceGetPassword(papi_service_t handle)308*2264Sjacobs papiServiceGetPassword(papi_service_t handle)
309*2264Sjacobs {
310*2264Sjacobs 	char *result = NULL;
311*2264Sjacobs 
312*2264Sjacobs 	if (handle != NULL) {
313*2264Sjacobs 		service_t *svc = handle;
314*2264Sjacobs 
315*2264Sjacobs 		result = svc->password;
316*2264Sjacobs 	}
317*2264Sjacobs 
318*2264Sjacobs 	return (result);
319*2264Sjacobs }
320*2264Sjacobs 
321*2264Sjacobs papi_encryption_t
papiServiceGetEncryption(papi_service_t handle)322*2264Sjacobs papiServiceGetEncryption(papi_service_t handle)
323*2264Sjacobs {
324*2264Sjacobs 	papi_encryption_t result = PAPI_ENCRYPT_NEVER;
325*2264Sjacobs 
326*2264Sjacobs 	if (handle != NULL) {
327*2264Sjacobs 		service_t *svc = handle;
328*2264Sjacobs 
329*2264Sjacobs 		result = svc->encryption;
330*2264Sjacobs 	}
331*2264Sjacobs 
332*2264Sjacobs 	return (result);
333*2264Sjacobs }
334*2264Sjacobs 
335*2264Sjacobs void *
papiServiceGetAppData(papi_service_t handle)336*2264Sjacobs papiServiceGetAppData(papi_service_t handle)
337*2264Sjacobs {
338*2264Sjacobs 	void *result = NULL;
339*2264Sjacobs 
340*2264Sjacobs 	if (handle != NULL) {
341*2264Sjacobs 		service_t *svc = handle;
342*2264Sjacobs 
343*2264Sjacobs 		result = svc->app_data;
344*2264Sjacobs 	}
345*2264Sjacobs 
346*2264Sjacobs 	return (result);
347*2264Sjacobs }
348*2264Sjacobs 
349*2264Sjacobs papi_attribute_t **
papiServiceGetAttributeList(papi_service_t handle)350*2264Sjacobs papiServiceGetAttributeList(papi_service_t handle)
351*2264Sjacobs {
352*2264Sjacobs 	papi_attribute_t **result = NULL;
353*2264Sjacobs 	service_t *svc = handle;
354*2264Sjacobs 
355*2264Sjacobs 	if (handle != NULL)
356*2264Sjacobs 		result = svc->attributes;
357*2264Sjacobs 
358*2264Sjacobs 	return (result);
359*2264Sjacobs }
360*2264Sjacobs 
361*2264Sjacobs char *
papiServiceGetStatusMessage(papi_service_t handle)362*2264Sjacobs papiServiceGetStatusMessage(papi_service_t handle)
363*2264Sjacobs {
364*2264Sjacobs 	char *result = NULL;
365*2264Sjacobs 	service_t *svc = handle;
366*2264Sjacobs 
367*2264Sjacobs 	papiAttributeListGetString(svc->attributes, NULL,
368*2264Sjacobs 					"detailed-status-message", &result);
369*2264Sjacobs 
370*2264Sjacobs 	return (result);
371*2264Sjacobs }
372*2264Sjacobs 
373*2264Sjacobs void
detailed_error(service_t * svc,char * fmt,...)374*2264Sjacobs detailed_error(service_t *svc, char *fmt, ...)
375*2264Sjacobs {
376*2264Sjacobs 	if ((svc != NULL) && (fmt != NULL)) {
377*2264Sjacobs 		va_list ap;
378*2264Sjacobs 		size_t size;
379*2264Sjacobs 		char *message = alloca(BUFSIZ);
380*2264Sjacobs 
381*2264Sjacobs 		va_start(ap, fmt);
382*2264Sjacobs 		/*
383*2264Sjacobs 		 * fill in the message.  If the buffer is too small, allocate
384*2264Sjacobs 		 * one that is large enough and fill it in.
385*2264Sjacobs 		 */
386*2264Sjacobs 		if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ)
387*2264Sjacobs 			if ((message = alloca(size)) != NULL)
388*2264Sjacobs 				vsnprintf(message, size, fmt, ap);
389*2264Sjacobs 		va_end(ap);
390*2264Sjacobs 
391*2264Sjacobs 		papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND,
392*2264Sjacobs 					"detailed-status-message", message);
393*2264Sjacobs 	}
394*2264Sjacobs }
395