xref: /titanic_50/usr/src/cmd/isns/isnsd/xml/data.c (revision 996d4a4cf95f66535e1588ba405de1c0f9843c6e)
1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte 
22fcf3ce44SJohn Forte /*
23530e2b59Swl202157@icefox  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24fcf3ce44SJohn Forte  * Use is subject to license terms.
25fcf3ce44SJohn Forte  */
26fcf3ce44SJohn Forte 
27fcf3ce44SJohn Forte #include <stdio.h>
28fcf3ce44SJohn Forte #include <stdlib.h>
29fcf3ce44SJohn Forte #include <unistd.h>
30fcf3ce44SJohn Forte #include <libgen.h>
31fcf3ce44SJohn Forte #include <string.h>
32fcf3ce44SJohn Forte #include <sys/types.h>
33fcf3ce44SJohn Forte #include <sys/stat.h>
34fcf3ce44SJohn Forte #include <sys/socket.h>
35fcf3ce44SJohn Forte #include <netinet/in.h>
36fcf3ce44SJohn Forte #include <arpa/inet.h>
37fcf3ce44SJohn Forte #include <errno.h>
38fcf3ce44SJohn Forte #include <fcntl.h>
39fcf3ce44SJohn Forte #include <libxml/parser.h>
40fcf3ce44SJohn Forte #include <libxml/xpath.h>
41fcf3ce44SJohn Forte 
42fcf3ce44SJohn Forte #include "isns_server.h"
43fcf3ce44SJohn Forte #include "isns_obj.h"
44fcf3ce44SJohn Forte #include "isns_log.h"
45fcf3ce44SJohn Forte 
46*996d4a4cSAlexander Pyhalov #if LIBXML_VERSION >= 20904
47*996d4a4cSAlexander Pyhalov #define	XMLSTRING_CAST (const char *)
48*996d4a4cSAlexander Pyhalov #else
49*996d4a4cSAlexander Pyhalov #define	XMLSTRING_CAST (const xmlChar *)
50*996d4a4cSAlexander Pyhalov #endif
51*996d4a4cSAlexander Pyhalov 
52fcf3ce44SJohn Forte /*
53fcf3ce44SJohn Forte  * external variables
54fcf3ce44SJohn Forte  */
55fcf3ce44SJohn Forte extern const int NUM_OF_ATTRS[MAX_OBJ_TYPE_FOR_SIZE];
56fcf3ce44SJohn Forte extern const int TYPE_OF_PARENT[MAX_OBJ_TYPE_FOR_SIZE];
57fcf3ce44SJohn Forte extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE];
58fcf3ce44SJohn Forte 
59fcf3ce44SJohn Forte extern char data_store[MAXPATHLEN];
60fcf3ce44SJohn Forte 
61fcf3ce44SJohn Forte /*
62fcf3ce44SJohn Forte  * local variables
63fcf3ce44SJohn Forte  */
64fcf3ce44SJohn Forte static xmlDocPtr xml_doc = NULL;
65fcf3ce44SJohn Forte static char *xml_file = NULL;
66fcf3ce44SJohn Forte static char *xml_tmp_file = NULL;
67fcf3ce44SJohn Forte static char *xml_bak_file = NULL;
68fcf3ce44SJohn Forte 
69fcf3ce44SJohn Forte static const int OBJ_DTD_ORDER[MAX_OBJ_TYPE_FOR_SIZE] = {
70fcf3ce44SJohn Forte 	0,
71fcf3ce44SJohn Forte 	1,	/* OBJ_ENTITY */
72fcf3ce44SJohn Forte 	2,	/* OBJ_ISCSI */
73fcf3ce44SJohn Forte 	3,	/* OBJ_PORTAL */
74fcf3ce44SJohn Forte 	4,	/* OBJ_PG */
75fcf3ce44SJohn Forte 	5,	/* OBJ_DD */
76fcf3ce44SJohn Forte 	6,	/* OBJ_DDS */
77fcf3ce44SJohn Forte 	0,	/* MAX_OBJ_TYPE */
78fcf3ce44SJohn Forte 	0,	/* OBJ_DUMMY1 */
79fcf3ce44SJohn Forte 	0,	/* OBJ_DUMMY2 */
80fcf3ce44SJohn Forte 	0,	/* OBJ_DUMMY3 */
81fcf3ce44SJohn Forte 	0,	/* OBJ_DUMMY4 */
82fcf3ce44SJohn Forte 	12,	/* OBJ_ASSOC_ISCSI */
83fcf3ce44SJohn Forte 	14,	/* OBJ_ASSOC_DD */
84fcf3ce44SJohn Forte };
85fcf3ce44SJohn Forte 
86fcf3ce44SJohn Forte #define	DEF_XML_ROOT(ISNS_DATA, VENDOR, SMI, VERSION, ONE_DOT_O) \
87fcf3ce44SJohn Forte 	(xmlChar *)ISNS_DATA, \
88fcf3ce44SJohn Forte 	(xmlChar *)VENDOR, \
89fcf3ce44SJohn Forte 	(xmlChar *)SMI, \
90fcf3ce44SJohn Forte 	(xmlChar *)VERSION, \
91fcf3ce44SJohn Forte 	(xmlChar *)ONE_DOT_O
92fcf3ce44SJohn Forte static const xmlChar *xml_root[] = {
93fcf3ce44SJohn Forte #include "data.def"
94fcf3ce44SJohn Forte };
95fcf3ce44SJohn Forte 
96fcf3ce44SJohn Forte #define	DEF_XML_DATA(TAG, TYPE, ARG1, ARG2) (xmlChar *)TAG,
97fcf3ce44SJohn Forte static const xmlChar* xmlTag[] = {
98fcf3ce44SJohn Forte #include "data.def"
99fcf3ce44SJohn Forte };
100fcf3ce44SJohn Forte 
101fcf3ce44SJohn Forte #define	DEF_XML_DATA(TAG, TYPE, ARG1, ARG2) TYPE,
102fcf3ce44SJohn Forte static const char *xmlType[] = {
103fcf3ce44SJohn Forte #include "data.def"
104fcf3ce44SJohn Forte };
105fcf3ce44SJohn Forte 
106fcf3ce44SJohn Forte #define	DEF_XML_DATA(TAG, TYPE, ARG1, ARG2) ARG1,
107fcf3ce44SJohn Forte static const int xmlArg1[] = {
108fcf3ce44SJohn Forte #include "data.def"
109fcf3ce44SJohn Forte };
110fcf3ce44SJohn Forte 
111fcf3ce44SJohn Forte #define	DEF_XML_DATA(TAG, TYPE, ARG1, ARG2) ARG2,
112fcf3ce44SJohn Forte static const int xmlArg2[] = {
113fcf3ce44SJohn Forte #include "data.def"
114fcf3ce44SJohn Forte };
115fcf3ce44SJohn Forte 
116fcf3ce44SJohn Forte #define	DEF_XML_PROP(INDEX, TYPE, NAME, TAG, ID) TYPE,
117fcf3ce44SJohn Forte static const unsigned char xmlPropType[] = {
118fcf3ce44SJohn Forte #include "data.def"
119fcf3ce44SJohn Forte };
120fcf3ce44SJohn Forte 
121fcf3ce44SJohn Forte #define	DEF_XML_PROP(INDEX, TYPE, NAME, TAG, ID) (xmlChar *)NAME,
122fcf3ce44SJohn Forte static const xmlChar *xmlPropName[] = {
123fcf3ce44SJohn Forte #include "data.def"
124fcf3ce44SJohn Forte };
125fcf3ce44SJohn Forte 
126fcf3ce44SJohn Forte #define	DEF_XML_PROP(INDEX, TYPE, NAME, TAG, ID) TAG,
127fcf3ce44SJohn Forte static const int xmlPropTag[] = {
128fcf3ce44SJohn Forte #include "data.def"
129fcf3ce44SJohn Forte };
130fcf3ce44SJohn Forte 
131fcf3ce44SJohn Forte #define	DEF_XML_PROP(INDEX, TYPE, NAME, TAG, ID) ID,
132fcf3ce44SJohn Forte static const int xmlPropID[] = {
133fcf3ce44SJohn Forte #include "data.def"
134fcf3ce44SJohn Forte };
135fcf3ce44SJohn Forte 
136fcf3ce44SJohn Forte #define	ARRAY_LENGTH(ARRAY) (sizeof (ARRAY) / sizeof (ARRAY[0]))
137fcf3ce44SJohn Forte 
138fcf3ce44SJohn Forte /*
139fcf3ce44SJohn Forte  * ****************************************************************************
140fcf3ce44SJohn Forte  *
141fcf3ce44SJohn Forte  * get_index_by_name:
142fcf3ce44SJohn Forte  *	find the index in the global tables for the name of an attribute.
143fcf3ce44SJohn Forte  *
144fcf3ce44SJohn Forte  * name - the name of an attribute.
145fcf3ce44SJohn Forte  * return - index or -1 for error.
146fcf3ce44SJohn Forte  *
147fcf3ce44SJohn Forte  * ****************************************************************************
148fcf3ce44SJohn Forte  */
149fcf3ce44SJohn Forte static int
get_index_by_name(const xmlChar * name)150fcf3ce44SJohn Forte get_index_by_name(
151fcf3ce44SJohn Forte 	const xmlChar *name
152fcf3ce44SJohn Forte )
153fcf3ce44SJohn Forte {
154fcf3ce44SJohn Forte 	int i;
155fcf3ce44SJohn Forte 	for (i = 0; i < ARRAY_LENGTH(xmlTag); i++) {
156fcf3ce44SJohn Forte 		if (xmlStrEqual(xmlTag[i], name)) {
157fcf3ce44SJohn Forte 			return (i);
158fcf3ce44SJohn Forte 		}
159fcf3ce44SJohn Forte 	}
160fcf3ce44SJohn Forte 	return (-1);
161fcf3ce44SJohn Forte }
162fcf3ce44SJohn Forte 
163fcf3ce44SJohn Forte /*
164fcf3ce44SJohn Forte  * ****************************************************************************
165fcf3ce44SJohn Forte  *
166fcf3ce44SJohn Forte  * get_index_by_otype:
167fcf3ce44SJohn Forte  *	find the index in the global tables for the type of an object.
168fcf3ce44SJohn Forte  *
169fcf3ce44SJohn Forte  * name - the type of an object.
170fcf3ce44SJohn Forte  * return - index or -1 for error.
171fcf3ce44SJohn Forte  *
172fcf3ce44SJohn Forte  * ****************************************************************************
173fcf3ce44SJohn Forte  */
174fcf3ce44SJohn Forte static int
get_index_by_otype(int otype)175fcf3ce44SJohn Forte get_index_by_otype(
176fcf3ce44SJohn Forte 	int otype
177fcf3ce44SJohn Forte )
178fcf3ce44SJohn Forte {
179fcf3ce44SJohn Forte 	int i;
180fcf3ce44SJohn Forte 	for (i = 0; i < ARRAY_LENGTH(xmlTag); i++) {
181fcf3ce44SJohn Forte 		if (xmlArg1[i] == otype && xmlType[i][0] == 'o') {
182fcf3ce44SJohn Forte 			return (i);
183fcf3ce44SJohn Forte 		}
184fcf3ce44SJohn Forte 	}
185fcf3ce44SJohn Forte 	return (-1);
186fcf3ce44SJohn Forte }
187fcf3ce44SJohn Forte 
188fcf3ce44SJohn Forte /*
189fcf3ce44SJohn Forte  * ****************************************************************************
190fcf3ce44SJohn Forte  *
191fcf3ce44SJohn Forte  * get_index_by_tag:
192fcf3ce44SJohn Forte  *	find the index in the global tables for the tag of an attribute.
193fcf3ce44SJohn Forte  *
194fcf3ce44SJohn Forte  * name - the tag of an attribute.
195fcf3ce44SJohn Forte  * return - index or -1 for error.
196fcf3ce44SJohn Forte  *
197fcf3ce44SJohn Forte  * ****************************************************************************
198fcf3ce44SJohn Forte  */
199fcf3ce44SJohn Forte static int
get_index_by_tag(int tag)200fcf3ce44SJohn Forte get_index_by_tag(
201fcf3ce44SJohn Forte 	int tag
202fcf3ce44SJohn Forte )
203fcf3ce44SJohn Forte {
204fcf3ce44SJohn Forte 	int i;
205fcf3ce44SJohn Forte 	for (i = 0; i < ARRAY_LENGTH(xmlTag); i++) {
206fcf3ce44SJohn Forte 		if (xmlArg1[i] == tag &&
207fcf3ce44SJohn Forte 		    xmlType[i][0] != 'o' &&
208fcf3ce44SJohn Forte 		    xmlType[i][0] != 'a') {
209fcf3ce44SJohn Forte 			return (i);
210fcf3ce44SJohn Forte 		}
211fcf3ce44SJohn Forte 	}
212fcf3ce44SJohn Forte 	return (-1);
213fcf3ce44SJohn Forte }
214fcf3ce44SJohn Forte 
215fcf3ce44SJohn Forte /*
216fcf3ce44SJohn Forte  * ****************************************************************************
217fcf3ce44SJohn Forte  *
218fcf3ce44SJohn Forte  * get_xml_doc:
219fcf3ce44SJohn Forte  *	open the xml file and assign the global xml doc if the xml file
220fcf3ce44SJohn Forte  *	is not opened, set the doc pointer with the opened xml file for
221fcf3ce44SJohn Forte  *	returnning.
222fcf3ce44SJohn Forte  *
223fcf3ce44SJohn Forte  * docp - the doc pointer for returning.
224fcf3ce44SJohn Forte  * return - error code.
225fcf3ce44SJohn Forte  *
226fcf3ce44SJohn Forte  * ****************************************************************************
227fcf3ce44SJohn Forte  */
228fcf3ce44SJohn Forte static int
get_xml_doc(xmlDocPtr * docp)229fcf3ce44SJohn Forte get_xml_doc(
230fcf3ce44SJohn Forte 	xmlDocPtr *docp
231fcf3ce44SJohn Forte )
232fcf3ce44SJohn Forte {
233fcf3ce44SJohn Forte 	int ec = 0;
234fcf3ce44SJohn Forte 
235fcf3ce44SJohn Forte 	if (xml_doc == NULL) {
236fcf3ce44SJohn Forte 		/* validate the xml file */
237fcf3ce44SJohn Forte 
238fcf3ce44SJohn Forte 		/* open the xml file */
239fcf3ce44SJohn Forte 		xml_doc = xmlParseFile(xml_file);
240fcf3ce44SJohn Forte 	}
241fcf3ce44SJohn Forte 
242fcf3ce44SJohn Forte 	*docp = xml_doc;
243fcf3ce44SJohn Forte 
244fcf3ce44SJohn Forte 	if (xml_doc == NULL) {
245fcf3ce44SJohn Forte 		ec = ISNS_RSP_INTERNAL_ERROR;
246fcf3ce44SJohn Forte 	}
247fcf3ce44SJohn Forte 
248fcf3ce44SJohn Forte 	return (ec);
249fcf3ce44SJohn Forte }
250fcf3ce44SJohn Forte 
251fcf3ce44SJohn Forte /*
252fcf3ce44SJohn Forte  * ****************************************************************************
253fcf3ce44SJohn Forte  *
254fcf3ce44SJohn Forte  * close_xml_doc:
255fcf3ce44SJohn Forte  *	close the global xml doc and ignore any changes that has been
256fcf3ce44SJohn Forte  *	made in it.
257fcf3ce44SJohn Forte  *
258fcf3ce44SJohn Forte  * ****************************************************************************
259fcf3ce44SJohn Forte  */
260fcf3ce44SJohn Forte static void
close_xml_doc()261fcf3ce44SJohn Forte close_xml_doc(
262fcf3ce44SJohn Forte )
263fcf3ce44SJohn Forte {
264fcf3ce44SJohn Forte 	if (xml_doc) {
265fcf3ce44SJohn Forte 		/* just close it */
266fcf3ce44SJohn Forte 		xmlFreeDoc(xml_doc);
267fcf3ce44SJohn Forte 		xml_doc = NULL;
268fcf3ce44SJohn Forte 	}
269fcf3ce44SJohn Forte }
270fcf3ce44SJohn Forte 
271fcf3ce44SJohn Forte /*
272fcf3ce44SJohn Forte  * ****************************************************************************
273fcf3ce44SJohn Forte  *
274fcf3ce44SJohn Forte  * convert_xml2attr:
275fcf3ce44SJohn Forte  *	convert a xml data to a TLV format isns attribute.
276fcf3ce44SJohn Forte  *
277fcf3ce44SJohn Forte  * tag - the tag of attribute.
278fcf3ce44SJohn Forte  * type - the data type of the xml data.
279fcf3ce44SJohn Forte  * value - the xml data.
280fcf3ce44SJohn Forte  * attr - TLV format attribute for returning.
281fcf3ce44SJohn Forte  * return - error code.
282fcf3ce44SJohn Forte  *
283fcf3ce44SJohn Forte  * ****************************************************************************
284fcf3ce44SJohn Forte  */
285fcf3ce44SJohn Forte static int
convert_xml2attr(const int tag,const unsigned char type,xmlChar * value,isns_attr_t * attr)286fcf3ce44SJohn Forte convert_xml2attr(
287fcf3ce44SJohn Forte 	const int tag,
288fcf3ce44SJohn Forte 	const unsigned char type,
289fcf3ce44SJohn Forte 	xmlChar *value,
290fcf3ce44SJohn Forte 	isns_attr_t *attr
291fcf3ce44SJohn Forte )
292fcf3ce44SJohn Forte {
293fcf3ce44SJohn Forte 	uint32_t len;
294fcf3ce44SJohn Forte 	int ec = 0;
295fcf3ce44SJohn Forte 
296fcf3ce44SJohn Forte 	attr->tag = tag;
297fcf3ce44SJohn Forte 	switch (type) {
298fcf3ce44SJohn Forte 		case 'u':
299fcf3ce44SJohn Forte 			/* 4-bytes non-negative integer */
300fcf3ce44SJohn Forte 			attr->len = 4;
301fcf3ce44SJohn Forte 			attr->value.ui = atoi((const char *)value);
302fcf3ce44SJohn Forte 			break;
303fcf3ce44SJohn Forte 		case 's':
304fcf3ce44SJohn Forte 			/* literal string */
305fcf3ce44SJohn Forte 			len = strlen((char *)value);
306fcf3ce44SJohn Forte 			len += 4 - (len % 4);
307fcf3ce44SJohn Forte 			attr->len = len;
308fcf3ce44SJohn Forte 			attr->value.ptr = (uchar_t *)malloc(attr->len);
309fcf3ce44SJohn Forte 			if (attr->value.ptr != NULL) {
310fcf3ce44SJohn Forte 				(void) strcpy((char *)attr->value.ptr,
311fcf3ce44SJohn Forte 				    (char *)value);
312fcf3ce44SJohn Forte 			} else {
313fcf3ce44SJohn Forte 				ec = ISNS_RSP_INTERNAL_ERROR;
314fcf3ce44SJohn Forte 			}
315fcf3ce44SJohn Forte 			break;
316fcf3ce44SJohn Forte 		case 'p':
317fcf3ce44SJohn Forte 			/* IPv6 block data */
318fcf3ce44SJohn Forte 			attr->len = sizeof (in6_addr_t);
319fcf3ce44SJohn Forte 			attr->value.ip = (in6_addr_t *)malloc(attr->len);
320fcf3ce44SJohn Forte 			if (attr->value.ip != NULL) {
321fcf3ce44SJohn Forte 				(void) inet_pton(AF_INET6,
322fcf3ce44SJohn Forte 				    (char *)value,
323fcf3ce44SJohn Forte 				    attr->value.ip);
324fcf3ce44SJohn Forte 			} else {
325fcf3ce44SJohn Forte 				ec = ISNS_RSP_INTERNAL_ERROR;
326fcf3ce44SJohn Forte 			}
327fcf3ce44SJohn Forte 			break;
328fcf3ce44SJohn Forte 		default:
329fcf3ce44SJohn Forte 			break;
330fcf3ce44SJohn Forte 	}
331fcf3ce44SJohn Forte 
332fcf3ce44SJohn Forte 	return (ec);
333fcf3ce44SJohn Forte }
334fcf3ce44SJohn Forte 
335fcf3ce44SJohn Forte /*
336fcf3ce44SJohn Forte  * ****************************************************************************
337fcf3ce44SJohn Forte  *
338fcf3ce44SJohn Forte  * convert_attr2xml:
339fcf3ce44SJohn Forte  *	convert a TLV format isns attribute to xml node format.
340fcf3ce44SJohn Forte  *
341fcf3ce44SJohn Forte  * node - the xml node where the new node is being added to.
342fcf3ce44SJohn Forte  * attr - the TLV format attribute.
343fcf3ce44SJohn Forte  * name - the name of the attribute in xml node.
344fcf3ce44SJohn Forte  * type - the data type of the attribute.
345fcf3ce44SJohn Forte  * elm_flag - 0: adding a xml attlist.
346fcf3ce44SJohn Forte  *	      1: adding a xml child node.
347fcf3ce44SJohn Forte  *	      2: adding a previous sibling node.
348fcf3ce44SJohn Forte  *	      3: adding a xml content node.
349fcf3ce44SJohn Forte  *	      4: adding a xml attribute.
350fcf3ce44SJohn Forte  * return - xml node.
351fcf3ce44SJohn Forte  *
352fcf3ce44SJohn Forte  * ****************************************************************************
353fcf3ce44SJohn Forte  */
354fcf3ce44SJohn Forte static xmlNodePtr
convert_attr2xml(xmlNodePtr node,const isns_attr_t * attr,const xmlChar * name,const char type,const int elm_flag)355fcf3ce44SJohn Forte convert_attr2xml(
356fcf3ce44SJohn Forte 	xmlNodePtr node,
357fcf3ce44SJohn Forte 	const isns_attr_t *attr,
358fcf3ce44SJohn Forte 	const xmlChar *name,
359fcf3ce44SJohn Forte 	const char type,
360fcf3ce44SJohn Forte 	const int elm_flag
361fcf3ce44SJohn Forte )
362fcf3ce44SJohn Forte {
363fcf3ce44SJohn Forte 	xmlChar buff[INET6_ADDRSTRLEN + 1] = { 0 };
364fcf3ce44SJohn Forte 	xmlChar *value = NULL;
365fcf3ce44SJohn Forte 	xmlNodePtr child = NULL;
366fcf3ce44SJohn Forte 
367fcf3ce44SJohn Forte 	switch (type) {
368fcf3ce44SJohn Forte 		case 'u':
369fcf3ce44SJohn Forte 			/* 4-bytes non-negative integer */
370fcf3ce44SJohn Forte 			if (xmlStrPrintf(buff, sizeof (buff),
371*996d4a4cSAlexander Pyhalov 			    XMLSTRING_CAST "%u",
372fcf3ce44SJohn Forte 			    attr->value.ui) > 0) {
373fcf3ce44SJohn Forte 				value = (xmlChar *)&buff;
374fcf3ce44SJohn Forte 			}
375fcf3ce44SJohn Forte 			break;
376fcf3ce44SJohn Forte 		case 's':
377fcf3ce44SJohn Forte 			/* literal string */
378fcf3ce44SJohn Forte 			value = (xmlChar *)attr->value.ptr;
379fcf3ce44SJohn Forte 			break;
380fcf3ce44SJohn Forte 		case 'p':
381fcf3ce44SJohn Forte 			/* IPv6 block data */
382fcf3ce44SJohn Forte 			value = (xmlChar *)inet_ntop(AF_INET6,
383fcf3ce44SJohn Forte 			    (char *)attr->value.ip,
384fcf3ce44SJohn Forte 			    (char *)buff,
385fcf3ce44SJohn Forte 			    sizeof (buff));
386fcf3ce44SJohn Forte 			break;
387fcf3ce44SJohn Forte 		default:
388fcf3ce44SJohn Forte 			break;
389fcf3ce44SJohn Forte 	}
390fcf3ce44SJohn Forte 
391fcf3ce44SJohn Forte 	if (!value) {
392fcf3ce44SJohn Forte 		return (NULL);
393fcf3ce44SJohn Forte 	}
394fcf3ce44SJohn Forte 
395fcf3ce44SJohn Forte 	switch (elm_flag) {
396fcf3ce44SJohn Forte 		case 0: /* attlist */
397fcf3ce44SJohn Forte 			if (xmlSetProp(node, name, value)) {
398fcf3ce44SJohn Forte 				child = node;
399fcf3ce44SJohn Forte 			}
400fcf3ce44SJohn Forte 			break;
401fcf3ce44SJohn Forte 		case 1: /* child element */
402fcf3ce44SJohn Forte 			child = xmlNewChild(node, NULL, name, value);
403fcf3ce44SJohn Forte 			break;
404fcf3ce44SJohn Forte 		case 2: /* prev sibling element */
405fcf3ce44SJohn Forte 			child = xmlNewNode(NULL, name);
406fcf3ce44SJohn Forte 			if (child != NULL &&
407fcf3ce44SJohn Forte 			    xmlAddPrevSibling(node, child) == NULL) {
408fcf3ce44SJohn Forte 				xmlFreeNode(child);
409fcf3ce44SJohn Forte 				node = NULL;
410fcf3ce44SJohn Forte 			} else {
411fcf3ce44SJohn Forte 				node = child;
412fcf3ce44SJohn Forte 			}
413fcf3ce44SJohn Forte 			/* LINTED E_CASE_FALLTHRU */
414fcf3ce44SJohn Forte 		case 3: /* set content */
415fcf3ce44SJohn Forte 			if (node) {
416fcf3ce44SJohn Forte 				xmlNodeSetContent(node, value);
417fcf3ce44SJohn Forte 			}
418fcf3ce44SJohn Forte 			child = node;
419fcf3ce44SJohn Forte 			break;
420fcf3ce44SJohn Forte 		case 4: /* new attr value */
421fcf3ce44SJohn Forte 			if (xmlSetProp(node, name, value)) {
422fcf3ce44SJohn Forte 				child = node;
423fcf3ce44SJohn Forte 			}
424fcf3ce44SJohn Forte 			break;
425fcf3ce44SJohn Forte 		default:
426fcf3ce44SJohn Forte 			ASSERT(0);
427fcf3ce44SJohn Forte 			break;
428fcf3ce44SJohn Forte 	}
429fcf3ce44SJohn Forte 
430fcf3ce44SJohn Forte 	return (child);
431fcf3ce44SJohn Forte }
432fcf3ce44SJohn Forte 
433fcf3ce44SJohn Forte /*
434fcf3ce44SJohn Forte  * ****************************************************************************
435fcf3ce44SJohn Forte  *
436fcf3ce44SJohn Forte  * parse_xml_prop:
437fcf3ce44SJohn Forte  *	parse the properties of a xml node and convert them to the attributes
438fcf3ce44SJohn Forte  *	of an isns object, these xml properties are the UID attribute and
439fcf3ce44SJohn Forte  *	key attributes of the isns object.
440fcf3ce44SJohn Forte  *
441fcf3ce44SJohn Forte  * node - the xml node that contains the properties.
442fcf3ce44SJohn Forte  * obj - the isns object.
443fcf3ce44SJohn Forte  * i  - the index of the attribute in the global tables.
444fcf3ce44SJohn Forte  * return - error code.
445fcf3ce44SJohn Forte  *
446fcf3ce44SJohn Forte  * ****************************************************************************
447fcf3ce44SJohn Forte  */
448fcf3ce44SJohn Forte static int
parse_xml_prop(xmlNodePtr node,isns_obj_t * obj,int i)449fcf3ce44SJohn Forte parse_xml_prop(
450fcf3ce44SJohn Forte 	xmlNodePtr node,
451fcf3ce44SJohn Forte 	isns_obj_t *obj,
452fcf3ce44SJohn Forte 	int i
453fcf3ce44SJohn Forte )
454fcf3ce44SJohn Forte {
455fcf3ce44SJohn Forte 	int ec = 0;
456fcf3ce44SJohn Forte 	const char *props = &xmlType[i][1];
457fcf3ce44SJohn Forte 	const xmlChar *prop_name;
458fcf3ce44SJohn Forte 	xmlChar *prop_value;
459fcf3ce44SJohn Forte 	unsigned char prop_type;
460fcf3ce44SJohn Forte 	int prop_tag;
461fcf3ce44SJohn Forte 	int prop_id;
462fcf3ce44SJohn Forte 	char prop;
463fcf3ce44SJohn Forte 	int j;
464fcf3ce44SJohn Forte 
465fcf3ce44SJohn Forte 	j = 0;
466fcf3ce44SJohn Forte 	prop = props[j ++];
467fcf3ce44SJohn Forte 	while (ec == 0 &&
468fcf3ce44SJohn Forte 	    prop >= 'a' && prop <= 'z') {
469fcf3ce44SJohn Forte 		prop -= 'a';
470fcf3ce44SJohn Forte 		prop_id = xmlPropID[prop];
471fcf3ce44SJohn Forte 		prop_tag = xmlPropTag[prop];
472fcf3ce44SJohn Forte 		prop_name = xmlPropName[prop];
473fcf3ce44SJohn Forte 		prop_type = xmlPropType[prop];
474fcf3ce44SJohn Forte 		prop_value = xmlGetProp(node, prop_name);
475fcf3ce44SJohn Forte 
476fcf3ce44SJohn Forte 		if (prop_value) {
477fcf3ce44SJohn Forte 			ec = convert_xml2attr(
478fcf3ce44SJohn Forte 			    prop_tag,
479fcf3ce44SJohn Forte 			    prop_type,
480fcf3ce44SJohn Forte 			    prop_value,
481fcf3ce44SJohn Forte 			    &(obj->attrs[prop_id]));
482fcf3ce44SJohn Forte 			xmlFree(prop_value);
483fcf3ce44SJohn Forte 		}
484fcf3ce44SJohn Forte 		prop = props[j ++];
485fcf3ce44SJohn Forte 	}
486fcf3ce44SJohn Forte 
487fcf3ce44SJohn Forte 	return (ec);
488fcf3ce44SJohn Forte }
489fcf3ce44SJohn Forte 
490fcf3ce44SJohn Forte /*
491fcf3ce44SJohn Forte  * ****************************************************************************
492fcf3ce44SJohn Forte  *
493fcf3ce44SJohn Forte  * parse_xml_attr:
494fcf3ce44SJohn Forte  *	parse a xml node and convert it to one isns object attribute.
495fcf3ce44SJohn Forte  *	this attribute is the non-key attribute of the isns object.
496fcf3ce44SJohn Forte  *
497fcf3ce44SJohn Forte  * node - the xml node.
498fcf3ce44SJohn Forte  * obj - the isns object.
499fcf3ce44SJohn Forte  * i  - the index of the attribute in the global tables.
500fcf3ce44SJohn Forte  * return - error code.
501fcf3ce44SJohn Forte  *
502fcf3ce44SJohn Forte  * ****************************************************************************
503fcf3ce44SJohn Forte  */
504fcf3ce44SJohn Forte static int
parse_xml_attr(xmlNodePtr node,isns_obj_t * obj,int i)505fcf3ce44SJohn Forte parse_xml_attr(
506fcf3ce44SJohn Forte 	xmlNodePtr node,
507fcf3ce44SJohn Forte 	isns_obj_t *obj,
508fcf3ce44SJohn Forte 	int i
509fcf3ce44SJohn Forte )
510fcf3ce44SJohn Forte {
511fcf3ce44SJohn Forte 	int ec = 0;
512fcf3ce44SJohn Forte 	const unsigned char attr_type = xmlType[i][0];
513fcf3ce44SJohn Forte 	const int attr_tag = xmlArg1[i];
514fcf3ce44SJohn Forte 	const int attr_id = xmlArg2[i];
515fcf3ce44SJohn Forte 	xmlChar *attr_value;
516fcf3ce44SJohn Forte 
517fcf3ce44SJohn Forte 	attr_value = xmlNodeGetContent(node);
518fcf3ce44SJohn Forte 
519fcf3ce44SJohn Forte 	if (attr_value) {
520fcf3ce44SJohn Forte 		ec = convert_xml2attr(
521fcf3ce44SJohn Forte 		    attr_tag,
522fcf3ce44SJohn Forte 		    attr_type,
523fcf3ce44SJohn Forte 		    attr_value,
524fcf3ce44SJohn Forte 		    &(obj->attrs[attr_id]));
525fcf3ce44SJohn Forte 		xmlFree(attr_value);
526fcf3ce44SJohn Forte 	}
527fcf3ce44SJohn Forte 
528fcf3ce44SJohn Forte 	return (ec);
529fcf3ce44SJohn Forte }
530fcf3ce44SJohn Forte 
531fcf3ce44SJohn Forte /*
532fcf3ce44SJohn Forte  * ****************************************************************************
533fcf3ce44SJohn Forte  *
534fcf3ce44SJohn Forte  * parse_xml_obj:
535fcf3ce44SJohn Forte  *	parse one isns object from the xml doc.
536fcf3ce44SJohn Forte  *
537fcf3ce44SJohn Forte  * nodep - the pointer of the xml node for parsing.
538fcf3ce44SJohn Forte  * objp - the pointer of isns object for returning.
539fcf3ce44SJohn Forte  * return - error code.
540fcf3ce44SJohn Forte  *
541fcf3ce44SJohn Forte  * ****************************************************************************
542fcf3ce44SJohn Forte  */
543fcf3ce44SJohn Forte static int
parse_xml_obj(xmlNodePtr * nodep,isns_obj_t ** objp)544fcf3ce44SJohn Forte parse_xml_obj(
545fcf3ce44SJohn Forte 	xmlNodePtr *nodep,
546fcf3ce44SJohn Forte 	isns_obj_t **objp
547fcf3ce44SJohn Forte )
548fcf3ce44SJohn Forte {
549fcf3ce44SJohn Forte 	int ec = 0;
550fcf3ce44SJohn Forte 	int i, j;
551fcf3ce44SJohn Forte 
552fcf3ce44SJohn Forte 	xmlNodePtr node = *nodep;
553fcf3ce44SJohn Forte 	xmlNodePtr children;
554fcf3ce44SJohn Forte 
555fcf3ce44SJohn Forte 	isns_obj_t *obj = *objp;
556fcf3ce44SJohn Forte 
557fcf3ce44SJohn Forte 	while (node && ec == 0) {
558fcf3ce44SJohn Forte 		if (node->type == XML_ELEMENT_NODE) {
559fcf3ce44SJohn Forte 			children = node->children;
560fcf3ce44SJohn Forte 			i = get_index_by_name(node->name);
561fcf3ce44SJohn Forte 			ASSERT(i >= 0);
562fcf3ce44SJohn Forte 			j = xmlType[i][0];
563fcf3ce44SJohn Forte 			if (j == 'o' && obj == NULL) {
564fcf3ce44SJohn Forte 				obj = obj_calloc(xmlArg1[i]);
565fcf3ce44SJohn Forte 				if (obj == NULL) {
566fcf3ce44SJohn Forte 					ec = ISNS_RSP_INTERNAL_ERROR;
567fcf3ce44SJohn Forte 					break;
568fcf3ce44SJohn Forte 				}
569fcf3ce44SJohn Forte 				if ((ec = parse_xml_prop(node, obj, i)) == 0 &&
570fcf3ce44SJohn Forte 				    (children == NULL ||
571fcf3ce44SJohn Forte 				    (ec = parse_xml_obj(&children, &obj)) ==
572fcf3ce44SJohn Forte 				    0)) {
573fcf3ce44SJohn Forte 					if (children != NULL &&
574fcf3ce44SJohn Forte 					    children != node->children) {
575fcf3ce44SJohn Forte 						*nodep = children;
576fcf3ce44SJohn Forte 					}
577fcf3ce44SJohn Forte 					*objp = obj;
578fcf3ce44SJohn Forte 				} else {
579fcf3ce44SJohn Forte 					free_object(obj);
580fcf3ce44SJohn Forte 				}
581fcf3ce44SJohn Forte 				break;
582fcf3ce44SJohn Forte 				/* LINTED E_NOP_IF_STMT */
583fcf3ce44SJohn Forte 			} else if (j == 'o') {
584fcf3ce44SJohn Forte 			} else if (j != 0) {
585fcf3ce44SJohn Forte 				ASSERT(obj);
586fcf3ce44SJohn Forte 				if (children != NULL) {
587fcf3ce44SJohn Forte 					ec = parse_xml_attr(children, obj, i);
588fcf3ce44SJohn Forte 					*nodep = children;
589fcf3ce44SJohn Forte 				} else {
590fcf3ce44SJohn Forte 					/* assign a default value */
591fcf3ce44SJohn Forte 					*nodep = node;
592fcf3ce44SJohn Forte 				}
593fcf3ce44SJohn Forte 			} else {
594fcf3ce44SJohn Forte 				/* unknown xml node */
595fcf3ce44SJohn Forte 				break;
596fcf3ce44SJohn Forte 			}
597fcf3ce44SJohn Forte 			/* LINTED E_NOP_ELSE_STMT */
598fcf3ce44SJohn Forte 		} else {
599fcf3ce44SJohn Forte 			/* carry return or blank spaces, skip it */
600fcf3ce44SJohn Forte 		}
601fcf3ce44SJohn Forte 		node = node->next;
602fcf3ce44SJohn Forte 	}
603fcf3ce44SJohn Forte 
604fcf3ce44SJohn Forte 	return (ec);
605fcf3ce44SJohn Forte }
606fcf3ce44SJohn Forte 
607fcf3ce44SJohn Forte /*
608fcf3ce44SJohn Forte  * ****************************************************************************
609fcf3ce44SJohn Forte  *
610fcf3ce44SJohn Forte  * locate_xml_node:
611fcf3ce44SJohn Forte  *	locate the xml node from xml doc by matching the object UID.
612fcf3ce44SJohn Forte  *
613fcf3ce44SJohn Forte  * doc - the xml doc.
614fcf3ce44SJohn Forte  * otype - the matching object type.
615fcf3ce44SJohn Forte  * match_uid - the matching object UID.
616fcf3ce44SJohn Forte  * node - the pointer of matched xml node for returning.
617fcf3ce44SJohn Forte  * context - the xml context for matching process.
618fcf3ce44SJohn Forte  * result - the xml result for matching process.
619fcf3ce44SJohn Forte  * return - error code.
620fcf3ce44SJohn Forte  *
621fcf3ce44SJohn Forte  * ****************************************************************************
622fcf3ce44SJohn Forte  */
623fcf3ce44SJohn Forte static int
locate_xml_node(xmlDocPtr doc,int otype,int match_uid,xmlNodePtr * node,xmlXPathContextPtr * context,xmlXPathObjectPtr * result)624fcf3ce44SJohn Forte locate_xml_node(
625fcf3ce44SJohn Forte 	xmlDocPtr doc,
626fcf3ce44SJohn Forte 	int otype,
627fcf3ce44SJohn Forte 	int match_uid,
628fcf3ce44SJohn Forte 	xmlNodePtr *node,
629fcf3ce44SJohn Forte 	xmlXPathContextPtr *context,
630fcf3ce44SJohn Forte 	xmlXPathObjectPtr *result
631fcf3ce44SJohn Forte )
632fcf3ce44SJohn Forte {
633fcf3ce44SJohn Forte 	int ec = 0;
634fcf3ce44SJohn Forte 
635fcf3ce44SJohn Forte 	xmlNodeSetPtr nodeset;
636fcf3ce44SJohn Forte 	xmlNodePtr curr;
637fcf3ce44SJohn Forte 	xmlChar expr[32] = { (xmlChar)'/', (xmlChar)'/', 0 };
638fcf3ce44SJohn Forte 
639fcf3ce44SJohn Forte 	char prop;
640fcf3ce44SJohn Forte 	const xmlChar *prop_name;
641fcf3ce44SJohn Forte 	xmlChar *prop_value;
642fcf3ce44SJohn Forte 	int uid;
643fcf3ce44SJohn Forte 
644fcf3ce44SJohn Forte 	int i, j;
645fcf3ce44SJohn Forte 
646fcf3ce44SJohn Forte 	*node = NULL;
647fcf3ce44SJohn Forte 
648fcf3ce44SJohn Forte 	i = get_index_by_otype(otype);
649fcf3ce44SJohn Forte 	ASSERT(i >= 0);
650fcf3ce44SJohn Forte 
651fcf3ce44SJohn Forte 	*context = xmlXPathNewContext(doc);
652fcf3ce44SJohn Forte 
653fcf3ce44SJohn Forte 	if (*context &&
654*996d4a4cSAlexander Pyhalov 	    xmlStrPrintf(&expr[2], 30, XMLSTRING_CAST "%s",
655fcf3ce44SJohn Forte 	    xmlTag[i]) != -1) {
656fcf3ce44SJohn Forte 		*result = xmlXPathEvalExpression(expr, *context);
657fcf3ce44SJohn Forte 		if (*result) {
658fcf3ce44SJohn Forte 			prop = xmlArg2[i] - 'a';
659fcf3ce44SJohn Forte 			prop_name = xmlPropName[prop];
660fcf3ce44SJohn Forte 			ASSERT(xmlPropType[prop] == 'u');
661fcf3ce44SJohn Forte 			nodeset = (*result)->nodesetval;
662fcf3ce44SJohn Forte 			for (j = 0;
663fcf3ce44SJohn Forte 			    nodeset && (j < nodeset->nodeNr);
664fcf3ce44SJohn Forte 			    j++) {
665fcf3ce44SJohn Forte 				curr = nodeset->nodeTab[j];
666fcf3ce44SJohn Forte 				prop_value = xmlGetProp(curr, prop_name);
667fcf3ce44SJohn Forte 				if (prop_value) {
668fcf3ce44SJohn Forte 					uid = atoi((const char *)prop_value);
669fcf3ce44SJohn Forte 					xmlFree(prop_value);
670fcf3ce44SJohn Forte 					if (uid == match_uid) {
671fcf3ce44SJohn Forte 						/* found it */
672fcf3ce44SJohn Forte 						*node = curr;
673fcf3ce44SJohn Forte 						return (ec);
674fcf3ce44SJohn Forte 					}
675fcf3ce44SJohn Forte 				}
676fcf3ce44SJohn Forte 			}
677fcf3ce44SJohn Forte 		} else {
678fcf3ce44SJohn Forte 			ec = ISNS_RSP_INTERNAL_ERROR;
679fcf3ce44SJohn Forte 		}
680fcf3ce44SJohn Forte 	} else {
681fcf3ce44SJohn Forte 		ec = ISNS_RSP_INTERNAL_ERROR;
682fcf3ce44SJohn Forte 	}
683fcf3ce44SJohn Forte 
684fcf3ce44SJohn Forte 	if (*result) {
685fcf3ce44SJohn Forte 		xmlXPathFreeObject(*result);
686fcf3ce44SJohn Forte 		*result = NULL;
687fcf3ce44SJohn Forte 	}
688fcf3ce44SJohn Forte 	if (*context) {
689fcf3ce44SJohn Forte 		xmlXPathFreeContext(*context);
690fcf3ce44SJohn Forte 		*context = NULL;
691fcf3ce44SJohn Forte 	}
692fcf3ce44SJohn Forte 
693fcf3ce44SJohn Forte 	return (ec);
694fcf3ce44SJohn Forte }
695fcf3ce44SJohn Forte 
696fcf3ce44SJohn Forte /*
697fcf3ce44SJohn Forte  * ****************************************************************************
698fcf3ce44SJohn Forte  *
699fcf3ce44SJohn Forte  * make_xml_node:
700fcf3ce44SJohn Forte  *	generate a xml node for presenting an isns object.
701fcf3ce44SJohn Forte  *
702fcf3ce44SJohn Forte  * obj - an isns object.
703fcf3ce44SJohn Forte  * return - the xml node.
704fcf3ce44SJohn Forte  *
705fcf3ce44SJohn Forte  * ****************************************************************************
706fcf3ce44SJohn Forte  */
707fcf3ce44SJohn Forte static xmlNodePtr
make_xml_node(const isns_obj_t * obj)708fcf3ce44SJohn Forte make_xml_node(
709fcf3ce44SJohn Forte 	const isns_obj_t *obj
710fcf3ce44SJohn Forte )
711fcf3ce44SJohn Forte {
712fcf3ce44SJohn Forte 	const isns_attr_t *attr;
713fcf3ce44SJohn Forte 
714fcf3ce44SJohn Forte 	xmlNodePtr node;
715fcf3ce44SJohn Forte 	const char *props;
716fcf3ce44SJohn Forte 	char prop;
717fcf3ce44SJohn Forte 	const xmlChar *name;
718fcf3ce44SJohn Forte 	unsigned char type;
719fcf3ce44SJohn Forte 	int prop_id;
720fcf3ce44SJohn Forte 	int i, j;
721fcf3ce44SJohn Forte 
722fcf3ce44SJohn Forte 	i = get_index_by_otype(obj->type);
723fcf3ce44SJohn Forte 	ASSERT(i >= 0);
724fcf3ce44SJohn Forte 	node = xmlNewNode(NULL, xmlTag[i]);
725fcf3ce44SJohn Forte 	if (!node) {
726fcf3ce44SJohn Forte 		return (NULL);
727fcf3ce44SJohn Forte 	}
728fcf3ce44SJohn Forte 
729fcf3ce44SJohn Forte 	/* generate xml attributes of the node */
730fcf3ce44SJohn Forte 	props = &xmlType[i][1];
731fcf3ce44SJohn Forte 	prop = *(props ++);
732fcf3ce44SJohn Forte 	while (prop >= 'a' && prop <= 'z') {
733fcf3ce44SJohn Forte 		prop -= 'a';
734fcf3ce44SJohn Forte 		prop_id = xmlPropID[prop];
735fcf3ce44SJohn Forte 		name = xmlPropName[prop];
736fcf3ce44SJohn Forte 		type = xmlPropType[prop];
737fcf3ce44SJohn Forte 		attr = &obj->attrs[prop_id];
738fcf3ce44SJohn Forte 		if (!convert_attr2xml(node, attr, name, type, 0)) {
739fcf3ce44SJohn Forte 			xmlFreeNode(node);
740fcf3ce44SJohn Forte 			return (NULL);
741fcf3ce44SJohn Forte 		}
742fcf3ce44SJohn Forte 		/* attr->tag = 0; */
743fcf3ce44SJohn Forte 		prop = *(props ++);
744fcf3ce44SJohn Forte 	}
745fcf3ce44SJohn Forte 
746fcf3ce44SJohn Forte 	/* generate sub elements for isns attributes of the object */
747fcf3ce44SJohn Forte 	i = 0;
748fcf3ce44SJohn Forte 	while (i < NUM_OF_ATTRS[obj->type]) {
749fcf3ce44SJohn Forte 		attr = &obj->attrs[i ++];
750fcf3ce44SJohn Forte 		j = get_index_by_tag(attr->tag);
751fcf3ce44SJohn Forte 		if (j >= 0) {
752fcf3ce44SJohn Forte 			name = xmlTag[j];
753fcf3ce44SJohn Forte 			type = xmlType[j][0];
754fcf3ce44SJohn Forte 			if (!convert_attr2xml(node, attr, name, type, 1)) {
755fcf3ce44SJohn Forte 				xmlFreeNode(node);
756fcf3ce44SJohn Forte 				return (NULL);
757fcf3ce44SJohn Forte 			}
758fcf3ce44SJohn Forte 		}
759fcf3ce44SJohn Forte 	}
760fcf3ce44SJohn Forte 
761fcf3ce44SJohn Forte 	return (node);
762fcf3ce44SJohn Forte }
763fcf3ce44SJohn Forte 
764fcf3ce44SJohn Forte /*
765fcf3ce44SJohn Forte  * ****************************************************************************
766fcf3ce44SJohn Forte  *
767fcf3ce44SJohn Forte  * xml_init_data:
768fcf3ce44SJohn Forte  *	initialization of the xml data store.
769fcf3ce44SJohn Forte  *
770fcf3ce44SJohn Forte  * return - error code.
771fcf3ce44SJohn Forte  *
772fcf3ce44SJohn Forte  * ****************************************************************************
773fcf3ce44SJohn Forte  */
774fcf3ce44SJohn Forte static int
xml_init_data()775fcf3ce44SJohn Forte xml_init_data(
776fcf3ce44SJohn Forte )
777fcf3ce44SJohn Forte {
778fcf3ce44SJohn Forte #define	XML_PATH	"/etc/isns"
779fcf3ce44SJohn Forte #define	XML_FILE_NAME	"/isnsdata.xml"
780fcf3ce44SJohn Forte #define	XML_DOT_TMP	".tmp"
781fcf3ce44SJohn Forte #define	XML_DOT_BAK	".bak"
782fcf3ce44SJohn Forte 
783fcf3ce44SJohn Forte 	int fd;
784fcf3ce44SJohn Forte 	xmlDocPtr doc;
785fcf3ce44SJohn Forte 	xmlNodePtr root;
786fcf3ce44SJohn Forte 
787fcf3ce44SJohn Forte 	int len;
788fcf3ce44SJohn Forte 	char *xml_path, *p = NULL;
789fcf3ce44SJohn Forte 
790fcf3ce44SJohn Forte 	char *cwd = NULL;
791fcf3ce44SJohn Forte 
792fcf3ce44SJohn Forte 	int has_bak = 0;
793fcf3ce44SJohn Forte 
794fcf3ce44SJohn Forte 	/* cannot reset the xml file when server is running */
795fcf3ce44SJohn Forte 	if (xml_file != NULL) {
796fcf3ce44SJohn Forte 		return (1);
797fcf3ce44SJohn Forte 	}
798fcf3ce44SJohn Forte 
799fcf3ce44SJohn Forte 	/* set the data store file name along with the backup */
800fcf3ce44SJohn Forte 	/* file name and temporary file name */
801fcf3ce44SJohn Forte 	len = strlen(data_store);
802fcf3ce44SJohn Forte 	if (len > 0) {
803fcf3ce44SJohn Forte 		xml_file = data_store;
804fcf3ce44SJohn Forte 		p = strdup(xml_file);
805fcf3ce44SJohn Forte 		xml_bak_file = (char *)malloc(len + 5);
806fcf3ce44SJohn Forte 		xml_tmp_file = (char *)malloc(len + 5);
807fcf3ce44SJohn Forte 		if (p != NULL &&
808fcf3ce44SJohn Forte 		    xml_bak_file != NULL &&
809fcf3ce44SJohn Forte 		    xml_tmp_file != NULL) {
810fcf3ce44SJohn Forte 			xml_path = dirname(p);
811fcf3ce44SJohn Forte 			(void) strcpy(xml_bak_file, xml_file);
812fcf3ce44SJohn Forte 			(void) strcat(xml_bak_file, XML_DOT_BAK);
813fcf3ce44SJohn Forte 			(void) strcpy(xml_tmp_file, xml_file);
814fcf3ce44SJohn Forte 			(void) strcat(xml_tmp_file, XML_DOT_TMP);
815fcf3ce44SJohn Forte 		} else {
816fcf3ce44SJohn Forte 			return (1);
817fcf3ce44SJohn Forte 		}
818fcf3ce44SJohn Forte 	} else {
819fcf3ce44SJohn Forte 		xml_path = XML_PATH;
820fcf3ce44SJohn Forte 		xml_file = XML_PATH XML_FILE_NAME;
821fcf3ce44SJohn Forte 		xml_bak_file = XML_PATH XML_FILE_NAME XML_DOT_BAK;
822fcf3ce44SJohn Forte 		xml_tmp_file = XML_PATH XML_FILE_NAME XML_DOT_TMP;
823fcf3ce44SJohn Forte 	}
824fcf3ce44SJohn Forte 
825fcf3ce44SJohn Forte 	/* save current working directory */
826fcf3ce44SJohn Forte 	cwd = getcwd(NULL, MAXPATHLEN);
827fcf3ce44SJohn Forte 	if (cwd == NULL) {
828fcf3ce44SJohn Forte 		return (1);
829fcf3ce44SJohn Forte 	}
830fcf3ce44SJohn Forte 	/* check access permission on data store directory */
831fcf3ce44SJohn Forte 	if (chdir(xml_path) != 0) {
832fcf3ce44SJohn Forte 		if (errno == ENOENT) {
833fcf3ce44SJohn Forte 			if (mkdir(xml_path, S_IRWXU) != 0 ||
834fcf3ce44SJohn Forte 			    chdir(xml_path) != 0) {
835fcf3ce44SJohn Forte 				return (1);
836fcf3ce44SJohn Forte 			}
837fcf3ce44SJohn Forte 		} else {
838fcf3ce44SJohn Forte 			return (1);
839fcf3ce44SJohn Forte 		}
840fcf3ce44SJohn Forte 	}
841fcf3ce44SJohn Forte 	/* go back to original working directory */
842fcf3ce44SJohn Forte 	(void) chdir(cwd);
843fcf3ce44SJohn Forte 	free(cwd);
844fcf3ce44SJohn Forte 	free(p);
845fcf3ce44SJohn Forte 
846fcf3ce44SJohn Forte 	/* do not keep blank spaces */
847fcf3ce44SJohn Forte 	(void) xmlKeepBlanksDefault(0);
848fcf3ce44SJohn Forte 
849530e2b59Swl202157@icefox 	/* remove the tmp file if it exists */
850530e2b59Swl202157@icefox 	if (access(xml_tmp_file, F_OK) == 0) {
851fcf3ce44SJohn Forte 		(void) remove(xml_tmp_file);
852530e2b59Swl202157@icefox 	}
853fcf3ce44SJohn Forte 
854fcf3ce44SJohn Forte 	/* test if we can write the bak file */
855fcf3ce44SJohn Forte 	fd = open(xml_bak_file, O_RDWR);
856fcf3ce44SJohn Forte 	if (fd == -1) {
857fcf3ce44SJohn Forte 		fd = open(xml_bak_file, O_RDWR | O_CREAT,
858fcf3ce44SJohn Forte 		    S_IRUSR | S_IWUSR);
859fcf3ce44SJohn Forte 		if (fd == -1) {
860fcf3ce44SJohn Forte 			return (1);
861fcf3ce44SJohn Forte 		} else {
862fcf3ce44SJohn Forte 			(void) close(fd);
863fcf3ce44SJohn Forte 			(void) remove(xml_bak_file);
864fcf3ce44SJohn Forte 		}
865fcf3ce44SJohn Forte 	} else {
866fcf3ce44SJohn Forte 		has_bak = 1;
867fcf3ce44SJohn Forte 		(void) close(fd);
868fcf3ce44SJohn Forte 	}
869fcf3ce44SJohn Forte 
870fcf3ce44SJohn Forte 	/* Test if we have the data store file, create an empty */
871fcf3ce44SJohn Forte 	/* data store if we do not have the data store file and */
872fcf3ce44SJohn Forte 	/* the backup data store. */
873fcf3ce44SJohn Forte 	fd = open(xml_file, O_RDWR);
874fcf3ce44SJohn Forte 	if (fd == -1) {
875fcf3ce44SJohn Forte 		if (has_bak == 0) {
876fcf3ce44SJohn Forte 			doc = xmlNewDoc(BAD_CAST "1.0");
877fcf3ce44SJohn Forte 			root = xmlNewNode(NULL, xml_root[0]);
878fcf3ce44SJohn Forte 			if (doc != NULL &&
879fcf3ce44SJohn Forte 			    root != NULL &&
880fcf3ce44SJohn Forte 			    xmlSetProp(root, xml_root[1], xml_root[2]) !=
881fcf3ce44SJohn Forte 			    NULL &&
882fcf3ce44SJohn Forte 			    xmlSetProp(root, xml_root[3], xml_root[4]) !=
883fcf3ce44SJohn Forte 			    NULL) {
884fcf3ce44SJohn Forte 				(void) xmlDocSetRootElement(doc, root);
885fcf3ce44SJohn Forte 				if (xmlSaveFormatFile(xml_file, doc, 1) == -1) {
886fcf3ce44SJohn Forte 					xmlFreeDoc(doc);
887fcf3ce44SJohn Forte 					return (-1);
888fcf3ce44SJohn Forte 				}
889fcf3ce44SJohn Forte 				xmlFreeDoc(doc);
890fcf3ce44SJohn Forte 			} else {
891fcf3ce44SJohn Forte 				if (doc != NULL) {
892fcf3ce44SJohn Forte 					xmlFreeDoc(doc);
893fcf3ce44SJohn Forte 				}
894fcf3ce44SJohn Forte 				if (root != NULL) {
895fcf3ce44SJohn Forte 					xmlFreeNode(root);
896fcf3ce44SJohn Forte 				}
897fcf3ce44SJohn Forte 				return (1);
898fcf3ce44SJohn Forte 			}
899fcf3ce44SJohn Forte 		} else {
900fcf3ce44SJohn Forte 			isnslog(LOG_WARNING, "get_xml_doc",
901fcf3ce44SJohn Forte 			    "initializing with backup data");
902fcf3ce44SJohn Forte 			if (rename(xml_bak_file, xml_file) != 0) {
903fcf3ce44SJohn Forte 				return (1);
904fcf3ce44SJohn Forte 			}
905fcf3ce44SJohn Forte 		}
906fcf3ce44SJohn Forte 	} else {
907fcf3ce44SJohn Forte 		(void) close(fd);
908fcf3ce44SJohn Forte 	}
909fcf3ce44SJohn Forte 
910fcf3ce44SJohn Forte 	return (0);
911fcf3ce44SJohn Forte }
912fcf3ce44SJohn Forte 
913fcf3ce44SJohn Forte /*
914fcf3ce44SJohn Forte  * ****************************************************************************
915fcf3ce44SJohn Forte  *
916fcf3ce44SJohn Forte  * xml_load_obj:
917fcf3ce44SJohn Forte  *	load an isns object from the xml data store.
918fcf3ce44SJohn Forte  *
919fcf3ce44SJohn Forte  * p - the pointer of current xml node.
920fcf3ce44SJohn Forte  * objp - the pointer of the object for returning.
921fcf3ce44SJohn Forte  * level - the direction of xml parsing for returning.
922fcf3ce44SJohn Forte  * return - error code.
923fcf3ce44SJohn Forte  *
924fcf3ce44SJohn Forte  * ****************************************************************************
925fcf3ce44SJohn Forte  */
926fcf3ce44SJohn Forte static int
xml_load_obj(void ** p,isns_obj_t ** objp,uchar_t * level)927fcf3ce44SJohn Forte xml_load_obj(
928fcf3ce44SJohn Forte 	void **p,
929fcf3ce44SJohn Forte 	isns_obj_t **objp,
930fcf3ce44SJohn Forte 	uchar_t *level
931fcf3ce44SJohn Forte )
932fcf3ce44SJohn Forte {
933fcf3ce44SJohn Forte 	xmlDocPtr doc = NULL;
934fcf3ce44SJohn Forte 	xmlNodePtr node = (xmlNodePtr)*p;
935fcf3ce44SJohn Forte 	int ec = 0;
936fcf3ce44SJohn Forte 
937fcf3ce44SJohn Forte 	*objp = NULL;
938fcf3ce44SJohn Forte 
939fcf3ce44SJohn Forte 	if (node == NULL) {
940fcf3ce44SJohn Forte 		*level = '^';
941fcf3ce44SJohn Forte 		ec = get_xml_doc(&doc);
942fcf3ce44SJohn Forte 		if (doc == NULL) {
943fcf3ce44SJohn Forte 			return (ec);
944fcf3ce44SJohn Forte 		}
945fcf3ce44SJohn Forte 		node = xmlDocGetRootElement(doc);
946fcf3ce44SJohn Forte 		if (node != NULL) {
947fcf3ce44SJohn Forte 			node = node->children;
948fcf3ce44SJohn Forte 		}
949fcf3ce44SJohn Forte 	} else if (node->children != NULL) {
950fcf3ce44SJohn Forte 		*level = '>';
951fcf3ce44SJohn Forte 		node = node->children;
952fcf3ce44SJohn Forte 	} else if (node->next != NULL) {
953fcf3ce44SJohn Forte 		*level = 'v';
954fcf3ce44SJohn Forte 		node = node->next;
955fcf3ce44SJohn Forte 	} else {
956fcf3ce44SJohn Forte 		*level = 'v';
957fcf3ce44SJohn Forte 		while (node != NULL && node->next == NULL) {
958fcf3ce44SJohn Forte 			if (node->type == XML_ELEMENT_NODE) {
959fcf3ce44SJohn Forte 				*level = '<';
960fcf3ce44SJohn Forte 			}
961fcf3ce44SJohn Forte 			node = node->parent;
962fcf3ce44SJohn Forte 		}
963fcf3ce44SJohn Forte 		if (node != NULL) {
964fcf3ce44SJohn Forte 			node = node->next;
965fcf3ce44SJohn Forte 		}
966fcf3ce44SJohn Forte 	}
967fcf3ce44SJohn Forte 
968fcf3ce44SJohn Forte 	/* there is a node, parse it */
969fcf3ce44SJohn Forte 	if (node) {
970fcf3ce44SJohn Forte 		ec = parse_xml_obj(&node, objp);
971fcf3ce44SJohn Forte 		*p = (void *)node;
972fcf3ce44SJohn Forte 	}
973fcf3ce44SJohn Forte 
974fcf3ce44SJohn Forte 	if (ec == 0 && *objp != NULL) {
975fcf3ce44SJohn Forte 		ec = update_deref_obj(*objp);
976fcf3ce44SJohn Forte 		if (ec != 0) {
977fcf3ce44SJohn Forte 			free_object(*objp);
978fcf3ce44SJohn Forte 			*objp = NULL;
979fcf3ce44SJohn Forte 		}
980fcf3ce44SJohn Forte 	}
981fcf3ce44SJohn Forte 
982fcf3ce44SJohn Forte 	/* no object available, close the xml doc */
983fcf3ce44SJohn Forte 	if (*objp == NULL) {
984fcf3ce44SJohn Forte 		(void) close_xml_doc();
985fcf3ce44SJohn Forte 	}
986fcf3ce44SJohn Forte 
987fcf3ce44SJohn Forte 	return (ec);
988fcf3ce44SJohn Forte }
989fcf3ce44SJohn Forte 
990fcf3ce44SJohn Forte /*
991fcf3ce44SJohn Forte  * ****************************************************************************
992fcf3ce44SJohn Forte  *
993fcf3ce44SJohn Forte  * xml_add_obj:
994fcf3ce44SJohn Forte  *	add an isns object to the xml data store.
995fcf3ce44SJohn Forte  *
996fcf3ce44SJohn Forte  * obj - the object being added.
997fcf3ce44SJohn Forte  * return - error code.
998fcf3ce44SJohn Forte  *
999fcf3ce44SJohn Forte  * ****************************************************************************
1000fcf3ce44SJohn Forte  */
1001fcf3ce44SJohn Forte static int
xml_add_obj(const isns_obj_t * obj)1002fcf3ce44SJohn Forte xml_add_obj(
1003fcf3ce44SJohn Forte 	const isns_obj_t *obj
1004fcf3ce44SJohn Forte )
1005fcf3ce44SJohn Forte {
1006fcf3ce44SJohn Forte 	int ec = 0;
1007fcf3ce44SJohn Forte 
1008fcf3ce44SJohn Forte 	xmlDocPtr doc;
1009fcf3ce44SJohn Forte 	xmlXPathContextPtr context = NULL;
1010fcf3ce44SJohn Forte 	xmlXPathObjectPtr result = NULL;
1011fcf3ce44SJohn Forte 	xmlNodePtr node, prev;
1012fcf3ce44SJohn Forte 	xmlNodePtr candidate;
1013fcf3ce44SJohn Forte 
1014fcf3ce44SJohn Forte 	uint32_t puid, parent_type;
1015fcf3ce44SJohn Forte 
1016fcf3ce44SJohn Forte 	int i;
1017fcf3ce44SJohn Forte 
1018fcf3ce44SJohn Forte 	/* get the xml doc */
1019fcf3ce44SJohn Forte 	ec = get_xml_doc(&doc);
1020fcf3ce44SJohn Forte 	if (doc == NULL) {
1021fcf3ce44SJohn Forte 		goto add_done;
1022fcf3ce44SJohn Forte 	}
1023fcf3ce44SJohn Forte 
1024fcf3ce44SJohn Forte 	/* create the candidate node */
1025fcf3ce44SJohn Forte 	candidate = make_xml_node(obj);
1026fcf3ce44SJohn Forte 	if (candidate == NULL) {
1027fcf3ce44SJohn Forte 		ec = ISNS_RSP_INTERNAL_ERROR;
1028fcf3ce44SJohn Forte 		goto add_done;
1029fcf3ce44SJohn Forte 	}
1030fcf3ce44SJohn Forte 
1031fcf3ce44SJohn Forte 	/* locate the position */
1032fcf3ce44SJohn Forte 	parent_type = TYPE_OF_PARENT[obj->type];
1033fcf3ce44SJohn Forte 	if (parent_type > 0) {
1034fcf3ce44SJohn Forte 		puid = get_parent_uid(obj);
1035fcf3ce44SJohn Forte 		ec = locate_xml_node(doc, parent_type, puid,
1036fcf3ce44SJohn Forte 		    &node, &context, &result);
1037fcf3ce44SJohn Forte 	} else {
1038fcf3ce44SJohn Forte 		node = xmlDocGetRootElement(doc);
1039fcf3ce44SJohn Forte 	}
1040fcf3ce44SJohn Forte 
1041fcf3ce44SJohn Forte 	/* cannot locate the point for inserting the node */
1042fcf3ce44SJohn Forte 	if (node == NULL) {
1043fcf3ce44SJohn Forte 		xmlFreeNode(candidate);
1044fcf3ce44SJohn Forte 		ec = ISNS_RSP_INTERNAL_ERROR;
1045fcf3ce44SJohn Forte 		goto add_done;
1046fcf3ce44SJohn Forte 	}
1047fcf3ce44SJohn Forte 
1048fcf3ce44SJohn Forte 	/* add it with the apporiate child order */
1049fcf3ce44SJohn Forte 	if (node->children) {
1050fcf3ce44SJohn Forte 		node = node->children;
1051fcf3ce44SJohn Forte 		while (node) {
1052fcf3ce44SJohn Forte 			if (node->type == XML_ELEMENT_NODE) {
1053fcf3ce44SJohn Forte 				i = get_index_by_name(node->name);
1054fcf3ce44SJohn Forte 				ASSERT(i >= 0);
1055fcf3ce44SJohn Forte 				if (xmlType[i][0] == 'o' &&
1056fcf3ce44SJohn Forte 				    OBJ_DTD_ORDER[xmlArg1[i]] >=
1057fcf3ce44SJohn Forte 				    OBJ_DTD_ORDER[obj->type]) {
1058fcf3ce44SJohn Forte 					break;
1059fcf3ce44SJohn Forte 				}
1060fcf3ce44SJohn Forte 			}
1061fcf3ce44SJohn Forte 			prev = node;
1062fcf3ce44SJohn Forte 			node = node->next;
1063fcf3ce44SJohn Forte 		}
1064fcf3ce44SJohn Forte 		if (node == NULL) {
1065fcf3ce44SJohn Forte 			node = xmlAddNextSibling(prev, candidate);
1066fcf3ce44SJohn Forte 		} else {
1067fcf3ce44SJohn Forte 			node = xmlAddPrevSibling(node, candidate);
1068fcf3ce44SJohn Forte 		}
1069fcf3ce44SJohn Forte 	} else {
1070fcf3ce44SJohn Forte 		node = xmlAddChild(node, candidate);
1071fcf3ce44SJohn Forte 	}
1072fcf3ce44SJohn Forte 
1073fcf3ce44SJohn Forte 	if (node == NULL) {
1074fcf3ce44SJohn Forte 		/* Failed, free the candidate node. */
1075fcf3ce44SJohn Forte 		xmlFreeNode(candidate);
1076fcf3ce44SJohn Forte 		ec = ISNS_RSP_INTERNAL_ERROR;
1077fcf3ce44SJohn Forte 	}
1078fcf3ce44SJohn Forte 
1079fcf3ce44SJohn Forte add_done:
1080fcf3ce44SJohn Forte 	if (result) {
1081fcf3ce44SJohn Forte 		xmlXPathFreeObject(result);
1082fcf3ce44SJohn Forte 	}
1083fcf3ce44SJohn Forte 	if (context) {
1084fcf3ce44SJohn Forte 		xmlXPathFreeContext(context);
1085fcf3ce44SJohn Forte 	}
1086fcf3ce44SJohn Forte 
1087fcf3ce44SJohn Forte 	return (ec);
1088fcf3ce44SJohn Forte }
1089fcf3ce44SJohn Forte 
1090fcf3ce44SJohn Forte /*
1091fcf3ce44SJohn Forte  * ****************************************************************************
1092fcf3ce44SJohn Forte  *
1093fcf3ce44SJohn Forte  * xml_modify_obj:
1094fcf3ce44SJohn Forte  *	modify an isns object in the xml data store.
1095fcf3ce44SJohn Forte  *
1096fcf3ce44SJohn Forte  * obj - the new object.
1097fcf3ce44SJohn Forte  * return - error code.
1098fcf3ce44SJohn Forte  *
1099fcf3ce44SJohn Forte  * ****************************************************************************
1100fcf3ce44SJohn Forte  */
1101fcf3ce44SJohn Forte static int
xml_modify_obj(const isns_obj_t * obj)1102fcf3ce44SJohn Forte xml_modify_obj(
1103fcf3ce44SJohn Forte 	const isns_obj_t *obj
1104fcf3ce44SJohn Forte )
1105fcf3ce44SJohn Forte {
1106fcf3ce44SJohn Forte 	int ec = 0;
1107fcf3ce44SJohn Forte 	xmlDocPtr doc;
1108fcf3ce44SJohn Forte 	xmlXPathContextPtr context = NULL;
1109fcf3ce44SJohn Forte 	xmlXPathObjectPtr result = NULL;
1110fcf3ce44SJohn Forte 	xmlNodePtr node, child;
1111fcf3ce44SJohn Forte 	const char *props;
1112fcf3ce44SJohn Forte 	char prop;
1113fcf3ce44SJohn Forte 	int prop_id;
1114fcf3ce44SJohn Forte 	int prop_tag;
1115fcf3ce44SJohn Forte 	const xmlChar *name;
1116fcf3ce44SJohn Forte 	unsigned char type;
1117fcf3ce44SJohn Forte 	const isns_attr_t *attr;
1118fcf3ce44SJohn Forte 	int i, j, k;
1119fcf3ce44SJohn Forte 	int make_child;
1120fcf3ce44SJohn Forte 
1121fcf3ce44SJohn Forte 	/* get the doc pointer */
1122fcf3ce44SJohn Forte 	ec = get_xml_doc(&doc);
1123fcf3ce44SJohn Forte 	if (doc == NULL) {
1124fcf3ce44SJohn Forte 		return (ec);
1125fcf3ce44SJohn Forte 	}
1126fcf3ce44SJohn Forte 
1127fcf3ce44SJohn Forte 	/* locate the node for the object */
1128fcf3ce44SJohn Forte 	i = get_index_by_otype(obj->type);
1129fcf3ce44SJohn Forte 	ASSERT(i >= 0);
1130fcf3ce44SJohn Forte 	prop = xmlArg2[i] - 'a';
1131fcf3ce44SJohn Forte 	prop_id = xmlPropID[prop];
1132fcf3ce44SJohn Forte 	attr = &obj->attrs[prop_id];
1133fcf3ce44SJohn Forte 	ec = locate_xml_node(doc,
1134fcf3ce44SJohn Forte 	    obj->type,
1135fcf3ce44SJohn Forte 	    attr->value.ui,
1136fcf3ce44SJohn Forte 	    &node, &context, &result);
1137fcf3ce44SJohn Forte 
1138fcf3ce44SJohn Forte 	/* modify it */
1139fcf3ce44SJohn Forte 	if (node != NULL) {
1140fcf3ce44SJohn Forte 		props = &xmlType[i][1];
1141fcf3ce44SJohn Forte 		prop = *(props ++);
1142fcf3ce44SJohn Forte 		while (prop >= 'a' && prop <= 'z') {
1143fcf3ce44SJohn Forte 			prop -= 'a';
1144fcf3ce44SJohn Forte 			prop_id = xmlPropID[prop];
1145fcf3ce44SJohn Forte 			prop_tag = xmlPropTag[prop];
1146fcf3ce44SJohn Forte 			attr = &obj->attrs[prop_id];
1147fcf3ce44SJohn Forte 			/* no need to update the key attributes, skip it. */
1148fcf3ce44SJohn Forte 			/* btw, dd and dd-set names are non-key attributes. */
1149fcf3ce44SJohn Forte 			if (prop_tag == ISNS_DD_NAME_ATTR_ID ||
1150fcf3ce44SJohn Forte 			    prop_tag == ISNS_DD_SET_NAME_ATTR_ID) {
1151fcf3ce44SJohn Forte 				name = xmlPropName[prop];
1152fcf3ce44SJohn Forte 				type = xmlPropType[prop];
1153fcf3ce44SJohn Forte 				if (!convert_attr2xml(node,
1154fcf3ce44SJohn Forte 				    attr, name, type, 4)) {
1155fcf3ce44SJohn Forte 					ec = ISNS_RSP_INTERNAL_ERROR;
1156fcf3ce44SJohn Forte 					goto modify_done;
1157fcf3ce44SJohn Forte 				}
1158fcf3ce44SJohn Forte 			}
1159fcf3ce44SJohn Forte 			/* attr->tag = 0; */
1160fcf3ce44SJohn Forte 			prop = *(props ++);
1161fcf3ce44SJohn Forte 		}
1162fcf3ce44SJohn Forte 		/* set the child */
1163fcf3ce44SJohn Forte 		child = node->children;
1164fcf3ce44SJohn Forte 		if (child == NULL) {
1165fcf3ce44SJohn Forte 			make_child = 1;
1166fcf3ce44SJohn Forte 		} else {
1167fcf3ce44SJohn Forte 			make_child = 0;
1168fcf3ce44SJohn Forte 		}
1169fcf3ce44SJohn Forte 		for (i = 0; i < NUM_OF_ATTRS[obj->type]; i++) {
1170fcf3ce44SJohn Forte 			attr = &obj->attrs[i];
1171fcf3ce44SJohn Forte 			j = get_index_by_tag(attr->tag);
1172fcf3ce44SJohn Forte 			if (j < 0) {
1173fcf3ce44SJohn Forte 				continue;
1174fcf3ce44SJohn Forte 			}
1175fcf3ce44SJohn Forte 			name = xmlTag[j];
1176fcf3ce44SJohn Forte 			type = xmlType[j][0];
1177fcf3ce44SJohn Forte 			if (make_child == 1) {
1178fcf3ce44SJohn Forte 				/* make a child node */
1179fcf3ce44SJohn Forte 				if (!convert_attr2xml(node, attr,
1180fcf3ce44SJohn Forte 				    name, type, 1)) {
1181fcf3ce44SJohn Forte 					ec = ISNS_RSP_INTERNAL_ERROR;
1182fcf3ce44SJohn Forte 					goto modify_done;
1183fcf3ce44SJohn Forte 				}
1184fcf3ce44SJohn Forte 				continue;
1185fcf3ce44SJohn Forte 			}
1186fcf3ce44SJohn Forte 			while (child) {
1187fcf3ce44SJohn Forte 				if (child->type == XML_ELEMENT_NODE) {
1188fcf3ce44SJohn Forte 					k = get_index_by_name(child->name);
1189fcf3ce44SJohn Forte 					ASSERT(k >= 0);
1190fcf3ce44SJohn Forte 					if (xmlType[k][0] == 'o' ||
1191fcf3ce44SJohn Forte 					    xmlType[k][0] == 'a' ||
1192fcf3ce44SJohn Forte 					    xmlArg1[k] > attr->tag) {
1193fcf3ce44SJohn Forte 						if (!convert_attr2xml(child,
1194fcf3ce44SJohn Forte 						    attr, name, type, 2)) {
1195fcf3ce44SJohn Forte 							/* internal error */
1196fcf3ce44SJohn Forte 							ec = 11;
1197fcf3ce44SJohn Forte 							goto modify_done;
1198fcf3ce44SJohn Forte 						}
1199fcf3ce44SJohn Forte 						break;
1200fcf3ce44SJohn Forte 					} else if (xmlArg1[k] == attr->tag) {
1201fcf3ce44SJohn Forte 						/* replace content */
1202fcf3ce44SJohn Forte 						if (!convert_attr2xml(child,
1203fcf3ce44SJohn Forte 						    attr, name, type, 3)) {
1204fcf3ce44SJohn Forte 							/* internal error */
1205fcf3ce44SJohn Forte 							ec = 11;
1206fcf3ce44SJohn Forte 							goto modify_done;
1207fcf3ce44SJohn Forte 						}
1208fcf3ce44SJohn Forte 						break;
1209fcf3ce44SJohn Forte 					}
1210fcf3ce44SJohn Forte 				}
1211fcf3ce44SJohn Forte 				child = child->next;
1212fcf3ce44SJohn Forte 			}
1213fcf3ce44SJohn Forte 			if (child == NULL) {
1214fcf3ce44SJohn Forte 				/* make a child node */
1215fcf3ce44SJohn Forte 				if (!convert_attr2xml(node, attr,
1216fcf3ce44SJohn Forte 				    name, type, 1)) {
1217fcf3ce44SJohn Forte 					ec = ISNS_RSP_INTERNAL_ERROR;
1218fcf3ce44SJohn Forte 					goto modify_done;
1219fcf3ce44SJohn Forte 				}
1220fcf3ce44SJohn Forte 			}
1221fcf3ce44SJohn Forte 		}
1222fcf3ce44SJohn Forte 	} else {
1223fcf3ce44SJohn Forte 		/* This case is for registering a node which has */
1224fcf3ce44SJohn Forte 		/* membership in one or more non-default DD(s). */
1225fcf3ce44SJohn Forte 		ec = xml_add_obj(obj);
1226fcf3ce44SJohn Forte 	}
1227fcf3ce44SJohn Forte 
1228fcf3ce44SJohn Forte modify_done:
1229fcf3ce44SJohn Forte 	if (result) {
1230fcf3ce44SJohn Forte 		xmlXPathFreeObject(result);
1231fcf3ce44SJohn Forte 	}
1232fcf3ce44SJohn Forte 	if (context) {
1233fcf3ce44SJohn Forte 		xmlXPathFreeContext(context);
1234fcf3ce44SJohn Forte 	}
1235fcf3ce44SJohn Forte 
1236fcf3ce44SJohn Forte 	return (ec);
1237fcf3ce44SJohn Forte }
1238fcf3ce44SJohn Forte 
1239fcf3ce44SJohn Forte /*
1240fcf3ce44SJohn Forte  * ****************************************************************************
1241fcf3ce44SJohn Forte  *
1242fcf3ce44SJohn Forte  * xml_delete_obj:
1243fcf3ce44SJohn Forte  *	delete an isns object from the xml data store.
1244fcf3ce44SJohn Forte  *
1245fcf3ce44SJohn Forte  * obj - the object being deleted.
1246fcf3ce44SJohn Forte  * return - error code.
1247fcf3ce44SJohn Forte  *
1248fcf3ce44SJohn Forte  * ****************************************************************************
1249fcf3ce44SJohn Forte  */
1250fcf3ce44SJohn Forte static int
xml_delete_obj(const isns_obj_t * obj)1251fcf3ce44SJohn Forte xml_delete_obj(
1252fcf3ce44SJohn Forte 	const isns_obj_t *obj
1253fcf3ce44SJohn Forte )
1254fcf3ce44SJohn Forte {
1255fcf3ce44SJohn Forte 	int ec = 0;
1256fcf3ce44SJohn Forte 	xmlDocPtr doc;
1257fcf3ce44SJohn Forte 	xmlXPathContextPtr context = NULL;
1258fcf3ce44SJohn Forte 	xmlXPathObjectPtr result = NULL;
1259fcf3ce44SJohn Forte 	xmlNodePtr node;
1260fcf3ce44SJohn Forte 
1261fcf3ce44SJohn Forte 	isns_type_t otype;
1262fcf3ce44SJohn Forte 	uint32_t uid;
1263fcf3ce44SJohn Forte 
1264fcf3ce44SJohn Forte 	/* get the xml doc */
1265fcf3ce44SJohn Forte 	ec = get_xml_doc(&doc);
1266fcf3ce44SJohn Forte 	if (doc == NULL) {
1267fcf3ce44SJohn Forte 		return (ec);
1268fcf3ce44SJohn Forte 	}
1269fcf3ce44SJohn Forte 
1270fcf3ce44SJohn Forte 	otype = obj->type;
1271fcf3ce44SJohn Forte #ifdef WRITE_DATA_ASYNC
1272fcf3ce44SJohn Forte 	/* it is a thin clone */
1273fcf3ce44SJohn Forte 	uid = obj->attrs[0].value.ui;
1274fcf3ce44SJohn Forte #else
1275fcf3ce44SJohn Forte 	uid = get_obj_uid(obj);
1276fcf3ce44SJohn Forte #endif
1277fcf3ce44SJohn Forte 
1278fcf3ce44SJohn Forte 	/* locate the object */
1279fcf3ce44SJohn Forte 	ec = locate_xml_node(doc,
1280fcf3ce44SJohn Forte 	    otype,
1281fcf3ce44SJohn Forte 	    uid,
1282fcf3ce44SJohn Forte 	    &node, &context, &result);
1283fcf3ce44SJohn Forte 
1284fcf3ce44SJohn Forte 	/* destroy it */
1285fcf3ce44SJohn Forte 	if (node) {
1286fcf3ce44SJohn Forte 		xmlUnlinkNode(node);
1287fcf3ce44SJohn Forte 		xmlFreeNode(node);
1288fcf3ce44SJohn Forte 	}
1289fcf3ce44SJohn Forte 
1290fcf3ce44SJohn Forte 	if (result) {
1291fcf3ce44SJohn Forte 		xmlXPathFreeObject(result);
1292fcf3ce44SJohn Forte 	}
1293fcf3ce44SJohn Forte 	if (context) {
1294fcf3ce44SJohn Forte 		xmlXPathFreeContext(context);
1295fcf3ce44SJohn Forte 	}
1296fcf3ce44SJohn Forte 
1297fcf3ce44SJohn Forte 	return (ec);
1298fcf3ce44SJohn Forte }
1299fcf3ce44SJohn Forte 
1300fcf3ce44SJohn Forte /*
1301fcf3ce44SJohn Forte  * ****************************************************************************
1302fcf3ce44SJohn Forte  *
1303fcf3ce44SJohn Forte  * xml_delete_assoc:
1304fcf3ce44SJohn Forte  *	delete a DD or DD-set membership from the xml data store.
1305fcf3ce44SJohn Forte  *
1306fcf3ce44SJohn Forte  * assoc - the membership being deleted.
1307fcf3ce44SJohn Forte  * return - error code.
1308fcf3ce44SJohn Forte  *
1309fcf3ce44SJohn Forte  * ****************************************************************************
1310fcf3ce44SJohn Forte  */
1311fcf3ce44SJohn Forte static int
xml_delete_assoc(const isns_obj_t * assoc)1312fcf3ce44SJohn Forte xml_delete_assoc(
1313fcf3ce44SJohn Forte 	const isns_obj_t *assoc
1314fcf3ce44SJohn Forte )
1315fcf3ce44SJohn Forte {
1316fcf3ce44SJohn Forte 	int ec = 0;
1317fcf3ce44SJohn Forte 	xmlDocPtr doc;
1318fcf3ce44SJohn Forte 	xmlXPathContextPtr context = NULL;
1319fcf3ce44SJohn Forte 	xmlXPathObjectPtr result = NULL;
1320fcf3ce44SJohn Forte 	xmlNodePtr node;
1321fcf3ce44SJohn Forte 
1322fcf3ce44SJohn Forte 	uint32_t puid, parent_type;
1323fcf3ce44SJohn Forte 	uint32_t uid, match_uid;
1324fcf3ce44SJohn Forte 
1325fcf3ce44SJohn Forte 	char prop;
1326fcf3ce44SJohn Forte 	const xmlChar *prop_name;
1327fcf3ce44SJohn Forte 	xmlChar *prop_value;
1328fcf3ce44SJohn Forte 	int i;
1329fcf3ce44SJohn Forte 
1330fcf3ce44SJohn Forte 	/* get the xml doc */
1331fcf3ce44SJohn Forte 	ec = get_xml_doc(&doc);
1332fcf3ce44SJohn Forte 	if (doc == NULL) {
1333fcf3ce44SJohn Forte 		return (ec);
1334fcf3ce44SJohn Forte 	}
1335fcf3ce44SJohn Forte 
1336fcf3ce44SJohn Forte 	/* get the container object UID */
1337fcf3ce44SJohn Forte 	parent_type = TYPE_OF_PARENT[assoc->type];
1338fcf3ce44SJohn Forte 	ASSERT(parent_type != 0);
1339fcf3ce44SJohn Forte 	puid = get_parent_uid(assoc);
1340fcf3ce44SJohn Forte 	ASSERT(puid != 0);
1341fcf3ce44SJohn Forte 
1342fcf3ce44SJohn Forte 	/* get the member object UID */
1343fcf3ce44SJohn Forte 	i = get_index_by_otype(assoc->type);
1344fcf3ce44SJohn Forte 	prop = xmlArg2[i] - 'a';
1345fcf3ce44SJohn Forte 	prop_name = xmlPropName[prop];
1346fcf3ce44SJohn Forte 	match_uid = assoc->attrs[UID_ATTR_INDEX[assoc->type]].value.ui;
1347fcf3ce44SJohn Forte 
1348fcf3ce44SJohn Forte 	/* locate the container object */
1349fcf3ce44SJohn Forte 	ec = locate_xml_node(doc, parent_type, puid,
1350fcf3ce44SJohn Forte 	    &node, &context, &result);
1351fcf3ce44SJohn Forte 
1352fcf3ce44SJohn Forte 	/* get the membership nodes */
1353fcf3ce44SJohn Forte 	if (node != NULL) {
1354fcf3ce44SJohn Forte 		node = node->children;
1355fcf3ce44SJohn Forte 	}
1356fcf3ce44SJohn Forte 
1357fcf3ce44SJohn Forte 	/* get the matching membership node */
1358fcf3ce44SJohn Forte 	while (node) {
1359fcf3ce44SJohn Forte 		if (node->type == XML_ELEMENT_NODE) {
1360fcf3ce44SJohn Forte 			i = get_index_by_name(node->name);
1361fcf3ce44SJohn Forte 			ASSERT(i >= 0);
1362fcf3ce44SJohn Forte 			if (xmlType[i][0] == 'o' &&
1363fcf3ce44SJohn Forte 			    xmlArg1[i] == assoc->type) {
1364fcf3ce44SJohn Forte 				prop_value = xmlGetProp(node, prop_name);
1365fcf3ce44SJohn Forte 				if (prop_value) {
1366fcf3ce44SJohn Forte 					uid = atoi((const char *)prop_value);
1367fcf3ce44SJohn Forte 					xmlFree(prop_value);
1368fcf3ce44SJohn Forte 					if (uid == match_uid) {
1369fcf3ce44SJohn Forte 						break;
1370fcf3ce44SJohn Forte 					}
1371fcf3ce44SJohn Forte 				}
1372fcf3ce44SJohn Forte 			}
1373fcf3ce44SJohn Forte 		}
1374fcf3ce44SJohn Forte 		node = node->next;
1375fcf3ce44SJohn Forte 	}
1376fcf3ce44SJohn Forte 
1377fcf3ce44SJohn Forte 	/* destroy it */
1378fcf3ce44SJohn Forte 	if (node) {
1379fcf3ce44SJohn Forte 		xmlUnlinkNode(node);
1380fcf3ce44SJohn Forte 		xmlFreeNode(node);
1381fcf3ce44SJohn Forte 	}
1382fcf3ce44SJohn Forte 
1383fcf3ce44SJohn Forte 	if (result) {
1384fcf3ce44SJohn Forte 		xmlXPathFreeObject(result);
1385fcf3ce44SJohn Forte 	}
1386fcf3ce44SJohn Forte 	if (context) {
1387fcf3ce44SJohn Forte 		xmlXPathFreeContext(context);
1388fcf3ce44SJohn Forte 	}
1389fcf3ce44SJohn Forte 
1390fcf3ce44SJohn Forte 	return (ec);
1391fcf3ce44SJohn Forte }
1392fcf3ce44SJohn Forte 
1393fcf3ce44SJohn Forte /*
1394fcf3ce44SJohn Forte  * ****************************************************************************
1395fcf3ce44SJohn Forte  *
1396fcf3ce44SJohn Forte  * xml_update_commit:
1397fcf3ce44SJohn Forte  *	backup the current written file and commit all updates from
1398fcf3ce44SJohn Forte  *	the xml doc to the written file.
1399fcf3ce44SJohn Forte  *
1400fcf3ce44SJohn Forte  * return - error code.
1401fcf3ce44SJohn Forte  *
1402fcf3ce44SJohn Forte  * ****************************************************************************
1403fcf3ce44SJohn Forte  */
1404fcf3ce44SJohn Forte static int
xml_update_commit()1405fcf3ce44SJohn Forte xml_update_commit(
1406fcf3ce44SJohn Forte )
1407fcf3ce44SJohn Forte {
1408fcf3ce44SJohn Forte 	int ec = 0;
1409fcf3ce44SJohn Forte 
1410fcf3ce44SJohn Forte 	if (xml_doc) {
1411fcf3ce44SJohn Forte 		/* write to tmp file */
1412fcf3ce44SJohn Forte 		if (xmlSaveFormatFile(xml_tmp_file, xml_doc, 1) == -1 ||
1413fcf3ce44SJohn Forte 		    /* backup the current file */
1414fcf3ce44SJohn Forte 		    rename(xml_file, xml_bak_file) != 0 ||
1415fcf3ce44SJohn Forte 		    /* rename the tmp file to the current file */
1416fcf3ce44SJohn Forte 		    rename(xml_tmp_file, xml_file) != 0) {
1417fcf3ce44SJohn Forte 			/* failed saving file */
1418fcf3ce44SJohn Forte 			ec = ISNS_RSP_INTERNAL_ERROR;
1419fcf3ce44SJohn Forte 		}
1420fcf3ce44SJohn Forte 		/* close the xml_doc */
1421fcf3ce44SJohn Forte 		xmlFreeDoc(xml_doc);
1422fcf3ce44SJohn Forte 		xml_doc = NULL;
1423fcf3ce44SJohn Forte 	}
1424fcf3ce44SJohn Forte 
1425fcf3ce44SJohn Forte 	return (ec);
1426fcf3ce44SJohn Forte }
1427fcf3ce44SJohn Forte 
1428fcf3ce44SJohn Forte /*
1429fcf3ce44SJohn Forte  * ****************************************************************************
1430fcf3ce44SJohn Forte  *
1431fcf3ce44SJohn Forte  * xml_update_retreat:
1432fcf3ce44SJohn Forte  *	ignore all of updates in the xml doc.
1433fcf3ce44SJohn Forte  *
1434fcf3ce44SJohn Forte  * return - 0: always successful.
1435fcf3ce44SJohn Forte  *
1436fcf3ce44SJohn Forte  * ****************************************************************************
1437fcf3ce44SJohn Forte  */
1438fcf3ce44SJohn Forte static int
xml_update_retreat()1439fcf3ce44SJohn Forte xml_update_retreat(
1440fcf3ce44SJohn Forte )
1441fcf3ce44SJohn Forte {
1442fcf3ce44SJohn Forte 	if (xml_doc) {
1443fcf3ce44SJohn Forte 		/* close the xml_doc */
1444fcf3ce44SJohn Forte 		xmlFreeDoc(xml_doc);
1445fcf3ce44SJohn Forte 		xml_doc = NULL;
1446fcf3ce44SJohn Forte 	}
1447fcf3ce44SJohn Forte 
1448fcf3ce44SJohn Forte 	return (0);
1449fcf3ce44SJohn Forte }
1450