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