xref: /onnv-gate/usr/src/cmd/isns/isnsd/xml/data.c (revision 10152:71b1112ff1d3)
17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
217836SJohn.Forte@Sun.COM 
227836SJohn.Forte@Sun.COM /*
23*10152Swl202157@icefox  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247836SJohn.Forte@Sun.COM  * Use is subject to license terms.
257836SJohn.Forte@Sun.COM  */
267836SJohn.Forte@Sun.COM 
277836SJohn.Forte@Sun.COM #include <stdio.h>
287836SJohn.Forte@Sun.COM #include <stdlib.h>
297836SJohn.Forte@Sun.COM #include <unistd.h>
307836SJohn.Forte@Sun.COM #include <libgen.h>
317836SJohn.Forte@Sun.COM #include <string.h>
327836SJohn.Forte@Sun.COM #include <sys/types.h>
337836SJohn.Forte@Sun.COM #include <sys/stat.h>
347836SJohn.Forte@Sun.COM #include <sys/socket.h>
357836SJohn.Forte@Sun.COM #include <netinet/in.h>
367836SJohn.Forte@Sun.COM #include <arpa/inet.h>
377836SJohn.Forte@Sun.COM #include <errno.h>
387836SJohn.Forte@Sun.COM #include <fcntl.h>
397836SJohn.Forte@Sun.COM #include <libxml/parser.h>
407836SJohn.Forte@Sun.COM #include <libxml/xpath.h>
417836SJohn.Forte@Sun.COM 
427836SJohn.Forte@Sun.COM #include "isns_server.h"
437836SJohn.Forte@Sun.COM #include "isns_obj.h"
447836SJohn.Forte@Sun.COM #include "isns_log.h"
457836SJohn.Forte@Sun.COM 
467836SJohn.Forte@Sun.COM /*
477836SJohn.Forte@Sun.COM  * external variables
487836SJohn.Forte@Sun.COM  */
497836SJohn.Forte@Sun.COM extern const int NUM_OF_ATTRS[MAX_OBJ_TYPE_FOR_SIZE];
507836SJohn.Forte@Sun.COM extern const int TYPE_OF_PARENT[MAX_OBJ_TYPE_FOR_SIZE];
517836SJohn.Forte@Sun.COM extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE];
527836SJohn.Forte@Sun.COM 
537836SJohn.Forte@Sun.COM extern char data_store[MAXPATHLEN];
547836SJohn.Forte@Sun.COM 
557836SJohn.Forte@Sun.COM /*
567836SJohn.Forte@Sun.COM  * local variables
577836SJohn.Forte@Sun.COM  */
587836SJohn.Forte@Sun.COM static xmlDocPtr xml_doc = NULL;
597836SJohn.Forte@Sun.COM static char *xml_file = NULL;
607836SJohn.Forte@Sun.COM static char *xml_tmp_file = NULL;
617836SJohn.Forte@Sun.COM static char *xml_bak_file = NULL;
627836SJohn.Forte@Sun.COM 
637836SJohn.Forte@Sun.COM static const int OBJ_DTD_ORDER[MAX_OBJ_TYPE_FOR_SIZE] = {
647836SJohn.Forte@Sun.COM 	0,
657836SJohn.Forte@Sun.COM 	1,	/* OBJ_ENTITY */
667836SJohn.Forte@Sun.COM 	2,	/* OBJ_ISCSI */
677836SJohn.Forte@Sun.COM 	3,	/* OBJ_PORTAL */
687836SJohn.Forte@Sun.COM 	4,	/* OBJ_PG */
697836SJohn.Forte@Sun.COM 	5,	/* OBJ_DD */
707836SJohn.Forte@Sun.COM 	6,	/* OBJ_DDS */
717836SJohn.Forte@Sun.COM 	0,	/* MAX_OBJ_TYPE */
727836SJohn.Forte@Sun.COM 	0,	/* OBJ_DUMMY1 */
737836SJohn.Forte@Sun.COM 	0,	/* OBJ_DUMMY2 */
747836SJohn.Forte@Sun.COM 	0,	/* OBJ_DUMMY3 */
757836SJohn.Forte@Sun.COM 	0,	/* OBJ_DUMMY4 */
767836SJohn.Forte@Sun.COM 	12,	/* OBJ_ASSOC_ISCSI */
777836SJohn.Forte@Sun.COM 	14,	/* OBJ_ASSOC_DD */
787836SJohn.Forte@Sun.COM };
797836SJohn.Forte@Sun.COM 
807836SJohn.Forte@Sun.COM #define	DEF_XML_ROOT(ISNS_DATA, VENDOR, SMI, VERSION, ONE_DOT_O) \
817836SJohn.Forte@Sun.COM 	(xmlChar *)ISNS_DATA, \
827836SJohn.Forte@Sun.COM 	(xmlChar *)VENDOR, \
837836SJohn.Forte@Sun.COM 	(xmlChar *)SMI, \
847836SJohn.Forte@Sun.COM 	(xmlChar *)VERSION, \
857836SJohn.Forte@Sun.COM 	(xmlChar *)ONE_DOT_O
867836SJohn.Forte@Sun.COM static const xmlChar *xml_root[] = {
877836SJohn.Forte@Sun.COM #include "data.def"
887836SJohn.Forte@Sun.COM };
897836SJohn.Forte@Sun.COM 
907836SJohn.Forte@Sun.COM #define	DEF_XML_DATA(TAG, TYPE, ARG1, ARG2) (xmlChar *)TAG,
917836SJohn.Forte@Sun.COM static const xmlChar* xmlTag[] = {
927836SJohn.Forte@Sun.COM #include "data.def"
937836SJohn.Forte@Sun.COM };
947836SJohn.Forte@Sun.COM 
957836SJohn.Forte@Sun.COM #define	DEF_XML_DATA(TAG, TYPE, ARG1, ARG2) TYPE,
967836SJohn.Forte@Sun.COM static const char *xmlType[] = {
977836SJohn.Forte@Sun.COM #include "data.def"
987836SJohn.Forte@Sun.COM };
997836SJohn.Forte@Sun.COM 
1007836SJohn.Forte@Sun.COM #define	DEF_XML_DATA(TAG, TYPE, ARG1, ARG2) ARG1,
1017836SJohn.Forte@Sun.COM static const int xmlArg1[] = {
1027836SJohn.Forte@Sun.COM #include "data.def"
1037836SJohn.Forte@Sun.COM };
1047836SJohn.Forte@Sun.COM 
1057836SJohn.Forte@Sun.COM #define	DEF_XML_DATA(TAG, TYPE, ARG1, ARG2) ARG2,
1067836SJohn.Forte@Sun.COM static const int xmlArg2[] = {
1077836SJohn.Forte@Sun.COM #include "data.def"
1087836SJohn.Forte@Sun.COM };
1097836SJohn.Forte@Sun.COM 
1107836SJohn.Forte@Sun.COM #define	DEF_XML_PROP(INDEX, TYPE, NAME, TAG, ID) TYPE,
1117836SJohn.Forte@Sun.COM static const unsigned char xmlPropType[] = {
1127836SJohn.Forte@Sun.COM #include "data.def"
1137836SJohn.Forte@Sun.COM };
1147836SJohn.Forte@Sun.COM 
1157836SJohn.Forte@Sun.COM #define	DEF_XML_PROP(INDEX, TYPE, NAME, TAG, ID) (xmlChar *)NAME,
1167836SJohn.Forte@Sun.COM static const xmlChar *xmlPropName[] = {
1177836SJohn.Forte@Sun.COM #include "data.def"
1187836SJohn.Forte@Sun.COM };
1197836SJohn.Forte@Sun.COM 
1207836SJohn.Forte@Sun.COM #define	DEF_XML_PROP(INDEX, TYPE, NAME, TAG, ID) TAG,
1217836SJohn.Forte@Sun.COM static const int xmlPropTag[] = {
1227836SJohn.Forte@Sun.COM #include "data.def"
1237836SJohn.Forte@Sun.COM };
1247836SJohn.Forte@Sun.COM 
1257836SJohn.Forte@Sun.COM #define	DEF_XML_PROP(INDEX, TYPE, NAME, TAG, ID) ID,
1267836SJohn.Forte@Sun.COM static const int xmlPropID[] = {
1277836SJohn.Forte@Sun.COM #include "data.def"
1287836SJohn.Forte@Sun.COM };
1297836SJohn.Forte@Sun.COM 
1307836SJohn.Forte@Sun.COM #define	ARRAY_LENGTH(ARRAY) (sizeof (ARRAY) / sizeof (ARRAY[0]))
1317836SJohn.Forte@Sun.COM 
1327836SJohn.Forte@Sun.COM /*
1337836SJohn.Forte@Sun.COM  * ****************************************************************************
1347836SJohn.Forte@Sun.COM  *
1357836SJohn.Forte@Sun.COM  * get_index_by_name:
1367836SJohn.Forte@Sun.COM  *	find the index in the global tables for the name of an attribute.
1377836SJohn.Forte@Sun.COM  *
1387836SJohn.Forte@Sun.COM  * name - the name of an attribute.
1397836SJohn.Forte@Sun.COM  * return - index or -1 for error.
1407836SJohn.Forte@Sun.COM  *
1417836SJohn.Forte@Sun.COM  * ****************************************************************************
1427836SJohn.Forte@Sun.COM  */
1437836SJohn.Forte@Sun.COM static int
get_index_by_name(const xmlChar * name)1447836SJohn.Forte@Sun.COM get_index_by_name(
1457836SJohn.Forte@Sun.COM 	const xmlChar *name
1467836SJohn.Forte@Sun.COM )
1477836SJohn.Forte@Sun.COM {
1487836SJohn.Forte@Sun.COM 	int i;
1497836SJohn.Forte@Sun.COM 	for (i = 0; i < ARRAY_LENGTH(xmlTag); i++) {
1507836SJohn.Forte@Sun.COM 		if (xmlStrEqual(xmlTag[i], name)) {
1517836SJohn.Forte@Sun.COM 			return (i);
1527836SJohn.Forte@Sun.COM 		}
1537836SJohn.Forte@Sun.COM 	}
1547836SJohn.Forte@Sun.COM 	return (-1);
1557836SJohn.Forte@Sun.COM }
1567836SJohn.Forte@Sun.COM 
1577836SJohn.Forte@Sun.COM /*
1587836SJohn.Forte@Sun.COM  * ****************************************************************************
1597836SJohn.Forte@Sun.COM  *
1607836SJohn.Forte@Sun.COM  * get_index_by_otype:
1617836SJohn.Forte@Sun.COM  *	find the index in the global tables for the type of an object.
1627836SJohn.Forte@Sun.COM  *
1637836SJohn.Forte@Sun.COM  * name - the type of an object.
1647836SJohn.Forte@Sun.COM  * return - index or -1 for error.
1657836SJohn.Forte@Sun.COM  *
1667836SJohn.Forte@Sun.COM  * ****************************************************************************
1677836SJohn.Forte@Sun.COM  */
1687836SJohn.Forte@Sun.COM static int
get_index_by_otype(int otype)1697836SJohn.Forte@Sun.COM get_index_by_otype(
1707836SJohn.Forte@Sun.COM 	int otype
1717836SJohn.Forte@Sun.COM )
1727836SJohn.Forte@Sun.COM {
1737836SJohn.Forte@Sun.COM 	int i;
1747836SJohn.Forte@Sun.COM 	for (i = 0; i < ARRAY_LENGTH(xmlTag); i++) {
1757836SJohn.Forte@Sun.COM 		if (xmlArg1[i] == otype && xmlType[i][0] == 'o') {
1767836SJohn.Forte@Sun.COM 			return (i);
1777836SJohn.Forte@Sun.COM 		}
1787836SJohn.Forte@Sun.COM 	}
1797836SJohn.Forte@Sun.COM 	return (-1);
1807836SJohn.Forte@Sun.COM }
1817836SJohn.Forte@Sun.COM 
1827836SJohn.Forte@Sun.COM /*
1837836SJohn.Forte@Sun.COM  * ****************************************************************************
1847836SJohn.Forte@Sun.COM  *
1857836SJohn.Forte@Sun.COM  * get_index_by_tag:
1867836SJohn.Forte@Sun.COM  *	find the index in the global tables for the tag of an attribute.
1877836SJohn.Forte@Sun.COM  *
1887836SJohn.Forte@Sun.COM  * name - the tag of an attribute.
1897836SJohn.Forte@Sun.COM  * return - index or -1 for error.
1907836SJohn.Forte@Sun.COM  *
1917836SJohn.Forte@Sun.COM  * ****************************************************************************
1927836SJohn.Forte@Sun.COM  */
1937836SJohn.Forte@Sun.COM static int
get_index_by_tag(int tag)1947836SJohn.Forte@Sun.COM get_index_by_tag(
1957836SJohn.Forte@Sun.COM 	int tag
1967836SJohn.Forte@Sun.COM )
1977836SJohn.Forte@Sun.COM {
1987836SJohn.Forte@Sun.COM 	int i;
1997836SJohn.Forte@Sun.COM 	for (i = 0; i < ARRAY_LENGTH(xmlTag); i++) {
2007836SJohn.Forte@Sun.COM 		if (xmlArg1[i] == tag &&
2017836SJohn.Forte@Sun.COM 		    xmlType[i][0] != 'o' &&
2027836SJohn.Forte@Sun.COM 		    xmlType[i][0] != 'a') {
2037836SJohn.Forte@Sun.COM 			return (i);
2047836SJohn.Forte@Sun.COM 		}
2057836SJohn.Forte@Sun.COM 	}
2067836SJohn.Forte@Sun.COM 	return (-1);
2077836SJohn.Forte@Sun.COM }
2087836SJohn.Forte@Sun.COM 
2097836SJohn.Forte@Sun.COM /*
2107836SJohn.Forte@Sun.COM  * ****************************************************************************
2117836SJohn.Forte@Sun.COM  *
2127836SJohn.Forte@Sun.COM  * get_xml_doc:
2137836SJohn.Forte@Sun.COM  *	open the xml file and assign the global xml doc if the xml file
2147836SJohn.Forte@Sun.COM  *	is not opened, set the doc pointer with the opened xml file for
2157836SJohn.Forte@Sun.COM  *	returnning.
2167836SJohn.Forte@Sun.COM  *
2177836SJohn.Forte@Sun.COM  * docp - the doc pointer for returning.
2187836SJohn.Forte@Sun.COM  * return - error code.
2197836SJohn.Forte@Sun.COM  *
2207836SJohn.Forte@Sun.COM  * ****************************************************************************
2217836SJohn.Forte@Sun.COM  */
2227836SJohn.Forte@Sun.COM static int
get_xml_doc(xmlDocPtr * docp)2237836SJohn.Forte@Sun.COM get_xml_doc(
2247836SJohn.Forte@Sun.COM 	xmlDocPtr *docp
2257836SJohn.Forte@Sun.COM )
2267836SJohn.Forte@Sun.COM {
2277836SJohn.Forte@Sun.COM 	int ec = 0;
2287836SJohn.Forte@Sun.COM 
2297836SJohn.Forte@Sun.COM 	if (xml_doc == NULL) {
2307836SJohn.Forte@Sun.COM 		/* validate the xml file */
2317836SJohn.Forte@Sun.COM 
2327836SJohn.Forte@Sun.COM 		/* open the xml file */
2337836SJohn.Forte@Sun.COM 		xml_doc = xmlParseFile(xml_file);
2347836SJohn.Forte@Sun.COM 	}
2357836SJohn.Forte@Sun.COM 
2367836SJohn.Forte@Sun.COM 	*docp = xml_doc;
2377836SJohn.Forte@Sun.COM 
2387836SJohn.Forte@Sun.COM 	if (xml_doc == NULL) {
2397836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
2407836SJohn.Forte@Sun.COM 	}
2417836SJohn.Forte@Sun.COM 
2427836SJohn.Forte@Sun.COM 	return (ec);
2437836SJohn.Forte@Sun.COM }
2447836SJohn.Forte@Sun.COM 
2457836SJohn.Forte@Sun.COM /*
2467836SJohn.Forte@Sun.COM  * ****************************************************************************
2477836SJohn.Forte@Sun.COM  *
2487836SJohn.Forte@Sun.COM  * close_xml_doc:
2497836SJohn.Forte@Sun.COM  *	close the global xml doc and ignore any changes that has been
2507836SJohn.Forte@Sun.COM  *	made in it.
2517836SJohn.Forte@Sun.COM  *
2527836SJohn.Forte@Sun.COM  * ****************************************************************************
2537836SJohn.Forte@Sun.COM  */
2547836SJohn.Forte@Sun.COM static void
close_xml_doc()2557836SJohn.Forte@Sun.COM close_xml_doc(
2567836SJohn.Forte@Sun.COM )
2577836SJohn.Forte@Sun.COM {
2587836SJohn.Forte@Sun.COM 	if (xml_doc) {
2597836SJohn.Forte@Sun.COM 		/* just close it */
2607836SJohn.Forte@Sun.COM 		xmlFreeDoc(xml_doc);
2617836SJohn.Forte@Sun.COM 		xml_doc = NULL;
2627836SJohn.Forte@Sun.COM 	}
2637836SJohn.Forte@Sun.COM }
2647836SJohn.Forte@Sun.COM 
2657836SJohn.Forte@Sun.COM /*
2667836SJohn.Forte@Sun.COM  * ****************************************************************************
2677836SJohn.Forte@Sun.COM  *
2687836SJohn.Forte@Sun.COM  * convert_xml2attr:
2697836SJohn.Forte@Sun.COM  *	convert a xml data to a TLV format isns attribute.
2707836SJohn.Forte@Sun.COM  *
2717836SJohn.Forte@Sun.COM  * tag - the tag of attribute.
2727836SJohn.Forte@Sun.COM  * type - the data type of the xml data.
2737836SJohn.Forte@Sun.COM  * value - the xml data.
2747836SJohn.Forte@Sun.COM  * attr - TLV format attribute for returning.
2757836SJohn.Forte@Sun.COM  * return - error code.
2767836SJohn.Forte@Sun.COM  *
2777836SJohn.Forte@Sun.COM  * ****************************************************************************
2787836SJohn.Forte@Sun.COM  */
2797836SJohn.Forte@Sun.COM static int
convert_xml2attr(const int tag,const unsigned char type,xmlChar * value,isns_attr_t * attr)2807836SJohn.Forte@Sun.COM convert_xml2attr(
2817836SJohn.Forte@Sun.COM 	const int tag,
2827836SJohn.Forte@Sun.COM 	const unsigned char type,
2837836SJohn.Forte@Sun.COM 	xmlChar *value,
2847836SJohn.Forte@Sun.COM 	isns_attr_t *attr
2857836SJohn.Forte@Sun.COM )
2867836SJohn.Forte@Sun.COM {
2877836SJohn.Forte@Sun.COM 	uint32_t len;
2887836SJohn.Forte@Sun.COM 	int ec = 0;
2897836SJohn.Forte@Sun.COM 
2907836SJohn.Forte@Sun.COM 	attr->tag = tag;
2917836SJohn.Forte@Sun.COM 	switch (type) {
2927836SJohn.Forte@Sun.COM 		case 'u':
2937836SJohn.Forte@Sun.COM 			/* 4-bytes non-negative integer */
2947836SJohn.Forte@Sun.COM 			attr->len = 4;
2957836SJohn.Forte@Sun.COM 			attr->value.ui = atoi((const char *)value);
2967836SJohn.Forte@Sun.COM 			break;
2977836SJohn.Forte@Sun.COM 		case 's':
2987836SJohn.Forte@Sun.COM 			/* literal string */
2997836SJohn.Forte@Sun.COM 			len = strlen((char *)value);
3007836SJohn.Forte@Sun.COM 			len += 4 - (len % 4);
3017836SJohn.Forte@Sun.COM 			attr->len = len;
3027836SJohn.Forte@Sun.COM 			attr->value.ptr = (uchar_t *)malloc(attr->len);
3037836SJohn.Forte@Sun.COM 			if (attr->value.ptr != NULL) {
3047836SJohn.Forte@Sun.COM 				(void) strcpy((char *)attr->value.ptr,
3057836SJohn.Forte@Sun.COM 				    (char *)value);
3067836SJohn.Forte@Sun.COM 			} else {
3077836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_INTERNAL_ERROR;
3087836SJohn.Forte@Sun.COM 			}
3097836SJohn.Forte@Sun.COM 			break;
3107836SJohn.Forte@Sun.COM 		case 'p':
3117836SJohn.Forte@Sun.COM 			/* IPv6 block data */
3127836SJohn.Forte@Sun.COM 			attr->len = sizeof (in6_addr_t);
3137836SJohn.Forte@Sun.COM 			attr->value.ip = (in6_addr_t *)malloc(attr->len);
3147836SJohn.Forte@Sun.COM 			if (attr->value.ip != NULL) {
3157836SJohn.Forte@Sun.COM 				(void) inet_pton(AF_INET6,
3167836SJohn.Forte@Sun.COM 				    (char *)value,
3177836SJohn.Forte@Sun.COM 				    attr->value.ip);
3187836SJohn.Forte@Sun.COM 			} else {
3197836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_INTERNAL_ERROR;
3207836SJohn.Forte@Sun.COM 			}
3217836SJohn.Forte@Sun.COM 			break;
3227836SJohn.Forte@Sun.COM 		default:
3237836SJohn.Forte@Sun.COM 			break;
3247836SJohn.Forte@Sun.COM 	}
3257836SJohn.Forte@Sun.COM 
3267836SJohn.Forte@Sun.COM 	return (ec);
3277836SJohn.Forte@Sun.COM }
3287836SJohn.Forte@Sun.COM 
3297836SJohn.Forte@Sun.COM /*
3307836SJohn.Forte@Sun.COM  * ****************************************************************************
3317836SJohn.Forte@Sun.COM  *
3327836SJohn.Forte@Sun.COM  * convert_attr2xml:
3337836SJohn.Forte@Sun.COM  *	convert a TLV format isns attribute to xml node format.
3347836SJohn.Forte@Sun.COM  *
3357836SJohn.Forte@Sun.COM  * node - the xml node where the new node is being added to.
3367836SJohn.Forte@Sun.COM  * attr - the TLV format attribute.
3377836SJohn.Forte@Sun.COM  * name - the name of the attribute in xml node.
3387836SJohn.Forte@Sun.COM  * type - the data type of the attribute.
3397836SJohn.Forte@Sun.COM  * elm_flag - 0: adding a xml attlist.
3407836SJohn.Forte@Sun.COM  *	      1: adding a xml child node.
3417836SJohn.Forte@Sun.COM  *	      2: adding a previous sibling node.
3427836SJohn.Forte@Sun.COM  *	      3: adding a xml content node.
3437836SJohn.Forte@Sun.COM  *	      4: adding a xml attribute.
3447836SJohn.Forte@Sun.COM  * return - xml node.
3457836SJohn.Forte@Sun.COM  *
3467836SJohn.Forte@Sun.COM  * ****************************************************************************
3477836SJohn.Forte@Sun.COM  */
3487836SJohn.Forte@Sun.COM static xmlNodePtr
convert_attr2xml(xmlNodePtr node,const isns_attr_t * attr,const xmlChar * name,const char type,const int elm_flag)3497836SJohn.Forte@Sun.COM convert_attr2xml(
3507836SJohn.Forte@Sun.COM 	xmlNodePtr node,
3517836SJohn.Forte@Sun.COM 	const isns_attr_t *attr,
3527836SJohn.Forte@Sun.COM 	const xmlChar *name,
3537836SJohn.Forte@Sun.COM 	const char type,
3547836SJohn.Forte@Sun.COM 	const int elm_flag
3557836SJohn.Forte@Sun.COM )
3567836SJohn.Forte@Sun.COM {
3577836SJohn.Forte@Sun.COM 	xmlChar buff[INET6_ADDRSTRLEN + 1] = { 0 };
3587836SJohn.Forte@Sun.COM 	xmlChar *value = NULL;
3597836SJohn.Forte@Sun.COM 	xmlNodePtr child = NULL;
3607836SJohn.Forte@Sun.COM 
3617836SJohn.Forte@Sun.COM 	switch (type) {
3627836SJohn.Forte@Sun.COM 		case 'u':
3637836SJohn.Forte@Sun.COM 			/* 4-bytes non-negative integer */
3647836SJohn.Forte@Sun.COM 			if (xmlStrPrintf(buff, sizeof (buff),
3657836SJohn.Forte@Sun.COM 			    (const unsigned char *)"%u",
3667836SJohn.Forte@Sun.COM 			    attr->value.ui) > 0) {
3677836SJohn.Forte@Sun.COM 				value = (xmlChar *)&buff;
3687836SJohn.Forte@Sun.COM 			}
3697836SJohn.Forte@Sun.COM 			break;
3707836SJohn.Forte@Sun.COM 		case 's':
3717836SJohn.Forte@Sun.COM 			/* literal string */
3727836SJohn.Forte@Sun.COM 			value = (xmlChar *)attr->value.ptr;
3737836SJohn.Forte@Sun.COM 			break;
3747836SJohn.Forte@Sun.COM 		case 'p':
3757836SJohn.Forte@Sun.COM 			/* IPv6 block data */
3767836SJohn.Forte@Sun.COM 			value = (xmlChar *)inet_ntop(AF_INET6,
3777836SJohn.Forte@Sun.COM 			    (char *)attr->value.ip,
3787836SJohn.Forte@Sun.COM 			    (char *)buff,
3797836SJohn.Forte@Sun.COM 			    sizeof (buff));
3807836SJohn.Forte@Sun.COM 			break;
3817836SJohn.Forte@Sun.COM 		default:
3827836SJohn.Forte@Sun.COM 			break;
3837836SJohn.Forte@Sun.COM 	}
3847836SJohn.Forte@Sun.COM 
3857836SJohn.Forte@Sun.COM 	if (!value) {
3867836SJohn.Forte@Sun.COM 		return (NULL);
3877836SJohn.Forte@Sun.COM 	}
3887836SJohn.Forte@Sun.COM 
3897836SJohn.Forte@Sun.COM 	switch (elm_flag) {
3907836SJohn.Forte@Sun.COM 		case 0: /* attlist */
3917836SJohn.Forte@Sun.COM 			if (xmlSetProp(node, name, value)) {
3927836SJohn.Forte@Sun.COM 				child = node;
3937836SJohn.Forte@Sun.COM 			}
3947836SJohn.Forte@Sun.COM 			break;
3957836SJohn.Forte@Sun.COM 		case 1: /* child element */
3967836SJohn.Forte@Sun.COM 			child = xmlNewChild(node, NULL, name, value);
3977836SJohn.Forte@Sun.COM 			break;
3987836SJohn.Forte@Sun.COM 		case 2: /* prev sibling element */
3997836SJohn.Forte@Sun.COM 			child = xmlNewNode(NULL, name);
4007836SJohn.Forte@Sun.COM 			if (child != NULL &&
4017836SJohn.Forte@Sun.COM 			    xmlAddPrevSibling(node, child) == NULL) {
4027836SJohn.Forte@Sun.COM 				xmlFreeNode(child);
4037836SJohn.Forte@Sun.COM 				node = NULL;
4047836SJohn.Forte@Sun.COM 			} else {
4057836SJohn.Forte@Sun.COM 				node = child;
4067836SJohn.Forte@Sun.COM 			}
4077836SJohn.Forte@Sun.COM 			/* LINTED E_CASE_FALLTHRU */
4087836SJohn.Forte@Sun.COM 		case 3: /* set content */
4097836SJohn.Forte@Sun.COM 			if (node) {
4107836SJohn.Forte@Sun.COM 				xmlNodeSetContent(node, value);
4117836SJohn.Forte@Sun.COM 			}
4127836SJohn.Forte@Sun.COM 			child = node;
4137836SJohn.Forte@Sun.COM 			break;
4147836SJohn.Forte@Sun.COM 		case 4: /* new attr value */
4157836SJohn.Forte@Sun.COM 			if (xmlSetProp(node, name, value)) {
4167836SJohn.Forte@Sun.COM 				child = node;
4177836SJohn.Forte@Sun.COM 			}
4187836SJohn.Forte@Sun.COM 			break;
4197836SJohn.Forte@Sun.COM 		default:
4207836SJohn.Forte@Sun.COM 			ASSERT(0);
4217836SJohn.Forte@Sun.COM 			break;
4227836SJohn.Forte@Sun.COM 	}
4237836SJohn.Forte@Sun.COM 
4247836SJohn.Forte@Sun.COM 	return (child);
4257836SJohn.Forte@Sun.COM }
4267836SJohn.Forte@Sun.COM 
4277836SJohn.Forte@Sun.COM /*
4287836SJohn.Forte@Sun.COM  * ****************************************************************************
4297836SJohn.Forte@Sun.COM  *
4307836SJohn.Forte@Sun.COM  * parse_xml_prop:
4317836SJohn.Forte@Sun.COM  *	parse the properties of a xml node and convert them to the attributes
4327836SJohn.Forte@Sun.COM  *	of an isns object, these xml properties are the UID attribute and
4337836SJohn.Forte@Sun.COM  *	key attributes of the isns object.
4347836SJohn.Forte@Sun.COM  *
4357836SJohn.Forte@Sun.COM  * node - the xml node that contains the properties.
4367836SJohn.Forte@Sun.COM  * obj - the isns object.
4377836SJohn.Forte@Sun.COM  * i  - the index of the attribute in the global tables.
4387836SJohn.Forte@Sun.COM  * return - error code.
4397836SJohn.Forte@Sun.COM  *
4407836SJohn.Forte@Sun.COM  * ****************************************************************************
4417836SJohn.Forte@Sun.COM  */
4427836SJohn.Forte@Sun.COM static int
parse_xml_prop(xmlNodePtr node,isns_obj_t * obj,int i)4437836SJohn.Forte@Sun.COM parse_xml_prop(
4447836SJohn.Forte@Sun.COM 	xmlNodePtr node,
4457836SJohn.Forte@Sun.COM 	isns_obj_t *obj,
4467836SJohn.Forte@Sun.COM 	int i
4477836SJohn.Forte@Sun.COM )
4487836SJohn.Forte@Sun.COM {
4497836SJohn.Forte@Sun.COM 	int ec = 0;
4507836SJohn.Forte@Sun.COM 	const char *props = &xmlType[i][1];
4517836SJohn.Forte@Sun.COM 	const xmlChar *prop_name;
4527836SJohn.Forte@Sun.COM 	xmlChar *prop_value;
4537836SJohn.Forte@Sun.COM 	unsigned char prop_type;
4547836SJohn.Forte@Sun.COM 	int prop_tag;
4557836SJohn.Forte@Sun.COM 	int prop_id;
4567836SJohn.Forte@Sun.COM 	char prop;
4577836SJohn.Forte@Sun.COM 	int j;
4587836SJohn.Forte@Sun.COM 
4597836SJohn.Forte@Sun.COM 	j = 0;
4607836SJohn.Forte@Sun.COM 	prop = props[j ++];
4617836SJohn.Forte@Sun.COM 	while (ec == 0 &&
4627836SJohn.Forte@Sun.COM 	    prop >= 'a' && prop <= 'z') {
4637836SJohn.Forte@Sun.COM 		prop -= 'a';
4647836SJohn.Forte@Sun.COM 		prop_id = xmlPropID[prop];
4657836SJohn.Forte@Sun.COM 		prop_tag = xmlPropTag[prop];
4667836SJohn.Forte@Sun.COM 		prop_name = xmlPropName[prop];
4677836SJohn.Forte@Sun.COM 		prop_type = xmlPropType[prop];
4687836SJohn.Forte@Sun.COM 		prop_value = xmlGetProp(node, prop_name);
4697836SJohn.Forte@Sun.COM 
4707836SJohn.Forte@Sun.COM 		if (prop_value) {
4717836SJohn.Forte@Sun.COM 			ec = convert_xml2attr(
4727836SJohn.Forte@Sun.COM 			    prop_tag,
4737836SJohn.Forte@Sun.COM 			    prop_type,
4747836SJohn.Forte@Sun.COM 			    prop_value,
4757836SJohn.Forte@Sun.COM 			    &(obj->attrs[prop_id]));
4767836SJohn.Forte@Sun.COM 			xmlFree(prop_value);
4777836SJohn.Forte@Sun.COM 		}
4787836SJohn.Forte@Sun.COM 		prop = props[j ++];
4797836SJohn.Forte@Sun.COM 	}
4807836SJohn.Forte@Sun.COM 
4817836SJohn.Forte@Sun.COM 	return (ec);
4827836SJohn.Forte@Sun.COM }
4837836SJohn.Forte@Sun.COM 
4847836SJohn.Forte@Sun.COM /*
4857836SJohn.Forte@Sun.COM  * ****************************************************************************
4867836SJohn.Forte@Sun.COM  *
4877836SJohn.Forte@Sun.COM  * parse_xml_attr:
4887836SJohn.Forte@Sun.COM  *	parse a xml node and convert it to one isns object attribute.
4897836SJohn.Forte@Sun.COM  *	this attribute is the non-key attribute of the isns object.
4907836SJohn.Forte@Sun.COM  *
4917836SJohn.Forte@Sun.COM  * node - the xml node.
4927836SJohn.Forte@Sun.COM  * obj - the isns object.
4937836SJohn.Forte@Sun.COM  * i  - the index of the attribute in the global tables.
4947836SJohn.Forte@Sun.COM  * return - error code.
4957836SJohn.Forte@Sun.COM  *
4967836SJohn.Forte@Sun.COM  * ****************************************************************************
4977836SJohn.Forte@Sun.COM  */
4987836SJohn.Forte@Sun.COM static int
parse_xml_attr(xmlNodePtr node,isns_obj_t * obj,int i)4997836SJohn.Forte@Sun.COM parse_xml_attr(
5007836SJohn.Forte@Sun.COM 	xmlNodePtr node,
5017836SJohn.Forte@Sun.COM 	isns_obj_t *obj,
5027836SJohn.Forte@Sun.COM 	int i
5037836SJohn.Forte@Sun.COM )
5047836SJohn.Forte@Sun.COM {
5057836SJohn.Forte@Sun.COM 	int ec = 0;
5067836SJohn.Forte@Sun.COM 	const unsigned char attr_type = xmlType[i][0];
5077836SJohn.Forte@Sun.COM 	const int attr_tag = xmlArg1[i];
5087836SJohn.Forte@Sun.COM 	const int attr_id = xmlArg2[i];
5097836SJohn.Forte@Sun.COM 	xmlChar *attr_value;
5107836SJohn.Forte@Sun.COM 
5117836SJohn.Forte@Sun.COM 	attr_value = xmlNodeGetContent(node);
5127836SJohn.Forte@Sun.COM 
5137836SJohn.Forte@Sun.COM 	if (attr_value) {
5147836SJohn.Forte@Sun.COM 		ec = convert_xml2attr(
5157836SJohn.Forte@Sun.COM 		    attr_tag,
5167836SJohn.Forte@Sun.COM 		    attr_type,
5177836SJohn.Forte@Sun.COM 		    attr_value,
5187836SJohn.Forte@Sun.COM 		    &(obj->attrs[attr_id]));
5197836SJohn.Forte@Sun.COM 		xmlFree(attr_value);
5207836SJohn.Forte@Sun.COM 	}
5217836SJohn.Forte@Sun.COM 
5227836SJohn.Forte@Sun.COM 	return (ec);
5237836SJohn.Forte@Sun.COM }
5247836SJohn.Forte@Sun.COM 
5257836SJohn.Forte@Sun.COM /*
5267836SJohn.Forte@Sun.COM  * ****************************************************************************
5277836SJohn.Forte@Sun.COM  *
5287836SJohn.Forte@Sun.COM  * parse_xml_obj:
5297836SJohn.Forte@Sun.COM  *	parse one isns object from the xml doc.
5307836SJohn.Forte@Sun.COM  *
5317836SJohn.Forte@Sun.COM  * nodep - the pointer of the xml node for parsing.
5327836SJohn.Forte@Sun.COM  * objp - the pointer of isns object for returning.
5337836SJohn.Forte@Sun.COM  * return - error code.
5347836SJohn.Forte@Sun.COM  *
5357836SJohn.Forte@Sun.COM  * ****************************************************************************
5367836SJohn.Forte@Sun.COM  */
5377836SJohn.Forte@Sun.COM static int
parse_xml_obj(xmlNodePtr * nodep,isns_obj_t ** objp)5387836SJohn.Forte@Sun.COM parse_xml_obj(
5397836SJohn.Forte@Sun.COM 	xmlNodePtr *nodep,
5407836SJohn.Forte@Sun.COM 	isns_obj_t **objp
5417836SJohn.Forte@Sun.COM )
5427836SJohn.Forte@Sun.COM {
5437836SJohn.Forte@Sun.COM 	int ec = 0;
5447836SJohn.Forte@Sun.COM 	int i, j;
5457836SJohn.Forte@Sun.COM 
5467836SJohn.Forte@Sun.COM 	xmlNodePtr node = *nodep;
5477836SJohn.Forte@Sun.COM 	xmlNodePtr children;
5487836SJohn.Forte@Sun.COM 
5497836SJohn.Forte@Sun.COM 	isns_obj_t *obj = *objp;
5507836SJohn.Forte@Sun.COM 
5517836SJohn.Forte@Sun.COM 	while (node && ec == 0) {
5527836SJohn.Forte@Sun.COM 		if (node->type == XML_ELEMENT_NODE) {
5537836SJohn.Forte@Sun.COM 			children = node->children;
5547836SJohn.Forte@Sun.COM 			i = get_index_by_name(node->name);
5557836SJohn.Forte@Sun.COM 			ASSERT(i >= 0);
5567836SJohn.Forte@Sun.COM 			j = xmlType[i][0];
5577836SJohn.Forte@Sun.COM 			if (j == 'o' && obj == NULL) {
5587836SJohn.Forte@Sun.COM 				obj = obj_calloc(xmlArg1[i]);
5597836SJohn.Forte@Sun.COM 				if (obj == NULL) {
5607836SJohn.Forte@Sun.COM 					ec = ISNS_RSP_INTERNAL_ERROR;
5617836SJohn.Forte@Sun.COM 					break;
5627836SJohn.Forte@Sun.COM 				}
5637836SJohn.Forte@Sun.COM 				if ((ec = parse_xml_prop(node, obj, i)) == 0 &&
5647836SJohn.Forte@Sun.COM 				    (children == NULL ||
5657836SJohn.Forte@Sun.COM 				    (ec = parse_xml_obj(&children, &obj)) ==
5667836SJohn.Forte@Sun.COM 				    0)) {
5677836SJohn.Forte@Sun.COM 					if (children != NULL &&
5687836SJohn.Forte@Sun.COM 					    children != node->children) {
5697836SJohn.Forte@Sun.COM 						*nodep = children;
5707836SJohn.Forte@Sun.COM 					}
5717836SJohn.Forte@Sun.COM 					*objp = obj;
5727836SJohn.Forte@Sun.COM 				} else {
5737836SJohn.Forte@Sun.COM 					free_object(obj);
5747836SJohn.Forte@Sun.COM 				}
5757836SJohn.Forte@Sun.COM 				break;
5767836SJohn.Forte@Sun.COM 				/* LINTED E_NOP_IF_STMT */
5777836SJohn.Forte@Sun.COM 			} else if (j == 'o') {
5787836SJohn.Forte@Sun.COM 			} else if (j != 0) {
5797836SJohn.Forte@Sun.COM 				ASSERT(obj);
5807836SJohn.Forte@Sun.COM 				if (children != NULL) {
5817836SJohn.Forte@Sun.COM 					ec = parse_xml_attr(children, obj, i);
5827836SJohn.Forte@Sun.COM 					*nodep = children;
5837836SJohn.Forte@Sun.COM 				} else {
5847836SJohn.Forte@Sun.COM 					/* assign a default value */
5857836SJohn.Forte@Sun.COM 					*nodep = node;
5867836SJohn.Forte@Sun.COM 				}
5877836SJohn.Forte@Sun.COM 			} else {
5887836SJohn.Forte@Sun.COM 				/* unknown xml node */
5897836SJohn.Forte@Sun.COM 				break;
5907836SJohn.Forte@Sun.COM 			}
5917836SJohn.Forte@Sun.COM 			/* LINTED E_NOP_ELSE_STMT */
5927836SJohn.Forte@Sun.COM 		} else {
5937836SJohn.Forte@Sun.COM 			/* carry return or blank spaces, skip it */
5947836SJohn.Forte@Sun.COM 		}
5957836SJohn.Forte@Sun.COM 		node = node->next;
5967836SJohn.Forte@Sun.COM 	}
5977836SJohn.Forte@Sun.COM 
5987836SJohn.Forte@Sun.COM 	return (ec);
5997836SJohn.Forte@Sun.COM }
6007836SJohn.Forte@Sun.COM 
6017836SJohn.Forte@Sun.COM /*
6027836SJohn.Forte@Sun.COM  * ****************************************************************************
6037836SJohn.Forte@Sun.COM  *
6047836SJohn.Forte@Sun.COM  * locate_xml_node:
6057836SJohn.Forte@Sun.COM  *	locate the xml node from xml doc by matching the object UID.
6067836SJohn.Forte@Sun.COM  *
6077836SJohn.Forte@Sun.COM  * doc - the xml doc.
6087836SJohn.Forte@Sun.COM  * otype - the matching object type.
6097836SJohn.Forte@Sun.COM  * match_uid - the matching object UID.
6107836SJohn.Forte@Sun.COM  * node - the pointer of matched xml node for returning.
6117836SJohn.Forte@Sun.COM  * context - the xml context for matching process.
6127836SJohn.Forte@Sun.COM  * result - the xml result for matching process.
6137836SJohn.Forte@Sun.COM  * return - error code.
6147836SJohn.Forte@Sun.COM  *
6157836SJohn.Forte@Sun.COM  * ****************************************************************************
6167836SJohn.Forte@Sun.COM  */
6177836SJohn.Forte@Sun.COM static int
locate_xml_node(xmlDocPtr doc,int otype,int match_uid,xmlNodePtr * node,xmlXPathContextPtr * context,xmlXPathObjectPtr * result)6187836SJohn.Forte@Sun.COM locate_xml_node(
6197836SJohn.Forte@Sun.COM 	xmlDocPtr doc,
6207836SJohn.Forte@Sun.COM 	int otype,
6217836SJohn.Forte@Sun.COM 	int match_uid,
6227836SJohn.Forte@Sun.COM 	xmlNodePtr *node,
6237836SJohn.Forte@Sun.COM 	xmlXPathContextPtr *context,
6247836SJohn.Forte@Sun.COM 	xmlXPathObjectPtr *result
6257836SJohn.Forte@Sun.COM )
6267836SJohn.Forte@Sun.COM {
6277836SJohn.Forte@Sun.COM 	int ec = 0;
6287836SJohn.Forte@Sun.COM 
6297836SJohn.Forte@Sun.COM 	xmlNodeSetPtr nodeset;
6307836SJohn.Forte@Sun.COM 	xmlNodePtr curr;
6317836SJohn.Forte@Sun.COM 	xmlChar expr[32] = { (xmlChar)'/', (xmlChar)'/', 0 };
6327836SJohn.Forte@Sun.COM 
6337836SJohn.Forte@Sun.COM 	char prop;
6347836SJohn.Forte@Sun.COM 	const xmlChar *prop_name;
6357836SJohn.Forte@Sun.COM 	xmlChar *prop_value;
6367836SJohn.Forte@Sun.COM 	int uid;
6377836SJohn.Forte@Sun.COM 
6387836SJohn.Forte@Sun.COM 	int i, j;
6397836SJohn.Forte@Sun.COM 
6407836SJohn.Forte@Sun.COM 	*node = NULL;
6417836SJohn.Forte@Sun.COM 
6427836SJohn.Forte@Sun.COM 	i = get_index_by_otype(otype);
6437836SJohn.Forte@Sun.COM 	ASSERT(i >= 0);
6447836SJohn.Forte@Sun.COM 
6457836SJohn.Forte@Sun.COM 	*context = xmlXPathNewContext(doc);
6467836SJohn.Forte@Sun.COM 
6477836SJohn.Forte@Sun.COM 	if (*context &&
6487836SJohn.Forte@Sun.COM 	    xmlStrPrintf(&expr[2], 30, (const unsigned char *)"%s",
6497836SJohn.Forte@Sun.COM 	    xmlTag[i]) != -1) {
6507836SJohn.Forte@Sun.COM 		*result = xmlXPathEvalExpression(expr, *context);
6517836SJohn.Forte@Sun.COM 		if (*result) {
6527836SJohn.Forte@Sun.COM 			prop = xmlArg2[i] - 'a';
6537836SJohn.Forte@Sun.COM 			prop_name = xmlPropName[prop];
6547836SJohn.Forte@Sun.COM 			ASSERT(xmlPropType[prop] == 'u');
6557836SJohn.Forte@Sun.COM 			nodeset = (*result)->nodesetval;
6567836SJohn.Forte@Sun.COM 			for (j = 0;
6577836SJohn.Forte@Sun.COM 			    nodeset && (j < nodeset->nodeNr);
6587836SJohn.Forte@Sun.COM 			    j++) {
6597836SJohn.Forte@Sun.COM 				curr = nodeset->nodeTab[j];
6607836SJohn.Forte@Sun.COM 				prop_value = xmlGetProp(curr, prop_name);
6617836SJohn.Forte@Sun.COM 				if (prop_value) {
6627836SJohn.Forte@Sun.COM 					uid = atoi((const char *)prop_value);
6637836SJohn.Forte@Sun.COM 					xmlFree(prop_value);
6647836SJohn.Forte@Sun.COM 					if (uid == match_uid) {
6657836SJohn.Forte@Sun.COM 						/* found it */
6667836SJohn.Forte@Sun.COM 						*node = curr;
6677836SJohn.Forte@Sun.COM 						return (ec);
6687836SJohn.Forte@Sun.COM 					}
6697836SJohn.Forte@Sun.COM 				}
6707836SJohn.Forte@Sun.COM 			}
6717836SJohn.Forte@Sun.COM 		} else {
6727836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INTERNAL_ERROR;
6737836SJohn.Forte@Sun.COM 		}
6747836SJohn.Forte@Sun.COM 	} else {
6757836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
6767836SJohn.Forte@Sun.COM 	}
6777836SJohn.Forte@Sun.COM 
6787836SJohn.Forte@Sun.COM 	if (*result) {
6797836SJohn.Forte@Sun.COM 		xmlXPathFreeObject(*result);
6807836SJohn.Forte@Sun.COM 		*result = NULL;
6817836SJohn.Forte@Sun.COM 	}
6827836SJohn.Forte@Sun.COM 	if (*context) {
6837836SJohn.Forte@Sun.COM 		xmlXPathFreeContext(*context);
6847836SJohn.Forte@Sun.COM 		*context = NULL;
6857836SJohn.Forte@Sun.COM 	}
6867836SJohn.Forte@Sun.COM 
6877836SJohn.Forte@Sun.COM 	return (ec);
6887836SJohn.Forte@Sun.COM }
6897836SJohn.Forte@Sun.COM 
6907836SJohn.Forte@Sun.COM /*
6917836SJohn.Forte@Sun.COM  * ****************************************************************************
6927836SJohn.Forte@Sun.COM  *
6937836SJohn.Forte@Sun.COM  * make_xml_node:
6947836SJohn.Forte@Sun.COM  *	generate a xml node for presenting an isns object.
6957836SJohn.Forte@Sun.COM  *
6967836SJohn.Forte@Sun.COM  * obj - an isns object.
6977836SJohn.Forte@Sun.COM  * return - the xml node.
6987836SJohn.Forte@Sun.COM  *
6997836SJohn.Forte@Sun.COM  * ****************************************************************************
7007836SJohn.Forte@Sun.COM  */
7017836SJohn.Forte@Sun.COM static xmlNodePtr
make_xml_node(const isns_obj_t * obj)7027836SJohn.Forte@Sun.COM make_xml_node(
7037836SJohn.Forte@Sun.COM 	const isns_obj_t *obj
7047836SJohn.Forte@Sun.COM )
7057836SJohn.Forte@Sun.COM {
7067836SJohn.Forte@Sun.COM 	const isns_attr_t *attr;
7077836SJohn.Forte@Sun.COM 
7087836SJohn.Forte@Sun.COM 	xmlNodePtr node;
7097836SJohn.Forte@Sun.COM 	const char *props;
7107836SJohn.Forte@Sun.COM 	char prop;
7117836SJohn.Forte@Sun.COM 	const xmlChar *name;
7127836SJohn.Forte@Sun.COM 	unsigned char type;
7137836SJohn.Forte@Sun.COM 	int prop_id;
7147836SJohn.Forte@Sun.COM 	int i, j;
7157836SJohn.Forte@Sun.COM 
7167836SJohn.Forte@Sun.COM 	i = get_index_by_otype(obj->type);
7177836SJohn.Forte@Sun.COM 	ASSERT(i >= 0);
7187836SJohn.Forte@Sun.COM 	node = xmlNewNode(NULL, xmlTag[i]);
7197836SJohn.Forte@Sun.COM 	if (!node) {
7207836SJohn.Forte@Sun.COM 		return (NULL);
7217836SJohn.Forte@Sun.COM 	}
7227836SJohn.Forte@Sun.COM 
7237836SJohn.Forte@Sun.COM 	/* generate xml attributes of the node */
7247836SJohn.Forte@Sun.COM 	props = &xmlType[i][1];
7257836SJohn.Forte@Sun.COM 	prop = *(props ++);
7267836SJohn.Forte@Sun.COM 	while (prop >= 'a' && prop <= 'z') {
7277836SJohn.Forte@Sun.COM 		prop -= 'a';
7287836SJohn.Forte@Sun.COM 		prop_id = xmlPropID[prop];
7297836SJohn.Forte@Sun.COM 		name = xmlPropName[prop];
7307836SJohn.Forte@Sun.COM 		type = xmlPropType[prop];
7317836SJohn.Forte@Sun.COM 		attr = &obj->attrs[prop_id];
7327836SJohn.Forte@Sun.COM 		if (!convert_attr2xml(node, attr, name, type, 0)) {
7337836SJohn.Forte@Sun.COM 			xmlFreeNode(node);
7347836SJohn.Forte@Sun.COM 			return (NULL);
7357836SJohn.Forte@Sun.COM 		}
7367836SJohn.Forte@Sun.COM 		/* attr->tag = 0; */
7377836SJohn.Forte@Sun.COM 		prop = *(props ++);
7387836SJohn.Forte@Sun.COM 	}
7397836SJohn.Forte@Sun.COM 
7407836SJohn.Forte@Sun.COM 	/* generate sub elements for isns attributes of the object */
7417836SJohn.Forte@Sun.COM 	i = 0;
7427836SJohn.Forte@Sun.COM 	while (i < NUM_OF_ATTRS[obj->type]) {
7437836SJohn.Forte@Sun.COM 		attr = &obj->attrs[i ++];
7447836SJohn.Forte@Sun.COM 		j = get_index_by_tag(attr->tag);
7457836SJohn.Forte@Sun.COM 		if (j >= 0) {
7467836SJohn.Forte@Sun.COM 			name = xmlTag[j];
7477836SJohn.Forte@Sun.COM 			type = xmlType[j][0];
7487836SJohn.Forte@Sun.COM 			if (!convert_attr2xml(node, attr, name, type, 1)) {
7497836SJohn.Forte@Sun.COM 				xmlFreeNode(node);
7507836SJohn.Forte@Sun.COM 				return (NULL);
7517836SJohn.Forte@Sun.COM 			}
7527836SJohn.Forte@Sun.COM 		}
7537836SJohn.Forte@Sun.COM 	}
7547836SJohn.Forte@Sun.COM 
7557836SJohn.Forte@Sun.COM 	return (node);
7567836SJohn.Forte@Sun.COM }
7577836SJohn.Forte@Sun.COM 
7587836SJohn.Forte@Sun.COM /*
7597836SJohn.Forte@Sun.COM  * ****************************************************************************
7607836SJohn.Forte@Sun.COM  *
7617836SJohn.Forte@Sun.COM  * xml_init_data:
7627836SJohn.Forte@Sun.COM  *	initialization of the xml data store.
7637836SJohn.Forte@Sun.COM  *
7647836SJohn.Forte@Sun.COM  * return - error code.
7657836SJohn.Forte@Sun.COM  *
7667836SJohn.Forte@Sun.COM  * ****************************************************************************
7677836SJohn.Forte@Sun.COM  */
7687836SJohn.Forte@Sun.COM static int
xml_init_data()7697836SJohn.Forte@Sun.COM xml_init_data(
7707836SJohn.Forte@Sun.COM )
7717836SJohn.Forte@Sun.COM {
7727836SJohn.Forte@Sun.COM #define	XML_PATH	"/etc/isns"
7737836SJohn.Forte@Sun.COM #define	XML_FILE_NAME	"/isnsdata.xml"
7747836SJohn.Forte@Sun.COM #define	XML_DOT_TMP	".tmp"
7757836SJohn.Forte@Sun.COM #define	XML_DOT_BAK	".bak"
7767836SJohn.Forte@Sun.COM 
7777836SJohn.Forte@Sun.COM 	int fd;
7787836SJohn.Forte@Sun.COM 	xmlDocPtr doc;
7797836SJohn.Forte@Sun.COM 	xmlNodePtr root;
7807836SJohn.Forte@Sun.COM 
7817836SJohn.Forte@Sun.COM 	int len;
7827836SJohn.Forte@Sun.COM 	char *xml_path, *p = NULL;
7837836SJohn.Forte@Sun.COM 
7847836SJohn.Forte@Sun.COM 	char *cwd = NULL;
7857836SJohn.Forte@Sun.COM 
7867836SJohn.Forte@Sun.COM 	int has_bak = 0;
7877836SJohn.Forte@Sun.COM 
7887836SJohn.Forte@Sun.COM 	/* cannot reset the xml file when server is running */
7897836SJohn.Forte@Sun.COM 	if (xml_file != NULL) {
7907836SJohn.Forte@Sun.COM 		return (1);
7917836SJohn.Forte@Sun.COM 	}
7927836SJohn.Forte@Sun.COM 
7937836SJohn.Forte@Sun.COM 	/* set the data store file name along with the backup */
7947836SJohn.Forte@Sun.COM 	/* file name and temporary file name */
7957836SJohn.Forte@Sun.COM 	len = strlen(data_store);
7967836SJohn.Forte@Sun.COM 	if (len > 0) {
7977836SJohn.Forte@Sun.COM 		xml_file = data_store;
7987836SJohn.Forte@Sun.COM 		p = strdup(xml_file);
7997836SJohn.Forte@Sun.COM 		xml_bak_file = (char *)malloc(len + 5);
8007836SJohn.Forte@Sun.COM 		xml_tmp_file = (char *)malloc(len + 5);
8017836SJohn.Forte@Sun.COM 		if (p != NULL &&
8027836SJohn.Forte@Sun.COM 		    xml_bak_file != NULL &&
8037836SJohn.Forte@Sun.COM 		    xml_tmp_file != NULL) {
8047836SJohn.Forte@Sun.COM 			xml_path = dirname(p);
8057836SJohn.Forte@Sun.COM 			(void) strcpy(xml_bak_file, xml_file);
8067836SJohn.Forte@Sun.COM 			(void) strcat(xml_bak_file, XML_DOT_BAK);
8077836SJohn.Forte@Sun.COM 			(void) strcpy(xml_tmp_file, xml_file);
8087836SJohn.Forte@Sun.COM 			(void) strcat(xml_tmp_file, XML_DOT_TMP);
8097836SJohn.Forte@Sun.COM 		} else {
8107836SJohn.Forte@Sun.COM 			return (1);
8117836SJohn.Forte@Sun.COM 		}
8127836SJohn.Forte@Sun.COM 	} else {
8137836SJohn.Forte@Sun.COM 		xml_path = XML_PATH;
8147836SJohn.Forte@Sun.COM 		xml_file = XML_PATH XML_FILE_NAME;
8157836SJohn.Forte@Sun.COM 		xml_bak_file = XML_PATH XML_FILE_NAME XML_DOT_BAK;
8167836SJohn.Forte@Sun.COM 		xml_tmp_file = XML_PATH XML_FILE_NAME XML_DOT_TMP;
8177836SJohn.Forte@Sun.COM 	}
8187836SJohn.Forte@Sun.COM 
8197836SJohn.Forte@Sun.COM 	/* save current working directory */
8207836SJohn.Forte@Sun.COM 	cwd = getcwd(NULL, MAXPATHLEN);
8217836SJohn.Forte@Sun.COM 	if (cwd == NULL) {
8227836SJohn.Forte@Sun.COM 		return (1);
8237836SJohn.Forte@Sun.COM 	}
8247836SJohn.Forte@Sun.COM 	/* check access permission on data store directory */
8257836SJohn.Forte@Sun.COM 	if (chdir(xml_path) != 0) {
8267836SJohn.Forte@Sun.COM 		if (errno == ENOENT) {
8277836SJohn.Forte@Sun.COM 			if (mkdir(xml_path, S_IRWXU) != 0 ||
8287836SJohn.Forte@Sun.COM 			    chdir(xml_path) != 0) {
8297836SJohn.Forte@Sun.COM 				return (1);
8307836SJohn.Forte@Sun.COM 			}
8317836SJohn.Forte@Sun.COM 		} else {
8327836SJohn.Forte@Sun.COM 			return (1);
8337836SJohn.Forte@Sun.COM 		}
8347836SJohn.Forte@Sun.COM 	}
8357836SJohn.Forte@Sun.COM 	/* go back to original working directory */
8367836SJohn.Forte@Sun.COM 	(void) chdir(cwd);
8377836SJohn.Forte@Sun.COM 	free(cwd);
8387836SJohn.Forte@Sun.COM 	free(p);
8397836SJohn.Forte@Sun.COM 
8407836SJohn.Forte@Sun.COM 	/* do not keep blank spaces */
8417836SJohn.Forte@Sun.COM 	(void) xmlKeepBlanksDefault(0);
8427836SJohn.Forte@Sun.COM 
843*10152Swl202157@icefox 	/* remove the tmp file if it exists */
844*10152Swl202157@icefox 	if (access(xml_tmp_file, F_OK) == 0) {
845*10152Swl202157@icefox 		(void) remove(xml_tmp_file);
8467836SJohn.Forte@Sun.COM 	}
8477836SJohn.Forte@Sun.COM 
8487836SJohn.Forte@Sun.COM 	/* test if we can write the bak file */
8497836SJohn.Forte@Sun.COM 	fd = open(xml_bak_file, O_RDWR);
8507836SJohn.Forte@Sun.COM 	if (fd == -1) {
8517836SJohn.Forte@Sun.COM 		fd = open(xml_bak_file, O_RDWR | O_CREAT,
8527836SJohn.Forte@Sun.COM 		    S_IRUSR | S_IWUSR);
8537836SJohn.Forte@Sun.COM 		if (fd == -1) {
8547836SJohn.Forte@Sun.COM 			return (1);
8557836SJohn.Forte@Sun.COM 		} else {
8567836SJohn.Forte@Sun.COM 			(void) close(fd);
8577836SJohn.Forte@Sun.COM 			(void) remove(xml_bak_file);
8587836SJohn.Forte@Sun.COM 		}
8597836SJohn.Forte@Sun.COM 	} else {
8607836SJohn.Forte@Sun.COM 		has_bak = 1;
8617836SJohn.Forte@Sun.COM 		(void) close(fd);
8627836SJohn.Forte@Sun.COM 	}
8637836SJohn.Forte@Sun.COM 
8647836SJohn.Forte@Sun.COM 	/* Test if we have the data store file, create an empty */
8657836SJohn.Forte@Sun.COM 	/* data store if we do not have the data store file and */
8667836SJohn.Forte@Sun.COM 	/* the backup data store. */
8677836SJohn.Forte@Sun.COM 	fd = open(xml_file, O_RDWR);
8687836SJohn.Forte@Sun.COM 	if (fd == -1) {
8697836SJohn.Forte@Sun.COM 		if (has_bak == 0) {
8707836SJohn.Forte@Sun.COM 			doc = xmlNewDoc(BAD_CAST "1.0");
8717836SJohn.Forte@Sun.COM 			root = xmlNewNode(NULL, xml_root[0]);
8727836SJohn.Forte@Sun.COM 			if (doc != NULL &&
8737836SJohn.Forte@Sun.COM 			    root != NULL &&
8747836SJohn.Forte@Sun.COM 			    xmlSetProp(root, xml_root[1], xml_root[2]) !=
8757836SJohn.Forte@Sun.COM 			    NULL &&
8767836SJohn.Forte@Sun.COM 			    xmlSetProp(root, xml_root[3], xml_root[4]) !=
8777836SJohn.Forte@Sun.COM 			    NULL) {
8787836SJohn.Forte@Sun.COM 				(void) xmlDocSetRootElement(doc, root);
8797836SJohn.Forte@Sun.COM 				if (xmlSaveFormatFile(xml_file, doc, 1) == -1) {
8807836SJohn.Forte@Sun.COM 					xmlFreeDoc(doc);
8817836SJohn.Forte@Sun.COM 					return (-1);
8827836SJohn.Forte@Sun.COM 				}
8837836SJohn.Forte@Sun.COM 				xmlFreeDoc(doc);
8847836SJohn.Forte@Sun.COM 			} else {
8857836SJohn.Forte@Sun.COM 				if (doc != NULL) {
8867836SJohn.Forte@Sun.COM 					xmlFreeDoc(doc);
8877836SJohn.Forte@Sun.COM 				}
8887836SJohn.Forte@Sun.COM 				if (root != NULL) {
8897836SJohn.Forte@Sun.COM 					xmlFreeNode(root);
8907836SJohn.Forte@Sun.COM 				}
8917836SJohn.Forte@Sun.COM 				return (1);
8927836SJohn.Forte@Sun.COM 			}
8937836SJohn.Forte@Sun.COM 		} else {
8947836SJohn.Forte@Sun.COM 			isnslog(LOG_WARNING, "get_xml_doc",
8957836SJohn.Forte@Sun.COM 			    "initializing with backup data");
8967836SJohn.Forte@Sun.COM 			if (rename(xml_bak_file, xml_file) != 0) {
8977836SJohn.Forte@Sun.COM 				return (1);
8987836SJohn.Forte@Sun.COM 			}
8997836SJohn.Forte@Sun.COM 		}
9007836SJohn.Forte@Sun.COM 	} else {
9017836SJohn.Forte@Sun.COM 		(void) close(fd);
9027836SJohn.Forte@Sun.COM 	}
9037836SJohn.Forte@Sun.COM 
9047836SJohn.Forte@Sun.COM 	return (0);
9057836SJohn.Forte@Sun.COM }
9067836SJohn.Forte@Sun.COM 
9077836SJohn.Forte@Sun.COM /*
9087836SJohn.Forte@Sun.COM  * ****************************************************************************
9097836SJohn.Forte@Sun.COM  *
9107836SJohn.Forte@Sun.COM  * xml_load_obj:
9117836SJohn.Forte@Sun.COM  *	load an isns object from the xml data store.
9127836SJohn.Forte@Sun.COM  *
9137836SJohn.Forte@Sun.COM  * p - the pointer of current xml node.
9147836SJohn.Forte@Sun.COM  * objp - the pointer of the object for returning.
9157836SJohn.Forte@Sun.COM  * level - the direction of xml parsing for returning.
9167836SJohn.Forte@Sun.COM  * return - error code.
9177836SJohn.Forte@Sun.COM  *
9187836SJohn.Forte@Sun.COM  * ****************************************************************************
9197836SJohn.Forte@Sun.COM  */
9207836SJohn.Forte@Sun.COM static int
xml_load_obj(void ** p,isns_obj_t ** objp,uchar_t * level)9217836SJohn.Forte@Sun.COM xml_load_obj(
9227836SJohn.Forte@Sun.COM 	void **p,
9237836SJohn.Forte@Sun.COM 	isns_obj_t **objp,
9247836SJohn.Forte@Sun.COM 	uchar_t *level
9257836SJohn.Forte@Sun.COM )
9267836SJohn.Forte@Sun.COM {
9277836SJohn.Forte@Sun.COM 	xmlDocPtr doc = NULL;
9287836SJohn.Forte@Sun.COM 	xmlNodePtr node = (xmlNodePtr)*p;
9297836SJohn.Forte@Sun.COM 	int ec = 0;
9307836SJohn.Forte@Sun.COM 
9317836SJohn.Forte@Sun.COM 	*objp = NULL;
9327836SJohn.Forte@Sun.COM 
9337836SJohn.Forte@Sun.COM 	if (node == NULL) {
9347836SJohn.Forte@Sun.COM 		*level = '^';
9357836SJohn.Forte@Sun.COM 		ec = get_xml_doc(&doc);
9367836SJohn.Forte@Sun.COM 		if (doc == NULL) {
9377836SJohn.Forte@Sun.COM 			return (ec);
9387836SJohn.Forte@Sun.COM 		}
9397836SJohn.Forte@Sun.COM 		node = xmlDocGetRootElement(doc);
9407836SJohn.Forte@Sun.COM 		if (node != NULL) {
9417836SJohn.Forte@Sun.COM 			node = node->children;
9427836SJohn.Forte@Sun.COM 		}
9437836SJohn.Forte@Sun.COM 	} else if (node->children != NULL) {
9447836SJohn.Forte@Sun.COM 		*level = '>';
9457836SJohn.Forte@Sun.COM 		node = node->children;
9467836SJohn.Forte@Sun.COM 	} else if (node->next != NULL) {
9477836SJohn.Forte@Sun.COM 		*level = 'v';
9487836SJohn.Forte@Sun.COM 		node = node->next;
9497836SJohn.Forte@Sun.COM 	} else {
9507836SJohn.Forte@Sun.COM 		*level = 'v';
9517836SJohn.Forte@Sun.COM 		while (node != NULL && node->next == NULL) {
9527836SJohn.Forte@Sun.COM 			if (node->type == XML_ELEMENT_NODE) {
9537836SJohn.Forte@Sun.COM 				*level = '<';
9547836SJohn.Forte@Sun.COM 			}
9557836SJohn.Forte@Sun.COM 			node = node->parent;
9567836SJohn.Forte@Sun.COM 		}
9577836SJohn.Forte@Sun.COM 		if (node != NULL) {
9587836SJohn.Forte@Sun.COM 			node = node->next;
9597836SJohn.Forte@Sun.COM 		}
9607836SJohn.Forte@Sun.COM 	}
9617836SJohn.Forte@Sun.COM 
9627836SJohn.Forte@Sun.COM 	/* there is a node, parse it */
9637836SJohn.Forte@Sun.COM 	if (node) {
9647836SJohn.Forte@Sun.COM 		ec = parse_xml_obj(&node, objp);
9657836SJohn.Forte@Sun.COM 		*p = (void *)node;
9667836SJohn.Forte@Sun.COM 	}
9677836SJohn.Forte@Sun.COM 
9687836SJohn.Forte@Sun.COM 	if (ec == 0 && *objp != NULL) {
9697836SJohn.Forte@Sun.COM 		ec = update_deref_obj(*objp);
9707836SJohn.Forte@Sun.COM 		if (ec != 0) {
9717836SJohn.Forte@Sun.COM 			free_object(*objp);
9727836SJohn.Forte@Sun.COM 			*objp = NULL;
9737836SJohn.Forte@Sun.COM 		}
9747836SJohn.Forte@Sun.COM 	}
9757836SJohn.Forte@Sun.COM 
9767836SJohn.Forte@Sun.COM 	/* no object available, close the xml doc */
9777836SJohn.Forte@Sun.COM 	if (*objp == NULL) {
9787836SJohn.Forte@Sun.COM 		(void) close_xml_doc();
9797836SJohn.Forte@Sun.COM 	}
9807836SJohn.Forte@Sun.COM 
9817836SJohn.Forte@Sun.COM 	return (ec);
9827836SJohn.Forte@Sun.COM }
9837836SJohn.Forte@Sun.COM 
9847836SJohn.Forte@Sun.COM /*
9857836SJohn.Forte@Sun.COM  * ****************************************************************************
9867836SJohn.Forte@Sun.COM  *
9877836SJohn.Forte@Sun.COM  * xml_add_obj:
9887836SJohn.Forte@Sun.COM  *	add an isns object to the xml data store.
9897836SJohn.Forte@Sun.COM  *
9907836SJohn.Forte@Sun.COM  * obj - the object being added.
9917836SJohn.Forte@Sun.COM  * return - error code.
9927836SJohn.Forte@Sun.COM  *
9937836SJohn.Forte@Sun.COM  * ****************************************************************************
9947836SJohn.Forte@Sun.COM  */
9957836SJohn.Forte@Sun.COM static int
xml_add_obj(const isns_obj_t * obj)9967836SJohn.Forte@Sun.COM xml_add_obj(
9977836SJohn.Forte@Sun.COM 	const isns_obj_t *obj
9987836SJohn.Forte@Sun.COM )
9997836SJohn.Forte@Sun.COM {
10007836SJohn.Forte@Sun.COM 	int ec = 0;
10017836SJohn.Forte@Sun.COM 
10027836SJohn.Forte@Sun.COM 	xmlDocPtr doc;
10037836SJohn.Forte@Sun.COM 	xmlXPathContextPtr context = NULL;
10047836SJohn.Forte@Sun.COM 	xmlXPathObjectPtr result = NULL;
10057836SJohn.Forte@Sun.COM 	xmlNodePtr node, prev;
10067836SJohn.Forte@Sun.COM 	xmlNodePtr candidate;
10077836SJohn.Forte@Sun.COM 
10087836SJohn.Forte@Sun.COM 	uint32_t puid, parent_type;
10097836SJohn.Forte@Sun.COM 
10107836SJohn.Forte@Sun.COM 	int i;
10117836SJohn.Forte@Sun.COM 
10127836SJohn.Forte@Sun.COM 	/* get the xml doc */
10137836SJohn.Forte@Sun.COM 	ec = get_xml_doc(&doc);
10147836SJohn.Forte@Sun.COM 	if (doc == NULL) {
10157836SJohn.Forte@Sun.COM 		goto add_done;
10167836SJohn.Forte@Sun.COM 	}
10177836SJohn.Forte@Sun.COM 
10187836SJohn.Forte@Sun.COM 	/* create the candidate node */
10197836SJohn.Forte@Sun.COM 	candidate = make_xml_node(obj);
10207836SJohn.Forte@Sun.COM 	if (candidate == NULL) {
10217836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
10227836SJohn.Forte@Sun.COM 		goto add_done;
10237836SJohn.Forte@Sun.COM 	}
10247836SJohn.Forte@Sun.COM 
10257836SJohn.Forte@Sun.COM 	/* locate the position */
10267836SJohn.Forte@Sun.COM 	parent_type = TYPE_OF_PARENT[obj->type];
10277836SJohn.Forte@Sun.COM 	if (parent_type > 0) {
10287836SJohn.Forte@Sun.COM 		puid = get_parent_uid(obj);
10297836SJohn.Forte@Sun.COM 		ec = locate_xml_node(doc, parent_type, puid,
10307836SJohn.Forte@Sun.COM 		    &node, &context, &result);
10317836SJohn.Forte@Sun.COM 	} else {
10327836SJohn.Forte@Sun.COM 		node = xmlDocGetRootElement(doc);
10337836SJohn.Forte@Sun.COM 	}
10347836SJohn.Forte@Sun.COM 
10357836SJohn.Forte@Sun.COM 	/* cannot locate the point for inserting the node */
10367836SJohn.Forte@Sun.COM 	if (node == NULL) {
10377836SJohn.Forte@Sun.COM 		xmlFreeNode(candidate);
10387836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
10397836SJohn.Forte@Sun.COM 		goto add_done;
10407836SJohn.Forte@Sun.COM 	}
10417836SJohn.Forte@Sun.COM 
10427836SJohn.Forte@Sun.COM 	/* add it with the apporiate child order */
10437836SJohn.Forte@Sun.COM 	if (node->children) {
10447836SJohn.Forte@Sun.COM 		node = node->children;
10457836SJohn.Forte@Sun.COM 		while (node) {
10467836SJohn.Forte@Sun.COM 			if (node->type == XML_ELEMENT_NODE) {
10477836SJohn.Forte@Sun.COM 				i = get_index_by_name(node->name);
10487836SJohn.Forte@Sun.COM 				ASSERT(i >= 0);
10497836SJohn.Forte@Sun.COM 				if (xmlType[i][0] == 'o' &&
10507836SJohn.Forte@Sun.COM 				    OBJ_DTD_ORDER[xmlArg1[i]] >=
10517836SJohn.Forte@Sun.COM 				    OBJ_DTD_ORDER[obj->type]) {
10527836SJohn.Forte@Sun.COM 					break;
10537836SJohn.Forte@Sun.COM 				}
10547836SJohn.Forte@Sun.COM 			}
10557836SJohn.Forte@Sun.COM 			prev = node;
10567836SJohn.Forte@Sun.COM 			node = node->next;
10577836SJohn.Forte@Sun.COM 		}
10587836SJohn.Forte@Sun.COM 		if (node == NULL) {
10597836SJohn.Forte@Sun.COM 			node = xmlAddNextSibling(prev, candidate);
10607836SJohn.Forte@Sun.COM 		} else {
10617836SJohn.Forte@Sun.COM 			node = xmlAddPrevSibling(node, candidate);
10627836SJohn.Forte@Sun.COM 		}
10637836SJohn.Forte@Sun.COM 	} else {
10647836SJohn.Forte@Sun.COM 		node = xmlAddChild(node, candidate);
10657836SJohn.Forte@Sun.COM 	}
10667836SJohn.Forte@Sun.COM 
10677836SJohn.Forte@Sun.COM 	if (node == NULL) {
10687836SJohn.Forte@Sun.COM 		/* Failed, free the candidate node. */
10697836SJohn.Forte@Sun.COM 		xmlFreeNode(candidate);
10707836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
10717836SJohn.Forte@Sun.COM 	}
10727836SJohn.Forte@Sun.COM 
10737836SJohn.Forte@Sun.COM add_done:
10747836SJohn.Forte@Sun.COM 	if (result) {
10757836SJohn.Forte@Sun.COM 		xmlXPathFreeObject(result);
10767836SJohn.Forte@Sun.COM 	}
10777836SJohn.Forte@Sun.COM 	if (context) {
10787836SJohn.Forte@Sun.COM 		xmlXPathFreeContext(context);
10797836SJohn.Forte@Sun.COM 	}
10807836SJohn.Forte@Sun.COM 
10817836SJohn.Forte@Sun.COM 	return (ec);
10827836SJohn.Forte@Sun.COM }
10837836SJohn.Forte@Sun.COM 
10847836SJohn.Forte@Sun.COM /*
10857836SJohn.Forte@Sun.COM  * ****************************************************************************
10867836SJohn.Forte@Sun.COM  *
10877836SJohn.Forte@Sun.COM  * xml_modify_obj:
10887836SJohn.Forte@Sun.COM  *	modify an isns object in the xml data store.
10897836SJohn.Forte@Sun.COM  *
10907836SJohn.Forte@Sun.COM  * obj - the new object.
10917836SJohn.Forte@Sun.COM  * return - error code.
10927836SJohn.Forte@Sun.COM  *
10937836SJohn.Forte@Sun.COM  * ****************************************************************************
10947836SJohn.Forte@Sun.COM  */
10957836SJohn.Forte@Sun.COM static int
xml_modify_obj(const isns_obj_t * obj)10967836SJohn.Forte@Sun.COM xml_modify_obj(
10977836SJohn.Forte@Sun.COM 	const isns_obj_t *obj
10987836SJohn.Forte@Sun.COM )
10997836SJohn.Forte@Sun.COM {
11007836SJohn.Forte@Sun.COM 	int ec = 0;
11017836SJohn.Forte@Sun.COM 	xmlDocPtr doc;
11027836SJohn.Forte@Sun.COM 	xmlXPathContextPtr context = NULL;
11037836SJohn.Forte@Sun.COM 	xmlXPathObjectPtr result = NULL;
11047836SJohn.Forte@Sun.COM 	xmlNodePtr node, child;
11057836SJohn.Forte@Sun.COM 	const char *props;
11067836SJohn.Forte@Sun.COM 	char prop;
11077836SJohn.Forte@Sun.COM 	int prop_id;
11087836SJohn.Forte@Sun.COM 	int prop_tag;
11097836SJohn.Forte@Sun.COM 	const xmlChar *name;
11107836SJohn.Forte@Sun.COM 	unsigned char type;
11117836SJohn.Forte@Sun.COM 	const isns_attr_t *attr;
11127836SJohn.Forte@Sun.COM 	int i, j, k;
11137836SJohn.Forte@Sun.COM 	int make_child;
11147836SJohn.Forte@Sun.COM 
11157836SJohn.Forte@Sun.COM 	/* get the doc pointer */
11167836SJohn.Forte@Sun.COM 	ec = get_xml_doc(&doc);
11177836SJohn.Forte@Sun.COM 	if (doc == NULL) {
11187836SJohn.Forte@Sun.COM 		return (ec);
11197836SJohn.Forte@Sun.COM 	}
11207836SJohn.Forte@Sun.COM 
11217836SJohn.Forte@Sun.COM 	/* locate the node for the object */
11227836SJohn.Forte@Sun.COM 	i = get_index_by_otype(obj->type);
11237836SJohn.Forte@Sun.COM 	ASSERT(i >= 0);
11247836SJohn.Forte@Sun.COM 	prop = xmlArg2[i] - 'a';
11257836SJohn.Forte@Sun.COM 	prop_id = xmlPropID[prop];
11267836SJohn.Forte@Sun.COM 	attr = &obj->attrs[prop_id];
11277836SJohn.Forte@Sun.COM 	ec = locate_xml_node(doc,
11287836SJohn.Forte@Sun.COM 	    obj->type,
11297836SJohn.Forte@Sun.COM 	    attr->value.ui,
11307836SJohn.Forte@Sun.COM 	    &node, &context, &result);
11317836SJohn.Forte@Sun.COM 
11327836SJohn.Forte@Sun.COM 	/* modify it */
11337836SJohn.Forte@Sun.COM 	if (node != NULL) {
11347836SJohn.Forte@Sun.COM 		props = &xmlType[i][1];
11357836SJohn.Forte@Sun.COM 		prop = *(props ++);
11367836SJohn.Forte@Sun.COM 		while (prop >= 'a' && prop <= 'z') {
11377836SJohn.Forte@Sun.COM 			prop -= 'a';
11387836SJohn.Forte@Sun.COM 			prop_id = xmlPropID[prop];
11397836SJohn.Forte@Sun.COM 			prop_tag = xmlPropTag[prop];
11407836SJohn.Forte@Sun.COM 			attr = &obj->attrs[prop_id];
11417836SJohn.Forte@Sun.COM 			/* no need to update the key attributes, skip it. */
11427836SJohn.Forte@Sun.COM 			/* btw, dd and dd-set names are non-key attributes. */
11437836SJohn.Forte@Sun.COM 			if (prop_tag == ISNS_DD_NAME_ATTR_ID ||
11447836SJohn.Forte@Sun.COM 			    prop_tag == ISNS_DD_SET_NAME_ATTR_ID) {
11457836SJohn.Forte@Sun.COM 				name = xmlPropName[prop];
11467836SJohn.Forte@Sun.COM 				type = xmlPropType[prop];
11477836SJohn.Forte@Sun.COM 				if (!convert_attr2xml(node,
11487836SJohn.Forte@Sun.COM 				    attr, name, type, 4)) {
11497836SJohn.Forte@Sun.COM 					ec = ISNS_RSP_INTERNAL_ERROR;
11507836SJohn.Forte@Sun.COM 					goto modify_done;
11517836SJohn.Forte@Sun.COM 				}
11527836SJohn.Forte@Sun.COM 			}
11537836SJohn.Forte@Sun.COM 			/* attr->tag = 0; */
11547836SJohn.Forte@Sun.COM 			prop = *(props ++);
11557836SJohn.Forte@Sun.COM 		}
11567836SJohn.Forte@Sun.COM 		/* set the child */
11577836SJohn.Forte@Sun.COM 		child = node->children;
11587836SJohn.Forte@Sun.COM 		if (child == NULL) {
11597836SJohn.Forte@Sun.COM 			make_child = 1;
11607836SJohn.Forte@Sun.COM 		} else {
11617836SJohn.Forte@Sun.COM 			make_child = 0;
11627836SJohn.Forte@Sun.COM 		}
11637836SJohn.Forte@Sun.COM 		for (i = 0; i < NUM_OF_ATTRS[obj->type]; i++) {
11647836SJohn.Forte@Sun.COM 			attr = &obj->attrs[i];
11657836SJohn.Forte@Sun.COM 			j = get_index_by_tag(attr->tag);
11667836SJohn.Forte@Sun.COM 			if (j < 0) {
11677836SJohn.Forte@Sun.COM 				continue;
11687836SJohn.Forte@Sun.COM 			}
11697836SJohn.Forte@Sun.COM 			name = xmlTag[j];
11707836SJohn.Forte@Sun.COM 			type = xmlType[j][0];
11717836SJohn.Forte@Sun.COM 			if (make_child == 1) {
11727836SJohn.Forte@Sun.COM 				/* make a child node */
11737836SJohn.Forte@Sun.COM 				if (!convert_attr2xml(node, attr,
11747836SJohn.Forte@Sun.COM 				    name, type, 1)) {
11757836SJohn.Forte@Sun.COM 					ec = ISNS_RSP_INTERNAL_ERROR;
11767836SJohn.Forte@Sun.COM 					goto modify_done;
11777836SJohn.Forte@Sun.COM 				}
11787836SJohn.Forte@Sun.COM 				continue;
11797836SJohn.Forte@Sun.COM 			}
11807836SJohn.Forte@Sun.COM 			while (child) {
11817836SJohn.Forte@Sun.COM 				if (child->type == XML_ELEMENT_NODE) {
11827836SJohn.Forte@Sun.COM 					k = get_index_by_name(child->name);
11837836SJohn.Forte@Sun.COM 					ASSERT(k >= 0);
11847836SJohn.Forte@Sun.COM 					if (xmlType[k][0] == 'o' ||
11857836SJohn.Forte@Sun.COM 					    xmlType[k][0] == 'a' ||
11867836SJohn.Forte@Sun.COM 					    xmlArg1[k] > attr->tag) {
11877836SJohn.Forte@Sun.COM 						if (!convert_attr2xml(child,
11887836SJohn.Forte@Sun.COM 						    attr, name, type, 2)) {
11897836SJohn.Forte@Sun.COM 							/* internal error */
11907836SJohn.Forte@Sun.COM 							ec = 11;
11917836SJohn.Forte@Sun.COM 							goto modify_done;
11927836SJohn.Forte@Sun.COM 						}
11937836SJohn.Forte@Sun.COM 						break;
11947836SJohn.Forte@Sun.COM 					} else if (xmlArg1[k] == attr->tag) {
11957836SJohn.Forte@Sun.COM 						/* replace content */
11967836SJohn.Forte@Sun.COM 						if (!convert_attr2xml(child,
11977836SJohn.Forte@Sun.COM 						    attr, name, type, 3)) {
11987836SJohn.Forte@Sun.COM 							/* internal error */
11997836SJohn.Forte@Sun.COM 							ec = 11;
12007836SJohn.Forte@Sun.COM 							goto modify_done;
12017836SJohn.Forte@Sun.COM 						}
12027836SJohn.Forte@Sun.COM 						break;
12037836SJohn.Forte@Sun.COM 					}
12047836SJohn.Forte@Sun.COM 				}
12057836SJohn.Forte@Sun.COM 				child = child->next;
12067836SJohn.Forte@Sun.COM 			}
12077836SJohn.Forte@Sun.COM 			if (child == NULL) {
12087836SJohn.Forte@Sun.COM 				/* make a child node */
12097836SJohn.Forte@Sun.COM 				if (!convert_attr2xml(node, attr,
12107836SJohn.Forte@Sun.COM 				    name, type, 1)) {
12117836SJohn.Forte@Sun.COM 					ec = ISNS_RSP_INTERNAL_ERROR;
12127836SJohn.Forte@Sun.COM 					goto modify_done;
12137836SJohn.Forte@Sun.COM 				}
12147836SJohn.Forte@Sun.COM 			}
12157836SJohn.Forte@Sun.COM 		}
12167836SJohn.Forte@Sun.COM 	} else {
12177836SJohn.Forte@Sun.COM 		/* This case is for registering a node which has */
12187836SJohn.Forte@Sun.COM 		/* membership in one or more non-default DD(s). */
12197836SJohn.Forte@Sun.COM 		ec = xml_add_obj(obj);
12207836SJohn.Forte@Sun.COM 	}
12217836SJohn.Forte@Sun.COM 
12227836SJohn.Forte@Sun.COM modify_done:
12237836SJohn.Forte@Sun.COM 	if (result) {
12247836SJohn.Forte@Sun.COM 		xmlXPathFreeObject(result);
12257836SJohn.Forte@Sun.COM 	}
12267836SJohn.Forte@Sun.COM 	if (context) {
12277836SJohn.Forte@Sun.COM 		xmlXPathFreeContext(context);
12287836SJohn.Forte@Sun.COM 	}
12297836SJohn.Forte@Sun.COM 
12307836SJohn.Forte@Sun.COM 	return (ec);
12317836SJohn.Forte@Sun.COM }
12327836SJohn.Forte@Sun.COM 
12337836SJohn.Forte@Sun.COM /*
12347836SJohn.Forte@Sun.COM  * ****************************************************************************
12357836SJohn.Forte@Sun.COM  *
12367836SJohn.Forte@Sun.COM  * xml_delete_obj:
12377836SJohn.Forte@Sun.COM  *	delete an isns object from the xml data store.
12387836SJohn.Forte@Sun.COM  *
12397836SJohn.Forte@Sun.COM  * obj - the object being deleted.
12407836SJohn.Forte@Sun.COM  * return - error code.
12417836SJohn.Forte@Sun.COM  *
12427836SJohn.Forte@Sun.COM  * ****************************************************************************
12437836SJohn.Forte@Sun.COM  */
12447836SJohn.Forte@Sun.COM static int
xml_delete_obj(const isns_obj_t * obj)12457836SJohn.Forte@Sun.COM xml_delete_obj(
12467836SJohn.Forte@Sun.COM 	const isns_obj_t *obj
12477836SJohn.Forte@Sun.COM )
12487836SJohn.Forte@Sun.COM {
12497836SJohn.Forte@Sun.COM 	int ec = 0;
12507836SJohn.Forte@Sun.COM 	xmlDocPtr doc;
12517836SJohn.Forte@Sun.COM 	xmlXPathContextPtr context = NULL;
12527836SJohn.Forte@Sun.COM 	xmlXPathObjectPtr result = NULL;
12537836SJohn.Forte@Sun.COM 	xmlNodePtr node;
12547836SJohn.Forte@Sun.COM 
12557836SJohn.Forte@Sun.COM 	isns_type_t otype;
12567836SJohn.Forte@Sun.COM 	uint32_t uid;
12577836SJohn.Forte@Sun.COM 
12587836SJohn.Forte@Sun.COM 	/* get the xml doc */
12597836SJohn.Forte@Sun.COM 	ec = get_xml_doc(&doc);
12607836SJohn.Forte@Sun.COM 	if (doc == NULL) {
12617836SJohn.Forte@Sun.COM 		return (ec);
12627836SJohn.Forte@Sun.COM 	}
12637836SJohn.Forte@Sun.COM 
12647836SJohn.Forte@Sun.COM 	otype = obj->type;
12657836SJohn.Forte@Sun.COM #ifdef WRITE_DATA_ASYNC
12667836SJohn.Forte@Sun.COM 	/* it is a thin clone */
12677836SJohn.Forte@Sun.COM 	uid = obj->attrs[0].value.ui;
12687836SJohn.Forte@Sun.COM #else
12697836SJohn.Forte@Sun.COM 	uid = get_obj_uid(obj);
12707836SJohn.Forte@Sun.COM #endif
12717836SJohn.Forte@Sun.COM 
12727836SJohn.Forte@Sun.COM 	/* locate the object */
12737836SJohn.Forte@Sun.COM 	ec = locate_xml_node(doc,
12747836SJohn.Forte@Sun.COM 	    otype,
12757836SJohn.Forte@Sun.COM 	    uid,
12767836SJohn.Forte@Sun.COM 	    &node, &context, &result);
12777836SJohn.Forte@Sun.COM 
12787836SJohn.Forte@Sun.COM 	/* destroy it */
12797836SJohn.Forte@Sun.COM 	if (node) {
12807836SJohn.Forte@Sun.COM 		xmlUnlinkNode(node);
12817836SJohn.Forte@Sun.COM 		xmlFreeNode(node);
12827836SJohn.Forte@Sun.COM 	}
12837836SJohn.Forte@Sun.COM 
12847836SJohn.Forte@Sun.COM 	if (result) {
12857836SJohn.Forte@Sun.COM 		xmlXPathFreeObject(result);
12867836SJohn.Forte@Sun.COM 	}
12877836SJohn.Forte@Sun.COM 	if (context) {
12887836SJohn.Forte@Sun.COM 		xmlXPathFreeContext(context);
12897836SJohn.Forte@Sun.COM 	}
12907836SJohn.Forte@Sun.COM 
12917836SJohn.Forte@Sun.COM 	return (ec);
12927836SJohn.Forte@Sun.COM }
12937836SJohn.Forte@Sun.COM 
12947836SJohn.Forte@Sun.COM /*
12957836SJohn.Forte@Sun.COM  * ****************************************************************************
12967836SJohn.Forte@Sun.COM  *
12977836SJohn.Forte@Sun.COM  * xml_delete_assoc:
12987836SJohn.Forte@Sun.COM  *	delete a DD or DD-set membership from the xml data store.
12997836SJohn.Forte@Sun.COM  *
13007836SJohn.Forte@Sun.COM  * assoc - the membership being deleted.
13017836SJohn.Forte@Sun.COM  * return - error code.
13027836SJohn.Forte@Sun.COM  *
13037836SJohn.Forte@Sun.COM  * ****************************************************************************
13047836SJohn.Forte@Sun.COM  */
13057836SJohn.Forte@Sun.COM static int
xml_delete_assoc(const isns_obj_t * assoc)13067836SJohn.Forte@Sun.COM xml_delete_assoc(
13077836SJohn.Forte@Sun.COM 	const isns_obj_t *assoc
13087836SJohn.Forte@Sun.COM )
13097836SJohn.Forte@Sun.COM {
13107836SJohn.Forte@Sun.COM 	int ec = 0;
13117836SJohn.Forte@Sun.COM 	xmlDocPtr doc;
13127836SJohn.Forte@Sun.COM 	xmlXPathContextPtr context = NULL;
13137836SJohn.Forte@Sun.COM 	xmlXPathObjectPtr result = NULL;
13147836SJohn.Forte@Sun.COM 	xmlNodePtr node;
13157836SJohn.Forte@Sun.COM 
13167836SJohn.Forte@Sun.COM 	uint32_t puid, parent_type;
13177836SJohn.Forte@Sun.COM 	uint32_t uid, match_uid;
13187836SJohn.Forte@Sun.COM 
13197836SJohn.Forte@Sun.COM 	char prop;
13207836SJohn.Forte@Sun.COM 	const xmlChar *prop_name;
13217836SJohn.Forte@Sun.COM 	xmlChar *prop_value;
13227836SJohn.Forte@Sun.COM 	int i;
13237836SJohn.Forte@Sun.COM 
13247836SJohn.Forte@Sun.COM 	/* get the xml doc */
13257836SJohn.Forte@Sun.COM 	ec = get_xml_doc(&doc);
13267836SJohn.Forte@Sun.COM 	if (doc == NULL) {
13277836SJohn.Forte@Sun.COM 		return (ec);
13287836SJohn.Forte@Sun.COM 	}
13297836SJohn.Forte@Sun.COM 
13307836SJohn.Forte@Sun.COM 	/* get the container object UID */
13317836SJohn.Forte@Sun.COM 	parent_type = TYPE_OF_PARENT[assoc->type];
13327836SJohn.Forte@Sun.COM 	ASSERT(parent_type != 0);
13337836SJohn.Forte@Sun.COM 	puid = get_parent_uid(assoc);
13347836SJohn.Forte@Sun.COM 	ASSERT(puid != 0);
13357836SJohn.Forte@Sun.COM 
13367836SJohn.Forte@Sun.COM 	/* get the member object UID */
13377836SJohn.Forte@Sun.COM 	i = get_index_by_otype(assoc->type);
13387836SJohn.Forte@Sun.COM 	prop = xmlArg2[i] - 'a';
13397836SJohn.Forte@Sun.COM 	prop_name = xmlPropName[prop];
13407836SJohn.Forte@Sun.COM 	match_uid = assoc->attrs[UID_ATTR_INDEX[assoc->type]].value.ui;
13417836SJohn.Forte@Sun.COM 
13427836SJohn.Forte@Sun.COM 	/* locate the container object */
13437836SJohn.Forte@Sun.COM 	ec = locate_xml_node(doc, parent_type, puid,
13447836SJohn.Forte@Sun.COM 	    &node, &context, &result);
13457836SJohn.Forte@Sun.COM 
13467836SJohn.Forte@Sun.COM 	/* get the membership nodes */
13477836SJohn.Forte@Sun.COM 	if (node != NULL) {
13487836SJohn.Forte@Sun.COM 		node = node->children;
13497836SJohn.Forte@Sun.COM 	}
13507836SJohn.Forte@Sun.COM 
13517836SJohn.Forte@Sun.COM 	/* get the matching membership node */
13527836SJohn.Forte@Sun.COM 	while (node) {
13537836SJohn.Forte@Sun.COM 		if (node->type == XML_ELEMENT_NODE) {
13547836SJohn.Forte@Sun.COM 			i = get_index_by_name(node->name);
13557836SJohn.Forte@Sun.COM 			ASSERT(i >= 0);
13567836SJohn.Forte@Sun.COM 			if (xmlType[i][0] == 'o' &&
13577836SJohn.Forte@Sun.COM 			    xmlArg1[i] == assoc->type) {
13587836SJohn.Forte@Sun.COM 				prop_value = xmlGetProp(node, prop_name);
13597836SJohn.Forte@Sun.COM 				if (prop_value) {
13607836SJohn.Forte@Sun.COM 					uid = atoi((const char *)prop_value);
13617836SJohn.Forte@Sun.COM 					xmlFree(prop_value);
13627836SJohn.Forte@Sun.COM 					if (uid == match_uid) {
13637836SJohn.Forte@Sun.COM 						break;
13647836SJohn.Forte@Sun.COM 					}
13657836SJohn.Forte@Sun.COM 				}
13667836SJohn.Forte@Sun.COM 			}
13677836SJohn.Forte@Sun.COM 		}
13687836SJohn.Forte@Sun.COM 		node = node->next;
13697836SJohn.Forte@Sun.COM 	}
13707836SJohn.Forte@Sun.COM 
13717836SJohn.Forte@Sun.COM 	/* destroy it */
13727836SJohn.Forte@Sun.COM 	if (node) {
13737836SJohn.Forte@Sun.COM 		xmlUnlinkNode(node);
13747836SJohn.Forte@Sun.COM 		xmlFreeNode(node);
13757836SJohn.Forte@Sun.COM 	}
13767836SJohn.Forte@Sun.COM 
13777836SJohn.Forte@Sun.COM 	if (result) {
13787836SJohn.Forte@Sun.COM 		xmlXPathFreeObject(result);
13797836SJohn.Forte@Sun.COM 	}
13807836SJohn.Forte@Sun.COM 	if (context) {
13817836SJohn.Forte@Sun.COM 		xmlXPathFreeContext(context);
13827836SJohn.Forte@Sun.COM 	}
13837836SJohn.Forte@Sun.COM 
13847836SJohn.Forte@Sun.COM 	return (ec);
13857836SJohn.Forte@Sun.COM }
13867836SJohn.Forte@Sun.COM 
13877836SJohn.Forte@Sun.COM /*
13887836SJohn.Forte@Sun.COM  * ****************************************************************************
13897836SJohn.Forte@Sun.COM  *
13907836SJohn.Forte@Sun.COM  * xml_update_commit:
13917836SJohn.Forte@Sun.COM  *	backup the current written file and commit all updates from
13927836SJohn.Forte@Sun.COM  *	the xml doc to the written file.
13937836SJohn.Forte@Sun.COM  *
13947836SJohn.Forte@Sun.COM  * return - error code.
13957836SJohn.Forte@Sun.COM  *
13967836SJohn.Forte@Sun.COM  * ****************************************************************************
13977836SJohn.Forte@Sun.COM  */
13987836SJohn.Forte@Sun.COM static int
xml_update_commit()13997836SJohn.Forte@Sun.COM xml_update_commit(
14007836SJohn.Forte@Sun.COM )
14017836SJohn.Forte@Sun.COM {
14027836SJohn.Forte@Sun.COM 	int ec = 0;
14037836SJohn.Forte@Sun.COM 
14047836SJohn.Forte@Sun.COM 	if (xml_doc) {
14057836SJohn.Forte@Sun.COM 		/* write to tmp file */
14067836SJohn.Forte@Sun.COM 		if (xmlSaveFormatFile(xml_tmp_file, xml_doc, 1) == -1 ||
14077836SJohn.Forte@Sun.COM 		    /* backup the current file */
14087836SJohn.Forte@Sun.COM 		    rename(xml_file, xml_bak_file) != 0 ||
14097836SJohn.Forte@Sun.COM 		    /* rename the tmp file to the current file */
14107836SJohn.Forte@Sun.COM 		    rename(xml_tmp_file, xml_file) != 0) {
14117836SJohn.Forte@Sun.COM 			/* failed saving file */
14127836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INTERNAL_ERROR;
14137836SJohn.Forte@Sun.COM 		}
14147836SJohn.Forte@Sun.COM 		/* close the xml_doc */
14157836SJohn.Forte@Sun.COM 		xmlFreeDoc(xml_doc);
14167836SJohn.Forte@Sun.COM 		xml_doc = NULL;
14177836SJohn.Forte@Sun.COM 	}
14187836SJohn.Forte@Sun.COM 
14197836SJohn.Forte@Sun.COM 	return (ec);
14207836SJohn.Forte@Sun.COM }
14217836SJohn.Forte@Sun.COM 
14227836SJohn.Forte@Sun.COM /*
14237836SJohn.Forte@Sun.COM  * ****************************************************************************
14247836SJohn.Forte@Sun.COM  *
14257836SJohn.Forte@Sun.COM  * xml_update_retreat:
14267836SJohn.Forte@Sun.COM  *	ignore all of updates in the xml doc.
14277836SJohn.Forte@Sun.COM  *
14287836SJohn.Forte@Sun.COM  * return - 0: always successful.
14297836SJohn.Forte@Sun.COM  *
14307836SJohn.Forte@Sun.COM  * ****************************************************************************
14317836SJohn.Forte@Sun.COM  */
14327836SJohn.Forte@Sun.COM static int
xml_update_retreat()14337836SJohn.Forte@Sun.COM xml_update_retreat(
14347836SJohn.Forte@Sun.COM )
14357836SJohn.Forte@Sun.COM {
14367836SJohn.Forte@Sun.COM 	if (xml_doc) {
14377836SJohn.Forte@Sun.COM 		/* close the xml_doc */
14387836SJohn.Forte@Sun.COM 		xmlFreeDoc(xml_doc);
14397836SJohn.Forte@Sun.COM 		xml_doc = NULL;
14407836SJohn.Forte@Sun.COM 	}
14417836SJohn.Forte@Sun.COM 
14427836SJohn.Forte@Sun.COM 	return (0);
14437836SJohn.Forte@Sun.COM }
1444