/*
* 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
* 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 2007 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 <inttypes.h>
#include <papi.h>
#include <ipp.h>
static papi_status_t
{
char *string;
/* read the language */
"read failed: lang len\n");
return (PAPI_BAD_REQUEST);
}
"Memory allocation failed");
return (PAPI_TEMPORARY_ERROR);
}
"read failed: lang\n");
return (PAPI_BAD_REQUEST);
}
/* read the text */
"read failed: text len\n");
return (PAPI_BAD_REQUEST);
}
"Memory allocation failed");
return (PAPI_TEMPORARY_ERROR);
}
"read failed: text\n");
return (PAPI_BAD_REQUEST);
}
return (PAPI_OK);
}
static struct {
} 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
{
int i;
return (0);
}
/* convert tyep IPP type to a type that is marginally compatible */
static int8_t
{
switch (i) {
case VTAG_ENUM:
case VTAG_INTEGER:
return (VTAG_INTEGER);
case VTAG_URI:
case VTAG_OCTET_STRING:
case VTAG_URI_SCHEME:
case VTAG_CHARSET:
case VTAG_NATURAL_LANGUAGE:
case VTAG_MIME_MEDIA_TYPE:
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
{
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 */
return (PAPI_OK);
return (PAPI_CONFLICT);
}
}
/* verify that the IPP value is within specification for the named attribute */
static int
{
#define within(a, b, c) ((b >= a) && (b <= c))
switch (type) {
case VTAG_ENUM:
case VTAG_INTEGER: {
rc = 0;
else
"%s(%s): %d: out of range (%d - %d)", name,
}
break;
case VTAG_BOOLEAN: {
if (within(0, v, 1))
rc = 0;
else
"%s(%s): %d: out of range (0 - 1)", name,
_ipp_tag_string(type), v);
}
break;
case VTAG_RANGE_OF_INTEGER: {
rc = 0;
else
"%s(%s): %d - %d: out of range (%d - %d)", name,
}
break;
case VTAG_URI:
case VTAG_OCTET_STRING:
case VTAG_URI_SCHEME:
case VTAG_CHARSET:
case VTAG_NATURAL_LANGUAGE:
case VTAG_MIME_MEDIA_TYPE:
case VTAG_NAME_WITHOUT_LANGUAGE: {
rc = 0;
else
"%s(%s): %s: too long (max length: %d)", name,
}
break;
case VTAG_KEYWORD: {
"%s(%s): %s: too long (max length: %d)", name,
else if (is_keyword(v) == 0)
"%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;
}
return (rc);
}
/*
* 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
{
int i;
/*
* RFC2910 3.3 says we need to handle `An expected but missing
* "begin-attribute-group-tag" field. How?
*/
/* Scream bloody murder, or assign a new type? */
"Bad attribute group tag 0x%.2hx (%s)",
return (PAPI_BAD_REQUEST);
}
/* This loops through *values* not *attributes*! */
for (i = 0; ; i++) {
"bad read: value tag\n");
return (PAPI_BAD_REQUEST);
}
/* are we done with this group ? */
break;
"bad read: name length\n");
return (PAPI_BAD_REQUEST);
}
/* Not just another value for the previous attribute */
if (name_length != 0) {
"alloca(): failed\n");
return (PAPI_TEMPORARY_ERROR);
}
"bad read: name\n");
return (PAPI_BAD_REQUEST);
}
}
"bad read: value length\n");
return (PAPI_BAD_REQUEST);
}
"Bad value length (%d) for type %s",
return (PAPI_BAD_REQUEST);
}
switch (value_tag) {
case VTAG_INTEGER:
case VTAG_ENUM: {
int32_t v;
return (PAPI_BAD_REQUEST);
}
PAPI_ATTR_APPEND, name, v);
}
break;
case VTAG_BOOLEAN: {
int8_t v;
"bad read: boolean\n");
return (PAPI_BAD_REQUEST);
}
PAPI_ATTR_APPEND, name, v);
}
break;
case VTAG_RANGE_OF_INTEGER: {
"bad read: min\n");
return (PAPI_BAD_REQUEST);
}
"bad read: max\n");
return (PAPI_BAD_REQUEST);
}
}
break;
case VTAG_RESOLUTION: {
int32_t x, y;
"bad read: x\n");
return (PAPI_BAD_REQUEST);
}
"bad read: y\n");
return (PAPI_BAD_REQUEST);
}
"bad read: units\n");
return (PAPI_BAD_REQUEST);
}
PAPI_ATTR_APPEND, name, x, y,
}
break;
case VTAG_DATE_TIME: {
time_t v;
int8_t c;
uint16_t s;
"bad read: year\n");
return (PAPI_BAD_REQUEST);
}
"bad read: month\n");
return (PAPI_BAD_REQUEST);
}
"bad read: day\n");
return (PAPI_BAD_REQUEST);
}
"bad read: hour\n");
return (PAPI_BAD_REQUEST);
}
"bad read: minutes\n");
return (PAPI_BAD_REQUEST);
}
"bad read: seconds\n");
return (PAPI_BAD_REQUEST);
}
"bad read: decisec\n");
return (PAPI_BAD_REQUEST);
}
/* tm.deciseconds = c; */
"bad read: utc_dir\n");
return (PAPI_BAD_REQUEST);
}
/* tm.utc_dir = c; */
"bad read: utc_hour\n");
return (PAPI_BAD_REQUEST);
}
/* tm.utc_hours = c; */
"bad read: utc_min\n");
return (PAPI_BAD_REQUEST);
}
/* tm.utc_minutes = c; */
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.
*/
break;
case VTAG_URI:
case VTAG_KEYWORD:
case VTAG_CHARSET: {
char *v;
"calloc(): failed\n");
return (PAPI_TEMPORARY_ERROR);
}
#ifdef NOTDEF
"bad read: stringy\n");
return (PAPI_BAD_REQUEST);
}
#else
{
char *p = v;
if (rc <= 0) {
"bad read: stringy\n");
return (PAPI_BAD_REQUEST);
}
i -= rc;
p += rc;
}
}
#endif
PAPI_ATTR_APPEND, name, v);
}
break;
case VTAG_UNKNOWN:
case VTAG_NOVALUE:
case VTAG_UNSUPPORTED:
break;
default: {
char *v;
"calloc(): failed\n");
return (PAPI_TEMPORARY_ERROR);
}
"bad read: other\n");
return (PAPI_BAD_REQUEST);
}
PAPI_ATTR_APPEND, name, v);
}
break;
}
}
if (attributes != NULL) {
}
return (PAPI_OK);
}
static papi_status_t
char type)
{
int8_t c;
uint16_t s;
int32_t i;
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.
*/
return (PAPI_BAD_REQUEST);
c = buf[0];
"version-major", c);
c = buf[1];
"version-minor", c);
if (type == IPP_TYPE_REQUEST)
attr_name = "operation-id";
attr_name, s);
"request-id", i);
return (PAPI_OK);
}
static papi_status_t
{
/* start reading the attribute groups */
return (PAPI_BAD_REQUEST);
}
return (result);
}
char type)
{
return (PAPI_BAD_ARGUMENT);
return (result);
}