prtfru.c revision 77acf672332ea28b22cae485d65f8c08a7e401f2
/*
* 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.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <alloca.h>
#include <assert.h>
#include <errno.h>
#include <libintl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "fru_tag.h"
#include "libfrup.h"
#include "libfrureg.h"
#define NUM_ITER_BYTES 4
#define HEAD_ITER 0
#define NUM_ITER 2
#define MAX_ITER 3
#define INDENT 3
#define TIMESTRINGLEN 128
#define TEMPERATURE_OFFSET 73
void **end_args);
const char *parent_path, int indent);
static char tagname[sizeof ("?_0123456789_0123456789_0123456789")];
int iterglobal = 0;
int FMAmessageR = -1;
/*
* Definition for data elements found in devices but not found in
* the system's version of libfrureg
*/
static fru_regdef_t unknown = {
-1,
-1,
-1,
-1,
0,
NULL,
0,
};
/*
* Write message to standard error and possibly the error log buffer
*/
static void
{
/* make relevant output appear before error message */
exit(1);
}
}
/*
* Write message to standard output
*/
static void
{
exit(1);
}
}
/*
* Safe wrapper for putchar()
*/
static void
voidputchar(int c)
{
exit(1);
}
}
static void (*safeputchar)(int c) = voidputchar;
/*
* Safe wrapper for puts()
*/
static void
voidputs(const char *s)
{
exit(1);
}
}
/*
* XML-safe wrapper for putchar(): quotes XML-special characters
*/
static void
xputchar(int c)
{
switch (c) {
case '<':
break;
case '>':
break;
case '&':
break;
case '"':
break;
default:
c = putchar(c);
break;
}
if (c == EOF) {
exit(1);
}
}
/*
* XML-safe analog of puts(): quotes XML-special characters
*/
static void
xputs(const char *s)
{
char c;
for (/* */; ((c = *s) != 0); s++)
xputchar(c);
}
/*
* Output the XML DTD derived from the registry provided by libfrureg
*/
int
output_dtd(void)
{
char **element;
unsigned int i, j, num_elements = 0;
const fru_regdef_t *def;
(num_elements == 0)) {
return (1);
}
return (1);
}
/*
* Output the DTD preamble
*/
output("<!ELEMENT FRUID_XML_Tree (Parameter*, "
"(Fru | Location | Container)*,\n"
" Parameter*, ErrorLog?, Parameter*)>\n"
"<!ATTLIST FRUID_XML_Tree>\n"
"\n"
"<!ELEMENT Parameter EMPTY>\n"
"<!ATTLIST Parameter type CDATA #REQUIRED>\n"
"<!ATTLIST Parameter name CDATA #REQUIRED>\n"
"<!ATTLIST Parameter value CDATA #REQUIRED>\n"
"\n"
"<!ELEMENT Fru (Fru | Location | Container)*>\n"
"<!ATTLIST Fru name CDATA #REQUIRED>\n"
"\n"
"<!ELEMENT Location (Fru | Location | Container)*>\n"
"<!ATTLIST Location\n"
" name CDATA #IMPLIED\n"
" value CDATA #IMPLIED\n"
">\n"
"\n"
"<!ELEMENT Container (ContainerData?, "
"(Fru | Location | Container)*)>\n"
"<!ATTLIST Container name CDATA #REQUIRED>\n"
"<!ATTLIST Container imagefile CDATA #IMPLIED>\n"
"\n"
"<!ELEMENT ContainerData (Segment*)>\n"
"<!ATTLIST ContainerData>\n"
"\n"
"<!ATTLIST Segment name CDATA #REQUIRED>\n"
"\n"
"<!ELEMENT Index EMPTY>\n"
"<!ATTLIST Index value CDATA #REQUIRED>\n"
"\n"
"<!ELEMENT ErrorLog (#PCDATA)>\n"
"<!ATTLIST ErrorLog>\n"
"\n");
/*
* Output the definition for each element
*/
for (i = 0; i < num_elements; i++) {
/* Prevent incompatible duplicate defn. from FRUID Registry. */
"definition for \"%s\"\n"),
element[i]);
return (1);
}
else
output("<!ELEMENT %s (Index_%s*)>\n"
"<!ATTLIST Index_%s>\n"
"<!ELEMENT Index_%s (%s",
output(")>\n");
output("<!ELEMENT %s EMPTY>\n"
"<!ATTLIST %s value CDATA #REQUIRED>\n",
output("<!-- %s valid enumeration values\n");
output("\t\"");
output("\"\n");
}
output("-->\n");
}
}
else
output("\n");
}
/* Provide for returning the tag for an "unknown" element */
output("<!ATTLIST UNKNOWN tag CDATA \"UNKNOWN\">\n\n");
/*
* List all data elements as possible members of "Segment"
*/
output("<!ELEMENT Segment ((UNKNOWN");
for (i = 0; i < num_elements; i++) {
}
output(")*)>\n");
return (0);
}
/*
* Function to convert bcd to binary to correct the SPD_Manufacturer_Week
*
*/
static void convertbcdtobinary(int *val)
{
int i;
tmpval = 0;
newval = 0;
i = 0;
rem = 0;
poweroften = 1;
while (tmpval != 0) {
if (i >= 1)
i ++;
}
}
/*
* Safely pretty-print the value of a field
*/
static void
{
int i, valueint;
const fru_regdef_t *new_def;
const char *parent_path;
case FDTYPE_Binary:
case FDISP_Binary:
for (i = 0; i < def->payloadLen; i++)
output("%c%c%c%c%c%c%c%c",
return;
case FDISP_Octal:
case FDISP_Decimal:
value = 0;
valueint = 0;
if ((value != 0) &&
return;
}
if ((value != 0) &&
"%llo" : "%lld (%lld degrees C)",
else
return;
case FDISP_Time:
errmsg = "time value too large for formatting";
break;
}
timefield = 0;
if (timefield == 0) {
errmsg = "No Value Recorded";
break;
}
errmsg = "cannot convert time value";
break;
}
== 0) {
errmsg = "formatted time would overflow buffer";
break;
}
return;
}
break;
case FDTYPE_ASCII:
if (!xml) {
if (FMAmessageR == 0)
elem_name = "FMA_Event_DataR";
else if (FMAmessageR == 1)
elem_name = "FMA_MessageR";
def->payloadLen);
new_def =
"/Status_EventsR[%d]/Message(FMA)",
parent_path = path;
output("\n");
return;
}
}
}
safeputchar(field[i]);
return;
case FDTYPE_Enumeration:
value = 0;
- def->payloadLen),
"FMA Message R") == 0)
FMAmessageR = 1;
else
"FMA Event Data R") == 0)
FMAmessageR = 0;
}
return;
}
errmsg = "unrecognized value";
break;
}
/* If nothing matched above, print the field in hex */
case FDISP_MSGID:
if (isprint(first_byte)) {
i++)
safeputchar(field[i]);
}
break;
case FDISP_UUID:
for (i = 0; i < def->payloadLen; i++) {
if ((i == 4) || (i == 6) ||
(i == 8) || (i == 10))
output("-");
}
break;
default:
for (i = 0; i < def->payloadLen; i++)
break;
}
/* Safely print any error message associated with the field */
if (errmsg) {
output(" (");
output(")");
}
}
}
/*
* Recursively print the contents of a data element
*/
static void
const char *parent_path, int indent)
{
char *path;
int bytes = 0, i;
/*
* Construct the path, or, for XML, the name, for the current
* data element
*/
if ((def->iterationCount == 0) &&
if (xml) {
}
else
path = "Index";
}
else
path = (char *)parent_path;
} else {
if (xml)
else {
}
}
/*
* Handle the various categories of data elements: iteration,
* record, and field
*/
if (def->iterationCount) {
n, valid = 1;
/*
* Make a new element definition to describe the components
* of the iteration
*/
newdef.iterationCount = 0;
/*
* Validate the contents of the iteration control bytes
*/
valid = 0;
"(should be less than %d)\n"),
}
valid = 0;
"(should not be greater than %d)\n"),
}
valid = 0;
"(should equal %d)\n"),
}
if (valid) {
} else {
head = 0;
}
if (xml)
else
num);
/*
* Print each component of the iteration
*/
n < num;
iterglobal = n;
indent);
}
const fru_regdef_t *component;
if (xml)
else
/*
* Print each component of the record
*/
}
} else if (xml) {
/*
* Base case: print the field formatted for XML
*/
? "%*s<UNKNOWN tag=\"%s\" value=\""
: "%*s<%s value=\"");
/*CSTYLED*/
const char *parent_path;
char path[16384];
const fru_regdef_t *new_def;
if (FMAmessageR == 0)
elem_name = "FMA_Event_DataR";
else if (FMAmessageR == 1)
elem_name = "FMA_MessageR";
"/Status_EventsR[%d]/Message(FMA)", iterglobal);
parent_path = path;
FMAmessageR = -1;
}
}
} else {
/*
* Base case: print the field
*/
output("\n");
}
}
/*
* Print the contents of a packet (i.e., a tagged data element)
*/
/* ARGSUSED */
static int
{
size_t payload_length = 0;
const fru_regdef_t *def;
/*
* Build a definition for unrecognized tags (e.g., not in libfrureg)
*/
if ((tag_type == -1) ||
if (tag_type == -1)
else
}
/*
* Print the defined element
*/
return (FRU_SUCCESS);
}
/*
* Print a segment's name and the contents of each data element in the segment
*/
static int
{
char *name;
int status;
name = "";
}
if (xml)
else
/* Iterate over the packets in the segment, printing the contents */
!= FRU_SUCCESS) {
}
return (FRU_SUCCESS);
}
/* ARGSUSED */
static void
{
}
/*
* Close the XML element for a "location" node
*/
/* ARGSUSED */
static void
void *args)
{
}
/*
* Close the XML element for a "fru" node
*/
/* ARGSUSED */
static void
{
}
/*
* Close the XML element for a "container" node
*/
/* ARGSUSED */
static void
void *args)
{
}
/*
* Introduce a node in XML and set the appropriate node-closing function
*/
/* ARGSUSED */
static void
{
switch (fru_type) {
case FRU_NODE_FRU:
*end_node = end_fru_xml;
break;
case FRU_NODE_CONTAINER:
break;
default:
break;
}
}
/*
* Print node info and, where appropriate, node contents
*/
/* ARGSUSED */
static fru_errno_t
{
int status;
}
if (containers_only) {
if (fru_type != FRU_NODE_CONTAINER)
return (FRU_SUCCESS);
}
/* Introduce the node */
if (list_only)
return (FRU_SUCCESS);
/* Print the contents of each packet in each segment of a container */
if (fru_type == FRU_NODE_CONTAINER) {
if ((status =
NULL))
!= FRU_SUCCESS) {
}
}
return (FRU_SUCCESS);
}
/*
* Process the node if its path matches the search path in "args"
*/
/* ARGSUSED */
static fru_errno_t
{
int status;
return (FRU_SUCCESS);
}
/*
* Write the trailer required for well-formed DTD-compliant XML
*/
static void
{
errno = 0;
char c;
output("<ErrorLog>\n");
if (!errno)
xputchar(c);
output("</ErrorLog>\n");
}
if (errno) {
/*NOTREACHED*/
}
output("</FRUID_XML_Tree>\n");
}
/*
* Print available FRU ID information
*/
int
int xml_flag)
{
fru_nodehdl_t frutree = 0;
/* Copy parameter flags to global flags */
/* Help arrange for correct, efficient interleaving of output */
/* Initialize for XML--or not */
if (xml) {
"Error creating error log file: %s\n",
return (1);
}
/* Output the XML preamble */
output("<?xml version=\"1.0\" ?>\n"
"<!--\n"
" Copyright 2000-2002 Sun Microsystems, Inc. "
"All rights reserved.\n"
" Use is subject to license terms.\n"
"-->\n\n"
"<!DOCTYPE FRUID_XML_Tree SYSTEM \"prtfrureg.dtd\">\n\n"
"<FRUID_XML_Tree>\n");
/* Arrange to always properly terminate XML */
if (atexit(terminate_xml))
} else
/* Get the root node */
return (1);
} else if (status != FRU_SUCCESS) {
return (1);
}
/* Process the tree */
if (searchpath == NULL) {
} else {
(void *)searchpath);
if (status == FRU_WALK_TERMINATE) {
} else if (status == FRU_SUCCESS) {
return (1);
}
}
if (status != FRU_SUCCESS)
}