libfru.cc revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* libfru is divided into the following modules:
* 1) This file. Support for the API and ties together all the sub-modules.
* 2) The parser which parses the field_paths supplied by the user.
* 3) The data_source sub-libraries which provide payloads(tags) and the tree
* structure of frus and locations.
* 4) The PayloadReader which given a payload and a path definition can extract
* the exact field the user is looking for.
* 5) The Registry which provides the definitions for all the Data Elements
* supported.
*
* 1) Parse the field_path given by the user.
* 2) Using the registry determine which payloads this data MAY appear in.
* 3) Figure out which tags of this type are in the container.
* 4) Find the specific tag which contains the instance of this data the user
* requested.
* 5) Get this tag from the data source and read it with the PayloadReader to
* 6) For UPDATES write this tag back to the data source.
*
* This algorithim is altered only when dealing with "UNKNOWN" payloads where
* it simplifies slightly.
*/
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <libintl.h>
#include <pthread.h>
#include <stdarg.h>
#include <dlfcn.h>
#include <alloca.h>
#include <limits.h>
#include "libfru.h"
#include "libfrup.h"
#include "libfruds.h"
#include "Ancestor.h"
#include "libfrureg.h"
#include "Parser.h"
#include "PayloadReader.h"
#define DATA_SOURCE_OBJ_NAME "data_source"
#define ENCRYPTION_LIB_NAME "libfrucrypt.so.1"
#define FRU_ENCRYPT_FUNC_NAME "fru_encrypt_func"
#define UNKNOWN_PATH "UNKNOWN"
#define IS_UNKNOWN_PATH(path) \
/* ========================================================================= */
/*
* Define a hash of rwlocks for each container.
*/
struct cont_lock
{
};
typedef struct cont_lock cont_lock_t;
#define CONT_LOCK_HASH_NUM 128
/*
* These control the Data sources available.
*/
static pthread_mutex_t ds_lock;
static int ds_lib_ref_cnt = 0;
static char *ds_lib_name = NULL;
/* ========================================================================= */
static const char *fru_errmsg[] =
{
"Success",
"Node not found",
"IO error",
"No registry definition for this element",
"Not container",
"Invalid handle",
"Invalid Segment",
"Invalid Path",
"Invalid Element",
"Invalid Data size (does not match registry definition)",
"Duplicate Segment",
"Not Field",
"No space available",
"Data could not be found",
"Iteration full",
"Invalid Permisions",
"Feature not Supported",
"Element is not Tagged",
"Failed to read container device",
"Segment Corrupt",
"Data Corrupt",
"General LIBFRU FAILURE",
"Walk terminated",
"Unknown error"
};
fru_encryption_supported(void)
{
if (encrypt_func == NULL)
return (FRU_NOTSUP);
else
return (FRU_SUCCESS);
}
extern "C" {
void
init_libfru(void)
{
// attempt to find the encryption library.
encrypt_func = NULL;
}
}
#pragma init(init_libfru)
}
/* ========================================================================= */
static void
{
/* insert at tail */
} else {
}
}
}
/* ========================================================================= */
static cont_lock_t *
{
break;
}
}
return (which);
}
/* ========================================================================= */
static cont_lock_t *
{
return (NULL);
}
return (NULL);
}
return (lock);
}
/* ========================================================================= */
static fru_errno_t
{
int hash_bucket = 0;
int lock_rc;
/* if not found add to hash */
return (FRU_FAILURE);
}
}
/* execute lock */
lock_rc = 0;
switch (mode) {
case READ_LOCK:
break;
case WRITE_LOCK:
break;
}
if (lock_rc != 0) {
return (FRU_FAILURE);
}
return (FRU_SUCCESS);
}
/* ========================================================================= */
/*
* Macro to make checking unlock_conatiner error code easier
*/
#define CHK_UNLOCK_CONTAINER(handle) \
return (FRU_FAILURE); \
}
static fru_errno_t
{
return (FRU_NODENOTFOUND);
}
return (FRU_FAILURE);
}
return (FRU_SUCCESS);
}
/* ========================================================================= */
static fru_errno_t
clear_cont_locks(void)
{
// for each bucket
for (int i = 0; i < CONT_LOCK_HASH_NUM; i++) {
// free all the locks
}
cont_lock_hash[i] = NULL;
}
return (FRU_SUCCESS);
}
/* ========================================================================= */
/* VARARGS */
fru_open_data_source(const char *name, ...)
{
int num_args = 0;
char *tmp;
int i = 0;
// we already have a DS assigned.
// user wants to open the same one... ok.
return (FRU_SUCCESS);
} else {
return (FRU_FAILURE);
}
}
return (FRU_NOTSUP);
}
return (FRU_FAILURE);
}
num_args++;
}
return (FRU_FAILURE);
}
}
// don't switch unless the source connects ok.
data_source = ds;
}
return (err);
}
/* ========================================================================= */
fru_close_data_source(void)
{
if (ds_lib_ref_cnt == 0) {
return (FRU_FAILURE);
}
if ((--ds_lib_ref_cnt) == 0) {
/* don't check err code here */
/* continue to clean up libfru and return the err at the end */
ds_lib_name = NULL;
data_source = NULL;
}
return (err);
}
/* ========================================================================= */
int
{
if (data_source == NULL) {
return (0);
}
return (0);
}
}
/* ========================================================================= */
static fru_errno_t
{
if (data_source == NULL) {
return (FRU_FAILURE);
}
/* get a list of all segments */
&raw_list)) != FRU_SUCCESS) {
return (err);
}
/* leave out the encrypted segments if necessary */
return (err);
}
if (fru_encryption_supported() == FRU_SUCCESS) {
} // else leave it out.
} else {
}
}
return (FRU_SUCCESS);
}
/* ========================================================================= */
const char *
{
(errnum >= 0)) {
}
return (gettext
}
/* ========================================================================= */
{
if (data_source == NULL) {
return (FRU_FAILURE);
}
if (err == FRU_SUCCESS) {
}
return (err);
}
/* ========================================================================= */
{
if (data_source == NULL) {
return (FRU_FAILURE);
}
&tr_child)) != FRU_SUCCESS) {
return (err);
}
!= FRU_SUCCESS) {
return (err);
}
if ((type == FRU_NODE_LOCATION) ||
(type == FRU_NODE_FRU) ||
(type == FRU_NODE_CONTAINER)) {
return (FRU_SUCCESS);
}
/*
* if the child is not valid try and find a peer of the child which is
* valid
*/
do {
&tr_child)) != FRU_SUCCESS) {
return (err);
}
!= FRU_SUCCESS) {
return (err);
}
if ((type == FRU_NODE_LOCATION) ||
(type == FRU_NODE_FRU) ||
(type == FRU_NODE_CONTAINER)) {
return (FRU_SUCCESS);
}
} while (1);
}
/* ========================================================================= */
{
if (data_source == NULL) {
return (FRU_FAILURE);
}
do {
!= FRU_SUCCESS) {
return (err);
}
!= FRU_SUCCESS) {
return (err);
}
if ((type == FRU_NODE_LOCATION) ||
(type == FRU_NODE_FRU) ||
(type == FRU_NODE_CONTAINER)) {
return (FRU_SUCCESS);
}
} while (1);
}
/* ========================================================================= */
{
if (data_source == NULL) {
return (FRU_FAILURE);
}
if (err == FRU_SUCCESS) {
}
return (err);
}
/* ========================================================================= */
{
if (data_source == NULL) {
return (FRU_FAILURE);
}
name));
}
/* ========================================================================= */
/*
* Project-private interface
*
* Apply process_node() to each node in the tree rooted at "node".
*
* process_node() has available the handle, path (in the subtree from the root
* "node" passed to fru_walk_tree()), and name of the node to which it is
* applied, as well as any arguments provided via the generic pointer "args".
* process_node() also takes a pointer to an end_node() function pointer
* argument and a pointer to a generic pointer "end_args" argument. If
* non-null, end_node() is called after the node and its children have been
* processed, but before the node's siblings are visited.
*/
extern "C" fru_errno_t
const char *path,
void **end_args),
void *args)
{
int prior_length;
/* Build node's path */
return (status);
return (FRU_FAILURE);
/* Process node */
!= FRU_SUCCESS) {
return (status);
}
/* Process children */
else if (status == FRU_NODENOTFOUND)
/* "Close" node */
if (status != FRU_SUCCESS)
return (status);
/* Process siblings */
else if (status == FRU_NODENOTFOUND)
return (status);
}
/* ========================================================================= */
/*
* Project-private interface
*
* Return true if "searchpath" equals "path" or is a tail of "path" and
* begins at a component name within "path"
*/
int
{
const char *match;
return (1);
return (0);
}
/* ========================================================================= */
{
if (data_source == NULL) {
return (FRU_FAILURE);
}
&tmp)) != FRU_SUCCESS) {
return (err);
}
return (FRU_SUCCESS);
}
/* ========================================================================= */
static fru_errno_t
{
return (err);
}
if (type == FRU_NODE_CONTAINER) {
return (FRU_SUCCESS);
}
return (FRU_NOTCONTAINER);
}
/* ========================================================================= */
{
if (e == NULL) {
return (FRU_SUCCESS);
}
return (FRU_SUCCESS);
}
/* ========================================================================= */
/*
* NOTE: does not free list. This is allocated by the user and should be
* deallocated by the user.
*/
{
return (FRU_SUCCESS);
}
}
}
return (FRU_SUCCESS);
}
/* ========================================================================= */
{
return (FRU_SUCCESS);
}
for (int i = 0; i < def->enum_count; i++)
}
def->enum_count = 0;
return (FRU_SUCCESS);
}
/* ========================================================================= */
{
return (err);
}
return (FRU_FAILURE);
}
return (err);
}
/* ========================================================================= */
{
int i = 0;
if (data_source == NULL) {
return (FRU_FAILURE);
}
(fru_encryption_supported() == FRU_NOTSUP)) {
return (FRU_NOTSUP);
}
return (err);
}
return (FRU_FAILURE);
}
/* get a list of all segments */
/* here we do not want to leave out the encrypted segments. */
&seg_list)) != FRU_SUCCESS) {
return (err);
}
== 0) {
return (FRU_DUPSEG);
}
}
return (err);
}
/* ========================================================================= */
{
return (FRU_INVALSEG);
}
if (data_source == NULL) {
return (FRU_FAILURE);
}
return (err);
}
return (FRU_FAILURE);
}
/* do not allow encrypted segments to be removed */
/* unless encryption is supported */
(fru_encryption_supported() == FRU_NOTSUP)) {
err = FRU_INVALSEG;
} else {
seg_name);
}
return (err);
}
/* ========================================================================= */
{
return (FRU_INVALSEG);
}
if (data_source == NULL) {
return (FRU_FAILURE);
}
return (err);
}
return (FRU_FAILURE);
}
// NOTE: not passing "definition" to this function such that I may
// check for encryption before allowing the user to get the data.
return (err);
}
(fru_encryption_supported() == FRU_NOTSUP)) {
return (FRU_INVALSEG);
}
// After encryption check, copy from my def to users.
return (FRU_SUCCESS);
}
/* ========================================================================= */
{
int i = 0;
int num_tags = 0;
return (FRU_INVALSEG);
}
if (data_source == NULL) {
return (FRU_FAILURE);
}
return (err);
}
return (FRU_FAILURE);
}
(fru_encryption_supported() == FRU_NOTSUP)) {
return (FRU_INVALSEG);
}
!= FRU_SUCCESS) {
return (err);
}
if (num_tags == 0) {
return (FRU_SUCCESS);
}
// allocate the memory for the names.
return (FRU_FAILURE);
}
// for each tag fill in it's name.
for (i = 0; i < num_tags; i++) {
return (FRU_FAILURE);
}
} else {
// instead of failing return "UNKNOWN"
return (FRU_FAILURE);
}
}
}
return (FRU_SUCCESS);
}
/* ========================================================================= */
/* Project-private interface */
extern "C" fru_errno_t
void *args)
{
if (data_source == NULL) {
return (FRU_FAILURE);
}
return (FRU_FAILURE);
}
return (status);
}
/* ========================================================================= */
/*
* Project-private interface
*
* This routine is only safe when called from within fru_for_each_segment()
* (which is currently the only way to get a segment handle) so that the
* segment's container will be locked
*/
{
name));
}
/* ========================================================================= */
/*
* Project-private interface
*
* This routine is only safe when called from within fru_for_each_segment()
* (which is currently the only way to get a segment handle) so that the
* segment's container will be locked
*/
extern "C" fru_errno_t
void *args)
{
}
/* ========================================================================= */
// To keep track of the number of instances for each type of tag which
// might occur.
struct TagInstPair
{
int inst;
};
struct tag_inst_hist_t
{
unsigned size;
unsigned numStored;
};
static fru_errno_t
{
// find if this tag has occured before.
int found = 0;
// if so just add to the instance.
found = 1;
break;
}
}
// if not add to the end of the array of instance 0.
if (!found) {
return (FRU_FAILURE);
}
}
return (FRU_SUCCESS);
}
static fru_errno_t
{
int j = 0;
return (FRU_SUCCESS);
}
}
return (FRU_FAILURE);
}
/* ========================================================================= */
// Input:
// a list of tags and number of them
// and an instance of the unknown payload you are looking for.
// Returns:
// on FRU_SUCCESS
// instance == the instance of the tag "tag" to read from the list
// else
// instance == the number of instances remaining.
//
static fru_errno_t
{
return (FRU_FAILURE);
}
// search all the tags untill they are exhausted or we find
// the instance we want.
int found = 0;
int instFound = 0;
// NOTE: instancesFound is a running total of the instances in the tags
// WE SKIPED!
// (ie instances left over == instance - instancesFound)
int i = 0;
for (i = 0; i < num_tags; i++) {
// unknown tag encountered.
!= FRU_SUCCESS) {
return (FRU_FAILURE);
}
// do this check because everything is 0 based.
// if we do the add before the check we will go
// to far.
found = 1;
break;
} else {
instFound++;
}
}
}
if (!found) {
return (FRU_DATANOTFOUND);
}
return (FRU_FAILURE);
}
return (FRU_SUCCESS);
}
// Input:
// a list of tags and number of them
// a list of Ancestors
// the instance we are looking for
// Returns:
// on FRU_SUCCESS
// instance == the instance of the field within the payload to read.
// correct == pointer into ants which is correct.
// tagInstance == instance of the tag
// else
// instance == the number of instances remaining.
// correct == NULL
// tagInstance == UNDEFINED
//
static fru_errno_t
int *tagInstance)
{
int j = 0;
int num_posible = 0;
num_posible++;
}
return (FRU_FAILURE);
}
int i = 0;
int found = 0;
int instancesFound = 0;
// NOTE: instancesFound is a running total of the instances in the tags
// WE SKIPED!
// (ie instances left over == instance - instancesFound)
for (i = 0; i < num_tags; i++) {
!= FRU_SUCCESS) {
return (FRU_FAILURE);
}
// do this check because everything is 0 based.
// if we do the add before the check we will go
// to far.
> (*instance)) {
found = 1;
break; /* while loop */
}
}
}
/* when found break out of both "for" and "while" loops */
if (found == 1) {
break; /* for loop */
}
}
*instance -= instancesFound;
if (!found) {
return (FRU_DATANOTFOUND);
}
!= FRU_SUCCESS) {
return (FRU_FAILURE);
}
return (FRU_SUCCESS);
}
/*
* Same as find_known_element but ONLY searches for absolute paths
* (ie PathDef->head == tag)
*/
static fru_errno_t
int *tagInstance)
{
// find the exact ancestor we want.
break;
}
}
// serious parser bug might cause this, double check.
return (FRU_FAILURE);
}
int found = 0;
(*tagInstance) = 0;
for (int i = 0; i < num_tags; i++) {
// do this check because everything is 0 based.
// if we do the add before the check we will go
// to far.
found = 1;
break;
}
(*tagInstance)++;
}
}
*instance -= (*tagInstance);
if (!found) {
return (FRU_DATANOTFOUND);
}
return (FRU_SUCCESS);
}
/* ========================================================================= */
// From the container, seg_name, instance, and field_path get me...
// pathDef: A linked list of Path Def objects which represent the
// field_path
// ancestors: A linked list of Tagged Ancestors which represent the
// possible payloads this data MAY reside in.
// correct: A pointer into the above list which indicates the Ancestor
// in which this instance actually resides.
// tagInstance: The instance of this ancestor in the segment. (ie Tag
// instance)
// instWICur: The instance of this element within the tag itself.
// Or in other words "the instances left"
// payload: The payload data
//
// For an "UNKNOWN" payload this will return NULL for the pathDef, ancestors,
// cur pointers. This will indicate to read that this payload should be
// returned with a special definition for it (UNKNOWN)... What a HACK I
// know...
#define READ_MODE 0
#define UPDATE_MODE 1
const char *seg_name,
int instance,
const char *field_path,
// returns the following...
int *tagInstance, // instance of the tag within the seg
int *instLeft, // within this payload
int mode)
{
int abs_path_flg = 0;
int num_tags = 0;
if (data_source == NULL) {
return (FRU_FAILURE);
}
!= FRU_SUCCESS) {
return (err);
}
if (num_tags == 0) {
return (FRU_DATANOTFOUND);
}
if (IS_UNKNOWN_PATH(field_path)) {
*tagInstance = 0;
int unknown_inst = instance;
&tagToRead)) != FRU_SUCCESS) {
*instLeft = unknown_inst;
return (err);
}
return (err);
}
&abs_path_flg, pathDef);
if (err != FRU_SUCCESS) {
return (err);
/* without valid ancestors we can't find payloads for this */
delete pathDef;
return (FRU_INVALELEMENT);
}
delete *ancestors; // linked list
delete *pathDef;
return (FRU_INVALPATH);
}
if (abs_path_flg == 1) {
!= FRU_SUCCESS) {
// set up to search next segment for instances left
// over
delete *ancestors; // linked list
delete *pathDef;
return (err);
}
} else {
!= FRU_SUCCESS) {
// set up to search next segment for instances left
// over
delete *ancestors; // linked list
delete *pathDef;
return (err);
}
}
// if we get here this means the instance number within the payload.
(*tagInstance),
!= FRU_SUCCESS) {
delete *ancestors; // linked list
delete *pathDef;
return (err);
}
return (FRU_SUCCESS);
}
/* ========================================================================= */
/*
* Handle decryption if necessary
*/
static fru_errno_t
{
if (fru_encryption_supported() == FRU_SUCCESS) {
return (err);
}
} else {
return (FRU_FAILURE);
}
}
return (FRU_SUCCESS);
}
/* ========================================================================= */
// Same as get_payload except if seg_name is NULL and it will find the one
// used and return it.
//
static fru_errno_t
char **seg_name,
int instance,
const char *field_path,
// returns the following...
int *tagInstance, // within the segment.
int *instLeft, // within this payload
{
return (err);
}
if (field_path == NULL)
return (FRU_INVALPATH);
// always check for valid segment names.
return (FRU_INVALSEG);
}
!= FRU_SUCCESS) {
return (err);
}
*payload, *payloadLen));
} else {
!= FRU_SUCCESS) {
return (err);
}
int found = 0;
if (err == FRU_SUCCESS) {
return (do_decryption(container,
(const char *)(*seg_name),
*payload, *payloadLen));
} else if (err == FRU_DATANOTFOUND) {
// we may have found some instances or none at
// all but not enough all together. search
// again with the # of instances left.
} else {
return (err);
}
}
return (FRU_DATANOTFOUND);
}
}
/* ========================================================================= */
const char *field_path,
char **found_path)
{
// just init this value for the user
*data_len = 0;
return (FRU_FAILURE);
}
int tagInstance = 0;
int instWIPayload = 0;
size_t payloadLen = 0;
if (err != FRU_SUCCESS) {
return (err);
}
delete ancestors;
delete pathDef;
return (FRU_FAILURE);
}
*data_len = payloadLen;
if (found_path != NULL) {
}
return (FRU_SUCCESS);
}
// get the specific data
delete pathDef;
if (err == FRU_SUCCESS) {
if (found_path != NULL) {
*found_path = (char *)malloc(
if ((*found_path) == NULL) {
delete ancestors;
return (FRU_FAILURE);
}
}
}
delete ancestors;
return (err);
}
/* ========================================================================= */
const char *field_path,
{
return (FRU_INVALPATH);
return (FRU_INVALSEG);
}
if (data_source == NULL) {
return (FRU_FAILURE);
}
return (FRU_FAILURE);
}
int tagInstance = 0;
int instWIPayload = 0;
size_t payloadLen = 0;
if (err != FRU_SUCCESS) {
return (err);
}
return (err);
}
// fill in the new data in the payload
if (err != FRU_SUCCESS) {
delete ancestors; // linked list.
delete pathDef;
return (err);
}
(fru_encryption_supported() == FRU_SUCCESS)) {
!= FRU_SUCCESS) {
delete ancestors; // linked list.
delete pathDef;
return (err);
}
}
delete ancestors; // linked list.
delete pathDef;
return (err);
}
/* ========================================================================= */
char **seg_name,
unsigned int instance,
const char *iter_path,
int *num_there,
char **found_path)
{
// this ensures a more descriptive error message.
return (FRU_FAILURE);
}
int tagInstance = 0;
int instWIPayload = 0;
size_t payloadLen = 0;
if (err != FRU_SUCCESS) {
return (err);
}
// clean up memory from called functions.
err = FRU_INVALPATH;
} else {
// get the specific data
}
delete pathDef;
if (err == FRU_SUCCESS) {
if (found_path != NULL) {
*found_path = (char *)malloc(
if ((*found_path) == NULL) {
delete ancestors;
return (FRU_FAILURE);
}
}
}
delete ancestors;
return (err);
}
/* ========================================================================= */
// When adding a new payload with 0 data the iteration control bytes must be
// filled in with the number possible.
const fru_regdef_t *def,
int inIteration)
{
(inIteration)) {
int offset = 0;
const fru_regdef_t *newDef
if (rc2 != FRU_SUCCESS)
return (rc2);
}
} // else field, no sub elements; do nothing... ;-)
} else {
int offset = 3;
for (int i = 0; i < def->iterationCount; i++) {
if (rc3 != FRU_SUCCESS)
return (rc3);
}
}
return (rc);
}
/* ========================================================================= */
const char *seg_name,
const char *element)
{
return (FRU_INVALSEG);
}
const fru_regdef_t *def
= fru_reg_lookup_def_by_name((char *)element);
return (FRU_NOREGDEF);
}
return (FRU_ELEMNOTTAGGED);
}
if (data_source == NULL) {
return (FRU_FAILURE);
}
return (err);
}
return (FRU_FAILURE);
}
if (err != FRU_SUCCESS) {
delete[] data;
return (err);
}
if (fru_encryption_supported() == FRU_NOTSUP) {
delete[] data;
return (FRU_INVALSEG);
}
delete[] data;
return (err);
}
}
delete[] data;
return (err);
}
/* ========================================================================= */
const char *seg_name,
unsigned int instance,
const char *element)
{
return (FRU_INVALSEG);
}
if (data_source == NULL) {
return (FRU_FAILURE);
}
return (err);
}
return (FRU_FAILURE);
}
(fru_encryption_supported() == FRU_NOTSUP)) {
return (FRU_INVALSEG);
}
// again the special case of UNKNOWN. This allows us to delete these
// elements if they are somehow not wanted.
// NOTE: "/UNKNOWN" is not supported just as "/ManR" would not be valid
// either. Both of these will result in returning FRU_NOREGDEF
int num_tags = 0;
!= FRU_SUCCESS) {
return (err);
}
return (err);
}
} else {
const fru_regdef_t *def
= fru_reg_lookup_def_by_name((char *)element);
return (FRU_NOREGDEF);
}
return (FRU_ELEMNOTTAGGED);
}
}
return (err);
}
/* General library support */
/* ========================================================================= */
static fru_errno_t
{
else
// zzz
// This should be the following statement.
// (*definition)->data_length = def->dataLength;
// instead of.
} else {
}
// END zzz
definition->enum_count = 0;
if (count != 0) {
(sizeof (fru_enum_t)) * count);
return (FRU_FAILURE);
}
((sizeof (fru_enum_t)) * count));
}
for (int i = 0; i < count; i++) {
return (FRU_FAILURE);
}
(definition->enum_count)++;
}
return (FRU_FAILURE);
}
return (FRU_SUCCESS);
}
/* ========================================================================= */
fru_get_definition(const char *element_name,
{
// find the last one in the string...
int abs_path_flg = 0;
&abs_path_flg, &pathDef);
if (err != FRU_SUCCESS) {
return (err);
}
delete ancestors;
delete pathDef;
return (err);
}
/* ========================================================================= */
{
unsigned int number = 0;
return (FRU_FAILURE);
}
return (FRU_SUCCESS);
}
/* ========================================================================= */
{
/* count them */
int number = 0;
number++;
}
if (number == 0) {
return (FRU_SUCCESS);
}
return (FRU_FAILURE);
}
for (int i = 0; i < number; i++) {
return (FRU_FAILURE);
}
return (FRU_FAILURE);
}
}
return (FRU_SUCCESS);
}
/*
* Enum string converters.
*/
/* ========================================================================= */
const char *
{
switch (e) {
case FDISP_Binary:
return (gettext("Binary"));
case FDISP_Hex:
return (gettext("Hex"));
case FDISP_Decimal:
return (gettext("Decimal"));
case FDISP_Octal:
return (gettext("Octal"));
case FDISP_String:
return (gettext("String"));
case FDISP_Time:
return (gettext("Time"));
case FDISP_UNDEFINED:
return (gettext("UNDEFINED"));
}
return (gettext("UNDEFINED"));
}
/* ========================================================================= */
const char *
{
switch (e) {
case FDTYPE_Binary:
return (gettext("Binary"));
case FDTYPE_ByteArray:
return (gettext("Byte Array"));
case FDTYPE_ASCII:
return (gettext("ASCII"));
case FDTYPE_Unicode:
return (gettext("Unicode"));
case FDTYPE_Record:
return (gettext("Record"));
case FDTYPE_Enumeration:
return (gettext("Enumeration"));
case FDTYPE_UNDEFINED:
return (gettext("UNDEFINED"));
}
return (gettext("UNDEFINED"));
}
/* ========================================================================= */
const char *
{
switch (e) {
case FRU_No:
return (gettext("No"));
case FRU_Yes:
return (gettext("Yes"));
case FRU_WHICH_UNDEFINED:
return (gettext("WHICH UNDEFINED"));
}
return (gettext("WHICH UNDEFINED"));
}
/* ========================================================================= */
const char *
{
switch (e) {
case FRU_FIFO:
return (gettext("FIFO"));
case FRU_Circular:
return (gettext("Circular"));
case FRU_Linear:
return (gettext("Linear"));
case FRU_LIFO:
return (gettext("LIFO"));
case FRU_NOT_ITERATED:
return (gettext("NOT ITERATED"));
}
return (gettext("NOT ITERATED"));
}