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