xref: /illumos-gate/usr/src/cmd/isns/isnsadm/isnsadm.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * isnsadm.c : isnsadm CL
28  *
29  */
30 
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <devid.h>
36 #include <fcntl.h>
37 #include <door.h>
38 #include <errno.h>
39 #include <strings.h>
40 #include <libscf.h>
41 #include <libxml/xmlreader.h>
42 #include <libxml/xmlwriter.h>
43 #include <libxml/parser.h>
44 #include <libxml/xpath.h>
45 #include <libxml/tree.h>
46 #include <wchar.h>
47 #include <locale.h>
48 #include "isns_mgmt.h"
49 #include "isns_utils.h"
50 #include "isns_protocol.h"
51 #include "cmdparse.h"
52 #include "isnsadm.h"
53 
54 /* object functions per subcommand */
55 static int list_node_func(int, char **, cmdOptions_t *, void *);
56 static int list_dd_func(int, char **, cmdOptions_t *, void *);
57 static int list_ddset_func(int, char **, cmdOptions_t *, void *);
58 static int add_node_func(int, char **, cmdOptions_t *, void *);
59 static int add_dd_func(int, char **, cmdOptions_t *, void *);
60 static int delete_dd_func(int, char **, cmdOptions_t *, void *);
61 static int delete_ddset_func(int, char **, cmdOptions_t *, void *);
62 static int create_dd_func(int, char **, cmdOptions_t *, void *);
63 static int create_ddset_func(int, char **, cmdOptions_t *, void *);
64 static int remove_node_func(int, char **, cmdOptions_t *, void *);
65 static int remove_dd_func(int, char **, cmdOptions_t *, void *);
66 static int modify_dd_func(int, char **, cmdOptions_t *, void *);
67 static int modify_ddset_func(int, char **, cmdOptions_t *, void *);
68 static int enable_ddset_func(int, char **, cmdOptions_t *, void *);
69 static int disable_ddset_func(int, char **, cmdOptions_t *, void *);
70 static int show_config_func(int, char **, cmdOptions_t *, void *);
71 static int i_enableddset(int, char **, boolean_t);
72 static xmlTextReaderPtr lookup_next_matching_elem(xmlTextReaderPtr, int *,
73 	const char *, const char *);
74 static int handle_association_info(xmlChar *, association_t);
75 static int process_result_response(xmlChar *, int obj);
76 static int process_get_assoc_response(xmlChar *, association_t);
77 static int process_get_response(object_type, xmlChar *, uint32_t);
78 static int cvt_enumerate_rsp_to_get_req(xmlChar *, xmlChar **, object_type,
79 	uint32_t);
80 static int build_get_xml_doc(int, char **, object_type, xmlChar **);
81 static int build_delete_xml_doc(int, char **, object_type, char *, xmlChar **);
82 static int build_create_xml_doc(int, char **, object_type, char *, xmlChar **);
83 static int build_modify_xml_doc(int, char **, object_type, boolean_t,
84 	xmlChar **);
85 static int build_rename_xml_doc(char *, object_type, uint32_t, xmlChar **);
86 static int build_assoc_xml_doc(xmlChar *, association_t, xmlChar **);
87 static int build_assoc_xml_doc(xmlChar *, association_t, xmlChar **);
88 static int build_enumerate_xml_doc(object_type, xmlChar **);
89 
90 #define	NEW_XMLARGV(old, n) (xmlChar **)realloc((xmlChar *)old, \
91 	(unsigned)(n+2) * sizeof (xmlChar *))
92 
93 #define	XML_SFREE(x)	(((x) != NULL) ? (xmlFree(x), (x) = NULL) : (void *)0)
94 
95 #define	VERSION_STRING_MAX_LEN	10
96 
97 #define	OPTIONSTRING_NAME	"name"
98 #define	OPTIONSTRING_DDNAME	"Discovery Domain name"
99 #define	OPTIONSTRING_DDSETNAME	"Discovery Domain Set name"
100 #define	OPTIONSTRING_TARGET	"target"
101 #define	OPTIONSTRING_INITIATOR	"initiator"
102 #define	OPTIONSTRING_VERBOSE	"verbose"
103 
104 #define	VERBOSE		0x00000001
105 #define	INITIATOR_ONLY	0x00000010
106 #define	TARGET_ONLY	0x00000100
107 
108 /* object table based on definitions in isns_mgmt.h. */
109 static obj_table_entry_t obj_table[] = {
110 	{NODEOBJECT, Node},
111 	{DDOBJECT, DiscoveryDomain},
112 	{DDSETOBJECT, DiscoveryDomainSet},
113 	{DDOBJECTMEMBER, DiscoveryDomainMember},
114 	{DDSETOBJECTMEMBER, DiscoveryDomainSetMember},
115 	{ISNSSERVER, ServerConfig},
116 	{NULL, 0}
117 };
118 
119 /*
120  *  MAJOR - This should only change when there is an incompatible change made
121  *  to the interfaces or the output.
122  *
123  *  MINOR - This should change whenever there is a new command or new feature
124  *  with no incompatible change.
125  */
126 #define	VERSION_STRING_MAJOR	    "1"
127 #define	VERSION_STRING_MINOR	    "0"
128 static char *ISNS_FMRI = "network/isns_server:default";
129 
130 /*
131  * Add new options here
132  */
133 
134 /* tables set up based on cmdparse instructions */
135 optionTbl_t longOptions[] = {
136 	{"target", no_arg, 't', OPTIONSTRING_TARGET},
137 	{"initiator", no_arg, 'i', OPTIONSTRING_INITIATOR},
138 	{"verbose", no_arg, 'v', OPTIONSTRING_VERBOSE},
139 	{"name", required_arg, 'n', OPTIONSTRING_NAME},
140 	{"dd", required_arg, 'd', OPTIONSTRING_DDNAME},
141 	{"dd-set", required_arg, 's', OPTIONSTRING_DDSETNAME},
142 	{NULL, 0, 0, 0}
143 };
144 
145 
146 /*
147  * Add new subcommands here
148  */
149 subCommandProps_t subcommands[] = {
150 	{"list-node", LISTNODE, list_node_func, "itv", B_FALSE, NULL,
151 		OPERAND_OPTIONAL_MULTIPLE, "node-name"},
152 	{"list-dd", LISTDD, list_dd_func, "v", B_FALSE, NULL,
153 		OPERAND_OPTIONAL_MULTIPLE, OPTIONSTRING_DDNAME},
154 	{"list-dd-set", LISTDDSET, list_ddset_func, "v", B_FALSE, NULL,
155 		OPERAND_OPTIONAL_MULTIPLE, OPTIONSTRING_DDSETNAME},
156 	{"create-dd", CREATEDD, create_dd_func, NULL, B_FALSE, NULL,
157 		OPERAND_MANDATORY_MULTIPLE, OPTIONSTRING_DDNAME},
158 	{"create-dd-set", CREATEDDSET, create_ddset_func, NULL, B_FALSE, NULL,
159 		OPERAND_MANDATORY_MULTIPLE, OPTIONSTRING_DDSETNAME},
160 	{"delete-dd", DELETEDD, delete_dd_func, NULL, B_FALSE, NULL,
161 		OPERAND_MANDATORY_MULTIPLE, OPTIONSTRING_DDNAME},
162 	{"delete-dd-set", DELETEDDSET, delete_ddset_func, NULL, B_FALSE, NULL,
163 		OPERAND_MANDATORY_MULTIPLE, OPTIONSTRING_DDSETNAME},
164 	{"add-node", ADDNODE, add_node_func, "d", B_TRUE, NULL,
165 		OPERAND_MANDATORY_MULTIPLE, "node-name"},
166 	{"add-dd", ADDDD, add_dd_func, "s", B_TRUE, NULL,
167 		OPERAND_MANDATORY_MULTIPLE, OPTIONSTRING_DDNAME},
168 	{"remove-node", REMOVENODE, remove_node_func, "d", B_TRUE, NULL,
169 		OPERAND_MANDATORY_MULTIPLE, "node-name"},
170 	{"remove-dd", REMOVEDD, remove_dd_func, "s", B_TRUE, NULL,
171 		OPERAND_MANDATORY_MULTIPLE, OPTIONSTRING_DDNAME},
172 	{"modify-dd", MODIFYDD, modify_dd_func, "n", B_TRUE, NULL,
173 		OPERAND_MANDATORY_SINGLE, OPTIONSTRING_NAME},
174 	{"modify-dd-set", MODIFYDDSET, modify_ddset_func, "n", B_TRUE, NULL,
175 		OPERAND_MANDATORY_SINGLE, OPTIONSTRING_NAME},
176 	{"enable-dd-set", ENABLEDDSET, enable_ddset_func, NULL, B_FALSE, NULL,
177 		OPERAND_MANDATORY_MULTIPLE, OPTIONSTRING_DDSETNAME},
178 	{"disable-dd-set", DISABLEDDSET, disable_ddset_func, NULL, B_FALSE,
179 		NULL, OPERAND_MANDATORY_MULTIPLE, OPTIONSTRING_DDSETNAME},
180 	{"show-config", SHOWCONFIG, show_config_func, NULL, B_FALSE, NULL,
181 		OPERAND_NONE, NULL},
182 	{NULL, 0, NULL, NULL, 0, NULL, 0, NULL}
183 };
184 
185 /*
186  * ****************************************************************************
187  *
188  * check_door_error
189  *
190  * input:
191  *  errno from the door call.
192  *
193  * Returns:
194  *  either door error or smf service error.
195  *
196  * ****************************************************************************
197  */
198 static int
199 check_door_error(int door_err, int err)
200 {
201 	char	*state = NULL;
202 	int	ret;
203 
204 	if (((state = smf_get_state(ISNS_FMRI)) != NULL) &&
205 	    (strcmp(state, SCF_STATE_STRING_ONLINE) != 0)) {
206 		ret = ERROR_ISNS_SMF_SERVICE_NOT_ONLINE;
207 	} else {
208 	    (void) fprintf(stderr, "%s\n",
209 		(door_err == ERROR_DOOR_CALL_FAILED) ?
210 		getTextMessage(ERROR_DOOR_CALL_FAILED) :
211 		getTextMessage(ERROR_DOOR_OPEN_FAILED));
212 	    (void) fprintf(stderr, "\terrno: %s\n", strerror(err));
213 	    ret = door_err;
214 	}
215 
216 	if (state) free(state);
217 
218 	return (ret);
219 }
220 
221 /*
222  * ****************************************************************************
223  *
224  * lookup an element based on the element name.
225  *
226  * reader	- current xmlReaderReadPtr
227  * m_falg	- indicate lookup result
228  * elem		- name of element to look up.
229  * endelem	- name of end element to look up.
230  *
231  * ****************************************************************************
232  */
233 static	xmlTextReaderPtr
234 lookup_next_matching_elem(xmlTextReaderPtr reader, int *m_flag,
235 	const char *elem, const char *endelem)
236 {
237 
238 	if (reader == NULL) {
239 	    *m_flag = NO_MATCH;
240 	    return (NULL);
241 	}
242 
243 	do {
244 	/*
245 	 * if (xmlTextReaderName(reader) != NULL) {
246 	 * 	printf("%s ", xmlTextReaderName(reader));
247 	 * }
248 	 * printf("%d %d %d\n",
249 	 * xmlTextReaderDepth(reader),
250 	 * xmlTextReaderNodeType(reader),
251 	 * xmlTextReaderIsEmptyElement(reader));
252 	 */
253 		/*
254 		 * if match with elem, return the reader with READER_MATCH flag.
255 		 * if match with end elem, return the reader wtih
256 		 * END_READER_MATCH flag.
257 		 */
258 	    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) {
259 		if (XMLNCMP(reader, elem) == 0) {
260 		    *m_flag = READER_MATCH;
261 		    return (reader);
262 		}
263 	    } else if (xmlTextReaderNodeType(reader) ==
264 		XML_READER_TYPE_END_ELEMENT) {
265 		if (XMLNCMP(reader, endelem) == 0) {
266 		    *m_flag = END_READER_MATCH;
267 		    return (reader);
268 		}
269 	    }
270 	} while (xmlTextReaderRead(reader) == 1);
271 
272 	*m_flag = NO_MATCH;
273 	return (NULL);
274 }
275 
276 /*
277  * ****************************************************************************
278  *
279  * Routine for getAssociated operation
280  *	Construct association request  based on the name and calls door
281  *	interface.
282  *
283  * name		- name attributes of an object for getting an association
284  * assoc	- association type
285  *
286  * ****************************************************************************
287  */
288 static int
289 handle_association_info(xmlChar *name, association_t assoc)
290 {
291 
292 	xmlChar *doc;
293 	door_arg_t darg;
294 	msg_code_t ret;
295 	int fd;
296 
297 	if ((ret = build_assoc_xml_doc(name, assoc, &doc)) != 0) {
298 	    return (ret);
299 	}
300 
301 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
302 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
303 	    return (ret);
304 	}
305 
306 	(void) bzero(&darg, sizeof (darg));
307 	bzero(&darg, sizeof (darg));
308 	darg.data_ptr = (char *)doc;
309 	darg.data_size = xmlStrlen(doc) + 1;
310 	darg.rbuf = NULL;
311 	darg.rsize = 0;
312 	if ((door_call(fd, &darg)) == -1) {
313 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
314 	    (void) close(fd);
315 	    (void) xmlFree(doc);
316 	    return (ret);
317 	}
318 
319 	if ((ret = process_get_assoc_response((xmlChar *)darg.rbuf,
320 	    assoc)) != 0) {
321 	/*
322 	 * door frame work allocated a buffer when the date lager
323 	 * that rbuf. indicate if munmap is required on rbuf.
324 	 */
325 	    (void) munmap(darg.rbuf, darg.rsize);
326 	    (void) close(fd);
327 	    (void) xmlFree(doc);
328 	    return (ret);
329 	}
330 
331 	(void) munmap(darg.rbuf, darg.rsize);
332 
333 	(void) close(fd);
334 	(void) xmlFree(doc);
335 
336 	return (0);
337 }
338 
339 /*
340  * ****************************************************************************
341  *
342  * process_error_status
343  *	The routine process non 0 status and print out error message.
344  *
345  * status	- status code
346  * reader	- reader that points to the message element.
347  *
348  * ****************************************************************************
349  */
350 static void
351 print_error_status(int status, int obj, xmlTextReaderPtr reader)
352 {
353 	int m_flag = 0;
354 
355 	switch (status) {
356 	case ISNS_RSP_BUSY:
357 	    (void) fprintf(stderr, "%s\n",
358 		getTextMessage(ERROR_SERVER_BUSY));
359 	    break;
360 	case ISNS_RSP_INTERNAL_ERROR:
361 	    (void) fprintf(stderr, "%s\n",
362 		getTextMessage(ERROR_SERVER_INTERNAL_ERROR));
363 	    break;
364 	case ISNS_RSP_OPTION_NOT_UNDERSTOOD:
365 	    if ((obj == DiscoveryDomain) ||
366 		(obj == DiscoveryDomainMember)) {
367 		(void) fprintf(stderr, "%s\n",
368 		getTextMessage(ERROR_OPERATION_NOT_ALLOWED_FOR_DEFAULT_DD));
369 	    } else {
370 		(void) fprintf(stderr, "%s\n",
371 		getTextMessage(ERROR_OPERATION_NOT_ALLOWED_FOR_DEFAULT_DDSET));
372 	    }
373 	    break;
374 	case PARTIAL_FAILURE:
375 	    (void) fprintf(stderr, "%s\n",
376 		getTextMessage(ERROR_PARTIAL_FAILURE));
377 	    break;
378 	case ERR_NO_SUCH_ASSOCIATION:
379 	    if ((obj == DiscoveryDomain) ||
380 		(obj == DiscoveryDomainMember)) {
381 		(void) fprintf(stderr, "%s\n",
382 		getTextMessage(ERROR_DDMEMBER_NOT_FOUND));
383 	    } else {
384 		(void) fprintf(stderr, "%s\n",
385 		getTextMessage(ERROR_DDSETMEMBER_NOT_FOUND));
386 	    }
387 	    break;
388 	case ERR_ALREADY_ASSOCIATED:
389 	    if ((obj == DiscoveryDomain) ||
390 		(obj == DiscoveryDomainMember)) {
391 		(void) fprintf(stderr, "%s\n",
392 		getTextMessage(ERROR_DDMEMBER_ALREADY_EXIST));
393 	    } else {
394 		(void) fprintf(stderr, "%s\n",
395 		getTextMessage(ERROR_DDSETMEMBER_ALREADY_EXIST));
396 	    }
397 	    break;
398 	case ERR_NAME_IN_USE:
399 	    if ((obj == DiscoveryDomain) ||
400 		(obj == DiscoveryDomainMember)) {
401 		(void) fprintf(stderr, "%s\n",
402 		getTextMessage(ERROR_DD_NAME_IN_USE));
403 	    } else {
404 		(void) fprintf(stderr, "%s\n",
405 		getTextMessage(ERROR_DDSET_NAME_IN_USE));
406 	    }
407 	    break;
408 	default:
409 	    reader = lookup_next_matching_elem(reader, &m_flag,
410 		MESSAGEELEMENT, RESULTELEMENT);
411 	    if (m_flag == READER_MATCH) {
412 		(void) xmlTextReaderRead(reader);
413 		(void) fprintf(stderr, "Error: %s\n",
414 			(const char *) xmlTextReaderConstValue(reader));
415 	    } else {
416 		(void) fprintf(stderr, "Error: %s\n",
417 		getTextMessage(ERROR_XML_MESSAGE_ELEM_NOT_FOUND));
418 	    }
419 	}
420 }
421 
422 /*
423  * ****************************************************************************
424  *
425  * print_partial_failure_info
426  *	The routine prints partial failure info.
427  *
428  * status	- status code
429  * reader	- reader that points to the message element.
430  *
431  * ****************************************************************************
432  */
433 static void
434 print_partial_failure_info(xmlChar *doc)
435 {
436 	xmlChar expr[ISNS_MAX_LABEL_LEN + 13];
437 	xmlDocPtr x_doc;
438 	xmlXPathContextPtr ctext = NULL;
439 	xmlXPathObjectPtr xpath_obj = NULL;
440 	xmlNodeSetPtr r_nodes = NULL;
441 	xmlAttrPtr attr = NULL;
442 	int i, cnt, obj = 0;
443 
444 	if ((x_doc = xmlParseMemory((const char *)doc, xmlStrlen(doc))) ==
445 	    NULL) {
446 	    (void) fprintf(stderr, "%s\n",
447 		getTextMessage(ERROR_NO_ADDITIONAL_PARTIAL_FAILIRE_INFO));
448 	}
449 
450 	ctext = xmlXPathNewContext(x_doc);
451 	if (ctext == NULL) {
452 	    (void) fprintf(stderr, "%s\n",
453 		getTextMessage(ERROR_NO_ADDITIONAL_PARTIAL_FAILIRE_INFO));
454 	}
455 
456 	for (i = 0; obj_table[i].obj_str != NULL; i++) {
457 	    (void) xmlStrPrintf(expr, ISNS_MAX_LABEL_LEN + 13,
458 		(const unsigned char *)"%s\"%s\"]", "//*[name()=",
459 		obj_table[i].obj_str);
460 	    xpath_obj = xmlXPathEvalExpression(expr, ctext);
461 	    if ((xpath_obj) && (xpath_obj->nodesetval) &&
462 		(xpath_obj->nodesetval->nodeNr > 0) &&
463 		(xpath_obj->nodesetval->nodeTab)) {
464 		obj = obj_table[i].obj_id;
465 		break;
466 	    }
467 	}
468 
469 	if (obj == 0) {
470 	    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
471 	    (void) fprintf(stderr, "%s\n",
472 		getTextMessage(ERROR_NO_ADDITIONAL_PARTIAL_FAILIRE_INFO));
473 	}
474 
475 	switch (obj) {
476 	    case DiscoveryDomainMember:
477 		r_nodes = xpath_obj->nodesetval;
478 		cnt = r_nodes->nodeNr;
479 		for (i = 0; i < cnt; i++) {
480 		    attr = r_nodes->nodeTab[i]->properties;
481 		    for (; attr != NULL; attr = attr->next) {
482 			if (xmlStrncmp(attr->name, (xmlChar *)DDNAMEATTR,
483 			    xmlStrlen((xmlChar *)DDNAMEATTR)) == 0) {
484 				(void) fprintf(stderr, "DD Name: %s\t",
485 				xmlNodeGetContent(attr->children));
486 			}
487 			if (xmlStrncmp(attr->name, (xmlChar *)NODENAMEATTR,
488 			    xmlStrlen((xmlChar *)NODENAMEATTR)) == 0) {
489 				(void) fprintf(stderr, "Node Name: %s\t",
490 				xmlNodeGetContent(attr->children));
491 			}
492 		    }
493 		    (void) fprintf(stderr, "\n");
494 		}
495 		if (xpath_obj) xmlXPathFreeObject(xpath_obj);
496 		break;
497 	    case DiscoveryDomainSetMember:
498 		r_nodes = xpath_obj->nodesetval;
499 		cnt = r_nodes->nodeNr;
500 		for (i = 0; i < cnt; i++) {
501 		    attr = r_nodes->nodeTab[i]->properties;
502 		    for (; attr != NULL; attr = attr->next) {
503 			if (xmlStrncmp(attr->name, (xmlChar *)DDSETNAMEATTR,
504 			    xmlStrlen((xmlChar *)DDNAMEATTR)) == 0) {
505 				(void) fprintf(stderr, "DD Set Name: %s\t",
506 				xmlNodeGetContent(attr->children));
507 			}
508 			if (xmlStrncmp(attr->name, (xmlChar *)DDNAMEATTR,
509 			    xmlStrlen((xmlChar *)NODENAMEATTR)) == 0) {
510 				(void) fprintf(stderr, "DD Name: %s\t",
511 				xmlNodeGetContent(attr->children));
512 			}
513 		    }
514 		    (void) fprintf(stderr, "\n");
515 		}
516 		if (xpath_obj) xmlXPathFreeObject(xpath_obj);
517 		break;
518 	    case Node:
519 	    case DiscoveryDomain:
520 	    case DiscoveryDomainSet:
521 		r_nodes = xpath_obj->nodesetval;
522 		cnt = r_nodes->nodeNr;
523 		for (i = 0; i < cnt; i++) {
524 		    attr = r_nodes->nodeTab[i]->properties;
525 		    for (; attr != NULL; attr = attr->next) {
526 			if ((xmlStrncmp(attr->name, (xmlChar *)NAMEATTR,
527 			    xmlStrlen((xmlChar *)NAMEATTR))) == 0) {
528 				(void) fprintf(stderr, "Object Name: %s\n",
529 				xmlNodeGetContent(attr->children));
530 			}
531 		    }
532 		}
533 		if (xpath_obj) xmlXPathFreeObject(xpath_obj);
534 		break;
535 	}
536 }
537 
538 /*
539  * ****************************************************************************
540  *
541  * process_result_response
542  *	The routine process association data based on the association type.
543  *
544  * doc		- result
545  * obj		- associated object type
546  *
547  * ****************************************************************************
548  */
549 static int
550 process_result_response(xmlChar *doc, int obj)
551 {
552 	xmlTextReaderPtr reader;
553 	int m_flag = 0, status;
554 
555 	if ((reader = (xmlTextReaderPtr)xmlReaderForMemory((const char *)doc,
556 	    xmlStrlen(doc), NULL, NULL, 0)) == NULL) {
557 		return (ERROR_XML_READER_NULL);
558 	}
559 
560 	/* if status is 0, continue on.  Otherwise return an error. */
561 	if (reader = lookup_next_matching_elem(reader, &m_flag, STATUSELEMENT,
562 	    RESULTELEMENT)) {
563 	    if (m_flag == READER_MATCH) {
564 		if (xmlTextReaderRead(reader) == 1) {
565 		    status =
566 		    atoi((const char *)xmlTextReaderConstValue(reader));
567 		    if (status != 0) {
568 			print_error_status(status, obj, reader);
569 			(void) xmlTextReaderClose(reader);
570 			(void) xmlFreeTextReader(reader);
571 			if (status == PARTIAL_FAILURE) {
572 			    print_partial_failure_info(doc);
573 			}
574 			return (status);
575 		    }
576 		} else {
577 		    (void) xmlTextReaderClose(reader);
578 		    (void) xmlFreeTextReader(reader);
579 		    return (ERROR_XML_STATUS_ELEM_NOT_FOUND);
580 		}
581 	    } else {
582 		(void) xmlTextReaderClose(reader);
583 		(void) xmlFreeTextReader(reader);
584 		return (ERROR_XML_STATUS_ELEM_NOT_FOUND);
585 	    }
586 	} else {
587 	    (void) fprintf(stderr, "%s\n",
588 		getTextMessage(ERROR_XML_READER_NULL));
589 	    return (ERROR_XML_READER_NULL);
590 	}
591 
592 	(void) xmlTextReaderClose(reader);
593 	(void) xmlFreeTextReader(reader);
594 	return (0);
595 }
596 
597 /*
598  * ****************************************************************************
599  *
600  * process_get_assoc_response
601  *	The routine process association data based on the association type.
602  *
603  * doc		- association data
604  * assoc	- associatiion type
605  *
606  * ****************************************************************************
607  */
608 static int
609 process_get_assoc_response(xmlChar *doc, association_t assoc)
610 {
611 	xmlTextReaderPtr reader;
612 	xmlChar *ddsname, *ddname, *nodename;
613 	wchar_t wc_name[ISNS_MAX_NAME_LEN];
614 	int m_flag = 0, h_printed = 0, status;
615 
616 	if ((reader = (xmlTextReaderPtr)xmlReaderForMemory((const char *)doc,
617 			xmlStrlen(doc), NULL, NULL, 0)) == NULL) {
618 	    return (ERROR_XML_READER_NULL);
619 	}
620 
621 	/* if status is 0, continue on.  Otherwise return an error. */
622 	if (reader = lookup_next_matching_elem(reader, &m_flag, STATUSELEMENT,
623 	    RESULTELEMENT)) {
624 	    if (m_flag == READER_MATCH) {
625 		if (xmlTextReaderRead(reader) == 1) {
626 		    status =
627 		    atoi((const char *)xmlTextReaderConstValue(reader));
628 		    if ((status != 0) && (status != PARTIAL_SUCCESS)) {
629 			/* not an error */
630 			if ((status !=  ERR_NO_SUCH_ASSOCIATION) &&
631 			    (status !=  ERR_NO_ASSOCIATED_DD_FOUND) &&
632 			    (status !=  ERR_NO_ASSOCIATED_DDSET_FOUND)) {
633 			    (void) xmlTextReaderClose(reader);
634 			    (void) xmlFreeTextReader(reader);
635 			    return (0);
636 			} else {
637 			    print_error_status(status,
638 				((assoc == node_to_dd) || (dd_to_node)) ?
639 				DiscoveryDomain : DiscoveryDomainSet, reader);
640 			    (void) xmlTextReaderClose(reader);
641 			    (void) xmlFreeTextReader(reader);
642 			    return (status);
643 			}
644 		    }
645 		} else {
646 		    (void) xmlTextReaderClose(reader);
647 		    (void) xmlFreeTextReader(reader);
648 		    return (ERROR_XML_STATUS_ELEM_NOT_FOUND);
649 		}
650 	    } else {
651 		return (ERROR_XML_STATUS_ELEM_NOT_FOUND);
652 	    }
653 	} else {
654 	    return (ERROR_XML_READER_NULL);
655 	}
656 
657 	m_flag = 0;
658 
659 	switch (assoc) {
660 	    case node_to_dd:
661 		/* process DD elements */
662 		while (reader = lookup_next_matching_elem(reader, &m_flag,
663 		    DDOBJECTMEMBER, ISNSRESPONSE)) {
664 		    if (m_flag == END_READER_MATCH) {
665 			(void) xmlTextReaderNext(reader);
666 			break;
667 		    } else if (m_flag == READER_MATCH) {
668 			if ((ddname = (xmlTextReaderGetAttribute(reader,
669 			    (const xmlChar *)DDNAMEATTR))) != NULL) {
670 			    if (mbstowcs(wc_name, (const char *)ddname,
671 				ISNS_MAX_NAME_LEN) == (size_t)-1) {
672 				(void) wcscpy(wc_name, L"-");
673 			    }
674 			    if (h_printed) {
675 				(void) printf("\tDD Name: %ws\n", wc_name);
676 			    } else {
677 				(void) printf("\tDD Name: %ws\n", wc_name);
678 				h_printed = 1;
679 			    }
680 			    xmlFree(ddname);
681 			} else {
682 			    if (h_printed) {
683 				(void) printf("\t         %s\n", "-");
684 			    } else {
685 				(void) printf("\tDD Name: %s\n", "-");
686 				h_printed = 1;
687 			    }
688 			}
689 		    }
690 		    m_flag = 0;
691 		    (void) xmlTextReaderRead(reader);
692 		}
693 	    break;
694 	case dd_to_node:
695 		/* process the DiscoveryDoamin elements */
696 	    while (reader = lookup_next_matching_elem(reader, &m_flag,
697 		    DDOBJECTMEMBER, ISNSRESPONSE)) {
698 		if (m_flag == END_READER_MATCH) {
699 		    (void) xmlTextReaderNext(reader);
700 		    break;
701 		} else if (m_flag == READER_MATCH) {
702 		    if ((nodename = (xmlTextReaderGetAttribute(reader,
703 			    (const xmlChar *)NODENAMEATTR))) != NULL) {
704 			if (mbstowcs(wc_name, (const char *)nodename,
705 			    ISNS_MAX_NAME_LEN) == (size_t)-1) {
706 			    (void) wcscpy(wc_name, L"-");
707 			}
708 			(void) printf("\tiSCSI name: %ws\n", wc_name);
709 			xmlFree(nodename);
710 		    } else {
711 			(void) printf("\tiSCSI name: %s\n", "-");
712 		    }
713 		}
714 		m_flag = 0;
715 		(void) xmlTextReaderRead(reader);
716 	    }
717 	    break;
718 	case dd_to_ddset:
719 		/* process the DiscoveryDoaminSet elements */
720 	    while (reader = lookup_next_matching_elem(reader, &m_flag,
721 		    DDSETOBJECTMEMBER, ISNSRESPONSE)) {
722 		if (m_flag == END_READER_MATCH) {
723 		    (void) xmlTextReaderNext(reader);
724 		    break;
725 		} else if (m_flag == READER_MATCH) {
726 		    if ((ddsname = (xmlTextReaderGetAttribute(reader,
727 			(const xmlChar *)DDSETNAMEATTR))) != NULL) {
728 			if (mbstowcs(wc_name, (const char *)ddsname,
729 			    ISNS_MAX_NAME_LEN) == (size_t)-1) {
730 			    (void) wcscpy(wc_name, L"-");
731 			}
732 			if (h_printed) {
733 			    (void) printf("\t           %ws\n", wc_name);
734 			} else {
735 			    (void) printf("\tDD set(s): %ws\n", wc_name);
736 			    h_printed = 1;
737 			}
738 			xmlFree(ddsname);
739 		    } else {
740 			(void) printf("\tDD set(s): %s\n", "-");
741 		    }
742 		}
743 		m_flag = 0;
744 		(void) xmlTextReaderRead(reader);
745 	    }
746 	    break;
747 	case ddset_to_dd:
748 		/* process the DiscoveryDoaminSet elements */
749 	    while (reader = lookup_next_matching_elem(reader, &m_flag,
750 		    DDSETOBJECTMEMBER, ISNSRESPONSE)) {
751 		if (m_flag == END_READER_MATCH) {
752 		    (void) xmlTextReaderNext(reader);
753 		    break;
754 		} else if (m_flag == READER_MATCH) {
755 			if ((ddname = (xmlTextReaderGetAttribute(reader,
756 			    (const xmlChar *)DDNAMEATTR))) != NULL) {
757 			    if (mbstowcs(wc_name, (const char *)ddname,
758 				ISNS_MAX_NAME_LEN) == (size_t)-1) {
759 				(void) wcscpy(wc_name, L"-");
760 			    }
761 			    (void) printf("\tDD Name: %ws\n", wc_name);
762 			    xmlFree(ddname);
763 			} else {
764 			    (void) printf("\tDD Name: %s\n", "-");
765 			}
766 		}
767 		m_flag = 0;
768 		(void) xmlTextReaderRead(reader);
769 	    }
770 	    break;
771 	default:
772 	    (void) xmlTextReaderClose(reader);
773 	    (void) xmlFreeTextReader(reader);
774 	    return (UNKNOWN);
775 	}
776 
777 	if (status == PARTIAL_SUCCESS) {
778 	    (void) fprintf(stderr, "%s\n",
779 		getTextMessage(ERROR_PARTIAL_SUCCESS));
780 	}
781 	(void) xmlTextReaderClose(reader);
782 	(void) xmlFreeTextReader(reader);
783 	return (status);
784 }
785 
786 /*
787  * ****************************************************************************
788  *
789  * process_get_response :
790  *	display data from the get response doc based on flag.
791  *
792  * obj		- object type
793  * doc		- docuemet to process
794  * flag		- options from the subcommand
795  *
796  * ****************************************************************************
797  */
798 static int
799 process_get_response(object_type obj, xmlChar *doc, uint32_t flag)
800 {
801 	xmlTextReaderPtr reader;
802 	int m_flag = 0, ret = 0, status;
803 	xmlChar *name = NULL;
804 	wchar_t wc_name[ISNS_MAX_NAME_LEN];
805 	int tag_printed = 0;
806 
807 	if ((reader = (xmlTextReaderPtr)xmlReaderForMemory((const char *)doc,
808 	    xmlStrlen(doc), NULL, NULL, 0)) == NULL) {
809 		return (ERROR_XML_READER_NULL);
810 	}
811 
812 	/* if status is 0, continue on.  Otherwise return an error. */
813 	if (reader = lookup_next_matching_elem(reader, &m_flag, STATUSELEMENT,
814 	    RESULTELEMENT)) {
815 	    if (m_flag == READER_MATCH) {
816 		if (xmlTextReaderRead(reader) == 1) {
817 		    status =
818 		    atoi((const char *)xmlTextReaderConstValue(reader));
819 		    if ((status != 0) && (status != PARTIAL_SUCCESS)) {
820 			print_error_status(status, obj, reader);
821 			(void) xmlTextReaderClose(reader);
822 			(void) xmlFreeTextReader(reader);
823 			return (status);
824 		    }
825 		} else {
826 		    (void) xmlTextReaderClose(reader);
827 		    (void) xmlFreeTextReader(reader);
828 		    return (ERROR_XML_STATUS_ELEM_NOT_FOUND);
829 		}
830 	    } else {
831 		(void) xmlTextReaderClose(reader);
832 		(void) xmlFreeTextReader(reader);
833 		return (ERROR_XML_STATUS_ELEM_NOT_FOUND);
834 	    }
835 	} else {
836 	    return (ERROR_XML_READER_NULL);
837 	}
838 
839 	m_flag = 0;
840 
841 	switch (obj) {
842 	    case Node:
843 		/* process the node elements */
844 		while (reader = lookup_next_matching_elem(reader, &m_flag,
845 		    NODEOBJECT, ISNSRESPONSE)) {
846 		    if (m_flag == END_READER_MATCH) {
847 			break;
848 		    }
849 
850 		    /* check the type */
851 		    if ((xmlTextReaderMoveToAttribute(reader,
852 			(const xmlChar *)TYPEATTR)) == 1) {
853 			if (((flag & TARGET_ONLY) == TARGET_ONLY) &&
854 			    (XMLNCMPVAL(reader, TARGETTYPE) != 0)) {
855 			    /* move to next node object. */
856 			    (void) xmlTextReaderMoveToElement(reader);
857 			    (void) xmlTextReaderNext(reader);
858 			    continue;
859 			}
860 			if (((flag & INITIATOR_ONLY) == INITIATOR_ONLY) &&
861 			    (XMLNCMPVAL(reader, INITIATORTYPE) != 0)) {
862 			    /* move to next node object. */
863 			    (void) xmlTextReaderMoveToElement(reader);
864 			    (void) xmlTextReaderNext(reader);
865 			    continue;
866 			}
867 		    } else {
868 			ret = ERROR_XML_TYPE_ATTR_NOT_FOUND;
869 			goto out;
870 		    }
871 
872 		    if (((xmlTextReaderMoveToAttribute(reader,
873 			(const xmlChar *)NAMEATTR)) == 1) &&
874 			(const char *)xmlTextReaderConstValue(reader)) {
875 			if (mbstowcs(wc_name,
876 			    (const char *)xmlTextReaderConstValue(reader),
877 			    ISNS_MAX_NAME_LEN) == (size_t)-1) {
878 			    (void) wcscpy(wc_name, L"-");
879 			}
880 			if ((flag & VERBOSE) == VERBOSE) {
881 			    name = xmlTextReaderValue(reader);
882 			    (void) printf("iSCSI Name: %ws\n", wc_name);
883 			} else {
884 			    (void) printf("iSCSI Name: %ws\n", wc_name);
885 			}
886 		    } else {
887 			XML_SFREE(name);
888 			ret = ERROR_XML_TYPE_ATTR_NOT_FOUND;
889 			goto out;
890 		    }
891 		    if ((xmlTextReaderMoveToAttribute(reader,
892 			(const xmlChar *)ALIASATTR)) == 1) {
893 			if (xmlStrcmp(xmlTextReaderConstValue(reader),
894 			    (xmlChar *)"") == 0) {
895 			    (void) printf("\tAlias: %s\n", "-");
896 			} else {
897 			    if (mbstowcs(wc_name,
898 				(const char *)xmlTextReaderConstValue(reader),
899 				ISNS_MAX_NAME_LEN) == (size_t)-1) {
900 				(void) wcscpy(wc_name, L"-");
901 			    }
902 			    (void) printf("\tAlias: %ws\n", wc_name);
903 			}
904 		    }
905 
906 		    /* type attribute exist based on the previous checking. */
907 		    (void) xmlTextReaderMoveToAttribute(reader,
908 			(const xmlChar *)TYPEATTR);
909 		    (void) printf("\tType: %s\n",
910 			(const char *)xmlTextReaderConstValue(reader) ?
911 			(const char *)xmlTextReaderConstValue(reader) : "-");
912 
913 		    if ((flag & VERBOSE) == VERBOSE) {
914 			/* print more details */
915 			m_flag = 0;
916 			/*
917 			 * No details for deregistered node.
918 			 * skip to next isns object.
919 			 */
920 			if ((reader = lookup_next_matching_elem(reader,
921 			    &m_flag, ENTITYID, ISNSOBJECT))) {
922 			    if (m_flag == READER_MATCH) {
923 				/* move to entity id value. */
924 				if ((xmlTextReaderRead(reader) == 1) &&
925 				    xmlTextReaderConstValue(reader)) {
926 				    if (mbstowcs(wc_name,
927 					(const char *)
928 					xmlTextReaderConstValue(reader),
929 					ISNS_MAX_NAME_LEN) == (size_t)-1) {
930 					(void) wcscpy(wc_name,
931 					    L"-");
932 				    }
933 				    (void) printf("\tNetwork Entity: %ws\n",
934 					wc_name);
935 				} else {
936 				    (void) printf("\tNework Entity: -\n");
937 				}
938 			    } else if (m_flag == END_READER_MATCH) {
939 				(void) xmlTextReaderRead(reader);
940 				XML_SFREE(name);
941 				continue;
942 			    }
943 			}
944 
945 			/* print  portal info */
946 			m_flag = 0;
947 			while ((reader = lookup_next_matching_elem(reader,
948 			    &m_flag, IPADDR, NODEOBJECT))) {
949 			    if (m_flag == END_READER_MATCH) {
950 				(void) xmlTextReaderRead(reader);
951 				break;
952 			    }
953 			    /* move to the value of IP addr. */
954 			    if ((xmlTextReaderRead(reader) == 1) &&
955 				xmlTextReaderConstValue(reader)) {
956 				(void) printf("\tPortal: %s",
957 				xmlTextReaderConstValue(reader));
958 				/* get port number */
959 				m_flag = 0;
960 				if (reader = lookup_next_matching_elem(reader,
961 				    &m_flag, PORTNUMBER, UDPTCPPORT)) {
962 				    if ((xmlTextReaderRead(reader) == 1) &&
963 					xmlTextReaderConstValue(reader)) {
964 				    (void) printf(":%d\n",
965 					atoi((const char *)
966 					xmlTextReaderConstValue(reader)));
967 				    } else {
968 					(void) printf(":-\n");
969 				    }
970 				}
971 				m_flag = 0;
972 				if (reader = lookup_next_matching_elem(reader,
973 				    &m_flag, GROUPTAG, GROUPTAG)) {
974 				    if ((xmlTextReaderRead(reader) == 1) &&
975 					xmlTextReaderConstValue(reader)) {
976 				    (void) printf("\t\tPortal Group: %s\n",
977 					xmlTextReaderConstValue(reader));
978 				    } else {
979 					(void) printf(":-\n");
980 				    }
981 				}
982 			    }
983 			} /* Portal end */
984 			if ((ret = handle_association_info(name,
985 			    node_to_dd)) != 0) {
986 			    XML_SFREE(name);
987 			    goto out;
988 			}
989 		    } /* verbose end */
990 		    XML_SFREE(name);
991 		    (void) xmlTextReaderRead(reader);
992 		    m_flag = 0;
993 		} /* end for node while */
994 		break;
995 	    case DiscoveryDomain:
996 		/* process the DiscoveryDoamin elements */
997 		while (reader = lookup_next_matching_elem(reader, &m_flag,
998 		    DDOBJECT, ISNSRESPONSE)) {
999 		    if (m_flag == END_READER_MATCH) {
1000 			(void) xmlTextReaderNext(reader);
1001 			break;
1002 		    }
1003 
1004 		    if (((xmlTextReaderMoveToAttribute(reader,
1005 			(const xmlChar *)NAMEATTR)) == 1) &&
1006 			(name = xmlTextReaderValue(reader))) {
1007 			if (mbstowcs(wc_name, (const char *)name,
1008 			    ISNS_MAX_NAME_LEN) == (size_t)-1) {
1009 			    (void) wcscpy(wc_name, L"-");
1010 			}
1011 			(void) printf("DD name: %ws\n", wc_name);
1012 		    } else {
1013 			ret = ERROR_XML_NAME_ATTR_NOT_FOUND;
1014 			XML_SFREE(name);
1015 			goto out;
1016 		    }
1017 		    if ((ret = handle_association_info(name, dd_to_ddset)) !=
1018 			0) {
1019 			XML_SFREE(name);
1020 			goto out;
1021 		    }
1022 		    /* handle verbose */
1023 		    if ((flag & VERBOSE) == VERBOSE) {
1024 			if ((ret = handle_association_info(name,
1025 			    dd_to_node)) != 0) {
1026 			    XML_SFREE(name);
1027 			    goto out;
1028 			}
1029 		    }
1030 		    XML_SFREE(name);
1031 		    m_flag = 0;
1032 		}
1033 		break;
1034 	    case DiscoveryDomainSet:
1035 		/* process the DiscoveryDoaminSet elements */
1036 		while (reader = lookup_next_matching_elem(reader, &m_flag,
1037 		    DDSETOBJECT, ISNSRESPONSE)) {
1038 		    if (m_flag == END_READER_MATCH) {
1039 			(void) xmlTextReaderNext(reader);
1040 			break;
1041 		    }
1042 
1043 		    if (((xmlTextReaderMoveToAttribute(reader,
1044 			(const xmlChar *)NAMEATTR)) == 1) &&
1045 			(const char *)xmlTextReaderConstValue(reader)) {
1046 			if (mbstowcs(wc_name,
1047 			    (const char *)xmlTextReaderConstValue(reader),
1048 			    ISNS_MAX_NAME_LEN) == (size_t)-1) {
1049 			    (void) wcscpy(wc_name, L"-");
1050 			}
1051 			if ((flag & VERBOSE) == VERBOSE) {
1052 			    name = xmlTextReaderValue(reader);
1053 			    (void) printf("DD Set name: %ws\n", wc_name);
1054 			} else {
1055 			    (void) printf("DD Set name: %ws\n", wc_name);
1056 			}
1057 		    } else {
1058 			ret = ERROR_XML_NAME_ATTR_NOT_FOUND;
1059 			XML_SFREE(name);
1060 			goto out;
1061 		    }
1062 		    m_flag = 0;
1063 		    if ((reader = lookup_next_matching_elem(reader,
1064 			&m_flag, ENABLEDELEM, ISNSOBJECT))) {
1065 			if (m_flag == READER_MATCH) {
1066 			    /* move to entity id value. */
1067 			    if ((xmlTextReaderRead(reader) == 1) &&
1068 				(XMLNCMPVAL(reader, XMLTRUE) == 0)) {
1069 				(void) printf("\tState: Enabled\n");
1070 			    } else {
1071 				(void) printf("\tState: Disabled\n");
1072 			    }
1073 			} else if (m_flag == END_READER_MATCH) {
1074 			    (void) xmlTextReaderRead(reader);
1075 			}
1076 		    }
1077 
1078 		    /* handle verbose */
1079 		    if ((flag & VERBOSE) == VERBOSE) {
1080 			if ((ret = handle_association_info(name,
1081 			    ddset_to_dd)) != 0) {
1082 			    XML_SFREE(name);
1083 			    goto out;
1084 			}
1085 		    }
1086 		    XML_SFREE(name);
1087 		    m_flag = 0;
1088 		}
1089 		break;
1090 	    case ServerConfig:
1091 		/* process the DiscoveryDoaminSet elements */
1092 		m_flag = 0;
1093 		reader = lookup_next_matching_elem(reader, &m_flag,
1094 		    ISNSSERVER, ISNSRESPONSE);
1095 		if (m_flag == END_READER_MATCH) {
1096 		    ret = ERROR_XML_ISNSSERVER_ELEM_NOT_FOUND;
1097 		    goto out;
1098 		}
1099 		m_flag = 0;
1100 		if ((reader = lookup_next_matching_elem(reader,
1101 		    &m_flag, DATASTORELOCATION, ISNSRESPONSE))) {
1102 		    if (m_flag == READER_MATCH) {
1103 			(void) xmlTextReaderRead(reader);
1104 			(void) printf("\tData Store Location: %s\n",
1105 			(const char *)xmlTextReaderConstValue(reader) ?
1106 			(const char *)xmlTextReaderConstValue(reader) : "-");
1107 		    }
1108 		}
1109 		m_flag = 0;
1110 		if ((reader = lookup_next_matching_elem(reader,
1111 		    &m_flag, ESIRETRYTHRESHOLD, ISNSRESPONSE))) {
1112 		    if (m_flag == READER_MATCH) {
1113 			(void) xmlTextReaderRead(reader);
1114 			(void) printf("\tEntity Status Inquiry Non-Response ");
1115 			(void) printf("Threshold: %d\n",
1116 			xmlTextReaderConstValue(reader) ?
1117 			atoi((const char *)xmlTextReaderConstValue(reader))
1118 			: 0);
1119 		    }
1120 		}
1121 		m_flag = 0;
1122 		if ((reader = lookup_next_matching_elem(reader,
1123 		    &m_flag, MANAGEMENTSCNENABLED, ISNSRESPONSE))) {
1124 		    if (m_flag == READER_MATCH) {
1125 			(void) xmlTextReaderRead(reader);
1126 			(void) printf("\tManagement SCN Enabled: %s\n",
1127 			(XMLNCMPVAL(reader, XMLTRUE) == 0) ?
1128 			"yes" : "no");
1129 		    }
1130 		}
1131 		m_flag = 0;
1132 		while ((reader = lookup_next_matching_elem(reader,
1133 		    &m_flag, CONTROLNODENAME, ISNSSERVER))) {
1134 		    if (m_flag == READER_MATCH) {
1135 			if (!xmlTextReaderIsEmptyElement(reader)) {
1136 			    (void) xmlTextReaderRead(reader);
1137 			    if (mbstowcs(wc_name,
1138 				(const char *)xmlTextReaderConstValue(reader),
1139 				ISNS_MAX_NAME_LEN) == (size_t)-1) {
1140 				(void) wcscpy(wc_name, L"-");
1141 			    }
1142 			    if (tag_printed) {
1143 				if (xmlTextReaderConstValue(reader)) {
1144 				    if (mbstowcs(wc_name,
1145 					(const char *)
1146 					xmlTextReaderConstValue(reader),
1147 					ISNS_MAX_NAME_LEN) == (size_t)-1) {
1148 					(void) wcscpy(wc_name, L"-");
1149 				    }
1150 				    (void) printf(
1151 				    "\t                               %ws\n",
1152 					wc_name);
1153 				} else {
1154 				    (void) printf(
1155 				    "\t                               %s\n",
1156 				    "-");
1157 				}
1158 			    } else {
1159 				if (xmlTextReaderConstValue(reader)) {
1160 				    if (mbstowcs(wc_name,
1161 					(const char *)
1162 					xmlTextReaderConstValue(reader),
1163 					ISNS_MAX_NAME_LEN) == (size_t)-1) {
1164 					(void) wcscpy(wc_name, L"-");
1165 				    }
1166 				    (void) printf(
1167 				    "\tAuthorized Control Node Names: %ws\n",
1168 					wc_name);
1169 				} else {
1170 				    (void) printf(
1171 				    "\tAuthorized Control Node Names: %s\n",
1172 				    "-");
1173 				}
1174 				tag_printed = 1;
1175 			    }
1176 			} else {
1177 			    (void) printf(
1178 				"\tAuthorized Control Node Names: %s\n", "-");
1179 			    break;
1180 			}
1181 		    } else {
1182 			break;
1183 		    }
1184 		}
1185 		break;
1186 	    default:
1187 		ret = UNKNOWN;
1188 	}
1189 
1190 out:
1191 	(void) xmlTextReaderClose(reader);
1192 	(void) xmlFreeTextReader(reader);
1193 	if (status == PARTIAL_SUCCESS) {
1194 	    (void) fprintf(stderr, "%s\n",
1195 		getTextMessage(ERROR_PARTIAL_SUCCESS));
1196 	    if (ret == 0) ret = status;
1197 	}
1198 	return (ret);
1199 
1200 }
1201 
1202 /*
1203  * ****************************************************************************
1204  *
1205  * cvt_enumerate_rsp_to_get_req:
1206  *	pull out object info from enumerate response and calls
1207  *	build_get_xml_doc based on object type.
1208  *
1209  * doc		- enumerate resonse from the server.
1210  * req_do	- pointer to get request doc.
1211  * object_type	- isns object type.
1212  * flag		- user options
1213  *
1214  * ****************************************************************************
1215  */
1216 static int
1217 cvt_enumerate_rsp_to_get_req(xmlChar *doc, xmlChar **req_doc,
1218 	object_type obj, uint32_t flag)
1219 {
1220 	xmlTextReaderPtr reader;
1221 	xmlChar **argxmlv;
1222 	int ret = 0, status;
1223 	int i, argxmlc = 0, m_flag = 0;
1224 
1225 	if ((reader = (xmlTextReaderPtr)xmlReaderForMemory((const char *)doc,
1226 	    xmlStrlen(doc), NULL, NULL, 0)) == NULL) {
1227 	    return (ERROR_XML_READER_NULL);
1228 	}
1229 
1230 	/* if status is 0, continue on.  Otherwise return an error. */
1231 	if (reader = lookup_next_matching_elem(reader, &m_flag, STATUSELEMENT,
1232 	    RESULTELEMENT)) {
1233 	    if (m_flag == READER_MATCH) {
1234 		if (xmlTextReaderRead(reader) == 1) {
1235 		    status =
1236 		    atoi((const char *)xmlTextReaderConstValue(reader));
1237 		    if (status != 0) {
1238 			print_error_status(status, obj, reader);
1239 			(void) xmlTextReaderClose(reader);
1240 			(void) xmlFreeTextReader(reader);
1241 			return (status);
1242 		    }
1243 		} else {
1244 		    (void) xmlTextReaderClose(reader);
1245 		    xmlFreeTextReader(reader);
1246 		    return (ERROR_XML_STATUS_ELEM_NOT_FOUND);
1247 		}
1248 	    } else {
1249 		return (ERROR_XML_STATUS_ELEM_NOT_FOUND);
1250 	    }
1251 	} else {
1252 	    return (ERROR_XML_READER_NULL);
1253 	}
1254 
1255 	m_flag = 0;
1256 
1257 	argxmlv = (xmlChar **)malloc(sizeof (xmlChar *));
1258 
1259 	/* XXX - validate isnsResponse element from response doc. */
1260 	switch (obj) {
1261 	    case Node:
1262 		/* process the node elements */
1263 		while (reader = lookup_next_matching_elem(reader, &m_flag,
1264 		    NODEOBJECT, ISNSRESPONSE)) {
1265 		    if (m_flag == END_READER_MATCH) {
1266 			(void) xmlTextReaderNext(reader);
1267 			break;
1268 		    }
1269 
1270 		    /* check the type */
1271 		    if ((xmlTextReaderMoveToAttribute(reader,
1272 			(const xmlChar *)TYPEATTR)) == 1) {
1273 			if (((flag & TARGET_ONLY) == TARGET_ONLY) &&
1274 			    (XMLNCMPVAL(reader, TARGETTYPE) != 0)) {
1275 			    /* move to next node object. */
1276 			    (void) xmlTextReaderMoveToElement(reader);
1277 			    (void) xmlTextReaderNext(reader);
1278 			    continue;
1279 			}
1280 			if (((flag & INITIATOR_ONLY) == INITIATOR_ONLY) &&
1281 			    (XMLNCMPVAL(reader, INITIATORTYPE) != 0)) {
1282 			    /* move to next node object. */
1283 			    (void) xmlTextReaderMoveToElement(reader);
1284 			    (void) xmlTextReaderNext(reader);
1285 			    continue;
1286 			}
1287 		    } else {
1288 			ret = ERROR_XML_TYPE_ATTR_NOT_FOUND;
1289 			goto out;
1290 		    }
1291 
1292 		    if (((xmlTextReaderMoveToAttribute(reader,
1293 			(const xmlChar *)NAMEATTR)) == 1) &&
1294 			xmlTextReaderConstValue(reader)) {
1295 			argxmlv = NEW_XMLARGV(argxmlv, argxmlc);
1296 			if (argxmlv == (xmlChar **)NULL) {
1297 			    ret = ERROR_MALLOC_FAILED;
1298 			    goto out;
1299 			}
1300 			argxmlv[argxmlc++] =
1301 			    xmlStrdup(xmlTextReaderConstValue(reader));
1302 			argxmlv[argxmlc] = NULL;
1303 		    } else {
1304 			ret = ERROR_XML_NAME_ATTR_NOT_FOUND;
1305 			goto out;
1306 		    }
1307 		    (void) xmlTextReaderRead(reader);
1308 		    m_flag = 0;
1309 		} /* end for node while */
1310 		break;
1311 	    case DiscoveryDomain:
1312 		/* process the DiscoveryDoamin elements */
1313 		while (reader = lookup_next_matching_elem(reader, &m_flag,
1314 		    DDOBJECT, ISNSRESPONSE)) {
1315 		    if (m_flag == END_READER_MATCH) {
1316 			(void) xmlTextReaderNext(reader);
1317 			break;
1318 		    }
1319 
1320 		    if (((xmlTextReaderMoveToAttribute(reader,
1321 			(const xmlChar *)NAMEATTR)) == 1) &&
1322 			xmlTextReaderConstValue(reader)) {
1323 			argxmlv = NEW_XMLARGV(argxmlv, argxmlc);
1324 			if (argxmlv == (xmlChar **)NULL) {
1325 			    ret = ERROR_MALLOC_FAILED;
1326 			    goto out;
1327 			}
1328 			argxmlv[argxmlc++] =
1329 			    xmlStrdup(xmlTextReaderConstValue(reader));
1330 			argxmlv[argxmlc] = NULL;
1331 		    } else {
1332 			    ret = ERROR_XML_NAME_ATTR_NOT_FOUND;
1333 			    goto out;
1334 		    }
1335 		    m_flag = 0;
1336 		    (void) xmlTextReaderRead(reader);
1337 		}
1338 		break;
1339 	    case DiscoveryDomainSet:
1340 		/* process the DiscoveryDoaminSet elements */
1341 		while (reader = lookup_next_matching_elem(reader, &m_flag,
1342 		    DDSETOBJECT, ISNSRESPONSE)) {
1343 		    if (m_flag == END_READER_MATCH) {
1344 			(void) xmlTextReaderNext(reader);
1345 			break;
1346 		    }
1347 
1348 		    if (((xmlTextReaderMoveToAttribute(reader,
1349 			(const xmlChar *)NAMEATTR)) == 1) &&
1350 			(const char *)xmlTextReaderConstValue(reader)) {
1351 			argxmlv = NEW_XMLARGV(argxmlv, argxmlc);
1352 			if (argxmlv == (xmlChar **)NULL) {
1353 			    ret = ERROR_MALLOC_FAILED;
1354 			    goto out;
1355 			}
1356 			argxmlv[argxmlc++] =
1357 			    xmlStrdup(xmlTextReaderConstValue(reader));
1358 			argxmlv[argxmlc] = NULL;
1359 		    } else {
1360 			ret = ERROR_XML_NAME_ATTR_NOT_FOUND;
1361 			goto out;
1362 		    }
1363 		    m_flag = 0;
1364 		    (void) xmlTextReaderRead(reader);
1365 		}
1366 		break;
1367 	    default:
1368 		ret = UNKNOWN;
1369 		goto out;
1370 	}
1371 
1372 	/* if no object found, stop here.  The status can be still 0. */
1373 	if (argxmlc != 0) {
1374 	    if ((ret = build_get_xml_doc(argxmlc, (char **)argxmlv, obj,
1375 		req_doc)) != 0) {
1376 		return (ret);
1377 	    }
1378 	} else {
1379 	    if (ret == 0) {
1380 		/* indicate there is no error but not object is found. */
1381 		ret = SUCCESS_WITH_NO_OBJECT;
1382 	    }
1383 	}
1384 
1385 out:
1386 	(void) xmlTextReaderClose(reader);
1387 	(void) xmlFreeTextReader(reader);
1388 	if (argxmlc != 0) {
1389 	    for (i = 0; i < argxmlc; i++) {
1390 		xmlFree(argxmlv[i]);
1391 	    }
1392 	    (void) free(argxmlv);
1393 	}
1394 	return (ret);
1395 
1396 }
1397 
1398 /*
1399  * ****************************************************************************
1400  *
1401  * build_delete_xml_doc -
1402  *	build remove request doc based the name.
1403  *	the resulted doc is passed in the doc ptr.
1404  *
1405  * name		- object type
1406  * assoc	- association type
1407  * doc		- ptr to the resulted doc
1408  *
1409  * ****************************************************************************
1410  */
1411 static int
1412 build_delete_xml_doc(int operandLen, char **operand, object_type obj,
1413 	char *container, xmlChar **doc)
1414 {
1415 	xmlTextWriterPtr writer;
1416 	xmlBufferPtr xbuf;
1417 	int i, len;
1418 
1419 	if ((xbuf = xmlBufferCreate()) == NULL) {
1420 		return (ERROR_XML_CREATE_BUFFER_FAILED);
1421 	}
1422 
1423 	if ((writer = xmlNewTextWriterMemory(xbuf, 0)) == NULL) {
1424 		return (ERROR_XML_CREATE_WRITER_FAILED);
1425 	}
1426 
1427 	if (xmlTextWriterStartDocument(writer, "1.0", NULL, NULL) < 0) {
1428 		return (ERROR_XML_START_DOC_FAILED);
1429 	}
1430 
1431 	/* Start element "isnsRequest". */
1432 	if (xmlTextWriterStartElement(writer, (xmlChar *)ISNSREQUEST) < 0) {
1433 	    return (ERROR_XML_START_ELEMENT_FAILED);
1434 	}
1435 
1436 	if ((xmlTextWriterWriteAttribute(writer,
1437 	    (xmlChar *)XMLNSATTR, (xmlChar *)XMLNSATTRVAL)) < 0) {
1438 	    return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1439 	}
1440 
1441 	/* request delete operation to get the entire list of obejct. */
1442 	if (xmlTextWriterStartElement(writer, (xmlChar *)DELETE) < 0) {
1443 		return (ERROR_XML_START_ELEMENT_FAILED);
1444 	}
1445 
1446 	switch (obj) {
1447 	    case DiscoveryDomain:
1448 		for (i = 0; i < operandLen; i++) {
1449 		    /* start Discovery Domain element. */
1450 		    if (xmlTextWriterStartElement(writer,
1451 			(xmlChar *)DDOBJECT) < 0) {
1452 			return (ERROR_XML_START_ELEMENT_FAILED);
1453 		    }
1454 
1455 		    /* Start attr "name". */
1456 		    if ((xmlTextWriterWriteAttribute(writer,
1457 			(xmlChar *)NAMEATTR, (xmlChar *)operand[i])) < 0) {
1458 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1459 		    }
1460 
1461 		    /* End element "DiscoveryDomain". */
1462 		    if (xmlTextWriterEndElement(writer) < 0) {
1463 			return (ERROR_XML_END_ELEMENT_FAILED);
1464 		    }
1465 		}
1466 		break;
1467 	    case DiscoveryDomainSet:
1468 		for (i = 0; i < operandLen; i++) {
1469 		    /* start Discovery DomainSet element. */
1470 		    if (xmlTextWriterStartElement(writer,
1471 			(xmlChar *)DDSETOBJECT) < 0) {
1472 			return (ERROR_XML_START_ELEMENT_FAILED);
1473 		    }
1474 
1475 		    /* Start attr "name". */
1476 		    if (xmlTextWriterWriteAttribute(writer,
1477 			(xmlChar *)NAMEATTR, (xmlChar *)operand[i]) < 0) {
1478 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1479 		    }
1480 
1481 		    /* End element "DiscoveryDomainSet". */
1482 		    if (xmlTextWriterEndElement(writer) < 0) {
1483 			return (ERROR_XML_END_ELEMENT_FAILED);
1484 		    }
1485 		}
1486 		break;
1487 	    case DiscoveryDomainMember:
1488 		for (i = 0; i < operandLen; i++) {
1489 		    /* start Discovery Domain Member element. */
1490 		    if (xmlTextWriterStartElement(writer,
1491 			(xmlChar *)DDOBJECTMEMBER) < 0) {
1492 			return (ERROR_XML_START_ELEMENT_FAILED);
1493 		    }
1494 
1495 		    /* Start attr "DD Name". */
1496 		    if (xmlTextWriterWriteAttribute(writer,
1497 			(xmlChar *)DDNAMEATTR, (xmlChar *)container) < 0) {
1498 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1499 		    }
1500 
1501 		    /* Start attr "Node Name". */
1502 		    if (xmlTextWriterWriteAttribute(writer,
1503 			(xmlChar *)NODENAMEATTR, (xmlChar *)operand[i]) < 0) {
1504 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1505 		    }
1506 
1507 		    /* End element "DiscoveryDomainMember. */
1508 		    if (xmlTextWriterEndElement(writer) < 0) {
1509 			return (ERROR_XML_END_ELEMENT_FAILED);
1510 		    }
1511 		}
1512 		break;
1513 	    case DiscoveryDomainSetMember:
1514 		for (i = 0; i < operandLen; i++) {
1515 		    /* start Discovery Domain Member element. */
1516 		    if (xmlTextWriterStartElement(writer,
1517 			(xmlChar *)DDSETOBJECTMEMBER) < 0) {
1518 			return (ERROR_XML_START_ELEMENT_FAILED);
1519 		    }
1520 
1521 		    /* Start attr "DD Set Name". */
1522 		    if (xmlTextWriterWriteAttribute(writer,
1523 			(xmlChar *)DDSETNAMEATTR, (xmlChar *)(container)) < 0) {
1524 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1525 		    }
1526 
1527 		    /* Start attr "DD Name". */
1528 		    if (xmlTextWriterWriteAttribute(writer,
1529 			(xmlChar *)DDNAMEATTR, (xmlChar *)(operand[i])) < 0) {
1530 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1531 		    }
1532 
1533 		    /* End element "DiscoveryDomainSetMember. */
1534 		    if (xmlTextWriterEndElement(writer) < 0) {
1535 			return (ERROR_XML_END_ELEMENT_FAILED);
1536 		    }
1537 		}
1538 		break;
1539 	    default:
1540 		    xmlFreeTextWriter(writer);
1541 		    return (UNKNOWN);
1542 	}
1543 
1544 	/* end createModify */
1545 	if (xmlTextWriterEndElement(writer) < 0) {
1546 	    xmlFreeTextWriter(writer);
1547 	    return (ERROR_XML_END_ELEMENT_FAILED);
1548 	}
1549 
1550 	/* End element "isnsRequest". */
1551 	if (xmlTextWriterEndElement(writer) < 0) {
1552 	    xmlFreeTextWriter(writer);
1553 	    return (ERROR_XML_END_ELEMENT_FAILED);
1554 	}
1555 	if (xmlTextWriterEndDocument(writer) < 0) {
1556 	    xmlFreeTextWriter(writer);
1557 	    return (ERROR_XML_END_DOC_FAILED);
1558 	}
1559 
1560 	xmlFreeTextWriter(writer);
1561 
1562 	len = xmlStrlen(xbuf->content) + 1;
1563 	/* XXX - copy NULL at the end by having one more extra byte */
1564 	if ((*doc = xmlStrndup(xbuf->content, len)) == NULL) {
1565 	    return (ERROR_XML_STRDUP_FAILED);
1566 	}
1567 
1568 	xmlBufferFree(xbuf);
1569 
1570 	return (0);
1571 }
1572 
1573 /*
1574  * ****************************************************************************
1575  *
1576  * build_modify_xml_doc -
1577  *	build create request doc based the name.
1578  *	the resulted doc is passed in the doc ptr.
1579  *
1580  * operannLen	- number of objects
1581  * operand	- object list
1582  * enabled	- indication of enable and disable boolean type element.
1583  * doc		- ptr to the resulted doc
1584  *
1585  * ****************************************************************************
1586  */
1587 static int
1588 build_modify_xml_doc(int operandLen, char **operand, object_type obj,
1589 	boolean_t enabled, xmlChar **doc)
1590 {
1591 	xmlTextWriterPtr writer;
1592 	xmlBufferPtr xbuf;
1593 	int i, len;
1594 
1595 	if ((xbuf = xmlBufferCreate()) == NULL) {
1596 		return (ERROR_XML_CREATE_BUFFER_FAILED);
1597 	}
1598 
1599 	if ((writer = xmlNewTextWriterMemory(xbuf, 0)) == NULL) {
1600 		return (ERROR_XML_CREATE_WRITER_FAILED);
1601 	}
1602 
1603 	if (xmlTextWriterStartDocument(writer, "1.0", NULL, NULL) < 0) {
1604 		return (ERROR_XML_START_DOC_FAILED);
1605 	}
1606 
1607 	/* Start element "isnsRequest". */
1608 	if (xmlTextWriterStartElement(writer, (xmlChar *)ISNSREQUEST) < 0) {
1609 	    return (ERROR_XML_START_ELEMENT_FAILED);
1610 	}
1611 
1612 	if ((xmlTextWriterWriteAttribute(writer,
1613 	    (xmlChar *)XMLNSATTR, (xmlChar *)XMLNSATTRVAL)) < 0) {
1614 	    return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1615 	}
1616 
1617 	/* request createModify operation to get the entire list of obejct. */
1618 	if (xmlTextWriterStartElement(writer, (xmlChar *)CREATEMODIFY) < 0) {
1619 		return (ERROR_XML_START_ELEMENT_FAILED);
1620 	}
1621 
1622 	switch (obj) {
1623 	    case DiscoveryDomain:
1624 		for (i = 0; i < operandLen; i++) {
1625 		    /* start Discovery Domain element. */
1626 		    if (xmlTextWriterStartElement(writer,
1627 			(xmlChar *)DDOBJECT) < 0) {
1628 			return (ERROR_XML_START_ELEMENT_FAILED);
1629 		    }
1630 
1631 		    /* write attr "name". */
1632 		    if ((xmlTextWriterWriteAttribute(writer,
1633 			(xmlChar *)NAMEATTR, (xmlChar *)operand[i])) < 0) {
1634 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1635 		    }
1636 
1637 		    /* write bootlist_enabled elem */
1638 		    if (xmlTextWriterWriteElement(writer,
1639 			(xmlChar *)BOOTLISTENABLEDELEM, (enabled)?
1640 			(xmlChar *)XMLTRUE : (xmlChar *)XMLFALSE) < 0) {
1641 			return (ERROR_XML_WRITE_ELEMENT_FAILED);
1642 		    }
1643 
1644 		    /* End element "DiscoveryDomain". */
1645 		    if (xmlTextWriterEndElement(writer) < 0) {
1646 			return (ERROR_XML_END_ELEMENT_FAILED);
1647 		    }
1648 		}
1649 		break;
1650 	    case DiscoveryDomainSet:
1651 		for (i = 0; i < operandLen; i++) {
1652 		    /* start Discovery DomainSet element. */
1653 		    if (xmlTextWriterStartElement(writer,
1654 			(xmlChar *)DDSETOBJECT) < 0) {
1655 			return (ERROR_XML_START_ELEMENT_FAILED);
1656 		    }
1657 
1658 		    /* Start attr "name". */
1659 		    if (xmlTextWriterWriteAttribute(writer,
1660 			(xmlChar *)NAMEATTR, (xmlChar *)operand[i]) < 0) {
1661 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1662 		    }
1663 
1664 		    /* write enabled elem */
1665 		    if (xmlTextWriterWriteElement(writer,
1666 			(xmlChar *)ENABLEDELEM, (enabled) ?
1667 			(xmlChar *)XMLTRUE : (xmlChar *)XMLFALSE) < 0) {
1668 			return (ERROR_XML_WRITE_ELEMENT_FAILED);
1669 		    }
1670 
1671 		    /* End element "DiscoveryDomainSet". */
1672 		    if (xmlTextWriterEndElement(writer) < 0) {
1673 			return (ERROR_XML_END_ELEMENT_FAILED);
1674 		    }
1675 		}
1676 		break;
1677 	    default:
1678 		    xmlFreeTextWriter(writer);
1679 		    return (UNKNOWN);
1680 	}
1681 
1682 	/* end createModify */
1683 	if (xmlTextWriterEndElement(writer) < 0) {
1684 	    xmlFreeTextWriter(writer);
1685 	    return (ERROR_XML_END_ELEMENT_FAILED);
1686 	}
1687 
1688 	/* End element "isnsRequest". */
1689 	if (xmlTextWriterEndElement(writer) < 0) {
1690 	    xmlFreeTextWriter(writer);
1691 	    return (ERROR_XML_END_ELEMENT_FAILED);
1692 	}
1693 	if (xmlTextWriterEndDocument(writer) < 0) {
1694 	    xmlFreeTextWriter(writer);
1695 	    return (ERROR_XML_END_DOC_FAILED);
1696 	}
1697 
1698 	xmlFreeTextWriter(writer);
1699 
1700 	len = xmlStrlen(xbuf->content) + 1;
1701 	/* XXX - copy NULL at the end by having one more extra byte */
1702 	if ((*doc = xmlStrndup(xbuf->content, len)) == NULL) {
1703 	    return (ERROR_XML_STRDUP_FAILED);
1704 	}
1705 
1706 	xmlBufferFree(xbuf);
1707 
1708 	return (0);
1709 }
1710 
1711 /*
1712  * ****************************************************************************
1713  *
1714  * build_rename_xml_doc -
1715  *	build create request doc based the name.
1716  *	the resulted doc is passed in the doc ptr.
1717  *
1718  * assoc	- a new name
1719  * id		- index of the object of which name  to be changed
1720  * doc		- ptr to the resulted doc
1721  *
1722  * ****************************************************************************
1723  */
1724 static int
1725 build_rename_xml_doc(char *name, object_type obj, uint32_t id, xmlChar **doc)
1726 {
1727 	xmlTextWriterPtr writer;
1728 	xmlBufferPtr xbuf;
1729 	int len;
1730 	char namebuf[32];
1731 
1732 	if ((xbuf = xmlBufferCreate()) == NULL) {
1733 		return (ERROR_XML_CREATE_BUFFER_FAILED);
1734 	}
1735 
1736 	if ((writer = xmlNewTextWriterMemory(xbuf, 0)) == NULL) {
1737 		return (ERROR_XML_CREATE_WRITER_FAILED);
1738 	}
1739 
1740 	if (xmlTextWriterStartDocument(writer, "1.0", NULL, NULL) < 0) {
1741 		return (ERROR_XML_START_DOC_FAILED);
1742 	}
1743 
1744 	/* Start element "isnsRequest". */
1745 	if (xmlTextWriterStartElement(writer, (xmlChar *)ISNSREQUEST) < 0) {
1746 	    return (ERROR_XML_START_ELEMENT_FAILED);
1747 	}
1748 
1749 	if ((xmlTextWriterWriteAttribute(writer,
1750 	    (xmlChar *)XMLNSATTR, (xmlChar *)XMLNSATTRVAL)) < 0) {
1751 	    return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1752 	}
1753 
1754 	/* request createModify operation to get the entire list of obejct. */
1755 	if (xmlTextWriterStartElement(writer, (xmlChar *)CREATEMODIFY) < 0) {
1756 		return (ERROR_XML_START_ELEMENT_FAILED);
1757 	}
1758 
1759 	switch (obj) {
1760 	    case DiscoveryDomain:
1761 		    /* start Discovery Domain element. */
1762 		    if (xmlTextWriterStartElement(writer,
1763 			(xmlChar *)DDOBJECT) < 0) {
1764 			return (ERROR_XML_START_ELEMENT_FAILED);
1765 		    }
1766 
1767 		    /* write attr "name". */
1768 		    if ((xmlTextWriterWriteAttribute(writer,
1769 			(xmlChar *)NAMEATTR, (xmlChar *)name)) < 0) {
1770 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1771 		    }
1772 
1773 		    /* write attr "id". */
1774 		    (void) sprintf(namebuf, "%d", id);
1775 		    if ((xmlTextWriterWriteAttribute(writer,
1776 			(xmlChar *)IDATTR, (xmlChar *)namebuf)) < 0) {
1777 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1778 		    }
1779 
1780 		    /* End element "DiscoveryDomain". */
1781 		    if (xmlTextWriterEndElement(writer) < 0) {
1782 			return (ERROR_XML_END_ELEMENT_FAILED);
1783 		    }
1784 		break;
1785 	    case DiscoveryDomainSet:
1786 		    /* start Discovery DomainSet element. */
1787 		    if (xmlTextWriterStartElement(writer,
1788 			(xmlChar *)DDSETOBJECT) < 0) {
1789 			return (ERROR_XML_START_ELEMENT_FAILED);
1790 		    }
1791 
1792 		    /* Start attr "name". */
1793 		    if (xmlTextWriterWriteAttribute(writer,
1794 			(xmlChar *)NAMEATTR, (xmlChar *)name) < 0) {
1795 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1796 		    }
1797 
1798 		    /* write attr "id". */
1799 		    (void) sprintf(namebuf, "%d", id);
1800 		    if ((xmlTextWriterWriteAttribute(writer,
1801 			(xmlChar *)IDATTR, (xmlChar *)namebuf)) < 0) {
1802 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1803 		    }
1804 
1805 		    /* End element "DiscoveryDomainSet". */
1806 		    if (xmlTextWriterEndElement(writer) < 0) {
1807 			return (ERROR_XML_END_ELEMENT_FAILED);
1808 		    }
1809 		break;
1810 	    default:
1811 		    xmlFreeTextWriter(writer);
1812 		    return (UNKNOWN);
1813 	}
1814 
1815 	/* end createModify */
1816 	if (xmlTextWriterEndElement(writer) < 0) {
1817 	    xmlFreeTextWriter(writer);
1818 	    return (ERROR_XML_END_ELEMENT_FAILED);
1819 	}
1820 
1821 	/* End element "isnsRequest". */
1822 	if (xmlTextWriterEndElement(writer) < 0) {
1823 	    xmlFreeTextWriter(writer);
1824 	    return (ERROR_XML_END_ELEMENT_FAILED);
1825 	}
1826 	if (xmlTextWriterEndDocument(writer) < 0) {
1827 	    xmlFreeTextWriter(writer);
1828 	    return (ERROR_XML_END_DOC_FAILED);
1829 	}
1830 
1831 	xmlFreeTextWriter(writer);
1832 
1833 	len = xmlStrlen(xbuf->content) + 1;
1834 	/* XXX - copy NULL at the end by having one more extra byte */
1835 	if ((*doc = xmlStrndup(xbuf->content, len)) == NULL) {
1836 	    return (ERROR_XML_STRDUP_FAILED);
1837 	}
1838 
1839 	xmlBufferFree(xbuf);
1840 
1841 	return (0);
1842 }
1843 
1844 /*
1845  * ****************************************************************************
1846  *
1847  * build_create_xml_doc -
1848  *	build create request doc based the name.
1849  *	the resulted doc is passed in the doc ptr.
1850  *
1851  * name		- object type
1852  * assoc	- association type
1853  * doc		- ptr to the resulted doc
1854  *
1855  * ****************************************************************************
1856  */
1857 static int
1858 build_create_xml_doc(int operandLen, char **operand, object_type obj,
1859 	char *container, xmlChar **doc)
1860 {
1861 	xmlTextWriterPtr writer;
1862 	xmlBufferPtr xbuf;
1863 	int i, len;
1864 
1865 	if ((xbuf = xmlBufferCreate()) == NULL) {
1866 		return (ERROR_XML_CREATE_BUFFER_FAILED);
1867 	}
1868 
1869 	if ((writer = xmlNewTextWriterMemory(xbuf, 0)) == NULL) {
1870 		return (ERROR_XML_CREATE_WRITER_FAILED);
1871 	}
1872 
1873 	if (xmlTextWriterStartDocument(writer, "1.0", NULL, NULL) < 0) {
1874 		return (ERROR_XML_START_DOC_FAILED);
1875 	}
1876 
1877 	/* Start element "isnsRequest". */
1878 	if (xmlTextWriterStartElement(writer, (xmlChar *)ISNSREQUEST) < 0) {
1879 	    return (ERROR_XML_START_ELEMENT_FAILED);
1880 	}
1881 
1882 	/* request createModify operation to get the entire list of obejct. */
1883 	if (xmlTextWriterStartElement(writer, (xmlChar *)CREATEMODIFY) < 0) {
1884 		return (ERROR_XML_START_ELEMENT_FAILED);
1885 	}
1886 
1887 	switch (obj) {
1888 	    case DiscoveryDomain:
1889 		for (i = 0; i < operandLen; i++) {
1890 		    /* start Discovery Domain element. */
1891 		    if (xmlTextWriterStartElement(writer,
1892 			(xmlChar *)DDOBJECT) < 0) {
1893 			return (ERROR_XML_START_ELEMENT_FAILED);
1894 		    }
1895 
1896 		    /* Start attr "name". */
1897 		    if ((xmlTextWriterWriteAttribute(writer,
1898 			(xmlChar *)NAMEATTR, (xmlChar *)operand[i])) < 0) {
1899 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1900 		    }
1901 
1902 		    /* End element "DiscoveryDomain". */
1903 		    if (xmlTextWriterEndElement(writer) < 0) {
1904 			return (ERROR_XML_END_ELEMENT_FAILED);
1905 		    }
1906 		}
1907 		break;
1908 	    case DiscoveryDomainSet:
1909 		for (i = 0; i < operandLen; i++) {
1910 		    /* start Discovery DomainSet element. */
1911 		    if (xmlTextWriterStartElement(writer,
1912 			(xmlChar *)DDSETOBJECT) < 0) {
1913 			return (ERROR_XML_START_ELEMENT_FAILED);
1914 		    }
1915 
1916 		    /* Start attr "name". */
1917 		    if (xmlTextWriterWriteAttribute(writer,
1918 			(xmlChar *)NAMEATTR, (xmlChar *)operand[i]) < 0) {
1919 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1920 		    }
1921 
1922 		    /* End element "DiscoveryDomainSet". */
1923 		    if (xmlTextWriterEndElement(writer) < 0) {
1924 			return (ERROR_XML_END_ELEMENT_FAILED);
1925 		    }
1926 		}
1927 		break;
1928 	    case DiscoveryDomainMember:
1929 		for (i = 0; i < operandLen; i++) {
1930 		    /* start Discovery Domain Member element. */
1931 		    if (xmlTextWriterStartElement(writer,
1932 			(xmlChar *)DDOBJECTMEMBER) < 0) {
1933 			return (ERROR_XML_START_ELEMENT_FAILED);
1934 		    }
1935 
1936 		    /* Start attr "DD Name". */
1937 		    if (xmlTextWriterWriteAttribute(writer,
1938 			(xmlChar *)DDNAMEATTR, (xmlChar *)container) < 0) {
1939 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1940 		    }
1941 
1942 		    /* Start attr "Node Name". */
1943 		    if (xmlTextWriterWriteAttribute(writer,
1944 			(xmlChar *)NODENAMEATTR, (xmlChar *)operand[i]) < 0) {
1945 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1946 		    }
1947 
1948 		    /* End element "DiscoveryDomainMember. */
1949 		    if (xmlTextWriterEndElement(writer) < 0) {
1950 			return (ERROR_XML_END_ELEMENT_FAILED);
1951 		    }
1952 		}
1953 		break;
1954 	    case DiscoveryDomainSetMember:
1955 		for (i = 0; i < operandLen; i++) {
1956 		    /* start Discovery Domain Member element. */
1957 		    if (xmlTextWriterStartElement(writer,
1958 			(xmlChar *)DDSETOBJECTMEMBER) < 0) {
1959 			return (ERROR_XML_START_ELEMENT_FAILED);
1960 		    }
1961 
1962 		    /* Start attr "DD Set Name". */
1963 		    if (xmlTextWriterWriteAttribute(writer,
1964 			(xmlChar *)DDSETNAMEATTR, (xmlChar *)(container)) < 0) {
1965 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1966 		    }
1967 
1968 		    /* Start attr "DD Name". */
1969 		    if (xmlTextWriterWriteAttribute(writer,
1970 			(xmlChar *)DDNAMEATTR, (xmlChar *)(operand[i])) < 0) {
1971 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
1972 		    }
1973 
1974 		    /* End element "DiscoveryDomainSetMember. */
1975 		    if (xmlTextWriterEndElement(writer) < 0) {
1976 			return (ERROR_XML_END_ELEMENT_FAILED);
1977 		    }
1978 		}
1979 		break;
1980 	    default:
1981 		    xmlFreeTextWriter(writer);
1982 		    return (UNKNOWN);
1983 	}
1984 
1985 	/* end createModify */
1986 	if (xmlTextWriterEndElement(writer) < 0) {
1987 	    xmlFreeTextWriter(writer);
1988 	    return (ERROR_XML_END_ELEMENT_FAILED);
1989 	}
1990 
1991 	/* End element "isnsRequest". */
1992 	if (xmlTextWriterEndElement(writer) < 0) {
1993 	    xmlFreeTextWriter(writer);
1994 	    return (ERROR_XML_END_ELEMENT_FAILED);
1995 	}
1996 	if (xmlTextWriterEndDocument(writer) < 0) {
1997 	    xmlFreeTextWriter(writer);
1998 	    return (ERROR_XML_END_DOC_FAILED);
1999 	}
2000 
2001 	xmlFreeTextWriter(writer);
2002 
2003 	len = xmlStrlen(xbuf->content) + 1;
2004 	/* XXX - copy NULL at the end by having one more extra byte */
2005 	if ((*doc = xmlStrndup(xbuf->content, len)) == NULL) {
2006 	    return (ERROR_XML_STRDUP_FAILED);
2007 	}
2008 
2009 	xmlBufferFree(xbuf);
2010 
2011 	return (0);
2012 }
2013 
2014 /*
2015  * ****************************************************************************
2016  *
2017  * build_assoc_xml_doc -
2018  *	build association request doc based the name.
2019  *	the resulted doc is passed in the doc ptr.
2020  *
2021  * name		- object type
2022  * assoc	- association type
2023  * doc		- ptr to the resulted doc
2024  *
2025  * ****************************************************************************
2026  */
2027 static int
2028 build_assoc_xml_doc(xmlChar *name, association_t assoc, xmlChar **doc)
2029 {
2030 	xmlTextWriterPtr writer;
2031 	xmlBufferPtr xbuf;
2032 	int len;
2033 
2034 	if ((xbuf = xmlBufferCreate()) == NULL) {
2035 		return (ERROR_XML_CREATE_BUFFER_FAILED);
2036 	}
2037 
2038 	if ((writer = xmlNewTextWriterMemory(xbuf, 0)) == NULL) {
2039 		return (ERROR_XML_CREATE_WRITER_FAILED);
2040 	}
2041 
2042 	if (xmlTextWriterStartDocument(writer, "1.0", NULL, NULL) < 0) {
2043 		return (ERROR_XML_START_DOC_FAILED);
2044 	}
2045 
2046 	/* Start element "isnsRequest". */
2047 	if (xmlTextWriterStartElement(writer, (xmlChar *)ISNSREQUEST) < 0) {
2048 	    return (ERROR_XML_START_ELEMENT_FAILED);
2049 	}
2050 
2051 	/* request getAssociated operation to get the entire list of obejct. */
2052 	if (xmlTextWriterStartElement(writer, (xmlChar *)GETASSOCIATED) < 0) {
2053 		return (ERROR_XML_START_ELEMENT_FAILED);
2054 	}
2055 
2056 	switch (assoc) {
2057 	    case (node_to_dd):
2058 		/* write association type. */
2059 		if (xmlTextWriterWriteElement(writer,
2060 		    (xmlChar *)ASSOCIATIONTYPE,
2061 		    (xmlChar *)DDOBJECTMEMBER) < 0) {
2062 		    return (ERROR_XML_WRITE_ELEMENT_FAILED);
2063 		}
2064 
2065 		if (xmlTextWriterStartElement(writer,
2066 		    (xmlChar *)ISNSOBJECT) < 0) {
2067 		    return (ERROR_XML_START_ELEMENT_FAILED);
2068 		}
2069 
2070 		if (xmlTextWriterStartElement(writer,
2071 		    (xmlChar *)NODEOBJECT) < 0) {
2072 		    return (ERROR_XML_START_ELEMENT_FAILED);
2073 		}
2074 
2075 		/* Start attr "name". */
2076 		if (xmlTextWriterWriteAttribute(writer,
2077 		    (xmlChar *)NAMEATTR, name) < 0) {
2078 		    return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
2079 		}
2080 		if (xmlTextWriterWriteAttribute(writer,
2081 		    (xmlChar *)TYPEATTR, (xmlChar *)EMPTYSTR) < 0) {
2082 		    return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
2083 		}
2084 		if (xmlTextWriterWriteAttribute(writer,
2085 		    (xmlChar *)ALIASATTR, (xmlChar *)EMPTYSTR) < 0) {
2086 		    return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
2087 		}
2088 
2089 		/* End element "Node". */
2090 		if (xmlTextWriterEndElement(writer) < 0) {
2091 		    return (ERROR_XML_END_ELEMENT_FAILED);
2092 		}
2093 
2094 		/* End element "isnsObject". */
2095 		if (xmlTextWriterEndElement(writer) < 0) {
2096 		    return (ERROR_XML_END_ELEMENT_FAILED);
2097 		}
2098 		break;
2099 	    case (dd_to_node):
2100 		/* write association type. */
2101 		if (xmlTextWriterWriteElement(writer,
2102 		    (xmlChar *)ASSOCIATIONTYPE,
2103 		    (xmlChar *)DDOBJECTMEMBER) < 0) {
2104 		    return (ERROR_XML_WRITE_ELEMENT_FAILED);
2105 		}
2106 
2107 		/* start isnsObject */
2108 		if (xmlTextWriterStartElement(writer,
2109 		    (xmlChar *)ISNSOBJECT) < 0) {
2110 		    return (ERROR_XML_START_ELEMENT_FAILED);
2111 		}
2112 
2113 		/* start DiscoveryDomain */
2114 		if (xmlTextWriterStartElement(writer,
2115 		    (xmlChar *)DDOBJECT) < 0) {
2116 		    return (ERROR_XML_START_ELEMENT_FAILED);
2117 		}
2118 
2119 		/* Start attr "name". */
2120 		if (xmlTextWriterWriteAttribute(writer,
2121 		    (xmlChar *)NAMEATTR, name) < 0) {
2122 		    return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
2123 		}
2124 
2125 		/* End element "DiscoveryDomain". */
2126 		if (xmlTextWriterEndElement(writer) < 0) {
2127 		    return (ERROR_XML_END_ELEMENT_FAILED);
2128 		}
2129 
2130 		/* End element "isnsObject". */
2131 		if (xmlTextWriterEndElement(writer) < 0) {
2132 		    return (ERROR_XML_END_ELEMENT_FAILED);
2133 		}
2134 		break;
2135 	    case (ddset_to_dd):
2136 		/* write association type. */
2137 		if (xmlTextWriterWriteElement(writer,
2138 		    (xmlChar *)ASSOCIATIONTYPE,
2139 		    (xmlChar *)DDSETOBJECTMEMBER) < 0) {
2140 		    return (ERROR_XML_WRITE_ELEMENT_FAILED);
2141 		}
2142 
2143 		/* start isnsObject */
2144 		if (xmlTextWriterStartElement(writer,
2145 		    (xmlChar *)ISNSOBJECT) < 0) {
2146 		    return (ERROR_XML_START_ELEMENT_FAILED);
2147 		}
2148 
2149 		/* start DiscoveryDomainSet */
2150 		if (xmlTextWriterStartElement(writer,
2151 		    (xmlChar *)DDSETOBJECT) < 0) {
2152 		    return (ERROR_XML_START_ELEMENT_FAILED);
2153 		}
2154 
2155 		/* Start attr "name". */
2156 		if (xmlTextWriterWriteAttribute(writer,
2157 		    (xmlChar *)NAMEATTR, name) < 0) {
2158 		    return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
2159 		}
2160 
2161 		/* End element "DiscoveryDomain". */
2162 		if (xmlTextWriterEndElement(writer) < 0) {
2163 		    return (ERROR_XML_END_ELEMENT_FAILED);
2164 		}
2165 
2166 		/* End element "isnsObject". */
2167 		if (xmlTextWriterEndElement(writer) < 0) {
2168 		    return (ERROR_XML_END_ELEMENT_FAILED);
2169 		}
2170 		break;
2171 	    case (dd_to_ddset):
2172 		/* write association type. */
2173 		if (xmlTextWriterWriteElement(writer,
2174 		    (xmlChar *)ASSOCIATIONTYPE,
2175 		    (xmlChar *)DDSETOBJECTMEMBER) < 0) {
2176 		    return (ERROR_XML_WRITE_ELEMENT_FAILED);
2177 		}
2178 
2179 		/* start isnsObject */
2180 		if (xmlTextWriterStartElement(writer,
2181 		    (xmlChar *)ISNSOBJECT) < 0) {
2182 		    return (ERROR_XML_START_ELEMENT_FAILED);
2183 		}
2184 
2185 		/* start DiscoveryDomain */
2186 		if (xmlTextWriterStartElement(writer,
2187 		    (xmlChar *)DDOBJECT) < 0) {
2188 		    return (ERROR_XML_START_ELEMENT_FAILED);
2189 		}
2190 
2191 		/* Start attr "name". */
2192 		if (xmlTextWriterWriteAttribute(writer,
2193 		    (xmlChar *)NAMEATTR, name) < 0) {
2194 		    return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
2195 		}
2196 
2197 		/* End element "DiscoveryDomain". */
2198 		if (xmlTextWriterEndElement(writer) < 0) {
2199 		    return (ERROR_XML_END_ELEMENT_FAILED);
2200 		}
2201 
2202 		/* End element "isnsObject". */
2203 		if (xmlTextWriterEndElement(writer) < 0) {
2204 		    return (ERROR_XML_END_ELEMENT_FAILED);
2205 		}
2206 		break;
2207 	    default:
2208 		return (UNKNOWN);
2209 	}
2210 
2211 	/* end getAssociated */
2212 	if (xmlTextWriterEndElement(writer) < 0) {
2213 		return (ERROR_XML_END_ELEMENT_FAILED);
2214 	}
2215 
2216 	/* End element "isnsRequest". */
2217 	if (xmlTextWriterEndElement(writer) < 0) {
2218 	    return (ERROR_XML_END_ELEMENT_FAILED);
2219 	}
2220 	if (xmlTextWriterEndDocument(writer) < 0) {
2221 	    return (ERROR_XML_END_DOC_FAILED);
2222 	}
2223 
2224 	xmlFreeTextWriter(writer);
2225 
2226 	len = xmlStrlen(xbuf->content) + 1;
2227 	/* XXX - copy NULL at the end by having one more extra byte */
2228 	if ((*doc = xmlStrndup(xbuf->content, len)) == NULL) {
2229 	    return (ERROR_XML_STRDUP_FAILED);
2230 	}
2231 
2232 	xmlBufferFree(xbuf);
2233 	return (0);
2234 }
2235 
2236 /*
2237  * ****************************************************************************
2238  *
2239  * build_enumerate_xml_doc -
2240  *	build association request doc based the name.
2241  *	the resulted doc is passed in the doc ptr.
2242  *
2243  * name		- object type
2244  * doc		- ptr to the resulted doc
2245  *
2246  * ****************************************************************************
2247  */
2248 static int
2249 build_enumerate_xml_doc(object_type obj, xmlChar **doc)
2250 {
2251 	xmlTextWriterPtr writer;
2252 	xmlBufferPtr xbuf;
2253 	int len;
2254 
2255 	if ((xbuf = xmlBufferCreate()) == NULL) {
2256 		return (ERROR_XML_CREATE_BUFFER_FAILED);
2257 	}
2258 
2259 	if ((writer = xmlNewTextWriterMemory(xbuf, 0)) == NULL) {
2260 		return (ERROR_XML_CREATE_WRITER_FAILED);
2261 	}
2262 
2263 	if (xmlTextWriterStartDocument(writer, "1.0", NULL, NULL) < 0) {
2264 		return (ERROR_XML_START_DOC_FAILED);
2265 	}
2266 
2267 	/* Start element "isnsRequest". */
2268 	if (xmlTextWriterStartElement(writer, (xmlChar *)ISNSREQUEST) < 0) {
2269 	    return (ERROR_XML_START_ELEMENT_FAILED);
2270 	}
2271 
2272 	/* Start attr "xmlns". */
2273 	if (xmlTextWriterWriteAttribute(writer,
2274 	    (xmlChar *)"xmlns",
2275 	    (xmlChar *)"http://www.sun.com/schema/isnsmanagement")) {
2276 	    return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
2277 	}
2278 
2279 	/* request enumerate operation to get the entire list of obejct. */
2280 	if (xmlTextWriterStartElement(writer, (xmlChar *)ENUMERATE) < 0) {
2281 	    return (ERROR_XML_START_ELEMENT_FAILED);
2282 	}
2283 
2284 	switch (obj) {
2285 	    case (Node):
2286 		if (xmlTextWriterWriteElement(writer,
2287 		    (xmlChar *)ISNSOBJECTTYPE, (xmlChar *)NODEOBJECT) < 0) {
2288 		    return (ERROR_XML_WRITE_ELEMENT_FAILED);
2289 		}
2290 		break;
2291 	    case (DiscoveryDomain):
2292 		if (xmlTextWriterWriteElement(writer,
2293 		    (xmlChar *)ISNSOBJECTTYPE,
2294 		    (xmlChar *)DDOBJECT) < 0) {
2295 		    return (ERROR_XML_WRITE_ELEMENT_FAILED);
2296 		}
2297 		break;
2298 	    case (DiscoveryDomainSet):
2299 		if (xmlTextWriterWriteElement(writer,
2300 		    (xmlChar *)ISNSOBJECTTYPE,
2301 		    (xmlChar *)DDSETOBJECT) < 0) {
2302 		    return (ERROR_XML_WRITE_ELEMENT_FAILED);
2303 		}
2304 		break;
2305 	    default:
2306 		return (UNKNOWN);
2307 	}
2308 
2309 	/* end isns object type */
2310 	if (xmlTextWriterEndElement(writer) < 0) {
2311 	    return (ERROR_XML_END_ELEMENT_FAILED);
2312 	}
2313 
2314 	/* End element "isnsRequest". */
2315 	if (xmlTextWriterEndElement(writer) < 0) {
2316 	    return (ERROR_XML_END_ELEMENT_FAILED);
2317 	}
2318 	if (xmlTextWriterEndDocument(writer) < 0) {
2319 	    return (ERROR_XML_END_DOC_FAILED);
2320 	}
2321 
2322 	xmlFreeTextWriter(writer);
2323 
2324 	len = xmlStrlen(xbuf->content) + 1;
2325 	/* XXX - copy NULL at the end by having one more extra byte */
2326 	if ((*doc = xmlStrndup(xbuf->content, len)) == NULL) {
2327 	    return (ERROR_XML_STRDUP_FAILED);
2328 	}
2329 
2330 	xmlBufferFree(xbuf);
2331 	return (0);
2332 }
2333 
2334 /*
2335  * ****************************************************************************
2336  *
2337  * build_get_xml_doc -
2338  *	build association request doc based the name.
2339  *	the resulted doc is passed in the doc ptr.
2340  *
2341  * name		- object type
2342  * assoc	- association type
2343  * doc		- ptr to the resulted doc
2344  *
2345  * ****************************************************************************
2346  */
2347 static int
2348 build_get_xml_doc(int operandLen, char **operand, object_type obj,
2349 	xmlChar **doc)
2350 {
2351 	xmlTextWriterPtr writer;
2352 	xmlBufferPtr xbuf;
2353 	int i, len;
2354 
2355 	if ((xbuf = xmlBufferCreate()) == NULL) {
2356 		return (ERROR_XML_CREATE_BUFFER_FAILED);
2357 	}
2358 
2359 	if ((writer = xmlNewTextWriterMemory(xbuf, 0)) == NULL) {
2360 		return (ERROR_XML_CREATE_WRITER_FAILED);
2361 	}
2362 
2363 	if (xmlTextWriterStartDocument(writer, "1.0", NULL, NULL) < 0) {
2364 		return (ERROR_XML_START_DOC_FAILED);
2365 	}
2366 
2367 	/* Start element "isnsRequest". */
2368 	if (xmlTextWriterStartElement(writer, (xmlChar *)ISNSREQUEST) < 0) {
2369 	    return (ERROR_XML_START_ELEMENT_FAILED);
2370 	}
2371 
2372 	/* Start attr "xmlns". */
2373 	if (xmlTextWriterWriteAttribute(writer,
2374 	    (xmlChar *)"xmlns",
2375 	    (xmlChar *)"http://www.sun.com/schema/isnsmanagement")) {
2376 	    return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
2377 	}
2378 
2379 	/* Start element "get". */
2380 	if (xmlTextWriterStartElement(writer, (xmlChar *)GET) < 0) {
2381 	    return (ERROR_XML_START_ELEMENT_FAILED);
2382 	}
2383 
2384 	switch (obj) {
2385 	    case (Node):
2386 		for (i = 0; i < operandLen; i++) {
2387 		    /* Start element "isnsObject". */
2388 		    if (xmlTextWriterStartElement(writer,
2389 			(xmlChar *)ISNSOBJECT) < 0) {
2390 			return (ERROR_XML_START_ELEMENT_FAILED);
2391 		    }
2392 
2393 		    /* Start element Node. */
2394 		    if (xmlTextWriterStartElement(writer,
2395 			(xmlChar *)NODEOBJECT) < 0) {
2396 			return (ERROR_XML_START_ELEMENT_FAILED);
2397 		    }
2398 
2399 		    /* Start attr "name". */
2400 		    if (xmlTextWriterWriteAttribute(writer,
2401 			(xmlChar *)NAMEATTR, (xmlChar *)operand[i]) < 0) {
2402 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
2403 		    }
2404 		    if (xmlTextWriterWriteAttribute(writer,
2405 			(xmlChar *)TYPEATTR, (xmlChar *)EMPTYSTR) < 0) {
2406 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
2407 		    }
2408 		    if (xmlTextWriterWriteAttribute(writer,
2409 			(xmlChar *)ALIASATTR, (xmlChar *)EMPTYSTR) < 0) {
2410 			return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
2411 		    }
2412 
2413 		    /* End element "Node". */
2414 		    if (xmlTextWriterEndElement(writer) < 0) {
2415 			return (ERROR_XML_END_ELEMENT_FAILED);
2416 		    }
2417 
2418 		    /* End element "isnsObject". */
2419 		    if (xmlTextWriterEndElement(writer) < 0) {
2420 			return (ERROR_XML_END_ELEMENT_FAILED);
2421 		    }
2422 		}
2423 		break;
2424 	    case (DiscoveryDomain):
2425 		    for (i = 0; i < operandLen; i++) {
2426 			/* Start element "isnsObject". */
2427 			if (xmlTextWriterStartElement(writer,
2428 			    (xmlChar *)ISNSOBJECT) < 0) {
2429 			    return (ERROR_XML_START_ELEMENT_FAILED);
2430 			}
2431 
2432 			if (xmlTextWriterStartElement(writer,
2433 			    (xmlChar *)DDOBJECT) < 0) {
2434 			    return (ERROR_XML_START_ELEMENT_FAILED);
2435 			}
2436 
2437 			/* Start attr "name". */
2438 			if (xmlTextWriterWriteAttribute(writer,
2439 			    (xmlChar *)NAMEATTR, (xmlChar *)operand[i]) < 0) {
2440 			    return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
2441 			}
2442 
2443 			/* End element "DiscoveryDomain". */
2444 			if (xmlTextWriterEndElement(writer) < 0) {
2445 			    return (ERROR_XML_END_ELEMENT_FAILED);
2446 			}
2447 
2448 			/* End element "isnsObject". */
2449 			if (xmlTextWriterEndElement(writer) < 0) {
2450 			    return (ERROR_XML_END_ELEMENT_FAILED);
2451 			}
2452 		    }
2453 		    break;
2454 	    case (DiscoveryDomainSet):
2455 		    for (i = 0; i < operandLen; i++) {
2456 			/* Start element "isnsObject". */
2457 			if (xmlTextWriterStartElement(writer,
2458 			    (xmlChar *)ISNSOBJECT) < 0) {
2459 			    return (ERROR_XML_START_ELEMENT_FAILED);
2460 			}
2461 
2462 			if (xmlTextWriterStartElement(writer,
2463 			    (xmlChar *)DDSETOBJECT) < 0) {
2464 			    return (ERROR_XML_START_ELEMENT_FAILED);
2465 			}
2466 
2467 			/* Start attr "name". */
2468 			if (xmlTextWriterWriteAttribute(writer,
2469 			    (xmlChar *)NAMEATTR, (xmlChar *)operand[i]) < 0) {
2470 			    return (ERROR_XML_WRITE_ATTRIBUTE_FAILED);
2471 			}
2472 
2473 			/* End element "DiscoveryDomain". */
2474 			if (xmlTextWriterEndElement(writer) < 0) {
2475 			    return (ERROR_XML_END_ELEMENT_FAILED);
2476 			}
2477 
2478 			/* End element "isnsObject". */
2479 			if (xmlTextWriterEndElement(writer) < 0) {
2480 			    return (ERROR_XML_END_ELEMENT_FAILED);
2481 			}
2482 		    }
2483 		    break;
2484 	    case (ServerConfig):
2485 		if (xmlTextWriterStartElement(writer,
2486 		    (xmlChar *)ISNSSERVER) < 0) {
2487 		    return (ERROR_XML_START_ELEMENT_FAILED);
2488 		}
2489 		if (xmlTextWriterEndElement(writer) < 0) {
2490 		    return (ERROR_XML_END_ELEMENT_FAILED);
2491 		}
2492 		break;
2493 	    default:
2494 	    return (UNKNOWN);
2495 	}
2496 
2497 	/* End element "get". */
2498 	if (xmlTextWriterEndElement(writer) < 0) {
2499 	    return (ERROR_XML_END_ELEMENT_FAILED);
2500 	}
2501 	/* End element "isnsRequest". */
2502 	if (xmlTextWriterEndElement(writer) < 0) {
2503 	    return (ERROR_XML_END_ELEMENT_FAILED);
2504 	}
2505 	if (xmlTextWriterEndDocument(writer) < 0) {
2506 	    return (ERROR_XML_END_DOC_FAILED);
2507 	}
2508 
2509 	xmlFreeTextWriter(writer);
2510 
2511 	len = xmlStrlen(xbuf->content) + 1;
2512 	/* XXX - copy NULL at the end by having one more extra byte */
2513 	if ((*doc = xmlStrndup(xbuf->content, len)) == NULL) {
2514 	    return (ERROR_XML_STRDUP_FAILED);
2515 	}
2516 
2517 	xmlBufferFree(xbuf);
2518 	return (0);
2519 }
2520 
2521 /*
2522  * ****************************************************************************
2523  *
2524  * list_node_func -
2525  * 	isnsadm list-node [options] [<node name>, ...]
2526  *
2527  * operandLen	- number of operands user passed into the cli
2528  * operand	- pointer to operand list from user
2529  * options	- pointer to option list from user
2530  *
2531  * ****************************************************************************
2532  */
2533 /*ARGSUSED*/
2534 static int
2535 list_node_func(int operandLen, char *operand[], cmdOptions_t *options,
2536 	void *addarg)
2537 {
2538 
2539 	cmdOptions_t *optionList = options;
2540 	xmlChar *doc, *e_doc;
2541 	int ret;
2542 	door_arg_t		darg;
2543 	int			fd, flag = 0;
2544 
2545 	for (; optionList->optval; optionList++) {
2546 	    switch (optionList->optval) {
2547 		case 'i':
2548 		    flag |= INITIATOR_ONLY;
2549 		    break;
2550 		case 't':
2551 		    flag |= TARGET_ONLY;
2552 		    break;
2553 		case 'v':
2554 		    flag |= VERBOSE;
2555 		    break;
2556 		default:
2557 		    return (UNKNOWN);
2558 	    }
2559 	}
2560 
2561 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
2562 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
2563 	    return (ret);
2564 	}
2565 
2566 	/* No operand specified. Issue enumerate. */
2567 	if (operandLen == 0) {
2568 	    ret = build_enumerate_xml_doc(Node, &doc);
2569 	    if (ret != 0) {
2570 		(void) close(fd);
2571 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
2572 		return (ret);
2573 	    }
2574 	    bzero(&darg, sizeof (darg));
2575 	    darg.data_ptr = (char *)doc;
2576 	    darg.data_size = xmlStrlen(doc) + 1;
2577 	    darg.rbuf = NULL;
2578 	    darg.rsize = 0;
2579 
2580 	    if ((flag & VERBOSE) == VERBOSE) {
2581 		if ((door_call(fd, &darg)) == -1) {
2582 		    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
2583 		    (void) close(fd);
2584 		    (void) xmlFree(doc);
2585 		    return (ret);
2586 		}
2587 
2588 		if ((ret = cvt_enumerate_rsp_to_get_req((xmlChar *)darg.rbuf,
2589 		    &e_doc, Node, flag)) != 0) {
2590 		    (void) munmap(darg.rbuf, darg.rsize);
2591 		    (void) close(fd);
2592 		    (void) xmlFree(doc);
2593 		    if (ret != SUCCESS_WITH_NO_OBJECT) {
2594 			(void) fprintf(stderr, "%s\n", getTextMessage(ret));
2595 		    } else {
2596 			ret = SUBCOMMAND_SUCCESS;
2597 		    }
2598 		    return (ret);
2599 		} else {
2600 		    (void) munmap(darg.rbuf, darg.rsize);
2601 		    (void) xmlFree(doc);
2602 		    doc = e_doc;
2603 		    bzero(&darg, sizeof (door_arg_t));
2604 		    darg.data_ptr = (char *)doc;
2605 		    darg.data_size = xmlStrlen(doc) + 1;
2606 		    darg.rbuf = NULL;
2607 		    darg.rsize = 0;
2608 		}
2609 	    }
2610 	} else {
2611 	    if ((ret = build_get_xml_doc(operandLen, operand, Node, &doc)) ==
2612 		0) {
2613 		bzero(&darg, sizeof (darg));
2614 		darg.data_ptr = (char *)doc;
2615 		darg.data_size = xmlStrlen(doc) + 1;
2616 		darg.rbuf = NULL;
2617 		darg.rsize = 0;
2618 	    } else {
2619 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
2620 		(void) close(fd);
2621 		(void) xmlFree(doc);
2622 		return (ret);
2623 	    }
2624 	}
2625 
2626 	if ((door_call(fd, &darg)) == -1) {
2627 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
2628 	    (void) close(fd);
2629 	    (void) xmlFree(doc);
2630 	    return (ret);
2631 	}
2632 
2633 	if ((ret = process_get_response(Node, (xmlChar *)darg.rbuf, flag)) !=
2634 	    0) {
2635 	/*
2636 	 * door frame work allocated a buffer when the date lager that rbuf.
2637 	 * indicate if munmap is required on rbuf.
2638 	 */
2639 	    (void) munmap(darg.rbuf, darg.rsize);
2640 	    (void) xmlFree(doc);
2641 	    (void) close(fd);
2642 	    return (ret);
2643 	}
2644 
2645 	(void) munmap(darg.rbuf, darg.rsize);
2646 	(void) close(fd);
2647 	xmlFree(doc);
2648 
2649 	return (SUBCOMMAND_SUCCESS);
2650 }
2651 
2652 /*
2653  * ****************************************************************************
2654  *
2655  * list_dd_func -
2656  * 	isnsadm list-dd [options] [<dd name>, ...]
2657  *
2658  * operandLen	- number of operands user passed into the cli
2659  * operand	- pointer to operand list from user
2660  * options	- pointer to option list from user
2661  *
2662  * ****************************************************************************
2663  */
2664 /*ARGSUSED*/
2665 static int
2666 list_dd_func(int operandLen, char *operand[], cmdOptions_t *options,
2667 	void *addarg)
2668 {
2669 	cmdOptions_t *optionList = options;
2670 	xmlChar *doc, *e_doc;
2671 	int ret;
2672 	door_arg_t		darg;
2673 	int			fd, flag = 0;
2674 
2675 	for (; optionList->optval; optionList++) {
2676 	    switch (optionList->optval) {
2677 		case 'v':
2678 		    flag |= VERBOSE;
2679 		    break;
2680 	    }
2681 	}
2682 
2683 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
2684 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
2685 	    return (ret);
2686 	}
2687 
2688 	/* No operand specified. Issue enumerate. */
2689 	if (operandLen == 0) {
2690 	    ret = build_enumerate_xml_doc(DiscoveryDomain, &doc);
2691 	    if (ret != 0) {
2692 		(void) close(fd);
2693 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
2694 		return (ret);
2695 	    }
2696 	    /* get the enumerate resposne first. */
2697 	    bzero(&darg, sizeof (darg));
2698 	    darg.data_ptr = (char *)doc;
2699 	    darg.data_size = xmlStrlen(doc) + 1;
2700 	    darg.rbuf = NULL;
2701 	    darg.rsize = 0;
2702 	    if ((door_call(fd, &darg)) == -1) {
2703 		ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
2704 		(void) close(fd);
2705 		(void) xmlFree(doc);
2706 		return (ret);
2707 	    }
2708 	    if ((ret = cvt_enumerate_rsp_to_get_req((xmlChar *)darg.rbuf,
2709 		&e_doc, DiscoveryDomain, flag)) != 0) {
2710 		(void) munmap(darg.rbuf, darg.rsize);
2711 		(void) close(fd);
2712 		(void) xmlFree(doc);
2713 		if (ret != SUCCESS_WITH_NO_OBJECT) {
2714 		    (void) fprintf(stderr, "%s\n", getTextMessage(ret));
2715 		} else {
2716 		    ret = SUBCOMMAND_SUCCESS;
2717 		}
2718 		return (ret);
2719 	    } else {
2720 		(void) munmap(darg.rbuf, darg.rsize);
2721 		(void) xmlFree(doc);
2722 		doc = e_doc;
2723 	    }
2724 	} else {
2725 	    if ((ret = build_get_xml_doc(operandLen, operand,
2726 		DiscoveryDomain, &doc)) != 0) {
2727 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
2728 		(void) close(fd);
2729 		(void) xmlFree(doc);
2730 		return (ret);
2731 	    }
2732 	}
2733 
2734 	bzero(&darg, sizeof (darg));
2735 	darg.data_ptr = (char *)doc;
2736 	darg.data_size = xmlStrlen(doc) + 1;
2737 	darg.rbuf = NULL;
2738 	darg.rsize = 0;
2739 
2740 	if ((door_call(fd, &darg)) == -1) {
2741 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
2742 	    (void) close(fd);
2743 	    (void) xmlFree(doc);
2744 	    return (ret);
2745 	}
2746 
2747 	if ((ret = process_get_response(DiscoveryDomain, (xmlChar *)darg.rbuf,
2748 	    flag)) != 0) {
2749 	    (void) munmap(darg.rbuf, darg.rsize);
2750 	    (void) close(fd);
2751 	    (void) xmlFree(doc);
2752 	    return (ret);
2753 	}
2754 
2755 	(void) munmap(darg.rbuf, darg.rsize);
2756 
2757 	(void) close(fd);
2758 	xmlFree(doc);
2759 
2760 	return (SUBCOMMAND_SUCCESS);
2761 }
2762 
2763 /*
2764  * ****************************************************************************
2765  *
2766  * list_ddset_func -
2767  * 	isnsadm list-dd-set [options] [<dd set name>, ...]
2768  *
2769  * operandLen	- number of operands user passed into the cli
2770  * operand	- pointer to operand list from user
2771  * options	- pointer to option list from user
2772  *
2773  * ****************************************************************************
2774  */
2775 /*ARGSUSED*/
2776 static int
2777 list_ddset_func(int operandLen, char *operand[], cmdOptions_t *options,
2778 	void *addarg)
2779 {
2780 	cmdOptions_t *optionList = options;
2781 	xmlChar *doc, *e_doc;
2782 	msg_code_t ret;
2783 	door_arg_t		darg;
2784 	int			fd, flag = 0;
2785 
2786 	for (; optionList->optval; optionList++) {
2787 	    switch (optionList->optval) {
2788 		case 'v':
2789 		    flag |= VERBOSE;
2790 		    break;
2791 	    }
2792 	}
2793 
2794 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
2795 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
2796 	    return (ret);
2797 	}
2798 
2799 	/* No operand specified. Issue enumerate. */
2800 	if (operandLen == 0) {
2801 	    ret = build_enumerate_xml_doc(DiscoveryDomainSet, &doc);
2802 	    if (ret != 0) {
2803 		(void) close(fd);
2804 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
2805 		return (ret);
2806 	    }
2807 	    /* get the enumerate resposne. */
2808 	    bzero(&darg, sizeof (darg));
2809 	    darg.data_ptr = (char *)doc;
2810 	    darg.data_size = xmlStrlen(doc) + 1;
2811 	    darg.rbuf = NULL;
2812 	    darg.rsize = 0;
2813 	    if ((door_call(fd, &darg)) == -1) {
2814 		ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
2815 		(void) close(fd);
2816 		(void) xmlFree(doc);
2817 		return (ret);
2818 	    }
2819 
2820 	    if ((ret = cvt_enumerate_rsp_to_get_req((xmlChar *)darg.rbuf,
2821 		&e_doc, DiscoveryDomainSet, flag)) != 0) {
2822 		(void) munmap(darg.rbuf, darg.rsize);
2823 		(void) close(fd);
2824 		(void) xmlFree(doc);
2825 		if (ret != SUCCESS_WITH_NO_OBJECT) {
2826 		    (void) fprintf(stderr, "%s\n", getTextMessage(ret));
2827 		} else {
2828 		    ret = SUBCOMMAND_SUCCESS;
2829 		}
2830 		return (ret);
2831 	    } else {
2832 		(void) munmap(darg.rbuf, darg.rsize);
2833 		(void) xmlFree(doc);
2834 		doc = e_doc;
2835 		bzero(&darg, sizeof (darg));
2836 		darg.data_ptr = (char *)doc;
2837 		darg.data_size = xmlStrlen(doc) + 1;
2838 		darg.rbuf = NULL;
2839 		darg.rsize = 0;
2840 	    }
2841 	} else {
2842 	    if ((ret = build_get_xml_doc(operandLen, operand,
2843 		DiscoveryDomainSet, &doc)) == 0) {
2844 		bzero(&darg, sizeof (darg));
2845 		darg.data_ptr = (char *)doc;
2846 		darg.data_size = xmlStrlen(doc) + 1;
2847 		darg.rbuf = NULL;
2848 		darg.rsize = 0;
2849 	    } else {
2850 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
2851 	    }
2852 	}
2853 
2854 	if ((door_call(fd, &darg)) == -1) {
2855 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
2856 	    (void) close(fd);
2857 	    (void) xmlFree(doc);
2858 	    return (ret);
2859 	}
2860 
2861 	/*
2862 	 * door frame work allocated a buffer when the date lager that rbuf.
2863 	 * indicate if munmap is required on rbuf.
2864 	 */
2865 	if ((ret = process_get_response(DiscoveryDomainSet,
2866 	    (xmlChar *)darg.rbuf, flag)) != 0) {
2867 	    (void) munmap(darg.rbuf, darg.rsize);
2868 	    (void) close(fd);
2869 	    (void) xmlFree(doc);
2870 	    return (ret);
2871 	}
2872 
2873 	(void) munmap(darg.rbuf, darg.rsize);
2874 	(void) close(fd);
2875 	(void) xmlFree(doc);
2876 
2877 	return (SUBCOMMAND_SUCCESS);
2878 }
2879 
2880 /*
2881  * ****************************************************************************
2882  *
2883  * create_dd_func -
2884  * 	create a DiscoveryDomain create-dd <dd name>, ...
2885  *
2886  * operandLen	- number of operands user passed into the cli
2887  * operand	- pointer to operand list from user
2888  * options	- pointer to option list from user
2889  *
2890  * ****************************************************************************
2891  */
2892 /*ARGSUSED*/
2893 static int
2894 create_dd_func(int operandLen, char *operand[], cmdOptions_t *options,
2895 	void *addarg)
2896 {
2897 	xmlChar *doc;
2898 	msg_code_t ret;
2899 	door_arg_t		darg;
2900 	int			fd;
2901 
2902 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
2903 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
2904 	    return (ret);
2905 	}
2906 
2907 	if ((ret = build_create_xml_doc(operandLen, operand,
2908 		DiscoveryDomain, NULL, &doc)) == 0) {
2909 		bzero(&darg, sizeof (darg));
2910 		darg.data_ptr = (char *)doc;
2911 		darg.data_size = xmlStrlen(doc) + 1;
2912 		darg.rbuf = NULL;
2913 		darg.rsize = 0;
2914 	} else {
2915 		(void) close(fd);
2916 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
2917 		return (ret);
2918 	}
2919 
2920 	if ((door_call(fd, &darg)) == -1) {
2921 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
2922 	    (void) close(fd);
2923 	    (void) xmlFree(doc);
2924 	    return (ret);
2925 	}
2926 
2927 	/*
2928 	 * door frame work allocated a buffer when the date lager that rbuf.
2929 	 * indicate if munmap is required on rbuf.
2930 	 */
2931 	if ((ret = process_result_response((xmlChar *)darg.rbuf,
2932 		DiscoveryDomain)) != 0) {
2933 	    (void) munmap(darg.rbuf, darg.rsize);
2934 	    (void) close(fd);
2935 	    (void) xmlFree(doc);
2936 	    return (ret);
2937 	}
2938 
2939 	(void) munmap(darg.rbuf, darg.rsize);
2940 	(void) close(fd);
2941 	xmlFree(doc);
2942 
2943 	return (SUBCOMMAND_SUCCESS);
2944 }
2945 
2946 /*
2947  * ****************************************************************************
2948  *
2949  * create_ddset_func -
2950  * 	create a DiscoveryDomainSet create-dd-set <dd set name>, ...
2951  *
2952  * operandLen	- number of operands user passed into the cli
2953  * operand	- pointer to operand list from user
2954  * options	- pointer to option list from user
2955  *
2956  * ****************************************************************************
2957  */
2958 /*ARGSUSED*/
2959 static int
2960 create_ddset_func(int operandLen, char *operand[], cmdOptions_t *options,
2961     void *addarg)
2962 {
2963 	xmlChar *doc;
2964 	msg_code_t ret;
2965 	door_arg_t		darg;
2966 	int			fd;
2967 
2968 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
2969 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
2970 	    return (ret);
2971 	}
2972 
2973 	if ((ret = build_create_xml_doc(operandLen, operand,
2974 		DiscoveryDomainSet, NULL, &doc)) == 0) {
2975 		bzero(&darg, sizeof (darg));
2976 		darg.data_ptr = (char *)doc;
2977 		darg.data_size = xmlStrlen(doc) + 1;
2978 		darg.rbuf = NULL;
2979 		darg.rsize = 0;
2980 	} else {
2981 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
2982 		(void) close(fd);
2983 		return (ret);
2984 	}
2985 
2986 	if ((door_call(fd, &darg)) == -1) {
2987 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
2988 	    (void) close(fd);
2989 	    (void) xmlFree(doc);
2990 	    return (ret);
2991 	}
2992 
2993 	/*
2994 	 * door frame work allocated a buffer when the date lager that rbuf.
2995 	 * indicate if munmap is required on rbuf.
2996 	 */
2997 	if ((ret = process_result_response((xmlChar *)darg.rbuf,
2998 		DiscoveryDomainSet)) != 0) {
2999 	    (void) munmap(darg.rbuf, darg.rsize);
3000 	    (void) close(fd);
3001 	    (void) xmlFree(doc);
3002 	    return (ret);
3003 	}
3004 
3005 	(void) munmap(darg.rbuf, darg.rsize);
3006 
3007 	(void) close(fd);
3008 	xmlFree(doc);
3009 
3010 	return (SUBCOMMAND_SUCCESS);
3011 }
3012 
3013 /*
3014  * ****************************************************************************
3015  *
3016  * modify_dd_func -
3017  * 	Modify a dd attr. currently rename function is supported
3018  *	modify-dd -n name <dd name>
3019  *
3020  * operandLen	- number of operands user passed into the cli
3021  * operand	- pointer to operand list from user
3022  * options	- pointer to option list from user
3023  *
3024  * ****************************************************************************
3025  */
3026 /*ARGSUSED*/
3027 static int
3028 modify_dd_func(int operandLen, char *operand[], cmdOptions_t *options,
3029 	void *addarg)
3030 {
3031 	xmlChar *doc;
3032 	xmlTextReaderPtr reader;
3033 	msg_code_t ret;
3034 	door_arg_t	darg;
3035 	int	fd, m_flag = 0;
3036 	uint32_t    id;
3037 
3038 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
3039 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
3040 	    return (ret);
3041 	}
3042 
3043 	if ((ret = build_get_xml_doc(operandLen, operand,
3044 		DiscoveryDomain, &doc)) == 0) {
3045 		bzero(&darg, sizeof (darg));
3046 		darg.data_ptr = (char *)doc;
3047 		darg.data_size = xmlStrlen(doc) + 1;
3048 		darg.rbuf = NULL;
3049 		darg.rsize = 0;
3050 	} else {
3051 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
3052 		(void) close(fd);
3053 		return (ret);
3054 	}
3055 
3056 	if ((door_call(fd, &darg)) == -1) {
3057 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
3058 	    (void) close(fd);
3059 	    (void) xmlFree(doc);
3060 	    return (ret);
3061 	}
3062 
3063 	/* Free the request that is created by xmlStrnDup. */
3064 	(void) xmlFree(doc);
3065 
3066 	/*
3067 	 * door frame work allocated a buffer when the date lager that rbuf.
3068 	 * indicate if munmap is required on rbuf.
3069 	 */
3070 	if ((ret = process_result_response((xmlChar *)darg.rbuf,
3071 		DiscoveryDomain)) != 0) {
3072 	    (void) munmap(darg.rbuf, darg.rsize);
3073 	    (void) close(fd);
3074 	    return (ret);
3075 	}
3076 
3077 	/* setup xml parser on the response. */
3078 	if ((reader = (xmlTextReaderPtr)xmlReaderForMemory
3079 	    ((const char *)darg.rbuf, xmlStrlen((xmlChar *)darg.rbuf),
3080 	    NULL, NULL, 0)) == NULL) {
3081 	    (void) munmap(darg.rbuf, darg.rsize);
3082 	    (void) close(fd);
3083 	    return (ERROR_XML_READER_NULL);
3084 	}
3085 
3086 	if (reader = lookup_next_matching_elem(reader, &m_flag, DDOBJECT,
3087 	    ISNSRESPONSE)) {
3088 	    if (m_flag == READER_MATCH) {
3089 		if ((xmlTextReaderMoveToAttribute(reader,
3090 			(const xmlChar *)IDATTR)) == 1) {
3091 		    id = atoi((const char *)xmlTextReaderConstValue(reader));
3092 		} else {
3093 			(void) xmlTextReaderClose(reader);
3094 			(void) xmlFreeTextReader(reader);
3095 			return (ERROR_XML_ID_ATTR_NOT_FOUND);
3096 		}
3097 	    } else {
3098 		(void) xmlTextReaderClose(reader);
3099 		(void) xmlFreeTextReader(reader);
3100 		return (ERROR_XML_DD_OBJECT_NOT_FOUND);
3101 	    }
3102 	} else {
3103 	    (void) fprintf(stderr, "%s\n",
3104 		getTextMessage(ERROR_XML_READER_NULL));
3105 	    return (ERROR_XML_READER_NULL);
3106 	}
3107 
3108 	(void) xmlTextReaderClose(reader);
3109 	(void) xmlFreeTextReader(reader);
3110 
3111 	if ((ret = build_rename_xml_doc(options->optarg, DiscoveryDomain,
3112 		id, &doc)) == 0) {
3113 		bzero(&darg, sizeof (darg));
3114 		darg.data_ptr = (char *)doc;
3115 		darg.data_size = xmlStrlen(doc) + 1;
3116 		darg.rbuf = NULL;
3117 		darg.rsize = 0;
3118 	} else {
3119 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
3120 		(void) close(fd);
3121 		return (ret);
3122 	}
3123 
3124 	if ((door_call(fd, &darg)) == -1) {
3125 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
3126 	    (void) close(fd);
3127 	    (void) xmlFree(doc);
3128 	    return (ret);
3129 	}
3130 
3131 	/*
3132 	 * door frame work allocated a buffer when the date lager that rbuf.
3133 	 * indicate if munmap is required on rbuf.
3134 	 */
3135 	if ((ret = process_result_response((xmlChar *)darg.rbuf,
3136 		DiscoveryDomain)) != 0) {
3137 	    (void) munmap(darg.rbuf, darg.rsize);
3138 	    (void) close(fd);
3139 	    (void) xmlFree(doc);
3140 	    return (ret);
3141 	}
3142 
3143 	(void) munmap(darg.rbuf, darg.rsize);
3144 	(void) close(fd);
3145 	xmlFree(doc);
3146 
3147 	return (SUBCOMMAND_SUCCESS);
3148 }
3149 
3150 /*
3151  * ****************************************************************************
3152  *
3153  * modify_ddset_func -
3154  * 	Modify a dd attr. currently rename function is supported
3155  *	modify-dd-set -n name <dd name>
3156  *
3157  * operandLen	- number of operands user passed into the cli
3158  * operand	- pointer to operand list from user
3159  * options	- pointer to option list from user
3160  *
3161  * ****************************************************************************
3162  */
3163 /*ARGSUSED*/
3164 static int
3165 modify_ddset_func(int operandLen, char *operand[], cmdOptions_t *options,
3166 	void *addarg)
3167 {
3168 	xmlChar *doc;
3169 	xmlTextReaderPtr reader;
3170 	msg_code_t ret;
3171 	door_arg_t	darg;
3172 	int	fd, m_flag = 0;
3173 	uint32_t    id;
3174 
3175 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
3176 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
3177 	    return (ret);
3178 	}
3179 
3180 	if ((ret = build_get_xml_doc(operandLen, operand,
3181 		DiscoveryDomainSet, &doc)) == 0) {
3182 		bzero(&darg, sizeof (darg));
3183 		darg.data_ptr = (char *)doc;
3184 		darg.data_size = xmlStrlen(doc) + 1;
3185 		darg.rbuf = NULL;
3186 		darg.rsize = 0;
3187 	} else {
3188 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
3189 		(void) close(fd);
3190 		return (ret);
3191 	}
3192 
3193 	if ((door_call(fd, &darg)) == -1) {
3194 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
3195 	    (void) close(fd);
3196 	    (void) xmlFree(doc);
3197 	    return (ret);
3198 	}
3199 
3200 	/* Free the request that is created by xmlStrnDup. */
3201 	(void) xmlFree(doc);
3202 
3203 	/*
3204 	 * door frame work allocated a buffer when the date lager that rbuf.
3205 	 * indicate if munmap is required on rbuf.
3206 	 */
3207 	if ((ret = process_result_response((xmlChar *)darg.rbuf,
3208 		DiscoveryDomainSet)) != 0) {
3209 	    (void) munmap(darg.rbuf, darg.rsize);
3210 	    (void) close(fd);
3211 	    return (ret);
3212 	}
3213 
3214 	/* setup xml parser on the response. */
3215 	if ((reader = (xmlTextReaderPtr)xmlReaderForMemory
3216 	    ((const char *)darg.rbuf, xmlStrlen((xmlChar *)darg.rbuf),
3217 	    NULL, NULL, 0)) == NULL) {
3218 	    (void) munmap(darg.rbuf, darg.rsize);
3219 	    (void) close(fd);
3220 	    return (ERROR_XML_READER_NULL);
3221 	}
3222 
3223 	if (reader = lookup_next_matching_elem(reader, &m_flag, DDSETOBJECT,
3224 	    ISNSRESPONSE)) {
3225 	    if (m_flag == READER_MATCH) {
3226 		if ((xmlTextReaderMoveToAttribute(reader,
3227 			(const xmlChar *)IDATTR)) == 1) {
3228 		    id = atoi((const char *)xmlTextReaderConstValue(reader));
3229 		} else {
3230 			(void) xmlTextReaderClose(reader);
3231 			(void) xmlFreeTextReader(reader);
3232 			return (ERROR_XML_ID_ATTR_NOT_FOUND);
3233 		}
3234 	    } else {
3235 		(void) xmlTextReaderClose(reader);
3236 		(void) xmlFreeTextReader(reader);
3237 		(void) fprintf(stderr, "%s\n",
3238 		    getTextMessage(ERROR_XML_NAME_ATTR_NOT_FOUND));
3239 		return (ERROR_XML_DD_SET_OBJECT_NOT_FOUND);
3240 	    }
3241 	}
3242 
3243 	(void) xmlTextReaderClose(reader);
3244 	(void) xmlFreeTextReader(reader);
3245 
3246 	if ((ret = build_rename_xml_doc(options->optarg, DiscoveryDomainSet,
3247 		id, &doc)) == 0) {
3248 		bzero(&darg, sizeof (darg));
3249 		darg.data_ptr = (char *)doc;
3250 		darg.data_size = xmlStrlen(doc) + 1;
3251 		darg.rbuf = NULL;
3252 		darg.rsize = 0;
3253 	} else {
3254 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
3255 		(void) close(fd);
3256 		return (ret);
3257 	}
3258 
3259 	if ((door_call(fd, &darg)) == -1) {
3260 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
3261 	    (void) close(fd);
3262 	    (void) xmlFree(doc);
3263 	    return (ret);
3264 	}
3265 
3266 	/*
3267 	 * door frame work allocated a buffer when the date lager that rbuf.
3268 	 * indicate if munmap is required on rbuf.
3269 	 */
3270 	if ((ret = process_result_response((xmlChar *)darg.rbuf,
3271 		DiscoveryDomainSet)) != 0) {
3272 	    (void) munmap(darg.rbuf, darg.rsize);
3273 	    (void) close(fd);
3274 	    (void) xmlFree(doc);
3275 	    return (ret);
3276 	}
3277 
3278 	(void) munmap(darg.rbuf, darg.rsize);
3279 	(void) close(fd);
3280 	xmlFree(doc);
3281 
3282 	return (SUBCOMMAND_SUCCESS);
3283 }
3284 
3285 /*
3286  * ****************************************************************************
3287  *
3288  * add_node_func -
3289  * 	Add a node to a DiscoveryDomain add-node -d dd-name <node name>, ...
3290  *
3291  * operandLen	- number of operands user passed into the cli
3292  * operand	- pointer to operand list from user
3293  * options	- pointer to option list from user
3294  *
3295  * ****************************************************************************
3296  */
3297 /*ARGSUSED*/
3298 static int
3299 add_node_func(int operandLen, char *operand[], cmdOptions_t *options,
3300 	void *addarg)
3301 {
3302 	xmlChar *doc;
3303 	msg_code_t ret;
3304 	door_arg_t	darg;
3305 	int	fd;
3306 
3307 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
3308 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
3309 	    return (ret);
3310 	}
3311 
3312 	if ((ret = build_create_xml_doc(operandLen, operand,
3313 		DiscoveryDomainMember, options->optarg, &doc)) == 0) {
3314 		bzero(&darg, sizeof (darg));
3315 		darg.data_ptr = (char *)doc;
3316 		darg.data_size = xmlStrlen(doc) + 1;
3317 		darg.rbuf = NULL;
3318 		darg.rsize = 0;
3319 	} else {
3320 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
3321 		(void) close(fd);
3322 		return (ret);
3323 	}
3324 
3325 	if ((door_call(fd, &darg)) == -1) {
3326 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
3327 	    (void) close(fd);
3328 	    (void) xmlFree(doc);
3329 	    return (ret);
3330 	}
3331 
3332 	/*
3333 	 * door frame work allocated a buffer when the date lager that rbuf.
3334 	 * indicate if munmap is required on rbuf.
3335 	 */
3336 	if ((ret = process_result_response((xmlChar *)darg.rbuf,
3337 		DiscoveryDomainMember)) != 0) {
3338 	    (void) munmap(darg.rbuf, darg.rsize);
3339 	    (void) close(fd);
3340 	    (void) xmlFree(doc);
3341 	    return (ret);
3342 	}
3343 
3344 	(void) munmap(darg.rbuf, darg.rsize);
3345 	(void) close(fd);
3346 	xmlFree(doc);
3347 
3348 	return (SUBCOMMAND_SUCCESS);
3349 }
3350 
3351 /*
3352  * ****************************************************************************
3353  *
3354  * add_dd_func -
3355  * 	Add a dd to a DiscoveryDomainSet add-dd -s dd-set name <dd name>, ...
3356  *
3357  * operandLen	- number of operands user passed into the cli
3358  * operand	- pointer to operand list from user
3359  * options	- pointer to option list from user
3360  *
3361  * ****************************************************************************
3362  */
3363 /*ARGSUSED*/
3364 static int
3365 add_dd_func(int operandLen, char *operand[], cmdOptions_t *options,
3366 	void *addarg)
3367 {
3368 	xmlChar *doc;
3369 	msg_code_t ret;
3370 	door_arg_t	darg;
3371 	int	fd;
3372 
3373 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
3374 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
3375 	    return (ret);
3376 	}
3377 
3378 	if ((ret = build_create_xml_doc(operandLen, operand,
3379 		DiscoveryDomainSetMember, options->optarg, &doc)) == 0) {
3380 		bzero(&darg, sizeof (darg));
3381 		darg.data_ptr = (char *)doc;
3382 		darg.data_size = xmlStrlen(doc) + 1;
3383 		darg.rbuf = NULL;
3384 		darg.rsize = 0;
3385 	} else {
3386 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
3387 		(void) close(fd);
3388 		return (ret);
3389 	}
3390 
3391 	if ((door_call(fd, &darg)) == -1) {
3392 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
3393 	    (void) close(fd);
3394 	    (void) xmlFree(doc);
3395 	    return (ret);
3396 	}
3397 
3398 	/*
3399 	 * door frame work allocated a buffer when the date lager that rbuf.
3400 	 * indicate if munmap is required on rbuf.
3401 	 */
3402 	if ((ret = process_result_response((xmlChar *)darg.rbuf,
3403 		DiscoveryDomainSetMember)) != 0) {
3404 	    (void) munmap(darg.rbuf, darg.rsize);
3405 	    (void) close(fd);
3406 	    (void) xmlFree(doc);
3407 	    return (ret);
3408 	}
3409 
3410 	(void) munmap(darg.rbuf, darg.rsize);
3411 	(void) close(fd);
3412 	xmlFree(doc);
3413 
3414 	return (SUBCOMMAND_SUCCESS);
3415 }
3416 
3417 /*
3418  * ****************************************************************************
3419  *
3420  * remove_node_func -
3421  * 	Remove a node from DiscoveryDomain
3422  *	remov-node -d dd-name <node name>, ...
3423  *
3424  * operandLen	- number of operands user passed into the cli
3425  * operand	- pointer to operand list from user
3426  * options	- pointer to option list from user
3427  *
3428  * ****************************************************************************
3429  */
3430 /*ARGSUSED*/
3431 static int
3432 remove_node_func(int operandLen, char *operand[], cmdOptions_t *options,
3433 	void *addarg)
3434 {
3435 	xmlChar *doc;
3436 	msg_code_t ret;
3437 	door_arg_t	darg;
3438 	int	fd;
3439 
3440 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
3441 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
3442 	    return (ret);
3443 	}
3444 
3445 	if ((ret = build_delete_xml_doc(operandLen, operand,
3446 		DiscoveryDomainMember, options->optarg, &doc)) == 0) {
3447 		bzero(&darg, sizeof (darg));
3448 		darg.data_ptr = (char *)doc;
3449 		darg.data_size = xmlStrlen(doc) + 1;
3450 		darg.rbuf = NULL;
3451 		darg.rsize = 0;
3452 	} else {
3453 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
3454 		(void) close(fd);
3455 		return (ret);
3456 	}
3457 
3458 	if ((door_call(fd, &darg)) == -1) {
3459 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
3460 	    (void) close(fd);
3461 	    (void) xmlFree(doc);
3462 	    return (ret);
3463 	}
3464 
3465 	/*
3466 	 * door frame work allocated a buffer when the date lager that rbuf.
3467 	 * indicate if munmap is required on rbuf.
3468 	 */
3469 	if ((ret = process_result_response((xmlChar *)darg.rbuf,
3470 		DiscoveryDomainMember)) != 0) {
3471 	    (void) munmap(darg.rbuf, darg.rsize);
3472 	    (void) close(fd);
3473 	    (void) xmlFree(doc);
3474 	    return (ret);
3475 	}
3476 
3477 	(void) munmap(darg.rbuf, darg.rsize);
3478 	(void) close(fd);
3479 	xmlFree(doc);
3480 
3481 	return (SUBCOMMAND_SUCCESS);
3482 }
3483 
3484 /*
3485  * ****************************************************************************
3486  *
3487  * remove_dd_func -
3488  * 	Remove a dd from DiscoveryDomainSet
3489  *	remove-dd -s dd-set name <dd name>, ...
3490  *
3491  * operandLen	- number of operands user passed into the cli
3492  * operand	- pointer to operand list from user
3493  * options	- pointer to option list from user
3494  *
3495  * ****************************************************************************
3496  */
3497 /*ARGSUSED*/
3498 static int
3499 remove_dd_func(int operandLen, char *operand[], cmdOptions_t *options,
3500 	void *addarg)
3501 {
3502 	xmlChar *doc;
3503 	msg_code_t ret;
3504 	door_arg_t	darg;
3505 	int	fd;
3506 
3507 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
3508 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
3509 	    return (ret);
3510 	}
3511 
3512 	if ((ret = build_delete_xml_doc(operandLen, operand,
3513 		DiscoveryDomainSetMember, options->optarg, &doc)) == 0) {
3514 		bzero(&darg, sizeof (darg));
3515 		darg.data_ptr = (char *)doc;
3516 		darg.data_size = xmlStrlen(doc) + 1;
3517 		darg.rbuf = NULL;
3518 		darg.rsize = 0;
3519 	} else {
3520 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
3521 		(void) close(fd);
3522 		return (ret);
3523 	}
3524 
3525 	if ((door_call(fd, &darg)) == -1) {
3526 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
3527 	    (void) close(fd);
3528 	    (void) xmlFree(doc);
3529 	    return (ret);
3530 	}
3531 
3532 	/*
3533 	 * door frame work allocated a buffer when the date lager that rbuf.
3534 	 * indicate if munmap is required on rbuf.
3535 	 */
3536 	if ((ret = process_result_response((xmlChar *)darg.rbuf,
3537 		DiscoveryDomainSetMember)) != 0) {
3538 	    (void) munmap(darg.rbuf, darg.rsize);
3539 	    (void) close(fd);
3540 	    (void) xmlFree(doc);
3541 	    return (ret);
3542 	}
3543 
3544 	(void) munmap(darg.rbuf, darg.rsize);
3545 	(void) close(fd);
3546 	xmlFree(doc);
3547 
3548 	return (SUBCOMMAND_SUCCESS);
3549 }
3550 
3551 /*
3552  * ****************************************************************************
3553  *
3554  * delete_dd_func -
3555  * 	remove a DiscoveryDomain remove-dd <dd name>, ...
3556  *
3557  * operandLen	- number of operands user passed into the cli
3558  * operand	- pointer to operand list from user
3559  * options	- pointer to option list from user
3560  *
3561  * ****************************************************************************
3562  */
3563 /*ARGSUSED*/
3564 static int
3565 delete_dd_func(int operandLen, char *operand[], cmdOptions_t *options,
3566 	void *addarg)
3567 {
3568 	xmlChar *doc;
3569 	msg_code_t ret;
3570 	door_arg_t		darg;
3571 	int			fd;
3572 
3573 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
3574 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
3575 	    return (ret);
3576 	}
3577 
3578 	if ((ret = build_delete_xml_doc(operandLen, operand,
3579 		DiscoveryDomain, NULL, &doc)) == 0) {
3580 		bzero(&darg, sizeof (darg));
3581 		darg.data_ptr = (char *)doc;
3582 		darg.data_size = xmlStrlen(doc) + 1;
3583 		darg.rbuf = NULL;
3584 		darg.rsize = 0;
3585 	} else {
3586 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
3587 		(void) close(fd);
3588 		return (ret);
3589 	}
3590 
3591 	if ((door_call(fd, &darg)) == -1) {
3592 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
3593 	    (void) close(fd);
3594 	    (void) xmlFree(doc);
3595 	    return (ret);
3596 	}
3597 
3598 	/*
3599 	 * door frame work allocated a buffer when the date lager that rbuf.
3600 	 * indicate if munmap is required on rbuf.
3601 	 */
3602 	if ((ret = process_result_response((xmlChar *)darg.rbuf,
3603 		DiscoveryDomain)) != 0) {
3604 	    (void) munmap(darg.rbuf, darg.rsize);
3605 	    (void) close(fd);
3606 	    (void) xmlFree(doc);
3607 	    return (ret);
3608 	}
3609 
3610 	(void) munmap(darg.rbuf, darg.rsize);
3611 
3612 	(void) close(fd);
3613 	xmlFree(doc);
3614 
3615 	return (SUBCOMMAND_SUCCESS);
3616 }
3617 
3618 /*
3619  * ****************************************************************************
3620  *
3621  * delete_ddset_func -
3622  * 	delete DiscoveryDomainSet(s) delete-dd-set <dd set name>, ...
3623  *
3624  * operandLen	- number of operands user passed into the cli
3625  * operand	- pointer to operand list from user
3626  * options	- pointer to option list from user
3627  *
3628  * ****************************************************************************
3629  */
3630 /*ARGSUSED*/
3631 static int
3632 delete_ddset_func(int operandLen, char *operand[], cmdOptions_t *options,
3633     void *addarg)
3634 {
3635 	xmlChar *doc;
3636 	msg_code_t ret;
3637 	door_arg_t		darg;
3638 	int			fd;
3639 
3640 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
3641 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
3642 	    return (ret);
3643 	}
3644 
3645 	if ((ret = build_delete_xml_doc(operandLen, operand,
3646 		DiscoveryDomainSet, NULL, &doc)) == 0) {
3647 		bzero(&darg, sizeof (darg));
3648 		darg.data_ptr = (char *)doc;
3649 		darg.data_size = xmlStrlen(doc) + 1;
3650 		darg.rbuf = NULL;
3651 		darg.rsize = 0;
3652 	} else {
3653 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
3654 		(void) close(fd);
3655 		return (ret);
3656 	}
3657 
3658 	if ((door_call(fd, &darg)) == -1) {
3659 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
3660 	    (void) close(fd);
3661 	    (void) xmlFree(doc);
3662 	    return (ret);
3663 	}
3664 
3665 	/*
3666 	 * door frame work allocated a buffer when the date lager that rbuf.
3667 	 * indicate if munmap is required on rbuf.
3668 	 */
3669 	if ((ret = process_result_response((xmlChar *)darg.rbuf,
3670 		DiscoveryDomainSet)) != 0) {
3671 	    (void) munmap(darg.rbuf, darg.rsize);
3672 	    (void) close(fd);
3673 	    (void) xmlFree(doc);
3674 	    return (ret);
3675 	}
3676 
3677 	(void) munmap(darg.rbuf, darg.rsize);
3678 	(void) close(fd);
3679 	xmlFree(doc);
3680 
3681 	return (SUBCOMMAND_SUCCESS);
3682 }
3683 
3684 /*
3685  * ****************************************************************************
3686  *
3687  * i_enableddset
3688  * 	enables/disables DiscoveryDomainSet(s)
3689  *
3690  * operandLen	- number of operands user passed into the cli
3691  * operand	- pointer to operand list from user
3692  * enable	- indication of enable/disable
3693  *
3694  * ****************************************************************************
3695  */
3696 static int
3697 i_enableddset(int operandLen, char *operand[], boolean_t enable)
3698 {
3699 	xmlChar *doc;
3700 	door_arg_t		darg;
3701 	int fd, ret = 0;
3702 
3703 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
3704 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
3705 	    return (ret);
3706 	}
3707 
3708 	if ((ret = build_modify_xml_doc(operandLen, operand,
3709 		DiscoveryDomainSet, enable, &doc)) == 0) {
3710 		bzero(&darg, sizeof (darg));
3711 		darg.data_ptr = (char *)doc;
3712 		darg.data_size = xmlStrlen(doc) + 1;
3713 		darg.rbuf = NULL;
3714 		darg.rsize = 0;
3715 	} else {
3716 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
3717 		(void) close(fd);
3718 		return (ret);
3719 	}
3720 
3721 	if ((door_call(fd, &darg)) == -1) {
3722 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
3723 	    (void) close(fd);
3724 	    (void) xmlFree(doc);
3725 	    return (ret);
3726 	}
3727 
3728 	xmlFree(doc);
3729 
3730 	if ((ret = process_result_response((xmlChar *)darg.rbuf,
3731 		DiscoveryDomainSet)) != 0) {
3732 	    (void) munmap(darg.rbuf, darg.rsize);
3733 	    (void) close(fd);
3734 	    return (ret);
3735 	}
3736 
3737 	(void) munmap(darg.rbuf, darg.rsize);
3738 	(void) close(fd);
3739 	return (SUBCOMMAND_SUCCESS);
3740 }
3741 
3742 /*
3743  * ****************************************************************************
3744  *
3745  * enable_ddset_func -
3746  * 	enables DiscoveryDomainSet(s) enable-dd-set <dd set name>, ...
3747  *
3748  * operandLen	- number of operands user passed into the cli
3749  * operand	- pointer to operand list from user
3750  * options	- pointer to option list from user
3751  *
3752  * ****************************************************************************
3753  */
3754 /*ARGSUSED*/
3755 static int
3756 enable_ddset_func(int operandLen, char *operand[], cmdOptions_t *options,
3757     void *addarg)
3758 {
3759 	return (i_enableddset(operandLen, operand, B_TRUE));
3760 }
3761 
3762 /*
3763  * ****************************************************************************
3764  *
3765  * disabledsetFunc -
3766  * 	disable DiscoveryDomainSet(s) disable-dd-set <dd set name>, ...
3767  *
3768  * operandLen	- number of operands user passed into the cli
3769  * operand	- pointer to operand list from user
3770  * options	- pointer to option list from user
3771  *
3772  * ****************************************************************************
3773  */
3774 /*ARGSUSED*/
3775 static int
3776 disable_ddset_func(int operandLen, char *operand[], cmdOptions_t *options,
3777     void *addarg)
3778 {
3779 	return (i_enableddset(operandLen, operand, B_FALSE));
3780 }
3781 
3782 /*
3783  * ****************************************************************************
3784  *
3785  * show_config_func -
3786  * 	isnsadm show-config
3787  *
3788  * operandLen	- number of operands user passed into the cli
3789  * operand	- pointer to operand list from user
3790  * options	- pointer to option list from user
3791  *
3792  * ****************************************************************************
3793  */
3794 /*ARGSUSED*/
3795 static int
3796 show_config_func(int operandLen, char *operand[], cmdOptions_t *options,
3797 	void *addarg)
3798 {
3799 	xmlChar *doc;
3800 	int ret;
3801 	door_arg_t		darg;
3802 	int			fd, flag = 0;
3803 
3804 	if ((fd = open(ISNS_DOOR_NAME, 0)) == -1) {
3805 	    ret = check_door_error(ERROR_DOOR_OPEN_FAILED, errno);
3806 	    return (ret);
3807 	}
3808 
3809 	if ((ret = build_get_xml_doc(operandLen, operand,
3810 		ServerConfig, &doc)) == 0) {
3811 		bzero(&darg, sizeof (darg));
3812 		darg.data_ptr = (char *)doc;
3813 		darg.data_size = xmlStrlen(doc) + 1;
3814 		darg.rbuf = NULL;
3815 		darg.rsize = 0;
3816 	} else {
3817 		(void) fprintf(stderr, "%s\n", getTextMessage(ret));
3818 		(void) close(fd);
3819 		(void) xmlFree(doc);
3820 		return (ret);
3821 	}
3822 
3823 	if ((door_call(fd, &darg)) == -1) {
3824 	    ret = check_door_error(ERROR_DOOR_CALL_FAILED, errno);
3825 	    (void) close(fd);
3826 	    (void) xmlFree(doc);
3827 	    return (ret);
3828 	}
3829 
3830 	if ((ret = process_get_response(ServerConfig, (xmlChar *)darg.rbuf,
3831 	    flag)) != 0) {
3832 	    (void) munmap(darg.rbuf, darg.rsize);
3833 	    (void) close(fd);
3834 	    (void) xmlFree(doc);
3835 	    return (ret);
3836 	}
3837 
3838 	(void) munmap(darg.rbuf, darg.rsize);
3839 	(void) close(fd);
3840 	xmlFree(doc);
3841 
3842 	return (SUBCOMMAND_SUCCESS);
3843 }
3844 
3845 /*
3846  * *************************************************************************
3847  *
3848  * main
3849  *
3850  * *************************************************************************
3851  */
3852 int
3853 main(int argc, char *argv[])
3854 {
3855 	synTables_t 			synTables;
3856 	char 				versionString[VERSION_STRING_MAX_LEN];
3857 	int 				ret;
3858 	int 				funcRet;
3859 	void 				*subcommandArgs = NULL;
3860 
3861 	(void) setlocale(LC_ALL, "");
3862 
3863 	(void) sprintf(versionString, "%2s.%2s",
3864 	    VERSION_STRING_MAJOR, VERSION_STRING_MINOR);
3865 	synTables.versionString = versionString;
3866 	synTables.longOptionTbl = &longOptions[0];
3867 	synTables.subCommandPropsTbl = &subcommands[0];
3868 
3869 	ret = cmdParse(argc, argv, synTables, subcommandArgs, &funcRet);
3870 
3871 	if (ret == 1) {
3872 		return (COMMAND_SYNTAX_FAILED);
3873 	} else if (ret == -1) {
3874 		perror(argv[0]);
3875 		return (1);
3876 	} else if (ret == 0) {
3877 		/*
3878 		 * strawman way to sort out the error code.
3879 		 * isnsi server protocol error range 0 - 99
3880 		 * isns server maangement op error range 100 -199
3881 		 * isnsadm error range 200 -299
3882 		 */
3883 	    if (funcRet == SUBCOMMAND_SUCCESS) {
3884 		return (0);
3885 	    } else if (funcRet > SUBCOMMAND_SUCCESS) {
3886 		if (funcRet != ERROR_DOOR_CALL_FAILED &&
3887 		    funcRet != ERROR_DOOR_OPEN_FAILED) {
3888 		    (void) fprintf(stderr, "%s\n", getTextMessage(funcRet));
3889 		}
3890 		return (1);
3891 	    } else {
3892 		return (1);
3893 	    }
3894 	}
3895 
3896 	return (0);
3897 } /* end main */
3898