8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / print / libpapi-dynamic / common / service.c
blob55f1732a659012e81fdee82216496f2b4244cff8
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 /* $Id: service.c 172 2006-05-24 20:54:00Z njacobs $ */
30 #pragma ident "%Z%%M% %I% %E% SMI"
32 /*LINTLIBRARY*/
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <stdarg.h>
37 #include <sys/types.h>
38 #include <unistd.h>
39 #include <string.h>
40 #include <alloca.h>
41 #include <libintl.h>
42 #include <papi_impl.h>
43 #include <config-site.h>
45 static int
46 interposed_auth_callback(papi_service_t handle, void *app_data)
48 int result = -1;
49 service_t *svc = app_data;
51 if (svc != NULL)
52 result = svc->authCB(svc, svc->app_data);
54 return (result);
57 static char *
58 default_service_uri(char *fallback)
60 char *result = NULL;
62 if (getuid() == geteuid())
63 result = getenv("PAPI_SERVICE_URI");
65 if (result == NULL) {
66 char *cups;
68 if ((cups = getenv("CUPS_SERVER")) != NULL) {
69 char buf[BUFSIZ];
71 snprintf(buf, sizeof (buf), "ipp://%s/printers/", cups);
72 result = strdup(buf);
76 if (result == NULL)
77 result = fallback;
79 return (result);
82 static char *
83 default_print_service()
85 static char *result = NULL;
87 if (result == NULL) {
88 char *service_uri = default_service_uri(DEFAULT_SERVICE_URI);
89 uri_t *uri = NULL;
91 if (uri_from_string(service_uri, &uri) != -1)
92 result = strdup(uri->scheme);
94 if (uri != NULL)
95 uri_free(uri);
98 return (result);
101 static papi_status_t
102 service_load(service_t *svc, char *name)
104 papi_status_t result;
105 char *scheme = default_print_service();
107 if (svc->so_handle != NULL) /* already loaded */
108 return (PAPI_OK);
110 if (name == NULL) /* no info, can't load yet */
111 return (PAPI_OK);
113 /* Lookup the printer in the configuration DB */
114 svc->attributes = getprinterbyname((char *)name, NULL);
116 if (svc->attributes != NULL) {
117 char *tmp = NULL;
119 /* Printer found (or was a URI), use the attribute data */
120 papiAttributeListGetString(svc->attributes, NULL,
121 "printer-uri-supported", &tmp);
122 if (tmp != NULL)
123 svc->name = strdup(tmp);
125 /* parse the URI and set the scheme(print service) */
126 if (uri_from_string(svc->name, &svc->uri) != -1)
127 scheme = (svc->uri)->scheme;
129 /* override the scheme if it was in the attributes */
130 papiAttributeListGetString(svc->attributes, NULL,
131 "print-service-module", &scheme);
133 } else /* not found, assume it is the actual print service name */
134 scheme = name;
136 result = psm_open(svc, scheme);
137 switch (result) {
138 case PAPI_OK:
139 break; /* no error */
140 case PAPI_URI_SCHEME:
141 result = PAPI_NOT_FOUND;
142 #ifdef DEBUG
143 detailed_error(svc, "Unable to load service for: %s", name);
144 #endif
145 break;
146 default: /* set the detailed message */
147 detailed_error(svc, "Unable to load service (%s) for: %s",
148 scheme, name);
151 return (result);
154 static papi_status_t
155 service_send_peer(service_t *svc)
157 papi_status_t result = PAPI_OK;
159 if ((svc->peer_fd != -1) && (svc->so_handle != NULL) &&
160 (svc->svc_handle != NULL)) {
161 papi_status_t (*f)();
163 f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetPeer");
165 if (f != NULL)
166 result = f(svc->svc_handle, svc->peer_fd);
169 return (result);
172 papi_status_t
173 service_connect(service_t *svc, char *name)
175 papi_status_t result = PAPI_NOT_POSSIBLE;
177 /* if there is no print service module loaded, try and load one. */
178 if (svc->so_handle == NULL)
179 result = service_load(svc, name);
180 else if ((svc->name == NULL) && (name != NULL))
181 svc->name = strdup(name);
184 * the print service module is loaded, but we don't have a service
185 * handle.
187 if (svc->so_handle != NULL) {
188 papi_status_t (*f)();
190 if (svc->svc_handle != NULL) /* already connected? */
191 return (PAPI_OK);
193 f = (papi_status_t (*)())psm_sym(svc, "papiServiceCreate");
195 if (f != NULL) {
196 char *user = svc->user;
197 char *password = svc->password;
199 /* if no API user, try the URI user */
200 if ((user == NULL) && (svc->uri != NULL))
201 user = (svc->uri)->user;
202 /* if no API password, try the URI password */
203 if ((password == NULL) && (svc->uri != NULL))
204 password = (svc->uri)->password;
206 result = f(&svc->svc_handle, svc->name, user, password,
207 (svc->authCB ? interposed_auth_callback
208 : NULL),
209 svc->encryption, svc);
210 (void) service_send_peer(svc);
214 return (result);
217 papi_status_t
218 papiServiceCreate(papi_service_t *handle, char *service_name, char *user_name,
219 char *password,
220 int (*authCB)(papi_service_t svc, void *app_data),
221 papi_encryption_t encryption, void *app_data)
223 papi_status_t result = PAPI_NOT_POSSIBLE;
224 service_t *svc = NULL;
225 uri_t *u = NULL;
227 if (handle == NULL)
228 return (PAPI_BAD_ARGUMENT);
230 if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL)
231 return (PAPI_TEMPORARY_ERROR);
233 svc->peer_fd = -1;
235 if (user_name != NULL)
236 svc->user = strdup(user_name);
238 if (password != NULL)
239 svc->password = strdup(password);
241 svc->encryption = encryption;
243 if (authCB != NULL)
244 svc->authCB = authCB;
246 if (app_data != NULL)
247 svc->app_data = app_data;
249 /* If not specified, get a "default" service from the environment */
250 if (service_name == NULL)
251 service_name = default_service_uri(NULL);
253 if (service_name != NULL) {
254 result = service_load(svc, service_name);
255 /* if the psm loaded and the svc contains a URI, connect */
256 if ((result == PAPI_OK) && (svc->uri != NULL))
257 result = service_connect(svc, service_name);
258 } else
259 result = PAPI_OK;
261 return (result);
264 void
265 papiServiceDestroy(papi_service_t handle)
267 if (handle != NULL) {
268 service_t *svc = handle;
270 if (svc->so_handle != NULL) {
271 if (svc->svc_handle != NULL) {
272 void (*f)();
274 f = (void (*)())psm_sym(svc,
275 "papiServiceDestroy");
276 f(svc->svc_handle);
278 psm_close(svc->so_handle);
280 if (svc->attributes != NULL)
281 papiAttributeListFree(svc->attributes);
282 if (svc->name != NULL)
283 free(svc->name);
284 if (svc->user != NULL)
285 free(svc->user);
286 if (svc->password != NULL)
287 free(svc->password);
288 if (svc->uri != NULL)
289 uri_free(svc->uri);
291 free(handle);
295 papi_status_t
296 papiServiceSetPeer(papi_service_t handle, int fd)
298 papi_status_t result = PAPI_OK;
300 if (handle != NULL) {
301 service_t *svc = handle;
303 svc->peer_fd = fd;
304 result = service_send_peer(svc);
305 } else
306 result = PAPI_BAD_ARGUMENT;
308 return (result);
311 papi_status_t
312 papiServiceSetUserName(papi_service_t handle, char *user_name)
314 papi_status_t result = PAPI_OK;
316 if (handle != NULL) {
317 service_t *svc = handle;
318 papi_status_t (*f)();
320 if (svc->user != NULL)
321 free(svc->user);
322 if (user_name != NULL)
323 svc->user = strdup(user_name);
324 f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetUserName");
325 if (f != NULL)
326 result = f(svc->svc_handle, user_name);
327 } else
328 result = PAPI_BAD_ARGUMENT;
330 return (result);
333 papi_status_t
334 papiServiceSetPassword(papi_service_t handle, char *password)
336 papi_status_t result = PAPI_OK;
338 if (handle != NULL) {
339 service_t *svc = handle;
340 papi_status_t (*f)();
342 if (svc->password != NULL)
343 free(svc->password);
344 if (password != NULL)
345 svc->password = strdup(password);
346 f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetPassword");
347 if (f != NULL)
348 result = f(svc->svc_handle, password);
349 } else
350 result = PAPI_BAD_ARGUMENT;
352 return (result);
355 papi_status_t
356 papiServiceSetEncryption(papi_service_t handle, papi_encryption_t encryption)
358 papi_status_t result = PAPI_OK;
360 if (handle != NULL) {
361 service_t *svc = handle;
362 papi_status_t (*f)();
364 svc->encryption = encryption;
365 f = (papi_status_t (*)())psm_sym(svc,
366 "papiServiceSetEncryption");
367 if (f != NULL)
368 result = f(svc->svc_handle, encryption);
369 } else
370 result = PAPI_BAD_ARGUMENT;
372 return (result);
375 papi_status_t
376 papiServiceSetAuthCB(papi_service_t handle,
377 int (*authCB)(papi_service_t svc, void *app_data))
379 papi_status_t result = PAPI_OK;
381 if (handle != NULL) {
382 service_t *svc = handle;
383 papi_status_t (*f)();
385 svc->authCB = authCB;
386 f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetAuthCB");
387 if (f != NULL)
388 result = f(svc->svc_handle, interposed_auth_callback);
389 } else
390 result = PAPI_BAD_ARGUMENT;
392 return (result);
396 papi_status_t
397 papiServiceSetAppData(papi_service_t handle, void *app_data)
399 papi_status_t result = PAPI_OK;
401 if (handle != NULL) {
402 service_t *svc = handle;
403 papi_status_t (*f)();
405 svc->app_data = (void *)app_data;
406 } else
407 result = PAPI_BAD_ARGUMENT;
409 return (result);
412 char *
413 papiServiceGetServiceName(papi_service_t handle)
415 char *result = NULL;
417 if (handle != NULL) {
418 service_t *svc = handle;
419 char *(*f)();
421 f = (char *(*)())psm_sym(svc, "papiServiceGetServiceName");
422 if (f != NULL)
423 result = f(svc->svc_handle);
424 if (result == NULL)
425 result = svc->name;
428 return (result);
431 char *
432 papiServiceGetUserName(papi_service_t handle)
434 char *result = NULL;
436 if (handle != NULL) {
437 service_t *svc = handle;
438 char *(*f)();
440 f = (char *(*)())psm_sym(svc, "papiServiceGetUserName");
441 if (f != NULL)
442 result = f(svc->svc_handle);
443 if (result == NULL)
444 result = svc->user;
447 return (result);
450 char *
451 papiServiceGetPassword(papi_service_t handle)
453 char *result = NULL;
455 if (handle != NULL) {
456 service_t *svc = handle;
457 char *(*f)();
459 f = (char *(*)())psm_sym(svc, "papiServiceGetPassword");
460 if (f != NULL)
461 result = f(svc->svc_handle);
462 if (result == NULL)
463 result = svc->password;
466 return (result);
469 papi_encryption_t
470 papiServiceGetEncryption(papi_service_t handle)
472 papi_encryption_t result = PAPI_ENCRYPT_NEVER;
474 if (handle != NULL) {
475 service_t *svc = handle;
476 papi_encryption_t (*f)();
478 f = (papi_encryption_t (*)())psm_sym(svc,
479 "papiServiceGetEncryption");
480 if (f != NULL)
481 result = f(svc->svc_handle);
482 if (result == PAPI_ENCRYPT_NEVER)
483 result = svc->encryption;
486 return (result);
489 void *
490 papiServiceGetAppData(papi_service_t handle)
492 void *result = NULL;
493 service_t *svc = handle;
495 if (handle != NULL)
496 result = svc->app_data;
498 return (result);
501 papi_attribute_t **
502 papiServiceGetAttributeList(papi_service_t handle)
504 papi_attribute_t **result = NULL;
505 service_t *svc = handle;
507 if (handle != NULL) {
508 papi_attribute_t **(*f)();
510 if (svc->so_handle == NULL) {
511 char *uri = default_service_uri(DEFAULT_SERVICE_URI);
513 if (service_connect(svc, uri) != PAPI_OK)
514 return (NULL);
517 f = (papi_attribute_t **(*)())psm_sym(svc,
518 "papiServiceGetAttributeList");
519 if (f != NULL)
520 result = f(svc->svc_handle);
521 } else
522 result = svc->attributes;
524 return (result);
527 char *
528 papiServiceGetStatusMessage(papi_service_t handle)
530 char *result = NULL;
531 service_t *svc = handle;
533 if (handle != NULL) {
534 char *(*f)();
536 f = (char *(*)())psm_sym(svc, "papiServiceGetStatusMessage");
537 if (f != NULL)
538 result = f(svc->svc_handle);
540 if (result == NULL) {
541 papiAttributeListGetString(svc->attributes, NULL,
542 "detailed-status-message", &result);
545 return (result);
548 void
549 detailed_error(service_t *svc, char *fmt, ...)
551 if ((svc != NULL) && (fmt != NULL)) {
552 va_list ap;
553 size_t size;
554 char *message = alloca(BUFSIZ);
556 va_start(ap, fmt);
558 * fill in the message. If the buffer is too small, allocate
559 * one that is large enough and fill it in.
561 if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ)
562 if ((message = alloca(size)) != NULL)
563 vsnprintf(message, size, fmt, ap);
564 va_end(ap);
566 papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND,
567 "detailed-status-message", message);
568 #ifdef DEBUG
569 fprintf(stderr, "detailed_error(%s)\n", message);
570 #endif