xml.c revision a9fd9a9e12bea66c9ea9b31f4b6f0ef584933f59
/*
* 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 <stdio.h>
#include <unistd.h>
#include <inttypes.h>
#include <assert.h>
#include <libxml/xmlreader.h>
#include <strings.h>
#include <ctype.h>
#include <stdlib.h>
#include <syslog.h>
#include "iscsitgt_impl.h"
/*
* Forward declarations
*/
static char *strip_space(char *value);
static tgt_node_t *node_alloc();
static void node_free(tgt_node_t *x);
static void buf_add_node_attr(char **b, tgt_node_t *x);
static void buf_add_comment(char **b, char *comment);
static void buf_add_str(char **b, char *str);
#define XML_COMMENT_STR "!--"
#define XML_COMMENT_END "--"
void
{
tgt_node_t *c;
tgt_node_t *c1;
if (n == NULL)
return;
for (c = n->x_child; c; ) {
tgt_node_free(c);
c = c1;
}
for (c = n->x_attr; c; ) {
node_free(c);
c = c1;
}
node_free(n);
}
/*
* []----
* | 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.
* []----
*/
static void
{
int i;
tgt_node_t *c;
if (t == NULL)
return;
/*
* If this node has an attribute which indicates it's incore only
* we don't dump it out to a file.
*/
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);
}
}
/*
* tgt_dump2buf -- dumps node tree to buffer, allocating memory as it goes
*
* It is up to the caller, when finished with 'buf', to call free()
*/
void
{
tgt_node_t *c;
if (n == NULL)
return;
return;
}
buf_add_node_attr(buf, n);
tgt_dump2buf(c, buf);
}
char *common_attr_list[] = {
0
};
{
char **ap;
tgt_node_t *n;
tgt_node_t *an;
n = *node;
if (n == NULL) {
n = node_alloc();
if (n == NULL)
return (False);
*node = n;
}
node_free(n);
return (False);
}
if (node_type == XML_ELEMENT_NODE) {
n = node_child(n);
*node = n;
if (n == NULL)
return (False);
}
if (xmlTextReaderAttributeCount(r) > 0) {
return (False);
False) {
return (False);
}
False) {
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);
}
{
tgt_node_t *a;
return (False);
return (True);
}
return (False);
}
{
tgt_node_t *c;
return (False);
return (True);
}
return (True);
}
return (False);
}
{
tgt_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;
char 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.
*/
*value);
*value);
else
*value);
} else
else
return (rval);
} else
return (True);
}
{
tgt_node_t *c;
return (False);
return (False);
return (True);
}
return (True);
}
return (False);
}
{
tgt_node_t *x;
tgt_node_t *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);
}
void
{
return;
c->x_parent = p;
p->x_child = c;
else {
p->x_child = c;
}
}
void
{
return;
p->x_attr = a;
else {
p->x_attr = a;
}
}
{
tgt_node_t *d = node_alloc();
int value_len = 0;
if (d == NULL)
return (NULL);
switch (type) {
case String:
if (value)
break;
case Int:
break;
case Uint64:
break;
}
if (value_len &&
return (NULL);
return (NULL);
}
if (value_str) {
switch (type) {
case String:
(char *)value);
break;
case Int:
*(int *)value);
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);
}
{
tgt_node_t *s;
tgt_node_t *c = NULL;
return (False);
/*
* See if the new child node matches one of the children
* in the parent.
*/
} else {
}
tgt_node_free(s);
break;
}
}
if (s == NULL)
return (False);
else
return (True);
}
void
{
tgt_node_t *s;
tgt_node_t *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) {
tgt_node_free(s->x_child);
}
(void) tgt_node_add(s, tgt_node_dup(c));
break;
}
}
if (s == NULL) {
/*
* Never found the child so add it
*/
}
}
{
return (False);
return (True);
}
{
break;
return (rval);
}
{
tgt_node_t *d = node_alloc();
tgt_node_t *c;
if (d == NULL)
return (NULL);
return (NULL);
return (NULL);
(void) tgt_node_add(d, tgt_node_dup(c));
(void) tgt_node_add_attr(d, tgt_node_dup(c));
return (d);
}
void
{
}
/*
* []----
* | tgt_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);
}
/*
* []----
* | tgt_buf_add_tag_and_attr -- variant on tgt_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);
}
/*
* []----
* | Utility functions
* []----
*/
static tgt_node_t *
{
if (x == NULL)
return (NULL);
return (x);
}
static void
node_free(tgt_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 tgt_node_t *
{
return (x->x_parent);
}
static tgt_node_t *
node_child(tgt_node_t *x)
{
tgt_node_t *n;
if ((n = node_alloc()) == NULL)
return (NULL);
x->x_child = n;
} else {
x->x_child = n;
}
n->x_parent = x;
return (n);
}
static tgt_node_t *
{
tgt_node_t *n;
n = node_alloc();
x->x_attr = n;
} else {
;
}
if (n != NULL)
n->x_parent = x;
return (n);
}
static void
buf_add_str(char **b, char *str)
{
int len;
int 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) {
return;
} else {
}
*b = p;
}
static void
buf_add_node_attr(char **b, tgt_node_t *x)
{
char *buf;
tgt_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, ">");
}
static void
buf_add_comment(char **b, char *comment)
{
char *p = *b;
int len;
int olen;
return;
/*
* Room for the strings, plus the brackets and NULL byte
*/
if (p == NULL)
else {
}
*b = p;
}
static char *
strip_space(char *value)
{
char *p;
char *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);
}