xref: /onnv-gate/usr/src/cmd/cmd-inet/usr.sbin/nwamcfg/nwamcfg.c (revision 13034:b615ff9cec13)
111767SAnurag.Maskey@Sun.COM /*
211767SAnurag.Maskey@Sun.COM  * CDDL HEADER START
311767SAnurag.Maskey@Sun.COM  *
411767SAnurag.Maskey@Sun.COM  * The contents of this file are subject to the terms of the
511767SAnurag.Maskey@Sun.COM  * Common Development and Distribution License (the "License").
611767SAnurag.Maskey@Sun.COM  * You may not use this file except in compliance with the License.
711767SAnurag.Maskey@Sun.COM  *
811767SAnurag.Maskey@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911767SAnurag.Maskey@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1011767SAnurag.Maskey@Sun.COM  * See the License for the specific language governing permissions
1111767SAnurag.Maskey@Sun.COM  * and limitations under the License.
1211767SAnurag.Maskey@Sun.COM  *
1311767SAnurag.Maskey@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1411767SAnurag.Maskey@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511767SAnurag.Maskey@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1611767SAnurag.Maskey@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1711767SAnurag.Maskey@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1811767SAnurag.Maskey@Sun.COM  *
1911767SAnurag.Maskey@Sun.COM  * CDDL HEADER END
2011767SAnurag.Maskey@Sun.COM  */
2111767SAnurag.Maskey@Sun.COM 
2211767SAnurag.Maskey@Sun.COM /*
23*13034SAnurag.Maskey@Oracle.COM  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2411767SAnurag.Maskey@Sun.COM  */
2511767SAnurag.Maskey@Sun.COM 
2611767SAnurag.Maskey@Sun.COM /*
2711767SAnurag.Maskey@Sun.COM  * nwamcfg is a lex/yacc based command interpreter used to manage network
2811767SAnurag.Maskey@Sun.COM  * configurations.  The lexer (see nwamcfg_lex.l) builds up tokens, which
2911767SAnurag.Maskey@Sun.COM  * the grammar (see nwamcfg_grammar.y) builds up into commands, some of
3011767SAnurag.Maskey@Sun.COM  * which takes resources and/or properties as arguments.
3111767SAnurag.Maskey@Sun.COM  */
3211767SAnurag.Maskey@Sun.COM 
3311767SAnurag.Maskey@Sun.COM #include <arpa/inet.h>
3411767SAnurag.Maskey@Sun.COM #include <assert.h>
3511767SAnurag.Maskey@Sun.COM #include <ctype.h>
3611767SAnurag.Maskey@Sun.COM #include <errno.h>
3711767SAnurag.Maskey@Sun.COM #include <libnwam.h>
3811767SAnurag.Maskey@Sun.COM #include <libtecla.h>
3911767SAnurag.Maskey@Sun.COM #include <locale.h>
4011767SAnurag.Maskey@Sun.COM #include <stdarg.h>
4111767SAnurag.Maskey@Sun.COM #include <stdio.h>
4211767SAnurag.Maskey@Sun.COM #include <string.h>
4311767SAnurag.Maskey@Sun.COM #include <sys/stat.h>
4411767SAnurag.Maskey@Sun.COM #include <sys/sysmacros.h>
4511767SAnurag.Maskey@Sun.COM #include <sys/types.h>
4611767SAnurag.Maskey@Sun.COM #include <unistd.h>
4711767SAnurag.Maskey@Sun.COM 
4811767SAnurag.Maskey@Sun.COM #include "nwamcfg.h"
4911767SAnurag.Maskey@Sun.COM 
5011767SAnurag.Maskey@Sun.COM #if !defined(TEXT_DOMAIN)		/* should be defined by cc -D */
5111767SAnurag.Maskey@Sun.COM #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it wasn't */
5211767SAnurag.Maskey@Sun.COM #endif
5311767SAnurag.Maskey@Sun.COM 
5411767SAnurag.Maskey@Sun.COM struct help {
5511767SAnurag.Maskey@Sun.COM 	uint_t		cmd_num;
5611767SAnurag.Maskey@Sun.COM 	const char	*cmd_name;
5711767SAnurag.Maskey@Sun.COM 	const char	*cmd_usage;
5811767SAnurag.Maskey@Sun.COM };
5911767SAnurag.Maskey@Sun.COM 
6011767SAnurag.Maskey@Sun.COM extern int yyparse(void);
6111767SAnurag.Maskey@Sun.COM extern int lex_lineno;
6211767SAnurag.Maskey@Sun.COM 
6311767SAnurag.Maskey@Sun.COM #define	MAX_LINE_LEN	1024
6411767SAnurag.Maskey@Sun.COM #define	MAX_CMD_HIST	1024
6511767SAnurag.Maskey@Sun.COM 
6611767SAnurag.Maskey@Sun.COM /* usage of commands */
6711767SAnurag.Maskey@Sun.COM #define	SHELP_CANCEL	"cancel"
6811767SAnurag.Maskey@Sun.COM #define	SHELP_CLEAR	"clear <prop-name>"
6911767SAnurag.Maskey@Sun.COM #define	SHELP_COMMIT	"commit"
7011767SAnurag.Maskey@Sun.COM #define	SHELP_CREATE	"create [-t <template>] <object-type> [<class>] " \
7111767SAnurag.Maskey@Sun.COM 			"<object-name>"
7211767SAnurag.Maskey@Sun.COM #define	SHELP_DESTROY	"destroy {-a | <object-type> [<class>] <object-name>}"
7311767SAnurag.Maskey@Sun.COM #define	SHELP_END	"end"
7411767SAnurag.Maskey@Sun.COM #define	SHELP_EXIT	"exit"
7511767SAnurag.Maskey@Sun.COM #define	SHELP_EXPORT	"export [-d] [-f <output-file>] " \
7611767SAnurag.Maskey@Sun.COM 			"[<object-type> [<class>] <object-name>]"
7711767SAnurag.Maskey@Sun.COM #define	SHELP_GET	"get [-V] <prop-name>"
7811767SAnurag.Maskey@Sun.COM #define	SHELP_HELP	"help [command-name]"
7911767SAnurag.Maskey@Sun.COM #define	SHELP_LIST	"list [-a] [<object-type> [<class>] <object-name>]"
8011767SAnurag.Maskey@Sun.COM #define	SHELP_REVERT	"revert"
8111767SAnurag.Maskey@Sun.COM #define	SHELP_SELECT	"select <object-type> [<class>] <object-name>"
8211767SAnurag.Maskey@Sun.COM #define	SHELP_SET	"set <prop-name>=<value1>[,<value2>...]"
8311767SAnurag.Maskey@Sun.COM #define	SHELP_VERIFY	"verify"
8411767SAnurag.Maskey@Sun.COM #define	SHELP_WALK	"walkprop [-a]"
8511767SAnurag.Maskey@Sun.COM 
8611767SAnurag.Maskey@Sun.COM /*
8711767SAnurag.Maskey@Sun.COM  * Scope Definitions:
8811767SAnurag.Maskey@Sun.COM  * Locations, ENMs, NCPs and Known WLANs are one scope level below global (GBL).
8911767SAnurag.Maskey@Sun.COM  * NCUs are one more level beneath the NCP scope.
9011767SAnurag.Maskey@Sun.COM  * Because the commands in Locations/ENM/Known WLAN and NCP level are different,
9111767SAnurag.Maskey@Sun.COM  * the scope are divided accordingly.
9211767SAnurag.Maskey@Sun.COM  *     GBL->LOC, GBL->ENM, GBL->WLAN or GBL->NCP->NCU
9311767SAnurag.Maskey@Sun.COM  */
9411767SAnurag.Maskey@Sun.COM #define	NWAM_SCOPE_GBL	0
9511767SAnurag.Maskey@Sun.COM #define	NWAM_SCOPE_LOC	1
9611767SAnurag.Maskey@Sun.COM #define	NWAM_SCOPE_ENM	2
9711767SAnurag.Maskey@Sun.COM #define	NWAM_SCOPE_WLAN	3
9811767SAnurag.Maskey@Sun.COM #define	NWAM_SCOPE_NCP	4
9911767SAnurag.Maskey@Sun.COM #define	NWAM_SCOPE_NCU	5
10011767SAnurag.Maskey@Sun.COM 
10111767SAnurag.Maskey@Sun.COM /* delimiter used for list of values */
10211767SAnurag.Maskey@Sun.COM #define	NWAM_VALUE_DELIMITER_CHAR	','
10311767SAnurag.Maskey@Sun.COM #define	NWAM_VALUE_DELIMITER_STR	","
10411767SAnurag.Maskey@Sun.COM 
10511767SAnurag.Maskey@Sun.COM /* the max number of values for an enum used by some properties in libnwam */
10611767SAnurag.Maskey@Sun.COM 
10711767SAnurag.Maskey@Sun.COM /*
10811767SAnurag.Maskey@Sun.COM  * All arrays/tables are null-terminated, rather than defining the length of
10911767SAnurag.Maskey@Sun.COM  * the array.  When looping, check for NULL rather than using the size.
11011767SAnurag.Maskey@Sun.COM  */
11111767SAnurag.Maskey@Sun.COM 
11211767SAnurag.Maskey@Sun.COM static struct help helptab[] = {
11311767SAnurag.Maskey@Sun.COM 	{ CMD_CANCEL,	"cancel",	SHELP_CANCEL	},
11411767SAnurag.Maskey@Sun.COM 	{ CMD_CLEAR,	"clear",	SHELP_CLEAR	},
11511767SAnurag.Maskey@Sun.COM 	{ CMD_COMMIT,	"commit",	SHELP_COMMIT	},
11611767SAnurag.Maskey@Sun.COM 	{ CMD_CREATE,	"create",	SHELP_CREATE	},
11711767SAnurag.Maskey@Sun.COM 	{ CMD_DESTROY,	"destroy",	SHELP_DESTROY	},
11811767SAnurag.Maskey@Sun.COM 	{ CMD_END,	"end",		SHELP_END	},
11911767SAnurag.Maskey@Sun.COM 	{ CMD_EXIT,	"exit",		SHELP_EXIT	},
12011767SAnurag.Maskey@Sun.COM 	{ CMD_EXPORT,	"export",	SHELP_EXPORT	},
12111767SAnurag.Maskey@Sun.COM 	{ CMD_GET,	"get",		SHELP_GET	},
12211767SAnurag.Maskey@Sun.COM 	{ CMD_HELP,	"help",		SHELP_HELP	},
12311767SAnurag.Maskey@Sun.COM 	{ CMD_LIST,	"list",		SHELP_LIST	},
12411767SAnurag.Maskey@Sun.COM 	{ CMD_REVERT,	"revert",	SHELP_REVERT	},
12511767SAnurag.Maskey@Sun.COM 	{ CMD_SELECT,	"select",	SHELP_SELECT	},
12611767SAnurag.Maskey@Sun.COM 	{ CMD_SET,	"set",		SHELP_SET	},
12711767SAnurag.Maskey@Sun.COM 	{ CMD_VERIFY,	"verify",	SHELP_VERIFY	},
12811767SAnurag.Maskey@Sun.COM 	{ CMD_WALKPROP,	"walkprop",	SHELP_WALK	},
12911767SAnurag.Maskey@Sun.COM 	{ 0, NULL, NULL }
13011767SAnurag.Maskey@Sun.COM };
13111767SAnurag.Maskey@Sun.COM 
13211767SAnurag.Maskey@Sun.COM /* These *must* match the order of the RT1_ define's from nwamcfg.h */
13311767SAnurag.Maskey@Sun.COM static char *res1_types[] = {
13411767SAnurag.Maskey@Sun.COM 	"unknown",
13511767SAnurag.Maskey@Sun.COM 	"loc",
13611767SAnurag.Maskey@Sun.COM 	"ncp",
13711767SAnurag.Maskey@Sun.COM 	"enm",
13811767SAnurag.Maskey@Sun.COM 	"wlan",
13911767SAnurag.Maskey@Sun.COM 	NULL
14011767SAnurag.Maskey@Sun.COM };
14111767SAnurag.Maskey@Sun.COM 
14211767SAnurag.Maskey@Sun.COM /* These *must* match the order of the RT2_ define's from nwamcfg.h */
14311767SAnurag.Maskey@Sun.COM static char *res2_types[] = {
14411767SAnurag.Maskey@Sun.COM 	"unknown",
14511767SAnurag.Maskey@Sun.COM 	"ncu",
14611767SAnurag.Maskey@Sun.COM 	NULL
14711767SAnurag.Maskey@Sun.COM };
14811767SAnurag.Maskey@Sun.COM 
14911767SAnurag.Maskey@Sun.COM /*
15011767SAnurag.Maskey@Sun.COM  * No array for NCU_CLASS_.  The #define's in nwamcfg.h matches the
15111767SAnurag.Maskey@Sun.COM  * enum nwam_ncu_class_t in libnwam and thus uses libnwam functions to
15211767SAnurag.Maskey@Sun.COM  * retrieve the string representation.
15311767SAnurag.Maskey@Sun.COM  */
15411767SAnurag.Maskey@Sun.COM 
15511767SAnurag.Maskey@Sun.COM /* These *MUST* match the order of the PT_ define's from nwamcfg.h */
15611767SAnurag.Maskey@Sun.COM static char *pt_types[] = {
15711767SAnurag.Maskey@Sun.COM 	"unknown",
15811767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_ACTIVATION_MODE,
15911767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_ENABLED,
16011767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_TYPE,
16111767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_CLASS,
16211767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_PARENT_NCP,
16311767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_PRIORITY_GROUP,
16411767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_PRIORITY_MODE,
16511767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_LINK_MAC_ADDR,
16611767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_LINK_AUTOPUSH,
16711767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_LINK_MTU,
16811767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_IP_VERSION,
16911767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_IPV4_ADDRSRC,
17011767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_IPV4_ADDR,
17111767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE,
17211767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_IPV6_ADDRSRC,
17311767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_IPV6_ADDR,
17411767SAnurag.Maskey@Sun.COM 	NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE,
17511767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_CONDITIONS,
17611767SAnurag.Maskey@Sun.COM 	NWAM_ENM_PROP_FMRI,
17711767SAnurag.Maskey@Sun.COM 	NWAM_ENM_PROP_START,
17811767SAnurag.Maskey@Sun.COM 	NWAM_ENM_PROP_STOP,
17911767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_NAMESERVICES,
18011767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE,
18111767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC,
18211767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_DNS_NAMESERVICE_DOMAIN,
18311767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_DNS_NAMESERVICE_SERVERS,
18411767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_DNS_NAMESERVICE_SEARCH,
18511767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC,
18611767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_NIS_NAMESERVICE_SERVERS,
18711767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC,
18811767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS,
18911767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_DEFAULT_DOMAIN,
19011767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_NFSV4_DOMAIN,
19111767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_IPFILTER_CONFIG_FILE,
19211767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_IPFILTER_V6_CONFIG_FILE,
19311767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_IPNAT_CONFIG_FILE,
19411767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_IPPOOL_CONFIG_FILE,
19511767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_IKE_CONFIG_FILE,
19611767SAnurag.Maskey@Sun.COM 	NWAM_LOC_PROP_IPSECPOLICY_CONFIG_FILE,
19711767SAnurag.Maskey@Sun.COM 	NWAM_KNOWN_WLAN_PROP_BSSIDS,
19811767SAnurag.Maskey@Sun.COM 	NWAM_KNOWN_WLAN_PROP_PRIORITY,
19911767SAnurag.Maskey@Sun.COM 	NWAM_KNOWN_WLAN_PROP_KEYNAME,
20011767SAnurag.Maskey@Sun.COM 	NWAM_KNOWN_WLAN_PROP_KEYSLOT,
20111767SAnurag.Maskey@Sun.COM 	NWAM_KNOWN_WLAN_PROP_SECURITY_MODE
20211767SAnurag.Maskey@Sun.COM };
20311767SAnurag.Maskey@Sun.COM 
20411767SAnurag.Maskey@Sun.COM /* properties table: maps PT_* constants to property names */
20511767SAnurag.Maskey@Sun.COM typedef struct prop_table_entry {
20611767SAnurag.Maskey@Sun.COM 	int			pte_type;
20711767SAnurag.Maskey@Sun.COM 	const char		*pte_name;
20811767SAnurag.Maskey@Sun.COM } prop_table_entry_t;
20911767SAnurag.Maskey@Sun.COM 
21011767SAnurag.Maskey@Sun.COM /* NCU properties table */
21111767SAnurag.Maskey@Sun.COM static prop_table_entry_t ncu_prop_table[] = {
21211767SAnurag.Maskey@Sun.COM 	{ PT_TYPE, 			NWAM_NCU_PROP_TYPE },
21311767SAnurag.Maskey@Sun.COM 	{ PT_CLASS, 			NWAM_NCU_PROP_CLASS },
21411767SAnurag.Maskey@Sun.COM 	{ PT_PARENT, 			NWAM_NCU_PROP_PARENT_NCP },
21511767SAnurag.Maskey@Sun.COM 	{ PT_ACTIVATION_MODE,		NWAM_NCU_PROP_ACTIVATION_MODE },
21611767SAnurag.Maskey@Sun.COM 	{ PT_ENABLED, 			NWAM_NCU_PROP_ENABLED },
21711767SAnurag.Maskey@Sun.COM 	{ PT_PRIORITY_GROUP, 		NWAM_NCU_PROP_PRIORITY_GROUP },
21811767SAnurag.Maskey@Sun.COM 	{ PT_PRIORITY_MODE,		NWAM_NCU_PROP_PRIORITY_MODE },
21911767SAnurag.Maskey@Sun.COM 	{ PT_LINK_MACADDR, 		NWAM_NCU_PROP_LINK_MAC_ADDR },
22011767SAnurag.Maskey@Sun.COM 	{ PT_LINK_AUTOPUSH, 		NWAM_NCU_PROP_LINK_AUTOPUSH },
22111767SAnurag.Maskey@Sun.COM 	{ PT_LINK_MTU, 			NWAM_NCU_PROP_LINK_MTU },
22211767SAnurag.Maskey@Sun.COM 	{ PT_IP_VERSION, 		NWAM_NCU_PROP_IP_VERSION },
22311767SAnurag.Maskey@Sun.COM 	{ PT_IPV4_ADDRSRC, 		NWAM_NCU_PROP_IPV4_ADDRSRC },
22411767SAnurag.Maskey@Sun.COM 	{ PT_IPV4_ADDR, 		NWAM_NCU_PROP_IPV4_ADDR },
22511767SAnurag.Maskey@Sun.COM 	{ PT_IPV4_DEFAULT_ROUTE,	NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE },
22611767SAnurag.Maskey@Sun.COM 	{ PT_IPV6_ADDRSRC, 		NWAM_NCU_PROP_IPV6_ADDRSRC },
22711767SAnurag.Maskey@Sun.COM 	{ PT_IPV6_ADDR, 		NWAM_NCU_PROP_IPV6_ADDR },
22811767SAnurag.Maskey@Sun.COM 	{ PT_IPV6_DEFAULT_ROUTE,	NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE },
22911767SAnurag.Maskey@Sun.COM 	{ 0, NULL }
23011767SAnurag.Maskey@Sun.COM };
23111767SAnurag.Maskey@Sun.COM 
23211767SAnurag.Maskey@Sun.COM /* ENM properties table */
23311767SAnurag.Maskey@Sun.COM static prop_table_entry_t enm_prop_table[] = {
23411767SAnurag.Maskey@Sun.COM 	{ PT_ENM_FMRI, 		NWAM_ENM_PROP_FMRI },
23511767SAnurag.Maskey@Sun.COM 	{ PT_ENM_START, 	NWAM_ENM_PROP_START },
23611767SAnurag.Maskey@Sun.COM 	{ PT_ENM_STOP, 		NWAM_ENM_PROP_STOP },
23711767SAnurag.Maskey@Sun.COM 	{ PT_ACTIVATION_MODE, 	NWAM_ENM_PROP_ACTIVATION_MODE },
23811767SAnurag.Maskey@Sun.COM 	{ PT_CONDITIONS, 	NWAM_ENM_PROP_CONDITIONS },
23911767SAnurag.Maskey@Sun.COM 	{ PT_ENABLED, 		NWAM_ENM_PROP_ENABLED },
24011767SAnurag.Maskey@Sun.COM 	{ 0, NULL }
24111767SAnurag.Maskey@Sun.COM };
24211767SAnurag.Maskey@Sun.COM 
24311767SAnurag.Maskey@Sun.COM /* LOCation properties table */
24411767SAnurag.Maskey@Sun.COM static prop_table_entry_t loc_prop_table[] = {
24511767SAnurag.Maskey@Sun.COM 	{ PT_ACTIVATION_MODE, 	NWAM_LOC_PROP_ACTIVATION_MODE },
24611767SAnurag.Maskey@Sun.COM 	{ PT_CONDITIONS, 	NWAM_LOC_PROP_CONDITIONS },
24711767SAnurag.Maskey@Sun.COM 	{ PT_ENABLED, 		NWAM_LOC_PROP_ENABLED },
24811767SAnurag.Maskey@Sun.COM 	{ PT_LOC_NAMESERVICES, 	NWAM_LOC_PROP_NAMESERVICES },
24911767SAnurag.Maskey@Sun.COM 	{ PT_LOC_NAMESERVICES_CONFIG, NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE },
25011767SAnurag.Maskey@Sun.COM 	{ PT_LOC_DNS_CONFIGSRC, NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC },
25111767SAnurag.Maskey@Sun.COM 	{ PT_LOC_DNS_DOMAIN, 	NWAM_LOC_PROP_DNS_NAMESERVICE_DOMAIN },
25211767SAnurag.Maskey@Sun.COM 	{ PT_LOC_DNS_SERVERS, 	NWAM_LOC_PROP_DNS_NAMESERVICE_SERVERS },
25311767SAnurag.Maskey@Sun.COM 	{ PT_LOC_DNS_SEARCH, 	NWAM_LOC_PROP_DNS_NAMESERVICE_SEARCH },
25411767SAnurag.Maskey@Sun.COM 	{ PT_LOC_NIS_CONFIGSRC, NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC },
25511767SAnurag.Maskey@Sun.COM 	{ PT_LOC_NIS_SERVERS, 	NWAM_LOC_PROP_NIS_NAMESERVICE_SERVERS },
25611767SAnurag.Maskey@Sun.COM 	{ PT_LOC_LDAP_CONFIGSRC, NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC },
25711767SAnurag.Maskey@Sun.COM 	{ PT_LOC_LDAP_SERVERS,	NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS },
25811767SAnurag.Maskey@Sun.COM 	{ PT_LOC_DEFAULT_DOMAIN, NWAM_LOC_PROP_DEFAULT_DOMAIN },
25911767SAnurag.Maskey@Sun.COM 	{ PT_LOC_NFSV4_DOMAIN, 	NWAM_LOC_PROP_NFSV4_DOMAIN },
26011767SAnurag.Maskey@Sun.COM 	{ PT_LOC_IPF_CONFIG, 	NWAM_LOC_PROP_IPFILTER_CONFIG_FILE },
26111767SAnurag.Maskey@Sun.COM 	{ PT_LOC_IPF_V6_CONFIG, NWAM_LOC_PROP_IPFILTER_V6_CONFIG_FILE },
26211767SAnurag.Maskey@Sun.COM 	{ PT_LOC_IPNAT_CONFIG, 	NWAM_LOC_PROP_IPNAT_CONFIG_FILE },
26311767SAnurag.Maskey@Sun.COM 	{ PT_LOC_IPPOOL_CONFIG, NWAM_LOC_PROP_IPPOOL_CONFIG_FILE },
26411767SAnurag.Maskey@Sun.COM 	{ PT_LOC_IKE_CONFIG, 	NWAM_LOC_PROP_IKE_CONFIG_FILE },
26511767SAnurag.Maskey@Sun.COM 	{ PT_LOC_IPSECPOL_CONFIG, NWAM_LOC_PROP_IPSECPOLICY_CONFIG_FILE },
26611767SAnurag.Maskey@Sun.COM 	{ 0, NULL }
26711767SAnurag.Maskey@Sun.COM };
26811767SAnurag.Maskey@Sun.COM 
26911767SAnurag.Maskey@Sun.COM /* Known WLAN properties table */
27011767SAnurag.Maskey@Sun.COM static prop_table_entry_t wlan_prop_table[] = {
27111767SAnurag.Maskey@Sun.COM 	{ PT_WLAN_BSSIDS, 	NWAM_KNOWN_WLAN_PROP_BSSIDS },
27211767SAnurag.Maskey@Sun.COM 	{ PT_WLAN_PRIORITY, 	NWAM_KNOWN_WLAN_PROP_PRIORITY },
27311767SAnurag.Maskey@Sun.COM 	{ PT_WLAN_KEYNAME, 	NWAM_KNOWN_WLAN_PROP_KEYNAME },
27411767SAnurag.Maskey@Sun.COM 	{ PT_WLAN_KEYSLOT, 	NWAM_KNOWN_WLAN_PROP_KEYSLOT },
27511767SAnurag.Maskey@Sun.COM 	{ PT_WLAN_SECURITY_MODE, NWAM_KNOWN_WLAN_PROP_SECURITY_MODE },
27611767SAnurag.Maskey@Sun.COM 	{ 0, NULL }
27711767SAnurag.Maskey@Sun.COM };
27811767SAnurag.Maskey@Sun.COM 
27911767SAnurag.Maskey@Sun.COM /* Returns the appropriate properties table for the given object type */
28011767SAnurag.Maskey@Sun.COM static prop_table_entry_t *
get_prop_table(nwam_object_type_t object_type)28111767SAnurag.Maskey@Sun.COM get_prop_table(nwam_object_type_t object_type)
28211767SAnurag.Maskey@Sun.COM {
28311767SAnurag.Maskey@Sun.COM 	switch (object_type) {
28411767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
28511767SAnurag.Maskey@Sun.COM 		return (ncu_prop_table);
28611767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
28711767SAnurag.Maskey@Sun.COM 		return (loc_prop_table);
28811767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
28911767SAnurag.Maskey@Sun.COM 		return (enm_prop_table);
29011767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
29111767SAnurag.Maskey@Sun.COM 		return (wlan_prop_table);
29211767SAnurag.Maskey@Sun.COM 	}
29311767SAnurag.Maskey@Sun.COM 	return (NULL);
29411767SAnurag.Maskey@Sun.COM }
29511767SAnurag.Maskey@Sun.COM 
29611767SAnurag.Maskey@Sun.COM /* Global variables */
29711767SAnurag.Maskey@Sun.COM 
29811767SAnurag.Maskey@Sun.COM /* set early in main(), never modified thereafter, used all over the place */
29911767SAnurag.Maskey@Sun.COM static char *execname;
30011767SAnurag.Maskey@Sun.COM 
30111767SAnurag.Maskey@Sun.COM /* set in modifying functions, checked in read_input() */
30211767SAnurag.Maskey@Sun.COM boolean_t saw_error = B_FALSE;
30311767SAnurag.Maskey@Sun.COM 
30411767SAnurag.Maskey@Sun.COM /* set in yacc parser, checked in read_input() */
30511767SAnurag.Maskey@Sun.COM boolean_t newline_terminated;
30611767SAnurag.Maskey@Sun.COM 
30711767SAnurag.Maskey@Sun.COM /* set in main(), checked in lex error handler */
30811767SAnurag.Maskey@Sun.COM boolean_t cmd_file_mode = B_FALSE;
30911767SAnurag.Maskey@Sun.COM 
31011767SAnurag.Maskey@Sun.COM /* set in exit_func(), checked in read_input() */
31111767SAnurag.Maskey@Sun.COM static boolean_t time_to_exit = B_FALSE;
31211767SAnurag.Maskey@Sun.COM 
31311767SAnurag.Maskey@Sun.COM /* used in nerr() and nwamerr() */
31411767SAnurag.Maskey@Sun.COM static char *cmd_file_name = NULL;
31511767SAnurag.Maskey@Sun.COM 
31611767SAnurag.Maskey@Sun.COM /* used with cmd_file to destroy all configurations */
31711767SAnurag.Maskey@Sun.COM static boolean_t remove_all_configurations = B_FALSE;
31811767SAnurag.Maskey@Sun.COM 
31911767SAnurag.Maskey@Sun.COM /* checked in read_input() and other places */
32011767SAnurag.Maskey@Sun.COM static boolean_t ok_to_prompt = B_FALSE;
32111767SAnurag.Maskey@Sun.COM 
32211767SAnurag.Maskey@Sun.COM /* initialized in do_interactive(), checked in initialize() */
32311767SAnurag.Maskey@Sun.COM static boolean_t interactive_mode;
32411767SAnurag.Maskey@Sun.COM 
32511767SAnurag.Maskey@Sun.COM static boolean_t need_to_commit = B_FALSE;
32611767SAnurag.Maskey@Sun.COM 
32711767SAnurag.Maskey@Sun.COM /* The gl_get_line() resource object */
32811767SAnurag.Maskey@Sun.COM static GetLine *gl;
32911767SAnurag.Maskey@Sun.COM 
33011767SAnurag.Maskey@Sun.COM /* set when create or read objects, used by other func */
33111767SAnurag.Maskey@Sun.COM static nwam_loc_handle_t loc_h = NULL;
33211767SAnurag.Maskey@Sun.COM static nwam_enm_handle_t enm_h = NULL;
33311767SAnurag.Maskey@Sun.COM static nwam_known_wlan_handle_t wlan_h = NULL;
33411767SAnurag.Maskey@Sun.COM static nwam_ncu_handle_t ncu_h = NULL;
33511767SAnurag.Maskey@Sun.COM static nwam_ncp_handle_t ncp_h = NULL;
33611767SAnurag.Maskey@Sun.COM 
33711767SAnurag.Maskey@Sun.COM static int current_scope = NWAM_SCOPE_GBL;
33811767SAnurag.Maskey@Sun.COM 
33911767SAnurag.Maskey@Sun.COM /* obj1_* are used in NWAM_SCOPE_{NCP,LOC,ENM,WLAN} */
34011767SAnurag.Maskey@Sun.COM static int obj1_type;
34111767SAnurag.Maskey@Sun.COM static char obj1_name[NWAM_MAX_NAME_LEN + 1];
34211767SAnurag.Maskey@Sun.COM 
34311767SAnurag.Maskey@Sun.COM /* obj2_* are used in NWAM_SCOPE_NCU only */
34411767SAnurag.Maskey@Sun.COM static int obj2_type;
34511767SAnurag.Maskey@Sun.COM static char obj2_name[NWAM_MAX_NAME_LEN + 1];
34611767SAnurag.Maskey@Sun.COM 
34711767SAnurag.Maskey@Sun.COM /* arrays for tab-completion */
34811767SAnurag.Maskey@Sun.COM /* commands at NWAM_SCOPE_GBL */
34911767SAnurag.Maskey@Sun.COM static const char *global_scope_cmds[] = {
35011767SAnurag.Maskey@Sun.COM 	"create ",
35111767SAnurag.Maskey@Sun.COM 	"destroy ",
35211767SAnurag.Maskey@Sun.COM 	"end ",
35311767SAnurag.Maskey@Sun.COM 	"exit ",
35411767SAnurag.Maskey@Sun.COM 	"export ",
35511767SAnurag.Maskey@Sun.COM 	"help ",
35611767SAnurag.Maskey@Sun.COM 	"list ",
35711767SAnurag.Maskey@Sun.COM 	"select ",
35811767SAnurag.Maskey@Sun.COM 	NULL
35911767SAnurag.Maskey@Sun.COM };
36011767SAnurag.Maskey@Sun.COM 
36111767SAnurag.Maskey@Sun.COM static const char *global_create_cmds[] = {
36211767SAnurag.Maskey@Sun.COM 	"create loc ",
36311767SAnurag.Maskey@Sun.COM 	"create enm ",
36411767SAnurag.Maskey@Sun.COM 	"create ncp ",
36511767SAnurag.Maskey@Sun.COM 	"create wlan ",
36611767SAnurag.Maskey@Sun.COM 	"create -t ",		/* template */
36711767SAnurag.Maskey@Sun.COM 	NULL
36811767SAnurag.Maskey@Sun.COM };
36911767SAnurag.Maskey@Sun.COM 
37011767SAnurag.Maskey@Sun.COM static const char *global_destroy_cmds[] = {
37111767SAnurag.Maskey@Sun.COM 	"destroy -a ",
37211767SAnurag.Maskey@Sun.COM 	"destroy loc ",
37311767SAnurag.Maskey@Sun.COM 	"destroy enm ",
37411767SAnurag.Maskey@Sun.COM 	"destroy ncp ",
37511767SAnurag.Maskey@Sun.COM 	"destroy wlan ",
37611767SAnurag.Maskey@Sun.COM 	NULL
37711767SAnurag.Maskey@Sun.COM };
37811767SAnurag.Maskey@Sun.COM 
37911767SAnurag.Maskey@Sun.COM static const char *global_export_cmds[] = {
38011767SAnurag.Maskey@Sun.COM 	"export ",
38111767SAnurag.Maskey@Sun.COM 	"export -d ",		/* add destroy -a */
38211767SAnurag.Maskey@Sun.COM 	"export -f ",		/* to file */
38311767SAnurag.Maskey@Sun.COM 	"export -d -f ",	/* add destroy -a to file */
38411767SAnurag.Maskey@Sun.COM 	"export loc ",
38511767SAnurag.Maskey@Sun.COM 	"export enm ",
38611767SAnurag.Maskey@Sun.COM 	"export ncp ",
38711767SAnurag.Maskey@Sun.COM 	"export wlan ",
38811767SAnurag.Maskey@Sun.COM 	NULL
38911767SAnurag.Maskey@Sun.COM };
39011767SAnurag.Maskey@Sun.COM 
39111767SAnurag.Maskey@Sun.COM static const char *global_list_cmds[] = {
39211767SAnurag.Maskey@Sun.COM 	"list ",
39311767SAnurag.Maskey@Sun.COM 	"list loc ",
39411767SAnurag.Maskey@Sun.COM 	"list enm ",
39511767SAnurag.Maskey@Sun.COM 	"list ncp ",
39611767SAnurag.Maskey@Sun.COM 	"list wlan ",
39711767SAnurag.Maskey@Sun.COM 	"list -a loc ",
39811767SAnurag.Maskey@Sun.COM 	"list -a enm ",
39911767SAnurag.Maskey@Sun.COM 	"list -a wlan ",
40011767SAnurag.Maskey@Sun.COM 	NULL
40111767SAnurag.Maskey@Sun.COM };
40211767SAnurag.Maskey@Sun.COM 
40311767SAnurag.Maskey@Sun.COM static const char *global_select_cmds[] = {
40411767SAnurag.Maskey@Sun.COM 	"select loc ",
40511767SAnurag.Maskey@Sun.COM 	"select enm ",
40611767SAnurag.Maskey@Sun.COM 	"select ncp ",
40711767SAnurag.Maskey@Sun.COM 	"select wlan ",
40811767SAnurag.Maskey@Sun.COM 	NULL
40911767SAnurag.Maskey@Sun.COM };
41011767SAnurag.Maskey@Sun.COM 
41111767SAnurag.Maskey@Sun.COM /* commands at NWAM_SCOPE_LOC, _ENM, _WLAN and _NCU */
41211767SAnurag.Maskey@Sun.COM static const char *non_ncp_scope_cmds[] = {
41311767SAnurag.Maskey@Sun.COM 	"cancel ",
41411767SAnurag.Maskey@Sun.COM 	"clear ",
41511767SAnurag.Maskey@Sun.COM 	"commit ",
41611767SAnurag.Maskey@Sun.COM 	"end ",
41711767SAnurag.Maskey@Sun.COM 	"exit ",
41811767SAnurag.Maskey@Sun.COM 	"export ",
41911767SAnurag.Maskey@Sun.COM 	"export -f ",
42011767SAnurag.Maskey@Sun.COM 	"get ",
42111767SAnurag.Maskey@Sun.COM 	"get -V ",	/* value only */
42211767SAnurag.Maskey@Sun.COM 	"help ",
42311767SAnurag.Maskey@Sun.COM 	"list ",
42411767SAnurag.Maskey@Sun.COM 	"list -a ",	/* all properties */
42511767SAnurag.Maskey@Sun.COM 	"revert ",
42611767SAnurag.Maskey@Sun.COM 	"set ",
42711767SAnurag.Maskey@Sun.COM 	"verify ",
42811767SAnurag.Maskey@Sun.COM 	"walkprop ",
42911767SAnurag.Maskey@Sun.COM 	"walkprop -a ",	/* all properties */
43011767SAnurag.Maskey@Sun.COM 	NULL
43111767SAnurag.Maskey@Sun.COM };
43211767SAnurag.Maskey@Sun.COM 
43311767SAnurag.Maskey@Sun.COM /* commands at NWAM_SCOPE_NCP */
43411767SAnurag.Maskey@Sun.COM static const char *ncp_scope_cmds[] = {
43511767SAnurag.Maskey@Sun.COM 	"cancel ",
43611767SAnurag.Maskey@Sun.COM 	"create ",
43711767SAnurag.Maskey@Sun.COM 	"destroy ",
43811767SAnurag.Maskey@Sun.COM 	"end ",
43911767SAnurag.Maskey@Sun.COM 	"exit ",
44011767SAnurag.Maskey@Sun.COM 	"export ",
44111767SAnurag.Maskey@Sun.COM 	"help ",
44211767SAnurag.Maskey@Sun.COM 	"list ",
44311767SAnurag.Maskey@Sun.COM 	"select ",
44411767SAnurag.Maskey@Sun.COM 	NULL
44511767SAnurag.Maskey@Sun.COM };
44611767SAnurag.Maskey@Sun.COM 
44711767SAnurag.Maskey@Sun.COM static const char *ncp_create_cmds[] = {
44811767SAnurag.Maskey@Sun.COM 	"create ncu ip ",
44911767SAnurag.Maskey@Sun.COM 	"create ncu phys ",
45011767SAnurag.Maskey@Sun.COM 	"create -t ",		/* template */
45111767SAnurag.Maskey@Sun.COM 	NULL
45211767SAnurag.Maskey@Sun.COM };
45311767SAnurag.Maskey@Sun.COM 
45411767SAnurag.Maskey@Sun.COM static const char *ncp_destroy_cmds[] = {
45511767SAnurag.Maskey@Sun.COM 	"destroy ncu ",
45611767SAnurag.Maskey@Sun.COM 	"destroy ncu ip ",
45711767SAnurag.Maskey@Sun.COM 	"destroy ncu phys ",
45811767SAnurag.Maskey@Sun.COM 	NULL
45911767SAnurag.Maskey@Sun.COM };
46011767SAnurag.Maskey@Sun.COM 
46111767SAnurag.Maskey@Sun.COM static const char *ncp_export_cmds[] = {
46211767SAnurag.Maskey@Sun.COM 	"export ",
46311767SAnurag.Maskey@Sun.COM 	"export -f ",		/* to file */
46411767SAnurag.Maskey@Sun.COM 	"export ncu ",
46511767SAnurag.Maskey@Sun.COM 	"export ncu ip ",
46611767SAnurag.Maskey@Sun.COM 	"export ncu phys ",
46711767SAnurag.Maskey@Sun.COM 	NULL
46811767SAnurag.Maskey@Sun.COM };
46911767SAnurag.Maskey@Sun.COM 
47011767SAnurag.Maskey@Sun.COM static const char *ncp_list_cmds[] = {
47111767SAnurag.Maskey@Sun.COM 	"list ",
47211767SAnurag.Maskey@Sun.COM 	"list ncu ",
47311767SAnurag.Maskey@Sun.COM 	"list ncu ip ",
47411767SAnurag.Maskey@Sun.COM 	"list ncu phys ",
47511767SAnurag.Maskey@Sun.COM 	"list -a ncu ",
47611767SAnurag.Maskey@Sun.COM 	"list -a ncu ip ",
47711767SAnurag.Maskey@Sun.COM 	"list -a ncu phys ",
47811767SAnurag.Maskey@Sun.COM 	NULL
47911767SAnurag.Maskey@Sun.COM };
48011767SAnurag.Maskey@Sun.COM 
48111767SAnurag.Maskey@Sun.COM static const char *ncp_select_cmds[] = {
48211767SAnurag.Maskey@Sun.COM 	"select ncu ",
48311767SAnurag.Maskey@Sun.COM 	"select ncu ip ",
48411767SAnurag.Maskey@Sun.COM 	"select ncu phys ",
48511767SAnurag.Maskey@Sun.COM 	NULL
48611767SAnurag.Maskey@Sun.COM };
48711767SAnurag.Maskey@Sun.COM 
48811767SAnurag.Maskey@Sun.COM /* Functions begin here */
48911767SAnurag.Maskey@Sun.COM 
49011767SAnurag.Maskey@Sun.COM cmd_t *
alloc_cmd(void)49111767SAnurag.Maskey@Sun.COM alloc_cmd(void)
49211767SAnurag.Maskey@Sun.COM {
49311767SAnurag.Maskey@Sun.COM 	cmd_t *cmd = calloc(1, sizeof (cmd_t));
49411767SAnurag.Maskey@Sun.COM 	if (cmd == NULL) {
49511767SAnurag.Maskey@Sun.COM 		nerr("Out of memory");
49611767SAnurag.Maskey@Sun.COM 		return (NULL);
49711767SAnurag.Maskey@Sun.COM 	}
49811767SAnurag.Maskey@Sun.COM 	cmd->cmd_argc = 0;
49911767SAnurag.Maskey@Sun.COM 	cmd->cmd_argv[0] = NULL;
50011767SAnurag.Maskey@Sun.COM 
50111767SAnurag.Maskey@Sun.COM 	return (cmd);
50211767SAnurag.Maskey@Sun.COM }
50311767SAnurag.Maskey@Sun.COM 
50411767SAnurag.Maskey@Sun.COM void
free_cmd(cmd_t * cmd)50511767SAnurag.Maskey@Sun.COM free_cmd(cmd_t *cmd)
50611767SAnurag.Maskey@Sun.COM {
50711767SAnurag.Maskey@Sun.COM 	int i;
50811767SAnurag.Maskey@Sun.COM 
50911767SAnurag.Maskey@Sun.COM 	for (i = 0; i < cmd->cmd_argc; i++)
51011767SAnurag.Maskey@Sun.COM 		free(cmd->cmd_argv[i]);
51111767SAnurag.Maskey@Sun.COM 	free(cmd);
51211767SAnurag.Maskey@Sun.COM }
51311767SAnurag.Maskey@Sun.COM 
51411767SAnurag.Maskey@Sun.COM void
array_free(void ** array,int nelem)51511767SAnurag.Maskey@Sun.COM array_free(void **array, int nelem)
51611767SAnurag.Maskey@Sun.COM {
51711767SAnurag.Maskey@Sun.COM 	int i;
51811767SAnurag.Maskey@Sun.COM 	for (i = 0; i < nelem; i++)
51911767SAnurag.Maskey@Sun.COM 		free(array[i]);
52011767SAnurag.Maskey@Sun.COM 	free(array);
52111767SAnurag.Maskey@Sun.COM }
52211767SAnurag.Maskey@Sun.COM 
52311767SAnurag.Maskey@Sun.COM static boolean_t
initial_match(const char * line1,const char * line2,int word_end)52411767SAnurag.Maskey@Sun.COM initial_match(const char *line1, const char *line2, int word_end)
52511767SAnurag.Maskey@Sun.COM {
52611767SAnurag.Maskey@Sun.COM 	if (word_end <= 0)
52711767SAnurag.Maskey@Sun.COM 		return (B_TRUE);
52811767SAnurag.Maskey@Sun.COM 	return (strncmp(line1, line2, word_end) == 0);
52911767SAnurag.Maskey@Sun.COM }
53011767SAnurag.Maskey@Sun.COM 
53111767SAnurag.Maskey@Sun.COM static int
add_stuff(WordCompletion * cpl,const char * line1,const char ** list,int word_end)53211767SAnurag.Maskey@Sun.COM add_stuff(WordCompletion *cpl, const char *line1, const char **list,
53311767SAnurag.Maskey@Sun.COM     int word_end)
53411767SAnurag.Maskey@Sun.COM {
53511767SAnurag.Maskey@Sun.COM 	int i, err;
53611767SAnurag.Maskey@Sun.COM 
53711767SAnurag.Maskey@Sun.COM 	for (i = 0; list[i] != NULL; i++) {
53811767SAnurag.Maskey@Sun.COM 		if (initial_match(line1, list[i], word_end)) {
53911767SAnurag.Maskey@Sun.COM 			err = cpl_add_completion(cpl, line1, 0, word_end,
54011767SAnurag.Maskey@Sun.COM 			    list[i] + word_end, "", "");
54111767SAnurag.Maskey@Sun.COM 			if (err != 0)
54211767SAnurag.Maskey@Sun.COM 				return (err);
54311767SAnurag.Maskey@Sun.COM 		}
54411767SAnurag.Maskey@Sun.COM 	}
54511767SAnurag.Maskey@Sun.COM 	return (0);
54611767SAnurag.Maskey@Sun.COM }
54711767SAnurag.Maskey@Sun.COM 
54811767SAnurag.Maskey@Sun.COM /*
54911767SAnurag.Maskey@Sun.COM  * To fill in the rest of a string when user types the tab key.
55011767SAnurag.Maskey@Sun.COM  * First digital number is the length of the string, the second digital number
55111767SAnurag.Maskey@Sun.COM  * is the min number of chars that is needed to uniquely identify a string.
55211767SAnurag.Maskey@Sun.COM  */
55311767SAnurag.Maskey@Sun.COM #define	MINI_STR(l, s, m, n) strncmp(l, s, MAX(MIN(sizeof (s) - 1, m), n))
55411767SAnurag.Maskey@Sun.COM 
55511767SAnurag.Maskey@Sun.COM /* ARGSUSED */
55611767SAnurag.Maskey@Sun.COM static
CPL_MATCH_FN(cmd_cpl_fn)55711767SAnurag.Maskey@Sun.COM CPL_MATCH_FN(cmd_cpl_fn)
55811767SAnurag.Maskey@Sun.COM {
55911767SAnurag.Maskey@Sun.COM 	/* tab-complete according to the current scope */
56011767SAnurag.Maskey@Sun.COM 	switch (current_scope) {
56111767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_GBL:
56211767SAnurag.Maskey@Sun.COM 		if (MINI_STR(line, "create ", word_end, 2) == 0)
56311767SAnurag.Maskey@Sun.COM 			return (add_stuff(cpl, line, global_create_cmds,
56411767SAnurag.Maskey@Sun.COM 			    word_end));
56511767SAnurag.Maskey@Sun.COM 		if (MINI_STR(line, "destroy ", word_end, 1) == 0)
56611767SAnurag.Maskey@Sun.COM 			return (add_stuff(cpl, line, global_destroy_cmds,
56711767SAnurag.Maskey@Sun.COM 			    word_end));
56811767SAnurag.Maskey@Sun.COM 		if (MINI_STR(line, "export ", word_end, 3) == 0)
56911767SAnurag.Maskey@Sun.COM 			return (add_stuff(cpl, line, global_export_cmds,
57011767SAnurag.Maskey@Sun.COM 			    word_end));
57111767SAnurag.Maskey@Sun.COM 		if (MINI_STR(line, "list ", word_end, 1) == 0)
57211767SAnurag.Maskey@Sun.COM 			return (add_stuff(cpl, line, global_list_cmds,
57311767SAnurag.Maskey@Sun.COM 			    word_end));
57411767SAnurag.Maskey@Sun.COM 		if (MINI_STR(line, "select ", word_end, 1) == 0)
57511767SAnurag.Maskey@Sun.COM 			return (add_stuff(cpl, line, global_select_cmds,
57611767SAnurag.Maskey@Sun.COM 			    word_end));
57711767SAnurag.Maskey@Sun.COM 		return (add_stuff(cpl, line, global_scope_cmds, word_end));
57811767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_LOC:
57911767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_ENM:
58011767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_WLAN:
58111767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_NCU:
58211767SAnurag.Maskey@Sun.COM 		return (add_stuff(cpl, line, non_ncp_scope_cmds, word_end));
58311767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_NCP:
58411767SAnurag.Maskey@Sun.COM 		if (MINI_STR(line, "create ", word_end, 2) == 0)
58511767SAnurag.Maskey@Sun.COM 			return (add_stuff(cpl, line, ncp_create_cmds,
58611767SAnurag.Maskey@Sun.COM 			    word_end));
58711767SAnurag.Maskey@Sun.COM 		if (MINI_STR(line, "destroy ", word_end, 1) == 0)
58811767SAnurag.Maskey@Sun.COM 			return (add_stuff(cpl, line, ncp_destroy_cmds,
58911767SAnurag.Maskey@Sun.COM 			    word_end));
59011767SAnurag.Maskey@Sun.COM 		if (MINI_STR(line, "export ", word_end, 3) == 0)
59111767SAnurag.Maskey@Sun.COM 			return (add_stuff(cpl, line, ncp_export_cmds,
59211767SAnurag.Maskey@Sun.COM 			    word_end));
59311767SAnurag.Maskey@Sun.COM 		if (MINI_STR(line, "list ", word_end, 1) == 0)
59411767SAnurag.Maskey@Sun.COM 			return (add_stuff(cpl, line, ncp_list_cmds, word_end));
59511767SAnurag.Maskey@Sun.COM 		if (MINI_STR(line, "select ", word_end, 1) == 0)
59611767SAnurag.Maskey@Sun.COM 			return (add_stuff(cpl, line, ncp_select_cmds,
59711767SAnurag.Maskey@Sun.COM 			    word_end));
59811767SAnurag.Maskey@Sun.COM 		return (add_stuff(cpl, line, ncp_scope_cmds, word_end));
59911767SAnurag.Maskey@Sun.COM 	}
60011767SAnurag.Maskey@Sun.COM 	/* should never get here */
60111767SAnurag.Maskey@Sun.COM 	return (NULL);
60211767SAnurag.Maskey@Sun.COM }
60311767SAnurag.Maskey@Sun.COM 
60411767SAnurag.Maskey@Sun.COM const char *
cmd_to_str(int cmd_num)60511767SAnurag.Maskey@Sun.COM cmd_to_str(int cmd_num)
60611767SAnurag.Maskey@Sun.COM {
60711767SAnurag.Maskey@Sun.COM 	assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
60811767SAnurag.Maskey@Sun.COM 	return (helptab[cmd_num].cmd_name);
60911767SAnurag.Maskey@Sun.COM }
61011767SAnurag.Maskey@Sun.COM 
61111767SAnurag.Maskey@Sun.COM /* Returns "loc", "enm", "wlan" or "ncp" as string */
61211767SAnurag.Maskey@Sun.COM static const char *
rt1_to_str(int res_type)61311767SAnurag.Maskey@Sun.COM rt1_to_str(int res_type)
61411767SAnurag.Maskey@Sun.COM {
61511767SAnurag.Maskey@Sun.COM 	assert(res_type >= RT1_MIN && res_type <= RT1_MAX);
61611767SAnurag.Maskey@Sun.COM 	return (res1_types[res_type]);
61711767SAnurag.Maskey@Sun.COM }
61811767SAnurag.Maskey@Sun.COM 
61911767SAnurag.Maskey@Sun.COM /* Returns "ncu" as string */
62011767SAnurag.Maskey@Sun.COM static const char *
rt2_to_str(int res_type)62111767SAnurag.Maskey@Sun.COM rt2_to_str(int res_type)
62211767SAnurag.Maskey@Sun.COM {
62311767SAnurag.Maskey@Sun.COM 	assert(res_type >= RT2_MIN && res_type <= RT2_MAX);
62411767SAnurag.Maskey@Sun.COM 	return (res2_types[res_type]);
62511767SAnurag.Maskey@Sun.COM }
62611767SAnurag.Maskey@Sun.COM 
62711767SAnurag.Maskey@Sun.COM /* Returns "ncp, "ncu", "loc", "enm", or "wlan" according to the scope */
62811767SAnurag.Maskey@Sun.COM static const char *
scope_to_str(int scope)62911767SAnurag.Maskey@Sun.COM scope_to_str(int scope) {
63011767SAnurag.Maskey@Sun.COM 	switch (scope) {
63111767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_GBL:
63211767SAnurag.Maskey@Sun.COM 		return ("global");
63311767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_NCP:
63411767SAnurag.Maskey@Sun.COM 		return ("ncp");
63511767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_NCU:
63611767SAnurag.Maskey@Sun.COM 		return ("ncu");
63711767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_LOC:
63811767SAnurag.Maskey@Sun.COM 		return ("loc");
63911767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_ENM:
64011767SAnurag.Maskey@Sun.COM 		return ("enm");
64111767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_WLAN:
64211767SAnurag.Maskey@Sun.COM 		return ("wlan");
64311767SAnurag.Maskey@Sun.COM 	default:
64411767SAnurag.Maskey@Sun.COM 		return ("invalid");
64511767SAnurag.Maskey@Sun.COM 	}
64611767SAnurag.Maskey@Sun.COM }
64711767SAnurag.Maskey@Sun.COM 
64811767SAnurag.Maskey@Sun.COM /* Given an enm property and value, returns it as a string */
64911767SAnurag.Maskey@Sun.COM static const char *
propval_to_str(const char * propname,uint64_t value)65011767SAnurag.Maskey@Sun.COM propval_to_str(const char *propname, uint64_t value)
65111767SAnurag.Maskey@Sun.COM {
65211767SAnurag.Maskey@Sun.COM 	const char *str;
65311767SAnurag.Maskey@Sun.COM 
65411767SAnurag.Maskey@Sun.COM 	if (nwam_uint64_get_value_string(propname, value, &str) == NWAM_SUCCESS)
65511767SAnurag.Maskey@Sun.COM 		return (str);
65611767SAnurag.Maskey@Sun.COM 	return (NULL);
65711767SAnurag.Maskey@Sun.COM }
65811767SAnurag.Maskey@Sun.COM 
65911767SAnurag.Maskey@Sun.COM /* Given an int for a prop, returns it as string */
66011767SAnurag.Maskey@Sun.COM static const char *
pt_to_str(int prop_type)66111767SAnurag.Maskey@Sun.COM pt_to_str(int prop_type)
66211767SAnurag.Maskey@Sun.COM {
66311767SAnurag.Maskey@Sun.COM 	assert(prop_type >= PT_MIN && prop_type <= PT_MAX);
66411767SAnurag.Maskey@Sun.COM 	return (pt_types[prop_type]);
66511767SAnurag.Maskey@Sun.COM }
66611767SAnurag.Maskey@Sun.COM 
66711767SAnurag.Maskey@Sun.COM /* Return B_TRUE if string starts with "t" or is 1, B_FALSE otherwise */
66811767SAnurag.Maskey@Sun.COM static boolean_t
str_to_boolean(const char * str)66911767SAnurag.Maskey@Sun.COM str_to_boolean(const char *str)
67011767SAnurag.Maskey@Sun.COM {
67111767SAnurag.Maskey@Sun.COM 	if (strncasecmp(str, "t", 1) == 0 || atoi(str) == 1)
67211767SAnurag.Maskey@Sun.COM 		return (B_TRUE);
67311767SAnurag.Maskey@Sun.COM 	else
67411767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
67511767SAnurag.Maskey@Sun.COM }
67611767SAnurag.Maskey@Sun.COM 
67711767SAnurag.Maskey@Sun.COM /*
67811767SAnurag.Maskey@Sun.COM  * This is a separate function rather than a set of define's because of the
67911767SAnurag.Maskey@Sun.COM  * gettext() wrapping.
68011767SAnurag.Maskey@Sun.COM  */
68111767SAnurag.Maskey@Sun.COM 
68211767SAnurag.Maskey@Sun.COM /*
68311767SAnurag.Maskey@Sun.COM  * TRANSLATION_NOTE
68411767SAnurag.Maskey@Sun.COM  * Each string below should have \t follow \n whenever needed; the
68511767SAnurag.Maskey@Sun.COM  * initial \t and the terminal \n will be provided by the calling function.
68611767SAnurag.Maskey@Sun.COM  */
68711767SAnurag.Maskey@Sun.COM 
68811767SAnurag.Maskey@Sun.COM static const char *
long_help(int cmd_num)68911767SAnurag.Maskey@Sun.COM long_help(int cmd_num)
69011767SAnurag.Maskey@Sun.COM {
69111767SAnurag.Maskey@Sun.COM 	assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
69211767SAnurag.Maskey@Sun.COM 	switch (cmd_num) {
69311767SAnurag.Maskey@Sun.COM 		case CMD_CANCEL:
69411767SAnurag.Maskey@Sun.COM 			return (gettext("Cancels the current configuration "
69511767SAnurag.Maskey@Sun.COM 			    "changes."));
69611767SAnurag.Maskey@Sun.COM 		case CMD_CLEAR:
69711767SAnurag.Maskey@Sun.COM 			return (gettext("Clears the value for the specified "
69811767SAnurag.Maskey@Sun.COM 			    "property."));
69911767SAnurag.Maskey@Sun.COM 		case CMD_COMMIT:
70011767SAnurag.Maskey@Sun.COM 			return (gettext("Commits the current configuration."));
70111767SAnurag.Maskey@Sun.COM 		case CMD_CREATE:
70211767SAnurag.Maskey@Sun.COM 			return (gettext("Creates a new profile or resource."));
70311767SAnurag.Maskey@Sun.COM 		case CMD_DESTROY:
70411767SAnurag.Maskey@Sun.COM 			return (gettext("Destroys the specified profile or "
70511767SAnurag.Maskey@Sun.COM 			    "resource."));
70611767SAnurag.Maskey@Sun.COM 		case CMD_END:
70711767SAnurag.Maskey@Sun.COM 			return (gettext("Ends specification of a resource."));
70811767SAnurag.Maskey@Sun.COM 		case CMD_EXIT:
70911767SAnurag.Maskey@Sun.COM 			return (gettext("Exits the program."));
71011767SAnurag.Maskey@Sun.COM 		case CMD_EXPORT:
71111767SAnurag.Maskey@Sun.COM 			return (gettext("Exports the configuration."));
71211767SAnurag.Maskey@Sun.COM 		case CMD_GET:
71311767SAnurag.Maskey@Sun.COM 			return (gettext("Gets the value of the specified "
71411767SAnurag.Maskey@Sun.COM 			    "property."));
71511767SAnurag.Maskey@Sun.COM 		case CMD_HELP:
71611767SAnurag.Maskey@Sun.COM 			return (gettext("Prints help message."));
71711767SAnurag.Maskey@Sun.COM 		case CMD_LIST:
71811767SAnurag.Maskey@Sun.COM 			return (gettext("Lists existing objects."));
71911767SAnurag.Maskey@Sun.COM 		case CMD_REVERT:
72011767SAnurag.Maskey@Sun.COM 			return (gettext("Reverts to the previous "
72111767SAnurag.Maskey@Sun.COM 			    "configuration."));
72211767SAnurag.Maskey@Sun.COM 		case CMD_SELECT:
72311767SAnurag.Maskey@Sun.COM 			return (gettext("Selects a resource to modify."));
72411767SAnurag.Maskey@Sun.COM 		case CMD_SET:
72511767SAnurag.Maskey@Sun.COM 			return (gettext("Sets the value of the specified "
72611767SAnurag.Maskey@Sun.COM 			    "property."));
72711767SAnurag.Maskey@Sun.COM 		case CMD_VERIFY:
72811767SAnurag.Maskey@Sun.COM 			return (gettext("Verifies an object."));
72911767SAnurag.Maskey@Sun.COM 		case CMD_WALKPROP:
73011767SAnurag.Maskey@Sun.COM 			return (gettext("Iterates over properties."));
73111767SAnurag.Maskey@Sun.COM 		default:
73211767SAnurag.Maskey@Sun.COM 			return (gettext("Unknown command."));
73311767SAnurag.Maskey@Sun.COM 	}
73411767SAnurag.Maskey@Sun.COM }
73511767SAnurag.Maskey@Sun.COM 
73611767SAnurag.Maskey@Sun.COM void
command_usage(int command)73711767SAnurag.Maskey@Sun.COM command_usage(int command)
73811767SAnurag.Maskey@Sun.COM {
73911767SAnurag.Maskey@Sun.COM 	if (command < CMD_MIN || command > CMD_MAX) {
74011767SAnurag.Maskey@Sun.COM 		nerr("Unknown command");
74111767SAnurag.Maskey@Sun.COM 	} else {
74211767SAnurag.Maskey@Sun.COM 		nerr("%s: %s: %s", gettext("Error"), gettext("usage"),
74311767SAnurag.Maskey@Sun.COM 		    helptab[command].cmd_usage);
74411767SAnurag.Maskey@Sun.COM 	}
74511767SAnurag.Maskey@Sun.COM }
74611767SAnurag.Maskey@Sun.COM 
74711767SAnurag.Maskey@Sun.COM static void
long_usage(uint_t cmd_num)74811767SAnurag.Maskey@Sun.COM long_usage(uint_t cmd_num)
74911767SAnurag.Maskey@Sun.COM {
75011767SAnurag.Maskey@Sun.COM 	(void) printf("%s: %s\n", gettext("usage"),
75111767SAnurag.Maskey@Sun.COM 	    helptab[cmd_num].cmd_usage);
75211767SAnurag.Maskey@Sun.COM 	(void) printf("\t%s\n", long_help(cmd_num));
75311767SAnurag.Maskey@Sun.COM }
75411767SAnurag.Maskey@Sun.COM 
75511767SAnurag.Maskey@Sun.COM /* Prints usage for command line options */
75611767SAnurag.Maskey@Sun.COM static void
cmd_line_usage()75711767SAnurag.Maskey@Sun.COM cmd_line_usage()
75811767SAnurag.Maskey@Sun.COM {
75911767SAnurag.Maskey@Sun.COM 	(void) printf("%s:\t%s\t\t\t\t(%s)\n", gettext("usage"), execname,
76011767SAnurag.Maskey@Sun.COM 	    gettext("interactive-mode"));
76111767SAnurag.Maskey@Sun.COM 	(void) printf("\t%s <%s> [%s...]\n", execname, gettext("command"),
76211767SAnurag.Maskey@Sun.COM 	    gettext("options"));
76311767SAnurag.Maskey@Sun.COM 	(void) printf("\t%s [-d] -f <%s>\n", execname, gettext("command-file"));
76411767SAnurag.Maskey@Sun.COM 	(void) printf("\t%s %s [<%s>]\n", execname, cmd_to_str(CMD_HELP),
76511767SAnurag.Maskey@Sun.COM 	    gettext("command"));
76611767SAnurag.Maskey@Sun.COM }
76711767SAnurag.Maskey@Sun.COM 
76811767SAnurag.Maskey@Sun.COM /* Prints the line number of the current command if in command-file mode */
76911767SAnurag.Maskey@Sun.COM static void
print_lineno()77011767SAnurag.Maskey@Sun.COM print_lineno()
77111767SAnurag.Maskey@Sun.COM {
77211767SAnurag.Maskey@Sun.COM 	static int last_lineno;
77311767SAnurag.Maskey@Sun.COM 
77411767SAnurag.Maskey@Sun.COM 	/* lex_lineno has already been incremented in the lexer; compensate */
77511767SAnurag.Maskey@Sun.COM 	if (cmd_file_mode && lex_lineno > last_lineno) {
77611767SAnurag.Maskey@Sun.COM 		if (strcmp(cmd_file_name, "-") == 0)
77711767SAnurag.Maskey@Sun.COM 			(void) fprintf(stderr, gettext("On line %d:\n"),
77811767SAnurag.Maskey@Sun.COM 			    lex_lineno - 1);
77911767SAnurag.Maskey@Sun.COM 		else
78011767SAnurag.Maskey@Sun.COM 			(void) fprintf(stderr, gettext("On line %d of %s:\n"),
78111767SAnurag.Maskey@Sun.COM 			    lex_lineno - 1, cmd_file_name);
78211767SAnurag.Maskey@Sun.COM 		last_lineno = lex_lineno;
78311767SAnurag.Maskey@Sun.COM 	}
78411767SAnurag.Maskey@Sun.COM }
78511767SAnurag.Maskey@Sun.COM 
78611767SAnurag.Maskey@Sun.COM /* PRINTFLIKE1 */
78711767SAnurag.Maskey@Sun.COM void
nerr(const char * format,...)78811767SAnurag.Maskey@Sun.COM nerr(const char *format, ...)
78911767SAnurag.Maskey@Sun.COM {
79011767SAnurag.Maskey@Sun.COM 	va_list	alist;
79111767SAnurag.Maskey@Sun.COM 
79211767SAnurag.Maskey@Sun.COM 	print_lineno();
79311767SAnurag.Maskey@Sun.COM 
79411767SAnurag.Maskey@Sun.COM 	format = gettext(format);
79511767SAnurag.Maskey@Sun.COM 	va_start(alist, format);
79611767SAnurag.Maskey@Sun.COM 	(void) vfprintf(stderr, format, alist);
79711767SAnurag.Maskey@Sun.COM 	va_end(alist);
79811767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, "\n");
79911767SAnurag.Maskey@Sun.COM 
80011767SAnurag.Maskey@Sun.COM 	saw_error = B_TRUE;
80111767SAnurag.Maskey@Sun.COM }
80211767SAnurag.Maskey@Sun.COM 
80311767SAnurag.Maskey@Sun.COM /* PRINTFLIKE2 */
80411767SAnurag.Maskey@Sun.COM static void
nwamerr(nwam_error_t err,const char * format,...)80511767SAnurag.Maskey@Sun.COM nwamerr(nwam_error_t err, const char *format, ...)
80611767SAnurag.Maskey@Sun.COM {
80711767SAnurag.Maskey@Sun.COM 	va_list	alist;
80811767SAnurag.Maskey@Sun.COM 
80911767SAnurag.Maskey@Sun.COM 	print_lineno();
81011767SAnurag.Maskey@Sun.COM 
81111767SAnurag.Maskey@Sun.COM 	format = gettext(format);
81211767SAnurag.Maskey@Sun.COM 	va_start(alist, format);
81311767SAnurag.Maskey@Sun.COM 	(void) vfprintf(stderr, format, alist);
81411767SAnurag.Maskey@Sun.COM 	va_end(alist);
81511767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, ": %s\n", nwam_strerror(err));
81611767SAnurag.Maskey@Sun.COM 
81711767SAnurag.Maskey@Sun.COM 	saw_error = B_TRUE;
81811767SAnurag.Maskey@Sun.COM }
81911767SAnurag.Maskey@Sun.COM 
82011767SAnurag.Maskey@Sun.COM void
properr(const char * prop)82111767SAnurag.Maskey@Sun.COM properr(const char *prop)
82211767SAnurag.Maskey@Sun.COM {
82311767SAnurag.Maskey@Sun.COM 	nerr("Invalid property: '%s'", prop);
82411767SAnurag.Maskey@Sun.COM }
82511767SAnurag.Maskey@Sun.COM 
82611767SAnurag.Maskey@Sun.COM /*
82711767SAnurag.Maskey@Sun.COM  * If free_ncu_only == B_TRUE, only ncu handle is freed, ncp handle remains the
82811767SAnurag.Maskey@Sun.COM  * same.  Since nwam_ncp_free() takes care of its ncus, no need to explicitly
82911767SAnurag.Maskey@Sun.COM  * call nwam_ncu_free() afterwards.
83011767SAnurag.Maskey@Sun.COM  */
83111767SAnurag.Maskey@Sun.COM static void
free_handle(boolean_t free_ncu_only)83211767SAnurag.Maskey@Sun.COM free_handle(boolean_t free_ncu_only)
83311767SAnurag.Maskey@Sun.COM {
83411767SAnurag.Maskey@Sun.COM 	if (ncp_h != NULL) {
83511767SAnurag.Maskey@Sun.COM 		if (!free_ncu_only) {
83611767SAnurag.Maskey@Sun.COM 			nwam_ncp_free(ncp_h);
83711767SAnurag.Maskey@Sun.COM 			ncp_h = NULL;
83811767SAnurag.Maskey@Sun.COM 			ncu_h = NULL;
83911767SAnurag.Maskey@Sun.COM 		} else if (ncu_h != NULL) {
84011767SAnurag.Maskey@Sun.COM 			nwam_ncu_free(ncu_h);
84111767SAnurag.Maskey@Sun.COM 			ncu_h = NULL;
84211767SAnurag.Maskey@Sun.COM 		}
84311767SAnurag.Maskey@Sun.COM 	}
84411767SAnurag.Maskey@Sun.COM 
84511767SAnurag.Maskey@Sun.COM 	if (enm_h != NULL) {
84611767SAnurag.Maskey@Sun.COM 		nwam_enm_free(enm_h);
84711767SAnurag.Maskey@Sun.COM 		enm_h = NULL;
84811767SAnurag.Maskey@Sun.COM 	}
84911767SAnurag.Maskey@Sun.COM 
85011767SAnurag.Maskey@Sun.COM 	if (loc_h != NULL) {
85111767SAnurag.Maskey@Sun.COM 		nwam_loc_free(loc_h);
85211767SAnurag.Maskey@Sun.COM 		loc_h = NULL;
85311767SAnurag.Maskey@Sun.COM 	}
85411767SAnurag.Maskey@Sun.COM 
85511767SAnurag.Maskey@Sun.COM 	if (wlan_h != NULL) {
85611767SAnurag.Maskey@Sun.COM 		nwam_known_wlan_free(wlan_h);
85711767SAnurag.Maskey@Sun.COM 		wlan_h = NULL;
85811767SAnurag.Maskey@Sun.COM 	}
85911767SAnurag.Maskey@Sun.COM }
86011767SAnurag.Maskey@Sun.COM 
86111767SAnurag.Maskey@Sun.COM /*
86211767SAnurag.Maskey@Sun.COM  * On input, TRUE => yes, FALSE => no.
86311767SAnurag.Maskey@Sun.COM  * On return, TRUE => 1, FALSE => no, could not ask => -1.
86411767SAnurag.Maskey@Sun.COM  */
86511767SAnurag.Maskey@Sun.COM static int
ask_yesno(boolean_t default_answer,const char * question)86611767SAnurag.Maskey@Sun.COM ask_yesno(boolean_t default_answer, const char *question)
86711767SAnurag.Maskey@Sun.COM {
86811767SAnurag.Maskey@Sun.COM 	char line[64];  /* should be enough to answer yes or no */
86911767SAnurag.Maskey@Sun.COM 
87011767SAnurag.Maskey@Sun.COM 	if (!ok_to_prompt) {
87111767SAnurag.Maskey@Sun.COM 		saw_error = B_TRUE;
87211767SAnurag.Maskey@Sun.COM 		return (-1);
87311767SAnurag.Maskey@Sun.COM 	}
87411767SAnurag.Maskey@Sun.COM 	for (;;) {
87511767SAnurag.Maskey@Sun.COM 		if (printf("%s (%s)? ", gettext(question),
87611767SAnurag.Maskey@Sun.COM 		    default_answer ? "[y]/n" : "y/[n]") < 0)
87711767SAnurag.Maskey@Sun.COM 			return (-1);
87811767SAnurag.Maskey@Sun.COM 		if (fgets(line, sizeof (line), stdin) == NULL)
87911767SAnurag.Maskey@Sun.COM 			return (-1);
88011767SAnurag.Maskey@Sun.COM 
88111767SAnurag.Maskey@Sun.COM 		if (line[0] == '\n')
88211767SAnurag.Maskey@Sun.COM 			return (default_answer ? 1 : 0);
88311767SAnurag.Maskey@Sun.COM 		if (tolower(line[0]) == 'y')
88411767SAnurag.Maskey@Sun.COM 			return (1);
88511767SAnurag.Maskey@Sun.COM 		if (tolower(line[0]) == 'n')
88611767SAnurag.Maskey@Sun.COM 			return (0);
88711767SAnurag.Maskey@Sun.COM 	}
88811767SAnurag.Maskey@Sun.COM }
88911767SAnurag.Maskey@Sun.COM 
89011767SAnurag.Maskey@Sun.COM /* This is the back-end helper function for read_input() below. */
89111767SAnurag.Maskey@Sun.COM static int
cleanup()89211767SAnurag.Maskey@Sun.COM cleanup()
89311767SAnurag.Maskey@Sun.COM {
89411767SAnurag.Maskey@Sun.COM 	int answer;
89511767SAnurag.Maskey@Sun.COM 
89611767SAnurag.Maskey@Sun.COM 	if (!interactive_mode && !cmd_file_mode) {
89711767SAnurag.Maskey@Sun.COM 		/*
89811767SAnurag.Maskey@Sun.COM 		 * If we're not in interactive mode, and we're not in command
89911767SAnurag.Maskey@Sun.COM 		 * file mode, then we must be in commands-from-the-command-line
90011767SAnurag.Maskey@Sun.COM 		 * mode.  As such, we can't loop back and ask for more input.
90111767SAnurag.Maskey@Sun.COM 		 * It was OK to prompt for such things as whether or not to
90211767SAnurag.Maskey@Sun.COM 		 * really delete something in the command handler called from
90311767SAnurag.Maskey@Sun.COM 		 * yyparse() above, but "really quit?" makes no sense in this
90411767SAnurag.Maskey@Sun.COM 		 * context.  So disable prompting.
90511767SAnurag.Maskey@Sun.COM 		 */
90611767SAnurag.Maskey@Sun.COM 		ok_to_prompt = B_FALSE;
90711767SAnurag.Maskey@Sun.COM 	}
90811767SAnurag.Maskey@Sun.COM 	if (need_to_commit) {
90911767SAnurag.Maskey@Sun.COM 		answer = ask_yesno(B_FALSE,
91011767SAnurag.Maskey@Sun.COM 		    "Configuration not saved; really quit");
91111767SAnurag.Maskey@Sun.COM 		switch (answer) {
91211767SAnurag.Maskey@Sun.COM 		case -1:
91311767SAnurag.Maskey@Sun.COM 			/* issue error here */
91411767SAnurag.Maskey@Sun.COM 			return (NWAM_ERR);
91511767SAnurag.Maskey@Sun.COM 		case 1:
91611767SAnurag.Maskey@Sun.COM 			/*
91711767SAnurag.Maskey@Sun.COM 			 * don't want to save, just exit. handles are freed at
91811767SAnurag.Maskey@Sun.COM 			 * end_func() or exit_func().
91911767SAnurag.Maskey@Sun.COM 			 */
92011767SAnurag.Maskey@Sun.COM 			return (NWAM_OK);
92111767SAnurag.Maskey@Sun.COM 		default:
92211767SAnurag.Maskey@Sun.COM 			/* loop back to read input */
92311767SAnurag.Maskey@Sun.COM 			time_to_exit = B_FALSE;
92411767SAnurag.Maskey@Sun.COM 			yyin = stdin;
92511767SAnurag.Maskey@Sun.COM 			return (NWAM_REPEAT);
92611767SAnurag.Maskey@Sun.COM 		}
92711767SAnurag.Maskey@Sun.COM 	}
92811767SAnurag.Maskey@Sun.COM 	return (saw_error ? NWAM_ERR : NWAM_OK);
92911767SAnurag.Maskey@Sun.COM }
93011767SAnurag.Maskey@Sun.COM 
93111767SAnurag.Maskey@Sun.COM static int
string_to_yyin(char * string)93211767SAnurag.Maskey@Sun.COM string_to_yyin(char *string)
93311767SAnurag.Maskey@Sun.COM {
93411767SAnurag.Maskey@Sun.COM 	if ((yyin = tmpfile()) == NULL)
93511767SAnurag.Maskey@Sun.COM 		goto error;
93611767SAnurag.Maskey@Sun.COM 	if (fwrite(string, strlen(string), 1, yyin) != 1)
93711767SAnurag.Maskey@Sun.COM 		goto error;
93811767SAnurag.Maskey@Sun.COM 	if (fseek(yyin, 0, SEEK_SET) != 0)
93911767SAnurag.Maskey@Sun.COM 		goto error;
94011767SAnurag.Maskey@Sun.COM 
94111767SAnurag.Maskey@Sun.COM 	return (NWAM_OK);
94211767SAnurag.Maskey@Sun.COM 
94311767SAnurag.Maskey@Sun.COM error:
94411767SAnurag.Maskey@Sun.COM 	nerr("problem creating temporary file");
94511767SAnurag.Maskey@Sun.COM 	return (NWAM_ERR);
94611767SAnurag.Maskey@Sun.COM }
94711767SAnurag.Maskey@Sun.COM 
94811767SAnurag.Maskey@Sun.COM /*
94911767SAnurag.Maskey@Sun.COM  * read_input() is the driver of this program.  It is a wrapper around
95011767SAnurag.Maskey@Sun.COM  * yyparse(), printing appropriate prompts when needed, checking for
95111767SAnurag.Maskey@Sun.COM  * exit conditions and reacting appropriately.  This function is
95211767SAnurag.Maskey@Sun.COM  * called when in interactive mode or command-file mode.
95311767SAnurag.Maskey@Sun.COM  */
95411767SAnurag.Maskey@Sun.COM static int
read_input(void)95511767SAnurag.Maskey@Sun.COM read_input(void)
95611767SAnurag.Maskey@Sun.COM {
95711767SAnurag.Maskey@Sun.COM 	boolean_t yyin_is_a_tty = isatty(fileno(yyin));
95811767SAnurag.Maskey@Sun.COM 	/*
95911767SAnurag.Maskey@Sun.COM 	 * The prompt is "e> " or "e:t1:o1> " or "e:t1:o1:t2:o2> " where e is
96011767SAnurag.Maskey@Sun.COM 	 * execname, t is resource type, o is object name.
96111767SAnurag.Maskey@Sun.COM 	 */
96211767SAnurag.Maskey@Sun.COM 	char prompt[MAXPATHLEN + (2 * (NWAM_MAX_TYPE_LEN + NWAM_MAX_NAME_LEN))
96311767SAnurag.Maskey@Sun.COM 	    + sizeof ("::::> ")];
96411767SAnurag.Maskey@Sun.COM 	char *line;
96511767SAnurag.Maskey@Sun.COM 
96611767SAnurag.Maskey@Sun.COM 	/* yyin should have been set to the appropriate (FILE *) if not stdin */
96711767SAnurag.Maskey@Sun.COM 	newline_terminated = B_TRUE;
96811767SAnurag.Maskey@Sun.COM 	for (;;) {
96911767SAnurag.Maskey@Sun.COM 		if (yyin_is_a_tty) {
97011767SAnurag.Maskey@Sun.COM 			if (newline_terminated) {
97111767SAnurag.Maskey@Sun.COM 				switch (current_scope) {
97211767SAnurag.Maskey@Sun.COM 				case NWAM_SCOPE_GBL:
97311767SAnurag.Maskey@Sun.COM 					(void) snprintf(prompt, sizeof (prompt),
97411767SAnurag.Maskey@Sun.COM 					    "%s> ", execname);
97511767SAnurag.Maskey@Sun.COM 					break;
97611767SAnurag.Maskey@Sun.COM 				case NWAM_SCOPE_LOC:
97711767SAnurag.Maskey@Sun.COM 				case NWAM_SCOPE_ENM:
97811767SAnurag.Maskey@Sun.COM 				case NWAM_SCOPE_WLAN:
97911767SAnurag.Maskey@Sun.COM 				case NWAM_SCOPE_NCP:
98011767SAnurag.Maskey@Sun.COM 					(void) snprintf(prompt, sizeof (prompt),
98111767SAnurag.Maskey@Sun.COM 					    "%s:%s:%s> ", execname,
98211767SAnurag.Maskey@Sun.COM 					    rt1_to_str(obj1_type), obj1_name);
98311767SAnurag.Maskey@Sun.COM 
98411767SAnurag.Maskey@Sun.COM 					break;
98511767SAnurag.Maskey@Sun.COM 				case NWAM_SCOPE_NCU:
98611767SAnurag.Maskey@Sun.COM 					(void) snprintf(prompt, sizeof (prompt),
98711767SAnurag.Maskey@Sun.COM 					    "%s:%s:%s:%s:%s> ", execname,
98811767SAnurag.Maskey@Sun.COM 					    rt1_to_str(obj1_type), obj1_name,
98911767SAnurag.Maskey@Sun.COM 					    rt2_to_str(obj2_type), obj2_name);
99011767SAnurag.Maskey@Sun.COM 				}
99111767SAnurag.Maskey@Sun.COM 			}
99211767SAnurag.Maskey@Sun.COM 			/*
99311767SAnurag.Maskey@Sun.COM 			 * If the user hits ^C then we want to catch it and
99411767SAnurag.Maskey@Sun.COM 			 * start over.  If the user hits EOF then we want to
99511767SAnurag.Maskey@Sun.COM 			 * bail out.
99611767SAnurag.Maskey@Sun.COM 			 */
99711767SAnurag.Maskey@Sun.COM 			line = gl_get_line(gl, prompt, NULL, -1);
99811767SAnurag.Maskey@Sun.COM 			if (gl_return_status(gl) == GLR_SIGNAL) {
99911767SAnurag.Maskey@Sun.COM 				gl_abandon_line(gl);
100011767SAnurag.Maskey@Sun.COM 				continue;
100111767SAnurag.Maskey@Sun.COM 			}
100211767SAnurag.Maskey@Sun.COM 			if (line == NULL)
100311767SAnurag.Maskey@Sun.COM 				break;
100411767SAnurag.Maskey@Sun.COM 			if (string_to_yyin(line) != NWAM_OK)
100511767SAnurag.Maskey@Sun.COM 				break;
100611767SAnurag.Maskey@Sun.COM 			while (!feof(yyin)) {
100711767SAnurag.Maskey@Sun.COM 				yyparse();
100811767SAnurag.Maskey@Sun.COM 
100911767SAnurag.Maskey@Sun.COM 				/*
101011767SAnurag.Maskey@Sun.COM 				 * If any command on a list of commands
101111767SAnurag.Maskey@Sun.COM 				 * give an error, don't continue with the
101211767SAnurag.Maskey@Sun.COM 				 * remaining commands.
101311767SAnurag.Maskey@Sun.COM 				 */
101411767SAnurag.Maskey@Sun.COM 				if (saw_error || time_to_exit)
101511767SAnurag.Maskey@Sun.COM 					break;
101611767SAnurag.Maskey@Sun.COM 			}
101711767SAnurag.Maskey@Sun.COM 		} else {
101811767SAnurag.Maskey@Sun.COM 			yyparse();
101911767SAnurag.Maskey@Sun.COM 		}
102011767SAnurag.Maskey@Sun.COM 
102111767SAnurag.Maskey@Sun.COM 		/* Bail out on an error in command-file mode. */
102211767SAnurag.Maskey@Sun.COM 		if (saw_error && cmd_file_mode && !interactive_mode)
102311767SAnurag.Maskey@Sun.COM 			time_to_exit = B_TRUE;
102411767SAnurag.Maskey@Sun.COM 		if (time_to_exit || (!yyin_is_a_tty && feof(yyin)))
102511767SAnurag.Maskey@Sun.COM 			break;
102611767SAnurag.Maskey@Sun.COM 	}
102711767SAnurag.Maskey@Sun.COM 	return (cleanup());
102811767SAnurag.Maskey@Sun.COM }
102911767SAnurag.Maskey@Sun.COM 
103011767SAnurag.Maskey@Sun.COM /*
103111767SAnurag.Maskey@Sun.COM  * This function is used in the interactive-mode scenario: it just calls
103211767SAnurag.Maskey@Sun.COM  * read_input() until we are done.
103311767SAnurag.Maskey@Sun.COM  */
103411767SAnurag.Maskey@Sun.COM static int
do_interactive(void)103511767SAnurag.Maskey@Sun.COM do_interactive(void)
103611767SAnurag.Maskey@Sun.COM {
103711767SAnurag.Maskey@Sun.COM 	int err;
103811767SAnurag.Maskey@Sun.COM 
103911767SAnurag.Maskey@Sun.COM 	interactive_mode = B_TRUE;
104011767SAnurag.Maskey@Sun.COM 	do {
104111767SAnurag.Maskey@Sun.COM 		err = read_input();
104211767SAnurag.Maskey@Sun.COM 	} while (err == NWAM_REPEAT);
104311767SAnurag.Maskey@Sun.COM 	return (err);
104411767SAnurag.Maskey@Sun.COM }
104511767SAnurag.Maskey@Sun.COM 
104611767SAnurag.Maskey@Sun.COM /* Calls the help_func() to print the usage of all commands */
104711767SAnurag.Maskey@Sun.COM void
help_wrap()104811767SAnurag.Maskey@Sun.COM help_wrap()
104911767SAnurag.Maskey@Sun.COM {
105011767SAnurag.Maskey@Sun.COM 	cmd_t *help_cmd;
105111767SAnurag.Maskey@Sun.COM 
105211767SAnurag.Maskey@Sun.COM 	if ((help_cmd = alloc_cmd()) == NULL)
105311767SAnurag.Maskey@Sun.COM 		exit(NWAM_ERR);
105411767SAnurag.Maskey@Sun.COM 	help_func(help_cmd);
105511767SAnurag.Maskey@Sun.COM 	free_cmd(help_cmd);
105611767SAnurag.Maskey@Sun.COM }
105711767SAnurag.Maskey@Sun.COM 
105811767SAnurag.Maskey@Sun.COM /* Check if the given command is allowed in the current scope */
105911767SAnurag.Maskey@Sun.COM boolean_t
check_scope(int cmd)106011767SAnurag.Maskey@Sun.COM check_scope(int cmd)
106111767SAnurag.Maskey@Sun.COM {
106211767SAnurag.Maskey@Sun.COM 	/* allowed in all scopes */
106311767SAnurag.Maskey@Sun.COM 	switch (cmd) {
106411767SAnurag.Maskey@Sun.COM 	case CMD_END:
106511767SAnurag.Maskey@Sun.COM 	case CMD_EXIT:
106611767SAnurag.Maskey@Sun.COM 	case CMD_HELP:
106711767SAnurag.Maskey@Sun.COM 	case CMD_LIST:
106811767SAnurag.Maskey@Sun.COM 	case CMD_EXPORT:
106911767SAnurag.Maskey@Sun.COM 		return (B_TRUE);
107011767SAnurag.Maskey@Sun.COM 	}
107111767SAnurag.Maskey@Sun.COM 	/* scope-specific */
107211767SAnurag.Maskey@Sun.COM 	switch (current_scope) {
107311767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_GBL:
107411767SAnurag.Maskey@Sun.COM 		switch (cmd) {
107511767SAnurag.Maskey@Sun.COM 		case CMD_CREATE:
107611767SAnurag.Maskey@Sun.COM 		case CMD_DESTROY:
107711767SAnurag.Maskey@Sun.COM 		case CMD_SELECT:
107811767SAnurag.Maskey@Sun.COM 			return (B_TRUE);
107911767SAnurag.Maskey@Sun.COM 		}
108011767SAnurag.Maskey@Sun.COM 		break;
108111767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_LOC:
108211767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_ENM:
108311767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_WLAN:
108411767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_NCU:
108511767SAnurag.Maskey@Sun.COM 		switch (cmd) {
108611767SAnurag.Maskey@Sun.COM 		case CMD_CANCEL:
108711767SAnurag.Maskey@Sun.COM 		case CMD_CLEAR:
108811767SAnurag.Maskey@Sun.COM 		case CMD_COMMIT:
108911767SAnurag.Maskey@Sun.COM 		case CMD_GET:
109011767SAnurag.Maskey@Sun.COM 		case CMD_REVERT:
109111767SAnurag.Maskey@Sun.COM 		case CMD_SET:
109211767SAnurag.Maskey@Sun.COM 		case CMD_VERIFY:
109311767SAnurag.Maskey@Sun.COM 		case CMD_WALKPROP:
109411767SAnurag.Maskey@Sun.COM 			return (B_TRUE);
109511767SAnurag.Maskey@Sun.COM 		}
109611767SAnurag.Maskey@Sun.COM 		break;
109711767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_NCP:
109811767SAnurag.Maskey@Sun.COM 		switch (cmd) {
109911767SAnurag.Maskey@Sun.COM 		case CMD_CANCEL:
110011767SAnurag.Maskey@Sun.COM 		case CMD_CREATE:
110111767SAnurag.Maskey@Sun.COM 		case CMD_DESTROY:
110211767SAnurag.Maskey@Sun.COM 		case CMD_SELECT:
110311767SAnurag.Maskey@Sun.COM 			return (B_TRUE);
110411767SAnurag.Maskey@Sun.COM 		}
110511767SAnurag.Maskey@Sun.COM 		break;
110611767SAnurag.Maskey@Sun.COM 	default:
110711767SAnurag.Maskey@Sun.COM 		nerr("Invalid scope");
110811767SAnurag.Maskey@Sun.COM 	}
110911767SAnurag.Maskey@Sun.COM 	nerr("'%s' is not allowed at this scope", cmd_to_str(cmd));
111011767SAnurag.Maskey@Sun.COM 	return (B_FALSE);
111111767SAnurag.Maskey@Sun.COM }
111211767SAnurag.Maskey@Sun.COM 
111311767SAnurag.Maskey@Sun.COM /* Returns the active object type depending on which handle is not NULL */
111411767SAnurag.Maskey@Sun.COM static nwam_object_type_t
active_object_type()111511767SAnurag.Maskey@Sun.COM active_object_type()
111611767SAnurag.Maskey@Sun.COM {
111711767SAnurag.Maskey@Sun.COM 	/* Check ncu_h before ncp_h, ncp_h must be loaded before ncu_h */
111811767SAnurag.Maskey@Sun.COM 	if (ncu_h != NULL)
111911767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_NCU);
112011767SAnurag.Maskey@Sun.COM 	else if (ncp_h != NULL)
112111767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_NCP);
112211767SAnurag.Maskey@Sun.COM 	else if (loc_h != NULL)
112311767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_LOC);
112411767SAnurag.Maskey@Sun.COM 	else if (enm_h != NULL)
112511767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_ENM);
112611767SAnurag.Maskey@Sun.COM 	else if (wlan_h != NULL)
112711767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_KNOWN_WLAN);
112811767SAnurag.Maskey@Sun.COM 	else
112911767SAnurag.Maskey@Sun.COM 		return (NWAM_OBJECT_TYPE_UNKNOWN);
113011767SAnurag.Maskey@Sun.COM }
113111767SAnurag.Maskey@Sun.COM 
113211767SAnurag.Maskey@Sun.COM /* Retrive the name of the object from its handle */
113311767SAnurag.Maskey@Sun.COM static nwam_error_t
object_name_from_handle(nwam_object_type_t object_type,void * handle,char ** namep)113411767SAnurag.Maskey@Sun.COM object_name_from_handle(nwam_object_type_t object_type, void *handle,
113511767SAnurag.Maskey@Sun.COM     char **namep)
113611767SAnurag.Maskey@Sun.COM {
113711767SAnurag.Maskey@Sun.COM 	switch (object_type) {
113811767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCP:
113911767SAnurag.Maskey@Sun.COM 		return (nwam_ncp_get_name(handle, namep));
114011767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
114111767SAnurag.Maskey@Sun.COM 		return (nwam_ncu_get_name(handle, namep));
114211767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
114311767SAnurag.Maskey@Sun.COM 		return (nwam_loc_get_name(handle, namep));
114411767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
114511767SAnurag.Maskey@Sun.COM 		return (nwam_enm_get_name(handle, namep));
114611767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
114711767SAnurag.Maskey@Sun.COM 		return (nwam_known_wlan_get_name(handle, namep));
114811767SAnurag.Maskey@Sun.COM 	}
114911767SAnurag.Maskey@Sun.COM 	return (NWAM_INVALID_ARG);
115011767SAnurag.Maskey@Sun.COM }
115111767SAnurag.Maskey@Sun.COM 
115211767SAnurag.Maskey@Sun.COM static void
do_commit()115311767SAnurag.Maskey@Sun.COM do_commit()
115411767SAnurag.Maskey@Sun.COM {
115511767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret = NWAM_SUCCESS;
115611767SAnurag.Maskey@Sun.COM 	const char	*errprop;
115711767SAnurag.Maskey@Sun.COM 
115811767SAnurag.Maskey@Sun.COM 	if (!need_to_commit)
115911767SAnurag.Maskey@Sun.COM 		return;
116011767SAnurag.Maskey@Sun.COM 
116111767SAnurag.Maskey@Sun.COM 	switch (active_object_type()) {
116211767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
116311767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_commit(ncu_h, 0);
116411767SAnurag.Maskey@Sun.COM 		break;
116511767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
116611767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_commit(enm_h, 0);
116711767SAnurag.Maskey@Sun.COM 		break;
116811767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
116911767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_commit(loc_h, 0);
117011767SAnurag.Maskey@Sun.COM 		break;
117111767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
117211767SAnurag.Maskey@Sun.COM 		ret = nwam_known_wlan_commit(wlan_h, 0);
117311767SAnurag.Maskey@Sun.COM 		break;
117411767SAnurag.Maskey@Sun.COM 	}
117511767SAnurag.Maskey@Sun.COM 
117611767SAnurag.Maskey@Sun.COM 	if (ret == NWAM_SUCCESS) {
117711767SAnurag.Maskey@Sun.COM 		need_to_commit = B_FALSE;
117811767SAnurag.Maskey@Sun.COM 		if (interactive_mode)
117911767SAnurag.Maskey@Sun.COM 			(void) printf(gettext("Committed changes\n"));
118011767SAnurag.Maskey@Sun.COM 	} else {
118111767SAnurag.Maskey@Sun.COM 		nwam_error_t verr;
118211767SAnurag.Maskey@Sun.COM 
118311767SAnurag.Maskey@Sun.COM 		/* Find property that caused failure */
118411767SAnurag.Maskey@Sun.COM 		switch (active_object_type()) {
118511767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_NCU:
118611767SAnurag.Maskey@Sun.COM 			verr = nwam_ncu_validate(ncu_h, &errprop);
118711767SAnurag.Maskey@Sun.COM 			break;
118811767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_ENM:
118911767SAnurag.Maskey@Sun.COM 			verr = nwam_enm_validate(enm_h, &errprop);
119011767SAnurag.Maskey@Sun.COM 			break;
119111767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_LOC:
119211767SAnurag.Maskey@Sun.COM 			verr = nwam_loc_validate(loc_h, &errprop);
119311767SAnurag.Maskey@Sun.COM 			break;
119411767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_KNOWN_WLAN:
119511767SAnurag.Maskey@Sun.COM 			verr = nwam_known_wlan_validate(wlan_h, &errprop);
119611767SAnurag.Maskey@Sun.COM 			break;
119711767SAnurag.Maskey@Sun.COM 		}
119811767SAnurag.Maskey@Sun.COM 
119911767SAnurag.Maskey@Sun.COM 		if (verr != NWAM_SUCCESS)
120011767SAnurag.Maskey@Sun.COM 			nwamerr(ret, "Commit error on property '%s'", errprop);
120111767SAnurag.Maskey@Sun.COM 		else
120211767SAnurag.Maskey@Sun.COM 			nwamerr(ret, "Commit error");
120311767SAnurag.Maskey@Sun.COM 	}
120411767SAnurag.Maskey@Sun.COM }
120511767SAnurag.Maskey@Sun.COM 
120611767SAnurag.Maskey@Sun.COM /*
120711767SAnurag.Maskey@Sun.COM  * Saves the current configuration to persistent storage.
120811767SAnurag.Maskey@Sun.COM  */
120911767SAnurag.Maskey@Sun.COM /* ARGSUSED */
121011767SAnurag.Maskey@Sun.COM void
commit_func(cmd_t * cmd)121111767SAnurag.Maskey@Sun.COM commit_func(cmd_t *cmd)
121211767SAnurag.Maskey@Sun.COM {
121311767SAnurag.Maskey@Sun.COM 	if (!need_to_commit) {
121411767SAnurag.Maskey@Sun.COM 		if (interactive_mode)
121511767SAnurag.Maskey@Sun.COM 			(void) printf(gettext("Nothing to commit\n"));
121611767SAnurag.Maskey@Sun.COM 	} else {
121711767SAnurag.Maskey@Sun.COM 		do_commit();
121811767SAnurag.Maskey@Sun.COM 	}
121911767SAnurag.Maskey@Sun.COM }
122011767SAnurag.Maskey@Sun.COM 
122111767SAnurag.Maskey@Sun.COM static void
do_cancel()122211767SAnurag.Maskey@Sun.COM do_cancel()
122311767SAnurag.Maskey@Sun.COM {
122411767SAnurag.Maskey@Sun.COM 	switch (current_scope) {
122511767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_NCU:
122611767SAnurag.Maskey@Sun.COM 		current_scope = NWAM_SCOPE_NCP;
122711767SAnurag.Maskey@Sun.COM 		obj2_type = 0;
122811767SAnurag.Maskey@Sun.COM 		free_handle(B_TRUE);
122911767SAnurag.Maskey@Sun.COM 		break;
123011767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_NCP:
123111767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_ENM:
123211767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_WLAN:
123311767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_LOC:
123411767SAnurag.Maskey@Sun.COM 		current_scope = NWAM_SCOPE_GBL;
123511767SAnurag.Maskey@Sun.COM 		obj1_type = 0;
123611767SAnurag.Maskey@Sun.COM 		free_handle(B_FALSE);
123711767SAnurag.Maskey@Sun.COM 		break;
123811767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_GBL:
123911767SAnurag.Maskey@Sun.COM 		free_handle(B_FALSE);
124011767SAnurag.Maskey@Sun.COM 		break;
124111767SAnurag.Maskey@Sun.COM 	default:
124211767SAnurag.Maskey@Sun.COM 		nerr("Invalid scope");
124311767SAnurag.Maskey@Sun.COM 		return;
124411767SAnurag.Maskey@Sun.COM 	}
124511767SAnurag.Maskey@Sun.COM 	need_to_commit = B_FALSE;
124611767SAnurag.Maskey@Sun.COM }
124711767SAnurag.Maskey@Sun.COM 
124811767SAnurag.Maskey@Sun.COM /*
124911767SAnurag.Maskey@Sun.COM  * End operation on current scope and go up one scope.
125011767SAnurag.Maskey@Sun.COM  * Changes are not saved, no prompt either.
125111767SAnurag.Maskey@Sun.COM  */
125211767SAnurag.Maskey@Sun.COM /* ARGSUSED */
125311767SAnurag.Maskey@Sun.COM void
cancel_func(cmd_t * cmd)125411767SAnurag.Maskey@Sun.COM cancel_func(cmd_t *cmd)
125511767SAnurag.Maskey@Sun.COM {
125611767SAnurag.Maskey@Sun.COM 	do_cancel();
125711767SAnurag.Maskey@Sun.COM }
125811767SAnurag.Maskey@Sun.COM 
125911767SAnurag.Maskey@Sun.COM /*
126011767SAnurag.Maskey@Sun.COM  * Removes leading and trailing quotes from a string.
126111767SAnurag.Maskey@Sun.COM  * Caller must free returned string.
126211767SAnurag.Maskey@Sun.COM  */
126311767SAnurag.Maskey@Sun.COM static char *
trim_quotes(const char * quoted_str)126411767SAnurag.Maskey@Sun.COM trim_quotes(const char *quoted_str)
126511767SAnurag.Maskey@Sun.COM {
126611767SAnurag.Maskey@Sun.COM 	char *str;
126711767SAnurag.Maskey@Sun.COM 	int end;
126811767SAnurag.Maskey@Sun.COM 
126911767SAnurag.Maskey@Sun.COM 	/* export_func() and list_func() can pass NULL here */
127011767SAnurag.Maskey@Sun.COM 	if (quoted_str == NULL)
127111767SAnurag.Maskey@Sun.COM 		return (NULL);
127211767SAnurag.Maskey@Sun.COM 
127311767SAnurag.Maskey@Sun.COM 	/* remove leading quote */
127411767SAnurag.Maskey@Sun.COM 	if (quoted_str[0] == '"')
127511767SAnurag.Maskey@Sun.COM 		str = strdup(quoted_str + 1);
127611767SAnurag.Maskey@Sun.COM 	else
127711767SAnurag.Maskey@Sun.COM 		str = strdup(quoted_str);
127811767SAnurag.Maskey@Sun.COM 	if (str == NULL)
127911767SAnurag.Maskey@Sun.COM 		return (NULL);
128011767SAnurag.Maskey@Sun.COM 
128111767SAnurag.Maskey@Sun.COM 	/* remove trailing quote and newline */
128211767SAnurag.Maskey@Sun.COM 	end = strlen(str) - 1;
128311767SAnurag.Maskey@Sun.COM 	while (end >= 0 && (str[end] == '"' || str[end] == '\n'))
128411767SAnurag.Maskey@Sun.COM 		end--;
128511767SAnurag.Maskey@Sun.COM 	str[end+1] = 0;
128611767SAnurag.Maskey@Sun.COM 
128711767SAnurag.Maskey@Sun.COM 	return (str);
128811767SAnurag.Maskey@Sun.COM }
128911767SAnurag.Maskey@Sun.COM 
129011767SAnurag.Maskey@Sun.COM /*
129111767SAnurag.Maskey@Sun.COM  * Creates a new resource and enters the scope of that resource.
129211767SAnurag.Maskey@Sun.COM  * The new resource can also be a copy of an existing resource (-t option).
129311767SAnurag.Maskey@Sun.COM  * If in interactive mode, then after creation call walkprop_func()
129411767SAnurag.Maskey@Sun.COM  * to do walk the properties for the new object.
129511767SAnurag.Maskey@Sun.COM  */
129611767SAnurag.Maskey@Sun.COM void
create_func(cmd_t * cmd)129711767SAnurag.Maskey@Sun.COM create_func(cmd_t *cmd)
129811767SAnurag.Maskey@Sun.COM {
129911767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret = NWAM_SUCCESS;
130011767SAnurag.Maskey@Sun.COM 	int		c;
130111767SAnurag.Maskey@Sun.COM 	boolean_t	template = B_FALSE;
130211767SAnurag.Maskey@Sun.COM 	char		*newname = NULL, *oldname = NULL;
130311767SAnurag.Maskey@Sun.COM 	cmd_t		*walkprop_cmd;
130411767SAnurag.Maskey@Sun.COM 
130511767SAnurag.Maskey@Sun.COM 	/* make sure right command at the right scope */
130611767SAnurag.Maskey@Sun.COM 	if (current_scope == NWAM_SCOPE_GBL &&
130711767SAnurag.Maskey@Sun.COM 	    cmd->cmd_res2_type == RT2_NCU) {
130811767SAnurag.Maskey@Sun.COM 		nerr("cannot create ncu at global scope");
130911767SAnurag.Maskey@Sun.COM 		return;
131011767SAnurag.Maskey@Sun.COM 	}
131111767SAnurag.Maskey@Sun.COM 	if (current_scope == NWAM_SCOPE_NCP &&
131211767SAnurag.Maskey@Sun.COM 	    cmd->cmd_res2_type != RT2_NCU) {
131311767SAnurag.Maskey@Sun.COM 		nerr("Cannot create given object at this scope");
131411767SAnurag.Maskey@Sun.COM 		return;
131511767SAnurag.Maskey@Sun.COM 	}
131611767SAnurag.Maskey@Sun.COM 
131711767SAnurag.Maskey@Sun.COM 	assert(cmd->cmd_argc > 0);
131811767SAnurag.Maskey@Sun.COM 	optind = 0;
131911767SAnurag.Maskey@Sun.COM 	while ((c = getopt(cmd->cmd_argc, cmd->cmd_argv, "t:")) != EOF) {
132011767SAnurag.Maskey@Sun.COM 		switch (c) {
132111767SAnurag.Maskey@Sun.COM 		case 't':
132211767SAnurag.Maskey@Sun.COM 			template = B_TRUE;
132311767SAnurag.Maskey@Sun.COM 			break;
132411767SAnurag.Maskey@Sun.COM 		default:
132511767SAnurag.Maskey@Sun.COM 			command_usage(CMD_CREATE);
132611767SAnurag.Maskey@Sun.COM 			return;
132711767SAnurag.Maskey@Sun.COM 		}
132811767SAnurag.Maskey@Sun.COM 	}
132911767SAnurag.Maskey@Sun.COM 
133011767SAnurag.Maskey@Sun.COM 	if (!template) {
133111767SAnurag.Maskey@Sun.COM 		/* no template given */
133211767SAnurag.Maskey@Sun.COM 		/* argv[0] is name */
133311767SAnurag.Maskey@Sun.COM 		newname = trim_quotes(cmd->cmd_argv[0]);
133411767SAnurag.Maskey@Sun.COM 		if (cmd->cmd_res1_type == RT1_ENM) {
133511767SAnurag.Maskey@Sun.COM 			ret = nwam_enm_create(newname, NULL, &enm_h);
133611767SAnurag.Maskey@Sun.COM 		} else if (cmd->cmd_res1_type == RT1_LOC) {
133711767SAnurag.Maskey@Sun.COM 			ret = nwam_loc_create(newname, &loc_h);
133811767SAnurag.Maskey@Sun.COM 		} else if (cmd->cmd_res1_type == RT1_WLAN) {
133911767SAnurag.Maskey@Sun.COM 			ret = nwam_known_wlan_create(newname, &wlan_h);
134011767SAnurag.Maskey@Sun.COM 		} else if (cmd->cmd_res1_type == RT1_NCP &&
134111767SAnurag.Maskey@Sun.COM 		    current_scope == NWAM_SCOPE_GBL) {
134211767SAnurag.Maskey@Sun.COM 			ret = nwam_ncp_create(newname, 0, &ncp_h);
134311767SAnurag.Maskey@Sun.COM 		} else if (cmd->cmd_res2_type == RT2_NCU) {
134411767SAnurag.Maskey@Sun.COM 			nwam_ncu_type_t		ncu_type;
134511767SAnurag.Maskey@Sun.COM 			nwam_ncu_class_t	ncu_class;
134611767SAnurag.Maskey@Sun.COM 
134711767SAnurag.Maskey@Sun.COM 			/* ncp must already be read */
134811767SAnurag.Maskey@Sun.COM 			if (ncp_h == NULL) {
134911767SAnurag.Maskey@Sun.COM 				nerr("Create error: NCP has not been read");
135011767SAnurag.Maskey@Sun.COM 				goto done;
135111767SAnurag.Maskey@Sun.COM 			}
135211767SAnurag.Maskey@Sun.COM 
135311767SAnurag.Maskey@Sun.COM 			ncu_class = (nwam_ncu_class_t)cmd->cmd_ncu_class_type;
135411767SAnurag.Maskey@Sun.COM 			ncu_type = nwam_ncu_class_to_type(ncu_class);
135511767SAnurag.Maskey@Sun.COM 			ret = nwam_ncu_create(ncp_h, newname, ncu_type,
135611767SAnurag.Maskey@Sun.COM 			    ncu_class, &ncu_h);
135711767SAnurag.Maskey@Sun.COM 		}
135811767SAnurag.Maskey@Sun.COM 
135911767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS) {
136011767SAnurag.Maskey@Sun.COM 			nwamerr(ret, "Create error");
136111767SAnurag.Maskey@Sun.COM 			goto done;
136211767SAnurag.Maskey@Sun.COM 		}
136311767SAnurag.Maskey@Sun.COM 
136411767SAnurag.Maskey@Sun.COM 	} else {
136511767SAnurag.Maskey@Sun.COM 		/* template given */
136611767SAnurag.Maskey@Sun.COM 		/* argv[0] is -t, argv[1] is old name, argv[2] is new name */
136711767SAnurag.Maskey@Sun.COM 		oldname = trim_quotes(cmd->cmd_argv[1]);
136811767SAnurag.Maskey@Sun.COM 		newname = trim_quotes(cmd->cmd_argv[2]);
136911767SAnurag.Maskey@Sun.COM 		if (cmd->cmd_res1_type == RT1_ENM) {
137011767SAnurag.Maskey@Sun.COM 			nwam_enm_handle_t oldenm_h;
137111767SAnurag.Maskey@Sun.COM 
137211767SAnurag.Maskey@Sun.COM 			ret = nwam_enm_read(oldname, 0, &oldenm_h);
137311767SAnurag.Maskey@Sun.COM 			if (ret != NWAM_SUCCESS)
137411767SAnurag.Maskey@Sun.COM 				goto read_error;
137511767SAnurag.Maskey@Sun.COM 			ret = nwam_enm_copy(oldenm_h, newname, &enm_h);
137611767SAnurag.Maskey@Sun.COM 			nwam_enm_free(oldenm_h);
137711767SAnurag.Maskey@Sun.COM 		} else if (cmd->cmd_res1_type == RT1_LOC) {
137811767SAnurag.Maskey@Sun.COM 			nwam_loc_handle_t oldloc_h;
137911767SAnurag.Maskey@Sun.COM 
138011767SAnurag.Maskey@Sun.COM 			ret = nwam_loc_read(oldname, 0, &oldloc_h);
138111767SAnurag.Maskey@Sun.COM 			if (ret != NWAM_SUCCESS)
138211767SAnurag.Maskey@Sun.COM 				goto read_error;
138311767SAnurag.Maskey@Sun.COM 			ret = nwam_loc_copy(oldloc_h, newname, &loc_h);
138411767SAnurag.Maskey@Sun.COM 			nwam_loc_free(oldloc_h);
138511767SAnurag.Maskey@Sun.COM 		} else if (cmd->cmd_res1_type == RT1_WLAN) {
138611767SAnurag.Maskey@Sun.COM 			nwam_known_wlan_handle_t oldwlan_h;
138711767SAnurag.Maskey@Sun.COM 
138811767SAnurag.Maskey@Sun.COM 			ret = nwam_known_wlan_read(oldname, 0, &oldwlan_h);
138911767SAnurag.Maskey@Sun.COM 			if (ret != NWAM_SUCCESS)
139011767SAnurag.Maskey@Sun.COM 				goto read_error;
139111767SAnurag.Maskey@Sun.COM 			ret = nwam_known_wlan_copy(oldwlan_h, newname, &wlan_h);
139211767SAnurag.Maskey@Sun.COM 			nwam_known_wlan_free(oldwlan_h);
139311767SAnurag.Maskey@Sun.COM 		} else if (cmd->cmd_res1_type == RT1_NCP &&
139411767SAnurag.Maskey@Sun.COM 		    current_scope == NWAM_SCOPE_GBL) {
139511767SAnurag.Maskey@Sun.COM 			nwam_ncp_handle_t oldncp_h;
139611767SAnurag.Maskey@Sun.COM 
139711767SAnurag.Maskey@Sun.COM 			ret = nwam_ncp_read(oldname, 0, &oldncp_h);
139811767SAnurag.Maskey@Sun.COM 			if (ret != NWAM_SUCCESS)
139911767SAnurag.Maskey@Sun.COM 				goto read_error;
140011767SAnurag.Maskey@Sun.COM 			ret = nwam_ncp_copy(oldncp_h, newname, &ncp_h);
140111767SAnurag.Maskey@Sun.COM 			nwam_ncp_free(oldncp_h);
140211767SAnurag.Maskey@Sun.COM 		} else if (cmd->cmd_res2_type == RT2_NCU) {
140311767SAnurag.Maskey@Sun.COM 			nwam_ncu_handle_t	oldncu_h;
140411767SAnurag.Maskey@Sun.COM 			nwam_ncu_type_t		ncu_type;
140511767SAnurag.Maskey@Sun.COM 			nwam_ncu_class_t	ncu_class;
140611767SAnurag.Maskey@Sun.COM 
140711767SAnurag.Maskey@Sun.COM 			/* ncp must already be read */
140811767SAnurag.Maskey@Sun.COM 			if (ncp_h == NULL) {
140911767SAnurag.Maskey@Sun.COM 				nerr("Copy error: NCP has not been read");
141011767SAnurag.Maskey@Sun.COM 				goto done;
141111767SAnurag.Maskey@Sun.COM 			}
141211767SAnurag.Maskey@Sun.COM 			ncu_class = (nwam_ncu_class_t)cmd->cmd_ncu_class_type;
141311767SAnurag.Maskey@Sun.COM 			ncu_type = nwam_ncu_class_to_type(ncu_class);
141411767SAnurag.Maskey@Sun.COM 			ret = nwam_ncu_read(ncp_h, oldname, ncu_type, 0,
141511767SAnurag.Maskey@Sun.COM 			    &oldncu_h);
141611767SAnurag.Maskey@Sun.COM 			if (ret != NWAM_SUCCESS)
141711767SAnurag.Maskey@Sun.COM 				goto read_error;
141811767SAnurag.Maskey@Sun.COM 			ret = nwam_ncu_copy(oldncu_h, newname, &ncu_h);
141911767SAnurag.Maskey@Sun.COM 			nwam_ncu_free(oldncu_h);
142011767SAnurag.Maskey@Sun.COM 		}
142111767SAnurag.Maskey@Sun.COM 
142211767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS) {
142311767SAnurag.Maskey@Sun.COM 			nwamerr(ret, "Copy error");
142411767SAnurag.Maskey@Sun.COM 			goto done;
142511767SAnurag.Maskey@Sun.COM 		}
142611767SAnurag.Maskey@Sun.COM 	}
142711767SAnurag.Maskey@Sun.COM 
142811767SAnurag.Maskey@Sun.COM 	if (current_scope == NWAM_SCOPE_GBL) {
142911767SAnurag.Maskey@Sun.COM 		(void) strlcpy(obj1_name, newname, sizeof (obj1_name));
143011767SAnurag.Maskey@Sun.COM 		obj1_type = cmd->cmd_res1_type;
143111767SAnurag.Maskey@Sun.COM 		if (obj1_type == RT1_ENM)
143211767SAnurag.Maskey@Sun.COM 			current_scope = NWAM_SCOPE_ENM;
143311767SAnurag.Maskey@Sun.COM 		else if (obj1_type == RT1_LOC)
143411767SAnurag.Maskey@Sun.COM 			current_scope = NWAM_SCOPE_LOC;
143511767SAnurag.Maskey@Sun.COM 		else if (obj1_type == RT1_WLAN)
143611767SAnurag.Maskey@Sun.COM 			current_scope = NWAM_SCOPE_WLAN;
143711767SAnurag.Maskey@Sun.COM 		else if (obj1_type == RT1_NCP)
143811767SAnurag.Maskey@Sun.COM 			current_scope = NWAM_SCOPE_NCP;
143911767SAnurag.Maskey@Sun.COM 	} else {
144011767SAnurag.Maskey@Sun.COM 		(void) strlcpy(obj2_name, newname, sizeof (obj2_name));
144111767SAnurag.Maskey@Sun.COM 		current_scope = NWAM_SCOPE_NCU;
144211767SAnurag.Maskey@Sun.COM 		obj2_type = cmd->cmd_res2_type;
144311767SAnurag.Maskey@Sun.COM 	}
144411767SAnurag.Maskey@Sun.COM 	if (current_scope != NWAM_SCOPE_NCP)
144511767SAnurag.Maskey@Sun.COM 		need_to_commit = B_TRUE;
144611767SAnurag.Maskey@Sun.COM 
144711767SAnurag.Maskey@Sun.COM 	/* do a walk of the properties if in interactive mode */
144811767SAnurag.Maskey@Sun.COM 	if (interactive_mode && current_scope != NWAM_SCOPE_NCP) {
144911767SAnurag.Maskey@Sun.COM 		(void) printf(gettext("Created %s '%s'.  "
145011767SAnurag.Maskey@Sun.COM 		    "Walking properties ...\n"),
145111767SAnurag.Maskey@Sun.COM 		    scope_to_str(current_scope), newname);
145211767SAnurag.Maskey@Sun.COM 		if ((walkprop_cmd = alloc_cmd()) == NULL)
145311767SAnurag.Maskey@Sun.COM 			goto done;
145411767SAnurag.Maskey@Sun.COM 		walkprop_func(walkprop_cmd);
145511767SAnurag.Maskey@Sun.COM 		free(walkprop_cmd);
145611767SAnurag.Maskey@Sun.COM 	}
145711767SAnurag.Maskey@Sun.COM 
145811767SAnurag.Maskey@Sun.COM read_error:
145911767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
146011767SAnurag.Maskey@Sun.COM 		nwamerr(ret, "Copy error reading '%s'", oldname);
146111767SAnurag.Maskey@Sun.COM 
146211767SAnurag.Maskey@Sun.COM done:
146311767SAnurag.Maskey@Sun.COM 	free(oldname);
146411767SAnurag.Maskey@Sun.COM 	free(newname);
146511767SAnurag.Maskey@Sun.COM }
146611767SAnurag.Maskey@Sun.COM 
146711767SAnurag.Maskey@Sun.COM /* Processing of return value for destroy_*_callback() */
146811767SAnurag.Maskey@Sun.COM static int
destroy_ret(nwam_object_type_t object_type,nwam_error_t ret,void * handle)146911767SAnurag.Maskey@Sun.COM destroy_ret(nwam_object_type_t object_type, nwam_error_t ret, void *handle)
147011767SAnurag.Maskey@Sun.COM {
147111767SAnurag.Maskey@Sun.COM 	if (ret == NWAM_ENTITY_NOT_DESTROYABLE) {
147211767SAnurag.Maskey@Sun.COM 		/* log a message to stderr, but don't consider it an error */
147311767SAnurag.Maskey@Sun.COM 		char *name;
147411767SAnurag.Maskey@Sun.COM 		if (object_name_from_handle(object_type, handle, &name)
147511767SAnurag.Maskey@Sun.COM 		    == NWAM_SUCCESS) {
147611767SAnurag.Maskey@Sun.COM 			(void) fprintf(stderr,
147711767SAnurag.Maskey@Sun.COM 			    gettext("%s '%s' cannot be removed\n"),
147811767SAnurag.Maskey@Sun.COM 			    nwam_object_type_to_string(object_type), name);
147911767SAnurag.Maskey@Sun.COM 			free(name);
148011767SAnurag.Maskey@Sun.COM 		}
148111767SAnurag.Maskey@Sun.COM 		return (0);
148211767SAnurag.Maskey@Sun.COM 	}
148311767SAnurag.Maskey@Sun.COM 
148411767SAnurag.Maskey@Sun.COM 	if (ret == NWAM_SUCCESS || ret == NWAM_ENTITY_IN_USE)
148511767SAnurag.Maskey@Sun.COM 		return (0);
148611767SAnurag.Maskey@Sun.COM 
148711767SAnurag.Maskey@Sun.COM 	return (1);
148811767SAnurag.Maskey@Sun.COM }
148911767SAnurag.Maskey@Sun.COM 
149011767SAnurag.Maskey@Sun.COM /*
149111767SAnurag.Maskey@Sun.COM  * NWAM_FLAG_DO_NOT_FREE is passed to nwam_*_destory() so that it does not
149211767SAnurag.Maskey@Sun.COM  * free the handle.  The calling nwam_walk_*() function frees this handle
149311767SAnurag.Maskey@Sun.COM  * as it is the function that created the handle.
149411767SAnurag.Maskey@Sun.COM  *
149511767SAnurag.Maskey@Sun.COM  * Objects that are not destroyable or are active cannot be destroyed.
149611767SAnurag.Maskey@Sun.COM  * Don't return error in these situations so the walk can continue.
149711767SAnurag.Maskey@Sun.COM  */
149811767SAnurag.Maskey@Sun.COM /* ARGSUSED */
149911767SAnurag.Maskey@Sun.COM static int
destroy_ncp_callback(nwam_ncp_handle_t ncp,void * arg)150011767SAnurag.Maskey@Sun.COM destroy_ncp_callback(nwam_ncp_handle_t ncp, void *arg)
150111767SAnurag.Maskey@Sun.COM {
150211767SAnurag.Maskey@Sun.COM 	/* The file is deleted, so NCUs are also removed */
150311767SAnurag.Maskey@Sun.COM 	nwam_error_t ret = nwam_ncp_destroy(ncp, NWAM_FLAG_DO_NOT_FREE);
150411767SAnurag.Maskey@Sun.COM 	return (destroy_ret(NWAM_OBJECT_TYPE_NCP, ret, ncp));
150511767SAnurag.Maskey@Sun.COM }
150611767SAnurag.Maskey@Sun.COM 
150711767SAnurag.Maskey@Sun.COM /* ARGSUSED */
150811767SAnurag.Maskey@Sun.COM static int
destroy_loc_callback(nwam_loc_handle_t loc,void * arg)150911767SAnurag.Maskey@Sun.COM destroy_loc_callback(nwam_loc_handle_t loc, void *arg)
151011767SAnurag.Maskey@Sun.COM {
151111767SAnurag.Maskey@Sun.COM 	nwam_error_t ret = nwam_loc_destroy(loc, NWAM_FLAG_DO_NOT_FREE);
151211767SAnurag.Maskey@Sun.COM 	return (destroy_ret(NWAM_OBJECT_TYPE_LOC, ret, loc));
151311767SAnurag.Maskey@Sun.COM }
151411767SAnurag.Maskey@Sun.COM 
151511767SAnurag.Maskey@Sun.COM /* ARGSUSED */
151611767SAnurag.Maskey@Sun.COM static int
destroy_enm_callback(nwam_enm_handle_t enm,void * arg)151711767SAnurag.Maskey@Sun.COM destroy_enm_callback(nwam_enm_handle_t enm, void *arg)
151811767SAnurag.Maskey@Sun.COM {
151911767SAnurag.Maskey@Sun.COM 	nwam_error_t ret = nwam_enm_destroy(enm, NWAM_FLAG_DO_NOT_FREE);
152011767SAnurag.Maskey@Sun.COM 	return (destroy_ret(NWAM_OBJECT_TYPE_ENM, ret, enm));
152111767SAnurag.Maskey@Sun.COM }
152211767SAnurag.Maskey@Sun.COM 
152311767SAnurag.Maskey@Sun.COM /* ARGSUSED */
152411767SAnurag.Maskey@Sun.COM static int
destroy_wlan_callback(nwam_known_wlan_handle_t wlan,void * arg)152511767SAnurag.Maskey@Sun.COM destroy_wlan_callback(nwam_known_wlan_handle_t wlan, void *arg)
152611767SAnurag.Maskey@Sun.COM {
152711767SAnurag.Maskey@Sun.COM 	nwam_error_t ret = nwam_known_wlan_destroy(wlan, NWAM_FLAG_DO_NOT_FREE);
152811767SAnurag.Maskey@Sun.COM 	return (destroy_ret(NWAM_OBJECT_TYPE_KNOWN_WLAN, ret, wlan));
152911767SAnurag.Maskey@Sun.COM }
153011767SAnurag.Maskey@Sun.COM 
153111767SAnurag.Maskey@Sun.COM /*
153211767SAnurag.Maskey@Sun.COM  * Remove all existing configuration that are not read-only.
153311767SAnurag.Maskey@Sun.COM  * walk through all ncps, locs, enms, wlans and destroy each one.
153411767SAnurag.Maskey@Sun.COM  */
153511767SAnurag.Maskey@Sun.COM static nwam_error_t
destroy_all(void)153611767SAnurag.Maskey@Sun.COM destroy_all(void)
153711767SAnurag.Maskey@Sun.COM {
153811767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
153911767SAnurag.Maskey@Sun.COM 
154011767SAnurag.Maskey@Sun.COM 	assert(remove_all_configurations);
154111767SAnurag.Maskey@Sun.COM 
154211767SAnurag.Maskey@Sun.COM 	ret = nwam_walk_ncps(destroy_ncp_callback, NULL, 0, NULL);
154311767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
154411767SAnurag.Maskey@Sun.COM 		goto done;
154511767SAnurag.Maskey@Sun.COM 
154611767SAnurag.Maskey@Sun.COM 	ret = nwam_walk_enms(destroy_enm_callback, NULL,
154711767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
154811767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
154911767SAnurag.Maskey@Sun.COM 		goto done;
155011767SAnurag.Maskey@Sun.COM 
155111767SAnurag.Maskey@Sun.COM 	ret = nwam_walk_locs(destroy_loc_callback, NULL,
155211767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
155311767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
155411767SAnurag.Maskey@Sun.COM 		goto done;
155511767SAnurag.Maskey@Sun.COM 
155611767SAnurag.Maskey@Sun.COM 	ret = nwam_walk_known_wlans(destroy_wlan_callback, NULL, 0, NULL);
155711767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
155811767SAnurag.Maskey@Sun.COM 		goto done;
155911767SAnurag.Maskey@Sun.COM 
156011767SAnurag.Maskey@Sun.COM 	if (interactive_mode)
156111767SAnurag.Maskey@Sun.COM 		(void) printf(gettext("All user-defined entities destroyed\n"));
156211767SAnurag.Maskey@Sun.COM 	remove_all_configurations = B_FALSE;
156311767SAnurag.Maskey@Sun.COM 
156411767SAnurag.Maskey@Sun.COM done:
156511767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS) {
156611767SAnurag.Maskey@Sun.COM 		nwamerr(ret, "Destroy error: "
156711767SAnurag.Maskey@Sun.COM 		    "could not destroy all configurations");
156811767SAnurag.Maskey@Sun.COM 	}
156911767SAnurag.Maskey@Sun.COM 	return (ret);
157011767SAnurag.Maskey@Sun.COM }
157111767SAnurag.Maskey@Sun.COM 
157211767SAnurag.Maskey@Sun.COM /*
157311767SAnurag.Maskey@Sun.COM  * Destroys an instance in persistent repository, and is permanent.
157411767SAnurag.Maskey@Sun.COM  * If interactive mode, it is allowed at global scope only
157511767SAnurag.Maskey@Sun.COM  * option -a destroys everything.
157611767SAnurag.Maskey@Sun.COM  */
157711767SAnurag.Maskey@Sun.COM void
destroy_func(cmd_t * cmd)157811767SAnurag.Maskey@Sun.COM destroy_func(cmd_t *cmd)
157911767SAnurag.Maskey@Sun.COM {
158011767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
158111767SAnurag.Maskey@Sun.COM 	char		*name, *realname = NULL;
158211767SAnurag.Maskey@Sun.COM 
158311767SAnurag.Maskey@Sun.COM 	if (current_scope == NWAM_SCOPE_NCP &&
158411767SAnurag.Maskey@Sun.COM 	    (cmd->cmd_res1_type == RT1_ENM || cmd->cmd_res1_type == RT1_LOC ||
158511767SAnurag.Maskey@Sun.COM 	    cmd->cmd_res1_type == RT1_WLAN)) {
158611767SAnurag.Maskey@Sun.COM 		nerr("Destroy error: only NCUs can be destroyed in NCP scope");
158711767SAnurag.Maskey@Sun.COM 		return;
158811767SAnurag.Maskey@Sun.COM 	}
158911767SAnurag.Maskey@Sun.COM 
159011767SAnurag.Maskey@Sun.COM 	assert(cmd->cmd_argc > 0);
159111767SAnurag.Maskey@Sun.COM 
159211767SAnurag.Maskey@Sun.COM 	/* res1_type is -1 if -a flag is used */
159311767SAnurag.Maskey@Sun.COM 	if (cmd->cmd_res1_type == -1) {
159411767SAnurag.Maskey@Sun.COM 		int c;
159511767SAnurag.Maskey@Sun.COM 
159611767SAnurag.Maskey@Sun.COM 		if (current_scope != NWAM_SCOPE_GBL) {
159711767SAnurag.Maskey@Sun.COM 			nerr("Cannot destroy all configurations in a "
159811767SAnurag.Maskey@Sun.COM 			    "non-global scope");
159911767SAnurag.Maskey@Sun.COM 			return;
160011767SAnurag.Maskey@Sun.COM 		}
160111767SAnurag.Maskey@Sun.COM 
160211767SAnurag.Maskey@Sun.COM 		optind = 0;
160311767SAnurag.Maskey@Sun.COM 		while ((c = getopt(cmd->cmd_argc, cmd->cmd_argv, "a")) != EOF) {
160411767SAnurag.Maskey@Sun.COM 			switch (c) {
160511767SAnurag.Maskey@Sun.COM 			case 'a':
160611767SAnurag.Maskey@Sun.COM 				remove_all_configurations = B_TRUE;
160711767SAnurag.Maskey@Sun.COM 				break;
160811767SAnurag.Maskey@Sun.COM 			default:
160911767SAnurag.Maskey@Sun.COM 				command_usage(CMD_DESTROY);
161011767SAnurag.Maskey@Sun.COM 				return;
161111767SAnurag.Maskey@Sun.COM 			}
161211767SAnurag.Maskey@Sun.COM 		}
161311767SAnurag.Maskey@Sun.COM 		if (remove_all_configurations) {
161411767SAnurag.Maskey@Sun.COM 			(void) destroy_all();
161511767SAnurag.Maskey@Sun.COM 			return;
161611767SAnurag.Maskey@Sun.COM 		}
161711767SAnurag.Maskey@Sun.COM 	}
161811767SAnurag.Maskey@Sun.COM 
161911767SAnurag.Maskey@Sun.COM 	/* argv[0] is name */
162011767SAnurag.Maskey@Sun.COM 	name = trim_quotes(cmd->cmd_argv[0]);
162111767SAnurag.Maskey@Sun.COM 	if (cmd->cmd_res2_type == RT2_NCU) {
162211767SAnurag.Maskey@Sun.COM 		nwam_ncu_type_t		ncu_type;
162311767SAnurag.Maskey@Sun.COM 		nwam_ncu_class_t	ncu_class;
162411767SAnurag.Maskey@Sun.COM 
162511767SAnurag.Maskey@Sun.COM 		/* ncp must already be read */
162611767SAnurag.Maskey@Sun.COM 		if (ncp_h == NULL) {
162711767SAnurag.Maskey@Sun.COM 			nerr("Destroy ncu error: NCP has not been read");
162811767SAnurag.Maskey@Sun.COM 			return;
162911767SAnurag.Maskey@Sun.COM 		}
163011767SAnurag.Maskey@Sun.COM 		ncu_class = (nwam_ncu_class_t)cmd->cmd_ncu_class_type;
163111767SAnurag.Maskey@Sun.COM 		ncu_type = nwam_ncu_class_to_type(ncu_class);
163211767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_read(ncp_h, name, ncu_type, 0, &ncu_h);
163311767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
163411767SAnurag.Maskey@Sun.COM 			goto done;
163511767SAnurag.Maskey@Sun.COM 		(void) object_name_from_handle(NWAM_OBJECT_TYPE_NCU, ncu_h,
163611767SAnurag.Maskey@Sun.COM 		    &realname);
163711767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_destroy(ncu_h, 0);
163811767SAnurag.Maskey@Sun.COM 		ncu_h = NULL;
163911767SAnurag.Maskey@Sun.COM 	} else if (cmd->cmd_res1_type == RT1_ENM) {
164011767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_enm_read(name, 0, &enm_h)) != NWAM_SUCCESS)
164111767SAnurag.Maskey@Sun.COM 			goto done;
164211767SAnurag.Maskey@Sun.COM 		(void) object_name_from_handle(NWAM_OBJECT_TYPE_ENM, enm_h,
164311767SAnurag.Maskey@Sun.COM 		    &realname);
164411767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_destroy(enm_h, 0);
164511767SAnurag.Maskey@Sun.COM 		enm_h = NULL;
164611767SAnurag.Maskey@Sun.COM 	} else if (cmd->cmd_res1_type == RT1_LOC) {
164711767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_loc_read(name, 0, &loc_h)) != NWAM_SUCCESS)
164811767SAnurag.Maskey@Sun.COM 			goto done;
164911767SAnurag.Maskey@Sun.COM 		(void) object_name_from_handle(NWAM_OBJECT_TYPE_LOC, loc_h,
165011767SAnurag.Maskey@Sun.COM 		    &realname);
165111767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_destroy(loc_h, 0);
165211767SAnurag.Maskey@Sun.COM 		loc_h = NULL;
165311767SAnurag.Maskey@Sun.COM 	} else if (cmd->cmd_res1_type == RT1_WLAN) {
165411767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_known_wlan_read(name, 0, &wlan_h))
165511767SAnurag.Maskey@Sun.COM 		    != NWAM_SUCCESS)
165611767SAnurag.Maskey@Sun.COM 			goto done;
165711767SAnurag.Maskey@Sun.COM 		(void) object_name_from_handle(NWAM_OBJECT_TYPE_KNOWN_WLAN,
165811767SAnurag.Maskey@Sun.COM 		    wlan_h, &realname);
165911767SAnurag.Maskey@Sun.COM 		ret = nwam_known_wlan_destroy(wlan_h, 0);
166011767SAnurag.Maskey@Sun.COM 		wlan_h = NULL;
166111767SAnurag.Maskey@Sun.COM 	} else if (cmd->cmd_res1_type == RT1_NCP) {
166211767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_ncp_read(name, 0, &ncp_h)) != NWAM_SUCCESS)
166311767SAnurag.Maskey@Sun.COM 			goto done;
166411767SAnurag.Maskey@Sun.COM 		(void) object_name_from_handle(NWAM_OBJECT_TYPE_NCP, ncp_h,
166511767SAnurag.Maskey@Sun.COM 		    &realname);
166611767SAnurag.Maskey@Sun.COM 		ret = nwam_ncp_destroy(ncp_h, 0);
166711767SAnurag.Maskey@Sun.COM 		ncp_h = NULL;
166811767SAnurag.Maskey@Sun.COM 	} else {
166911767SAnurag.Maskey@Sun.COM 		nerr("Destroy error: unknown object-type");
167011767SAnurag.Maskey@Sun.COM 	}
167111767SAnurag.Maskey@Sun.COM 
167211767SAnurag.Maskey@Sun.COM done:
167311767SAnurag.Maskey@Sun.COM 	if (ret == NWAM_ENTITY_IN_USE)  {
167411767SAnurag.Maskey@Sun.COM 		nerr("Destroy error: active entity cannot be destroyed");
167511767SAnurag.Maskey@Sun.COM 	} else if (ret != NWAM_SUCCESS) {
167611767SAnurag.Maskey@Sun.COM 		nwamerr(ret, "Destroy error");
167711767SAnurag.Maskey@Sun.COM 	} else if (interactive_mode) {
167811767SAnurag.Maskey@Sun.COM 		(void) printf(gettext("Destroyed %s '%s'\n"),
167911767SAnurag.Maskey@Sun.COM 		    (cmd->cmd_res2_type == RT2_NCU ?
168011767SAnurag.Maskey@Sun.COM 		    rt2_to_str(cmd->cmd_res2_type) :
168111767SAnurag.Maskey@Sun.COM 		    rt1_to_str(cmd->cmd_res1_type)),
168211767SAnurag.Maskey@Sun.COM 		    realname != NULL ? realname : name);
168311767SAnurag.Maskey@Sun.COM 	}
168411767SAnurag.Maskey@Sun.COM 	free(name);
168511767SAnurag.Maskey@Sun.COM 	free(realname);
168611767SAnurag.Maskey@Sun.COM }
168711767SAnurag.Maskey@Sun.COM 
168811767SAnurag.Maskey@Sun.COM /*
168911767SAnurag.Maskey@Sun.COM  * End operation on current scope and go up one scope.
169011767SAnurag.Maskey@Sun.COM  * Changes are saved.
169111767SAnurag.Maskey@Sun.COM  */
169211767SAnurag.Maskey@Sun.COM /* ARGSUSED */
169311767SAnurag.Maskey@Sun.COM void
end_func(cmd_t * cmd)169411767SAnurag.Maskey@Sun.COM end_func(cmd_t *cmd)
169511767SAnurag.Maskey@Sun.COM {
169611767SAnurag.Maskey@Sun.COM 	/* if need_to_commit is set, commit changes */
169711767SAnurag.Maskey@Sun.COM 	if (need_to_commit)
169811767SAnurag.Maskey@Sun.COM 		do_commit();
169911767SAnurag.Maskey@Sun.COM 
170011767SAnurag.Maskey@Sun.COM 	/*
170111767SAnurag.Maskey@Sun.COM 	 * Call do_cancel() to go up one scope.  If commit fails,
170211767SAnurag.Maskey@Sun.COM 	 * need_to_commit is not reset and users are asked if they want to end.
170311767SAnurag.Maskey@Sun.COM 	 */
170411767SAnurag.Maskey@Sun.COM 	if (!need_to_commit ||
170511767SAnurag.Maskey@Sun.COM 	    (need_to_commit && (ask_yesno(B_FALSE,
170611767SAnurag.Maskey@Sun.COM 	    "Configuration not saved; really end")) == 1)) {
170711767SAnurag.Maskey@Sun.COM 		/* set time_to_exit if in global scope */
170811767SAnurag.Maskey@Sun.COM 		if (current_scope == NWAM_SCOPE_GBL)
170911767SAnurag.Maskey@Sun.COM 			time_to_exit = B_TRUE;
171011767SAnurag.Maskey@Sun.COM 		/* call do_cancel() to go up one scope */
171111767SAnurag.Maskey@Sun.COM 		do_cancel();
171211767SAnurag.Maskey@Sun.COM 	}
171311767SAnurag.Maskey@Sun.COM }
171411767SAnurag.Maskey@Sun.COM 
171511767SAnurag.Maskey@Sun.COM /*
171611767SAnurag.Maskey@Sun.COM  * Exit immediately.  Configuration changes are saved by calling end_func().
171711767SAnurag.Maskey@Sun.COM  */
171811767SAnurag.Maskey@Sun.COM /* ARGSUSED */
171911767SAnurag.Maskey@Sun.COM void
exit_func(cmd_t * cmd)172011767SAnurag.Maskey@Sun.COM exit_func(cmd_t *cmd)
172111767SAnurag.Maskey@Sun.COM {
172211767SAnurag.Maskey@Sun.COM 	cmd_t *end_cmd;
172311767SAnurag.Maskey@Sun.COM 
172411767SAnurag.Maskey@Sun.COM 	if (need_to_commit) {
172511767SAnurag.Maskey@Sun.COM 		if ((end_cmd = alloc_cmd()) == NULL) {
172611767SAnurag.Maskey@Sun.COM 			nerr("Exit error");
172711767SAnurag.Maskey@Sun.COM 			return;
172811767SAnurag.Maskey@Sun.COM 		}
172911767SAnurag.Maskey@Sun.COM 		end_func(end_cmd);
173011767SAnurag.Maskey@Sun.COM 		free_cmd(end_cmd);
173111767SAnurag.Maskey@Sun.COM 	}
173211767SAnurag.Maskey@Sun.COM 
173311767SAnurag.Maskey@Sun.COM 	/*
173411767SAnurag.Maskey@Sun.COM 	 * If need_to_commit is still set, then the commit failed.
173511767SAnurag.Maskey@Sun.COM 	 * Otherwise, exit.
173611767SAnurag.Maskey@Sun.COM 	 */
173711767SAnurag.Maskey@Sun.COM 	if (!need_to_commit)
173811767SAnurag.Maskey@Sun.COM 		time_to_exit = B_TRUE;
173911767SAnurag.Maskey@Sun.COM }
174011767SAnurag.Maskey@Sun.COM 
174111767SAnurag.Maskey@Sun.COM void
help_func(cmd_t * cmd)174211767SAnurag.Maskey@Sun.COM help_func(cmd_t *cmd)
174311767SAnurag.Maskey@Sun.COM {
174411767SAnurag.Maskey@Sun.COM 	int i;
174511767SAnurag.Maskey@Sun.COM 
174611767SAnurag.Maskey@Sun.COM 	if (cmd->cmd_argc == 0) {
174711767SAnurag.Maskey@Sun.COM 		(void) printf(gettext("commands:\n"));
174811767SAnurag.Maskey@Sun.COM 		for (i = CMD_MIN; i <= CMD_MAX; i++)
174911767SAnurag.Maskey@Sun.COM 			(void) printf("\t%s\n", helptab[i].cmd_usage);
175011767SAnurag.Maskey@Sun.COM 		return;
175111767SAnurag.Maskey@Sun.COM 	}
175211767SAnurag.Maskey@Sun.COM 
175311767SAnurag.Maskey@Sun.COM 	for (i = CMD_MIN; i <= CMD_MAX; i++) {
175411767SAnurag.Maskey@Sun.COM 		if (strcmp(cmd->cmd_argv[0], cmd_to_str(i)) == 0) {
175511767SAnurag.Maskey@Sun.COM 			long_usage(i);
175611767SAnurag.Maskey@Sun.COM 			return;
175711767SAnurag.Maskey@Sun.COM 		}
175811767SAnurag.Maskey@Sun.COM 	}
175911767SAnurag.Maskey@Sun.COM 	(void) fprintf(stderr, gettext("Unknown command: '%s'\n"),
176011767SAnurag.Maskey@Sun.COM 	    cmd->cmd_argv[0]);
176111767SAnurag.Maskey@Sun.COM 	help_wrap();
176211767SAnurag.Maskey@Sun.COM }
176311767SAnurag.Maskey@Sun.COM 
176411767SAnurag.Maskey@Sun.COM /*
176511767SAnurag.Maskey@Sun.COM  * Revert configuration of an instance to latest previous version.
176611767SAnurag.Maskey@Sun.COM  * Free the handle and read again.
176711767SAnurag.Maskey@Sun.COM  */
176811767SAnurag.Maskey@Sun.COM /* ARGSUSED */
176911767SAnurag.Maskey@Sun.COM void
revert_func(cmd_t * cmd)177011767SAnurag.Maskey@Sun.COM revert_func(cmd_t *cmd)
177111767SAnurag.Maskey@Sun.COM {
1772*13034SAnurag.Maskey@Oracle.COM 	nwam_error_t		ret;
1773*13034SAnurag.Maskey@Oracle.COM 	char			*name = NULL;
1774*13034SAnurag.Maskey@Oracle.COM 	nwam_ncu_type_t		ncu_type;
1775*13034SAnurag.Maskey@Oracle.COM 	nwam_object_type_t	object_type = active_object_type();
1776*13034SAnurag.Maskey@Oracle.COM 
1777*13034SAnurag.Maskey@Oracle.COM 	switch (object_type) {
177811767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
177911767SAnurag.Maskey@Sun.COM 		/* retrieve name and type to use later */
178011767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_ncu_get_ncu_type(ncu_h, &ncu_type))
178111767SAnurag.Maskey@Sun.COM 		    != NWAM_SUCCESS) {
178211767SAnurag.Maskey@Sun.COM 			nwamerr(ret, "Revert error: Get ncu type error");
178311767SAnurag.Maskey@Sun.COM 			return;
178411767SAnurag.Maskey@Sun.COM 		}
178511767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_ncu_get_name(ncu_h, &name)) != NWAM_SUCCESS)
178611767SAnurag.Maskey@Sun.COM 			goto name_error;
178711767SAnurag.Maskey@Sun.COM 		nwam_ncu_free(ncu_h);
178811767SAnurag.Maskey@Sun.COM 		ncu_h = NULL;
178911767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_read(ncp_h, name, ncu_type, 0, &ncu_h);
179011767SAnurag.Maskey@Sun.COM 		break;
179111767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
179211767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_enm_get_name(enm_h, &name)) != NWAM_SUCCESS)
179311767SAnurag.Maskey@Sun.COM 			goto name_error;
179411767SAnurag.Maskey@Sun.COM 		nwam_enm_free(enm_h);
179511767SAnurag.Maskey@Sun.COM 		enm_h = NULL;
179611767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_read(name, 0, &enm_h);
179711767SAnurag.Maskey@Sun.COM 		break;
179811767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
179911767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_loc_get_name(loc_h, &name)) != NWAM_SUCCESS)
180011767SAnurag.Maskey@Sun.COM 			goto name_error;
180111767SAnurag.Maskey@Sun.COM 		nwam_loc_free(loc_h);
180211767SAnurag.Maskey@Sun.COM 		loc_h = NULL;
180311767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_read(name, 0, &loc_h);
180411767SAnurag.Maskey@Sun.COM 		break;
180511767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
180611767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_known_wlan_get_name(wlan_h, &name))
180711767SAnurag.Maskey@Sun.COM 		    != NWAM_SUCCESS)
180811767SAnurag.Maskey@Sun.COM 			goto name_error;
180911767SAnurag.Maskey@Sun.COM 		nwam_known_wlan_free(wlan_h);
181011767SAnurag.Maskey@Sun.COM 		wlan_h = NULL;
181111767SAnurag.Maskey@Sun.COM 		ret = nwam_known_wlan_read(name, 0, &wlan_h);
181211767SAnurag.Maskey@Sun.COM 		break;
181311767SAnurag.Maskey@Sun.COM 	}
181411767SAnurag.Maskey@Sun.COM 
181511767SAnurag.Maskey@Sun.COM 	/* Exit this scope because handle already freed (call do_cancel()) */
181611767SAnurag.Maskey@Sun.COM 	need_to_commit = B_FALSE;
1817*13034SAnurag.Maskey@Oracle.COM 
181811767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS) {
1819*13034SAnurag.Maskey@Oracle.COM 		if (ret == NWAM_ENTITY_NOT_FOUND) {
1820*13034SAnurag.Maskey@Oracle.COM 			nerr("%s '%s' does not exist to revert to, removing it",
1821*13034SAnurag.Maskey@Oracle.COM 			    nwam_object_type_to_string(object_type), name);
1822*13034SAnurag.Maskey@Oracle.COM 		} else {
1823*13034SAnurag.Maskey@Oracle.COM 			nwamerr(ret, "Revert error");
1824*13034SAnurag.Maskey@Oracle.COM 		}
182511767SAnurag.Maskey@Sun.COM 		do_cancel();
182611767SAnurag.Maskey@Sun.COM 	}
1827*13034SAnurag.Maskey@Oracle.COM 	free(name);
182811767SAnurag.Maskey@Sun.COM 	return;
182911767SAnurag.Maskey@Sun.COM 
183011767SAnurag.Maskey@Sun.COM name_error:
183111767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
183211767SAnurag.Maskey@Sun.COM 		nwamerr(ret, "Revert error: get name error");
183311767SAnurag.Maskey@Sun.COM }
183411767SAnurag.Maskey@Sun.COM 
183511767SAnurag.Maskey@Sun.COM /*
183611767SAnurag.Maskey@Sun.COM  * Load a resource from persistent repository and enter the scope
183711767SAnurag.Maskey@Sun.COM  * of that resource.
183811767SAnurag.Maskey@Sun.COM  */
183911767SAnurag.Maskey@Sun.COM void
select_func(cmd_t * cmd)184011767SAnurag.Maskey@Sun.COM select_func(cmd_t *cmd)
184111767SAnurag.Maskey@Sun.COM {
184211767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
184311767SAnurag.Maskey@Sun.COM 	char		*name, *realname = NULL;
184411767SAnurag.Maskey@Sun.COM 
184511767SAnurag.Maskey@Sun.COM 	assert(cmd->cmd_argc > 0);
184611767SAnurag.Maskey@Sun.COM 	if (current_scope == NWAM_SCOPE_NCP && cmd->cmd_res2_type != RT2_NCU) {
184711767SAnurag.Maskey@Sun.COM 		nerr("cannot select '%s' at this scope",
184811767SAnurag.Maskey@Sun.COM 		    rt1_to_str(cmd->cmd_res1_type));
184911767SAnurag.Maskey@Sun.COM 		return;
185011767SAnurag.Maskey@Sun.COM 	}
185111767SAnurag.Maskey@Sun.COM 
185211767SAnurag.Maskey@Sun.COM 	/* argv[0] is name */
185311767SAnurag.Maskey@Sun.COM 	name = trim_quotes(cmd->cmd_argv[0]);
185411767SAnurag.Maskey@Sun.COM 	switch (cmd->cmd_res1_type) {
185511767SAnurag.Maskey@Sun.COM 	case RT1_LOC:
185611767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_read(name, 0, &loc_h);
185711767SAnurag.Maskey@Sun.COM 		if (ret == NWAM_SUCCESS) {
185811767SAnurag.Maskey@Sun.COM 			current_scope = NWAM_SCOPE_LOC;
185911767SAnurag.Maskey@Sun.COM 			(void) object_name_from_handle(NWAM_OBJECT_TYPE_LOC,
186011767SAnurag.Maskey@Sun.COM 			    loc_h, &realname);
186111767SAnurag.Maskey@Sun.COM 		}
186211767SAnurag.Maskey@Sun.COM 		break;
186311767SAnurag.Maskey@Sun.COM 	case RT1_ENM:
186411767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_read(name, 0, &enm_h);
186511767SAnurag.Maskey@Sun.COM 		if (ret == NWAM_SUCCESS) {
186611767SAnurag.Maskey@Sun.COM 			current_scope = NWAM_SCOPE_ENM;
186711767SAnurag.Maskey@Sun.COM 			(void) object_name_from_handle(NWAM_OBJECT_TYPE_ENM,
186811767SAnurag.Maskey@Sun.COM 			    enm_h, &realname);
186911767SAnurag.Maskey@Sun.COM 		}
187011767SAnurag.Maskey@Sun.COM 		break;
187111767SAnurag.Maskey@Sun.COM 	case RT1_WLAN:
187211767SAnurag.Maskey@Sun.COM 		ret = nwam_known_wlan_read(name, 0, &wlan_h);
187311767SAnurag.Maskey@Sun.COM 		if (ret == NWAM_SUCCESS) {
187411767SAnurag.Maskey@Sun.COM 			current_scope = NWAM_SCOPE_WLAN;
187511767SAnurag.Maskey@Sun.COM 			(void) object_name_from_handle
187611767SAnurag.Maskey@Sun.COM 			    (NWAM_OBJECT_TYPE_KNOWN_WLAN, wlan_h, &realname);
187711767SAnurag.Maskey@Sun.COM 		}
187811767SAnurag.Maskey@Sun.COM 		break;
187911767SAnurag.Maskey@Sun.COM 	case RT1_NCP:
188011767SAnurag.Maskey@Sun.COM 		if (cmd->cmd_res2_type == RT2_NCU) {
188111767SAnurag.Maskey@Sun.COM 			nwam_ncu_type_t		ncu_type;
188211767SAnurag.Maskey@Sun.COM 			nwam_ncu_class_t	ncu_class;
188311767SAnurag.Maskey@Sun.COM 
188411767SAnurag.Maskey@Sun.COM 			/* ncp must already be read */
188511767SAnurag.Maskey@Sun.COM 			if (ncp_h == NULL) {
188611767SAnurag.Maskey@Sun.COM 				nerr("Select error: NCP has not been read");
188711767SAnurag.Maskey@Sun.COM 				free(name);
188811767SAnurag.Maskey@Sun.COM 				return;
188911767SAnurag.Maskey@Sun.COM 			}
189011767SAnurag.Maskey@Sun.COM 			ncu_class = (nwam_ncu_class_t)cmd->cmd_ncu_class_type;
189111767SAnurag.Maskey@Sun.COM 			ncu_type = nwam_ncu_class_to_type(ncu_class);
189211767SAnurag.Maskey@Sun.COM 			ret = nwam_ncu_read(ncp_h, name, ncu_type, 0, &ncu_h);
189311767SAnurag.Maskey@Sun.COM 			if (ret == NWAM_SUCCESS) {
189411767SAnurag.Maskey@Sun.COM 				current_scope = NWAM_SCOPE_NCU;
189511767SAnurag.Maskey@Sun.COM 				(void) object_name_from_handle
189611767SAnurag.Maskey@Sun.COM 				    (NWAM_OBJECT_TYPE_NCU, ncu_h, &realname);
189711767SAnurag.Maskey@Sun.COM 			}
189811767SAnurag.Maskey@Sun.COM 		} else {
189911767SAnurag.Maskey@Sun.COM 			ret = nwam_ncp_read(name, 0, &ncp_h);
190011767SAnurag.Maskey@Sun.COM 			if (ret == NWAM_SUCCESS) {
190111767SAnurag.Maskey@Sun.COM 				current_scope = NWAM_SCOPE_NCP;
190211767SAnurag.Maskey@Sun.COM 				(void) object_name_from_handle
190311767SAnurag.Maskey@Sun.COM 				    (NWAM_OBJECT_TYPE_NCP, ncp_h, &realname);
190411767SAnurag.Maskey@Sun.COM 			}
190511767SAnurag.Maskey@Sun.COM 		}
190611767SAnurag.Maskey@Sun.COM 		break;
190711767SAnurag.Maskey@Sun.COM 	default:
190811767SAnurag.Maskey@Sun.COM 		nerr("Select error: unknown object-type");
190911767SAnurag.Maskey@Sun.COM 		free(name);
191011767SAnurag.Maskey@Sun.COM 		return;
191111767SAnurag.Maskey@Sun.COM 	}
191211767SAnurag.Maskey@Sun.COM 
191311767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS) {
191411767SAnurag.Maskey@Sun.COM 		nwamerr(ret, "Select error");
191511767SAnurag.Maskey@Sun.COM 	} else {
191611767SAnurag.Maskey@Sun.COM 		/* set the obj*_name or obj*_type depending on current scope */
191711767SAnurag.Maskey@Sun.COM 		if (current_scope == NWAM_SCOPE_NCU) {
191811767SAnurag.Maskey@Sun.COM 			obj2_type = RT2_NCU;
191911767SAnurag.Maskey@Sun.COM 			(void) strlcpy(obj2_name,
192011767SAnurag.Maskey@Sun.COM 			    realname != NULL ? realname : name,
192111767SAnurag.Maskey@Sun.COM 			    sizeof (obj2_name));
192211767SAnurag.Maskey@Sun.COM 		} else {
192311767SAnurag.Maskey@Sun.COM 			(void) strlcpy(obj1_name,
192411767SAnurag.Maskey@Sun.COM 			    realname != NULL ? realname : name,
192511767SAnurag.Maskey@Sun.COM 			    sizeof (obj1_name));
192611767SAnurag.Maskey@Sun.COM 			obj1_type = cmd->cmd_res1_type;
192711767SAnurag.Maskey@Sun.COM 		}
192811767SAnurag.Maskey@Sun.COM 	}
192911767SAnurag.Maskey@Sun.COM 	free(name);
193011767SAnurag.Maskey@Sun.COM 	free(realname);
193111767SAnurag.Maskey@Sun.COM }
193211767SAnurag.Maskey@Sun.COM 
193311767SAnurag.Maskey@Sun.COM /* Given an int for prop, returns it as string */
193411767SAnurag.Maskey@Sun.COM static const char *
pt_to_prop_name(nwam_object_type_t object_type,int pt_type)193511767SAnurag.Maskey@Sun.COM pt_to_prop_name(nwam_object_type_t object_type, int pt_type)
193611767SAnurag.Maskey@Sun.COM {
193711767SAnurag.Maskey@Sun.COM 	int i;
193811767SAnurag.Maskey@Sun.COM 	prop_table_entry_t *prop_table = get_prop_table(object_type);
193911767SAnurag.Maskey@Sun.COM 
194011767SAnurag.Maskey@Sun.COM 	for (i = 0; prop_table[i].pte_name != NULL; i++) {
194111767SAnurag.Maskey@Sun.COM 		if (pt_type == prop_table[i].pte_type)
194211767SAnurag.Maskey@Sun.COM 			return (prop_table[i].pte_name);
194311767SAnurag.Maskey@Sun.COM 	}
194411767SAnurag.Maskey@Sun.COM 	return (NULL);
194511767SAnurag.Maskey@Sun.COM }
194611767SAnurag.Maskey@Sun.COM 
194711767SAnurag.Maskey@Sun.COM /* Given a prop as a string, returns it as an int */
194811767SAnurag.Maskey@Sun.COM static int
prop_to_pt(nwam_object_type_t object_type,const char * prop)194911767SAnurag.Maskey@Sun.COM prop_to_pt(nwam_object_type_t object_type, const char *prop)
195011767SAnurag.Maskey@Sun.COM {
195111767SAnurag.Maskey@Sun.COM 	int i;
195211767SAnurag.Maskey@Sun.COM 	prop_table_entry_t *prop_table = get_prop_table(object_type);
195311767SAnurag.Maskey@Sun.COM 
195411767SAnurag.Maskey@Sun.COM 	for (i = 0; prop_table[i].pte_name != NULL; i++) {
195511767SAnurag.Maskey@Sun.COM 		if (strcmp(prop, prop_table[i].pte_name) == 0)
195611767SAnurag.Maskey@Sun.COM 			return (prop_table[i].pte_type);
195711767SAnurag.Maskey@Sun.COM 	}
195811767SAnurag.Maskey@Sun.COM 	return (-1);
195911767SAnurag.Maskey@Sun.COM }
196011767SAnurag.Maskey@Sun.COM 
196111767SAnurag.Maskey@Sun.COM /* Given a prop as an int, returns its type (nwam_value_type_t) */
196211767SAnurag.Maskey@Sun.COM static nwam_value_type_t
prop_value_type(nwam_object_type_t object_type,const char * prop)196311767SAnurag.Maskey@Sun.COM prop_value_type(nwam_object_type_t object_type, const char *prop)
196411767SAnurag.Maskey@Sun.COM {
196511767SAnurag.Maskey@Sun.COM 	nwam_error_t		ret;
196611767SAnurag.Maskey@Sun.COM 	nwam_value_type_t	value_type;
196711767SAnurag.Maskey@Sun.COM 
196811767SAnurag.Maskey@Sun.COM 	switch (object_type) {
196911767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
197011767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_get_prop_type(prop, &value_type);
197111767SAnurag.Maskey@Sun.COM 		break;
197211767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
197311767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_get_prop_type(prop, &value_type);
197411767SAnurag.Maskey@Sun.COM 		break;
197511767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
197611767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_get_prop_type(prop, &value_type);
197711767SAnurag.Maskey@Sun.COM 		break;
197811767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
197911767SAnurag.Maskey@Sun.COM 		ret = nwam_known_wlan_get_prop_type(prop, &value_type);
198011767SAnurag.Maskey@Sun.COM 		break;
198111767SAnurag.Maskey@Sun.COM 	}
198211767SAnurag.Maskey@Sun.COM 
198311767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
198411767SAnurag.Maskey@Sun.COM 		value_type = NWAM_VALUE_TYPE_UNKNOWN;
198511767SAnurag.Maskey@Sun.COM 
198611767SAnurag.Maskey@Sun.COM 	return (value_type);
198711767SAnurag.Maskey@Sun.COM }
198811767SAnurag.Maskey@Sun.COM 
198911767SAnurag.Maskey@Sun.COM /*
199011767SAnurag.Maskey@Sun.COM  * Converts input_str to an array nwam_value.
199111767SAnurag.Maskey@Sun.COM  * If is_list_prop, break input_str into array of strings first.
199211767SAnurag.Maskey@Sun.COM  */
199311767SAnurag.Maskey@Sun.COM static nwam_value_t
str_to_nwam_value(nwam_object_type_t object_type,char * input_str,int pt_type,boolean_t is_list_prop)199411767SAnurag.Maskey@Sun.COM str_to_nwam_value(nwam_object_type_t object_type, char *input_str, int pt_type,
199511767SAnurag.Maskey@Sun.COM     boolean_t is_list_prop)
199611767SAnurag.Maskey@Sun.COM {
199711767SAnurag.Maskey@Sun.COM 	int		i, n = 0, ret;
199811767SAnurag.Maskey@Sun.COM 	nwam_value_t	data;
199911767SAnurag.Maskey@Sun.COM 	char		**val;
200011767SAnurag.Maskey@Sun.COM 	int		max_str_num;
200111767SAnurag.Maskey@Sun.COM 
200211767SAnurag.Maskey@Sun.COM 	nwam_value_type_t	value_type;
200311767SAnurag.Maskey@Sun.COM 	int64_t			*int_vals;
200411767SAnurag.Maskey@Sun.COM 	uint64_t		*uint_vals;
200511767SAnurag.Maskey@Sun.COM 	boolean_t		*boolean_vals;
200611767SAnurag.Maskey@Sun.COM 
200711767SAnurag.Maskey@Sun.COM 	/*
200811767SAnurag.Maskey@Sun.COM 	 * Worst case is that each char separated by DELIMITER, so the
200911767SAnurag.Maskey@Sun.COM 	 * max number of sub strings is half of string length + 1.
201011767SAnurag.Maskey@Sun.COM 	 */
201111767SAnurag.Maskey@Sun.COM 	max_str_num = strlen(input_str) / 2 + 1;
201211767SAnurag.Maskey@Sun.COM 
201311767SAnurag.Maskey@Sun.COM 	val = calloc(max_str_num, sizeof (char *));
201411767SAnurag.Maskey@Sun.COM 	if (val == NULL) {
201511767SAnurag.Maskey@Sun.COM 		nerr("Out of memory");
201611767SAnurag.Maskey@Sun.COM 		return (NULL);
201711767SAnurag.Maskey@Sun.COM 	}
201811767SAnurag.Maskey@Sun.COM 
201911767SAnurag.Maskey@Sun.COM 	if (is_list_prop) {
202011767SAnurag.Maskey@Sun.COM 		char *tmp, *next;
202111767SAnurag.Maskey@Sun.COM 		/*
202211767SAnurag.Maskey@Sun.COM 		 * Break down input_str and save as array of sub strings.
202311767SAnurag.Maskey@Sun.COM 		 * Set num as the number of the sub strings.
202411767SAnurag.Maskey@Sun.COM 		 * Use nwam_tokenize_by_unescaped_delim() rather than strtok()
202511767SAnurag.Maskey@Sun.COM 		 * because DELIMITER may be escaped
202611767SAnurag.Maskey@Sun.COM 		 */
202711767SAnurag.Maskey@Sun.COM 		tmp = (char *)input_str;
202811767SAnurag.Maskey@Sun.COM 		while ((tmp = nwam_tokenize_by_unescaped_delim(tmp,
202911767SAnurag.Maskey@Sun.COM 		    NWAM_VALUE_DELIMITER_CHAR, &next)) != NULL) {
203011767SAnurag.Maskey@Sun.COM 			val[n++] = trim_quotes(tmp);
203111767SAnurag.Maskey@Sun.COM 			tmp = next;
203211767SAnurag.Maskey@Sun.COM 		}
203311767SAnurag.Maskey@Sun.COM 	} else {
203411767SAnurag.Maskey@Sun.COM 		val[n++] = trim_quotes(input_str);
203511767SAnurag.Maskey@Sun.COM 	}
203611767SAnurag.Maskey@Sun.COM 
203711767SAnurag.Maskey@Sun.COM 	/* initialize int_vals or booleans_vals depending on pt_type */
203811767SAnurag.Maskey@Sun.COM 	value_type = prop_value_type(object_type,
203911767SAnurag.Maskey@Sun.COM 	    pt_to_prop_name(object_type, pt_type));
204011767SAnurag.Maskey@Sun.COM 	if (value_type == NWAM_VALUE_TYPE_INT64) {
204111767SAnurag.Maskey@Sun.COM 		int_vals = calloc(n, sizeof (int64_t));
204211767SAnurag.Maskey@Sun.COM 		if (int_vals == NULL) {
204311767SAnurag.Maskey@Sun.COM 			nerr("Out of memory");
204411767SAnurag.Maskey@Sun.COM 			array_free((void **)val, max_str_num);
204511767SAnurag.Maskey@Sun.COM 			return (NULL);
204611767SAnurag.Maskey@Sun.COM 		}
204711767SAnurag.Maskey@Sun.COM 	} else if (value_type == NWAM_VALUE_TYPE_UINT64) {
204811767SAnurag.Maskey@Sun.COM 		uint_vals = calloc(n, sizeof (uint64_t));
204911767SAnurag.Maskey@Sun.COM 		if (uint_vals == NULL) {
205011767SAnurag.Maskey@Sun.COM 			nerr("Out of memory");
205111767SAnurag.Maskey@Sun.COM 			array_free((void **)val, max_str_num);
205211767SAnurag.Maskey@Sun.COM 			return (NULL);
205311767SAnurag.Maskey@Sun.COM 		}
205411767SAnurag.Maskey@Sun.COM 	} else if (value_type == NWAM_VALUE_TYPE_BOOLEAN) {
205511767SAnurag.Maskey@Sun.COM 		boolean_vals = calloc(n, sizeof (boolean_t));
205611767SAnurag.Maskey@Sun.COM 		if (boolean_vals == NULL) {
205711767SAnurag.Maskey@Sun.COM 			nerr("Out of memory");
205811767SAnurag.Maskey@Sun.COM 			array_free((void **)val, max_str_num);
205911767SAnurag.Maskey@Sun.COM 			return (NULL);
206011767SAnurag.Maskey@Sun.COM 		}
206111767SAnurag.Maskey@Sun.COM 	}
206211767SAnurag.Maskey@Sun.COM 	/* set the appropriate array */
206311767SAnurag.Maskey@Sun.COM 	for (i = 0; i < n; i++) {
206411767SAnurag.Maskey@Sun.COM 		switch (value_type) {
206511767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_STRING:
206611767SAnurag.Maskey@Sun.COM 			/* nothing to do - val already has the char** array */
206711767SAnurag.Maskey@Sun.COM 			break;
206811767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_INT64:
206911767SAnurag.Maskey@Sun.COM 		{
207011767SAnurag.Maskey@Sun.COM 			int_vals[i] = (int64_t)atoi(val[i]);
207111767SAnurag.Maskey@Sun.COM 			break;
207211767SAnurag.Maskey@Sun.COM 		}
207311767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_UINT64:
207411767SAnurag.Maskey@Sun.COM 		{
207511767SAnurag.Maskey@Sun.COM 			uint64_t str_as_enum;
207611767SAnurag.Maskey@Sun.COM 			char *endptr;
207711767SAnurag.Maskey@Sun.COM 
207811767SAnurag.Maskey@Sun.COM 			ret = nwam_value_string_get_uint64(
207911767SAnurag.Maskey@Sun.COM 			    pt_to_prop_name(object_type, pt_type),
208011767SAnurag.Maskey@Sun.COM 			    val[i], &str_as_enum);
208111767SAnurag.Maskey@Sun.COM 			/*
208211767SAnurag.Maskey@Sun.COM 			 * Returns _SUCCESS if value for enum is valid.
208311767SAnurag.Maskey@Sun.COM 			 * Returns _INVALID_ARG if property is not an enum.
208411767SAnurag.Maskey@Sun.COM 			 */
208511767SAnurag.Maskey@Sun.COM 			if (ret == NWAM_SUCCESS) {
208611767SAnurag.Maskey@Sun.COM 				uint_vals[i] = str_as_enum;
208711767SAnurag.Maskey@Sun.COM 			} else if (ret == NWAM_INVALID_ARG) {
208811767SAnurag.Maskey@Sun.COM 				uint_vals[i] = strtoul(val[i], &endptr, 10);
208911767SAnurag.Maskey@Sun.COM 				/* verify conversion is valid */
209011767SAnurag.Maskey@Sun.COM 				if (endptr == val[i]) {
209111767SAnurag.Maskey@Sun.COM 					free(uint_vals);
209211767SAnurag.Maskey@Sun.COM 					array_free((void **)val, max_str_num);
209311767SAnurag.Maskey@Sun.COM 					return (NULL);
209411767SAnurag.Maskey@Sun.COM 				}
209511767SAnurag.Maskey@Sun.COM 			} else {
209611767SAnurag.Maskey@Sun.COM 				free(uint_vals);
209711767SAnurag.Maskey@Sun.COM 				array_free((void **)val, max_str_num);
209811767SAnurag.Maskey@Sun.COM 				return (NULL);
209911767SAnurag.Maskey@Sun.COM 			}
210011767SAnurag.Maskey@Sun.COM 			break;
210111767SAnurag.Maskey@Sun.COM 		}
210211767SAnurag.Maskey@Sun.COM 		case NWAM_VALUE_TYPE_BOOLEAN:
210311767SAnurag.Maskey@Sun.COM 			boolean_vals[i] = str_to_boolean(val[i]);
210411767SAnurag.Maskey@Sun.COM 			break;
210511767SAnurag.Maskey@Sun.COM 		default:
210611767SAnurag.Maskey@Sun.COM 			array_free((void **)val, max_str_num);
210711767SAnurag.Maskey@Sun.COM 			return (NULL);
210811767SAnurag.Maskey@Sun.COM 		}
210911767SAnurag.Maskey@Sun.COM 	}
211011767SAnurag.Maskey@Sun.COM 
211111767SAnurag.Maskey@Sun.COM 	/* create nwam_value_t */
211211767SAnurag.Maskey@Sun.COM 	if (value_type == NWAM_VALUE_TYPE_STRING) {
211311767SAnurag.Maskey@Sun.COM 		ret = nwam_value_create_string_array(val, n, &data);
211411767SAnurag.Maskey@Sun.COM 	} else if (value_type == NWAM_VALUE_TYPE_INT64) {
211511767SAnurag.Maskey@Sun.COM 		ret = nwam_value_create_int64_array(int_vals, n, &data);
211611767SAnurag.Maskey@Sun.COM 		free(int_vals);
211711767SAnurag.Maskey@Sun.COM 	} else if (value_type == NWAM_VALUE_TYPE_UINT64) {
211811767SAnurag.Maskey@Sun.COM 		ret = nwam_value_create_uint64_array(uint_vals, n, &data);
211911767SAnurag.Maskey@Sun.COM 		free(uint_vals);
212011767SAnurag.Maskey@Sun.COM 	} else if (value_type == NWAM_VALUE_TYPE_BOOLEAN) {
212111767SAnurag.Maskey@Sun.COM 		ret = nwam_value_create_boolean_array(boolean_vals, n, &data);
212211767SAnurag.Maskey@Sun.COM 		free(boolean_vals);
212311767SAnurag.Maskey@Sun.COM 	}
212411767SAnurag.Maskey@Sun.COM 	array_free((void **)val, max_str_num);
212511767SAnurag.Maskey@Sun.COM 
212611767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS) {
212711767SAnurag.Maskey@Sun.COM 		nwamerr(ret, "Failed creating nwam_value");
212811767SAnurag.Maskey@Sun.COM 		return (NULL);
212911767SAnurag.Maskey@Sun.COM 	}
213011767SAnurag.Maskey@Sun.COM 
213111767SAnurag.Maskey@Sun.COM 	return (data);
213211767SAnurag.Maskey@Sun.COM }
213311767SAnurag.Maskey@Sun.COM 
213411767SAnurag.Maskey@Sun.COM /*
213511767SAnurag.Maskey@Sun.COM  * Displaying/Skipping of properties
213611767SAnurag.Maskey@Sun.COM  * ---------------------------------
213711767SAnurag.Maskey@Sun.COM  *
213811767SAnurag.Maskey@Sun.COM  * This table shows if a specific property should be shown if some
213911767SAnurag.Maskey@Sun.COM  * other property has a specific value.  This table is used by
214011767SAnurag.Maskey@Sun.COM  * show_prop_test(), which is called by set_func() and walkprop_func().
214111767SAnurag.Maskey@Sun.COM  *
214211767SAnurag.Maskey@Sun.COM  * An entry in the table looks like:
214311767SAnurag.Maskey@Sun.COM  *	{ property1, property2, { val1, val2, -1 } }
214411767SAnurag.Maskey@Sun.COM  * This is read as:
214511767SAnurag.Maskey@Sun.COM  *	"show property1 only if property2 has value val1 or val2"
214611767SAnurag.Maskey@Sun.COM  *
214711767SAnurag.Maskey@Sun.COM  * NB: If a property does not appear in this table, then that implies
214811767SAnurag.Maskey@Sun.COM  * that the property is always shown.
214911767SAnurag.Maskey@Sun.COM  *
215011767SAnurag.Maskey@Sun.COM  * A property can have more than one rule.  In such a case, the property is
215111767SAnurag.Maskey@Sun.COM  * displayed only any of the rules is satisfied.  This checking, however,
215211767SAnurag.Maskey@Sun.COM  * is recursive.  If a rule says that a property can be displayed, then the
215311767SAnurag.Maskey@Sun.COM  * property that's checked should also satisfy its rules.  In the above
215411767SAnurag.Maskey@Sun.COM  * example, if property1 is to be displayed, then property2 should also
215511767SAnurag.Maskey@Sun.COM  * satisfy its rules and be displayable.  This recursion is necessary as
215611767SAnurag.Maskey@Sun.COM  * properties that are not displayed (because rules are not satisfied) are
215711767SAnurag.Maskey@Sun.COM  * not deleted.
215811767SAnurag.Maskey@Sun.COM  */
215911767SAnurag.Maskey@Sun.COM 
216011767SAnurag.Maskey@Sun.COM /* The most number of values in pde_checkvals below */
216111767SAnurag.Maskey@Sun.COM #define	NWAM_CHECKVALS_MAX	5
216211767SAnurag.Maskey@Sun.COM 
216311767SAnurag.Maskey@Sun.COM typedef struct prop_display_entry {
216411767SAnurag.Maskey@Sun.COM 	const char	*pde_name;		/* property to show */
216511767SAnurag.Maskey@Sun.COM 	const char	*pde_checkname;		/* property to check */
216611767SAnurag.Maskey@Sun.COM 	int64_t	pde_checkvals[NWAM_CHECKVALS_MAX]; /* show prop for these */
216711767SAnurag.Maskey@Sun.COM } prop_display_entry_t;
216811767SAnurag.Maskey@Sun.COM 
216911767SAnurag.Maskey@Sun.COM /* Rules for showing properties: commented for clarity */
217011767SAnurag.Maskey@Sun.COM 
217111767SAnurag.Maskey@Sun.COM /*
217211767SAnurag.Maskey@Sun.COM  * Rules for NCUs
217311767SAnurag.Maskey@Sun.COM  * NB: There is no need to have an entry if a property is for IP only.
217411767SAnurag.Maskey@Sun.COM  *     This is taken care of in libnwam_ncp.c
217511767SAnurag.Maskey@Sun.COM  */
217611767SAnurag.Maskey@Sun.COM static prop_display_entry_t ncu_prop_display_entry_table[] = {
217711767SAnurag.Maskey@Sun.COM 	/* show priority-{group,mode} if activation == prioritized */
217811767SAnurag.Maskey@Sun.COM 	{ NWAM_NCU_PROP_PRIORITY_GROUP, NWAM_NCU_PROP_ACTIVATION_MODE,
217911767SAnurag.Maskey@Sun.COM 	    { NWAM_ACTIVATION_MODE_PRIORITIZED, -1 } },
218011767SAnurag.Maskey@Sun.COM 	{ NWAM_NCU_PROP_PRIORITY_MODE, NWAM_NCU_PROP_ACTIVATION_MODE,
218111767SAnurag.Maskey@Sun.COM 	    { NWAM_ACTIVATION_MODE_PRIORITIZED, -1 } },
218211767SAnurag.Maskey@Sun.COM 	/* show ipv4-addrsrc if ip-version == ipv4 */
218311767SAnurag.Maskey@Sun.COM 	{ NWAM_NCU_PROP_IPV4_ADDRSRC, NWAM_NCU_PROP_IP_VERSION,
218411767SAnurag.Maskey@Sun.COM 	    { IPV4_VERSION, -1 } },
218511767SAnurag.Maskey@Sun.COM 	/* show ipv4-addr if ipv4-addrsrc == static */
218611767SAnurag.Maskey@Sun.COM 	{ NWAM_NCU_PROP_IPV4_ADDR, NWAM_NCU_PROP_IPV4_ADDRSRC,
218711767SAnurag.Maskey@Sun.COM 	    { NWAM_ADDRSRC_STATIC, -1 } },
218811767SAnurag.Maskey@Sun.COM 	/* show ipv4-default-route if ip-version == ipv4 */
218911767SAnurag.Maskey@Sun.COM 	{ NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE, NWAM_NCU_PROP_IP_VERSION,
219011767SAnurag.Maskey@Sun.COM 	    { IPV4_VERSION, -1 } },
219111767SAnurag.Maskey@Sun.COM 	/* show ipv6-addrsrc if ip-version == ipv6 */
219211767SAnurag.Maskey@Sun.COM 	{ NWAM_NCU_PROP_IPV6_ADDRSRC, NWAM_NCU_PROP_IP_VERSION,
219311767SAnurag.Maskey@Sun.COM 	    { IPV6_VERSION, -1 } },
219411767SAnurag.Maskey@Sun.COM 	/* show ipv6-addr if ipv6-addrsrc == static */
219511767SAnurag.Maskey@Sun.COM 	{ NWAM_NCU_PROP_IPV6_ADDR, NWAM_NCU_PROP_IPV6_ADDRSRC,
219611767SAnurag.Maskey@Sun.COM 	    { NWAM_ADDRSRC_STATIC, -1 } },
219711767SAnurag.Maskey@Sun.COM 	/* show ipv6-default-route if ip-version == ipv6 */
219811767SAnurag.Maskey@Sun.COM 	{ NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE, NWAM_NCU_PROP_IP_VERSION,
219911767SAnurag.Maskey@Sun.COM 	    { IPV6_VERSION, -1 } },
220011767SAnurag.Maskey@Sun.COM 	{ NULL, NULL, { -1 } }
220111767SAnurag.Maskey@Sun.COM };
220211767SAnurag.Maskey@Sun.COM 
220311767SAnurag.Maskey@Sun.COM /* Rules for ENMs */
220411767SAnurag.Maskey@Sun.COM static prop_display_entry_t enm_prop_display_entry_table[] = {
220511767SAnurag.Maskey@Sun.COM 	/* show conditions if activation-mode == conditional-{all,any} */
220611767SAnurag.Maskey@Sun.COM 	{ NWAM_ENM_PROP_CONDITIONS, NWAM_ENM_PROP_ACTIVATION_MODE,
220711767SAnurag.Maskey@Sun.COM 	    { NWAM_ACTIVATION_MODE_CONDITIONAL_ALL,
220811767SAnurag.Maskey@Sun.COM 	    NWAM_ACTIVATION_MODE_CONDITIONAL_ANY, -1 } },
220911767SAnurag.Maskey@Sun.COM 	{ NULL, NULL, { -1 } }
221011767SAnurag.Maskey@Sun.COM };
221111767SAnurag.Maskey@Sun.COM 
221211767SAnurag.Maskey@Sun.COM /* Rules for LOCations */
221311767SAnurag.Maskey@Sun.COM static prop_display_entry_t loc_prop_display_entry_table[] = {
221411767SAnurag.Maskey@Sun.COM 	/* show conditions if activation-mode == conditional-{all,any} */
221511767SAnurag.Maskey@Sun.COM 	{ NWAM_LOC_PROP_CONDITIONS, NWAM_LOC_PROP_ACTIVATION_MODE,
221611767SAnurag.Maskey@Sun.COM 	    { NWAM_ACTIVATION_MODE_CONDITIONAL_ALL,
221711767SAnurag.Maskey@Sun.COM 	    NWAM_ACTIVATION_MODE_CONDITIONAL_ANY, -1 } },
221811767SAnurag.Maskey@Sun.COM 	/* show dns-nameservice-configsrc if nameservices == dns */
221911767SAnurag.Maskey@Sun.COM 	{ NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC, NWAM_LOC_PROP_NAMESERVICES,
222011767SAnurag.Maskey@Sun.COM 	    { NWAM_NAMESERVICES_DNS, -1 } },
222111767SAnurag.Maskey@Sun.COM 	/* show other DNS options if dns-nameservices-configsrc == manual */
222211767SAnurag.Maskey@Sun.COM 	{ NWAM_LOC_PROP_DNS_NAMESERVICE_DOMAIN,
222311767SAnurag.Maskey@Sun.COM 	    NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC,
222411767SAnurag.Maskey@Sun.COM 	    { NWAM_CONFIGSRC_MANUAL, -1 } },
222511767SAnurag.Maskey@Sun.COM 	{ NWAM_LOC_PROP_DNS_NAMESERVICE_SERVERS,
222611767SAnurag.Maskey@Sun.COM 	    NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC,
222711767SAnurag.Maskey@Sun.COM 	    { NWAM_CONFIGSRC_MANUAL, -1 } },
222811767SAnurag.Maskey@Sun.COM 	{ NWAM_LOC_PROP_DNS_NAMESERVICE_SEARCH,
222911767SAnurag.Maskey@Sun.COM 	    NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC,
223011767SAnurag.Maskey@Sun.COM 	    { NWAM_CONFIGSRC_MANUAL, -1 } },
223111767SAnurag.Maskey@Sun.COM 	/* show nis-nameservice-configsrc if nameservices == nis */
223211767SAnurag.Maskey@Sun.COM 	{ NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC, NWAM_LOC_PROP_NAMESERVICES,
223311767SAnurag.Maskey@Sun.COM 	    { NWAM_NAMESERVICES_NIS, -1 } },
223411767SAnurag.Maskey@Sun.COM 	/* show nis-nameservice-servers if nis-nameservice-configsrc = manual */
223511767SAnurag.Maskey@Sun.COM 	{ NWAM_LOC_PROP_NIS_NAMESERVICE_SERVERS,
223611767SAnurag.Maskey@Sun.COM 	    NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC,
223711767SAnurag.Maskey@Sun.COM 	    { NWAM_CONFIGSRC_MANUAL, -1 } },
223811767SAnurag.Maskey@Sun.COM 	/* show ldap-nameservice-configsrc if nameservices == ldap */
223911767SAnurag.Maskey@Sun.COM 	{ NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC, NWAM_LOC_PROP_NAMESERVICES,
224011767SAnurag.Maskey@Sun.COM 	    { NWAM_NAMESERVICES_LDAP, -1 } },
224111767SAnurag.Maskey@Sun.COM 	/* show ldap-nameservice-servers if ldap-nameservice-configsrc=manual */
224211767SAnurag.Maskey@Sun.COM 	{ NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS,
224311767SAnurag.Maskey@Sun.COM 	    NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC,
224411767SAnurag.Maskey@Sun.COM 	    { NWAM_CONFIGSRC_MANUAL, -1 } },
224511767SAnurag.Maskey@Sun.COM 	/* show default-domain if {nis,ldap}-nameservice-configsrc == manual */
224611767SAnurag.Maskey@Sun.COM 	{ NWAM_LOC_PROP_DEFAULT_DOMAIN, NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC,
224711767SAnurag.Maskey@Sun.COM 	    { NWAM_CONFIGSRC_MANUAL, -1 } },
224811767SAnurag.Maskey@Sun.COM 	{ NWAM_LOC_PROP_DEFAULT_DOMAIN,
224911767SAnurag.Maskey@Sun.COM 	    NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC,
225011767SAnurag.Maskey@Sun.COM 	    { NWAM_CONFIGSRC_MANUAL, -1 } },
225111767SAnurag.Maskey@Sun.COM 	{ NULL, NULL, { -1 } }
225211767SAnurag.Maskey@Sun.COM };
225311767SAnurag.Maskey@Sun.COM 
225411767SAnurag.Maskey@Sun.COM /* Rules for Known WLANs */
225511767SAnurag.Maskey@Sun.COM static prop_display_entry_t wlan_prop_display_entry_table[] = {
225611767SAnurag.Maskey@Sun.COM 	/* no rules for WLANs */
225711767SAnurag.Maskey@Sun.COM 	{ NULL, NULL, { -1 } }
225811767SAnurag.Maskey@Sun.COM };
225911767SAnurag.Maskey@Sun.COM 
226011767SAnurag.Maskey@Sun.COM /* Returns the appropriate rules table for the given object type */
226111767SAnurag.Maskey@Sun.COM static prop_display_entry_t *
get_prop_display_table(nwam_object_type_t object_type)226211767SAnurag.Maskey@Sun.COM get_prop_display_table(nwam_object_type_t object_type)
226311767SAnurag.Maskey@Sun.COM {
226411767SAnurag.Maskey@Sun.COM 	switch (object_type) {
226511767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
226611767SAnurag.Maskey@Sun.COM 		return (ncu_prop_display_entry_table);
226711767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
226811767SAnurag.Maskey@Sun.COM 		return (loc_prop_display_entry_table);
226911767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
227011767SAnurag.Maskey@Sun.COM 		return (enm_prop_display_entry_table);
227111767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
227211767SAnurag.Maskey@Sun.COM 		return (wlan_prop_display_entry_table);
227311767SAnurag.Maskey@Sun.COM 	}
227411767SAnurag.Maskey@Sun.COM 	return (NULL);
227511767SAnurag.Maskey@Sun.COM }
227611767SAnurag.Maskey@Sun.COM 
227711767SAnurag.Maskey@Sun.COM /*
227811767SAnurag.Maskey@Sun.COM  * Tests whether prop must be shown during a walk depending on the
227911767SAnurag.Maskey@Sun.COM  * value of a different property.
228011767SAnurag.Maskey@Sun.COM  *
228111767SAnurag.Maskey@Sun.COM  * This function is also used by set_func() to determine whether the
228211767SAnurag.Maskey@Sun.COM  * property being set should be allowed or not.  If the property
228311767SAnurag.Maskey@Sun.COM  * would not be displayed in a walk, then it should not be set.
228411767SAnurag.Maskey@Sun.COM  *
228511767SAnurag.Maskey@Sun.COM  * The checked_props and num_checked arguments are used to avoid circular
228611767SAnurag.Maskey@Sun.COM  * dependencies between properties.  When this function recursively calls
228711767SAnurag.Maskey@Sun.COM  * itself, it adds the property that it just checked to the checked_props
228811767SAnurag.Maskey@Sun.COM  * list.
228911767SAnurag.Maskey@Sun.COM  */
229011767SAnurag.Maskey@Sun.COM static boolean_t
show_prop_test(nwam_object_type_t object_type,const char * prop,prop_display_entry_t * display_list,char ** checked_props,int num_checked)229111767SAnurag.Maskey@Sun.COM show_prop_test(nwam_object_type_t object_type, const char *prop,
229211767SAnurag.Maskey@Sun.COM     prop_display_entry_t *display_list, char **checked_props, int num_checked)
229311767SAnurag.Maskey@Sun.COM {
229411767SAnurag.Maskey@Sun.COM 	nwam_error_t		ret;
229511767SAnurag.Maskey@Sun.COM 	nwam_value_t		prop_val;
229611767SAnurag.Maskey@Sun.COM 	nwam_value_type_t	prop_type;
229711767SAnurag.Maskey@Sun.COM 	int			i, j, k;
229811767SAnurag.Maskey@Sun.COM 	boolean_t		prop_found = B_FALSE, show_prop = B_FALSE;
229911767SAnurag.Maskey@Sun.COM 
230011767SAnurag.Maskey@Sun.COM 	/*
230111767SAnurag.Maskey@Sun.COM 	 * Check if this property has already been checked previously in
230211767SAnurag.Maskey@Sun.COM 	 * the recursion.  If so, return B_FALSE so that the initial prop
230311767SAnurag.Maskey@Sun.COM 	 * is not displayed.
230411767SAnurag.Maskey@Sun.COM 	 */
230511767SAnurag.Maskey@Sun.COM 	for (i = 0; i < num_checked; i++) {
230611767SAnurag.Maskey@Sun.COM 		if (strcmp(prop, checked_props[i]) == 0) {
230711767SAnurag.Maskey@Sun.COM 			free(checked_props);
230811767SAnurag.Maskey@Sun.COM 			return (B_FALSE);
230911767SAnurag.Maskey@Sun.COM 		}
231011767SAnurag.Maskey@Sun.COM 	}
231111767SAnurag.Maskey@Sun.COM 
231211767SAnurag.Maskey@Sun.COM 	for (i = 0; display_list[i].pde_name != NULL; i++) {
231311767SAnurag.Maskey@Sun.COM 		if (strcmp(prop, display_list[i].pde_name) != 0)
231411767SAnurag.Maskey@Sun.COM 			continue;
231511767SAnurag.Maskey@Sun.COM 		prop_found = B_TRUE;
231611767SAnurag.Maskey@Sun.COM 
231711767SAnurag.Maskey@Sun.COM 		/* get the value(s) of the (other) property to check */
231811767SAnurag.Maskey@Sun.COM 		switch (object_type) {
231911767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_NCU:
232011767SAnurag.Maskey@Sun.COM 			ret = nwam_ncu_get_prop_value(ncu_h,
232111767SAnurag.Maskey@Sun.COM 			    display_list[i].pde_checkname, &prop_val);
232211767SAnurag.Maskey@Sun.COM 			break;
232311767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_LOC:
232411767SAnurag.Maskey@Sun.COM 			ret = nwam_loc_get_prop_value(loc_h,
232511767SAnurag.Maskey@Sun.COM 			    display_list[i].pde_checkname, &prop_val);
232611767SAnurag.Maskey@Sun.COM 			break;
232711767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_ENM:
232811767SAnurag.Maskey@Sun.COM 			ret = nwam_enm_get_prop_value(enm_h,
232911767SAnurag.Maskey@Sun.COM 			    display_list[i].pde_checkname, &prop_val);
233011767SAnurag.Maskey@Sun.COM 			break;
233111767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_KNOWN_WLAN:
233211767SAnurag.Maskey@Sun.COM 			return (B_TRUE);
233311767SAnurag.Maskey@Sun.COM 		}
233411767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
233511767SAnurag.Maskey@Sun.COM 			continue;
233611767SAnurag.Maskey@Sun.COM 
233711767SAnurag.Maskey@Sun.COM 		/* prop_val may contain a uint64 array or a boolean */
233811767SAnurag.Maskey@Sun.COM 		if (nwam_value_get_type(prop_val, &prop_type) != NWAM_SUCCESS)
233911767SAnurag.Maskey@Sun.COM 			continue;
234011767SAnurag.Maskey@Sun.COM 
234111767SAnurag.Maskey@Sun.COM 		if (prop_type == NWAM_VALUE_TYPE_UINT64) {
234211767SAnurag.Maskey@Sun.COM 			uint64_t	*prop_uvals;
234311767SAnurag.Maskey@Sun.COM 			int64_t		*check_uvals;
234411767SAnurag.Maskey@Sun.COM 			uint_t		numvals;
234511767SAnurag.Maskey@Sun.COM 
234611767SAnurag.Maskey@Sun.COM 			if (nwam_value_get_uint64_array(prop_val, &prop_uvals,
234711767SAnurag.Maskey@Sun.COM 			    &numvals) != NWAM_SUCCESS) {
234811767SAnurag.Maskey@Sun.COM 				nwam_value_free(prop_val);
234911767SAnurag.Maskey@Sun.COM 				continue;
235011767SAnurag.Maskey@Sun.COM 			}
235111767SAnurag.Maskey@Sun.COM 
235211767SAnurag.Maskey@Sun.COM 			/* for each value in uvals, check each value in table */
235311767SAnurag.Maskey@Sun.COM 			for (j = 0; j < numvals; j++) {
235411767SAnurag.Maskey@Sun.COM 				check_uvals = display_list[i].pde_checkvals;
235511767SAnurag.Maskey@Sun.COM 				for (k = 0; check_uvals[k] != -1; k++) {
235611767SAnurag.Maskey@Sun.COM 					/* show if uvals[j] matches */
235711767SAnurag.Maskey@Sun.COM 					if (prop_uvals[j] ==
235811767SAnurag.Maskey@Sun.COM 					    (uint64_t)check_uvals[k]) {
235911767SAnurag.Maskey@Sun.COM 						show_prop = B_TRUE;
236011767SAnurag.Maskey@Sun.COM 						goto next_rule;
236111767SAnurag.Maskey@Sun.COM 					}
236211767SAnurag.Maskey@Sun.COM 				}
236311767SAnurag.Maskey@Sun.COM 			}
236411767SAnurag.Maskey@Sun.COM 		} else if (prop_type == NWAM_VALUE_TYPE_BOOLEAN) {
236511767SAnurag.Maskey@Sun.COM 			boolean_t bval;
236611767SAnurag.Maskey@Sun.COM 
236711767SAnurag.Maskey@Sun.COM 			if (nwam_value_get_boolean(prop_val, &bval) !=
236811767SAnurag.Maskey@Sun.COM 			    NWAM_SUCCESS) {
236911767SAnurag.Maskey@Sun.COM 				nwam_value_free(prop_val);
237011767SAnurag.Maskey@Sun.COM 				continue;
237111767SAnurag.Maskey@Sun.COM 			}
237211767SAnurag.Maskey@Sun.COM 
237311767SAnurag.Maskey@Sun.COM 			for (k = 0;
237411767SAnurag.Maskey@Sun.COM 			    display_list[i].pde_checkvals[k] != -1;
237511767SAnurag.Maskey@Sun.COM 			    k++) {
237611767SAnurag.Maskey@Sun.COM 				/* show if bval matches */
237711767SAnurag.Maskey@Sun.COM 				if (bval == (boolean_t)
237811767SAnurag.Maskey@Sun.COM 				    display_list[i].pde_checkvals[k]) {
237911767SAnurag.Maskey@Sun.COM 					show_prop = B_TRUE;
238011767SAnurag.Maskey@Sun.COM 					goto next_rule;
238111767SAnurag.Maskey@Sun.COM 				}
238211767SAnurag.Maskey@Sun.COM 			}
238311767SAnurag.Maskey@Sun.COM 		}
238411767SAnurag.Maskey@Sun.COM 
238511767SAnurag.Maskey@Sun.COM next_rule:
238611767SAnurag.Maskey@Sun.COM 		nwam_value_free(prop_val);
238711767SAnurag.Maskey@Sun.COM 		/*
238811767SAnurag.Maskey@Sun.COM 		 * If show_prop is set, then a rule is satisfied; no need to
238911767SAnurag.Maskey@Sun.COM 		 * check other rules for this prop.  However, recursively
239011767SAnurag.Maskey@Sun.COM 		 * check if the checked prop (pde_checkname) satisfies its
239111767SAnurag.Maskey@Sun.COM 		 * rules.  Also, update the check_props array with this prop.
239211767SAnurag.Maskey@Sun.COM 		 */
239311767SAnurag.Maskey@Sun.COM 		if (show_prop) {
239411767SAnurag.Maskey@Sun.COM 			char **newprops = realloc(checked_props,
239511767SAnurag.Maskey@Sun.COM 			    ++num_checked * sizeof (char *));
239611767SAnurag.Maskey@Sun.COM 			if (newprops == NULL) {
239711767SAnurag.Maskey@Sun.COM 				free(checked_props);
239811767SAnurag.Maskey@Sun.COM 				return (B_FALSE);
239911767SAnurag.Maskey@Sun.COM 			}
240011767SAnurag.Maskey@Sun.COM 			checked_props = newprops;
240111767SAnurag.Maskey@Sun.COM 			checked_props[num_checked - 1] = (char *)prop;
240211767SAnurag.Maskey@Sun.COM 
240311767SAnurag.Maskey@Sun.COM 			return (show_prop_test(object_type,
240411767SAnurag.Maskey@Sun.COM 			    display_list[i].pde_checkname, display_list,
240511767SAnurag.Maskey@Sun.COM 			    checked_props, num_checked));
240611767SAnurag.Maskey@Sun.COM 		}
240711767SAnurag.Maskey@Sun.COM 	}
240811767SAnurag.Maskey@Sun.COM 
240911767SAnurag.Maskey@Sun.COM 	/*
241011767SAnurag.Maskey@Sun.COM 	 * If we are here and prop_found is set, it means that no rules were
241111767SAnurag.Maskey@Sun.COM 	 * satisfied by prop; return B_FALSE.  If prop_found is not set, then
241211767SAnurag.Maskey@Sun.COM 	 * prop did not have a rule so it must be displayed; return B_TRUE.
241311767SAnurag.Maskey@Sun.COM 	 */
241411767SAnurag.Maskey@Sun.COM 	free(checked_props);
241511767SAnurag.Maskey@Sun.COM 	if (prop_found)
241611767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
241711767SAnurag.Maskey@Sun.COM 	else
241811767SAnurag.Maskey@Sun.COM 		return (B_TRUE);
241911767SAnurag.Maskey@Sun.COM }
242011767SAnurag.Maskey@Sun.COM 
242111767SAnurag.Maskey@Sun.COM /*
242211767SAnurag.Maskey@Sun.COM  * Returns true if the given property is read-only and cannot be modified.
242311767SAnurag.Maskey@Sun.COM  */
242411767SAnurag.Maskey@Sun.COM static boolean_t
is_prop_read_only(nwam_object_type_t object_type,const char * prop)242511767SAnurag.Maskey@Sun.COM is_prop_read_only(nwam_object_type_t object_type, const char *prop)
242611767SAnurag.Maskey@Sun.COM {
242711767SAnurag.Maskey@Sun.COM 	boolean_t ro;
242811767SAnurag.Maskey@Sun.COM 
242911767SAnurag.Maskey@Sun.COM 	switch (object_type) {
243011767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
243111767SAnurag.Maskey@Sun.COM 		if (nwam_ncu_prop_read_only(prop, &ro) == NWAM_SUCCESS && ro)
243211767SAnurag.Maskey@Sun.COM 			return (B_TRUE);
243311767SAnurag.Maskey@Sun.COM 		break;
243411767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
243511767SAnurag.Maskey@Sun.COM 		if (nwam_enm_prop_read_only(prop, &ro) == NWAM_SUCCESS && ro)
243611767SAnurag.Maskey@Sun.COM 			return (B_TRUE);
243711767SAnurag.Maskey@Sun.COM 		break;
243811767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
243911767SAnurag.Maskey@Sun.COM 		if (nwam_loc_prop_read_only(prop, &ro) == NWAM_SUCCESS && ro)
244011767SAnurag.Maskey@Sun.COM 			return (B_TRUE);
244111767SAnurag.Maskey@Sun.COM 		break;
244211767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
244311767SAnurag.Maskey@Sun.COM 		/* no read-only properties for WLANs */
244411767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
244511767SAnurag.Maskey@Sun.COM 	}
244611767SAnurag.Maskey@Sun.COM 	return (B_FALSE);
244711767SAnurag.Maskey@Sun.COM }
244811767SAnurag.Maskey@Sun.COM 
244911767SAnurag.Maskey@Sun.COM /* Returns true if the property is multi-valued */
245011767SAnurag.Maskey@Sun.COM static boolean_t
is_prop_multivalued(nwam_object_type_t object_type,const char * prop)245111767SAnurag.Maskey@Sun.COM is_prop_multivalued(nwam_object_type_t object_type, const char *prop)
245211767SAnurag.Maskey@Sun.COM {
245311767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
245411767SAnurag.Maskey@Sun.COM 	boolean_t	multi;
245511767SAnurag.Maskey@Sun.COM 
245611767SAnurag.Maskey@Sun.COM 	switch (object_type) {
245711767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
245811767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_prop_multivalued(prop, &multi);
245911767SAnurag.Maskey@Sun.COM 		break;
246011767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
246111767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_prop_multivalued(prop, &multi);
246211767SAnurag.Maskey@Sun.COM 		break;
246311767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
246411767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_prop_multivalued(prop, &multi);
246511767SAnurag.Maskey@Sun.COM 		break;
246611767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
246711767SAnurag.Maskey@Sun.COM 		ret = nwam_known_wlan_prop_multivalued(prop, &multi);
246811767SAnurag.Maskey@Sun.COM 		break;
246911767SAnurag.Maskey@Sun.COM 	}
247011767SAnurag.Maskey@Sun.COM 
247111767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
247211767SAnurag.Maskey@Sun.COM 		multi = B_FALSE;
247311767SAnurag.Maskey@Sun.COM 	return (multi);
247411767SAnurag.Maskey@Sun.COM }
247511767SAnurag.Maskey@Sun.COM 
247611767SAnurag.Maskey@Sun.COM /*
247711767SAnurag.Maskey@Sun.COM  * Prints out error message specific to property that could not be set.
247811767SAnurag.Maskey@Sun.COM  * Property description is used to help guide user in entering correct value.
247911767SAnurag.Maskey@Sun.COM  */
248011767SAnurag.Maskey@Sun.COM static void
invalid_set_prop_msg(const char * prop,nwam_error_t err)248111767SAnurag.Maskey@Sun.COM invalid_set_prop_msg(const char *prop, nwam_error_t err)
248211767SAnurag.Maskey@Sun.COM {
248311767SAnurag.Maskey@Sun.COM 	const char *description;
248411767SAnurag.Maskey@Sun.COM 
248511767SAnurag.Maskey@Sun.COM 	if (err == NWAM_SUCCESS)
248611767SAnurag.Maskey@Sun.COM 		return;
248711767SAnurag.Maskey@Sun.COM 
248811767SAnurag.Maskey@Sun.COM 	if (err != NWAM_ENTITY_INVALID_VALUE) {
248911767SAnurag.Maskey@Sun.COM 		nwamerr(err, "Set error");
249011767SAnurag.Maskey@Sun.COM 		return;
249111767SAnurag.Maskey@Sun.COM 	}
249211767SAnurag.Maskey@Sun.COM 
249311767SAnurag.Maskey@Sun.COM 	switch (active_object_type()) {
249411767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
249511767SAnurag.Maskey@Sun.COM 		(void) nwam_ncu_get_prop_description(prop, &description);
249611767SAnurag.Maskey@Sun.COM 		break;
249711767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
249811767SAnurag.Maskey@Sun.COM 		(void) nwam_loc_get_prop_description(prop, &description);
249911767SAnurag.Maskey@Sun.COM 		break;
250011767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
250111767SAnurag.Maskey@Sun.COM 		(void) nwam_enm_get_prop_description(prop, &description);
250211767SAnurag.Maskey@Sun.COM 		break;
250311767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
250411767SAnurag.Maskey@Sun.COM 		(void) nwam_known_wlan_get_prop_description(prop,
250511767SAnurag.Maskey@Sun.COM 		    &description);
250611767SAnurag.Maskey@Sun.COM 		break;
250711767SAnurag.Maskey@Sun.COM 	}
250811767SAnurag.Maskey@Sun.COM 	nerr("Set error: invalid value\n'%s' %s", prop, description);
250911767SAnurag.Maskey@Sun.COM }
251011767SAnurag.Maskey@Sun.COM 
251111767SAnurag.Maskey@Sun.COM /*
251211767SAnurag.Maskey@Sun.COM  * Sets the property value.
251311767SAnurag.Maskey@Sun.COM  * Read-only properties and objects cannot be set.
251411767SAnurag.Maskey@Sun.COM  * "read-only" is a special in that it can be set on a read-only object.
251511767SAnurag.Maskey@Sun.COM  * The object has to be committed before other properties can be set.
251611767SAnurag.Maskey@Sun.COM  * Also uses show_prop_test() to test if the property being set would
251711767SAnurag.Maskey@Sun.COM  * be skipped during a walk (as determined by the value of some other
251811767SAnurag.Maskey@Sun.COM  * property).  If so, then it cannot be set.
251911767SAnurag.Maskey@Sun.COM  */
252011767SAnurag.Maskey@Sun.COM void
set_func(cmd_t * cmd)252111767SAnurag.Maskey@Sun.COM set_func(cmd_t *cmd)
252211767SAnurag.Maskey@Sun.COM {
252311767SAnurag.Maskey@Sun.COM 	int			pt_type = cmd->cmd_prop_type;
252411767SAnurag.Maskey@Sun.COM 	nwam_error_t		ret = NWAM_SUCCESS;
252511767SAnurag.Maskey@Sun.COM 	nwam_value_t		prop_value;
252611767SAnurag.Maskey@Sun.COM 	const char		*prop;
252711767SAnurag.Maskey@Sun.COM 	boolean_t		is_listprop = B_FALSE;
252811767SAnurag.Maskey@Sun.COM 	nwam_object_type_t	object_type;
252911767SAnurag.Maskey@Sun.COM 	prop_display_entry_t	*prop_table;
253011767SAnurag.Maskey@Sun.COM 	char			**checked = NULL;
253111767SAnurag.Maskey@Sun.COM 
253211767SAnurag.Maskey@Sun.COM 	assert(cmd->cmd_argc > 0);
253311767SAnurag.Maskey@Sun.COM 
253411767SAnurag.Maskey@Sun.COM 	object_type = active_object_type();
253511767SAnurag.Maskey@Sun.COM 	prop_table = get_prop_display_table(object_type);
253611767SAnurag.Maskey@Sun.COM 
253711767SAnurag.Maskey@Sun.COM 	/* argv[0] is property value */
253811767SAnurag.Maskey@Sun.COM 	if ((prop = pt_to_prop_name(object_type, pt_type)) == NULL) {
253911767SAnurag.Maskey@Sun.COM 		nerr("Set error: invalid %s property: '%s'",
254011767SAnurag.Maskey@Sun.COM 		    scope_to_str(current_scope), pt_to_str(pt_type));
254111767SAnurag.Maskey@Sun.COM 		return;
254211767SAnurag.Maskey@Sun.COM 	}
254311767SAnurag.Maskey@Sun.COM 
254411767SAnurag.Maskey@Sun.COM 	/* check if property can be set */
254511767SAnurag.Maskey@Sun.COM 	if (is_prop_read_only(object_type, prop)) {
254611767SAnurag.Maskey@Sun.COM 		nerr("Set error: property '%s' is read-only", prop);
254711767SAnurag.Maskey@Sun.COM 		return;
254811767SAnurag.Maskey@Sun.COM 	}
254911767SAnurag.Maskey@Sun.COM 	if (!show_prop_test(object_type, prop, prop_table, checked, 0)) {
255011767SAnurag.Maskey@Sun.COM 		if (interactive_mode) {
255111767SAnurag.Maskey@Sun.COM 			(void) printf(gettext("setting property '%s' "
255211767SAnurag.Maskey@Sun.COM 			    "has no effect\n"), prop);
255311767SAnurag.Maskey@Sun.COM 		}
255411767SAnurag.Maskey@Sun.COM 	}
255511767SAnurag.Maskey@Sun.COM 
255611767SAnurag.Maskey@Sun.COM 	is_listprop = is_prop_multivalued(object_type, prop);
255711767SAnurag.Maskey@Sun.COM 	prop_value = str_to_nwam_value(object_type, cmd->cmd_argv[0], pt_type,
255811767SAnurag.Maskey@Sun.COM 	    is_listprop);
255911767SAnurag.Maskey@Sun.COM 	if (prop_value == NULL) {
256011767SAnurag.Maskey@Sun.COM 		invalid_set_prop_msg(prop, NWAM_ENTITY_INVALID_VALUE);
256111767SAnurag.Maskey@Sun.COM 		return;
256211767SAnurag.Maskey@Sun.COM 	}
256311767SAnurag.Maskey@Sun.COM 
256411767SAnurag.Maskey@Sun.COM 	/* set the property value */
256511767SAnurag.Maskey@Sun.COM 	switch (object_type) {
256611767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
256711767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_set_prop_value(ncu_h, prop, prop_value);
256811767SAnurag.Maskey@Sun.COM 		break;
256911767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
257011767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_set_prop_value(loc_h, prop, prop_value);
257111767SAnurag.Maskey@Sun.COM 		break;
257211767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
257311767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_set_prop_value(enm_h, prop, prop_value);
257411767SAnurag.Maskey@Sun.COM 		break;
257511767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
257611767SAnurag.Maskey@Sun.COM 		ret = nwam_known_wlan_set_prop_value(wlan_h, prop, prop_value);
257711767SAnurag.Maskey@Sun.COM 		break;
257811767SAnurag.Maskey@Sun.COM 	}
257911767SAnurag.Maskey@Sun.COM 	nwam_value_free(prop_value);
258011767SAnurag.Maskey@Sun.COM 
258111767SAnurag.Maskey@Sun.COM 	/* delete other properties if needed */
258211767SAnurag.Maskey@Sun.COM 	if (ret == NWAM_SUCCESS)
258311767SAnurag.Maskey@Sun.COM 		need_to_commit = B_TRUE;
258411767SAnurag.Maskey@Sun.COM 	else
258511767SAnurag.Maskey@Sun.COM 		invalid_set_prop_msg(prop, ret);
258611767SAnurag.Maskey@Sun.COM }
258711767SAnurag.Maskey@Sun.COM 
258811767SAnurag.Maskey@Sun.COM static int
list_callback(nwam_object_type_t object_type,void * handle,boolean_t * list_msgp,const char * msg)258911767SAnurag.Maskey@Sun.COM list_callback(nwam_object_type_t object_type, void *handle,
259011767SAnurag.Maskey@Sun.COM     boolean_t *list_msgp, const char *msg)
259111767SAnurag.Maskey@Sun.COM {
259211767SAnurag.Maskey@Sun.COM 	nwam_error_t		ret;
259311767SAnurag.Maskey@Sun.COM 	char			*name;
259411767SAnurag.Maskey@Sun.COM 	nwam_ncu_class_t	class;
259511767SAnurag.Maskey@Sun.COM 
259611767SAnurag.Maskey@Sun.COM 	if (*list_msgp) {
259711767SAnurag.Maskey@Sun.COM 		(void) printf("%s:\n", msg);
259811767SAnurag.Maskey@Sun.COM 		*list_msgp = B_FALSE;
259911767SAnurag.Maskey@Sun.COM 	}
260011767SAnurag.Maskey@Sun.COM 
260111767SAnurag.Maskey@Sun.COM 	ret = object_name_from_handle(object_type, handle, &name);
260211767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS) {
260311767SAnurag.Maskey@Sun.COM 		nwamerr(ret, "List error: failed to get name");
260411767SAnurag.Maskey@Sun.COM 		return (1);
260511767SAnurag.Maskey@Sun.COM 	}
260611767SAnurag.Maskey@Sun.COM 
260711767SAnurag.Maskey@Sun.COM 	/* If NCU, get its class and print */
260811767SAnurag.Maskey@Sun.COM 	if (object_type == NWAM_OBJECT_TYPE_NCU) {
260911767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_ncu_get_ncu_class(handle, &class))
261011767SAnurag.Maskey@Sun.COM 		    != NWAM_SUCCESS) {
261111767SAnurag.Maskey@Sun.COM 			nwamerr(ret, "List error: failed to get ncu class");
261211767SAnurag.Maskey@Sun.COM 			free(name);
261311767SAnurag.Maskey@Sun.COM 			return (1);
261411767SAnurag.Maskey@Sun.COM 		} else {
261511767SAnurag.Maskey@Sun.COM 			(void) printf("\t%s",
261611767SAnurag.Maskey@Sun.COM 			    propval_to_str(NWAM_NCU_PROP_CLASS, class));
261711767SAnurag.Maskey@Sun.COM 		}
261811767SAnurag.Maskey@Sun.COM 	}
261911767SAnurag.Maskey@Sun.COM 	(void) printf("\t%s\n", name);
262011767SAnurag.Maskey@Sun.COM 
262111767SAnurag.Maskey@Sun.COM 	free(name);
262211767SAnurag.Maskey@Sun.COM 	return (0);
262311767SAnurag.Maskey@Sun.COM }
262411767SAnurag.Maskey@Sun.COM 
262511767SAnurag.Maskey@Sun.COM /* Print out name, type and status */
262611767SAnurag.Maskey@Sun.COM static int
list_loc_callback(nwam_loc_handle_t loc,void * arg)262711767SAnurag.Maskey@Sun.COM list_loc_callback(nwam_loc_handle_t loc, void *arg)
262811767SAnurag.Maskey@Sun.COM {
262911767SAnurag.Maskey@Sun.COM 	return (list_callback(NWAM_OBJECT_TYPE_LOC, loc, arg, "Locations"));
263011767SAnurag.Maskey@Sun.COM }
263111767SAnurag.Maskey@Sun.COM 
263211767SAnurag.Maskey@Sun.COM static int
list_enm_callback(nwam_enm_handle_t enm,void * arg)263311767SAnurag.Maskey@Sun.COM list_enm_callback(nwam_enm_handle_t enm, void *arg)
263411767SAnurag.Maskey@Sun.COM {
263511767SAnurag.Maskey@Sun.COM 	return (list_callback(NWAM_OBJECT_TYPE_ENM, enm, arg, "ENMs"));
263611767SAnurag.Maskey@Sun.COM }
263711767SAnurag.Maskey@Sun.COM 
263811767SAnurag.Maskey@Sun.COM static int
list_wlan_callback(nwam_known_wlan_handle_t wlan,void * arg)263911767SAnurag.Maskey@Sun.COM list_wlan_callback(nwam_known_wlan_handle_t wlan, void *arg)
264011767SAnurag.Maskey@Sun.COM {
264111767SAnurag.Maskey@Sun.COM 	return (list_callback(NWAM_OBJECT_TYPE_KNOWN_WLAN, wlan, arg, "WLANs"));
264211767SAnurag.Maskey@Sun.COM }
264311767SAnurag.Maskey@Sun.COM 
264411767SAnurag.Maskey@Sun.COM static int
list_ncp_callback(nwam_ncp_handle_t ncp,void * arg)264511767SAnurag.Maskey@Sun.COM list_ncp_callback(nwam_ncp_handle_t ncp, void *arg)
264611767SAnurag.Maskey@Sun.COM {
264711767SAnurag.Maskey@Sun.COM 	return (list_callback(NWAM_OBJECT_TYPE_NCP, ncp, arg, "NCPs"));
264811767SAnurag.Maskey@Sun.COM }
264911767SAnurag.Maskey@Sun.COM 
265011767SAnurag.Maskey@Sun.COM static int
list_ncu_callback(nwam_ncu_handle_t ncu,void * arg)265111767SAnurag.Maskey@Sun.COM list_ncu_callback(nwam_ncu_handle_t ncu, void *arg)
265211767SAnurag.Maskey@Sun.COM {
265311767SAnurag.Maskey@Sun.COM 	return (list_callback(NWAM_OBJECT_TYPE_NCU, ncu, arg, "NCUs"));
265411767SAnurag.Maskey@Sun.COM }
265511767SAnurag.Maskey@Sun.COM 
265611767SAnurag.Maskey@Sun.COM /* functions to convert a value to a string */
265711767SAnurag.Maskey@Sun.COM /* ARGSUSED */
265811767SAnurag.Maskey@Sun.COM static const char *
str2str(void * s,const char * prop,char * str)265911767SAnurag.Maskey@Sun.COM str2str(void *s, const char *prop, char *str)
266011767SAnurag.Maskey@Sun.COM {
266111767SAnurag.Maskey@Sun.COM 	(void) snprintf(str, NWAM_MAX_VALUE_LEN, "%s", s);
266211767SAnurag.Maskey@Sun.COM 	return (str);
266311767SAnurag.Maskey@Sun.COM }
266411767SAnurag.Maskey@Sun.COM 
266511767SAnurag.Maskey@Sun.COM /* ARGSUSED */
266611767SAnurag.Maskey@Sun.COM static const char *
str2qstr(void * s,const char * prop,char * qstr)266711767SAnurag.Maskey@Sun.COM str2qstr(void *s, const char *prop, char *qstr)
266811767SAnurag.Maskey@Sun.COM {
266911767SAnurag.Maskey@Sun.COM 	/* quoted strings */
267011767SAnurag.Maskey@Sun.COM 	(void) snprintf(qstr, NWAM_MAX_VALUE_LEN, "\"%s\"", s);
267111767SAnurag.Maskey@Sun.COM 	return (qstr);
267211767SAnurag.Maskey@Sun.COM }
267311767SAnurag.Maskey@Sun.COM 
267411767SAnurag.Maskey@Sun.COM /* ARGSUSED */
267511767SAnurag.Maskey@Sun.COM static const char *
int2str(void * in,const char * prop,char * instr)267611767SAnurag.Maskey@Sun.COM int2str(void *in, const char *prop, char *instr)
267711767SAnurag.Maskey@Sun.COM {
267811767SAnurag.Maskey@Sun.COM 	(void) snprintf(instr, NWAM_MAX_VALUE_LEN, "%lld", *((int64_t *)in));
267911767SAnurag.Maskey@Sun.COM 	return (instr);
268011767SAnurag.Maskey@Sun.COM }
268111767SAnurag.Maskey@Sun.COM 
268211767SAnurag.Maskey@Sun.COM static const char *
uint2str(void * uin,const char * prop,char * uintstr)268311767SAnurag.Maskey@Sun.COM uint2str(void *uin, const char *prop, char *uintstr)
268411767SAnurag.Maskey@Sun.COM {
268511767SAnurag.Maskey@Sun.COM 	/* returns NWAM_SUCCESS if prop is enum with string in uintstr */
268611767SAnurag.Maskey@Sun.COM 	if (nwam_uint64_get_value_string(prop, *((uint64_t *)uin),
268711767SAnurag.Maskey@Sun.COM 	    (const char **)&uintstr) != NWAM_SUCCESS) {
268811767SAnurag.Maskey@Sun.COM 		(void) snprintf(uintstr, NWAM_MAX_VALUE_LEN, "%lld",
268911767SAnurag.Maskey@Sun.COM 		    *((uint64_t *)uin));
269011767SAnurag.Maskey@Sun.COM 	}
269111767SAnurag.Maskey@Sun.COM 	return (uintstr);
269211767SAnurag.Maskey@Sun.COM }
269311767SAnurag.Maskey@Sun.COM 
269411767SAnurag.Maskey@Sun.COM /* ARGSUSED */
269511767SAnurag.Maskey@Sun.COM static const char *
bool2str(void * bool,const char * prop,char * boolstr)269611767SAnurag.Maskey@Sun.COM bool2str(void *bool, const char *prop, char *boolstr)
269711767SAnurag.Maskey@Sun.COM {
269811767SAnurag.Maskey@Sun.COM 	(void) snprintf(boolstr, NWAM_MAX_VALUE_LEN, "%s",
269911767SAnurag.Maskey@Sun.COM 	    *((boolean_t *)bool) ? "true" : "false");
270011767SAnurag.Maskey@Sun.COM 	return (boolstr);
270111767SAnurag.Maskey@Sun.COM }
270211767SAnurag.Maskey@Sun.COM 
270311767SAnurag.Maskey@Sun.COM /*
270411767SAnurag.Maskey@Sun.COM  * Print the value (enums are converted to string), use DELIMITER for
270511767SAnurag.Maskey@Sun.COM  * array.  If strings are to be "quoted", pass B_TRUE for quoted_strings.
270611767SAnurag.Maskey@Sun.COM  */
270711767SAnurag.Maskey@Sun.COM static void
output_prop_val(const char * prop_name,nwam_value_t value,FILE * wf,boolean_t quoted_strings)270811767SAnurag.Maskey@Sun.COM output_prop_val(const char *prop_name, nwam_value_t value, FILE *wf,
270911767SAnurag.Maskey@Sun.COM     boolean_t quoted_strings)
271011767SAnurag.Maskey@Sun.COM {
271111767SAnurag.Maskey@Sun.COM 	nwam_value_type_t	value_type;
271211767SAnurag.Maskey@Sun.COM 	uint_t			num;
271311767SAnurag.Maskey@Sun.COM 
271411767SAnurag.Maskey@Sun.COM 	/* arrays for values retrieved according to the type of value */
271511767SAnurag.Maskey@Sun.COM 	char		**svals;
271611767SAnurag.Maskey@Sun.COM 	uint64_t	*uvals;
271711767SAnurag.Maskey@Sun.COM 	int64_t		*ivals;
271811767SAnurag.Maskey@Sun.COM 	boolean_t	*bvals;
271911767SAnurag.Maskey@Sun.COM 
272011767SAnurag.Maskey@Sun.COM 	/* pointer to function to generate string representation of value */
272111767SAnurag.Maskey@Sun.COM 	const char	*(*tostr)(void *, const char *, char *);
272211767SAnurag.Maskey@Sun.COM 	char		str[NWAM_MAX_VALUE_LEN]; /* to store the string */
272311767SAnurag.Maskey@Sun.COM 	int		i;
272411767SAnurag.Maskey@Sun.COM 
272511767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_type(value, &value_type) != NWAM_SUCCESS) {
272611767SAnurag.Maskey@Sun.COM 		nerr("Get value type error");
272711767SAnurag.Maskey@Sun.COM 		return;
272811767SAnurag.Maskey@Sun.COM 	}
272911767SAnurag.Maskey@Sun.COM 
273011767SAnurag.Maskey@Sun.COM 	if (value_type == NWAM_VALUE_TYPE_STRING) {
273111767SAnurag.Maskey@Sun.COM 		if (nwam_value_get_string_array(value, &svals, &num) !=
273211767SAnurag.Maskey@Sun.COM 		    NWAM_SUCCESS) {
273311767SAnurag.Maskey@Sun.COM 			nerr("Get string array error");
273411767SAnurag.Maskey@Sun.COM 			return;
273511767SAnurag.Maskey@Sun.COM 		}
273611767SAnurag.Maskey@Sun.COM 		tostr = quoted_strings ? str2qstr : str2str;
273711767SAnurag.Maskey@Sun.COM 	} else if (value_type == NWAM_VALUE_TYPE_INT64) {
273811767SAnurag.Maskey@Sun.COM 		if (nwam_value_get_int64_array(value, &ivals, &num) !=
273911767SAnurag.Maskey@Sun.COM 		    NWAM_SUCCESS) {
274011767SAnurag.Maskey@Sun.COM 			nerr("Get int64 array error");
274111767SAnurag.Maskey@Sun.COM 			return;
274211767SAnurag.Maskey@Sun.COM 		}
274311767SAnurag.Maskey@Sun.COM 		tostr = int2str;
274411767SAnurag.Maskey@Sun.COM 	} else if (value_type == NWAM_VALUE_TYPE_UINT64) {
274511767SAnurag.Maskey@Sun.COM 		if (nwam_value_get_uint64_array(value, &uvals, &num) !=
274611767SAnurag.Maskey@Sun.COM 		    NWAM_SUCCESS) {
274711767SAnurag.Maskey@Sun.COM 			nerr("Get uint64 array error");
274811767SAnurag.Maskey@Sun.COM 			return;
274911767SAnurag.Maskey@Sun.COM 		}
275011767SAnurag.Maskey@Sun.COM 		tostr = uint2str;
275111767SAnurag.Maskey@Sun.COM 	} else if (value_type == NWAM_VALUE_TYPE_BOOLEAN) {
275211767SAnurag.Maskey@Sun.COM 		if (nwam_value_get_boolean_array(value, &bvals, &num) !=
275311767SAnurag.Maskey@Sun.COM 		    NWAM_SUCCESS) {
275411767SAnurag.Maskey@Sun.COM 			nerr("Get boolean array error");
275511767SAnurag.Maskey@Sun.COM 			return;
275611767SAnurag.Maskey@Sun.COM 		}
275711767SAnurag.Maskey@Sun.COM 		tostr = bool2str;
275811767SAnurag.Maskey@Sun.COM 	}
275911767SAnurag.Maskey@Sun.COM 
276011767SAnurag.Maskey@Sun.COM 	/* now, loop and print each value */
276111767SAnurag.Maskey@Sun.COM 	for (i = 0; i < num; i++) {
276211767SAnurag.Maskey@Sun.COM 		void *val;
276311767SAnurag.Maskey@Sun.COM 
276411767SAnurag.Maskey@Sun.COM 		/* get the pointer to the ith value to pass to func() */
276511767SAnurag.Maskey@Sun.COM 		if (value_type == NWAM_VALUE_TYPE_STRING)
276611767SAnurag.Maskey@Sun.COM 			val = svals[i];
276711767SAnurag.Maskey@Sun.COM 		else if (value_type == NWAM_VALUE_TYPE_UINT64)
276811767SAnurag.Maskey@Sun.COM 			val = &(uvals[i]);
276911767SAnurag.Maskey@Sun.COM 		else if (value_type == NWAM_VALUE_TYPE_INT64)
277011767SAnurag.Maskey@Sun.COM 			val = &(ivals[i]);
277111767SAnurag.Maskey@Sun.COM 		else if (value_type == NWAM_VALUE_TYPE_BOOLEAN)
277211767SAnurag.Maskey@Sun.COM 			val = &(bvals[i]);
277311767SAnurag.Maskey@Sun.COM 
277411767SAnurag.Maskey@Sun.COM 		(void) fprintf(wf, "%s%s", tostr(val, prop_name, str),
277511767SAnurag.Maskey@Sun.COM 		    i != num-1 ? NWAM_VALUE_DELIMITER_STR : "");
277611767SAnurag.Maskey@Sun.COM 	}
277711767SAnurag.Maskey@Sun.COM }
277811767SAnurag.Maskey@Sun.COM 
277911767SAnurag.Maskey@Sun.COM /* Prints the property names aligned (for list/get) or "prop=" (for export) */
278011767SAnurag.Maskey@Sun.COM static int
output_propname_common(const char * prop,nwam_value_t values,void * arg,int width)278111767SAnurag.Maskey@Sun.COM output_propname_common(const char *prop, nwam_value_t values, void *arg,
278211767SAnurag.Maskey@Sun.COM     int width)
278311767SAnurag.Maskey@Sun.COM {
278411767SAnurag.Maskey@Sun.COM 	FILE *of = (arg == NULL) ? stdout : arg;
278511767SAnurag.Maskey@Sun.COM 
278611767SAnurag.Maskey@Sun.COM 	/* arg is NULL for list/get, not NULL for export */
278711767SAnurag.Maskey@Sun.COM 	if (arg == NULL)
278811767SAnurag.Maskey@Sun.COM 		(void) fprintf(of, "\t%-*s\t", width, prop);
278911767SAnurag.Maskey@Sun.COM 	else
279011767SAnurag.Maskey@Sun.COM 		(void) fprintf(of, "%s=", prop);
279111767SAnurag.Maskey@Sun.COM 
279211767SAnurag.Maskey@Sun.COM 	if (values != NULL)
279311767SAnurag.Maskey@Sun.COM 		output_prop_val(prop, values, of, B_TRUE);
279411767SAnurag.Maskey@Sun.COM 
279511767SAnurag.Maskey@Sun.COM 	(void) fprintf(of, "\n");
279611767SAnurag.Maskey@Sun.COM 	return (0);
279711767SAnurag.Maskey@Sun.COM }
279811767SAnurag.Maskey@Sun.COM 
279911767SAnurag.Maskey@Sun.COM static int
output_propname(const char * prop,nwam_value_t values,void * arg)280011767SAnurag.Maskey@Sun.COM output_propname(const char *prop, nwam_value_t values, void *arg)
280111767SAnurag.Maskey@Sun.COM {
280211767SAnurag.Maskey@Sun.COM 	return (output_propname_common(prop, values, arg, 16));
280311767SAnurag.Maskey@Sun.COM }
280411767SAnurag.Maskey@Sun.COM 
280511767SAnurag.Maskey@Sun.COM /* For locations because of longer property names */
280611767SAnurag.Maskey@Sun.COM static int
output_loc_propname(const char * prop,nwam_value_t values,void * arg)280711767SAnurag.Maskey@Sun.COM output_loc_propname(const char *prop, nwam_value_t values, void *arg)
280811767SAnurag.Maskey@Sun.COM {
280911767SAnurag.Maskey@Sun.COM 	return (output_propname_common(prop, values, arg, 25));
281011767SAnurag.Maskey@Sun.COM }
281111767SAnurag.Maskey@Sun.COM 
281211767SAnurag.Maskey@Sun.COM /*
281311767SAnurag.Maskey@Sun.COM  * all_props specifies whether properties that have not been set should be
281411767SAnurag.Maskey@Sun.COM  * printed or not.  ncp and ncu_type are used only when the object_type is
281511767SAnurag.Maskey@Sun.COM  * NCU.
281611767SAnurag.Maskey@Sun.COM  */
281711767SAnurag.Maskey@Sun.COM static nwam_error_t
listprop(nwam_object_type_t object_type,void * handle,const char * name,boolean_t all_props,nwam_ncp_handle_t ncp,nwam_ncu_type_t ncu_type)281811767SAnurag.Maskey@Sun.COM listprop(nwam_object_type_t object_type, void *handle, const char *name,
281911767SAnurag.Maskey@Sun.COM     boolean_t all_props, nwam_ncp_handle_t ncp, nwam_ncu_type_t ncu_type)
282011767SAnurag.Maskey@Sun.COM {
282111767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
282211767SAnurag.Maskey@Sun.COM 	char		*lname = NULL, *realname = NULL;
282311767SAnurag.Maskey@Sun.COM 	boolean_t	lhandle = B_FALSE;
282411767SAnurag.Maskey@Sun.COM 	const char	**props = NULL;
282511767SAnurag.Maskey@Sun.COM 	uint_t		prop_num;
282611767SAnurag.Maskey@Sun.COM 	int		i;
282711767SAnurag.Maskey@Sun.COM 	nwam_value_t	vals;
282811767SAnurag.Maskey@Sun.COM 
282911767SAnurag.Maskey@Sun.COM 	/*
283011767SAnurag.Maskey@Sun.COM 	 * handle is NULL if called from a scope higher than the object's
283111767SAnurag.Maskey@Sun.COM 	 * scope, but name must be given; so get the handle.
283211767SAnurag.Maskey@Sun.COM 	 */
283311767SAnurag.Maskey@Sun.COM 	if (handle == NULL) {
283411767SAnurag.Maskey@Sun.COM 		lname = trim_quotes(name); /* name may have quotes */
283511767SAnurag.Maskey@Sun.COM 		switch (object_type) {
283611767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_NCP:
283711767SAnurag.Maskey@Sun.COM 			if ((ret = nwam_ncp_read(lname, 0,
283811767SAnurag.Maskey@Sun.COM 			    (nwam_ncp_handle_t *)&handle)) != NWAM_SUCCESS)
283911767SAnurag.Maskey@Sun.COM 				goto readfail;
284011767SAnurag.Maskey@Sun.COM 			break;
284111767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_NCU:
284211767SAnurag.Maskey@Sun.COM 			ret = nwam_ncu_read(ncp, lname, ncu_type, 0,
284311767SAnurag.Maskey@Sun.COM 			    (nwam_ncu_handle_t *)&handle);
284411767SAnurag.Maskey@Sun.COM 			if (ret == NWAM_ENTITY_MULTIPLE_VALUES) {
284511767SAnurag.Maskey@Sun.COM 				/*
284611767SAnurag.Maskey@Sun.COM 				 * Multiple NCUs with the given name exists.
284711767SAnurag.Maskey@Sun.COM 				 * Call listprop() for each NCU type.
284811767SAnurag.Maskey@Sun.COM 				 */
284911767SAnurag.Maskey@Sun.COM 				if ((ret = listprop(object_type, NULL, lname,
285011767SAnurag.Maskey@Sun.COM 				    all_props, ncp, NWAM_NCU_TYPE_LINK))
285111767SAnurag.Maskey@Sun.COM 				    != NWAM_SUCCESS)
285211767SAnurag.Maskey@Sun.COM 					goto done;
285311767SAnurag.Maskey@Sun.COM 				ret = listprop(object_type, NULL, lname,
285411767SAnurag.Maskey@Sun.COM 				    all_props, ncp, NWAM_NCU_TYPE_INTERFACE);
285511767SAnurag.Maskey@Sun.COM 				goto done;
285611767SAnurag.Maskey@Sun.COM 			} else if (ret != NWAM_SUCCESS) {
285711767SAnurag.Maskey@Sun.COM 				goto readfail;
285811767SAnurag.Maskey@Sun.COM 			}
285911767SAnurag.Maskey@Sun.COM 			break;
286011767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_LOC:
286111767SAnurag.Maskey@Sun.COM 			if ((ret = nwam_loc_read(lname, 0,
286211767SAnurag.Maskey@Sun.COM 			    (nwam_loc_handle_t *)&handle)) != NWAM_SUCCESS)
286311767SAnurag.Maskey@Sun.COM 				goto readfail;
286411767SAnurag.Maskey@Sun.COM 			break;
286511767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_ENM:
286611767SAnurag.Maskey@Sun.COM 			if ((ret = nwam_enm_read(lname, 0,
286711767SAnurag.Maskey@Sun.COM 			    (nwam_enm_handle_t *)&handle)) != NWAM_SUCCESS)
286811767SAnurag.Maskey@Sun.COM 				goto readfail;
286911767SAnurag.Maskey@Sun.COM 			break;
287011767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_KNOWN_WLAN:
287111767SAnurag.Maskey@Sun.COM 			if ((ret = nwam_known_wlan_read(lname, 0,
287211767SAnurag.Maskey@Sun.COM 			    (nwam_known_wlan_handle_t *)&handle))
287311767SAnurag.Maskey@Sun.COM 			    != NWAM_SUCCESS)
287411767SAnurag.Maskey@Sun.COM 				goto readfail;
287511767SAnurag.Maskey@Sun.COM 			break;
287611767SAnurag.Maskey@Sun.COM 		}
287711767SAnurag.Maskey@Sun.COM 		lhandle = B_TRUE;
287811767SAnurag.Maskey@Sun.COM 	}
287911767SAnurag.Maskey@Sun.COM 
288011767SAnurag.Maskey@Sun.COM 	if ((ret = object_name_from_handle(object_type, handle, &realname))
288111767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
288211767SAnurag.Maskey@Sun.COM 		goto done;
288311767SAnurag.Maskey@Sun.COM 
288411767SAnurag.Maskey@Sun.COM 	/* get the property list */
288511767SAnurag.Maskey@Sun.COM 	switch (object_type) {
288611767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCP:
288711767SAnurag.Maskey@Sun.COM 	{
288811767SAnurag.Maskey@Sun.COM 		/* walk NCUs */
288911767SAnurag.Maskey@Sun.COM 		boolean_t list_msg = B_TRUE;
289011767SAnurag.Maskey@Sun.COM 		ret = nwam_ncp_walk_ncus(handle, list_ncu_callback, &list_msg,
289111767SAnurag.Maskey@Sun.COM 		    NWAM_FLAG_NCU_TYPE_CLASS_ALL, NULL);
289211767SAnurag.Maskey@Sun.COM 		goto done;
289311767SAnurag.Maskey@Sun.COM 	}
289411767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
289511767SAnurag.Maskey@Sun.COM 	{
289611767SAnurag.Maskey@Sun.COM 		nwam_ncu_type_t		ncu_type;
289711767SAnurag.Maskey@Sun.COM 		nwam_ncu_class_t	ncu_class;
289811767SAnurag.Maskey@Sun.COM 
289911767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_ncu_get_ncu_type(handle, &ncu_type))
290011767SAnurag.Maskey@Sun.COM 		    != NWAM_SUCCESS)
290111767SAnurag.Maskey@Sun.COM 			goto done;
290211767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_ncu_get_ncu_class(handle, &ncu_class))
290311767SAnurag.Maskey@Sun.COM 		    != NWAM_SUCCESS)
290411767SAnurag.Maskey@Sun.COM 			goto done;
290511767SAnurag.Maskey@Sun.COM 
290611767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_get_default_proplist(ncu_type, ncu_class, &props,
290711767SAnurag.Maskey@Sun.COM 		    &prop_num);
290811767SAnurag.Maskey@Sun.COM 		break;
290911767SAnurag.Maskey@Sun.COM 	}
291011767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
291111767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_get_default_proplist(&props, &prop_num);
291211767SAnurag.Maskey@Sun.COM 		break;
291311767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
291411767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_get_default_proplist(&props, &prop_num);
291511767SAnurag.Maskey@Sun.COM 		break;
291611767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
291711767SAnurag.Maskey@Sun.COM 		ret = nwam_known_wlan_get_default_proplist(&props, &prop_num);
291811767SAnurag.Maskey@Sun.COM 		break;
291911767SAnurag.Maskey@Sun.COM 	}
292011767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
292111767SAnurag.Maskey@Sun.COM 		goto done;
292211767SAnurag.Maskey@Sun.COM 
292311767SAnurag.Maskey@Sun.COM 	/* print object type and name */
292411767SAnurag.Maskey@Sun.COM 	(void) printf("%s:%s\n", nwam_object_type_to_string(object_type),
292511767SAnurag.Maskey@Sun.COM 	    realname);
292611767SAnurag.Maskey@Sun.COM 
292711767SAnurag.Maskey@Sun.COM 	/* Loop through the properties and print */
292811767SAnurag.Maskey@Sun.COM 	for (i = 0; i < prop_num; i++) {
292911767SAnurag.Maskey@Sun.COM 		/* get the existing value for this property */
293011767SAnurag.Maskey@Sun.COM 		switch (object_type) {
293111767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_NCU:
293211767SAnurag.Maskey@Sun.COM 			ret = nwam_ncu_get_prop_value(handle, props[i], &vals);
293311767SAnurag.Maskey@Sun.COM 			break;
293411767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_LOC:
293511767SAnurag.Maskey@Sun.COM 			ret = nwam_loc_get_prop_value(handle, props[i], &vals);
293611767SAnurag.Maskey@Sun.COM 			break;
293711767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_ENM:
293811767SAnurag.Maskey@Sun.COM 			ret = nwam_enm_get_prop_value(handle, props[i], &vals);
293911767SAnurag.Maskey@Sun.COM 			break;
294011767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_KNOWN_WLAN:
294111767SAnurag.Maskey@Sun.COM 			ret = nwam_known_wlan_get_prop_value(handle, props[i],
294211767SAnurag.Maskey@Sun.COM 			    &vals);
294311767SAnurag.Maskey@Sun.COM 			break;
294411767SAnurag.Maskey@Sun.COM 		}
294511767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS) {
294611767SAnurag.Maskey@Sun.COM 			/* _ENTITY_NOT_FOUND is ok if listing for all props */
294711767SAnurag.Maskey@Sun.COM 			if (!all_props)
294811767SAnurag.Maskey@Sun.COM 				continue;
294911767SAnurag.Maskey@Sun.COM 			else if (ret != NWAM_ENTITY_NOT_FOUND)
295011767SAnurag.Maskey@Sun.COM 				continue;
295111767SAnurag.Maskey@Sun.COM 		}
295211767SAnurag.Maskey@Sun.COM 
295311767SAnurag.Maskey@Sun.COM 		/* print property and value */
295411767SAnurag.Maskey@Sun.COM 		if (object_type == NWAM_OBJECT_TYPE_LOC)
295511767SAnurag.Maskey@Sun.COM 			output_loc_propname(props[i], vals, NULL);
295611767SAnurag.Maskey@Sun.COM 		else
295711767SAnurag.Maskey@Sun.COM 			output_propname(props[i], vals, NULL);
295811767SAnurag.Maskey@Sun.COM 		nwam_value_free(vals);
295911767SAnurag.Maskey@Sun.COM 	}
296011767SAnurag.Maskey@Sun.COM 
296111767SAnurag.Maskey@Sun.COM done:
296211767SAnurag.Maskey@Sun.COM 	free(lname);
296311767SAnurag.Maskey@Sun.COM 	free(realname);
296411767SAnurag.Maskey@Sun.COM 	if (props != NULL)
296511767SAnurag.Maskey@Sun.COM 		free(props);
296611767SAnurag.Maskey@Sun.COM 	if (lhandle) {
296711767SAnurag.Maskey@Sun.COM 		switch (object_type) {
296811767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_NCP:
296911767SAnurag.Maskey@Sun.COM 			nwam_ncp_free(handle);
297011767SAnurag.Maskey@Sun.COM 			break;
297111767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_NCU:
297211767SAnurag.Maskey@Sun.COM 			nwam_ncu_free(handle);
297311767SAnurag.Maskey@Sun.COM 			break;
297411767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_LOC:
297511767SAnurag.Maskey@Sun.COM 			nwam_loc_free(handle);
297611767SAnurag.Maskey@Sun.COM 			break;
297711767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_ENM:
297811767SAnurag.Maskey@Sun.COM 			nwam_enm_free(handle);
297911767SAnurag.Maskey@Sun.COM 			break;
298011767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_KNOWN_WLAN:
298111767SAnurag.Maskey@Sun.COM 			nwam_known_wlan_free(handle);
298211767SAnurag.Maskey@Sun.COM 			break;
298311767SAnurag.Maskey@Sun.COM 		}
298411767SAnurag.Maskey@Sun.COM 	}
298511767SAnurag.Maskey@Sun.COM 	/* don't treat _ENTITY_NOT_FOUND as an error */
298611767SAnurag.Maskey@Sun.COM 	if (ret == NWAM_ENTITY_NOT_FOUND)
298711767SAnurag.Maskey@Sun.COM 		ret = NWAM_SUCCESS;
298811767SAnurag.Maskey@Sun.COM 	return (ret);
298911767SAnurag.Maskey@Sun.COM 
299011767SAnurag.Maskey@Sun.COM readfail:
299111767SAnurag.Maskey@Sun.COM 	/* When nwam_*_read() fails */
299211767SAnurag.Maskey@Sun.COM 	free(lname);
299311767SAnurag.Maskey@Sun.COM 	return (ret);
299411767SAnurag.Maskey@Sun.COM }
299511767SAnurag.Maskey@Sun.COM 
299611767SAnurag.Maskey@Sun.COM /*
299711767SAnurag.Maskey@Sun.COM  * List profiles or property and its values.
299811767SAnurag.Maskey@Sun.COM  * If the -a option is specified, all properties are listed.
299911767SAnurag.Maskey@Sun.COM  */
300011767SAnurag.Maskey@Sun.COM void
list_func(cmd_t * cmd)300111767SAnurag.Maskey@Sun.COM list_func(cmd_t *cmd)
300211767SAnurag.Maskey@Sun.COM {
300311767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret = NWAM_SUCCESS;
300411767SAnurag.Maskey@Sun.COM 	boolean_t	list_msg = B_TRUE;
300511767SAnurag.Maskey@Sun.COM 
300611767SAnurag.Maskey@Sun.COM 	boolean_t	list_loc = B_FALSE, list_enm = B_FALSE;
300711767SAnurag.Maskey@Sun.COM 	boolean_t	list_ncp = B_FALSE, list_ncu = B_FALSE;
300811767SAnurag.Maskey@Sun.COM 	boolean_t	list_wlan = B_FALSE;
300911767SAnurag.Maskey@Sun.COM 
301011767SAnurag.Maskey@Sun.COM 	/* whether all properties should be listed, given by the -a option */
301111767SAnurag.Maskey@Sun.COM 	boolean_t	all_props = B_FALSE;
301211767SAnurag.Maskey@Sun.COM 
301311767SAnurag.Maskey@Sun.COM 	/*
301411767SAnurag.Maskey@Sun.COM 	 * list_props says whether the properties should be listed.
301511767SAnurag.Maskey@Sun.COM 	 * Note that, here NCUs are treated as properties of NCPs.
301611767SAnurag.Maskey@Sun.COM 	 */
301711767SAnurag.Maskey@Sun.COM 	boolean_t	list_props = B_FALSE;
301811767SAnurag.Maskey@Sun.COM 
301911767SAnurag.Maskey@Sun.COM 	/* determine which properties to list, also validity tests */
302011767SAnurag.Maskey@Sun.COM 	if (current_scope == NWAM_SCOPE_GBL) {
302111767SAnurag.Maskey@Sun.COM 		/* res1_type is -1 if only "list -a" is used */
302211767SAnurag.Maskey@Sun.COM 		if (cmd->cmd_res1_type == -1) {
302311767SAnurag.Maskey@Sun.COM 			nerr("'list' requires an object to be specified with "
302411767SAnurag.Maskey@Sun.COM 			    "the -a option in the global scope");
302511767SAnurag.Maskey@Sun.COM 			return;
302611767SAnurag.Maskey@Sun.COM 		}
302711767SAnurag.Maskey@Sun.COM 		if (cmd->cmd_res1_type == RT1_LOC) {
302811767SAnurag.Maskey@Sun.COM 			list_props = B_TRUE;
302911767SAnurag.Maskey@Sun.COM 			list_loc = B_TRUE;
303011767SAnurag.Maskey@Sun.COM 		} else if (cmd->cmd_res1_type == RT1_ENM) {
303111767SAnurag.Maskey@Sun.COM 			list_props = B_TRUE;
303211767SAnurag.Maskey@Sun.COM 			list_enm = B_TRUE;
303311767SAnurag.Maskey@Sun.COM 		} else if (cmd->cmd_res1_type == RT1_WLAN) {
303411767SAnurag.Maskey@Sun.COM 			list_props = B_TRUE;
303511767SAnurag.Maskey@Sun.COM 			list_wlan = B_TRUE;
303611767SAnurag.Maskey@Sun.COM 		} else if (cmd->cmd_res1_type == RT1_NCP) {
303711767SAnurag.Maskey@Sun.COM 			list_ncp = B_TRUE;
303811767SAnurag.Maskey@Sun.COM 			list_props = B_TRUE;
303911767SAnurag.Maskey@Sun.COM 		} else {
304011767SAnurag.Maskey@Sun.COM 			list_loc = B_TRUE;
304111767SAnurag.Maskey@Sun.COM 			list_enm = B_TRUE;
304211767SAnurag.Maskey@Sun.COM 			list_wlan = B_TRUE;
304311767SAnurag.Maskey@Sun.COM 			list_ncp = B_TRUE;
304411767SAnurag.Maskey@Sun.COM 		}
304511767SAnurag.Maskey@Sun.COM 	}
304611767SAnurag.Maskey@Sun.COM 	if ((current_scope == NWAM_SCOPE_LOC ||
304711767SAnurag.Maskey@Sun.COM 	    current_scope == NWAM_SCOPE_ENM ||
304811767SAnurag.Maskey@Sun.COM 	    current_scope == NWAM_SCOPE_WLAN ||
304911767SAnurag.Maskey@Sun.COM 	    current_scope == NWAM_SCOPE_NCU) &&
305011767SAnurag.Maskey@Sun.COM 	    (cmd->cmd_argc >= 1 && cmd->cmd_res1_type != -1)) {
305111767SAnurag.Maskey@Sun.COM 		nerr("Additional options are not allowed with the -a option "
305211767SAnurag.Maskey@Sun.COM 		    "at this scope");
305311767SAnurag.Maskey@Sun.COM 		return;
305411767SAnurag.Maskey@Sun.COM 	}
305511767SAnurag.Maskey@Sun.COM 	if (current_scope == NWAM_SCOPE_LOC) {
305611767SAnurag.Maskey@Sun.COM 		list_loc = B_TRUE;
305711767SAnurag.Maskey@Sun.COM 		list_props = B_TRUE;
305811767SAnurag.Maskey@Sun.COM 	}
305911767SAnurag.Maskey@Sun.COM 	if (current_scope == NWAM_SCOPE_ENM) {
306011767SAnurag.Maskey@Sun.COM 		list_enm = B_TRUE;
306111767SAnurag.Maskey@Sun.COM 		list_props = B_TRUE;
306211767SAnurag.Maskey@Sun.COM 	}
306311767SAnurag.Maskey@Sun.COM 	if (current_scope == NWAM_SCOPE_WLAN) {
306411767SAnurag.Maskey@Sun.COM 		list_wlan = B_TRUE;
306511767SAnurag.Maskey@Sun.COM 		list_props = B_TRUE;
306611767SAnurag.Maskey@Sun.COM 	}
306711767SAnurag.Maskey@Sun.COM 	if (current_scope == NWAM_SCOPE_NCP) {
306811767SAnurag.Maskey@Sun.COM 		if (cmd->cmd_res1_type == RT1_ENM ||
306911767SAnurag.Maskey@Sun.COM 		    cmd->cmd_res1_type == RT1_LOC ||
307011767SAnurag.Maskey@Sun.COM 		    cmd->cmd_res1_type == RT1_WLAN) {
307111767SAnurag.Maskey@Sun.COM 			nerr("only ncu can be listed at this scope");
307211767SAnurag.Maskey@Sun.COM 			return;
307311767SAnurag.Maskey@Sun.COM 		}
307411767SAnurag.Maskey@Sun.COM 		if (cmd->cmd_res2_type == RT2_NCU) {
307511767SAnurag.Maskey@Sun.COM 			list_ncu = B_TRUE;
307611767SAnurag.Maskey@Sun.COM 			list_props = B_TRUE;
307711767SAnurag.Maskey@Sun.COM 		} else {
307811767SAnurag.Maskey@Sun.COM 			list_ncp = B_TRUE;
307911767SAnurag.Maskey@Sun.COM 			list_props = B_TRUE;
308011767SAnurag.Maskey@Sun.COM 		}
308111767SAnurag.Maskey@Sun.COM 	}
308211767SAnurag.Maskey@Sun.COM 	if (current_scope == NWAM_SCOPE_NCU) {
308311767SAnurag.Maskey@Sun.COM 		list_ncu = B_TRUE;
308411767SAnurag.Maskey@Sun.COM 		list_props = B_TRUE;
308511767SAnurag.Maskey@Sun.COM 	}
308611767SAnurag.Maskey@Sun.COM 
308711767SAnurag.Maskey@Sun.COM 	/* Check if the -a option is specified to list all properties */
308811767SAnurag.Maskey@Sun.COM 	if (cmd->cmd_res1_type == -1 || cmd->cmd_argc == 2) {
308911767SAnurag.Maskey@Sun.COM 		int c, argc = 1;
309011767SAnurag.Maskey@Sun.COM 		char **argv;
309111767SAnurag.Maskey@Sun.COM 		optind = 0;
309211767SAnurag.Maskey@Sun.COM 
309311767SAnurag.Maskey@Sun.COM 		/* if res1_type is -1, option is in argv[0], else in argv[1] */
309411767SAnurag.Maskey@Sun.COM 		if (cmd->cmd_res1_type == -1)
309511767SAnurag.Maskey@Sun.COM 			argv = cmd->cmd_argv;
309611767SAnurag.Maskey@Sun.COM 		else
309711767SAnurag.Maskey@Sun.COM 			argv = &(cmd->cmd_argv[1]);
309811767SAnurag.Maskey@Sun.COM 		while ((c = getopt(argc, argv, "a")) != EOF) {
309911767SAnurag.Maskey@Sun.COM 			switch (c) {
310011767SAnurag.Maskey@Sun.COM 			case 'a':
310111767SAnurag.Maskey@Sun.COM 				all_props = B_TRUE;
310211767SAnurag.Maskey@Sun.COM 				break;
310311767SAnurag.Maskey@Sun.COM 			default:
310411767SAnurag.Maskey@Sun.COM 				command_usage(CMD_LIST);
310511767SAnurag.Maskey@Sun.COM 				return;
310611767SAnurag.Maskey@Sun.COM 			}
310711767SAnurag.Maskey@Sun.COM 		}
310811767SAnurag.Maskey@Sun.COM 		if (cmd->cmd_res1_type == -1)
310911767SAnurag.Maskey@Sun.COM 			cmd->cmd_argv[0] = NULL;
311011767SAnurag.Maskey@Sun.COM 	}
311111767SAnurag.Maskey@Sun.COM 
311211767SAnurag.Maskey@Sun.COM 	/*
311311767SAnurag.Maskey@Sun.COM 	 * Now, print objects and/or according to the flags set.
311411767SAnurag.Maskey@Sun.COM 	 * name, if requested, is in argv[0].
311511767SAnurag.Maskey@Sun.COM 	 */
311611767SAnurag.Maskey@Sun.COM 	if (list_ncp) {
311711767SAnurag.Maskey@Sun.COM 		list_msg = B_TRUE;
311811767SAnurag.Maskey@Sun.COM 		if (list_props) {
311911767SAnurag.Maskey@Sun.COM 			ret = listprop(NWAM_OBJECT_TYPE_NCP, ncp_h,
312011767SAnurag.Maskey@Sun.COM 			    cmd->cmd_argv[0], all_props, NULL, -1);
312111767SAnurag.Maskey@Sun.COM 		} else {
312211767SAnurag.Maskey@Sun.COM 			ret = nwam_walk_ncps(list_ncp_callback, &list_msg, 0,
312311767SAnurag.Maskey@Sun.COM 			    NULL);
312411767SAnurag.Maskey@Sun.COM 		}
312511767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
312611767SAnurag.Maskey@Sun.COM 			goto done;
312711767SAnurag.Maskey@Sun.COM 	}
312811767SAnurag.Maskey@Sun.COM 
312911767SAnurag.Maskey@Sun.COM 	if (list_ncu) {
313011767SAnurag.Maskey@Sun.COM 		list_msg = B_TRUE;
313111767SAnurag.Maskey@Sun.COM 		if (ncp_h == NULL) {
313211767SAnurag.Maskey@Sun.COM 			nerr("NCP has not been read");
313311767SAnurag.Maskey@Sun.COM 			return;
313411767SAnurag.Maskey@Sun.COM 		}
313511767SAnurag.Maskey@Sun.COM 		if (list_props) {
313611767SAnurag.Maskey@Sun.COM 			nwam_ncu_class_t	ncu_class;
313711767SAnurag.Maskey@Sun.COM 			nwam_ncu_type_t		ncu_type;
313811767SAnurag.Maskey@Sun.COM 
313911767SAnurag.Maskey@Sun.COM 			/* determine the NCU type first */
314011767SAnurag.Maskey@Sun.COM 			if (ncu_h == NULL) {
314111767SAnurag.Maskey@Sun.COM 				ncu_class = (nwam_ncu_class_t)
314211767SAnurag.Maskey@Sun.COM 				    cmd->cmd_ncu_class_type;
314311767SAnurag.Maskey@Sun.COM 				ncu_type = nwam_ncu_class_to_type(ncu_class);
314411767SAnurag.Maskey@Sun.COM 			} else {
314511767SAnurag.Maskey@Sun.COM 				if ((ret = nwam_ncu_get_ncu_type(ncu_h,
314611767SAnurag.Maskey@Sun.COM 				    &ncu_type)) != NWAM_SUCCESS)
314711767SAnurag.Maskey@Sun.COM 					goto done;
314811767SAnurag.Maskey@Sun.COM 			}
314911767SAnurag.Maskey@Sun.COM 			ret = listprop(NWAM_OBJECT_TYPE_NCU, ncu_h,
315011767SAnurag.Maskey@Sun.COM 			    cmd->cmd_argv[0], all_props, ncp_h, ncu_type);
315111767SAnurag.Maskey@Sun.COM 			if (ret != NWAM_SUCCESS)
315211767SAnurag.Maskey@Sun.COM 				goto done;
315311767SAnurag.Maskey@Sun.COM 		}
315411767SAnurag.Maskey@Sun.COM 	}
315511767SAnurag.Maskey@Sun.COM 
315611767SAnurag.Maskey@Sun.COM 	if (list_loc) {
315711767SAnurag.Maskey@Sun.COM 		list_msg = B_TRUE;
315811767SAnurag.Maskey@Sun.COM 		if (list_props) {
315911767SAnurag.Maskey@Sun.COM 			ret = listprop(NWAM_OBJECT_TYPE_LOC, loc_h,
316011767SAnurag.Maskey@Sun.COM 			    cmd->cmd_argv[0], all_props, NULL, -1);
316111767SAnurag.Maskey@Sun.COM 		} else {
316211767SAnurag.Maskey@Sun.COM 			ret = nwam_walk_locs(list_loc_callback, &list_msg,
316311767SAnurag.Maskey@Sun.COM 			    NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
316411767SAnurag.Maskey@Sun.COM 		}
316511767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
316611767SAnurag.Maskey@Sun.COM 			goto done;
316711767SAnurag.Maskey@Sun.COM 	}
316811767SAnurag.Maskey@Sun.COM 
316911767SAnurag.Maskey@Sun.COM 	if (list_enm) {
317011767SAnurag.Maskey@Sun.COM 		list_msg = B_TRUE;
317111767SAnurag.Maskey@Sun.COM 		if (list_props) {
317211767SAnurag.Maskey@Sun.COM 			ret = listprop(NWAM_OBJECT_TYPE_ENM, enm_h,
317311767SAnurag.Maskey@Sun.COM 			    cmd->cmd_argv[0], all_props, NULL, -1);
317411767SAnurag.Maskey@Sun.COM 		} else {
317511767SAnurag.Maskey@Sun.COM 			ret = nwam_walk_enms(list_enm_callback, &list_msg,
317611767SAnurag.Maskey@Sun.COM 			    NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
317711767SAnurag.Maskey@Sun.COM 		}
317811767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
317911767SAnurag.Maskey@Sun.COM 			goto done;
318011767SAnurag.Maskey@Sun.COM 	}
318111767SAnurag.Maskey@Sun.COM 
318211767SAnurag.Maskey@Sun.COM 	if (list_wlan) {
318311767SAnurag.Maskey@Sun.COM 		list_msg = B_TRUE;
318411767SAnurag.Maskey@Sun.COM 		if (list_props) {
318511767SAnurag.Maskey@Sun.COM 			ret = listprop(NWAM_OBJECT_TYPE_KNOWN_WLAN, wlan_h,
318611767SAnurag.Maskey@Sun.COM 			    cmd->cmd_argv[0], all_props, NULL, -1);
318711767SAnurag.Maskey@Sun.COM 		} else {
318811767SAnurag.Maskey@Sun.COM 			ret = nwam_walk_known_wlans(list_wlan_callback,
318911767SAnurag.Maskey@Sun.COM 			    &list_msg, NWAM_FLAG_KNOWN_WLAN_WALK_PRIORITY_ORDER,
319011767SAnurag.Maskey@Sun.COM 			    NULL);
319111767SAnurag.Maskey@Sun.COM 		}
319211767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
319311767SAnurag.Maskey@Sun.COM 			goto done;
319411767SAnurag.Maskey@Sun.COM 	}
319511767SAnurag.Maskey@Sun.COM 
319611767SAnurag.Maskey@Sun.COM done:
319711767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
319811767SAnurag.Maskey@Sun.COM 		nwamerr(ret, "List error");
319911767SAnurag.Maskey@Sun.COM }
320011767SAnurag.Maskey@Sun.COM 
320111767SAnurag.Maskey@Sun.COM static int
write_export_command(nwam_object_type_t object_type,const char * prop,nwam_value_t values,FILE * of)320211767SAnurag.Maskey@Sun.COM write_export_command(nwam_object_type_t object_type, const char *prop,
320311767SAnurag.Maskey@Sun.COM     nwam_value_t values, FILE *of)
320411767SAnurag.Maskey@Sun.COM {
320511767SAnurag.Maskey@Sun.COM 	/* exclude read-only properties */
320611767SAnurag.Maskey@Sun.COM 	if (is_prop_read_only(object_type, prop))
320711767SAnurag.Maskey@Sun.COM 		return (0);
320811767SAnurag.Maskey@Sun.COM 
320911767SAnurag.Maskey@Sun.COM 	(void) fprintf(of, "set ");
321011767SAnurag.Maskey@Sun.COM 	output_propname(prop, values, of);
321111767SAnurag.Maskey@Sun.COM 	return (0);
321211767SAnurag.Maskey@Sun.COM }
321311767SAnurag.Maskey@Sun.COM 
321411767SAnurag.Maskey@Sun.COM static int
export_ncu_callback(nwam_ncu_handle_t ncu,void * arg)321511767SAnurag.Maskey@Sun.COM export_ncu_callback(nwam_ncu_handle_t ncu, void *arg)
321611767SAnurag.Maskey@Sun.COM {
321711767SAnurag.Maskey@Sun.COM 	char		*name;
321811767SAnurag.Maskey@Sun.COM 	const char	**props;
321911767SAnurag.Maskey@Sun.COM 	nwam_ncu_type_t type;
322011767SAnurag.Maskey@Sun.COM 	nwam_ncu_class_t class;
322111767SAnurag.Maskey@Sun.COM 	nwam_value_t	vals;
322211767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
322311767SAnurag.Maskey@Sun.COM 	uint_t		num;
322411767SAnurag.Maskey@Sun.COM 	int		i;
322511767SAnurag.Maskey@Sun.COM 	FILE		*of = arg;
322611767SAnurag.Maskey@Sun.COM 
322711767SAnurag.Maskey@Sun.COM 	assert(of != NULL);
322811767SAnurag.Maskey@Sun.COM 
322911767SAnurag.Maskey@Sun.COM 	/* get the NCU's type and class */
323011767SAnurag.Maskey@Sun.COM 	if ((ret = nwam_ncu_get_ncu_type(ncu, &type)) != NWAM_SUCCESS)
323111767SAnurag.Maskey@Sun.COM 		return (ret);
323211767SAnurag.Maskey@Sun.COM 	if ((ret = nwam_ncu_get_ncu_class(ncu, &class)) != NWAM_SUCCESS)
323311767SAnurag.Maskey@Sun.COM 		return (ret);
323411767SAnurag.Maskey@Sun.COM 
323511767SAnurag.Maskey@Sun.COM 	if ((ret = nwam_ncu_get_name(ncu, &name)) != NWAM_SUCCESS)
323611767SAnurag.Maskey@Sun.COM 		return (ret);
323711767SAnurag.Maskey@Sun.COM 
323811767SAnurag.Maskey@Sun.COM 	(void) fprintf(of, "create ncu %s \"%s\"\n",
323911767SAnurag.Maskey@Sun.COM 	    propval_to_str(NWAM_NCU_PROP_CLASS, class), name);
324011767SAnurag.Maskey@Sun.COM 	free(name);
324111767SAnurag.Maskey@Sun.COM 	/*
324211767SAnurag.Maskey@Sun.COM 	 * Because of dependencies between properties, they have to be
324311767SAnurag.Maskey@Sun.COM 	 * exported in the same order as when they are walked.
324411767SAnurag.Maskey@Sun.COM 	 */
324511767SAnurag.Maskey@Sun.COM 	if ((ret = nwam_ncu_get_default_proplist(type, class, &props, &num))
324611767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
324711767SAnurag.Maskey@Sun.COM 		return (ret);
324811767SAnurag.Maskey@Sun.COM 	for (i = 0; i < num; i++) {
324911767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_get_prop_value(ncu, props[i], &vals);
325011767SAnurag.Maskey@Sun.COM 		if (ret == NWAM_SUCCESS) {
325111767SAnurag.Maskey@Sun.COM 			write_export_command(NWAM_OBJECT_TYPE_NCU, props[i],
325211767SAnurag.Maskey@Sun.COM 			    vals, of);
325311767SAnurag.Maskey@Sun.COM 			nwam_value_free(vals);
325411767SAnurag.Maskey@Sun.COM 		}
325511767SAnurag.Maskey@Sun.COM 	}
325611767SAnurag.Maskey@Sun.COM 	(void) fprintf(of, "end\n");
325711767SAnurag.Maskey@Sun.COM 
325811767SAnurag.Maskey@Sun.COM 	free(props);
325911767SAnurag.Maskey@Sun.COM 	return (0);
326011767SAnurag.Maskey@Sun.COM }
326111767SAnurag.Maskey@Sun.COM 
326211767SAnurag.Maskey@Sun.COM static int
export_ncp_callback(nwam_ncp_handle_t ncp,void * arg)326311767SAnurag.Maskey@Sun.COM export_ncp_callback(nwam_ncp_handle_t ncp, void *arg)
326411767SAnurag.Maskey@Sun.COM {
326511767SAnurag.Maskey@Sun.COM 	char		*name;
326611767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
326711767SAnurag.Maskey@Sun.COM 	FILE		*of = arg;
326811767SAnurag.Maskey@Sun.COM 
326911767SAnurag.Maskey@Sun.COM 	assert(of != NULL);
327011767SAnurag.Maskey@Sun.COM 
327111767SAnurag.Maskey@Sun.COM 	if ((ret = nwam_ncp_get_name(ncp, &name)) != NWAM_SUCCESS)
327211767SAnurag.Maskey@Sun.COM 		return (ret);
327311767SAnurag.Maskey@Sun.COM 
327411767SAnurag.Maskey@Sun.COM 	/* Do not export "automatic" NCP */
327511767SAnurag.Maskey@Sun.COM 	if (NWAM_NCP_AUTOMATIC(name)) {
327611767SAnurag.Maskey@Sun.COM 		free(name);
327711767SAnurag.Maskey@Sun.COM 		return (0);
327811767SAnurag.Maskey@Sun.COM 	}
327911767SAnurag.Maskey@Sun.COM 
328011767SAnurag.Maskey@Sun.COM 	(void) fprintf(of, "create ncp \"%s\"\n", name);
328111767SAnurag.Maskey@Sun.COM 	free(name);
328211767SAnurag.Maskey@Sun.COM 
328311767SAnurag.Maskey@Sun.COM 	/* now walk NCUs for this ncp */
328411767SAnurag.Maskey@Sun.COM 	ret = nwam_ncp_walk_ncus(ncp, export_ncu_callback, of,
328511767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_CLASS_ALL, NULL);
328611767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS) {
328711767SAnurag.Maskey@Sun.COM 		nwamerr(ret, "Export ncp error: failed to walk ncus");
328811767SAnurag.Maskey@Sun.COM 		return (ret);
328911767SAnurag.Maskey@Sun.COM 	}
329011767SAnurag.Maskey@Sun.COM 	(void) fprintf(of, "end\n");
329111767SAnurag.Maskey@Sun.COM 	return (0);
329211767SAnurag.Maskey@Sun.COM }
329311767SAnurag.Maskey@Sun.COM 
329411767SAnurag.Maskey@Sun.COM static int
export_enm_callback(nwam_enm_handle_t enm,void * arg)329511767SAnurag.Maskey@Sun.COM export_enm_callback(nwam_enm_handle_t enm, void *arg)
329611767SAnurag.Maskey@Sun.COM {
329711767SAnurag.Maskey@Sun.COM 	char		*name;
329811767SAnurag.Maskey@Sun.COM 	const char	**props;
329911767SAnurag.Maskey@Sun.COM 	nwam_value_t	vals;
330011767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
330111767SAnurag.Maskey@Sun.COM 	uint_t		num;
330211767SAnurag.Maskey@Sun.COM 	int		i;
330311767SAnurag.Maskey@Sun.COM 	FILE		*of = arg;
330411767SAnurag.Maskey@Sun.COM 
330511767SAnurag.Maskey@Sun.COM 	assert(of != NULL);
330611767SAnurag.Maskey@Sun.COM 
330711767SAnurag.Maskey@Sun.COM 	if ((ret = nwam_enm_get_name(enm, &name)) != NWAM_SUCCESS)
330811767SAnurag.Maskey@Sun.COM 		return (ret);
330911767SAnurag.Maskey@Sun.COM 
331011767SAnurag.Maskey@Sun.COM 	(void) fprintf(of, "create enm \"%s\"\n", name);
331111767SAnurag.Maskey@Sun.COM 	free(name);
331211767SAnurag.Maskey@Sun.COM 	/*
331311767SAnurag.Maskey@Sun.COM 	 * Because of dependencies between properties, they have to be
331411767SAnurag.Maskey@Sun.COM 	 * exported in the same order as when they are walked.
331511767SAnurag.Maskey@Sun.COM 	 */
331611767SAnurag.Maskey@Sun.COM 	if ((ret = nwam_enm_get_default_proplist(&props, &num)) != NWAM_SUCCESS)
331711767SAnurag.Maskey@Sun.COM 		return (ret);
331811767SAnurag.Maskey@Sun.COM 	for (i = 0; i < num; i++) {
331911767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_get_prop_value(enm, props[i], &vals);
332011767SAnurag.Maskey@Sun.COM 		if (ret == NWAM_SUCCESS) {
332111767SAnurag.Maskey@Sun.COM 			write_export_command(NWAM_OBJECT_TYPE_ENM, props[i],
332211767SAnurag.Maskey@Sun.COM 			    vals, of);
332311767SAnurag.Maskey@Sun.COM 			nwam_value_free(vals);
332411767SAnurag.Maskey@Sun.COM 		}
332511767SAnurag.Maskey@Sun.COM 	}
332611767SAnurag.Maskey@Sun.COM 	(void) fprintf(of, "end\n");
332711767SAnurag.Maskey@Sun.COM 
332811767SAnurag.Maskey@Sun.COM 	free(props);
332911767SAnurag.Maskey@Sun.COM 	return (0);
333011767SAnurag.Maskey@Sun.COM }
333111767SAnurag.Maskey@Sun.COM 
333211767SAnurag.Maskey@Sun.COM static int
export_loc_callback(nwam_loc_handle_t loc,void * arg)333311767SAnurag.Maskey@Sun.COM export_loc_callback(nwam_loc_handle_t loc, void *arg)
333411767SAnurag.Maskey@Sun.COM {
333511767SAnurag.Maskey@Sun.COM 	char		*name;
333611767SAnurag.Maskey@Sun.COM 	const char	**props;
333711767SAnurag.Maskey@Sun.COM 	nwam_value_t	vals;
333811767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
333911767SAnurag.Maskey@Sun.COM 	uint_t		num;
334011767SAnurag.Maskey@Sun.COM 	int		i;
334111767SAnurag.Maskey@Sun.COM 	FILE		*of = arg;
334211767SAnurag.Maskey@Sun.COM 
334311767SAnurag.Maskey@Sun.COM 	assert(of != NULL);
334411767SAnurag.Maskey@Sun.COM 
334511767SAnurag.Maskey@Sun.COM 	if ((ret = nwam_loc_get_name(loc, &name)) != NWAM_SUCCESS)
334611767SAnurag.Maskey@Sun.COM 		return (ret);
334711767SAnurag.Maskey@Sun.COM 
334811767SAnurag.Maskey@Sun.COM 	/* Do not export Automatic, NoNet or Legacy locations */
334911767SAnurag.Maskey@Sun.COM 	if (NWAM_LOC_NAME_PRE_DEFINED(name)) {
335011767SAnurag.Maskey@Sun.COM 		free(name);
335111767SAnurag.Maskey@Sun.COM 		return (0);
335211767SAnurag.Maskey@Sun.COM 	}
335311767SAnurag.Maskey@Sun.COM 
335411767SAnurag.Maskey@Sun.COM 	(void) fprintf(of, "create loc \"%s\"\n", name);
335511767SAnurag.Maskey@Sun.COM 	free(name);
335611767SAnurag.Maskey@Sun.COM 	/*
335711767SAnurag.Maskey@Sun.COM 	 * Because of dependencies between properties, they have to be
335811767SAnurag.Maskey@Sun.COM 	 * exported in the same order as when they are walked.
335911767SAnurag.Maskey@Sun.COM 	 */
336011767SAnurag.Maskey@Sun.COM 	if ((ret = nwam_loc_get_default_proplist(&props, &num)) != NWAM_SUCCESS)
336111767SAnurag.Maskey@Sun.COM 		return (ret);
336211767SAnurag.Maskey@Sun.COM 	for (i = 0; i < num; i++) {
336311767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_get_prop_value(loc, props[i], &vals);
336411767SAnurag.Maskey@Sun.COM 		if (ret == NWAM_SUCCESS) {
336511767SAnurag.Maskey@Sun.COM 			write_export_command(NWAM_OBJECT_TYPE_LOC, props[i],
336611767SAnurag.Maskey@Sun.COM 			    vals, of);
336711767SAnurag.Maskey@Sun.COM 			nwam_value_free(vals);
336811767SAnurag.Maskey@Sun.COM 		}
336911767SAnurag.Maskey@Sun.COM 	}
337011767SAnurag.Maskey@Sun.COM 	(void) fprintf(of, "end\n");
337111767SAnurag.Maskey@Sun.COM 
337211767SAnurag.Maskey@Sun.COM 	free(props);
337311767SAnurag.Maskey@Sun.COM 	return (0);
337411767SAnurag.Maskey@Sun.COM }
337511767SAnurag.Maskey@Sun.COM 
337611767SAnurag.Maskey@Sun.COM static int
export_wlan_callback(nwam_known_wlan_handle_t wlan,void * arg)337711767SAnurag.Maskey@Sun.COM export_wlan_callback(nwam_known_wlan_handle_t wlan, void *arg)
337811767SAnurag.Maskey@Sun.COM {
337911767SAnurag.Maskey@Sun.COM 	char		*name;
338011767SAnurag.Maskey@Sun.COM 	const char	**props;
338111767SAnurag.Maskey@Sun.COM 	nwam_value_t	vals;
338211767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
338311767SAnurag.Maskey@Sun.COM 	uint_t		num;
338411767SAnurag.Maskey@Sun.COM 	int		i;
338511767SAnurag.Maskey@Sun.COM 	FILE		*of = arg;
338611767SAnurag.Maskey@Sun.COM 
338711767SAnurag.Maskey@Sun.COM 	assert(of != NULL);
338811767SAnurag.Maskey@Sun.COM 
338911767SAnurag.Maskey@Sun.COM 	if ((ret = nwam_known_wlan_get_name(wlan, &name)) != NWAM_SUCCESS)
339011767SAnurag.Maskey@Sun.COM 		return (ret);
339111767SAnurag.Maskey@Sun.COM 
339211767SAnurag.Maskey@Sun.COM 	(void) fprintf(of, "create wlan \"%s\"\n", name);
339311767SAnurag.Maskey@Sun.COM 	free(name);
339411767SAnurag.Maskey@Sun.COM 	/*
339511767SAnurag.Maskey@Sun.COM 	 * Because of dependencies between properties, they have to be
339611767SAnurag.Maskey@Sun.COM 	 * exported in the same order as when they are walked.
339711767SAnurag.Maskey@Sun.COM 	 */
339811767SAnurag.Maskey@Sun.COM 	if ((ret = nwam_known_wlan_get_default_proplist(&props, &num))
339911767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
340011767SAnurag.Maskey@Sun.COM 		return (ret);
340111767SAnurag.Maskey@Sun.COM 	for (i = 0; i < num; i++) {
340211767SAnurag.Maskey@Sun.COM 		ret = nwam_known_wlan_get_prop_value(wlan, props[i], &vals);
340311767SAnurag.Maskey@Sun.COM 		if (ret == NWAM_SUCCESS) {
340411767SAnurag.Maskey@Sun.COM 			write_export_command(NWAM_OBJECT_TYPE_KNOWN_WLAN,
340511767SAnurag.Maskey@Sun.COM 			    props[i], vals, of);
340611767SAnurag.Maskey@Sun.COM 			nwam_value_free(vals);
340711767SAnurag.Maskey@Sun.COM 		}
340811767SAnurag.Maskey@Sun.COM 	}
340911767SAnurag.Maskey@Sun.COM 	(void) fprintf(of, "end\n");
341011767SAnurag.Maskey@Sun.COM 
341111767SAnurag.Maskey@Sun.COM 	free(props);
341211767SAnurag.Maskey@Sun.COM 	return (0);
341311767SAnurag.Maskey@Sun.COM }
341411767SAnurag.Maskey@Sun.COM 
341511767SAnurag.Maskey@Sun.COM /*
341611767SAnurag.Maskey@Sun.COM  * Writes configuration to screen or file (with -f option).
341711767SAnurag.Maskey@Sun.COM  * Writes a "destroy -a" if option -d is given.
341811767SAnurag.Maskey@Sun.COM  */
341911767SAnurag.Maskey@Sun.COM void
export_func(cmd_t * cmd)342011767SAnurag.Maskey@Sun.COM export_func(cmd_t *cmd)
342111767SAnurag.Maskey@Sun.COM {
342211767SAnurag.Maskey@Sun.COM 	int		c;
342311767SAnurag.Maskey@Sun.COM 	boolean_t	need_to_close = B_FALSE, write_to_file = B_FALSE;
342411767SAnurag.Maskey@Sun.COM 	boolean_t	add_destroy = B_FALSE, lhandle = B_FALSE;
342511767SAnurag.Maskey@Sun.COM 	char		filepath[MAXPATHLEN];
342611767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret = NWAM_SUCCESS;
342711767SAnurag.Maskey@Sun.COM 	FILE		*of = NULL; /* either filename or stdout */
342811767SAnurag.Maskey@Sun.COM 
342911767SAnurag.Maskey@Sun.COM 	/* what to export */
343011767SAnurag.Maskey@Sun.COM 	boolean_t export_ncp = B_FALSE, export_ncu = B_FALSE;
343111767SAnurag.Maskey@Sun.COM 	boolean_t export_loc = B_FALSE, export_enm = B_FALSE;
343211767SAnurag.Maskey@Sun.COM 	boolean_t export_wlan = B_FALSE;
343311767SAnurag.Maskey@Sun.COM 	char *name = NULL;
343411767SAnurag.Maskey@Sun.COM 
343511767SAnurag.Maskey@Sun.COM 	/* check for -d and -f flags */
343611767SAnurag.Maskey@Sun.COM 	filepath[0] = '\0';
343711767SAnurag.Maskey@Sun.COM 	optind = 0;
343811767SAnurag.Maskey@Sun.COM 	while ((c = getopt(cmd->cmd_argc, cmd->cmd_argv, "df:")) != EOF) {
343911767SAnurag.Maskey@Sun.COM 		switch (c) {
344011767SAnurag.Maskey@Sun.COM 		case 'f':
344111767SAnurag.Maskey@Sun.COM 			write_to_file = B_TRUE;
344211767SAnurag.Maskey@Sun.COM 			break;
344311767SAnurag.Maskey@Sun.COM 		case 'd':
344411767SAnurag.Maskey@Sun.COM 			add_destroy = B_TRUE;
344511767SAnurag.Maskey@Sun.COM 			break;
344611767SAnurag.Maskey@Sun.COM 		default:
344711767SAnurag.Maskey@Sun.COM 			command_usage(CMD_EXPORT);
344811767SAnurag.Maskey@Sun.COM 			return;
344911767SAnurag.Maskey@Sun.COM 		}
345011767SAnurag.Maskey@Sun.COM 	}
345111767SAnurag.Maskey@Sun.COM 
345211767SAnurag.Maskey@Sun.COM 	/* determine where to export */
345311767SAnurag.Maskey@Sun.COM 	if (!write_to_file) {
345411767SAnurag.Maskey@Sun.COM 		of = stdout;
345511767SAnurag.Maskey@Sun.COM 	} else {
345611767SAnurag.Maskey@Sun.COM 		/*
345711767SAnurag.Maskey@Sun.COM 		 * If -d was specified with -f, then argv[2] is filename,
345811767SAnurag.Maskey@Sun.COM 		 * otherwise, argv[1] is filename.
345911767SAnurag.Maskey@Sun.COM 		 */
346011767SAnurag.Maskey@Sun.COM 		(void) strlcpy(filepath,
346111767SAnurag.Maskey@Sun.COM 		    (add_destroy ? cmd->cmd_argv[2] : cmd->cmd_argv[1]),
346211767SAnurag.Maskey@Sun.COM 		    sizeof (filepath));
346311767SAnurag.Maskey@Sun.COM 		if ((of = fopen(filepath, "w")) == NULL) {
346411767SAnurag.Maskey@Sun.COM 			nerr(gettext("opening file '%s': %s"), filepath,
346511767SAnurag.Maskey@Sun.COM 			    strerror(errno));
346611767SAnurag.Maskey@Sun.COM 			goto done;
346711767SAnurag.Maskey@Sun.COM 		}
346811767SAnurag.Maskey@Sun.COM 		setbuf(of, NULL);
346911767SAnurag.Maskey@Sun.COM 		need_to_close = B_TRUE;
347011767SAnurag.Maskey@Sun.COM 	}
347111767SAnurag.Maskey@Sun.COM 
347211767SAnurag.Maskey@Sun.COM 	if (add_destroy) {
347311767SAnurag.Maskey@Sun.COM 		/* only possible in global scope */
347411767SAnurag.Maskey@Sun.COM 		if (current_scope == NWAM_SCOPE_GBL) {
347511767SAnurag.Maskey@Sun.COM 			(void) fprintf(of, "destroy -a\n");
347611767SAnurag.Maskey@Sun.COM 		} else {
347711767SAnurag.Maskey@Sun.COM 			nerr("Option -d is not allowed in non-global scope");
347811767SAnurag.Maskey@Sun.COM 			goto done;
347911767SAnurag.Maskey@Sun.COM 		}
348011767SAnurag.Maskey@Sun.COM 	}
348111767SAnurag.Maskey@Sun.COM 
348211767SAnurag.Maskey@Sun.COM 	/* In the following scopes, only the -f argument is valid */
348311767SAnurag.Maskey@Sun.COM 	if (((current_scope == NWAM_SCOPE_LOC ||
348411767SAnurag.Maskey@Sun.COM 	    current_scope == NWAM_SCOPE_ENM ||
348511767SAnurag.Maskey@Sun.COM 	    current_scope == NWAM_SCOPE_WLAN ||
348611767SAnurag.Maskey@Sun.COM 	    current_scope == NWAM_SCOPE_NCU) &&
348711767SAnurag.Maskey@Sun.COM 	    cmd->cmd_argc != 0 && !write_to_file)) {
348811767SAnurag.Maskey@Sun.COM 		nerr("'export' does not take arguments at this scope");
348911767SAnurag.Maskey@Sun.COM 		goto done;
349011767SAnurag.Maskey@Sun.COM 	}
349111767SAnurag.Maskey@Sun.COM 	if (current_scope == NWAM_SCOPE_NCP) {
349211767SAnurag.Maskey@Sun.COM 		if (cmd->cmd_res1_type == RT1_ENM ||
349311767SAnurag.Maskey@Sun.COM 		    cmd->cmd_res1_type == RT1_LOC ||
349411767SAnurag.Maskey@Sun.COM 		    cmd->cmd_res1_type == RT1_WLAN) {
349511767SAnurag.Maskey@Sun.COM 			nerr("only ncu can be exported at this scope");
349611767SAnurag.Maskey@Sun.COM 			goto done;
349711767SAnurag.Maskey@Sun.COM 		}
349811767SAnurag.Maskey@Sun.COM 	}
349911767SAnurag.Maskey@Sun.COM 
350011767SAnurag.Maskey@Sun.COM 	/*
350111767SAnurag.Maskey@Sun.COM 	 * Determine what objects to export depending on scope and command
350211767SAnurag.Maskey@Sun.COM 	 * arguments.  If -f is specified, then the object name is argv[2].
350311767SAnurag.Maskey@Sun.COM 	 * Otherwise, argv[0] is name, unless exporting all in global
350411767SAnurag.Maskey@Sun.COM 	 * scope in which case name is set back to NULL.
350511767SAnurag.Maskey@Sun.COM 	 */
350611767SAnurag.Maskey@Sun.COM 	switch (current_scope) {
350711767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_GBL:
350811767SAnurag.Maskey@Sun.COM 		name = (write_to_file ? trim_quotes(cmd->cmd_argv[2]) :
350911767SAnurag.Maskey@Sun.COM 		    trim_quotes(cmd->cmd_argv[0]));
351011767SAnurag.Maskey@Sun.COM 		switch (cmd->cmd_res1_type) {
351111767SAnurag.Maskey@Sun.COM 		case RT1_LOC:
351211767SAnurag.Maskey@Sun.COM 			export_loc = B_TRUE;
351311767SAnurag.Maskey@Sun.COM 			break;
351411767SAnurag.Maskey@Sun.COM 		case RT1_ENM:
351511767SAnurag.Maskey@Sun.COM 			export_enm = B_TRUE;
351611767SAnurag.Maskey@Sun.COM 			break;
351711767SAnurag.Maskey@Sun.COM 		case RT1_WLAN:
351811767SAnurag.Maskey@Sun.COM 			export_wlan = B_TRUE;
351911767SAnurag.Maskey@Sun.COM 			break;
352011767SAnurag.Maskey@Sun.COM 		case RT1_NCP:
352111767SAnurag.Maskey@Sun.COM 			export_ncp = B_TRUE;
352211767SAnurag.Maskey@Sun.COM 			if (cmd->cmd_res2_type == RT2_NCU) {
352311767SAnurag.Maskey@Sun.COM 				nerr("cannot export ncu at from global scope");
352411767SAnurag.Maskey@Sun.COM 				goto done;
352511767SAnurag.Maskey@Sun.COM 			}
352611767SAnurag.Maskey@Sun.COM 			break;
352711767SAnurag.Maskey@Sun.COM 		default:
352811767SAnurag.Maskey@Sun.COM 			/* export everything */
352911767SAnurag.Maskey@Sun.COM 			export_loc = B_TRUE;
353011767SAnurag.Maskey@Sun.COM 			export_enm = B_TRUE;
353111767SAnurag.Maskey@Sun.COM 			export_wlan = B_TRUE;
353211767SAnurag.Maskey@Sun.COM 			export_ncp = B_TRUE; /* NCP will export the NCUs */
353311767SAnurag.Maskey@Sun.COM 			free(name);
353411767SAnurag.Maskey@Sun.COM 			name = NULL; /* exporting all, undo name */
353511767SAnurag.Maskey@Sun.COM 			break;
353611767SAnurag.Maskey@Sun.COM 		}
353711767SAnurag.Maskey@Sun.COM 		break;
353811767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_LOC:
353911767SAnurag.Maskey@Sun.COM 		export_loc = B_TRUE;
354011767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_get_name(loc_h, &name);
354111767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
354211767SAnurag.Maskey@Sun.COM 			goto fail;
354311767SAnurag.Maskey@Sun.COM 		break;
354411767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_ENM:
354511767SAnurag.Maskey@Sun.COM 		export_enm = B_TRUE;
354611767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_get_name(enm_h, &name);
354711767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
354811767SAnurag.Maskey@Sun.COM 			goto fail;
354911767SAnurag.Maskey@Sun.COM 		break;
355011767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_WLAN:
355111767SAnurag.Maskey@Sun.COM 		export_wlan = B_TRUE;
355211767SAnurag.Maskey@Sun.COM 		ret = nwam_known_wlan_get_name(wlan_h, &name);
355311767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
355411767SAnurag.Maskey@Sun.COM 			goto fail;
355511767SAnurag.Maskey@Sun.COM 		break;
355611767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_NCP:
355711767SAnurag.Maskey@Sun.COM 		if (cmd->cmd_res2_type == RT2_NCU) {
355811767SAnurag.Maskey@Sun.COM 			export_ncu = B_TRUE;
355911767SAnurag.Maskey@Sun.COM 			name = (write_to_file ? trim_quotes(cmd->cmd_argv[2]) :
356011767SAnurag.Maskey@Sun.COM 			    trim_quotes(cmd->cmd_argv[0]));
356111767SAnurag.Maskey@Sun.COM 		} else {
356211767SAnurag.Maskey@Sun.COM 			export_ncp = B_TRUE;
356311767SAnurag.Maskey@Sun.COM 			ret = nwam_ncp_get_name(ncp_h, &name);
356411767SAnurag.Maskey@Sun.COM 			if (ret != NWAM_SUCCESS)
356511767SAnurag.Maskey@Sun.COM 				goto fail;
356611767SAnurag.Maskey@Sun.COM 		}
356711767SAnurag.Maskey@Sun.COM 		break;
356811767SAnurag.Maskey@Sun.COM 	case NWAM_SCOPE_NCU:
356911767SAnurag.Maskey@Sun.COM 		export_ncu = B_TRUE;
357011767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_get_name(ncu_h, &name);
357111767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
357211767SAnurag.Maskey@Sun.COM 			goto fail;
357311767SAnurag.Maskey@Sun.COM 		break;
357411767SAnurag.Maskey@Sun.COM 	default:
357511767SAnurag.Maskey@Sun.COM 		nerr("Invalid scope");
357611767SAnurag.Maskey@Sun.COM 		goto done;
357711767SAnurag.Maskey@Sun.COM 	}
357811767SAnurag.Maskey@Sun.COM 
357911767SAnurag.Maskey@Sun.COM 	/* Now, export objects according to the flags set */
358011767SAnurag.Maskey@Sun.COM 	if (export_ncp) {
358111767SAnurag.Maskey@Sun.COM 		lhandle = B_FALSE;
358211767SAnurag.Maskey@Sun.COM 		if (name == NULL) {
358311767SAnurag.Maskey@Sun.COM 			/* export all NCPs */
358411767SAnurag.Maskey@Sun.COM 			ret = nwam_walk_ncps(export_ncp_callback, of, 0, NULL);
358511767SAnurag.Maskey@Sun.COM 		} else if (NWAM_NCP_AUTOMATIC(name)) {
358611767SAnurag.Maskey@Sun.COM 			nerr("'%s' ncp cannot be exported", name);
358711767SAnurag.Maskey@Sun.COM 			goto fail;
358811767SAnurag.Maskey@Sun.COM 		} else {
358911767SAnurag.Maskey@Sun.COM 			if (ncp_h == NULL) {
359011767SAnurag.Maskey@Sun.COM 				ret = nwam_ncp_read(name, 0, &ncp_h);
359111767SAnurag.Maskey@Sun.COM 				if (ret != NWAM_SUCCESS)
359211767SAnurag.Maskey@Sun.COM 					goto fail;
359311767SAnurag.Maskey@Sun.COM 				lhandle = B_TRUE;
359411767SAnurag.Maskey@Sun.COM 			}
359511767SAnurag.Maskey@Sun.COM 			/* will export NCUs also */
359611767SAnurag.Maskey@Sun.COM 			ret = export_ncp_callback(ncp_h, of);
359711767SAnurag.Maskey@Sun.COM 			if (lhandle) {
359811767SAnurag.Maskey@Sun.COM 				nwam_ncp_free(ncp_h);
359911767SAnurag.Maskey@Sun.COM 				ncp_h = NULL;
360011767SAnurag.Maskey@Sun.COM 			}
360111767SAnurag.Maskey@Sun.COM 		}
360211767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
360311767SAnurag.Maskey@Sun.COM 			goto fail;
360411767SAnurag.Maskey@Sun.COM 	}
360511767SAnurag.Maskey@Sun.COM 
360611767SAnurag.Maskey@Sun.COM 	if (export_ncu) {
360711767SAnurag.Maskey@Sun.COM 		if (name == NULL) {
360811767SAnurag.Maskey@Sun.COM 			/* export all NCUs */
360911767SAnurag.Maskey@Sun.COM 			ret = nwam_ncp_walk_ncus(ncp_h, export_ncu_callback, of,
361011767SAnurag.Maskey@Sun.COM 			    NWAM_FLAG_NCU_TYPE_CLASS_ALL, NULL);
361111767SAnurag.Maskey@Sun.COM 		} else {
361211767SAnurag.Maskey@Sun.COM 			if (ncu_h == NULL) {
361311767SAnurag.Maskey@Sun.COM 				/* no NCU handle -> called from NCP scope */
361411767SAnurag.Maskey@Sun.COM 				nwam_ncu_type_t		ncu_type;
361511767SAnurag.Maskey@Sun.COM 				nwam_ncu_class_t	ncu_class;
361611767SAnurag.Maskey@Sun.COM 
361711767SAnurag.Maskey@Sun.COM 				ncu_class = (nwam_ncu_class_t)
361811767SAnurag.Maskey@Sun.COM 				    cmd->cmd_ncu_class_type;
361911767SAnurag.Maskey@Sun.COM 				ncu_type = nwam_ncu_class_to_type(ncu_class);
362011767SAnurag.Maskey@Sun.COM 				ret = nwam_ncu_read(ncp_h, name,
362111767SAnurag.Maskey@Sun.COM 				    ncu_type, 0, &ncu_h);
362211767SAnurag.Maskey@Sun.COM 				if (ret == NWAM_SUCCESS) {
362311767SAnurag.Maskey@Sun.COM 					/* one NCU with given name */
362411767SAnurag.Maskey@Sun.COM 					ret = export_ncu_callback(ncu_h, of);
362511767SAnurag.Maskey@Sun.COM 					nwam_ncu_free(ncu_h);
362611767SAnurag.Maskey@Sun.COM 					ncu_h = NULL;
362711767SAnurag.Maskey@Sun.COM 				} else if (ret == NWAM_ENTITY_MULTIPLE_VALUES) {
362811767SAnurag.Maskey@Sun.COM 					/* multiple NCUs with given name */
362911767SAnurag.Maskey@Sun.COM 					ret = nwam_ncu_read(ncp_h, name,
363011767SAnurag.Maskey@Sun.COM 					    NWAM_NCU_TYPE_LINK, 0, &ncu_h);
363111767SAnurag.Maskey@Sun.COM 					if (ret != NWAM_SUCCESS)
363211767SAnurag.Maskey@Sun.COM 						goto fail;
363311767SAnurag.Maskey@Sun.COM 					ret = export_ncu_callback(ncu_h, of);
363411767SAnurag.Maskey@Sun.COM 					nwam_ncu_free(ncu_h);
363511767SAnurag.Maskey@Sun.COM 					ncu_h = NULL;
363611767SAnurag.Maskey@Sun.COM 
363711767SAnurag.Maskey@Sun.COM 					ret = nwam_ncu_read(ncp_h, name,
363811767SAnurag.Maskey@Sun.COM 					    NWAM_NCU_TYPE_INTERFACE, 0, &ncu_h);
363911767SAnurag.Maskey@Sun.COM 					if (ret != NWAM_SUCCESS)
364011767SAnurag.Maskey@Sun.COM 						goto fail;
364111767SAnurag.Maskey@Sun.COM 					ret = export_ncu_callback(ncu_h, of);
364211767SAnurag.Maskey@Sun.COM 					nwam_ncu_free(ncu_h);
364311767SAnurag.Maskey@Sun.COM 					ncu_h = NULL;
364411767SAnurag.Maskey@Sun.COM 				} else {
364511767SAnurag.Maskey@Sun.COM 					goto fail;
364611767SAnurag.Maskey@Sun.COM 				}
364711767SAnurag.Maskey@Sun.COM 			} else {
364811767SAnurag.Maskey@Sun.COM 				/* NCU handle exists */
364911767SAnurag.Maskey@Sun.COM 				ret = export_ncu_callback(ncu_h, of);
365011767SAnurag.Maskey@Sun.COM 			}
365111767SAnurag.Maskey@Sun.COM 		}
365211767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
365311767SAnurag.Maskey@Sun.COM 			goto fail;
365411767SAnurag.Maskey@Sun.COM 	}
365511767SAnurag.Maskey@Sun.COM 
365611767SAnurag.Maskey@Sun.COM 	if (export_loc) {
365711767SAnurag.Maskey@Sun.COM 		lhandle = B_FALSE;
365811767SAnurag.Maskey@Sun.COM 		if (name == NULL) {
365911767SAnurag.Maskey@Sun.COM 			/* export all locations */
366011767SAnurag.Maskey@Sun.COM 			ret = nwam_walk_locs(export_loc_callback, of,
366111767SAnurag.Maskey@Sun.COM 			    NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
366211767SAnurag.Maskey@Sun.COM 		} else if (NWAM_LOC_NAME_PRE_DEFINED(name)) {
366311767SAnurag.Maskey@Sun.COM 			nerr("'%s' loc cannot be exported", name);
366411767SAnurag.Maskey@Sun.COM 			goto fail;
366511767SAnurag.Maskey@Sun.COM 		} else {
366611767SAnurag.Maskey@Sun.COM 			if (loc_h == NULL) {
366711767SAnurag.Maskey@Sun.COM 				ret = nwam_loc_read(name, 0, &loc_h);
366811767SAnurag.Maskey@Sun.COM 				if (ret != NWAM_SUCCESS)
366911767SAnurag.Maskey@Sun.COM 					goto fail;
367011767SAnurag.Maskey@Sun.COM 				lhandle = B_TRUE;
367111767SAnurag.Maskey@Sun.COM 			}
367211767SAnurag.Maskey@Sun.COM 			ret = export_loc_callback(loc_h, of);
367311767SAnurag.Maskey@Sun.COM 			if (lhandle) {
367411767SAnurag.Maskey@Sun.COM 				nwam_loc_free(loc_h);
367511767SAnurag.Maskey@Sun.COM 				loc_h = NULL;
367611767SAnurag.Maskey@Sun.COM 			}
367711767SAnurag.Maskey@Sun.COM 		}
367811767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
367911767SAnurag.Maskey@Sun.COM 			goto fail;
368011767SAnurag.Maskey@Sun.COM 	}
368111767SAnurag.Maskey@Sun.COM 
368211767SAnurag.Maskey@Sun.COM 	if (export_enm) {
368311767SAnurag.Maskey@Sun.COM 		lhandle = B_FALSE;
368411767SAnurag.Maskey@Sun.COM 		if (name == NULL) {
368511767SAnurag.Maskey@Sun.COM 			/* export all ENMs */
368611767SAnurag.Maskey@Sun.COM 			ret = nwam_walk_enms(export_enm_callback, of,
368711767SAnurag.Maskey@Sun.COM 			    NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
368811767SAnurag.Maskey@Sun.COM 		} else {
368911767SAnurag.Maskey@Sun.COM 			if (enm_h == NULL) {
369011767SAnurag.Maskey@Sun.COM 				ret = nwam_enm_read(name, 0, &enm_h);
369111767SAnurag.Maskey@Sun.COM 				if (ret != NWAM_SUCCESS)
369211767SAnurag.Maskey@Sun.COM 					goto fail;
369311767SAnurag.Maskey@Sun.COM 				lhandle = B_TRUE;
369411767SAnurag.Maskey@Sun.COM 			}
369511767SAnurag.Maskey@Sun.COM 			ret = export_enm_callback(enm_h, of);
369611767SAnurag.Maskey@Sun.COM 			if (lhandle) {
369711767SAnurag.Maskey@Sun.COM 				nwam_enm_free(enm_h);
369811767SAnurag.Maskey@Sun.COM 				enm_h = NULL;
369911767SAnurag.Maskey@Sun.COM 			}
370011767SAnurag.Maskey@Sun.COM 		}
370111767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
370211767SAnurag.Maskey@Sun.COM 			goto fail;
370311767SAnurag.Maskey@Sun.COM 	}
370411767SAnurag.Maskey@Sun.COM 
370511767SAnurag.Maskey@Sun.COM 	if (export_wlan) {
370611767SAnurag.Maskey@Sun.COM 		lhandle = B_FALSE;
370711767SAnurag.Maskey@Sun.COM 		if (name == NULL) {
370811767SAnurag.Maskey@Sun.COM 			/* export all WLANs */
370911767SAnurag.Maskey@Sun.COM 			ret = nwam_walk_known_wlans(export_wlan_callback, of,
371011767SAnurag.Maskey@Sun.COM 			    NWAM_FLAG_KNOWN_WLAN_WALK_PRIORITY_ORDER, NULL);
371111767SAnurag.Maskey@Sun.COM 		} else {
371211767SAnurag.Maskey@Sun.COM 			if (wlan_h == NULL) {
371311767SAnurag.Maskey@Sun.COM 				ret = nwam_known_wlan_read(name, 0,
371411767SAnurag.Maskey@Sun.COM 				    &wlan_h);
371511767SAnurag.Maskey@Sun.COM 				if (ret != NWAM_SUCCESS)
371611767SAnurag.Maskey@Sun.COM 					goto fail;
371711767SAnurag.Maskey@Sun.COM 				lhandle = B_TRUE;
371811767SAnurag.Maskey@Sun.COM 			}
371911767SAnurag.Maskey@Sun.COM 			ret = export_wlan_callback(wlan_h, of);
372011767SAnurag.Maskey@Sun.COM 			if (lhandle) {
372111767SAnurag.Maskey@Sun.COM 				nwam_known_wlan_free(wlan_h);
372211767SAnurag.Maskey@Sun.COM 				wlan_h = NULL;
372311767SAnurag.Maskey@Sun.COM 			}
372411767SAnurag.Maskey@Sun.COM 		}
372511767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS)
372611767SAnurag.Maskey@Sun.COM 			goto fail;
372711767SAnurag.Maskey@Sun.COM 	}
372811767SAnurag.Maskey@Sun.COM 
372911767SAnurag.Maskey@Sun.COM fail:
373011767SAnurag.Maskey@Sun.COM 	free(name);
373111767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
373211767SAnurag.Maskey@Sun.COM 		nwamerr(ret, "Export error");
373311767SAnurag.Maskey@Sun.COM 
373411767SAnurag.Maskey@Sun.COM done:
373511767SAnurag.Maskey@Sun.COM 	if (need_to_close)
373611767SAnurag.Maskey@Sun.COM 		(void) fclose(of);
373711767SAnurag.Maskey@Sun.COM }
373811767SAnurag.Maskey@Sun.COM 
373911767SAnurag.Maskey@Sun.COM /*
374011767SAnurag.Maskey@Sun.COM  * Get property value.  If the -V option is specified, only the value is
374111767SAnurag.Maskey@Sun.COM  * printed without the property name.
374211767SAnurag.Maskey@Sun.COM  */
374311767SAnurag.Maskey@Sun.COM void
get_func(cmd_t * cmd)374411767SAnurag.Maskey@Sun.COM get_func(cmd_t *cmd)
374511767SAnurag.Maskey@Sun.COM {
374611767SAnurag.Maskey@Sun.COM 	nwam_error_t		ret = NWAM_SUCCESS;
374711767SAnurag.Maskey@Sun.COM 	nwam_value_t		prop_value;
374811767SAnurag.Maskey@Sun.COM 	const char		*prop;
374911767SAnurag.Maskey@Sun.COM 	boolean_t		value_only = B_FALSE;
375011767SAnurag.Maskey@Sun.COM 	nwam_object_type_t	object_type = active_object_type();
375111767SAnurag.Maskey@Sun.COM 
375211767SAnurag.Maskey@Sun.COM 	/* check if option is -V to print value only */
375311767SAnurag.Maskey@Sun.COM 	if (cmd->cmd_argc == 1) {
375411767SAnurag.Maskey@Sun.COM 		int c;
375511767SAnurag.Maskey@Sun.COM 
375611767SAnurag.Maskey@Sun.COM 		optind = 0;
375711767SAnurag.Maskey@Sun.COM 		while ((c = getopt(cmd->cmd_argc, cmd->cmd_argv, "V")) != EOF) {
375811767SAnurag.Maskey@Sun.COM 			switch (c) {
375911767SAnurag.Maskey@Sun.COM 			case 'V':
376011767SAnurag.Maskey@Sun.COM 				value_only = B_TRUE;
376111767SAnurag.Maskey@Sun.COM 				break;
376211767SAnurag.Maskey@Sun.COM 			default:
376311767SAnurag.Maskey@Sun.COM 				command_usage(CMD_GET);
376411767SAnurag.Maskey@Sun.COM 				return;
376511767SAnurag.Maskey@Sun.COM 			}
376611767SAnurag.Maskey@Sun.COM 		}
376711767SAnurag.Maskey@Sun.COM 	}
376811767SAnurag.Maskey@Sun.COM 
376911767SAnurag.Maskey@Sun.COM 	/* property to get is in cmd->cmd_prop_type */
377011767SAnurag.Maskey@Sun.COM 	if ((prop = pt_to_prop_name(object_type, cmd->cmd_prop_type)) == NULL) {
377111767SAnurag.Maskey@Sun.COM 		nerr("Get error: invalid %s property: '%s'",
377211767SAnurag.Maskey@Sun.COM 		    scope_to_str(current_scope), pt_to_str(cmd->cmd_prop_type));
377311767SAnurag.Maskey@Sun.COM 		return;
377411767SAnurag.Maskey@Sun.COM 	}
377511767SAnurag.Maskey@Sun.COM 
377611767SAnurag.Maskey@Sun.COM 	switch (object_type) {
377711767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
377811767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_get_prop_value(ncu_h, prop, &prop_value);
377911767SAnurag.Maskey@Sun.COM 		break;
378011767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
378111767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_get_prop_value(loc_h, prop, &prop_value);
378211767SAnurag.Maskey@Sun.COM 		break;
378311767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
378411767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_get_prop_value(enm_h, prop, &prop_value);
378511767SAnurag.Maskey@Sun.COM 		break;
378611767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
378711767SAnurag.Maskey@Sun.COM 		ret = nwam_known_wlan_get_prop_value(wlan_h, prop, &prop_value);
378811767SAnurag.Maskey@Sun.COM 		break;
378911767SAnurag.Maskey@Sun.COM 	}
379011767SAnurag.Maskey@Sun.COM 
379111767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS) {
379211767SAnurag.Maskey@Sun.COM 		if (ret == NWAM_ENTITY_NOT_FOUND)
379311767SAnurag.Maskey@Sun.COM 			nerr("Get error: property '%s' has not been set", prop);
379411767SAnurag.Maskey@Sun.COM 		else
379511767SAnurag.Maskey@Sun.COM 			nwamerr(ret, "Get error");
379611767SAnurag.Maskey@Sun.COM 		return;
379711767SAnurag.Maskey@Sun.COM 	}
379811767SAnurag.Maskey@Sun.COM 
379911767SAnurag.Maskey@Sun.COM 	if (value_only) {
380011767SAnurag.Maskey@Sun.COM 		output_prop_val(prop, prop_value, stdout, B_FALSE);
380111767SAnurag.Maskey@Sun.COM 		(void) printf("\n");
380211767SAnurag.Maskey@Sun.COM 	} else {
380311767SAnurag.Maskey@Sun.COM 		output_propname(prop, prop_value, NULL);
380411767SAnurag.Maskey@Sun.COM 	}
380511767SAnurag.Maskey@Sun.COM 	nwam_value_free(prop_value);
380611767SAnurag.Maskey@Sun.COM }
380711767SAnurag.Maskey@Sun.COM 
380811767SAnurag.Maskey@Sun.COM /*
380911767SAnurag.Maskey@Sun.COM  * Clears value of a property.
381011767SAnurag.Maskey@Sun.COM  * Read-only properties cannot be cleared.
381111767SAnurag.Maskey@Sun.COM  * If clearing a property invalidates the object, then that property
381211767SAnurag.Maskey@Sun.COM  * cannot be cleared.
381311767SAnurag.Maskey@Sun.COM  */
381411767SAnurag.Maskey@Sun.COM void
clear_func(cmd_t * cmd)381511767SAnurag.Maskey@Sun.COM clear_func(cmd_t *cmd)
381611767SAnurag.Maskey@Sun.COM {
381711767SAnurag.Maskey@Sun.COM 	nwam_error_t		ret;
381811767SAnurag.Maskey@Sun.COM 	const char		*prop;
381911767SAnurag.Maskey@Sun.COM 	nwam_object_type_t	object_type = active_object_type();
382011767SAnurag.Maskey@Sun.COM 
382111767SAnurag.Maskey@Sun.COM 	/* property to clear is in cmd->cmd_prop_type */
382211767SAnurag.Maskey@Sun.COM 	if ((prop = pt_to_prop_name(object_type, cmd->cmd_prop_type)) == NULL) {
382311767SAnurag.Maskey@Sun.COM 		nerr("Clear error: invalid %s property: '%s'",
382411767SAnurag.Maskey@Sun.COM 		    scope_to_str(current_scope), pt_to_str(cmd->cmd_prop_type));
382511767SAnurag.Maskey@Sun.COM 		return;
382611767SAnurag.Maskey@Sun.COM 	}
382711767SAnurag.Maskey@Sun.COM 	if (is_prop_read_only(object_type, prop)) {
382811767SAnurag.Maskey@Sun.COM 		nerr("Clear error: property '%s' is read-only", prop);
382911767SAnurag.Maskey@Sun.COM 		return;
383011767SAnurag.Maskey@Sun.COM 	}
383111767SAnurag.Maskey@Sun.COM 
383211767SAnurag.Maskey@Sun.COM 	switch (object_type) {
383311767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
383411767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_delete_prop(ncu_h, prop);
383511767SAnurag.Maskey@Sun.COM 		break;
383611767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
383711767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_delete_prop(loc_h, prop);
383811767SAnurag.Maskey@Sun.COM 		break;
383911767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
384011767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_delete_prop(enm_h, prop);
384111767SAnurag.Maskey@Sun.COM 		break;
384211767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
384311767SAnurag.Maskey@Sun.COM 		ret = nwam_known_wlan_delete_prop(wlan_h, prop);
384411767SAnurag.Maskey@Sun.COM 		break;
384511767SAnurag.Maskey@Sun.COM 	}
384611767SAnurag.Maskey@Sun.COM 
384711767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS) {
384811767SAnurag.Maskey@Sun.COM 		if (ret == NWAM_INVALID_ARG || ret == NWAM_ENTITY_NOT_FOUND) {
384911767SAnurag.Maskey@Sun.COM 			nerr("Clear error: property '%s' has not been set",
385011767SAnurag.Maskey@Sun.COM 			    prop);
385111767SAnurag.Maskey@Sun.COM 		} else {
385211767SAnurag.Maskey@Sun.COM 			nwamerr(ret, "Clear error");
385311767SAnurag.Maskey@Sun.COM 		}
385411767SAnurag.Maskey@Sun.COM 		return;
385511767SAnurag.Maskey@Sun.COM 	}
385611767SAnurag.Maskey@Sun.COM 
385711767SAnurag.Maskey@Sun.COM 	need_to_commit = B_TRUE;
385811767SAnurag.Maskey@Sun.COM }
385911767SAnurag.Maskey@Sun.COM 
386011767SAnurag.Maskey@Sun.COM /*
386111767SAnurag.Maskey@Sun.COM  * Prints all the choices available for an enum property [c1|c2|c3].
386211767SAnurag.Maskey@Sun.COM  * Prints [true|false] for a boolean property.
386311767SAnurag.Maskey@Sun.COM  */
386411767SAnurag.Maskey@Sun.COM static void
print_all_prop_choices(nwam_object_type_t object_type,const char * prop)386511767SAnurag.Maskey@Sun.COM print_all_prop_choices(nwam_object_type_t object_type, const char *prop)
386611767SAnurag.Maskey@Sun.COM {
386711767SAnurag.Maskey@Sun.COM 	uint64_t		i = 0;
386811767SAnurag.Maskey@Sun.COM 	const char		*str;
386911767SAnurag.Maskey@Sun.COM 	boolean_t		choices = B_FALSE;
387011767SAnurag.Maskey@Sun.COM 	nwam_value_type_t	value_type;
387111767SAnurag.Maskey@Sun.COM 	nwam_error_t		ret;
387211767SAnurag.Maskey@Sun.COM 
387311767SAnurag.Maskey@Sun.COM 	/* Special case: print object-specific options for activation-mode */
387411767SAnurag.Maskey@Sun.COM 	if (strcmp(prop, NWAM_NCU_PROP_ACTIVATION_MODE) == 0) {
387511767SAnurag.Maskey@Sun.COM 		/* "manual" for all objects */
387611767SAnurag.Maskey@Sun.COM 		(void) printf(" [%s|",
387711767SAnurag.Maskey@Sun.COM 		    propval_to_str(NWAM_NCU_PROP_ACTIVATION_MODE,
387811767SAnurag.Maskey@Sun.COM 		    NWAM_ACTIVATION_MODE_MANUAL));
387911767SAnurag.Maskey@Sun.COM 		if (object_type == NWAM_OBJECT_TYPE_NCU) {
388011767SAnurag.Maskey@Sun.COM 			(void) printf("%s]",
388111767SAnurag.Maskey@Sun.COM 			    propval_to_str(NWAM_NCU_PROP_ACTIVATION_MODE,
388211767SAnurag.Maskey@Sun.COM 			    NWAM_ACTIVATION_MODE_PRIORITIZED));
388311767SAnurag.Maskey@Sun.COM 		} else {
388411767SAnurag.Maskey@Sun.COM 			(void) printf("%s|%s]",
388511767SAnurag.Maskey@Sun.COM 			    propval_to_str(NWAM_NCU_PROP_ACTIVATION_MODE,
388611767SAnurag.Maskey@Sun.COM 			    NWAM_ACTIVATION_MODE_CONDITIONAL_ANY),
388711767SAnurag.Maskey@Sun.COM 			    propval_to_str(NWAM_NCU_PROP_ACTIVATION_MODE,
388811767SAnurag.Maskey@Sun.COM 			    NWAM_ACTIVATION_MODE_CONDITIONAL_ALL));
388911767SAnurag.Maskey@Sun.COM 		}
389011767SAnurag.Maskey@Sun.COM 		return;
389111767SAnurag.Maskey@Sun.COM 	}
389211767SAnurag.Maskey@Sun.COM 
389311767SAnurag.Maskey@Sun.COM 	/* Special case: only "manual" configsrc is allowed for LDAP */
389411767SAnurag.Maskey@Sun.COM 	if (strcmp(prop, NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC) == 0) {
389511767SAnurag.Maskey@Sun.COM 		(void) printf(" [%s]",
389611767SAnurag.Maskey@Sun.COM 		    propval_to_str(NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC,
389711767SAnurag.Maskey@Sun.COM 		    NWAM_CONFIGSRC_MANUAL));
389811767SAnurag.Maskey@Sun.COM 		return;
389911767SAnurag.Maskey@Sun.COM 	}
390011767SAnurag.Maskey@Sun.COM 
390111767SAnurag.Maskey@Sun.COM 	value_type = prop_value_type(object_type, prop);
390211767SAnurag.Maskey@Sun.COM 	switch (value_type) {
390311767SAnurag.Maskey@Sun.COM 	case NWAM_VALUE_TYPE_UINT64:
390411767SAnurag.Maskey@Sun.COM 		/* uint64 may be an enum, will print nothing if not an enum */
390511767SAnurag.Maskey@Sun.COM 		while ((ret = nwam_uint64_get_value_string(prop, i++, &str))
390611767SAnurag.Maskey@Sun.COM 		    == NWAM_SUCCESS || ret == NWAM_ENTITY_INVALID_VALUE) {
390711767SAnurag.Maskey@Sun.COM 			/* No string representation for i, continue. */
390811767SAnurag.Maskey@Sun.COM 			if (ret == NWAM_ENTITY_INVALID_VALUE)
390911767SAnurag.Maskey@Sun.COM 				continue;
391011767SAnurag.Maskey@Sun.COM 
391111767SAnurag.Maskey@Sun.COM 			if (!choices)
391211767SAnurag.Maskey@Sun.COM 				(void) printf("%s", " [");
391311767SAnurag.Maskey@Sun.COM 			(void) printf("%s%s", choices ? "|" : "", str);
391411767SAnurag.Maskey@Sun.COM 			choices = B_TRUE;
391511767SAnurag.Maskey@Sun.COM 		}
391611767SAnurag.Maskey@Sun.COM 		if (choices)
391711767SAnurag.Maskey@Sun.COM 			(void) putchar(']');
391811767SAnurag.Maskey@Sun.COM 		break;
391911767SAnurag.Maskey@Sun.COM 	case NWAM_VALUE_TYPE_BOOLEAN:
392011767SAnurag.Maskey@Sun.COM 		(void) printf(" [%s|%s]", "true", "false");
392111767SAnurag.Maskey@Sun.COM 		break;
392211767SAnurag.Maskey@Sun.COM 	case NWAM_VALUE_TYPE_STRING:
392311767SAnurag.Maskey@Sun.COM 		break;
392411767SAnurag.Maskey@Sun.COM 	}
392511767SAnurag.Maskey@Sun.COM }
392611767SAnurag.Maskey@Sun.COM 
392711767SAnurag.Maskey@Sun.COM /*
392811767SAnurag.Maskey@Sun.COM  * Walk through object properties.
392911767SAnurag.Maskey@Sun.COM  * For newly-created object, the property name with no value is displayed, and
393011767SAnurag.Maskey@Sun.COM  * the user can input a value for each property.
393111767SAnurag.Maskey@Sun.COM  * For existing object, the current value is displayed and user input overwrites
393211767SAnurag.Maskey@Sun.COM  * the existing one. If no input is given, the existing value remains.
393311767SAnurag.Maskey@Sun.COM  * Read-only properties are not displayed.
393411767SAnurag.Maskey@Sun.COM  * Read-only objects cannot be walked.
393511767SAnurag.Maskey@Sun.COM  * If the -a option is specified, no properties are skipped.
393611767SAnurag.Maskey@Sun.COM  */
393711767SAnurag.Maskey@Sun.COM void
walkprop_func(cmd_t * cmd)393811767SAnurag.Maskey@Sun.COM walkprop_func(cmd_t *cmd)
393911767SAnurag.Maskey@Sun.COM {
394011767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret = NWAM_SUCCESS;
394111767SAnurag.Maskey@Sun.COM 	nwam_value_t	vals = NULL; /* freed in _wait_input() */
394211767SAnurag.Maskey@Sun.COM 	int		i;
394311767SAnurag.Maskey@Sun.COM 	uint_t		prop_num;
394411767SAnurag.Maskey@Sun.COM 	const char	**props;
394511767SAnurag.Maskey@Sun.COM 	boolean_t	read_only = B_FALSE, all_props = B_FALSE;
394611767SAnurag.Maskey@Sun.COM 
394711767SAnurag.Maskey@Sun.COM 	nwam_object_type_t object_type;
394811767SAnurag.Maskey@Sun.COM 	prop_display_entry_t *prop_table;
394911767SAnurag.Maskey@Sun.COM 
395011767SAnurag.Maskey@Sun.COM 	if (!interactive_mode) {
395111767SAnurag.Maskey@Sun.COM 		nerr("'walkprop' is only allowed in interactive mode");
395211767SAnurag.Maskey@Sun.COM 		return;
395311767SAnurag.Maskey@Sun.COM 	}
395411767SAnurag.Maskey@Sun.COM 
395511767SAnurag.Maskey@Sun.COM 	/* check if option -a is specified to show all properties */
395611767SAnurag.Maskey@Sun.COM 	if (cmd->cmd_argc == 1) {
395711767SAnurag.Maskey@Sun.COM 		int c;
395811767SAnurag.Maskey@Sun.COM 		optind = 0;
395911767SAnurag.Maskey@Sun.COM 		while ((c = getopt(cmd->cmd_argc, cmd->cmd_argv, "a")) != EOF) {
396011767SAnurag.Maskey@Sun.COM 			switch (c) {
396111767SAnurag.Maskey@Sun.COM 			case 'a':
396211767SAnurag.Maskey@Sun.COM 				all_props = B_TRUE;
396311767SAnurag.Maskey@Sun.COM 				break;
396411767SAnurag.Maskey@Sun.COM 			default:
396511767SAnurag.Maskey@Sun.COM 				command_usage(CMD_WALKPROP);
396611767SAnurag.Maskey@Sun.COM 				return;
396711767SAnurag.Maskey@Sun.COM 			}
396811767SAnurag.Maskey@Sun.COM 		}
396911767SAnurag.Maskey@Sun.COM 	}
397011767SAnurag.Maskey@Sun.COM 
397111767SAnurag.Maskey@Sun.COM 	/* read-only objects cannot be walked */
397211767SAnurag.Maskey@Sun.COM 	if (obj1_type == RT1_NCP) {
397311767SAnurag.Maskey@Sun.COM 		/* must be in NCU scope, NCP scope doesn't get here */
397411767SAnurag.Maskey@Sun.COM 		(void) nwam_ncu_get_read_only(ncu_h, &read_only);
397511767SAnurag.Maskey@Sun.COM 	}
397611767SAnurag.Maskey@Sun.COM 	if (read_only) {
397711767SAnurag.Maskey@Sun.COM 		nerr("'walkprop' cannot be used in read-only objects");
397811767SAnurag.Maskey@Sun.COM 		return;
397911767SAnurag.Maskey@Sun.COM 	}
398011767SAnurag.Maskey@Sun.COM 
398111767SAnurag.Maskey@Sun.COM 	/* get the current object type and the prop_display_table */
398211767SAnurag.Maskey@Sun.COM 	object_type = active_object_type();
398311767SAnurag.Maskey@Sun.COM 	prop_table = get_prop_display_table(object_type);
398411767SAnurag.Maskey@Sun.COM 
398511767SAnurag.Maskey@Sun.COM 	/* get the property list depending on the object type */
398611767SAnurag.Maskey@Sun.COM 	switch (object_type) {
398711767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
398811767SAnurag.Maskey@Sun.COM 	{
398911767SAnurag.Maskey@Sun.COM 		nwam_ncu_type_t		ncu_type;
399011767SAnurag.Maskey@Sun.COM 		nwam_ncu_class_t	ncu_class;
399111767SAnurag.Maskey@Sun.COM 
399211767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_ncu_get_ncu_type(ncu_h, &ncu_type))
399311767SAnurag.Maskey@Sun.COM 		    != NWAM_SUCCESS)
399411767SAnurag.Maskey@Sun.COM 			break;
399511767SAnurag.Maskey@Sun.COM 		if ((ret = nwam_ncu_get_ncu_class(ncu_h, &ncu_class))
399611767SAnurag.Maskey@Sun.COM 		    != NWAM_SUCCESS)
399711767SAnurag.Maskey@Sun.COM 			break;
399811767SAnurag.Maskey@Sun.COM 
399911767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_get_default_proplist(ncu_type, ncu_class, &props,
400011767SAnurag.Maskey@Sun.COM 		    &prop_num);
400111767SAnurag.Maskey@Sun.COM 		break;
400211767SAnurag.Maskey@Sun.COM 	}
400311767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
400411767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_get_default_proplist(&props, &prop_num);
400511767SAnurag.Maskey@Sun.COM 		break;
400611767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
400711767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_get_default_proplist(&props, &prop_num);
400811767SAnurag.Maskey@Sun.COM 		break;
400911767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
401011767SAnurag.Maskey@Sun.COM 		ret = nwam_known_wlan_get_default_proplist(&props, &prop_num);
401111767SAnurag.Maskey@Sun.COM 		break;
401211767SAnurag.Maskey@Sun.COM 	}
401311767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS) {
401411767SAnurag.Maskey@Sun.COM 		nwamerr(ret, "Walkprop error: could not get property list");
401511767SAnurag.Maskey@Sun.COM 		return;
401611767SAnurag.Maskey@Sun.COM 	}
401711767SAnurag.Maskey@Sun.COM 
401811767SAnurag.Maskey@Sun.COM 	/* Loop through the properties */
401911767SAnurag.Maskey@Sun.COM 	if (all_props)
402011767SAnurag.Maskey@Sun.COM 		(void) printf(gettext("Walking all properties ...\n"));
402111767SAnurag.Maskey@Sun.COM 	for (i = 0; i < prop_num; i++) {
402211767SAnurag.Maskey@Sun.COM 		char line[NWAM_MAX_VALUE_LEN];
402311767SAnurag.Maskey@Sun.COM 		char **checked = NULL;
402411767SAnurag.Maskey@Sun.COM 
402511767SAnurag.Maskey@Sun.COM 		/* check if this property should be displayed */
402611767SAnurag.Maskey@Sun.COM 		if (is_prop_read_only(object_type, props[i]))
402711767SAnurag.Maskey@Sun.COM 			continue;
402811767SAnurag.Maskey@Sun.COM 		if (!all_props &&
402911767SAnurag.Maskey@Sun.COM 		    !show_prop_test(object_type, props[i], prop_table,
403011767SAnurag.Maskey@Sun.COM 		    checked, 0))
403111767SAnurag.Maskey@Sun.COM 			continue;
403211767SAnurag.Maskey@Sun.COM 
403311767SAnurag.Maskey@Sun.COM 		/* get the existing value for this property */
403411767SAnurag.Maskey@Sun.COM 		switch (object_type) {
403511767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_NCU:
403611767SAnurag.Maskey@Sun.COM 			ret = nwam_ncu_get_prop_value(ncu_h, props[i], &vals);
403711767SAnurag.Maskey@Sun.COM 			break;
403811767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_LOC:
403911767SAnurag.Maskey@Sun.COM 			ret = nwam_loc_get_prop_value(loc_h, props[i], &vals);
404011767SAnurag.Maskey@Sun.COM 			break;
404111767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_ENM:
404211767SAnurag.Maskey@Sun.COM 			ret = nwam_enm_get_prop_value(enm_h, props[i], &vals);
404311767SAnurag.Maskey@Sun.COM 			break;
404411767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_KNOWN_WLAN:
404511767SAnurag.Maskey@Sun.COM 			ret = nwam_known_wlan_get_prop_value(wlan_h, props[i],
404611767SAnurag.Maskey@Sun.COM 			    &vals);
404711767SAnurag.Maskey@Sun.COM 			break;
404811767SAnurag.Maskey@Sun.COM 		}
404911767SAnurag.Maskey@Sun.COM 		/* returns NWAM_ENTITY_NOT_FOUND if no existing value */
405011767SAnurag.Maskey@Sun.COM 		if (ret != NWAM_SUCCESS && ret != NWAM_ENTITY_NOT_FOUND)
405111767SAnurag.Maskey@Sun.COM 			continue;
405211767SAnurag.Maskey@Sun.COM 
405311767SAnurag.Maskey@Sun.COM 		/* print property */
405411767SAnurag.Maskey@Sun.COM 		(void) printf("%s", props[i]);
405511767SAnurag.Maskey@Sun.COM 		/* print the existing value(s) if they exist */
405611767SAnurag.Maskey@Sun.COM 		if (ret == NWAM_SUCCESS) {
405711767SAnurag.Maskey@Sun.COM 			(void) printf(" (");
405811767SAnurag.Maskey@Sun.COM 			output_prop_val(props[i], vals, stdout, B_TRUE);
405911767SAnurag.Maskey@Sun.COM 			(void) putchar(')');
406011767SAnurag.Maskey@Sun.COM 			nwam_value_free(vals);
406111767SAnurag.Maskey@Sun.COM 		}
406211767SAnurag.Maskey@Sun.COM 		/* print choices, won't print anything if there aren't any */
406311767SAnurag.Maskey@Sun.COM 		print_all_prop_choices(object_type, props[i]);
406411767SAnurag.Maskey@Sun.COM 		(void) printf("> ");
406511767SAnurag.Maskey@Sun.COM 
406611767SAnurag.Maskey@Sun.COM 		/* wait for user input */
406711767SAnurag.Maskey@Sun.COM 		if (fgets(line, sizeof (line), stdin) == NULL)
406811767SAnurag.Maskey@Sun.COM 			continue;
406911767SAnurag.Maskey@Sun.COM 
407011767SAnurag.Maskey@Sun.COM 		/* if user input new value, existing value is overrode */
407111767SAnurag.Maskey@Sun.COM 		if (line[0] != '\n') {
407211767SAnurag.Maskey@Sun.COM 			boolean_t is_listprop;
407311767SAnurag.Maskey@Sun.COM 			int pt_type = prop_to_pt(object_type, props[i]);
407411767SAnurag.Maskey@Sun.COM 
407511767SAnurag.Maskey@Sun.COM 			is_listprop = is_prop_multivalued(object_type,
407611767SAnurag.Maskey@Sun.COM 			    props[i]);
407711767SAnurag.Maskey@Sun.COM 			vals = str_to_nwam_value(object_type, line, pt_type,
407811767SAnurag.Maskey@Sun.COM 			    is_listprop);
407911767SAnurag.Maskey@Sun.COM 			if (vals == NULL) {
408011767SAnurag.Maskey@Sun.COM 				ret = NWAM_ENTITY_INVALID_VALUE;
408111767SAnurag.Maskey@Sun.COM 				goto repeat;
408211767SAnurag.Maskey@Sun.COM 			}
408311767SAnurag.Maskey@Sun.COM 
408411767SAnurag.Maskey@Sun.COM 			/* set the new value for the property */
408511767SAnurag.Maskey@Sun.COM 			switch (object_type) {
408611767SAnurag.Maskey@Sun.COM 			case NWAM_OBJECT_TYPE_NCU:
408711767SAnurag.Maskey@Sun.COM 				ret = nwam_ncu_set_prop_value(ncu_h, props[i],
408811767SAnurag.Maskey@Sun.COM 				    vals);
408911767SAnurag.Maskey@Sun.COM 				break;
409011767SAnurag.Maskey@Sun.COM 			case NWAM_OBJECT_TYPE_LOC:
409111767SAnurag.Maskey@Sun.COM 				ret = nwam_loc_set_prop_value(loc_h, props[i],
409211767SAnurag.Maskey@Sun.COM 				    vals);
409311767SAnurag.Maskey@Sun.COM 				break;
409411767SAnurag.Maskey@Sun.COM 			case NWAM_OBJECT_TYPE_ENM:
409511767SAnurag.Maskey@Sun.COM 				ret = nwam_enm_set_prop_value(enm_h, props[i],
409611767SAnurag.Maskey@Sun.COM 				    vals);
409711767SAnurag.Maskey@Sun.COM 				break;
409811767SAnurag.Maskey@Sun.COM 			case NWAM_OBJECT_TYPE_KNOWN_WLAN:
409911767SAnurag.Maskey@Sun.COM 				ret = nwam_known_wlan_set_prop_value(wlan_h,
410011767SAnurag.Maskey@Sun.COM 				    props[i], vals);
410111767SAnurag.Maskey@Sun.COM 				break;
410211767SAnurag.Maskey@Sun.COM 			}
410311767SAnurag.Maskey@Sun.COM 			nwam_value_free(vals);
410411767SAnurag.Maskey@Sun.COM 
410511767SAnurag.Maskey@Sun.COM 			if (ret != NWAM_SUCCESS)
410611767SAnurag.Maskey@Sun.COM 				goto repeat;
410711767SAnurag.Maskey@Sun.COM 
410811767SAnurag.Maskey@Sun.COM 			need_to_commit = B_TRUE;
410911767SAnurag.Maskey@Sun.COM 			continue;
411011767SAnurag.Maskey@Sun.COM 
411111767SAnurag.Maskey@Sun.COM repeat:
411211767SAnurag.Maskey@Sun.COM 			invalid_set_prop_msg(props[i], ret);
411311767SAnurag.Maskey@Sun.COM 			i--; /* decrement i to repeat */
411411767SAnurag.Maskey@Sun.COM 		}
411511767SAnurag.Maskey@Sun.COM 	}
411611767SAnurag.Maskey@Sun.COM 
411711767SAnurag.Maskey@Sun.COM 	free(props);
411811767SAnurag.Maskey@Sun.COM }
411911767SAnurag.Maskey@Sun.COM 
412011767SAnurag.Maskey@Sun.COM /*
412111767SAnurag.Maskey@Sun.COM  * Verify whether all properties of a resource are valid.
412211767SAnurag.Maskey@Sun.COM  */
412311767SAnurag.Maskey@Sun.COM /* ARGSUSED */
412411767SAnurag.Maskey@Sun.COM void
verify_func(cmd_t * cmd)412511767SAnurag.Maskey@Sun.COM verify_func(cmd_t *cmd)
412611767SAnurag.Maskey@Sun.COM {
412711767SAnurag.Maskey@Sun.COM 	nwam_error_t	ret;
412811767SAnurag.Maskey@Sun.COM 	const char	*errprop;
412911767SAnurag.Maskey@Sun.COM 
413011767SAnurag.Maskey@Sun.COM 	switch (active_object_type()) {
413111767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
413211767SAnurag.Maskey@Sun.COM 		ret = nwam_ncu_validate(ncu_h, &errprop);
413311767SAnurag.Maskey@Sun.COM 		break;
413411767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
413511767SAnurag.Maskey@Sun.COM 		ret = nwam_loc_validate(loc_h, &errprop);
413611767SAnurag.Maskey@Sun.COM 		break;
413711767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
413811767SAnurag.Maskey@Sun.COM 		ret = nwam_enm_validate(enm_h, &errprop);
413911767SAnurag.Maskey@Sun.COM 		break;
414011767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_KNOWN_WLAN:
414111767SAnurag.Maskey@Sun.COM 		ret = nwam_known_wlan_validate(wlan_h, &errprop);
414211767SAnurag.Maskey@Sun.COM 		break;
414311767SAnurag.Maskey@Sun.COM 	}
414411767SAnurag.Maskey@Sun.COM 	if (ret != NWAM_SUCCESS)
414511767SAnurag.Maskey@Sun.COM 		nwamerr(ret, "Verify error on property '%s'", errprop);
414611767SAnurag.Maskey@Sun.COM 	else if (interactive_mode)
414711767SAnurag.Maskey@Sun.COM 		(void) printf(gettext("All properties verified\n"));
414811767SAnurag.Maskey@Sun.COM }
414911767SAnurag.Maskey@Sun.COM 
415011767SAnurag.Maskey@Sun.COM /*
415111767SAnurag.Maskey@Sun.COM  * command-line mode (# nwamcfg list or # nwamcfg "select loc test; list")
415211767SAnurag.Maskey@Sun.COM  */
415311767SAnurag.Maskey@Sun.COM static int
one_command_at_a_time(int argc,char * argv[])415411767SAnurag.Maskey@Sun.COM one_command_at_a_time(int argc, char *argv[])
415511767SAnurag.Maskey@Sun.COM {
415611767SAnurag.Maskey@Sun.COM 	char *command;
415711767SAnurag.Maskey@Sun.COM 	size_t len = 2; /* terminal \n\0 */
415811767SAnurag.Maskey@Sun.COM 	int i, err;
415911767SAnurag.Maskey@Sun.COM 
416011767SAnurag.Maskey@Sun.COM 	for (i = 0; i < argc; i++)
416111767SAnurag.Maskey@Sun.COM 		len += strlen(argv[i]) + 1;
416211767SAnurag.Maskey@Sun.COM 	if ((command = malloc(len)) == NULL) {
416311767SAnurag.Maskey@Sun.COM 		nerr("Out of memory");
416411767SAnurag.Maskey@Sun.COM 		return (NWAM_ERR);
416511767SAnurag.Maskey@Sun.COM 	}
416611767SAnurag.Maskey@Sun.COM 	(void) strlcpy(command, argv[0], len);
416711767SAnurag.Maskey@Sun.COM 	for (i = 1; i < argc; i++) {
416811767SAnurag.Maskey@Sun.COM 		(void) strlcat(command, " ", len);
416911767SAnurag.Maskey@Sun.COM 		(void) strlcat(command, argv[i], len);
417011767SAnurag.Maskey@Sun.COM 	}
417111767SAnurag.Maskey@Sun.COM 	(void) strlcat(command, "\n", len);
417211767SAnurag.Maskey@Sun.COM 	err = string_to_yyin(command);
417311767SAnurag.Maskey@Sun.COM 	free(command);
417411767SAnurag.Maskey@Sun.COM 	if (err != NWAM_OK)
417511767SAnurag.Maskey@Sun.COM 		return (err);
417611767SAnurag.Maskey@Sun.COM 	while (!feof(yyin)) {
417711767SAnurag.Maskey@Sun.COM 		yyparse();
417811767SAnurag.Maskey@Sun.COM 
417911767SAnurag.Maskey@Sun.COM 		/*
418011767SAnurag.Maskey@Sun.COM 		 * If any command on a list of commands give an error,
418111767SAnurag.Maskey@Sun.COM 		 * don't continue with the remaining commands.
418211767SAnurag.Maskey@Sun.COM 		 */
418311767SAnurag.Maskey@Sun.COM 		if (saw_error || time_to_exit)
418411767SAnurag.Maskey@Sun.COM 			return (cleanup());
418511767SAnurag.Maskey@Sun.COM 	}
418611767SAnurag.Maskey@Sun.COM 
418711767SAnurag.Maskey@Sun.COM 	/* if there are changes to commit, commit it */
418811767SAnurag.Maskey@Sun.COM 	if (need_to_commit) {
418911767SAnurag.Maskey@Sun.COM 		do_commit();
419011767SAnurag.Maskey@Sun.COM 		/* if need_to_commit is not set, then there was a error */
419111767SAnurag.Maskey@Sun.COM 		if (need_to_commit)
419211767SAnurag.Maskey@Sun.COM 			return (NWAM_ERR);
419311767SAnurag.Maskey@Sun.COM 	}
419411767SAnurag.Maskey@Sun.COM 
419511767SAnurag.Maskey@Sun.COM 	if (!interactive_mode)
419611767SAnurag.Maskey@Sun.COM 		return (cleanup());
419711767SAnurag.Maskey@Sun.COM 	else {
419811767SAnurag.Maskey@Sun.COM 		yyin = stdin;
419911767SAnurag.Maskey@Sun.COM 		return (read_input());
420011767SAnurag.Maskey@Sun.COM 	}
420111767SAnurag.Maskey@Sun.COM }
420211767SAnurag.Maskey@Sun.COM 
420311767SAnurag.Maskey@Sun.COM /*
420411767SAnurag.Maskey@Sun.COM  * cmd_file is slightly more complicated, as it has to open the command file
420511767SAnurag.Maskey@Sun.COM  * and set yyin appropriately.  Once that is done, though, it just calls
420611767SAnurag.Maskey@Sun.COM  * read_input(), and only once, since prompting is not possible.
420711767SAnurag.Maskey@Sun.COM  */
420811767SAnurag.Maskey@Sun.COM static int
cmd_file(char * file)420911767SAnurag.Maskey@Sun.COM cmd_file(char *file)
421011767SAnurag.Maskey@Sun.COM {
421111767SAnurag.Maskey@Sun.COM 	FILE *infile;
421211767SAnurag.Maskey@Sun.COM 	int err;
421311767SAnurag.Maskey@Sun.COM 	struct stat statbuf;
421411767SAnurag.Maskey@Sun.COM 	boolean_t using_real_file = (strcmp(file, "-") != 0);
421511767SAnurag.Maskey@Sun.COM 
421611767SAnurag.Maskey@Sun.COM 	if (using_real_file) {
421711767SAnurag.Maskey@Sun.COM 		/*
421811767SAnurag.Maskey@Sun.COM 		 * nerr() prints a line number in cmd_file_mode, which we do
421911767SAnurag.Maskey@Sun.COM 		 * not want here, so temporarily unset it.
422011767SAnurag.Maskey@Sun.COM 		 */
422111767SAnurag.Maskey@Sun.COM 		cmd_file_mode = B_FALSE;
422211767SAnurag.Maskey@Sun.COM 		if ((infile = fopen(file, "r")) == NULL) {
422311767SAnurag.Maskey@Sun.COM 			nerr(gettext("could not open file '%s': %s"),
422411767SAnurag.Maskey@Sun.COM 			    file, strerror(errno));
422511767SAnurag.Maskey@Sun.COM 			return (1);
422611767SAnurag.Maskey@Sun.COM 		}
422711767SAnurag.Maskey@Sun.COM 		if ((err = fstat(fileno(infile), &statbuf)) != 0) {
422811767SAnurag.Maskey@Sun.COM 			nerr(gettext("could not stat file '%s': %s"),
422911767SAnurag.Maskey@Sun.COM 			    file, strerror(errno));
423011767SAnurag.Maskey@Sun.COM 			err = 1;
423111767SAnurag.Maskey@Sun.COM 			goto done;
423211767SAnurag.Maskey@Sun.COM 		}
423311767SAnurag.Maskey@Sun.COM 		if (!S_ISREG(statbuf.st_mode)) {
423411767SAnurag.Maskey@Sun.COM 			nerr(gettext("'%s' is not a regular file."), file);
423511767SAnurag.Maskey@Sun.COM 			err = 1;
423611767SAnurag.Maskey@Sun.COM 			goto done;
423711767SAnurag.Maskey@Sun.COM 		}
423811767SAnurag.Maskey@Sun.COM 
423911767SAnurag.Maskey@Sun.COM 		/*
424011767SAnurag.Maskey@Sun.COM 		 * If -d was passed on the command-line, we need to
424111767SAnurag.Maskey@Sun.COM 		 * start by removing any existing configuration.
424211767SAnurag.Maskey@Sun.COM 		 * Alternatively, the file may begin with 'destroy -a';
424311767SAnurag.Maskey@Sun.COM 		 * but in that case, the line will go through the lexer
424411767SAnurag.Maskey@Sun.COM 		 * and be processed as it's encountered in the file.
424511767SAnurag.Maskey@Sun.COM 		 */
424611767SAnurag.Maskey@Sun.COM 		if (remove_all_configurations && destroy_all() != NWAM_SUCCESS)
424711767SAnurag.Maskey@Sun.COM 			goto done;
424811767SAnurag.Maskey@Sun.COM 
424911767SAnurag.Maskey@Sun.COM 		/* set up for lexer */
425011767SAnurag.Maskey@Sun.COM 		yyin = infile;
425111767SAnurag.Maskey@Sun.COM 		cmd_file_mode = B_TRUE;
425211767SAnurag.Maskey@Sun.COM 		ok_to_prompt = B_FALSE;
425311767SAnurag.Maskey@Sun.COM 	} else {
425411767SAnurag.Maskey@Sun.COM 		/*
425511767SAnurag.Maskey@Sun.COM 		 * "-f -" is essentially the same as interactive mode,
425611767SAnurag.Maskey@Sun.COM 		 * so treat it that way.
425711767SAnurag.Maskey@Sun.COM 		 */
425811767SAnurag.Maskey@Sun.COM 		interactive_mode = B_TRUE;
425911767SAnurag.Maskey@Sun.COM 	}
426011767SAnurag.Maskey@Sun.COM 	/* NWAM_REPEAT is for interactive mode; treat it like NWAM_ERR here. */
426111767SAnurag.Maskey@Sun.COM 	if ((err = read_input()) == NWAM_REPEAT)
426211767SAnurag.Maskey@Sun.COM 		err = NWAM_ERR;
426311767SAnurag.Maskey@Sun.COM 	if (err == NWAM_OK)
426411767SAnurag.Maskey@Sun.COM 		(void) printf(gettext("Configuration read.\n"));
426511767SAnurag.Maskey@Sun.COM 
426611767SAnurag.Maskey@Sun.COM done:
426711767SAnurag.Maskey@Sun.COM 	if (using_real_file)
426811767SAnurag.Maskey@Sun.COM 		(void) fclose(infile);
426911767SAnurag.Maskey@Sun.COM 	return (err);
427011767SAnurag.Maskey@Sun.COM }
427111767SAnurag.Maskey@Sun.COM 
427211767SAnurag.Maskey@Sun.COM int
main(int argc,char * argv[])427311767SAnurag.Maskey@Sun.COM main(int argc, char *argv[])
427411767SAnurag.Maskey@Sun.COM {
427511767SAnurag.Maskey@Sun.COM 	int	err;
427611767SAnurag.Maskey@Sun.COM 	char	c;
427711767SAnurag.Maskey@Sun.COM 
427811767SAnurag.Maskey@Sun.COM 	/* This must be before anything goes to stdout. */
427911767SAnurag.Maskey@Sun.COM 	setbuf(stdout, NULL);
428011767SAnurag.Maskey@Sun.COM 
428111767SAnurag.Maskey@Sun.COM 	if ((execname = strrchr(argv[0], '/')) == NULL)
428211767SAnurag.Maskey@Sun.COM 		execname = argv[0];
428311767SAnurag.Maskey@Sun.COM 	else
428411767SAnurag.Maskey@Sun.COM 		execname++;
428511767SAnurag.Maskey@Sun.COM 
428611767SAnurag.Maskey@Sun.COM 	(void) setlocale(LC_ALL, "");
428711767SAnurag.Maskey@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
428811767SAnurag.Maskey@Sun.COM 
428911767SAnurag.Maskey@Sun.COM 	while ((c = getopt(argc, argv, "?hf:d")) != EOF) {
429011767SAnurag.Maskey@Sun.COM 		switch (c) {
429111767SAnurag.Maskey@Sun.COM 		case 'f':
429211767SAnurag.Maskey@Sun.COM 			cmd_file_name = optarg;
429311767SAnurag.Maskey@Sun.COM 			cmd_file_mode = B_TRUE;
429411767SAnurag.Maskey@Sun.COM 			break;
429511767SAnurag.Maskey@Sun.COM 		case '?':
429611767SAnurag.Maskey@Sun.COM 		case 'h':
429711767SAnurag.Maskey@Sun.COM 			cmd_line_usage();
429811767SAnurag.Maskey@Sun.COM 			return (NWAM_OK);
429911767SAnurag.Maskey@Sun.COM 		case 'd':
430011767SAnurag.Maskey@Sun.COM 			remove_all_configurations = B_TRUE;
430111767SAnurag.Maskey@Sun.COM 			break;
430211767SAnurag.Maskey@Sun.COM 		default:
430311767SAnurag.Maskey@Sun.COM 			cmd_line_usage();
430411767SAnurag.Maskey@Sun.COM 			return (NWAM_ERR);
430511767SAnurag.Maskey@Sun.COM 		}
430611767SAnurag.Maskey@Sun.COM 	}
430711767SAnurag.Maskey@Sun.COM 	/* -d can only be used with -f */
430811767SAnurag.Maskey@Sun.COM 	if (remove_all_configurations && !cmd_file_mode) {
430911767SAnurag.Maskey@Sun.COM 		nerr("Option -d can only be used with -f");
431011767SAnurag.Maskey@Sun.COM 		return (NWAM_ERR);
431111767SAnurag.Maskey@Sun.COM 	}
431211767SAnurag.Maskey@Sun.COM 
431311767SAnurag.Maskey@Sun.COM 	/*
431411767SAnurag.Maskey@Sun.COM 	 * This may get set back to FALSE again in cmd_file() if cmd_file_name
431511767SAnurag.Maskey@Sun.COM 	 * is a "real" file as opposed to "-" (i.e. meaning use stdin).
431611767SAnurag.Maskey@Sun.COM 	 */
431711767SAnurag.Maskey@Sun.COM 	if (isatty(STDIN_FILENO))
431811767SAnurag.Maskey@Sun.COM 		ok_to_prompt = B_TRUE;
431911767SAnurag.Maskey@Sun.COM 	if ((gl = new_GetLine(MAX_LINE_LEN, MAX_CMD_HIST)) == NULL)
432011767SAnurag.Maskey@Sun.COM 		exit(NWAM_ERR);
432111767SAnurag.Maskey@Sun.COM 	if (gl_customize_completion(gl, NULL, cmd_cpl_fn) != 0)
432211767SAnurag.Maskey@Sun.COM 		exit(NWAM_ERR);
432311767SAnurag.Maskey@Sun.COM 	(void) sigset(SIGINT, SIG_IGN);
432411767SAnurag.Maskey@Sun.COM 
432511767SAnurag.Maskey@Sun.COM 	if (optind == argc) {
432611767SAnurag.Maskey@Sun.COM 		/* interactive or command-file mode */
432711767SAnurag.Maskey@Sun.COM 		if (!cmd_file_mode)
432811767SAnurag.Maskey@Sun.COM 			err = do_interactive();
432911767SAnurag.Maskey@Sun.COM 		else
433011767SAnurag.Maskey@Sun.COM 			err = cmd_file(cmd_file_name);
433111767SAnurag.Maskey@Sun.COM 	} else {
433211767SAnurag.Maskey@Sun.COM 		/* command-line mode */
433311767SAnurag.Maskey@Sun.COM 		err = one_command_at_a_time(argc - optind, &(argv[optind]));
433411767SAnurag.Maskey@Sun.COM 	}
433511767SAnurag.Maskey@Sun.COM 	(void) del_GetLine(gl);
433611767SAnurag.Maskey@Sun.COM 
433711767SAnurag.Maskey@Sun.COM 	return (err);
433811767SAnurag.Maskey@Sun.COM }
4339