OpenSolaris_b135/lib/print/libipp-listener/common/common.c

Compare this file to the similar file:
Show the results in this format:

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 *
 */

/* $Id: common.c 155 2006-04-26 02:34:54Z ktou $ */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <papi.h>
#include <ipp-listener.h>

char *
ipp_svc_status_mesg(papi_service_t svc, papi_status_t status)
{
	char *mesg =  papiServiceGetStatusMessage(svc);

	if (mesg == NULL)
		mesg = papiStatusString(status);

	return (mesg);
}

char *
destination_from_printer_uri(char *uri)
{
	static char buf[64];
	char *result = NULL;

	if (uri != NULL)
		result = strrchr(uri, '/');

	if (result == NULL)
		result = uri;
	else
		result++;

#ifdef FORCE_LPSCHED_URI
	snprintf(buf, sizeof (buf), "lpsched://localhost/printers/%s", result);
	result = buf;
#endif /* FORCE_LPSCHED_URI */

	return (result);
}

void
get_printer_id(papi_attribute_t **attributes, char **printer, int *id)
{
	papi_status_t result;
	char *job = NULL;
	char *fodder;
	int junk;

	if (printer == NULL)
		printer = &fodder;
	if (id == NULL)
		id = &junk;

	*printer = NULL;
	*id = -1;

	result = papiAttributeListGetString(attributes, NULL, "job-uri", &job);
	if (result != PAPI_OK) {
		result = papiAttributeListGetString(attributes, NULL,
						"printer-uri", printer);
		if (result == PAPI_OK)
			papiAttributeListGetInteger(attributes, NULL,
						"job-id", id);
	} else {
		*printer = job;
		if ((job = strrchr(*printer, '/')) != NULL) {
			*job = '\0';
			*id = atoi(++job);
		}
	}
}

void
get_string_list(papi_attribute_t **attributes, char *name, char ***values)
{
	papi_status_t result;

	void *iterator = NULL;
	char *value = NULL;

	for (result = papiAttributeListGetString(attributes, &iterator,
					name, &value);
	    result == PAPI_OK;
	    result = papiAttributeListGetString(attributes, &iterator,
					NULL, &value))
		list_append(values, value);
}

void
add_default_attributes(papi_attribute_t ***attributes)
{

	(void) papiAttributeListAddString(attributes, PAPI_ATTR_APPEND,
			"ipp-versions-supported", "1.0");
	(void) papiAttributeListAddString(attributes, PAPI_ATTR_APPEND,
			"ipp-versions-supported", "1.1");
	(void) papiAttributeListAddBoolean(attributes, PAPI_ATTR_EXCL,
			"multiple-document-jobs-supported", 0);
	/*
	 * Should be able to ask the web server if it supports SSL or TLS, but
	 * for now, we pick only "none"
	 */
	(void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
			"uri-security-supported", "none");

	/*
	 * For now, we only "none".  As we support more authentication methods,
	 * we will need to add the associated uri for each.  Valid values would
	 * be:
	 *	"none", "requesting-user-name", "basic", "digest", "certificate"
	 * See RFC2911 page 127 for more information.
	 */
	(void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
			"uri-authentication-supported", "requesting-user-name");
	(void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
			"uri-security-supported", "none");
	/* printer-uri-supported is added in the service based attributes */

	(void) papiAttributeListAddInteger(attributes, PAPI_ATTR_EXCL,
			"multiple-operation-time-out", 60);

	/* I18N related */
	(void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
			"charset-configured", "utf-8");
	(void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
			"charset-supported", "utf-8");
	(void) papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
			"natural-language-configured", "en-us");
}

static void
massage_printer_attributes_group(papi_attribute_t **group, char *printer_uri)
{
	if (papiAttributeListFind(group, "printer-uri-supported") != NULL)
		papiAttributeListAddString(&group, PAPI_ATTR_REPLACE,
				"printer-uri-supported", printer_uri);
}

