xml.c revision 36c5fee33fa8b822175d410202aebcf592c8d342
/*
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <inttypes.h>
#include <assert.h>
#include <libxml/xmlreader.h>
#include <strings.h>
#include <ctype.h>
#include <stdlib.h>
#include <syslog.h>
#include "xml.h"
/*
* Forward declarations
*/
static char *strip_space(char *value);
static xml_node_t *node_alloc();
static void node_free(xml_node_t *x);
#define XML_COMMENT_STR "!--"
#define XML_COMMENT_END "--"
void
{
xml_node_t *c,
*c1;
if (n == NULL)
return;
for (c = n->x_child; c; ) {
xml_tree_free(c);
c = c1;
}
for (c = n->x_attr; c; ) {
node_free(c);
c = c1;
}
node_free(n);
}
void
{
int i;
xml_node_t *c;
if (n == NULL)
return;
for (i = 0; i < depth; i++)
(void) printf(" ");
c->x_value,
} else {
}
} else if (n->x_name) {
if (c != n->x_attr)
(void) printf(" ");
c->x_value);
}
(void) printf(")...\n");
} else
}
}
void
{
xml_node_t *c;
if (n == NULL)
return;
return;
}
buf_add_node_attr(buf, n);
xml_walk_to_buf(c, buf);
}
/*
* []----
* | xml_update_config -- dump out in core node tree to XML parsable file
* |
* | The depth argument is only used to pad the output with white space
* | for indentation. This is meant to help the readability of the file
* | for humans.
* []----
*/
void
{
int i;
xml_node_t *c;
if (t == NULL)
return;
for (i = 0; i < depth; i++)
t->x_value, XML_COMMENT_END);
return;
}
t->x_name);
} else {
c->x_value);
if (t->x_value) {
for (i = 0; i < depth + 1; i++)
}
for (i = 0; i < depth; i++)
}
}
{
return (False);
} else {
/*
* Make sure only root can access the file since we're
* optionally keeping CHAP secrets located here.
*/
return (True);
}
}
char *common_attr_list[] = {
"name",
"version",
0
};
{
*value;
char **ap;
xml_node_t *n,
*an;
n = *node;
if (n == NULL) {
n = node_alloc();
if (n == NULL)
return (False);
*node = n;
}
node_free(n);
return (False);
}
if (xmlTextReaderAttributeCount(r) > 0) {
return (False);
return (False);
}
return (False);
}
}
}
}
if (node_type == XML_ELEMENT_NODE) {
n = node_child(n);
*node = n;
if (n == NULL)
return (False);
}
node_free(n);
return (False);
}
node_free(n);
return (False);
}
} else if (node_type == XML_ELEMENT_DECL) {
n = node_parent(n);
if (n == NULL)
return (False);
*node = n;
} else if (node_type == XML_COMMENT_NODE) {
n = node_child(n);
node_free(n);
return (False);
}
node_free(n);
return (False);
}
} else if (node_type != XML_DTD_NODE) {
node_free(n);
return (False);
}
return (True);
}
{
xml_node_t *a;
return (False);
return (True);
}
return (False);
}
{
xml_node_t *c;
return (False);
return (True);
}
return (True);
}
return (False);
}
{
xml_node_t *c;
return (False);
return (False);
return (True);
}
return (True);
}
return (False);
}
/*
* []----
* | xml_find_value_intchk -- if node exists, check to see if value is okay
* []----
*/
{
char *str,
chk[32];
/*
* Validate that the input string hasn't overrun what
* what an integer can handle. This is done by simply
* printing out the result of the conversion into a buffer
* and comparing it to the incoming string. That way when
* someone enters 4294967296 which strtol returns as 0
* we'll catch it.
*/
else
} else
else
return (rval);
} else
return (True);
}
{
xml_node_t *c;
return (False);
return (False);
return (True);
}
return (True);
}
return (False);
}
{
xml_node_t *x,
*p;
if (n == NULL)
return (NULL);
return (x);
return (NULL);
}
return (NULL);
return (n);
return (p);
return (NULL);
}
{
} else {
if (n != NULL)
n = n->x_child;
else
return (NULL);
}
while (n) {
return (n);
n = n->x_sibling;
}
return (NULL);
}
{
xml_node_t *s;
return (False);
p->x_child = c;
else {
;
s->x_sibling = c;
}
return (True);
}
{
xml_node_t *d = node_alloc();
int value_len;
char *value_str;
if (d == NULL)
return (NULL);
switch (type) {
case String:
break;
case Int:
break;
case Uint64:
break;
}
return (NULL);
return (NULL);
}
switch (type) {
case String:
break;
case Int:
break;
case Uint64:
break;
}
return (d);
}
{
char *bp;
*buf_size = 0;
return (False);
}
ip++;
bp += 2;
}
return (True);
}
{
uint8_t *i;
*ip_size = 0;
return (False);
}
char x[3];
x[2] = 0;
buf += 2;
}
return (True);
}
void
{
}
{
xml_node_t *s,
*c = NULL;
return (False);
/*
* See if the new child node matches one of the children
* in the parent.
*/
} else {
}
xml_tree_free(s);
break;
}
}
if (s == NULL)
return (False);
else
return (True);
}
void
{
xml_node_t *s,
*c;
return;
/*
* See if the new child node matches one of the children
* in the parent.
*/
/*
* We have a match. Now save the values of the new
* child in this current node.
*/
if (s->x_child) {
xml_tree_free(s->x_child);
}
(void) xml_add_child(s, xml_node_dup(c));
break;
}
}
if (s == NULL) {
/*
* Never found the child so add it
*/
}
}
#ifdef notused
/*
* Update node value when value type is usigned long long
*/
{
return (False);
return (True);
return (True);
}
#endif
{
return (False);
return (True);
}
{
break;
return (rval);
}
{
xml_node_t *d = node_alloc(),
*c;
if (d == NULL)
return (NULL);
return (NULL);
return (NULL);
(void) xml_add_child(d, xml_node_dup(c));
return (d);
}
/*
* []----
* | Utility functions
* []----
*/
static xml_node_t *
{
if (x == NULL)
return (NULL);
return (x);
}
static void
node_free(xml_node_t *x)
{
if (x->x_name)
if (x->x_value)
free(x);
}
static Boolean_t
{
return (False);
x->x_name = strip_space((char *)n);
return (True);
}
static Boolean_t
{
return (False);
strip_space((char *)n) : strdup((char *)n);
return (True);
}
static xml_node_t *
{
return (x->x_parent);
}
static xml_node_t *
node_child(xml_node_t *x)
{
xml_node_t *n,
*next;
n = node_alloc();
x->x_child = n;
} else {
;
}
if (n != NULL)
n->x_parent = x;
return (n);
}
static xml_node_t *
{
xml_node_t *n,
*next;
n = node_alloc();
x->x_attr = n;
} else {
;
}
if (n != NULL)
n->x_parent = x;
return (n);
}
void
buf_add_str(char **b, char *str)
{
int len,
olen = 0;
char *p = *b;
/*
* Make sure we have enough room for the string and tag characters
* plus a NULL byte.
*/
return;
if (p == NULL) {
} else {
}
*b = p;
}
/*
* []----
* | buf_add_tag -- adds string to buffer allocating space, sets up tags too
* |
* | Helper function to build a string by allocating memory as we go.
* | If the string argument 'str' is defined to be a start or end tag
* | as declared by 'type' argument add the appropriate characters.
* []----
*/
void
{
char *buf;
int len;
/*
* We will add potentially up to 3 extra characters plus the NULL byte
*/
return;
buf_add_str(b, buf);
}
/*
* []----
* | buf_add_tag_and_attr -- variant on buf_add_tag which also gives attr
* []----
*/
void
{
char *buf;
int len;
/*
* In addition to the 'str' and 'attr' strings the code will add
* three characters plus a null byte.
*/
return;
buf_add_str(b, buf);
}
void
buf_add_node_attr(char **b, xml_node_t *x)
{
char *buf;
xml_node_t *n;
int len;
/* ---- null byte and starting '<' character ---- */
return;
buf_add_str(b, buf);
return;
buf_add_str(b, buf);
}
buf_add_str(b, ">");
}
void
xml_add_comment(char **b, char *comment)
{
char *p = *b;
int len,
olen;
return;
/*
* Room for the strings, plus the brackets and NULL byte
*/
if (p == NULL)
else {
}
*b = p;
}
void
{
}
static char *
strip_space(char *value)
{
char *p,
*n;
for (p = value; p && *p; p++)
if (!isspace(*p))
break;
if ((p == NULL) || (*p == '\0'))
return (NULL);
p = strdup(p);
for (n = (p + strlen(p) - 1); n >= p; n--)
if (!isspace(*n)) {
n++;
break;
}
*n = '\0';
return (p);
}