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