static void
massage_job_attributes_group(papi_attribute_t **group, char *printer_uri)
{
	if (papiAttributeListFind(group, "job-printer-uri") != NULL)
		papiAttributeListAddString(&group, PAPI_ATTR_REPLACE,
				"job-printer-uri", printer_uri);

	if (papiAttributeListFind(group, "job-printer-uri") != NULL) {
		char buf[BUFSIZ];
		int32_t id = -1;

		papiAttributeListGetInteger(group, NULL, "job-id", &id);
		snprintf(buf, sizeof (buf), "%s/%d", printer_uri, id);
		papiAttributeListAddString(&group, PAPI_ATTR_REPLACE,
				"job-uri", buf);
	}
}

/*
 * This function will replace the job/printer URIs with the requested
 * uri because the print service may return a URI that isn't IPP based.
 */
void
massage_response(papi_attribute_t **request, papi_attribute_t **response)
{
	papi_status_t status;
	papi_attribute_t **group = NULL;
	void *iter = NULL;
	char *host = "localhost";
	char *path = "/printers/";
	int port = 631;
	char buf[BUFSIZ];

	(void) papiAttributeListGetString(request, NULL, "uri-host", &host);
	(void) papiAttributeListGetString(request, NULL, "uri-path", &path);
	(void) papiAttributeListGetInteger(request, NULL, "uri-port", &port);

	if (port == 631)
		snprintf(buf, sizeof (buf), "ipp://%s%s", host, path);
	else
		snprintf(buf, sizeof (buf), "http://%s:%d%s", host, port, path);

	for (status = papiAttributeListGetCollection(response, &iter,
				"printer-attributes-group", &group);
	     status == PAPI_OK;
	     status = papiAttributeListGetCollection(NULL, &iter,
				NULL, &group))
		massage_printer_attributes_group(group, buf);

	iter = NULL;
	for (status = papiAttributeListGetCollection(response, &iter,
				"job-attributes-group", &group);
	     status == PAPI_OK;
	     status = papiAttributeListGetCollection(NULL, &iter,
				NULL, &group))
		massage_job_attributes_group(group, buf);
}

/*
 * This walks through the locale tab and returns the installed
 * locales.  There must be a better way.
 */
void
add_supported_locales(papi_attribute_t ***attributes)
{
	FILE *fp;

	papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
			"generated-natural-language-supported", "en-us");

#ifndef __linux__	/* this is Solaris specific */
	if ((fp = fopen("/usr/lib/locale/lcttab", "r")) != NULL) {
		char buf[1024];

		while (fgets(buf, sizeof (buf), fp) != NULL) {
			char *name, *file;
			int i, passed = 1;

			name = strtok(buf, " \t\n");

			for (i = 0; ((passed == 1) && (name[i] != NULL)); i++)
				if (isalpha(name[i]) != 0)
					name[i] = tolower(name[i]);
				else if ((name[i] == '_') || (name[i] == '-'))
					name[i] = '-';
				else
					passed = 0;

			if ((passed == 1) &&
			    ((file = strtok(NULL, " \t\n")) != NULL)) {
					char path[1024];

				snprintf(path, sizeof (path),
					"/usr/lib/locale/%s", file);

				if (access(path, F_OK) == 0)
					papiAttributeListAddString(attributes,
						PAPI_ATTR_APPEND,
					"generated-natural-language-supported",
					name);
			}
		}
	}
#endif
}

void
papi_to_ipp_printer_group(papi_attribute_t ***response,
		papi_attribute_t **request, int flags, papi_printer_t p)
{
	papi_attribute_t **ipp_group = NULL;

	copy_attributes(&ipp_group, papiPrinterGetAttributeList(p));

	/* Windows clients appear to have a problem with very large values */
	papiAttributeListDelete(&ipp_group, "lpsched-printer-ppd-contents");

	add_default_attributes(&ipp_group);
	ipp_operations_supported(&ipp_group, request);

	(void) papiAttributeListAddCollection(response, flags,
			"printer-attributes-group", ipp_group);
	papiAttributeListFree(ipp_group);
}

void
papi_to_ipp_job_group(papi_attribute_t ***response,
			papi_attribute_t **request, int flags, papi_job_t j)
{
	papi_attribute_t **ipp_group = NULL;

	copy_attributes(&ipp_group, papiJobGetAttributeList(j));

	(void) papiAttributeListAddCollection(response, flags,
			"job-attributes-group", ipp_group);
	papiAttributeListFree(ipp_group);
}