diff options
author | jacobs <none@none> | 2006-06-22 13:28:31 -0700 |
---|---|---|
committer | jacobs <none@none> | 2006-06-22 13:28:31 -0700 |
commit | 355b4669e025ff377602b6fc7caaf30dbc218371 (patch) | |
tree | 29a740456e8d09f935e18068ce72814285fafeec /usr/src/lib/print/libipp-core | |
parent | 5d0bc3ededb82d77f7c33d8f58e517a837ba5140 (diff) | |
download | illumos-joyent-355b4669e025ff377602b6fc7caaf30dbc218371.tar.gz |
LSARC/2003/547 PAPI Print Commands
LSARC/2006/172 PAPI Print Commands Packaging Breakout
4144591 lpstat -d reports *process* default printer as *system* default printer
4299193 lp -cd <queue> <file> causes multiple -d options errors
4327963 RFE cancel on local queue should not require in.lpd
4331220 lpmove doesn't work on remote print queues
4470602 Customer wants to increase print limit of 52 files to 300
4949866 lpstat shows FAILED printers due to expanded status message
4994469 lpadmin doesn't add filter definitions for printers
6302778 RUNPATH & RPATH errors in SUNWipplu package
6314007 lpstat should report paper type list supported by a printer
6317991 lprm -Pprintername - command results in aSegmentation fault
6338002 lpsched support for PAPI is incomplete
6346505 print commands should use PAPI for service interaction (LSARC/2003/547)
6364267 psm-lpsched has replicated code
6389273 RUNPATH and RPATH failures in SUNWippcore
--HG--
rename : usr/src/cmd/lp/cmd/cancel.c => deleted_files/usr/src/cmd/lp/cmd/cancel.c
rename : usr/src/cmd/lp/cmd/comb.c => deleted_files/usr/src/cmd/lp/cmd/comb.c
rename : usr/src/cmd/lp/cmd/lp.c => deleted_files/usr/src/cmd/lp/cmd/lp.c
rename : usr/src/cmd/lp/cmd/lpc/Makefile => deleted_files/usr/src/cmd/lp/cmd/lpc/Makefile
rename : usr/src/cmd/lp/cmd/lpc/cmds.c => deleted_files/usr/src/cmd/lp/cmd/lpc/cmds.c
rename : usr/src/cmd/lp/cmd/lpc/cmdtab.c => deleted_files/usr/src/cmd/lp/cmd/lpc/cmdtab.c
rename : usr/src/cmd/lp/cmd/lpc/fatalmsg.c => deleted_files/usr/src/cmd/lp/cmd/lpc/fatalmsg.c
rename : usr/src/cmd/lp/cmd/lpc/global.c => deleted_files/usr/src/cmd/lp/cmd/lpc/global.c
rename : usr/src/cmd/lp/cmd/lpc/lpc.c => deleted_files/usr/src/cmd/lp/cmd/lpc/lpc.c
rename : usr/src/cmd/lp/cmd/lpc/lpc.h => deleted_files/usr/src/cmd/lp/cmd/lpc/lpc.h
rename : usr/src/cmd/lp/cmd/lpc/process.c => deleted_files/usr/src/cmd/lp/cmd/lpc/process.c
rename : usr/src/cmd/lp/cmd/lpc/sndrcv.c => deleted_files/usr/src/cmd/lp/cmd/lpc/sndrcv.c
rename : usr/src/cmd/lp/cmd/lpc/topq.c => deleted_files/usr/src/cmd/lp/cmd/lpc/topq.c
rename : usr/src/cmd/lp/cmd/lpmove.c => deleted_files/usr/src/cmd/lp/cmd/lpmove.c
rename : usr/src/cmd/lp/cmd/lpstat/Makefile => deleted_files/usr/src/cmd/lp/cmd/lpstat/Makefile
rename : usr/src/cmd/lp/cmd/lpstat/accept.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/accept.c
rename : usr/src/cmd/lp/cmd/lpstat/add_mounted.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/add_mounted.c
rename : usr/src/cmd/lp/cmd/lpstat/charset.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/charset.c
rename : usr/src/cmd/lp/cmd/lpstat/class.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/class.c
rename : usr/src/cmd/lp/cmd/lpstat/device.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/device.c
rename : usr/src/cmd/lp/cmd/lpstat/done.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/done.c
rename : usr/src/cmd/lp/cmd/lpstat/form.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/form.c
rename : usr/src/cmd/lp/cmd/lpstat/lpstat.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/lpstat.c
rename : usr/src/cmd/lp/cmd/lpstat/lpstat.h => deleted_files/usr/src/cmd/lp/cmd/lpstat/lpstat.h
rename : usr/src/cmd/lp/cmd/lpstat/output.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/output.c
rename : usr/src/cmd/lp/cmd/lpstat/parse.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/parse.c
rename : usr/src/cmd/lp/cmd/lpstat/printer.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/printer.c
rename : usr/src/cmd/lp/cmd/lpstat/request.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/request.c
rename : usr/src/cmd/lp/cmd/lpstat/send_message.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/send_message.c
rename : usr/src/cmd/lp/lib/papi/attribute.c => deleted_files/usr/src/cmd/lp/lib/papi/attribute.c
rename : usr/src/cmd/lp/lib/papi/list.c => deleted_files/usr/src/cmd/lp/lib/papi/list.c
rename : usr/src/cmd/lp/lib/papi/papi.h => deleted_files/usr/src/cmd/lp/lib/papi/papi.h
rename : usr/src/cmd/lp/lib/papi/status.c => deleted_files/usr/src/cmd/lp/lib/papi/status.c
rename : usr/src/cmd/print/cancel/Makefile => deleted_files/usr/src/cmd/print/cancel/Makefile
rename : usr/src/cmd/print/cancel/cancel.c => deleted_files/usr/src/cmd/print/cancel/cancel.c
rename : usr/src/cmd/print/cancel/cancel_list.c => deleted_files/usr/src/cmd/print/cancel/cancel_list.c
rename : usr/src/cmd/print/cancel/cancel_list.h => deleted_files/usr/src/cmd/print/cancel/cancel_list.h
rename : usr/src/cmd/print/lp/Makefile => deleted_files/usr/src/cmd/print/lp/Makefile
rename : usr/src/cmd/print/lpmove/Makefile => deleted_files/usr/src/cmd/print/lpmove/Makefile
rename : usr/src/cmd/print/lpmove/lpmove.c => deleted_files/usr/src/cmd/print/lpmove/lpmove.c
rename : usr/src/cmd/print/lpstat/Makefile => deleted_files/usr/src/cmd/print/lpstat/Makefile
rename : usr/src/cmd/print/lpstat/bsd-functions.c => deleted_files/usr/src/cmd/print/lpstat/bsd-functions.c
rename : usr/src/cmd/print/lpstat/bsd-functions.h => deleted_files/usr/src/cmd/print/lpstat/bsd-functions.h
rename : usr/src/cmd/print/lpstat/lpstat.c => deleted_files/usr/src/cmd/print/lpstat/lpstat.c
rename : usr/src/cmd/print/lpstat/parse.h => deleted_files/usr/src/cmd/print/lpstat/parse.h
rename : usr/src/cmd/print/lpstat/parse_bsd.c => deleted_files/usr/src/cmd/print/lpstat/parse_bsd.c
rename : usr/src/cmd/print/lpstat/sysv-functions.c => deleted_files/usr/src/cmd/print/lpstat/sysv-functions.c
rename : usr/src/cmd/print/lpstat/sysv-functions.h => deleted_files/usr/src/cmd/print/lpstat/sysv-functions.h
rename : usr/src/cmd/print/scripts/accept => deleted_files/usr/src/cmd/print/scripts/accept
rename : usr/src/cmd/lp/lib/papi/mapfile-vers => usr/src/cmd/lp/lib/papi/mapfile
rename : usr/src/cmd/print/lp/cleanup.xml => usr/src/cmd/print/gateway/cleanup.xml
rename : usr/src/cmd/print/lp/print-cleanup => usr/src/cmd/print/gateway/print-cleanup
rename : usr/src/cmd/print/lp/lp.c => usr/src/cmd/print/gateway/printd.c
rename : usr/src/lib/print/job.c => usr/src/lib/print/libprint/common/job.c
rename : usr/src/lib/print/job.h => usr/src/lib/print/libprint/common/job.h
rename : usr/src/lib/print/list.c => usr/src/lib/print/libprint/common/list.c
rename : usr/src/lib/print/list.h => usr/src/lib/print/libprint/common/list.h
rename : usr/src/lib/print/llib-lprint => usr/src/lib/print/libprint/common/llib-lprint
rename : usr/src/lib/print/mapfile-vers => usr/src/lib/print/libprint/common/mapfile-vers
rename : usr/src/lib/print/misc.c => usr/src/lib/print/libprint/common/misc.c
rename : usr/src/lib/print/misc.h => usr/src/lib/print/libprint/common/misc.h
rename : usr/src/lib/print/network.c => usr/src/lib/print/libprint/common/network.c
rename : usr/src/lib/print/network.h => usr/src/lib/print/libprint/common/network.h
rename : usr/src/lib/print/ns.c => usr/src/lib/print/libprint/common/ns.c
rename : usr/src/lib/print/ns.h => usr/src/lib/print/libprint/common/ns.h
rename : usr/src/lib/print/ns_bsd_addr.c => usr/src/lib/print/libprint/common/ns_bsd_addr.c
rename : usr/src/lib/print/ns_cmn_kvp.c => usr/src/lib/print/libprint/common/ns_cmn_kvp.c
rename : usr/src/lib/print/ns_cmn_printer.c => usr/src/lib/print/libprint/common/ns_cmn_printer.c
rename : usr/src/lib/print/nss_convert.c => usr/src/lib/print/libprint/common/nss_convert.c
rename : usr/src/lib/print/nss_ldap.c => usr/src/lib/print/libprint/common/nss_ldap.c
rename : usr/src/lib/print/nss_printer.c => usr/src/lib/print/libprint/common/nss_printer.c
rename : usr/src/lib/print/nss_write.c => usr/src/lib/print/libprint/common/nss_write.c
rename : usr/src/lib/print/sunPrinter.at.conf.txt => usr/src/lib/print/libprint/common/sunPrinter.at.conf.txt
rename : usr/src/lib/print/sunPrinter.oc.conf.txt => usr/src/lib/print/libprint/common/sunPrinter.oc.conf.txt
Diffstat (limited to 'usr/src/lib/print/libipp-core')
-rw-r--r-- | usr/src/lib/print/libipp-core/Makefile | 56 | ||||
-rw-r--r-- | usr/src/lib/print/libipp-core/Makefile.com | 58 | ||||
-rw-r--r-- | usr/src/lib/print/libipp-core/common/ipp.c | 136 | ||||
-rw-r--r-- | usr/src/lib/print/libipp-core/common/ipp.h | 348 | ||||
-rw-r--r-- | usr/src/lib/print/libipp-core/common/ipp_types.c | 303 | ||||
-rw-r--r-- | usr/src/lib/print/libipp-core/common/mapfile | 48 | ||||
-rw-r--r-- | usr/src/lib/print/libipp-core/common/read.c | 666 | ||||
-rw-r--r-- | usr/src/lib/print/libipp-core/common/strings.c | 411 | ||||
-rw-r--r-- | usr/src/lib/print/libipp-core/common/write.c | 415 | ||||
-rw-r--r-- | usr/src/lib/print/libipp-core/i386/Makefile | 30 | ||||
-rw-r--r-- | usr/src/lib/print/libipp-core/sparc/Makefile | 30 |
11 files changed, 2501 insertions, 0 deletions
diff --git a/usr/src/lib/print/libipp-core/Makefile b/usr/src/lib/print/libipp-core/Makefile new file mode 100644 index 0000000000..b92d620b10 --- /dev/null +++ b/usr/src/lib/print/libipp-core/Makefile @@ -0,0 +1,56 @@ +# +# 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. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../../Makefile.lib + +#HDRS = papi.h +#HDRDIR = common +SUBDIRS = $(MACH) +#$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber install: .WAIT $(SUBDIRS) + +lint: # $(SUBDIRS) + +install_h: # $(ROOTHDRS) + +check: # $(CHECKHDRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../../Makefile.targ diff --git a/usr/src/lib/print/libipp-core/Makefile.com b/usr/src/lib/print/libipp-core/Makefile.com new file mode 100644 index 0000000000..56099a4aa9 --- /dev/null +++ b/usr/src/lib/print/libipp-core/Makefile.com @@ -0,0 +1,58 @@ +# +# 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. +# +# ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY = libipp-core.a +VERS = .0 +OBJECTS = ipp.o ipp_types.o read.o strings.o write.o + +include ../../../Makefile.lib +include ../../../Makefile.rootfs + +ROOTLIBDIR= $(ROOT)/usr/lib + +LIBS = $(DYNLIB) + +SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c) + +$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) + +SRCDIR = ../common +MAPFILE = $(SRCDIR)/mapfile + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I$(SRCDIR) +CPPFLAGS += -I../../libpapi-common/common +DYNFLAGS += -M $(MAPFILE) +LDLIBS += -lpapi-common -lc + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include ../../../Makefile.targ diff --git a/usr/src/lib/print/libipp-core/common/ipp.c b/usr/src/lib/print/libipp-core/common/ipp.c new file mode 100644 index 0000000000..133fb0ad13 --- /dev/null +++ b/usr/src/lib/print/libipp-core/common/ipp.c @@ -0,0 +1,136 @@ +/* + * 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: ipp.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdarg.h> +#include <papi.h> +#include "ipp.h" + +/* + * IPP requests/responses are represented as attribute lists. An IPP request + * attribute list will contain header information attributes: + * version-major (int) + * version-minor (int) + * request-id (int) + * operation-id (int) + * It will also contain 1 or more attribute groups (collections) + * operational-attribute-group + * ... + * this routine validates that the request falls within the guidelines of + * the protocol specification (or some other level of conformance if the + * restrictions have been specified at the top level of the request using + * a "conformance" attribute. + */ +papi_status_t +ipp_validate_request(papi_attribute_t **request, papi_attribute_t ***response) +{ + papi_attribute_t **attributes = NULL; + papi_status_t result = PAPI_OK; + char *s; + + if ((request == NULL) || (response == NULL) || (*response == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* validate the operational attributes group */ + result = papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &attributes); + if (result != PAPI_OK) { + ipp_set_status(response, result, + "operational attribute group: %s", + papiStatusString(result)); + return (result); + } + + result = papiAttributeListGetString(attributes, NULL, + "attributes-charset", &s); + if (result != PAPI_OK) { + ipp_set_status(response, result, "attributes-charset: %s", + papiStatusString(result)); + return (result); + } + + result = papiAttributeListGetString(attributes, NULL, + "attributes-natural-language", &s); + if (result != PAPI_OK) { + ipp_set_status(response, result, + "attributes-natural-language: %s", + papiStatusString(result)); + return (result); + } + + return (result); +} + +/* + * Add/Modify the statuse-code and status-message in an IPP response's + * operational attributes group. + */ +void +ipp_set_status(papi_attribute_t ***message, papi_status_t status, + char *format, ...) +{ + if (message == NULL) + return; + + if (format != NULL) { + papi_attribute_t **operational = NULL; + papi_attribute_t **saved; + char mesg[256]; /* status-message is type text(255) */ + va_list ap; + + (void) papiAttributeListGetCollection(*message, NULL, + "operational-attributes-group", + &operational); + saved = operational; + + va_start(ap, format); + (void) vsnprintf(mesg, sizeof (mesg), format, ap); + va_end(ap); + + (void) papiAttributeListAddString(&operational, + PAPI_ATTR_APPEND, "status-message", mesg); + + /* + * We need to check and see if adding the status-message caused + * the operational attributes group to be relocated in memory. + * If it has been, we will need to re-add the collection to + * the message. + */ + if (saved != operational) + (void) papiAttributeListAddCollection(message, + PAPI_ATTR_REPLACE, + "operational-attributes-group", + operational); + } + + (void) papiAttributeListAddInteger(message, PAPI_ATTR_APPEND, + "status-code", status); +} diff --git a/usr/src/lib/print/libipp-core/common/ipp.h b/usr/src/lib/print/libipp-core/common/ipp.h new file mode 100644 index 0000000000..c13728e334 --- /dev/null +++ b/usr/src/lib/print/libipp-core/common/ipp.h @@ -0,0 +1,348 @@ +/* + * 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. + * + */ + +#ifndef _IPP_H +#define _IPP_H + +/* $Id: ipp.h 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdarg.h> +#include <sys/time.h> +#include <papi.h> +#include <inttypes.h> + + +typedef ssize_t (*ipp_reader_t)(void *fd, void *buffer, size_t buffer_size); +typedef ssize_t (*ipp_writer_t)(void *fd, void *buffer, size_t buffer_size); + +enum { + IPP_TYPE_UNKNOWN = 0, + IPP_TYPE_REQUEST = 1, + IPP_TYPE_RESPONSE = 2 +}; + +/* + * How closely do we conform to the spec when parsing? Do we + * a) Stop parsing only when we encounter an error that prevents us from + * continuing parsing (a server error or ridiculously malformed request)? + * b) Stop parsing when we know the server wouldn't be able to act on the + * response correctly, even if we can make sense of some of the data? + * c) Jawohl, Mein IPP Spec! + * The answer will usually be b, though a will be useful for debugging. + */ +enum { + IPP_PARSE_CONFORMANCE_RASH = 0, + IPP_PARSE_CONFORMANCE_LOOSE = 1, + IPP_PARSE_CONFORMANCE_STRICT = 2 +}; + + +/* Operation IDs */ +enum { + OPID_MIN = 0x0000, /* 0x0000 */ + OPID_RESERVED_0000 = 0x0000, /* 0x0000 */ + OPID_RESERVED_0001, /* 0x0001 */ + OPID_PRINT_JOB, /* 0x0002 */ + OPID_PRINT_URI, /* 0x0003 */ + OPID_VALIDATE_JOB, /* 0x0004 */ + OPID_CREATE_JOB, /* 0x0005 */ + OPID_SEND_DOCUMENT, /* 0x0006 */ + OPID_SEND_URI, /* 0x0007 */ + OPID_CANCEL_JOB, /* 0x0008 */ + OPID_GET_JOB_ATTRIBUTES, /* 0x0009 */ + OPID_GET_JOBS, /* 0x000a */ + OPID_GET_PRINTER_ATTRIBUTES, /* 0x000b */ + OPID_HOLD_JOB, /* 0x000c */ + OPID_RELEASE_JOB, /* 0x000d */ + OPID_RESTART_JOB, /* 0x000e */ + OPID_RESERVED_000F, /* 0x000f */ + OPID_PAUSE_PRINTER, /* 0x0010 */ + OPID_RESUME_PRINTER, /* 0x0011 */ + OPID_PURGE_JOBS, /* 0x0012 */ + OPID_SET_PRINTER_ATTRIBUTES, /* 0x0013 */ + OPID_SET_JOB_ATTRIBUTES, /* 0x0014 */ + OPID_GET_PRINTER_SUPPORTED_VALUES, /* 0x0015 */ + OPID_CREATE_PRINTER_SUBSCRIPTION, /* 0x0016 */ + OPID_CREATE_JOB_SUBSCRIPTION, /* 0x0017 */ + OPID_GET_SUBSCRIPTION_ATTRIBUTES, /* 0x0018 */ + OPID_GET_SUBSCRIPTIONS, /* 0x0019 */ + OPID_RENEW_SUBSCRIPTION, /* 0x001a */ + OPID_CANCEL_SUBSCRIPTION, /* 0x001b */ + OPID_GET_NOTIFICATIONS, /* 0x001c */ + OPID_SEND_NOTIFICATIONS, /* 0x001d */ + OPID_GET_RESOURCE_ATTRIBUTES, /* 0x001e */ + OPID_GET_RESOURCE_DATA, /* 0x001f */ + OPID_GET_RESOURCES, /* 0x0020 */ + OPID_GET_PRINT_SUPPORT_FILES, /* 0x0021 */ + OPID_ENABLE_PRINTER, /* 0x0022 */ + OPID_DISABLE_PRINTER, /* 0x0023 */ + OPID_PAUSE_PRINTER_AFTER_CURRENT_JOB, /* 0x0024 */ + OPID_HOLD_NEW_JOBS, /* 0x0025 */ + OPID_RELEASE_HELD_NEW_JOBS, /* 0x0026 */ + OPID_DEACTIVATE_PRINTER, /* 0x0027 */ + OPID_ACTIVATE_PRINTER, /* 0x0028 */ + OPID_RESTART_PRINTER, /* 0x0029 */ + OPID_SHUTDOWN_PRINTER, /* 0x002a */ + OPID_STARTUP_PRINTER, /* 0x002b */ + OPID_REPROCESS_JOB, /* 0x002c */ + OPID_CANCEL_CURRENT_JOB, /* 0x002d */ + OPID_SUSPEND_CURRENT_JOB, /* 0x002e */ + OPID_RESUME_JOB, /* 0x002f */ + OPID_PROMOTE_JOB, /* 0x0030 */ + OPID_SCHEDULE_JOB_AFTER, /* 0x0031 */ + OPID_RESERVED_MIN, /* 0x0032 */ + OPID_RESERVED_0032 = 0x0032, /* 0x0032 */ + /* ... */ + OPID_RESERVED_3FFF = 0x3fff, /* 0x3fff */ + OPID_RESERVED_MAX = 0x3fff, /* 0x3fff */ + OPID_RESERVED_VENDOR_MIN = 0x4000, /* 0x4000 */ + OPID_RESERVED_VENDOR_4000 = 0x4000, /* 0x4000 */ + /* ... */ + OPID_RESERVED_VENDOR_8FFF = 0x8fff, /* 0x8fff */ + OPID_RESERVED_VENDOR_MAX = 0x8fff, /* 0x8fff */ + OPID_MAX = 0x8fff /* 0x8fff */ +}; + +enum { + /* Delimiter Tags */ + DTAG_MIN = 0x00, /* 0x00 */ + DTAG_RESERVED_DELIMITER_00 = 0x00, /* 0x00 */ + DTAG_OPERATION_ATTRIBUTES, /* 0x01 */ + DTAG_JOB_ATTRIBUTES, /* 0x02 */ + DTAG_END_OF_ATTRIBUTES, /* 0x03 */ + DTAG_PRINTER_ATTRIBUTES, /* 0x04 */ + DTAG_UNSUPPORTED_ATTRIBUTES, /* 0x05 */ + DTAG_SUBSCRIPTION_ATTRIBUTES, /* 0x06 */ + DTAG_EVENT_NOTIFICATION_ATTRIBUTES, /* 0x07 */ + DTAG_RESERVED_DELIMITER_08, /* 0x08 */ + DTAG_RESERVED_DELIMITER_09, /* 0x09 */ + DTAG_RESERVED_DELIMITER_0A, /* 0x0a */ + DTAG_RESERVED_DELIMITER_0B, /* 0x0b */ + DTAG_RESERVED_DELIMITER_0C, /* 0x0c */ + DTAG_RESERVED_DELIMITER_0D, /* 0x0d */ + DTAG_RESERVED_DELIMITER_0E, /* 0x0e */ + DTAG_RESERVED_DELIMITER_0F, /* 0x0f */ + DTAG_MAX = 0x0f, /* 0x0f */ + + /* Value Tags */ + VTAG_MIN = 0x10, /* 0x10 */ + VTAG_UNSUPPORTED = 0x10, /* 0x10 */ + VTAG_RESERVED_DEFAULT, /* 0x11 */ + VTAG_UNKNOWN, /* 0x12 */ + VTAG_NOVALUE, /* 0x13 */ + VTAG_RESERVED_OOB_14, /* 0x14 */ + VTAG_NOT_SETTABLE, /* 0x15 */ + VTAG_DELETE_ATTRIBUTE, /* 0x16 */ + VTAG_ADMIN_DEFINE, /* 0x17 */ + VTAG_RESERVED_OOB_18, /* 0x18 */ + VTAG_RESERVED_OOB_19, /* 0x19 */ + VTAG_RESERVED_OOB_1A, /* 0x1a */ + VTAG_RESERVED_OOB_1B, /* 0x1b */ + VTAG_RESERVED_OOB_1C, /* 0x1c */ + VTAG_RESERVED_OOB_1D, /* 0x1d */ + VTAG_RESERVED_OOB_1E, /* 0x1e */ + VTAG_RESERVED_OOB_1F, /* 0x1f */ + VTAG_RESERVED_INT_GEN, /* 0x20 */ + VTAG_INTEGER, /* 0x21 */ + VTAG_BOOLEAN, /* 0x22 */ + VTAG_ENUM, /* 0x23 */ + VTAG_RESERVED_INT_24, /* 0x24 */ + VTAG_RESERVED_INT_25, /* 0x25 */ + VTAG_RESERVED_INT_26, /* 0x26 */ + VTAG_RESERVED_INT_27, /* 0x27 */ + VTAG_RESERVED_INT_28, /* 0x28 */ + VTAG_RESERVED_INT_29, /* 0x29 */ + VTAG_RESERVED_INT_2A, /* 0x2a */ + VTAG_RESERVED_INT_2B, /* 0x2b */ + VTAG_RESERVED_INT_2C, /* 0x2c */ + VTAG_RESERVED_INT_2D, /* 0x2d */ + VTAG_RESERVED_INT_2E, /* 0x2e */ + VTAG_RESERVED_INT_2F, /* 0x2f */ + VTAG_OCTET_STRING, /* 0x30 */ + VTAG_DATE_TIME, /* 0x31 */ + VTAG_RESOLUTION, /* 0x32 */ + VTAG_RANGE_OF_INTEGER, /* 0x33 */ + VTAG_BEGIN_COLLECTION, /* 0x34 */ + VTAG_TEXT_WITH_LANGUAGE, /* 0x35 */ + VTAG_NAME_WITH_LANGUAGE, /* 0x36 */ + VTAG_END_COLLECTION, /* 0x37 */ + VTAG_RESERVED_STRING_38, /* 0x38 */ + VTAG_RESERVED_STRING_39, /* 0x39 */ + VTAG_RESERVED_STRING_3A, /* 0x3a */ + VTAG_RESERVED_STRING_3B, /* 0x3b */ + VTAG_RESERVED_STRING_3C, /* 0x3c */ + VTAG_RESERVED_STRING_3D, /* 0x3d */ + VTAG_RESERVED_STRING_3E, /* 0x3e */ + VTAG_RESERVED_STRING_3F, /* 0x3f */ + VTAG_RESERVED_CHAR_GEN, /* 0x40 */ + VTAG_TEXT_WITHOUT_LANGUAGE, /* 0x41 */ + VTAG_NAME_WITHOUT_LANGUAGE, /* 0x42 */ + VTAG_RESERVED_43, /* 0x43 */ + VTAG_KEYWORD, /* 0x44 */ + VTAG_URI, /* 0x45 */ + VTAG_URI_SCHEME, /* 0x46 */ + VTAG_CHARSET, /* 0x47 */ + VTAG_NATURAL_LANGUAGE, /* 0x48 */ + VTAG_MIME_MEDIA_TYPE, /* 0x49 */ + VTAG_MEMBER_ATTR_NAME, /* 0x4a */ + VTAG_RESERVED_STRING_4B, /* 0x4b */ + VTAG_RESERVED_STRING_4C, /* 0x4c */ + VTAG_RESERVED_STRING_4D, /* 0x4d */ + VTAG_RESERVED_STRING_4E, /* 0x4e */ + VTAG_RESERVED_STRING_4F, /* 0x4f */ + VTAG_RESERVED_STRING_50, /* 0x50 */ + VTAG_RESERVED_STRING_51, /* 0x51 */ + VTAG_RESERVED_STRING_52, /* 0x52 */ + VTAG_RESERVED_STRING_53, /* 0x53 */ + VTAG_RESERVED_STRING_54, /* 0x54 */ + VTAG_RESERVED_STRING_55, /* 0x55 */ + VTAG_RESERVED_STRING_56, /* 0x56 */ + VTAG_RESERVED_STRING_57, /* 0x57 */ + VTAG_RESERVED_STRING_58, /* 0x58 */ + VTAG_RESERVED_STRING_59, /* 0x59 */ + VTAG_RESERVED_STRING_5A, /* 0x5a */ + VTAG_RESERVED_STRING_5B, /* 0x5b */ + VTAG_RESERVED_STRING_5C, /* 0x5c */ + VTAG_RESERVED_STRING_5D, /* 0x5d */ + VTAG_RESERVED_STRING_5E, /* 0x5e */ + VTAG_RESERVED_STRING_5F, /* 0x5f */ + VTAG_RESERVED_MAX = 0x5f, /* 0x5f */ + VTAG_MAX = 0x5f, /* 0x5f */ + VTAG_EXTEND = 0x7f /* 0x7f */ +}; + +/* Response codes */ +enum { + IPP_OK_MIN = 0x0000, + IPP_OK = 0x0000, /* 0x0000 */ + IPP_OK_IGNORED_ATTRIBUTES, /* 0x0001 */ + IPP_OK_CONFLICTING_ATTRIBUTES, /* 0x0002 */ + IPP_OK_IGNORED_SUBSCRIPTIONS, /* 0x0003 */ + IPP_OK_IGNORED_NOTIFICATIONS, /* 0x0004 */ + IPP_OK_TOO_MANY_EVENTS, /* 0x0005 */ + IPP_OK_BUT_CANCEL_SUBSCRIPTION, /* 0x0006 */ + IPP_OK_MAX = IPP_OK_BUT_CANCEL_SUBSCRIPTION, + + IPP_REDIR_MIN = 0x0300, + IPP_REDIR_OTHER_SIZE = 0x0300, /* 0x0300 */ + IPP_REDIR_MAX = 0x0300, + + IPP_CERR_MIN = 0x0400, + IPP_CERR_BAD_REQUEST = 0x0400, /* 0x0400 */ + IPP_CERR_FORBIDDEN, /* 0x0401 */ + IPP_CERR_NOT_AUTHENTICATED, /* 0x0402 */ + IPP_CERR_NOT_AUTHORIZED, /* 0x0403 */ + IPP_CERR_NOT_POSSIBLE, /* 0x0404 */ + IPP_CERR_TIMEOUT, /* 0x0405 */ + IPP_CERR_NOT_FOUND, /* 0x0406 */ + IPP_CERR_GONE, /* 0x0407 */ + IPP_CERR_REQUEST_ENTITY, /* 0x0408 */ + IPP_CERR_REQUEST_VALUE, /* 0x0409 */ + IPP_CERR_DOCUMENT_FORMAT, /* 0x040a */ + IPP_CERR_ATTRIBUTES, /* 0x040b */ + IPP_CERR_URI_SCHEME, /* 0x040c */ + IPP_CERR_CHARSET, /* 0x040d */ + IPP_CERR_CONFLICT, /* 0x040e */ + IPP_CERR_COMPRESSION_NOT_SUPPORTED, /* 0x040f */ + IPP_CERR_COMPRESSION_ERROR, /* 0x0410 */ + IPP_CERR_DOCUMENT_FORMAT_ERROR, /* 0x0411 */ + IPP_CERR_DOCUMENT_ACCESS_ERROR, /* 0x0412 */ + IPP_CERR_ATTRIBUTES_NOT_SETTABLE, /* 0x0413 */ + IPP_CERR_IGNORED_ALL_SUBSCRIPTIONS, /* 0x0414 */ + IPP_CERR_TOO_MANY_SUBSCRIPTIONS, /* 0x0415 */ + IPP_CERR_IGNORED_ALL_NOTIFICATIONS, /* 0x0416 */ + IPP_CERR_PRINT_SUPPORT_FILE_NOT_FOUND, /* 0x0417 */ + IPP_CERR_MAX = IPP_CERR_PRINT_SUPPORT_FILE_NOT_FOUND, + + IPP_SERR_MIN = 0x0500, + IPP_SERR_INTERNAL = 0x0500, /* 0x0500 */ + IPP_SERR_OPERATION_NOT_SUPPORTED, /* 0x0501 */ + IPP_SERR_SERVICE_UNAVAILABLE, /* 0x0502 */ + IPP_SERR_VERSION_NOT_SUPPORTED, /* 0x0503 */ + IPP_SERR_DEVICE_ERROR, /* 0x0504 */ + IPP_SERR_TEMPORARY_ERROR, /* 0x0505 */ + IPP_SERR_NOT_ACCEPTING, /* 0x0506 */ + IPP_SERR_BUSY, /* 0x0507 */ + IPP_SERR_CANCELLED, /* 0x0508 */ + IPP_SERR_MULTIPLE_DOCS_NOT_SUPPORTED, /* 0x0509 */ + IPP_SERR_PRINTER_IS_DEACTIVATED, /* 0x050a */ + IPP_SERR_MAX = IPP_SERR_PRINTER_IS_DEACTIVATED +}; + +/* Job state codes */ +enum { + IPP_JOB_STATE_PENDING = 3, + IPP_JOB_STATE_PENDING_HELD = 4, + IPP_JOB_STATE_PROCESSING = 5, + IPP_JOB_STATE_PROCESSING_STOPPED = 6, + IPP_JOB_STATE_CANCELED = 7, + IPP_JOB_STATE_ABORTED = 8, + IPP_JOB_STATE_COMPLETED = 9 +}; + +/* exported functions */ +extern papi_status_t ipp_read_message(ipp_reader_t iread, void *fd, + papi_attribute_t ***message, char type); + +extern papi_status_t ipp_write_message(ipp_writer_t iwrite, void *fd, + papi_attribute_t **message); + +/* internal functions shared between modules */ +extern void ipp_set_status(papi_attribute_t ***message, papi_status_t status, + char *format, ...); +extern papi_status_t ipp_validate_request(papi_attribute_t **request, + papi_attribute_t ***response); + +extern int ipp_severity(int16_t status); + +extern int16_t ipp_charset_supported(char *charset); + +extern void *string_to_ipp_attr_value(int8_t type, char *value); + +extern char *ipp_uri_to_printer(char *uri); +extern void *papi_attribute_to_ipp_attr(int8_t type, papi_attribute_t *attr); + +extern int8_t name_to_ipp_type(char *name); +extern char *job_template[]; +extern char *job_description[]; +extern char *printer_description[]; +extern char *ipp_tag_string(int8_t tag, char *buf, size_t bufsiz); +extern size_t min_val_len(int8_t type, char *name); +extern size_t max_val_len(int8_t type, char *name); +extern int is_keyword(char *value); + +#ifdef __cplusplus +} +#endif + +#endif /* _IPP_H */ diff --git a/usr/src/lib/print/libipp-core/common/ipp_types.c b/usr/src/lib/print/libipp-core/common/ipp_types.c new file mode 100644 index 0000000000..47fc32c259 --- /dev/null +++ b/usr/src/lib/print/libipp-core/common/ipp_types.c @@ -0,0 +1,303 @@ +/* + * 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: ipp_types.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <ipp.h> +#include <errno.h> +#include <values.h> + +#ifndef MININT +#define MININT (-MAXINT - 1) +#endif + +typedef struct { + char *name; + int8_t ipp_type; + int min; + int max; +} attr_info_list_t; + +static attr_info_list_t attr_list[] = { + {"operation-attribute-group", DTAG_OPERATION_ATTRIBUTES, 0, 0}, + {"job-attribute-group", DTAG_JOB_ATTRIBUTES, 0, 0}, + {"printer-attribute-group", DTAG_PRINTER_ATTRIBUTES, 0, 0}, + {"unsupported-attribute-group", DTAG_UNSUPPORTED_ATTRIBUTES, 0, 0}, + {"subscription-attribute-group", DTAG_SUBSCRIPTION_ATTRIBUTES, 0, 0}, + {"even-notificaton-attribute-group", + DTAG_EVENT_NOTIFICATION_ATTRIBUTES, 0, 0}, + {"attributes-charset", VTAG_CHARSET, 0, 255}, + {"attributes-natural-language", VTAG_NATURAL_LANGUAGE, 0, 255}, + {"charset-configured", VTAG_CHARSET, 0, 255}, + {"charset-supported", VTAG_CHARSET, 0, 255}, + {"color-supported", VTAG_BOOLEAN, 0, 1}, + {"compression", VTAG_KEYWORD, 1, 255}, + {"compression-supported", VTAG_KEYWORD, 1, 255}, + {"copies", VTAG_INTEGER, 1, MAXINT}, + {"copies-default", VTAG_INTEGER, 1, MAXINT}, + {"copies-supported", VTAG_RANGE_OF_INTEGER, 1, MAXINT}, + {"date-at-completed", VTAG_DATE_TIME, 0, 0}, + {"date-at-creation", VTAG_DATE_TIME, 0, 0}, + {"date-at-processing", VTAG_DATE_TIME, 0, 0}, + {"detailed-status-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, + {"document-access-error", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, + {"document-format", VTAG_MIME_MEDIA_TYPE, 0, 255}, + {"document-format-default", VTAG_MIME_MEDIA_TYPE, 0, 255}, + {"document-format-supported", VTAG_MIME_MEDIA_TYPE, 0, 255}, + {"document-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"document-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"document-natural-language", VTAG_NATURAL_LANGUAGE, 0, 255}, + {"finishing", VTAG_ENUM, 3, 31}, + {"finishing-default", VTAG_ENUM, 3, 31}, + {"finishing-supported", VTAG_ENUM, 3, 31}, + {"generated-natural-language-supported", VTAG_NATURAL_LANGUAGE, 0, 255}, + {"ipp-attribute-fidelity", VTAG_BOOLEAN, 0, 1}, + {"ipp-versions-supported", VTAG_KEYWORD, 1, 255}, + {"job-detailed-status-messages", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, + {"job-document-access-errors", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, + {"job-hold-until", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-hold-until-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-hold-until-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-id", VTAG_INTEGER, 1, MAXINT}, + {"job-impressions", VTAG_INTEGER, 0, MAXINT}, + {"job-impressions-completed", VTAG_INTEGER, 0, MAXINT}, + {"job-impressions-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT}, + {"job-k-octets", VTAG_INTEGER, 0, MAXINT}, + {"job-k-octets-processed", VTAG_INTEGER, 0, MAXINT}, + {"job-k-octets-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT}, + {"job-media-sheets", VTAG_INTEGER, 0, MAXINT}, + {"job-media-sheets-completed", VTAG_INTEGER, 0, MAXINT}, + {"job-media-sheets-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT}, + {"job-message-from-operator", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, + {"job-more-info", VTAG_URI, 0, 1023}, + {"job-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-originating-user-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-printer-up-time", VTAG_INTEGER, 1, MAXINT}, + {"job-printer-uri", VTAG_URI, 0, 1023}, + {"job-priority", VTAG_INTEGER, 1, 100}, + {"job-priority-default", VTAG_INTEGER, 1, 100}, + {"job-priority-supported", VTAG_INTEGER, 1, 100}, + {"job-sheets", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-sheets-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-sheets-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-state", VTAG_ENUM, 3, 9}, + {"job-state-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, + {"job-state-reasons", VTAG_KEYWORD, 1, 255}, + {"job-uri", VTAG_URI, 0, 1023}, + {"last-document", VTAG_BOOLEAN, 0, 1}, + {"limit", VTAG_INTEGER, 1, MAXINT}, + {"media", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"media-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"media-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, + {"multiple-document-handling", VTAG_KEYWORD, 1, 255}, + {"multiple-document-handling-default", VTAG_KEYWORD, 1, 255}, + {"multiple-document-handling-supported", VTAG_KEYWORD, 1, 255}, + {"multiple-document-jobs-supported", VTAG_BOOLEAN, 0, 1}, + {"multiple-operation-time-out", VTAG_INTEGER, 1, MAXINT}, + {"my-jobs", VTAG_BOOLEAN, 0, 1}, + {"natural-language-configured", VTAG_NATURAL_LANGUAGE, 0, 255}, + {"number-of-documents", VTAG_INTEGER, 0, MAXINT}, + {"number-of-intervening-jobs", VTAG_INTEGER, 0, MAXINT}, + {"number-up", VTAG_INTEGER, 1, MAXINT}, + {"number-up-default", VTAG_INTEGER, 1, MAXINT}, + {"number-up-supported", VTAG_INTEGER, 1, MAXINT}, + {"operations-supported", VTAG_ENUM, 1, 0x8FFF}, + {"orientation-requested", VTAG_ENUM, 3, 6}, + {"orientation-requested-default", VTAG_ENUM, 3, 6}, + {"orientation-requested-supported", VTAG_ENUM, 3, 6}, + {"output-device-assigned", VTAG_NAME_WITHOUT_LANGUAGE, 0, 127}, + {"page-ranges", VTAG_RANGE_OF_INTEGER, 1, MAXINT}, + {"page-ranges-supported", VTAG_BOOLEAN, 0, 1}, + {"pages-per-minute", VTAG_INTEGER, 0, MAXINT}, + {"pages-per-minute-color", VTAG_INTEGER, 0, MAXINT}, + {"pdl-override-supported", VTAG_KEYWORD, 1, 255}, + {"print-quality", VTAG_ENUM, 3, 5}, + {"print-quality-default", VTAG_ENUM, 3, 5}, + {"print-quality-supported", VTAG_ENUM, 3, 5}, + {"printer-current-time", VTAG_DATE_TIME, 0, 1}, + {"printer-driver-installer", VTAG_URI, 0, 1023}, + {"printer-id", VTAG_INTEGER, 1, MAXINT}, + {"printer-info", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, + {"printer-is-accepting-jobs", VTAG_BOOLEAN, 0, 1}, + {"printer-location", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, + {"printer-make-and-model", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, + {"printer-message-from-operator", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, + {"printer-more-info", VTAG_URI, 0, 1023}, + {"printer-more-info-manufacturer", VTAG_URI, 0, 1023}, + {"printer-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 127}, + {"printer-resolution", VTAG_RESOLUTION, 0, 0}, + {"printer-resolution-default", VTAG_RESOLUTION, 0, 0}, + {"printer-resolution-supported", VTAG_RESOLUTION, 0, 0}, + {"printer-state", VTAG_ENUM, 3, 5}, + {"printer-state-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, + {"printer-state-reasons", VTAG_KEYWORD, 1, 255}, + {"printer-up-time", VTAG_INTEGER, 1, MAXINT}, + {"printer-uri", VTAG_URI, 0, 1023}, + {"printer-uri-supported", VTAG_URI, 0, 1023}, + {"queued-job-count", VTAG_INTEGER, 0, MAXINT}, + {"reference-uri-schemes-supported", VTAG_URI_SCHEME, 0, 63}, + {"requested-attributes", VTAG_KEYWORD, 1, 255}, + {"requesting-user-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"sides", VTAG_KEYWORD, 1, 255}, + {"sides-default", VTAG_KEYWORD, 1, 255}, + {"sides-supported", VTAG_KEYWORD, 1, 255}, + {"status-code", VTAG_ENUM, 1, 0x7FFF}, + {"status-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 255}, + {"time-at-completed", VTAG_INTEGER, MININT, MAXINT}, + {"time-at-creation", VTAG_INTEGER, MININT, MAXINT}, + {"time-at-processing", VTAG_INTEGER, MININT, MAXINT}, + {"uri-authentication-supported", VTAG_KEYWORD, 1, 255}, + {"uri-security-supported", VTAG_KEYWORD, 1, 255}, + {"which-jobs", VTAG_KEYWORD, 1, 255}, + {NULL, 0, 0, 0} +}; + + +static attr_info_list_t * +get_attr_info_by_name(char *name) +{ + if (name != NULL) { + int i; + + for (i = 0; attr_list[i].name != NULL; i++) + if (strcasecmp(attr_list[i].name, name) == 0) + return (&attr_list[i]); + } + + return (NULL); +} + +size_t +max_val_len(int8_t type, char *name) +{ + attr_info_list_t *t; + int result; + + switch (type) { + case VTAG_INTEGER: + case VTAG_RANGE_OF_INTEGER: + case VTAG_ENUM: + result = MAXINT; + break; + case VTAG_URI: + case VTAG_OCTET_STRING: + case VTAG_TEXT_WITHOUT_LANGUAGE: + result = 1023; + break; + case VTAG_NATURAL_LANGUAGE: + case VTAG_URI_SCHEME: + case VTAG_CHARSET: + result = 63; + break; + case VTAG_NAME_WITHOUT_LANGUAGE: + case VTAG_MIME_MEDIA_TYPE: + case VTAG_KEYWORD: + result = 255; + break; + default: + result = MAXINT; + } + +#define min(a, b) ((a < b) ? a : b) + if ((t = get_attr_info_by_name(name)) != NULL) + result = min(t->max, result); +#undef min + + return (result); +} + +size_t +min_val_len(int8_t type, char *name) +{ + attr_info_list_t *t; + int result; + + switch (type) { + case VTAG_INTEGER: + case VTAG_RANGE_OF_INTEGER: + result = MININT; + break; + case VTAG_ENUM: + result = 1; + break; + case VTAG_URI: + case VTAG_OCTET_STRING: + case VTAG_TEXT_WITHOUT_LANGUAGE: + case VTAG_MIME_MEDIA_TYPE: + case VTAG_NAME_WITHOUT_LANGUAGE: + case VTAG_URI_SCHEME: + case VTAG_CHARSET: + case VTAG_NATURAL_LANGUAGE: + result = 0; + break; + case VTAG_KEYWORD: + result = 1; + break; + default: + result = MININT; + } + +#define max(a, b) ((a > b) ? a : b) + if ((t = get_attr_info_by_name(name)) != NULL) + result = max(t->min, result); +#undef max + + return (result); +} + +int +is_keyword(char *k) +{ + /* [a-z][a-z0-9._-]* */ + if (*k < 'a' && *k > 'z') + return (0); + while (*(++k) != '\0') + if (*k < 'a' && *k > 'z' && *k < '0' && *k > '9' && + *k != '.' && *k != '_' && *k != '-') + return (0); + return (1); +} + +int8_t +name_to_ipp_type(char *name) +{ + int i; + + if (name != NULL) + for (i = 0; attr_list[i].name != NULL; i++) + if (strcasecmp(attr_list[i].name, name) == 0) + return (attr_list[i].ipp_type); + + return (0); +} diff --git a/usr/src/lib/print/libipp-core/common/mapfile b/usr/src/lib/print/libipp-core/common/mapfile new file mode 100644 index 0000000000..7911a40932 --- /dev/null +++ b/usr/src/lib/print/libipp-core/common/mapfile @@ -0,0 +1,48 @@ +# +# 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: mapfile 151 2006-04-25 16:55:34Z njacobs $ + +# ident "%Z%%M% %I% %E% SMI" +# + + +# +# Common interfaces that are most likely to be shared amongst the various +# PAPI implementations. +# + +SUNWprivate_1.0 { + global: + ipp_read_message ; + ipp_write_message ; + ipp_validate_request ; + ipp_set_status ; + + local: + * ; +} ; diff --git a/usr/src/lib/print/libipp-core/common/read.c b/usr/src/lib/print/libipp-core/common/read.c new file mode 100644 index 0000000000..8bfca1e15b --- /dev/null +++ b/usr/src/lib/print/libipp-core/common/read.c @@ -0,0 +1,666 @@ +/* + * 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: read.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <alloca.h> +#include <string.h> +#include <stdarg.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <inttypes.h> + +#include <papi.h> +#include <ipp.h> + + +#define _ipp_tag_string(id) ipp_tag_string((id), buf, sizeof (buf)) + +static papi_status_t +read_name_with_language(ipp_reader_t iread, void *fd, + papi_attribute_t ***message) +{ + char *string; + uint16_t size; + + /* read the language */ + if (iread(fd, &size, 2) != 2) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "read failed: lang len\n"); + return (PAPI_BAD_REQUEST); + } + size = (uint16_t)ntohs(size); + + if ((string = alloca(size + 1)) == NULL) { + ipp_set_status(message, PAPI_TEMPORARY_ERROR, + "Memory allocation failed"); + return (PAPI_TEMPORARY_ERROR); + } + if (iread(fd, string, size) != size) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "read failed: lang\n"); + return (PAPI_BAD_REQUEST); + } + + /* read the text */ + if (iread(fd, &size, 2) != 2) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "read failed: text len\n"); + return (PAPI_BAD_REQUEST); + } + size = (uint16_t)ntohs(size); + + if ((string = alloca(size + 1)) == NULL) { + ipp_set_status(message, PAPI_TEMPORARY_ERROR, + "Memory allocation failed"); + return (PAPI_TEMPORARY_ERROR); + } + if (iread(fd, string, size) != size) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "read failed: text\n"); + return (PAPI_BAD_REQUEST); + } + + return (PAPI_OK); +} + + +static struct { + int8_t ipp_type; + int8_t size; +} type_info[] = { + { VTAG_INTEGER, 4 }, + { VTAG_ENUM, 4 }, + { VTAG_BOOLEAN, 1 }, + { VTAG_RANGE_OF_INTEGER, 8 }, + { VTAG_RESOLUTION, 9 }, + { VTAG_DATE_TIME, 11 }, + { DTAG_MIN, 0 } +}; + +/* verify that the IPP type and size are compatible */ +static int +validate_length(int8_t type, int8_t size) +{ + int i; + + for (i = 0; type_info[i].ipp_type != DTAG_MIN; i++) + if (type_info[i].ipp_type == type) + return ((type_info[i].size == size) ? 0 : -1); + return (0); +} + +/* convert tyep IPP type to a type that is marginally compatible */ +static int8_t +base_type(int8_t i) +{ + switch (i) { + case VTAG_ENUM: + case VTAG_INTEGER: + return (VTAG_INTEGER); + case VTAG_URI: + case VTAG_OCTET_STRING: + case VTAG_TEXT_WITHOUT_LANGUAGE: + case VTAG_URI_SCHEME: + case VTAG_CHARSET: + case VTAG_NATURAL_LANGUAGE: + case VTAG_MIME_MEDIA_TYPE: + case VTAG_NAME_WITHOUT_LANGUAGE: + case VTAG_KEYWORD: + return (VTAG_TEXT_WITHOUT_LANGUAGE); + case VTAG_BOOLEAN: + case VTAG_RANGE_OF_INTEGER: + case VTAG_DATE_TIME: + case VTAG_RESOLUTION: + default: + return (i); + } +} + +/* verify that the IPP type is correct for the named attribute */ +static papi_status_t +validate_type(char *name, int8_t type) +{ + int8_t t = name_to_ipp_type(name); + + if (t == 0) /* The attribute is not defined in the RFC */ + return (PAPI_NOT_FOUND); + else if (t == type) /* The supplied type matched the RFC type */ + return (PAPI_OK); + else { /* The supplied type doesn't match the RFC */ + if (base_type(t) == base_type(type)) + return (PAPI_OK); + + return (PAPI_CONFLICT); + } +} + +/* verify that the IPP value is within specification for the named attribute */ +static int +validate_value(papi_attribute_t ***message, char *name, int8_t type, ...) +{ +#define within(a, b, c) ((b >= a) && (b <= c)) + va_list ap; + int rc = -1; + int min = min_val_len(type, name), + max = max_val_len(type, name); + char buf[64]; /* For _ipp_<...>_string() */ + + va_start(ap, type); + switch (type) { + case VTAG_ENUM: + case VTAG_INTEGER: { + int32_t i = (int32_t)va_arg(ap, int32_t); + + if (within(min, i, max)) + rc = 0; + else + ipp_set_status(message, PAPI_BAD_ARGUMENT, + "%s(%s): %d: out of range (%d - %d)", name, + _ipp_tag_string(type), i, min, max); + } + break; + case VTAG_BOOLEAN: { + int8_t v = (int8_t)va_arg(ap, int); + + if (within(0, v, 1)) + rc = 0; + else + ipp_set_status(message, PAPI_BAD_ARGUMENT, + "%s(%s): %d: out of range (0 - 1)", name, + _ipp_tag_string(type), v); + } + break; + case VTAG_RANGE_OF_INTEGER: { + int32_t lower = (int32_t)va_arg(ap, int32_t); + int32_t upper = (int32_t)va_arg(ap, int32_t); + + if (within(min, lower, max) && + within(min, upper, max)) + rc = 0; + else + ipp_set_status(message, PAPI_BAD_ARGUMENT, + "%s(%s): %d - %d: out of range (%d - %d)", name, + _ipp_tag_string(type), lower, upper, min, max); + } + break; + case VTAG_URI: + case VTAG_OCTET_STRING: + case VTAG_TEXT_WITHOUT_LANGUAGE: + case VTAG_URI_SCHEME: + case VTAG_CHARSET: + case VTAG_NATURAL_LANGUAGE: + case VTAG_MIME_MEDIA_TYPE: + case VTAG_NAME_WITHOUT_LANGUAGE: { + char *v = (char *)va_arg(ap, char *); + + if (strlen(v) < max) + rc = 0; + else + ipp_set_status(message, PAPI_BAD_ARGUMENT, + "%s(%s): %s: too long (max length: %d)", name, + _ipp_tag_string(type), v, max); + } + break; + case VTAG_KEYWORD: { + char *v = (char *)va_arg(ap, char *); + + if (strlen(v) >= max) + ipp_set_status(message, PAPI_BAD_ARGUMENT, + "%s(%s): %s: too long (max length: %d)", name, + _ipp_tag_string(type), v, max); + else if (is_keyword(v) == 0) + ipp_set_status(message, PAPI_BAD_ARGUMENT, + "%s(%s): %s: invalid keyword", name, + _ipp_tag_string(type), v); + else + rc = 0; + } + break; + case VTAG_DATE_TIME: + case VTAG_RESOLUTION: + default: + rc = 0; + } + va_end(ap); + + return (rc); +#undef within +} + +/* + * read_attr_group() reads in enough of the message data to parse an entire + * attribute group. Since to determine that the group is finished you have to + * read the character that determines the type of the next group, this function + * must return that character, in order that our caller knows how to call us for + * the next group. Thus type is used both as an input parameter (the type of + * attribute group to read in) and an output parameter (the type of the next + * attribute group). + */ + +static papi_status_t +ipp_read_attribute_group(ipp_reader_t iread, void *fd, int8_t *type, + papi_attribute_t ***message) +{ + int8_t value_tag; + uint16_t name_length, value_length; + papi_attribute_t **attributes = NULL; + char *name = NULL; + int i; + char buf[64]; /* For _ipp_<...>_string() */ + + /* + * RFC2910 3.3 says we need to handle `An expected but missing + * "begin-attribute-group-tag" field. How? + */ + if (*type > DTAG_MAX) { + /* Scream bloody murder, or assign a new type? */ + ipp_set_status(message, PAPI_BAD_REQUEST, + "Bad attribute group tag 0x%.2hx (%s)", + *type, _ipp_tag_string(*type)); + return (PAPI_BAD_REQUEST); + } + + /* This loops through *values* not *attributes*! */ + for (i = 0; ; i++) { + papi_status_t valid = PAPI_OK; + if (iread(fd, &value_tag, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: value tag\n"); + return (PAPI_BAD_REQUEST); + } + /* are we done with this group ? */ + if (value_tag <= DTAG_MAX) + break; + + if (iread(fd, &name_length, 2) != 2) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: name length\n"); + return (PAPI_BAD_REQUEST); + } + name_length = (uint16_t)ntohs(name_length); + + /* Not just another value for the previous attribute */ + if (name_length != 0) { + if ((name = alloca(name_length + 1)) == NULL) { + ipp_set_status(message, PAPI_TEMPORARY_ERROR, + "alloca(): failed\n"); + return (PAPI_TEMPORARY_ERROR); + } + (void) memset(name, 0, name_length + 1); + + if (iread(fd, name, name_length) != name_length) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: name\n"); + return (PAPI_BAD_REQUEST); + } + } + + valid = validate_type(name, value_tag); + if ((valid != PAPI_OK) && (valid != PAPI_NOT_FOUND)) + ipp_set_status(message, valid, "%s(%s): %s", name, + _ipp_tag_string(value_tag), + papiStatusString(valid)); + + if (iread(fd, &value_length, 2) != 2) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: value length\n"); + return (PAPI_BAD_REQUEST); + } + value_length = (uint16_t)ntohs(value_length); + + if (validate_length(value_tag, value_length) < 0) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "Bad value length (%d) for type %s", + value_length, _ipp_tag_string(value_tag)); + return (PAPI_BAD_REQUEST); + } + + switch (value_tag) { + case VTAG_INTEGER: + case VTAG_ENUM: { + int32_t v; + + if (iread(fd, &v, value_length) != value_length) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: int/enum\n"); + return (PAPI_BAD_REQUEST); + } + v = (int32_t)ntohl(v); + (void) validate_value(message, name, value_tag, v); + papiAttributeListAddInteger(&attributes, + PAPI_ATTR_APPEND, name, v); + + } + break; + case VTAG_BOOLEAN: { + int8_t v; + + if (iread(fd, &v, value_length) != value_length) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: boolean\n"); + return (PAPI_BAD_REQUEST); + } + (void) validate_value(message, name, value_tag, v); + papiAttributeListAddBoolean(&attributes, + PAPI_ATTR_APPEND, name, v); + } + break; + case VTAG_RANGE_OF_INTEGER: { + int32_t min, max; + + if (iread(fd, &min, 4) != 4) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: min\n"); + return (PAPI_BAD_REQUEST); + } + if (iread(fd, &max, 4) != 4) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: max\n"); + return (PAPI_BAD_REQUEST); + } + min = (int32_t)ntohl(min); + max = (int32_t)ntohl(max); + (void) validate_value(message, name, value_tag, + min, max); + papiAttributeListAddRange(&attributes, PAPI_ATTR_APPEND, + name, min, max); + } + break; + case VTAG_RESOLUTION: { + int32_t x, y; + int8_t units; + + if (iread(fd, &x, 4) != 4) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: x\n"); + return (PAPI_BAD_REQUEST); + } + if (iread(fd, &y, 4) != 4) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: y\n"); + return (PAPI_BAD_REQUEST); + } + if (iread(fd, &units, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: units\n"); + return (PAPI_BAD_REQUEST); + } + x = (int32_t)ntohl(x); + y = (int32_t)ntohl(y); + papiAttributeListAddResolution(&attributes, + PAPI_ATTR_APPEND, name, x, y, + (papi_resolution_unit_t)units); + } + break; + case VTAG_DATE_TIME: { + struct tm tm; + time_t v; + int8_t c; + uint16_t s; + + (void) memset(&tm, 0, sizeof (tm)); + if (iread(fd, &s, 2) != 2) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: year\n"); + return (PAPI_BAD_REQUEST); + } + tm.tm_year = (uint16_t)ntohs(s) - 1900; + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: month\n"); + return (PAPI_BAD_REQUEST); + } + tm.tm_mon = c - 1; + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: day\n"); + return (PAPI_BAD_REQUEST); + } + tm.tm_mday = c; + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: hour\n"); + return (PAPI_BAD_REQUEST); + } + tm.tm_hour = c; + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: minutes\n"); + return (PAPI_BAD_REQUEST); + } + tm.tm_min = c; + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: seconds\n"); + return (PAPI_BAD_REQUEST); + } + tm.tm_sec = c; + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: decisec\n"); + return (PAPI_BAD_REQUEST); + } + /* tm.deciseconds = c; */ + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: utc_dir\n"); + return (PAPI_BAD_REQUEST); + } + /* tm.utc_dir = c; */ + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: utc_hour\n"); + return (PAPI_BAD_REQUEST); + } + /* tm.utc_hours = c; */ + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: utc_min\n"); + return (PAPI_BAD_REQUEST); + } + /* tm.utc_minutes = c; */ + + v = mktime(&tm); + + (void) validate_value(message, name, value_tag, v); + papiAttributeListAddDatetime(&attributes, + PAPI_ATTR_APPEND, name, v); + } + break; + case VTAG_NAME_WITH_LANGUAGE: + case VTAG_TEXT_WITH_LANGUAGE: + /* + * we are dropping this because we don't support + * name with language at this time. + */ + (void) read_name_with_language(iread, fd, message); + break; + case VTAG_NAME_WITHOUT_LANGUAGE: + case VTAG_TEXT_WITHOUT_LANGUAGE: + case VTAG_URI: + case VTAG_KEYWORD: + case VTAG_CHARSET: { + char *v; + + if ((v = calloc(1, value_length + 1)) == NULL) { + ipp_set_status(message, PAPI_TEMPORARY_ERROR, + "calloc(): failed\n"); + return (PAPI_TEMPORARY_ERROR); + } +#ifdef NOTDEF + if (iread(fd, v, value_length) != value_length) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: stringy\n"); + return (PAPI_BAD_REQUEST); + } +#else + { + int rc, i = value_length; + char *p = v; + + while ((rc = iread(fd, p, i)) != i) { + if (rc <= 0) { + ipp_set_status(message, + PAPI_BAD_REQUEST, + "bad read: stringy\n"); + return (PAPI_BAD_REQUEST); + } + i -= rc; + p += rc; + } + } +#endif + (void) validate_value(message, name, value_tag, v); + papiAttributeListAddString(&attributes, + PAPI_ATTR_APPEND, name, v); + } + break; + case VTAG_UNKNOWN: + case VTAG_NOVALUE: + case VTAG_UNSUPPORTED: + papiAttributeListAddValue(&attributes, PAPI_ATTR_EXCL, + name, PAPI_COLLECTION, NULL); + break; + default: { + char *v; + + if ((v = calloc(1, value_length + 1)) == NULL) { + ipp_set_status(message, PAPI_TEMPORARY_ERROR, + "calloc(): failed\n"); + return (PAPI_TEMPORARY_ERROR); + } + if (iread(fd, v, value_length) != value_length) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: other\n"); + return (PAPI_BAD_REQUEST); + } + papiAttributeListAddString(&attributes, + PAPI_ATTR_APPEND, name, v); + } + break; + } + } + + if (attributes != NULL) { + char name[32]; + + (void) ipp_tag_string(*type, name, sizeof (name)); + papiAttributeListAddCollection(message, PAPI_ATTR_APPEND, name, + attributes); + } + + *type = value_tag; + + return (PAPI_OK); +} + + +static papi_status_t +ipp_read_header(ipp_reader_t iread, void *fd, papi_attribute_t ***message, + char type) +{ + char *attr_name = "status-code"; /* default to a response */ + char buf[8]; + int8_t c; + uint16_t s; + int32_t i; + + if ((iread == NULL) || (fd == NULL) || (message == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* + * Apache 1.X uses the buffer supplied to it's read call to read in + * the chunk size when chunking is used. This causes problems + * reading the header a piece at a time, because we don't have + * enough room to read in the chunk size prior to reading the + * chunk. + */ + + if (iread(fd, buf, 8) != 8) + return (PAPI_BAD_REQUEST); + + c = buf[0]; + (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE, + "version-major", c); + + c = buf[1]; + (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE, + "version-minor", c); + + memcpy(&s, &buf[2], 2); + s = (uint16_t)ntohs(s); + if (type == IPP_TYPE_REQUEST) + attr_name = "operation-id"; + (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE, + attr_name, s); + + memcpy(&s, &buf[4], 4); + i = (uint32_t)ntohl(i); + (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE, + "request-id", i); + + return (PAPI_OK); +} + +static papi_status_t +ipp_read_attribute_groups(ipp_reader_t iread, void *fd, + papi_attribute_t ***message) +{ + papi_status_t result = PAPI_OK; + int8_t tag; + + /* start reading the attribute groups */ + if (iread(fd, &tag, 1) != 1) /* prime the pump */ + return (PAPI_BAD_REQUEST); + + while ((tag != DTAG_END_OF_ATTRIBUTES) && (result == PAPI_OK)) { + result = ipp_read_attribute_group(iread, fd, &tag, message); + } + + return (result); +} + +papi_status_t +ipp_read_message(ipp_reader_t iread, void *fd, papi_attribute_t ***message, + char type) +{ + papi_status_t result = PAPI_OK; + + if ((iread == NULL) || (fd == NULL) || (message == NULL)) + return (PAPI_BAD_ARGUMENT); + + result = ipp_read_header(iread, fd, message, type); + if (result == PAPI_OK) + result = ipp_read_attribute_groups(iread, fd, message); + + return (result); +} diff --git a/usr/src/lib/print/libipp-core/common/strings.c b/usr/src/lib/print/libipp-core/common/strings.c new file mode 100644 index 0000000000..b47449b8cc --- /dev/null +++ b/usr/src/lib/print/libipp-core/common/strings.c @@ -0,0 +1,411 @@ +/* + * 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: strings.c 151 2006-04-25 16:55:34Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "ipp.h" + +static char *tag_strings[] = { + /* delimiter tags */ + "reserved-delimiter-00", + "operational-attributes-group", + "job-attributes-group", + "end-of-attributes-group", + "printer-attributes-group", + "unsupported-attributes-group", + "subscription-attributes-group", + "event-notification-attributes-group", + "reserved-delimiter-08", + "reserved-delimiter-09", + "reserved-delimiter-0a", + "reserved-delimiter-0b", + "reserved-delimiter-0c", + "reserved-delimiter-0d", + "reserved-delimiter-0e", + "reserved-delimiter-0f", + /* value tags */ + "unsupported", + "reserved-default", + "unknown", + "no-value", + "reserved-out-of-band-14", + "not-settable", + "delete-attribute", + "admin-define", + "reserved-out-of-band-18", + "reserved-out-of-band-19", + "reserved-out-of-band-1a", + "reserved-out-of-band-1b", + "reserved-out-of-band-1c", + "reserved-out-of-band-1d", + "reserved-out-of-band-1e", + "reserved-out-of-band-1f", + "reserved", + "integer", + "boolean", + "enum", + "reserved-integer-type-24", + "reserved-integer-type-25", + "reserved-integer-type-26", + "reserved-integer-type-27", + "reserved-integer-type-28", + "reserved-integer-type-29", + "reserved-integer-type-2a", + "reserved-integer-type-2b", + "reserved-integer-type-2c", + "reserved-integer-type-2d", + "reserved-integer-type-2e", + "reserved-integer-type-2f", + "octetString", + "dateTime", + "resolution", + "rangeOfInteger", + "begCollection", + "textWithLanguage", + "nameWithLanguage", + "endCollection", + "reserved-octetString-38", + "reserved-octetString-39", + "reserved-octetString-3a", + "reserved-octetString-3b", + "reserved-octetString-3c", + "reserved-octetString-3d", + "reserved-octetString-3e", + "reserved-octetString-3f", + "reserved", + "textWithoutLanguage", + "nameWithoutLanguage", + "reserved", + "keyword", + "uri", + "uriScheme", + "charset", + "naturalLanguage", + "mimeMediaType", + "memberAttrName", + "reserved-charString-4b", + "reserved-charString-4c", + "reserved-charString-4d", + "reserved-charString-4e", + "reserved-charString-4f", + "reserved-charString-50", + "reserved-charString-51", + "reserved-charString-52", + "reserved-charString-53", + "reserved-charString-54", + "reserved-charString-55", + "reserved-charString-56", + "reserved-charString-57", + "reserved-charString-58", + "reserved-charString-59", + "reserved-charString-5a", + "reserved-charString-5b", + "reserved-charString-5c", + "reserved-charString-5d", + "reserved-charString-5e", + "reserved-charString-5f", +}; + +static char *opid_strings[] = { + "reserved-0x0000", + "reserved-0x0001", + "Print-Job", + "Print-URI", + "Validate-Job", + "Create-Job", + "Send-Document", + "Send-URI", + "Cancel-Job", + "Get-Job-Attributes", + "Get-Jobs", + "Get-Printer-Attributes", + "Hold-Job", + "Release-Job", + "Restart-Job", + "reserved-0x000f", + "Pause-Printer", + "Resume-Printer", + "Purge-Jobs", + "Set-Printer-Attributes", + "Set-Job-Attributes", + "Get-Printer-Supported-Values", + "Create-Printer-Subscription", + "Create-Job-Subscription", + "Get-Subscription-Attributes", + "Get-Subscriptions", + "Renew-Subscription", + "Cancel-Subscription", + "Get-Notifications", + "Send-Notifications", + "Get-Resource-Attributes-deleted", + "Get-Resource-Data-deleted", + "Get-Resources-deleted", + "Get-Print-Support-Files", + "Disable-Printer", + "Pause-Printer-After-Current-Job", + "Hold-New-Jobs", + "Release-Held-New-Jobs", + "Deactivate-Printer", + "Activate-Printer", + "Restart-Printer", + "Shutdown-Printer", + "Startup-Printer", + "Reprocess-Job", + "Cancel-Current-Job", + "Suspend-Current-Job", + "Resume-Job", + "Promote-Job", + "Schedule-Job-After", + NULL +}; + +static char *res_opid_strings[] = { + "Microsoft-0x4000", + "CUPS-Get-Default", + "CUPS-Get-Printers", + "CUPS-Add-Printer", + "CUPS-Delete-Printer", + "CUPS-Get-Classes", + "CUPS-Add-Class", + "CUPS-Delete-Class", + "CUPS-Accept-Jobs", + "CUPS-Reject-Jobs", + "CUPS-Set-Default", + "CUPS-Get-Devices", + "CUPS-Get-PPDs", + "CUPS-Move-Job", + "CUPS-0x400e", + "CUPS-0x400f", + "Peerless-0x4010", + NULL +}; +#define KNOWN_RESERVED_MIN 0x4000 +#define KNOWN_RESERVED_MAX 0x4010 + +static char *ok_status_strings[] = { + "successful-ok", + "successful-ok-ignored-or-substituted-attributes", + "successful-ok-conflicting-attributes", + "successful-ok-ignored-subscriptions", + "successful-ok-ignored-notifications", + "successful-ok-too-many-events", + "successful-ok-but-cancel-subscription" +}; + +static char *redir_status_strings[] = { + "redirection-other-site" +}; + +static char *client_error_status_strings[] = { + "client-error-bad-request", + "client-error-forbidden", + "client-error-not-authenticated", + "client-error-not-authorized", + "client-error-not-possible", + "client-error-timeout", + "client-error-not-found", + "client-error-gone", + "client-error-request-entity-too-large", + "client-error-request-value-too-long", + "client-error-document-format-not-supported", + "client-error-attributes-or-values-not-supported", + "client-error-uri-scheme-not-supported", + "client-error-charset-not-supported", + "client-error-conflicting-attributes", + "client-error-compression-not-supported", + "client-error-compression-error", + "client-error-document-format-error", + "client-error-document-access-error", + "client-error-attributes-not-settable", + "client-error-ignored-all-subscriptions", + "client-error-too-many-subscriptions", + "client-error-ignored-all-notifications", + "client-error-print-support-file-not-found" +}; + +static char *server_error_status_strings[] = { + "server-error-internal-error", + "server-error-operation-not-supported", + "server-error-service-unavailable", + "server-error-version-not-supported", + "server-error-device-error", + "server-error-temporary-error", + "server-error-not-accepting-jobs", + "server-error-busy", + "server-error-job-canceled", + "server-error-multiple-document-jobs-not-supported", + "server-error-printer-is-deactivated" +}; + +char * +ipp_tag_string(int8_t id, char *ret, size_t len) +{ + if (id < VTAG_MAX) + (void) strlcpy(ret, tag_strings[id], len); + else if (id == VTAG_EXTEND) + (void) strlcpy(ret, "extension", len); + else + (void) snprintf(ret, len, "bogus-0x%.2x", id); + + return (ret); +} + +char * +ipp_opid_string(int16_t id, char *ret, size_t len) +{ + if (id < OPID_RESERVED_MIN) + (void) strlcpy(ret, opid_strings[id], len); + else if (id < OPID_RESERVED_VENDOR_MIN) + (void) snprintf(ret, len, "reserved-0x%.4x", id); + else if (id <= KNOWN_RESERVED_MAX) + (void) strlcpy(ret, + res_opid_strings[id - KNOWN_RESERVED_MIN], len); + else /* if (id <= OPID_RESERVED_VENDOR_MAX) */ + (void) snprintf(ret, len, "reserved-vendor-0x%.4x", id); + + return (ret); +} + +int16_t +ipp_string_opid(char *string) +{ + int i; + + for (i = 0; opid_strings[i] != NULL; i++) + if (strcasecmp(opid_strings[i], string) == 0) + return (i); + + for (i = 0; res_opid_strings[i] != NULL; i++) + if (strcasecmp(res_opid_strings[i], string) == 0) + return (0x4000 + i); + + return (-1); +} + +char * +ipp_status_string(int16_t id, char *ret, size_t len) +{ + if (id <= IPP_OK_MAX) + (void) strlcpy(ret, ok_status_strings[id], len); + else if (id >= IPP_REDIR_MIN && id <= IPP_REDIR_MAX) + (void) strlcpy(ret, + redir_status_strings[id - IPP_REDIR_MIN], len); + else if (id >= IPP_CERR_MIN && id <= IPP_CERR_MAX) + (void) strlcpy(ret, + client_error_status_strings[id - IPP_CERR_MIN], len); + else if (id >= IPP_SERR_MIN && id <= IPP_SERR_MAX) + (void) strlcpy(ret, + server_error_status_strings[id - IPP_SERR_MIN], len); + else + (void) snprintf(ret, len, "bogus-0x%.4hx", id); + + return (ret); +} + + + +/* + * attribute template handling routines + */ +char *job_template[] = { + "copies", + "finishing", + "job-hold-until", + "job-priority", + "job-sheets", + "media", + "multiple-document-handling", + "number-up", + "page-ranges-supported", + "print-quality", + "printer-resoultion", + "sides", + NULL +}; + +char *job_description[] = { + "copies-default", "copies-supported", + "finishing-default", "finishing-supported", + "job-hold-until-default", "job-hold-until-supported", + "job-priority-default", "job-priority-supported", + "job-sheets-default", "job-sheets-supported", + "media-default", "media-supported", + "multiple-document-handling-default", + "multiple-document-handling-supported", + "number-up-default", "number-up-supported", + "page-ranges-supported", + "print-quality-default", "print-quality-supported", + "printer-resoultion-default", "printer-resoultion-supported", + "sides-default", "sides-supported", + NULL +}; + +char *printer_description[] = { + "printer-uri-supported", + "uri-security-supported", + "uri-authentication-supported", + "printer-name", + "printer-location", + "printer-info", + "printer-more-info", + "printer-driver-installer", + "printer-make-and-model", + "printer-more-info-manufacturer", + "printer-state", + "printer-state-reasons", + "printer-state-message", + "ipp-versions-supported", + "multiple-document-jobs-supported", + "charset-configured", + "charset-supported", + "natural-language-configured", + "generated-natural-language-supported", + "document-format-default", + "document-format-supported", + "printer-is-accepting-jobs", + "queued-job-count", + "printer-message-from-operator", + "color-supported", + "reference-uri-schemes-supported", + "pdl-override-supported", + "printer-up-time", + "printer-current-time", + "multiple-operation-time-out", + "compression-supported", + "job-k-octets-supported", + "job-impressions-supported", + "job-media-sheets-supported", + "pages-per-minute", + "pages-per-minute-color", + NULL +}; diff --git a/usr/src/lib/print/libipp-core/common/write.c b/usr/src/lib/print/libipp-core/common/write.c new file mode 100644 index 0000000000..aef693a365 --- /dev/null +++ b/usr/src/lib/print/libipp-core/common/write.c @@ -0,0 +1,415 @@ +/* + * 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: write.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <inttypes.h> + +#include <papi.h> +#include <ipp.h> + +static int8_t +papi_attribute_to_ipp_type(papi_attribute_value_type_t type) +{ + switch (type) { + case PAPI_INTEGER: + return (VTAG_INTEGER); + case PAPI_BOOLEAN: + return (VTAG_BOOLEAN); + case PAPI_RANGE: + return (VTAG_RANGE_OF_INTEGER); + case PAPI_RESOLUTION: + return (VTAG_RESOLUTION); + case PAPI_DATETIME: + return (VTAG_DATE_TIME); + case PAPI_STRING: + return (VTAG_TEXT_WITHOUT_LANGUAGE); + } + + return (0); +} + +static papi_status_t +papi_ipp_type_match(papi_attribute_value_type_t papi, int8_t ipp) +{ + switch (papi) { + case PAPI_STRING: + switch (ipp) { + case VTAG_URI: + case VTAG_OCTET_STRING: + case VTAG_TEXT_WITHOUT_LANGUAGE: + case VTAG_URI_SCHEME: + case VTAG_CHARSET: + case VTAG_NATURAL_LANGUAGE: + case VTAG_MIME_MEDIA_TYPE: + case VTAG_NAME_WITHOUT_LANGUAGE: + case VTAG_KEYWORD: + break; + default: + return (PAPI_CONFLICT); + } + break; + case PAPI_INTEGER: + switch (ipp) { + case VTAG_ENUM: + case VTAG_INTEGER: + break; + default: + return (PAPI_CONFLICT); + } + break; + case PAPI_BOOLEAN: + if (ipp != VTAG_BOOLEAN) + return (PAPI_CONFLICT); + break; + case PAPI_RANGE: + if (ipp != VTAG_RANGE_OF_INTEGER) + return (PAPI_CONFLICT); + break; + case PAPI_RESOLUTION: + if (ipp != VTAG_RESOLUTION) + return (PAPI_CONFLICT); + break; + case PAPI_DATETIME: + if (ipp != VTAG_DATE_TIME) + return (PAPI_CONFLICT); + break; + case PAPI_COLLECTION: + /* don't need to match */ + break; + } + + return (PAPI_OK); +} + +static papi_status_t +ipp_write_attribute(ipp_writer_t iwrite, void *fd, papi_attribute_t *attribute) +{ + papi_status_t status; + papi_attribute_value_t **values; + int8_t type; + int i; + char *name; + + name = attribute->name; + values = attribute->values; + + if ((type = name_to_ipp_type(name)) == 0) + type = papi_attribute_to_ipp_type(attribute->type); + + /* The types don't match, so don't send the attribute */ + if ((status = papi_ipp_type_match(attribute->type, type)) != PAPI_OK) + return (status); + + if (values == NULL) { + uint16_t length; + + type = VTAG_UNSUPPORTED; + if (iwrite(fd, &type, 1) != 1) + return (PAPI_DEVICE_ERROR); + + if (name != NULL) { /* first value gets named */ + length = (uint16_t)htons(strlen(name)); + + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, name, strlen(name)) != strlen(name)) + return (PAPI_DEVICE_ERROR); + } + + length = (uint16_t)htons(0); + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + + return (PAPI_OK); + } + + + + for (i = 0; values[i] != NULL; i++) { + papi_attribute_value_t *value = values[i]; + uint16_t length = 0; + + if (iwrite(fd, &type, 1) != 1) + return (PAPI_DEVICE_ERROR); + + if (name != NULL) { /* first value gets named */ + length = (uint16_t)htons(strlen(name)); + + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, name, strlen(name)) != strlen(name)) + return (PAPI_DEVICE_ERROR); + name = NULL; + } else { + length = (uint16_t)htons(0); + + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + } + + switch (attribute->type) { + case PAPI_STRING: { + char *v = (char *)value->string; + + if (v != NULL) { + size_t str_length = strlen(v); + + /* + * if the length is more than 16 bits can + * express, send what can be represented + * in 16 bits. IPP "strings" can only be + * that large. + */ + if (str_length > 0xFFFF) + str_length = 0xFFFF; + + length = (uint16_t)htons(str_length); + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, v, str_length) != str_length) + return (PAPI_DEVICE_ERROR); + } else + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + } + break; + case PAPI_BOOLEAN: { + int8_t v = (int8_t)value->boolean; + + length = (uint16_t)htons(1); + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, &v, 1) != 1) + return (PAPI_DEVICE_ERROR); + } + break; + case PAPI_INTEGER: { + int32_t v = (int32_t)value->integer; + + length = (uint16_t)htons(4); + v = (int32_t)htonl(v); + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, &v, 4) != 4) + return (PAPI_DEVICE_ERROR); + } + break; + case PAPI_RANGE: { + int32_t min = (int32_t)htonl((int)(value->range).lower), + max = (int32_t)htonl((int)(value->range).upper); + + length = (uint16_t)htons(8); + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, &min, 4) != 4) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, &max, 4) != 4) + return (PAPI_DEVICE_ERROR); + } + break; + case PAPI_RESOLUTION: { + int32_t x = (int)(value->resolution).xres, + y = (int)(value->resolution).yres; + int8_t units = (int8_t)(value->resolution).units; + + length = (uint16_t)htons(9); + x = (int32_t)htonl(x); + y = (int32_t)htonl(y); + + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, &x, 4) != 4) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, &y, 4) != 4) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, &units, 1) != 1) + return (PAPI_DEVICE_ERROR); + } + break; + case PAPI_DATETIME: { + struct tm *v = gmtime(&value->datetime); + int8_t c; + uint16_t s; + + length = (uint16_t)htons(11); + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + s = (uint16_t)htons(v->tm_year + 1900); + if (iwrite(fd, &s, 2) != 2) + return (PAPI_DEVICE_ERROR); + c = v->tm_mon + 1; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = v->tm_mday; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = v->tm_hour; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = v->tm_min; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = v->tm_sec; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = /* v->deciseconds */ 0; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = /* v->utc_dir */ 0; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = /* v->utc_hours */ 0; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = /* v->utc_minutes */ 0; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + } + break; + default: { + /* + * If there is a value, it is not one of our + * types, so we couldn't use it anyway. We assume + * that it was an OOB type with no value + */ + length = (uint16_t)htons(0); + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + } + break; + } + } + + return (PAPI_OK); +} + +static papi_status_t +ipp_write_attribute_group(ipp_writer_t iwrite, void *fd, int8_t type, + papi_attribute_t **attributes) +{ + papi_status_t result = PAPI_OK; + int i; + + /* write group tag */ + if (iwrite(fd, &type, 1) != 1) + return (PAPI_DEVICE_ERROR); + + /* write values */ + for (i = 0; ((attributes[i] != NULL) && (result == PAPI_OK)); i++) + result = ipp_write_attribute(iwrite, fd, attributes[i]); + + return (result); +} + +static papi_status_t +ipp_write_attribute_groups(ipp_writer_t iwrite, void *fd, + papi_attribute_t **groups) +{ + papi_status_t result = PAPI_OK; + int8_t c; + + for (c = DTAG_MIN; c <= DTAG_MAX; c++) { + papi_status_t status; + papi_attribute_t **group = NULL; + void *iter = NULL; + char name[32]; + + (void) ipp_tag_string(c, name, sizeof (name)); + for (status = papiAttributeListGetCollection(groups, &iter, + name, &group); + ((status == PAPI_OK) && (result == PAPI_OK)); + status = papiAttributeListGetCollection(groups, &iter, + NULL, &group)) + result = ipp_write_attribute_group(iwrite, fd, + c, group); + } + + c = DTAG_END_OF_ATTRIBUTES; + if (iwrite(fd, &c, 1) != 1) + result = PAPI_DEVICE_ERROR; + + return (result); +} + +static papi_status_t +ipp_write_message_header(ipp_writer_t iwrite, void *fd, + papi_attribute_t **message) +{ + int tmp; + int8_t c; + uint16_t s; + int32_t i; + + /* write the version */ + papiAttributeListGetInteger(message, NULL, "version-major", &tmp); + c = tmp; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + + papiAttributeListGetInteger(message, NULL, "version-minor", &tmp); + c = tmp; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + + /* write the request/status code */ + papiAttributeListGetInteger(message, NULL, "status-code", &tmp); + papiAttributeListGetInteger(message, NULL, "operation-id", &tmp); + s = (uint16_t)htons(tmp); + if (iwrite(fd, &s, 2) != 2) + return (PAPI_DEVICE_ERROR); + + /* write the request id */ + papiAttributeListGetInteger(message, NULL, "request-id", &tmp); + i = (uint32_t)htonl(tmp); + if (iwrite(fd, &i, 4) != 4) + return (PAPI_DEVICE_ERROR); + + return (PAPI_OK); +} + +papi_status_t +ipp_write_message(ipp_writer_t iwrite, void *fd, papi_attribute_t **message) +{ + papi_status_t result; + + if ((iwrite == NULL) || (fd == NULL) || (message == NULL)) + return (PAPI_BAD_ARGUMENT); + + result = ipp_write_message_header(iwrite, fd, message); + if (result == PAPI_OK) + result = ipp_write_attribute_groups(iwrite, fd, message); + + return (result); +} diff --git a/usr/src/lib/print/libipp-core/i386/Makefile b/usr/src/lib/print/libipp-core/i386/Makefile new file mode 100644 index 0000000000..3b985583a4 --- /dev/null +++ b/usr/src/lib/print/libipp-core/i386/Makefile @@ -0,0 +1,30 @@ +# +# 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. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libipp-core/sparc/Makefile b/usr/src/lib/print/libipp-core/sparc/Makefile new file mode 100644 index 0000000000..3b985583a4 --- /dev/null +++ b/usr/src/lib/print/libipp-core/sparc/Makefile @@ -0,0 +1,30 @@ +# +# 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. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) |