sml.c revision 5c51f1241dbbdf2656d0e10011981411ed0c9673
/*
* 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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Module: sml.c
* Synopsis: simplified markup language (SML) support
* Taxonomy: project private
* Debug flag: sml
* Description:
*
* This module implements methods that support the processing of a
* simplified markup language (SML). Objects that contain SML data
* can be created and manipulated, and SML can be imported into
* internal SML objects or exported from internal SML objects.
*
* Public Methods:
*
* smlAddTag - Add new tag object into existing tag object
* smlConvertStringToTag - Convert string into tag object
* smlConvertTagToString - Convert a tag object into a string
* representation of the XML
* smlDbgPrintTag - Print a representation of an XML tag if debugging
* smlDelParam - Delete a parameter from a tag object
* smlDelTag - Delete element from tag object
* smlDup - Duplicate a tag object
* smlFindAndDelTag - Delete a tag if found in tag object
* smlFreeTag - Free a tag object and all its contents when no
* longer needed
* smlFstatCompareEq - Compare file status information
* smlGetElementName - Return a tag's element name
* smlGetNumParams - Get number of parameters set in tag
* smlGetParam - Get a parameter from a tag
* smlGetParamF - Get a formatted parameter from a tag
* smlGetParamByTag - Get a parameter by tag and index
* smlGetParamByTagParam Get parameter given tag name, index,
* parameter name, and value
* smlGetParamName - Get the name of a tag parameter given its index
* smlGetParam_r - Get a parameter from a tag into fixed buffer
* smlGetTag - Get an element from a tag
* smlGetTagByName - Get an element given a name and an index
* smlGetTagByTagParam - Get element given tag name, index, parameter name,
* and value
* smlGetVerbose - get current verbose mode setting
* smlLoadTagFromFile - Load a file into a tag object
* smlNewTag - Create a new (empty) tag object
* smlParamEq - Determine if parameter is equal to a specified value
* smlParamEqF - Determine if parameter is equal to a specified value
* smlPrintTag - Print a simple XML representation of a tag to stderr
* smlReadOneTag - read one complete tag from a datastream
* smlReadTagFromDs - read tag object from datastream
* smlSetFileStatInfo - encode file status information into tag
* smlSetParam - Set parameter value in tag object
* smlSetParamF - Set parameter value in tag object
* smlWriteTagToDs - Write an XML representation of a tag to a datastream
* smlWriteTagToFd - Write an XML representation of a tag to an open file
* descriptor
* smlWriteTagToFile - Write an XML representation of a tag to a file
*/
/*
* Unix includes
*/
#include <locale.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <libintl.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include <fcntl.h>
#include <limits.h>
#include <strings.h>
/*
* liblu Includes
*/
#include "libinst.h"
#include "messages.h"
/* Should be defined by cc -D */
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
/*
* Private Method Forward Declarations
*/
/*PRINTFLIKE2*/
static int _smlWriteSimpleTag(char **a_str,
static char *_sml_fileStatInfoTag = "File-Stat-Info";
/*
*
* This definition controls the maximum size of any individual sml
* component, such as a tag name, tag *value*, etc. The code should
* someday be revised to dynamically allocate whatever memory is needed
* to hold such components while parsing, but that exercise is left for
* another day. Any component that exceeds this length is silently
* truncated...
*/
#define MAX_SML_COMPONENT_LENGTH 16384
/*
* Public Methods
*/
/*
* Name: smlAddTag
* Description: Add new tag object into existing tag object
* Arguments: r_tag - [RO, *RW] - (SML_TAG **)
* Pointer to handle to the tag object to update
* The handle may be updated if the tag object is
* moved in memory
* a_index - [RO] - (int)
* Add the tag after the "n"th tag in the tag object
* -1 == add the tag to the end of the tag object
* 0 == add the tag to the beginning of the tag object
* a_subTag - [RO, *RW] - (SML_TAG *)
* The tag to add to 'tag'
* Returns: SML_TAG *
* The location within "r_tag" where "a_subTag"
* has been added - this is the handle into the r_tag
* object to the tag that was just added
* Errors: If the tag object cannot be updated, the process exits
*/
SML_TAG *
{
/* entry assertions */
/* if no tag to update specified, ignore request */
if (tag == SML_TAG__NULL) {
return (tag);
}
/* entry debugging info */
/* if index is out of range or -1, append to tag object */
}
/* bump number of tags in tag object */
/* expand tag object to hold new subtag */
/* if not appending, adjust tag object to hold new subtag */
}
/* copy new subtag into correct location in tag object */
sizeof (SML_TAG));
}
/*
* Name: smlDelTag
* Description: Delete element from tag object
* Arguments: tag - [RO, *RW] - (SML_TAG *)
* The tag object to update
* sub_tag - [RO, *RW] - (SML_TAG *)
* Element to be removed from the tag object
* Returns: void
* The sub_tag is removed from the tag object
* NOTE: The sub-tag and all elements contained within it are deallocated
* the sub-tag is no longer valid when this method returns
*/
void
{
int index;
/* entry assertions */
/* if no tag to update specified, ignore request */
if (tag == SML_TAG__NULL) {
return;
}
/* entry debugging info */
/* if tag object is empty, ignore request */
return;
}
/* determine index into tag object of element to remove */
break;
}
}
/* if element not found in tag, ignore request */
return;
}
/* free up the subtag to be deleted */
/*
* if not removing last element, collapse tag object removing
* target element
*/
}
/* one less tag object in tag */
/*
* If only one tag left, then delete entire tag structure
* otherwise reallocate removing unneeded entry
*/
/* realloc removing last element in tag object */
} else {
}
}
/*
* Name: smlFreeTag
* Description: Free a tag object and all its contents when no longer needed
* Arguments: tag - [RO, *RW] - (SML_TAG *)
* The tag object to be deleted
* Returns: void
* The tag object and all its contents are deallocated
*/
void
{
/* entry assertions */
/* entry debugging info */
}
/* free the tag object contents */
/* free the tag object handle */
}
/*
* Name: smlGetNumParams
* Synopsis: Get number of parameters set in tag
* Description: Return the number of parameters set in a tag
* Arguments: a_tag - [RO, *RO] - (SML_TAG *)
* The tag object to obtain the # params from
* Returns: int
* Number of parameters set in tag
* 0 = no parameters are set
*/
int
{
}
/*
* Name: smlGetParam_r
* Description: Get a parameter from a tag into a buffer of fixed size
* Arguments: tag - [RO, *RO] - (SML_TAG *)
* The tag object to obtain the parameter from
* name - [RO, *RO] - (char *)
* Name of the parameter to retrieve
* buf - [RO, *RW] - (char *)
* Location of buffer to contain results
* bufLen - [RO, *RO] - (int)
* Maximum bytes available in buffer to contain results
* Returns: void
*/
void
{
int k;
/* entry assertions */
/* terminate the buffer */
buf[0] = '\0';
/* if no tag specified, return NULL */
if (tag == SML_TAG__NULL) {
return;
}
/* if no parameters in tag, return NULL */
return;
}
/* entry debugging info */
/* scan tag object looking for specified parameter */
for (k = 0; k < tag->params_num; k++) {
return;
}
}
/* parameter not found - return */
}
/*
* Name: smlGetParam
* Description: Get a parameter from a tag
* Arguments: tag - [RO, *RO] - (SML_TAG *)
* The tag object to obtain the parameter from
* name - [RO, *RO] - (char *)
* Name of the parameter to retrieve
* Returns: char *
* Value of the specified parameter
* == (char *)NULL if the parameter does not exist
* NOTE: Any parameter returned is placed in new storage for the
* calling method. The caller must use 'free' to dispose
* of the storage once the parameter is no longer needed.
*/
char *
{
int k;
/* entry assertions */
/* entry debugging info */
/* if no tag specified, return NULL */
if (tag == SML_TAG__NULL) {
return ((char *)NULL);
}
/* if no parameters in tag, return NULL */
return ((char *)NULL);
}
/* entry debugging info */
/* scan tag object looking for specified parameter */
for (k = 0; k < tag->params_num; k++) {
}
}
/* parameter not found - return NULL */
return ((char *)NULL);
}
/*
* Name: smlGetParamName
* Description: Get the name of a tag parameter given its index
* Arguments: tag - [RO, *RO] - (SML_TAG *)
* The tag object to obtain the parameter name from
* index - [RO] - (int)
* Index of parameter name to return
* Returns: char *
* Name of 'index'th parameter
* == (char *)NULL if no such parameter exists in tag
* NOTE: Any parameter name returned is placed in new storage for the
* calling method. The caller must use 'free' to dispose
* of the storage once the parameter name is no longer needed.
*/
char *
{
/* if no tag specified, return NULL */
return ((char *)NULL);
}
/* entry debugging info */
/* if no parameters in tag, return NULL */
return ((char *)NULL);
}
/* if index not within range, return NULL */
return ((char *)NULL);
}
/* index within range - return parameter name */
}
/*
* Name: smlGetParamByTag
* Synopsis: Get a parameter value from a tag by name and index
* Description: Call to look for a parameter value from a tag with
* a given name with a parameter of a given name
* Arguments: tag - [RO, *RO] - (SML_TAG *)
* The tag object to obtain the parameter
* index - [RO] - (int)
* Index of nth tag by name to look for
* tagName - [RO, *RO] - (char *)
* Name of tag to look for
* paramName - [RO, *RO] - (char *)
* Name of parameter to return value of
* Returns: char *
* == (char *)NULL - no parameter value set
* != (char *)NULL - value of parameter set
*/
char *
{
/* entry assertions */
/* entry debugging info */
/* find the requested tag by name and index */
if (rtag == SML_TAG__NULL) {
return ((char *)NULL);
}
}
/*
* Name: smlGetTagByTagParam
* Synopsis: Get element given tag name, index, parameter name, and value
* Description: Call to look for a tag with a given nae, that has a parameter
* of a given name with a specified value
* Arguments: tag - [RO, *RO] - (SML_TAG *)
* The tag object to obtain the element from
* index - [RO] - (int)
* Index of nth name to return
* tagName - [RO, *RO] - (char *)
* Tag name to look up
* paramName - [RO, *RO] - (char *)
* Parameter name to look up
* paramValue - [RO, *RO] - (char *)
* Parameter value to match
* Returns: SML_TAG *
* The 'index'th occurance of element 'name' with
* a parameter 'name' with value specified
* == SML_TAG__NULL if no such element exists
*/
SML_TAG *
{
int ti; /* tag structure index */
/* entry assertions */
/* if tag has no elements, return NULL */
return (SML_TAG__NULL);
}
/*
* Search algorithm:
* -> search tag structure; for each tag with element == "tagName":
* -> search tag parameters; if parameter name == "paramName"
* -> if parameter value != "paramValue"; to next tag
* -> if parameter value == "paramValue":
* -> if not the "index"th paramValue found; to next tag
* -> return tag found
*/
int pi; /* parameter structure index */
/* if tag element does not match, go on to next tag */
continue;
}
/* if parameter name doesnt match to next parameter */
continue;
}
/* if parameter value doesnt match to next tag */
paramValue)) {
break;
}
/*
* found element/paramname/paramvalue:
* -> if this is not the 'index'th one, go to next tag
*/
if (index-- != 0) {
break;
}
/*
* found specified element/paramname/paramvalue:
* -> return the tag found
*/
}
}
/* no such element found - return NULL */
return (SML_TAG__NULL);
}
/*
* Name: smlGetParamByTagParam
* Synopsis: Get parameter given tag name, index, parameter name, and value
* Description: Call to return the value of a parameter from a tag of a
* given name, with a parameter of a given name with a
* specified value
* Arguments: tag - [RO, *RO] - (SML_TAG *)
* The tag object to obtain the element from
* index - [RO] - (int)
* Index of nth name to return
* tagName - [RO, *RO] - (char *)
* Tag name to look up
* paramName - [RO, *RO] - (char *)
* Parameter name to look up
* paramValue - [RO, *RO] - (char *)
* Parameter value to match
* paramReturn - [RO, *RO] - (char *)
* Parameter name to return the value of
* Returns: char *
* The value of parameter 'paramReturn' from the
* The 'index'th occurance of element 'name' with
* a parameter 'name' with value specified
* == (char *)NULL if no such parameter exists
*/
char *
{
int ti; /* tag structure index */
/* entry assertions */
/* if tag has no elements, return NULL */
return ((char *)NULL);
}
/*
* Search algorithm:
* -> search tag structure; for each tag with element == "tagName":
* -> search tag parameters; if parameter name == "paramName"
* -> if parameter value != "paramValue"; to next tag
* -> if parameter value == "paramValue":
* -> if not the "index"th paramValue found; to next tag
* -> return value of "paramReturn"
*/
int pi; /* parameter structure index */
/* if tag element does not match, go on to next tag */
continue;
}
/* if parameter name doesnt match to next parameter */
continue;
}
/* if parameter value doesnt match to next tag */
paramValue)) {
break;
}
/*
* found element/paramname/paramvalue:
* -> if this is not the 'index'th one, go to next tag
*/
if (index-- != 0) {
break;
}
/*
* found specified element/paramname/paramvalue:
* -> return parameter requested
*/
}
}
/* no such element found - return NULL */
return ((char *)NULL);
}
/*
* Name: smlGetElementName
* Description: Return the name of a given tag
* Arguments: a_tag - [RO, *RO] - (SML_TAG *)
* The tag object to obtain the element name from
* Returns: char *
* Value of name of specified tag
* NOTE: Any name string returned is placed in new storage for the
* calling method. The caller must use 'free' to dispose
* of the storage once the name string is no longer needed.
*/
char *
{
/* entry assertions */
/* return the tag name */
}
/*
* Name: smlGetTag
* Description: Get an element from a tag
* Arguments: tag - [RO, *RO] - (SML_TAG *)
* The tag object to obtain the element from
* index - [RO] - (int)
* Index of element to return
* Returns: SML_TAG *
* The 'index'th element from the specified tag
* == SML_TAG__NULL if no such tag or element
*/
SML_TAG *
{
/* if no tag specified, return NULL */
return (SML_TAG__NULL);
}
/* if tag has no elements, return NULL */
return (SML_TAG__NULL);
}
/* if index not within range, return NULL */
return (SML_TAG__NULL);
}
/* index within range, return element specified */
}
/*
* Name: smlGetTagByName
* Description: Get an element given a name and an index
* Arguments: tag - [RO, *RO] - (SML_TAG *)
* The tag object to obtain the element from
* index - [RO] - (int)
* Index of nth name to return
* name - [RO, *RO] - (char *)
* Tag name to look up
* Returns: SML_TAG *
* The 'index'th occurance of element 'name'
* == SML_TAG__NULL if no such element exists
*/
SML_TAG *
{
int k;
/* if no tag specified, return NULL */
return (SML_TAG__NULL);
}
/* if this tag is the one mentioned, return it */
return (tag);
}
/* if tag has no elements, return NULL */
return (SML_TAG__NULL);
}
/* if index out of range, return NULL */
return (SML_TAG__NULL);
}
/* index within range - search for specified element */
if (index == 0) {
} else {
index--;
}
}
}
/* no such element found - return NULL */
return (SML_TAG__NULL);
}
/*
* Name: smlConvertStringToTag
* Description: Convert string into tag object
* Arguments: err - [RO, *RW] (LU_ERR)
* Error object - used to contain any errors encountered
* and return those errors to this methods caller
* r_tag - [RW, *RW] - (SML_TAG **)
* Pointer to handle to place new tag object
* str - [RO, *RO] - (char *)
* String object to convert to tag object
* Returns: int
* RESULT_OK - string converted to tag object
* RESULT_ERR - problem converting string to tag object
* NOTE: Any tag object returned is placed in new storage for the
* calling method. The caller must use 'smlFreeTag' to dispose
* of the storage once the tag object name is no longer needed.
*/
int
{
int r;
/* entry assertions */
for (;;) {
if (r != RESULT_OK) {
return (r);
}
if (tmp_tag == SML_TAG__NULL) {
if (*str != '\0') {
continue;
}
return (RESULT_OK);
}
sizeof (SML_TAG));
}
}
/*
* Name: smlReadOneTag
* Description: read one complete tag from a datastream
* Arguments: err - [RO, *RW] (LU_ERR)
* Error object - used to contain any errors encountered
* and return those errors to this methods caller
* r_tag - [RW, *RW] - (SML_TAG **)
* Pointer to handle to place new tag object
* == SML_TAG__NULL if empty tag found (not an error)
* ds - [RO, *RO] - (LU_DS)
* Handle to datastream to read tag from
* Returns: int
* RESULT_OK - tag successfully read
* RESULT_ERR - problem reading tag
* NOTE: Any tag object returned is placed in new storage for the
* calling method. The caller must use 'smlFreeTag' to dispose
* of the storage once the tag object name is no longer needed.
*/
int
{
int r;
/* entry assertions */
/* entry debugging info */
/* reset return tag */
*r_tag = SML_TAG__NULL;
/* read tag from datastream, no parent tag to attach it to */
if (r != RESULT_OK) {
return (r);
}
if (*r_tag != SML_TAG__NULL) {
(unsigned long)*r_tag,
} else {
}
/* exit debugging info */
return (RESULT_OK);
}
/*
* Name: smlNewTag
* Description: Create a new (empty) tag object
* Arguments: name - [RO, *RO] - (char *)
* Name of tag; NULL to give the tag no name
* Returns: SML_TAG *
* Tag object created
* NOTE: Any tag object returned is placed in new storage for the
* calling method. The caller must use 'smlFreeTag' to dispose
* of the storage once the tag object name is no longer needed.
* Errors: If the tag object cannot be created, the process exits
*/
SML_TAG *
{
/* entry assertions */
/* entry debugging info */
/* allocate zeroed storage for the tag object */
/* if name is provided, duplicate and assign it */
}
/* exit assertions */
/* exit debugging info */
return (tag);
}
/*
* Name: smlConvertTagToString
* Description: Convert a tag object into a string representation of the XML
* Arguments: tag - [RO, *RO] - (SML_TAG *)
* The tag object to convert to a string
* Returns: char *
* String representation (in XML) of tag object
* == (char *)NULL if conversion is not possible
* NOTE: Any string returned is placed in new storage for the
* calling method. The caller must use 'free' to dispose
* of the storage once the string is no longer needed.
*/
char *
{
/* entry assertions */
/* convert the tag object into the datastream */
/* return the results */
return (str);
}
/*
* Name: smlDbgPrintTag
* Synopsis: Print a representation of an XML tag if debugging
* Arguments: a_tag - [RO, *RO] - (SML_TAG *)
* Pointer to tag structure to dump
* a_format - [RO, RO*] (char *)
* printf-style format for debugging message to be output
* VARG_LIST - [RO] (?)
* arguments as appropriate to 'format' specified
* Returns: void
* If one of the debugging flags is set, the hexdump
* is output.
*/
/*PRINTFLIKE2*/
void
{
char bfr[1];
/* entry assertions */
/*
* output the message header
*/
/* determine size of the message in bytes */
/* allocate storage to hold the message */
/* generate the results of the printf conversion */
/* convert the tag into a string to be printed */
}
}
/*
* Name: smlDelParam
* Description: Delete a parameter from a tag object
* Arguments: tag - [RO, *RW] - (SML_TAG *)
* The tag object to delete the parameter from
* name - [RO, *RO] - (char *)
* The parameter to delete from the tag object
* Returns: void
* If the parameter exists, it is deleted from the tag
*/
void
{
int k;
/* entry assertions */
/* entry debugging info */
/* if tag has no parameters, nothing to delete */
return;
}
/* search the tag for the parameter */
for (k = 0; k < tag->params_num; k++) {
break;
}
}
/* if the parameter was not found, nothing to delete */
if (k >= tag->params_num) {
name);
return;
}
/* parameter found - indicate deleted */
/* free up storage fro parameter */
/* if not at end, compact parameter storage */
}
/* one less parameter object in tag */
tag->params_num --;
/*
* If only one parameter left, then delete entire parameter storage,
* otherwise reallocate removing unneeded entry
*/
if (tag->params_num > 0) {
/* realloc removing last element in tag object */
} else {
}
}
/*
* Name: smlSetParamF
* Description: Set formatted parameter value in tag object
* Arguments: tag - [RO, *RW] - (SML_TAG *)
* The tag object to set the parameter in
* name - [RO, *RO] - (char *)
* The parameter to add to the tag object
* format - [RO, RO*] (char *)
* printf-style format to create parameter value from
* ... - [RO] (?)
* arguments as appropriate to 'format' specified
* Returns: void
* The parameter value is set in the tag object
* according to the results of the format string
* and arguments
*/
/*PRINTFLIKE3*/
void
{
char fbfr[1];
/* entry assertions */
/* determine size of the parameter name in bytes */
/* allocate storage to hold the message */
/* generate the parameter name and store it in the allocated storage */
/* add the parameter to the tag */
/* free up temporary storage and return */
}
/*
* Name: smlGetParam
* Description: Get a format-generated parameter from a tag
* Arguments: tag - [RO, *RO] - (SML_TAG *)
* The tag object to obtain the parameter from
* format - [RO, RO*] (char *)
* printf-style format for parameter name to be
* looked up to be formatted
* ... - [RO] (?)
* arguments as appropriate to 'format' specified
* Returns: char *
* Value of the specified parameter
* == (char *)NULL if the parameter does not exist
* NOTE: Any parameter returned is placed in new storage for the
* calling method. The caller must use 'free' to dispose
* of the storage once the parameter is no longer needed.
*/
/*PRINTFLIKE2*/
char *
{
char fbfr[1];
char *p;
/* entry assertions */
/* determine size of the parameter name in bytes */
/* allocate storage to hold the message */
/* generate the parameter name and store it in the allocated storage */
/* add the parameter to the tag */
/* free up temporary storage and return */
return (p);
}
/*
* Name: smlSetParam
* Description: Set parameter value in tag object
* Arguments: tag - [RO, *RW] - (SML_TAG *)
* The tag object to set the parameter in
* name - [RO, *RO] - (char *)
* The parameter to add to the tag object
* value - [RO, *RO] - (char *)
* The value of the parameter to set in the tag object
* Returns: void
* The parameter value is set in the tag object
*/
void
{
/* entry assertions */
/* entry debugging info */
/* if parameters exist, see if modifying existing parameter */
int k;
for (k = 0; k < tag->params_num; k++) {
/* if name does not match, skip */
continue;
}
/* found parameter - if value is same, leave alone */
return;
}
/* exists and has different value - change */
return;
}
}
/* not modifying existing - add new parameter */
tag->params_num++;
sizeof (SML_PARAM));
}
/*
* Name: smlParamEqF
* Description: Determine if parameter is equal to a specified formatted value
* Arguments: tag - [RO, *RO] - (SML_TAG *)
* The tag object to look for the parameter to compare
* findTag - [RO, *RO] - (char *)
* Tag within tag object to look for the parameter in
* findParam - [RO, *RO] - (char *)
* Parameter within tag to look for
* format - [RO, RO*] (char *)
* printf-style format for value to be compared against
* parameter value
* ... - [RO] (?)
* arguments as appropriate to 'format' specified to
* generate the value to compare parameter with
* Returns: boolean_t
* B_TRUE - the parameter exists and matches given value
* B_FALSE - parameter does not exist or does not match
*/
/*PRINTFLIKE4*/
{
char fbfr[1];
boolean_t b;
/* entry assertions */
/* determine size of the parameter value in bytes */
/* allocate storage to hold the message */
/* generate the parameter value and store it in the allocated storage */
/* add the parameter to the tag */
/* free up temporary storage and return */
return (b);
}
/*
* Name: smlParamEq
* Description: Determine if parameter is equal to a specified value
* Arguments: tag - [RO, *RO] - (SML_TAG *)
* The tag object to look for the parameter to compare
* findTag - [RO, *RO] - (char *)
* Tag within tag object to look for the parameter in
* findParam - [RO, *RO] - (char *)
* Parameter within tag to look for
* str - [RO, *RO] - (char *)
* Value to compare parameter with
* Returns: boolean_t
* B_TRUE - the parameter exists and matches given value
* B_FALSE - parameter does not exist or does not match
*/
{
char *rparm;
/* entry assertions */
/* look for the specified tag - if not found, return false */
if (rtag == SML_TAG__NULL) {
return (B_FALSE);
}
/* look for the specified parameter - if not found, return false */
return (B_FALSE);
}
/* parameter found - compare against given value */
/* free up parameter storage */
/* return results of comparison */
}
/*
* Name: smlFindAndDelTag
* Description: Delete a tag if found in tag object
* Arguments: tag - [RO, *RW] - (SML_TAG *)
* The tag object to delete the tag from
* findTag - [RO, *RO] - (char *)
* Tag within tag object to delete
* Returns: boolean_t
* B_TRUE - tag found and deleted
* B_FALSE - tag not found
*/
{
/* entry assertions */
/* find the specified tag - if not found, return false */
if (rtag == SML_TAG__NULL) {
return (B_FALSE);
}
/* tag found - delete it and return true */
return (B_TRUE);
}
/*
* Name: smlDup
* Description: Duplicate a tag object
* Arguments: tag - [RO, *RO] - (SML_TAG *)
* The tag object to duplicate
* Returns: SML_TAG *
* A handle to a complete duplicate of the tag provided
* NOTE: Any tag object returned is placed in new storage for the
* calling method. The caller must use 'smlFreeTag' to dispose
* of the storage once the tag object name is no longer needed.
* Errors: If the tag object cannot be duplicated, the process exits
*/
SML_TAG *
{
int i;
/* entry assertions */
/* allocate zeroed storage for the tag object */
/* duplicate all parameters of the tag */
for (i = 0; i < rtag->params_num; i++) {
(char *)NULL;
(char *)NULL;
}
}
/* duplicate all elements of the tag */
sizeof (SML_TAG));
}
}
/* exit assertions */
/* return */
return (rtag);
}
/*
* Name: smlSetFileStatInfo
* Description; Given a file status structure and path name, encode the
* structure and place it and the name into the specified tag
* in a "_sml_fileStatInfoTag" (private) element
* Arguments: tag - [RO, *RO] - (SML_TAG *)
* The tag object to deposit the information into
* statbuf - [RO, *RO] - (struct stat *)
* Pointer to file status structure to encode
* path - [RO, *RO] - (char *)
* Pointer to path name of file to encode
* Returns: void
* The information is placed into the specified tag object
*/
void
{
/* entry assertions */
/* if stat info exists, delete it */
/* create the file stat info inside of the top level tag */
== SML_TAG__NULL);
/* obtain handle on newly created file stat info tag */
/* add file info as parameters to the tag */
}
}
/*
* Name: smlFstatCompareEQ
* Description: Given a file status structure and path name, look for the
* information placed into a tag object via smlSetFileStatInfo
* and if present compare the encoded information with the
* arguments provided
* Arguments: statbuf - [RO, *RO] - (struct stat *)
* Pointer to file status structure to compare
* tag - [RO, *RO] - (SML_TAG *)
* The tag object to compare against
* path - [RO, *RO] - (char *)
* Pointer to path name of file to compare
* Returns: boolean_t
* B_TRUE - both status structures are identical
* B_FALSE - the status structures are not equal
*/
{
if (tag == SML_TAG__NULL) {
return (B_FALSE);
}
return (B_FALSE);
}
if (smlParamEq(tag,
return (B_FALSE);
}
}
return (B_FALSE);
}
return (B_FALSE);
}
return (B_FALSE);
}
return (B_FALSE);
}
return (B_FALSE);
}
return (B_TRUE);
}
/*
* Name: set_verbose
* Description: Turns on verbose output
* Scope: public
* Arguments: verbose = B_TRUE indicates verbose mode
* Returns: none
*/
void
{
}
/*
* Name: get_verbose
* Description: Returns whether or not to output verbose messages
* Scope: public
* Arguments: none
* Returns: B_TRUE - verbose messages should be output
*/
{
return (verbose);
}
/*
* Name: sml_strPrintf
* Synopsis: Create string from printf style format and arguments
* Description: Call to convert a printf style format and arguments into a
* string of characters placed in allocated storage
* Arguments: format - [RO, RO*] (char *)
* printf-style format for string to be formatted
* ... - [RO] (?)
* arguments as appropriate to 'format' specified
* Returns: char *
* A string representing the printf conversion results
* NOTE: Any string returned is placed in new storage for the
* calling method. The caller must use 'free' to dispose
* of the storage once the string is no longer needed.
* Errors: If the string cannot be created, the process exits
*/
/*PRINTFLIKE1*/
char *
sml_strPrintf(char *a_format, ...)
{
char bfr[1];
/* entry assertions */
/* determine size of the message in bytes */
/* allocate storage to hold the message */
/* generate the results of the printf conversion */
/* return the results */
return (rstr);
}
/*
* Name: sml_strPrintf_r
* Synopsis: Create string from printf style format and arguments
* Description: Call to convert a printf style format and arguments into a
* string of characters placed in allocated storage
* Arguments: a_buf - [RO, *RW] - (char *)
* - Pointer to buffer used as storage space for the
* returned string created
* a_bufLen - [RO, *RO] - (int)
* - Size of 'a_buf' in bytes - a maximum of 'a_bufLen-1'
* bytes will be placed in 'a_buf' - the returned
* string is always null terminated
* a_format - [RO, RO*] (char *)
* printf-style format for string to be formatted
* VARG_LIST - [RO] (?)
* arguments as appropriate to 'format' specified
* Returns: void
*/
/*PRINTFLIKE3*/
void
{
/* entry assertions */
/* generate the results of the printf conversion */
}
/*
* Name: sml_XmlEncodeString
* Description: Given a plain text string, convert that string into one that
* encoded using the XML character reference encoding format.
* Arguments: a_plain_text_string - [RO, *RO] (char *)
* The plain text string to convert (encode)
* Returns: char *
* The encoded form of the plain text string provided
* NOTE: Any string returned is placed in new storage for the
* calling method. The caller must use 'lu_memFree' to dispose
* of the storage once the string is no longer needed.
*/
char *
{
char *stringHead; /* -> start of string containing encoded data */
long stringTail; /* byte pos of first free byte in stringHead */
long stringLength; /* total bytes allocd starting at stringHead */
char *p; /* temp -> to retrieve bytes from src string */
long textLength = 0; /* length of the string to convert */
/* entry assertions */
/* Allocate initial string buffer to hold results */
stringTail = 0;
/* Add in the encoded message text */
/*
* Must have at least 12 bytes: this must be at least the
* maximum number of bytes that can be added for a single
* byte as the last byte of the stream. Assuming the byte
* needs to be encoded, it could be:
* &#xxxxxxxx;\0
* If not that many bytes left, grow the buffer.
*/
}
/*
* See if this byte is a 'printable 7-bit ascii value'.
* If so just add it to the new string; otherwise, must
* output an XML character value encoding for the byte.
*/
switch (*p) {
case '!':
case '#':
case '%':
case '\'':
case '(':
case ')':
case '*':
case '+':
case ',':
case '-':
case '.':
case '/':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case ':':
case ';':
case '<':
case '=':
case '>':
case '?':
case '@':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case '[':
case ']':
case '^':
case '_':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
case '{':
case '|':
case '}':
case '~':
case ' ':
/*
* It is a printable 7-bit ascii character:
* just add it to the end of the new string.
*/
stringHead[stringTail++] = *p;
break;
default:
/*
* It is not a printable 7-bit ascii character:
* add it as an xml character value encoding.
*/
(*p)&0xFF);
break;
}
}
/* Terminate the new string */
/* realloc the string so it is only as big as it needs to be */
return (stringHead);
}
/*
* Name: sml_XmlDecodeString
* Description: Given a string encoded using the XML character reference format,
* convert that string into a plain text (unencoded) string.
* Arguments: a_xml_encoded_string - [RO, *RO] (char *)
* The XML encoded string to convert to plain text
* Returns: char *
* The unencoded (plain text) form of the encoded string
* NOTE: Any string returned is placed in new storage for the
* calling method. The caller must use 'lu_memFree' to dispose
* of the storage once the string is no longer needed.
*/
char *
{
char *s = NULL; /* -> index into encoded bytes string */
char *d = NULL; /* -> index into decoded bytes string */
long textLength = 0; /* length of encoded string to decode */
unsigned long rv = 0; /* temp to hold scanf results of byte conv */
char *i = NULL; /* temp to hold strchr results */
/*
* A finite state machine is used to convert the xml encoded string
* into plain text. The states of the machine are defined below.
*/
#define fsms_text 0 /* Decoding plain text */
/* entry assertions */
/*
* Allocate string that can contain the decoded string.
* Since decoding always results in a shorter string (bytes encoded
* using the XML character reference are larger in the encoded form)
* we can allocate a string the same size as the encoded string.
*/
/*
* Convert all bytes.
*/
/* Decoding plain text */
s++, textLength--) {
switch (fsmsState) {
case fsms_text: /* Decoding plain text */
}
if (*s == '&') {
/* Found & */
continue;
}
*d++ = *s;
continue;
case fsms_seenAmp: /* Found & */
if (*s == '#') {
/* Found # following & */
continue;
}
*d++ = '&';
*d++ = *s;
continue;
case fsms_seenPound: /* Found # following & */
i = strchr(s, ';');
if (i == NULL) {
/* Decoding plain text */
*d++ = '&';
*d++ = '#';
*d++ = *s;
continue;
}
/* Collecting character reference bytes */
/*FALLTHRU*/
/* Collecting character reference bytes */
case fsms_collect:
if (*s != ';') {
switch (*s) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
*ri++ = *s;
break;
default:
*ri = '\0';
*d++ = '&';
*d++ = '#';
*d++ = *s;
/* Decoding plain text */
break;
}
continue;
}
*ri = '\0';
*d++ = '?';
} else {
*d++ = (rv & 0xFF);
}
/* Decoding plain text */
}
}
/* Done converting bytes - deallocate reference byte storage */
/* terminate the converted (plain text) string */
*d = '\0';
/* exit assertions */
return (stringHead);
}
/*
* Private Methods
*/
/*
* Name: _smlReadTag
* Description: read complete tag from a datastream
* Arguments: err - [RO, *RW] (LU_ERR)
* Error object - used to contain any errors encountered
* and return those errors to this methods caller
* r_tag - [RW, *RW] - (SML_TAG **)
* Pointer to handle to place new tag object
* == SML_TAG__NULL if empty tag found (not an error)
* ds - [RO, *RO] - (LU_DS)
* Handle to datastream to read tag from
* parent - [RO, *RO] - (char *)
* Name for parent of tag (NONE if top of tag)
* Returns: int
* RESULT_OK - tag successfully read
* RESULT_ERR - problem reading tag
* NOTE: Any tag object returned is placed in new storage for the
* calling method. The caller must use 'smlFreeTag' to dispose
* of the storage once the tag object name is no longer needed.
* Errors: If the tag object cannot be duplicated, the process exits
*/
static int
{
int r;
char name[MAX_SML_COMPONENT_LENGTH];
int pos = 0;
int c;
char *p = *a_str;
/* entry assertions */
/* entry debugging info */
/* reset return tag */
*r_tag = SML_TAG__NULL;
/* allocate zeroed storage for the tag object */
/* reset name accumulator storage */
/* ignore delimters before tag */
for (;;) {
if ((*p == '\0') || ((c = (*p++)) == '\0')) {
p ? p : "?");
*a_str = p;
return (RESULT_OK);
}
/* EOF in middle of processing tag */
p ? p : "?");
*a_str = p;
return (RESULT_ERR);
}
/* if beginning of tag, break out */
if (c == '<') {
break;
}
/* not tag beginning: ignore delimiters if not inside tag yet */
/* ignore delimters */
continue;
}
/* on blank lines, return no tag object */
if (c == '\n') {
p ? p : "?");
*a_str = p;
return (RESULT_OK);
}
/* invalid character before tag start */
c, (unsigned int)c);
*a_str = p;
return (RESULT_ERR);
}
}
/*
* all delimiters have been ignored and opening tag character seen;
* process tag
*/
assert(c == '<');
c = *p;
if (*p != '\0') {
p++;
}
/* handle EOF after tag opening character found */
if (c == '\0') {
*a_str = p;
return (RESULT_ERR);
}
/* is this a tag closure? */
if (c == '/') {
for (;;) {
/* get next character of tag name */
c = *p;
if (*p != '\0') {
p++;
}
/* EOF inside tag name? */
if (c == '\0') {
*a_str = p;
return (RESULT_ERR);
}
/* tag close: break out of collection loop */
if (c == '>') {
break;
}
/* see if illegal character in tag name */
/* CSTYLED */
if (strchr("/ \t\n\":<?$'\\`!@#%^&*()+=|[]{};,", c)
!= NULL) {
c, (unsigned int)c, name);
*a_str = p;
return (RESULT_ERR);
}
/* valid character - add to name if room left */
pos++;
}
}
/* close of tag found */
assert(c == '>');
/* is the tag empty? If so that's an error */
if (*name == '\0') {
*a_str = p;
return (RESULT_ERR);
}
/* if no parent, a close tag outside of any open tag */
name);
*a_str = p;
return (RESULT_ERR);
}
/* if not close to current parent, error */
*a_str = p;
return (RESULT_ERR);
}
/* close of current tag found - success */
name);
*a_str = p;
return (RESULT_OK);
}
/* not starting a close tag */
assert(c != '/');
assert(c != '<');
/* at start of tag - input tag name */
pos = 0;
for (;;) {
/* EOF inside of tag name? */
if (c == '\0') {
*a_str = p;
return (RESULT_ERR);
}
/* if separator or end of line then tag name collected */
break;
}
/* see if illegal character in tag name */
/*CSTYLED*/
c, (unsigned int)c, name);
*a_str = p;
return (RESULT_ERR);
}
/* close current tag? */
if (c == '/') {
/* get next character of tag name */
c = *p;
if (*p != '\0') {
p++;
}
/* tag close not found? */
if (c != '>') {
*a_str = p;
return (RESULT_ERR);
}
/* is the tag empty? If so that's an error */
if (*name == '\0') {
*a_str = p;
return (RESULT_ERR);
}
/* tag closed */
*a_str = p;
return (RESULT_OK);
}
/* valid character - add to name if room left */
pos++;
}
/* get next character to parse */
c = *p;
if (*p != '\0') {
p++;
}
}
/* have a valid tag name: <tagname */
/* place tag name inside of tag object */
/* clear out name accumulator to get parameters */
pos = 0;
/* input parameters */
if (c != '>')
for (;;) {
char *pname;
char *pvalue;
/* pass spaces before parameter name */
for (;;) {
/* get next character of parameter name */
c = *p;
if (*p != '\0') {
p++;
}
/* EOF inside parameter name? */
if (c == '\0') {
*a_str = p;
return (RESULT_ERR);
}
continue;
}
/* see if illegal character in parameter name */
/*CSTYLED*/
if (strchr("\":<?$'\\`!@#%^&*()+=|[]{};,.", c) !=
(char *)NULL) {
*a_str = p;
return (RESULT_ERR);
}
/* tag close found? */
if (c == '>') {
break;
}
/* close tag found ? */
if (c == '/') {
c = *p;
if (*p != '\0') {
p++;
}
if (c == '>') {
*a_str = p;
return (RESULT_OK);
}
/* / not followed by > */
*a_str = p;
return (RESULT_ERR);
}
/* valid character - add to name if room left */
pos++;
}
break;
}
if (c == '>') {
break;
}
/* input parameter name */
for (;;) {
c = *p;
if (*p != '\0') {
p++;
}
/* EOF inside of parameter name? */
if (c == '\0') {
*a_str = p;
return (RESULT_ERR);
}
/*CSTYLED*/
*a_str = p;
return (RESULT_ERR);
}
/* name - value separator found ? */
if (c == '=') {
break;
}
/* valid character - add to name if room left */
pos++;
}
}
/* is the parameter name empty? If so that's an error */
if (*name == '\0') {
*a_str = p;
return (RESULT_ERR);
}
/* have a parameter name */
/* duplicate (save) parameter name */
/* clear out name accumulator to get parameters */
pos = 0;
c = *p;
if (*p != '\0') {
p++;
}
if (c != '"') {
c, (unsigned int)c);
*a_str = p;
return (RESULT_ERR);
}
/* input parameter value */
for (;;) {
c = *p;
if (*p != '\0') {
p++;
}
/* EOF inside of parameter value? */
if (c == '\0') {
*a_str = p;
return (RESULT_ERR);
}
/* close of parameter value? */
if (c == '"') {
break;
}
*a_str = p;
return (RESULT_ERR);
}
/* valid character - add to value if room left */
pos++;
}
}
/* got the value */
pos = 0;
tag->params_num++;
sizeof (SML_PARAM));
if (c == '>') {
break;
}
}
/* finished processing this tag element entry */
sizeof (SML_TAG));
}
c = *p;
if (*p != '\0') {
p++;
}
*a_str = p;
return (r);
}
/*
* Name: _smlWriteParamValue
* Description: XML Encode a plain text parameter value and write to datastream
* Arguments: ds - [RO, *RO] - (LU_DS)
* Handle to datastream to write parameter value to
* value - [RO, *RO] - (char *)
* Parameter value to be encoded and written
* Returns: int
* RESULT_OK - tag successfully read
* RESULT_ERR - problem reading tag
*/
static int
{
char *ns;
char *p;
/* entry assertions */
/* xml encode the plain text string */
p = sml_XmlEncodeString(value);
/* write the xml encoded parameter value to the datastream */
/* free up xml encoded value storage */
free(p);
return (RESULT_ERR);
}
}
/* return results */
return (RESULT_OK);
}
static int
{
int r;
int k;
char *ns;
char *np0;
char *np1;
return (RESULT_OK);
}
}
if (tag->params_num == 0) {
return (RESULT_OK);
} else {
return (RESULT_ERR);
}
}
} else {
return (RESULT_ERR);
}
return (RESULT_ERR);
}
return (RESULT_ERR);
}
return (RESULT_ERR);
}
return (RESULT_ERR);
}
return (RESULT_ERR);
}
}
return (RESULT_ERR);
}
return (RESULT_ERR);
}
} else {
return (RESULT_ERR);
}
return (RESULT_ERR);
}
}
}
if (r != RESULT_OK) {
return (r);
}
}
return (RESULT_ERR);
}
return (RESULT_ERR);
}
}
return (RESULT_OK);
}
static void
{
int k;
/* entry assertions */
/* entry debugging info */
(unsigned long)tag,
for (k = 0; k < tag->params_num; k++) {
}
}
}
tag->params_num = 0;
}
}
}
/*
* Name: log_msg
* Description: Outputs messages to logging facility.
* Scope: public
* Arguments: type - the severity of the message
* out - where to output the message.
* fmt - the printf format, plus its arguments
* Returns: none
*/
/*PRINTFLIKE2*/
static void
{
char bfr[1];
char *prefix;
switch (a_type) {
case LOG_MSG_ERR:
default:
break;
case LOG_MSG_WRN:
break;
case LOG_MSG_INFO:
break;
case LOG_MSG_DEBUG:
if (!smlGetVerbose()) {
/* no debug messages if not verbose mode */
return;
}
break;
}
}
/* determine size of the message in bytes */
/* allocate storage to hold the message */
/* generate the results of the printf conversion */
/*
* nothing output, try stderr as a
* last resort
*/
}
}