/*
* 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);
}