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