4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
27 * nwamcfg is a lex/yacc based command interpreter used to manage network
28 * configurations. The lexer (see nwamcfg_lex.l) builds up tokens, which
29 * the grammar (see nwamcfg_grammar.y) builds up into commands, some of
30 * which takes resources and/or properties as arguments.
33 #include <arpa/inet.h>
44 #include <sys/sysmacros.h>
45 #include <sys/types.h>
50 #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */
51 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
57 const char *cmd_usage
;
60 extern int yyparse(void);
61 extern int lex_lineno
;
63 #define MAX_LINE_LEN 1024
64 #define MAX_CMD_HIST 1024
66 /* usage of commands */
67 #define SHELP_CANCEL "cancel"
68 #define SHELP_CLEAR "clear <prop-name>"
69 #define SHELP_COMMIT "commit"
70 #define SHELP_CREATE "create [-t <template>] <object-type> [<class>] " \
72 #define SHELP_DESTROY "destroy {-a | <object-type> [<class>] <object-name>}"
73 #define SHELP_END "end"
74 #define SHELP_EXIT "exit"
75 #define SHELP_EXPORT "export [-d] [-f <output-file>] " \
76 "[<object-type> [<class>] <object-name>]"
77 #define SHELP_GET "get [-V] <prop-name>"
78 #define SHELP_HELP "help [command-name]"
79 #define SHELP_LIST "list [-a] [<object-type> [<class>] <object-name>]"
80 #define SHELP_REVERT "revert"
81 #define SHELP_SELECT "select <object-type> [<class>] <object-name>"
82 #define SHELP_SET "set <prop-name>=<value1>[,<value2>...]"
83 #define SHELP_VERIFY "verify"
84 #define SHELP_WALK "walkprop [-a]"
88 * Locations, ENMs, NCPs and Known WLANs are one scope level below global (GBL).
89 * NCUs are one more level beneath the NCP scope.
90 * Because the commands in Locations/ENM/Known WLAN and NCP level are different,
91 * the scope are divided accordingly.
92 * GBL->LOC, GBL->ENM, GBL->WLAN or GBL->NCP->NCU
94 #define NWAM_SCOPE_GBL 0
95 #define NWAM_SCOPE_LOC 1
96 #define NWAM_SCOPE_ENM 2
97 #define NWAM_SCOPE_WLAN 3
98 #define NWAM_SCOPE_NCP 4
99 #define NWAM_SCOPE_NCU 5
101 /* delimiter used for list of values */
102 #define NWAM_VALUE_DELIMITER_CHAR ','
103 #define NWAM_VALUE_DELIMITER_STR ","
105 /* the max number of values for an enum used by some properties in libnwam */
108 * All arrays/tables are null-terminated, rather than defining the length of
109 * the array. When looping, check for NULL rather than using the size.
112 static struct help helptab
[] = {
113 { CMD_CANCEL
, "cancel", SHELP_CANCEL
},
114 { CMD_CLEAR
, "clear", SHELP_CLEAR
},
115 { CMD_COMMIT
, "commit", SHELP_COMMIT
},
116 { CMD_CREATE
, "create", SHELP_CREATE
},
117 { CMD_DESTROY
, "destroy", SHELP_DESTROY
},
118 { CMD_END
, "end", SHELP_END
},
119 { CMD_EXIT
, "exit", SHELP_EXIT
},
120 { CMD_EXPORT
, "export", SHELP_EXPORT
},
121 { CMD_GET
, "get", SHELP_GET
},
122 { CMD_HELP
, "help", SHELP_HELP
},
123 { CMD_LIST
, "list", SHELP_LIST
},
124 { CMD_REVERT
, "revert", SHELP_REVERT
},
125 { CMD_SELECT
, "select", SHELP_SELECT
},
126 { CMD_SET
, "set", SHELP_SET
},
127 { CMD_VERIFY
, "verify", SHELP_VERIFY
},
128 { CMD_WALKPROP
, "walkprop", SHELP_WALK
},
132 /* These *must* match the order of the RT1_ define's from nwamcfg.h */
133 static char *res1_types
[] = {
142 /* These *must* match the order of the RT2_ define's from nwamcfg.h */
143 static char *res2_types
[] = {
150 * No array for NCU_CLASS_. The #define's in nwamcfg.h matches the
151 * enum nwam_ncu_class_t in libnwam and thus uses libnwam functions to
152 * retrieve the string representation.
155 /* These *MUST* match the order of the PT_ define's from nwamcfg.h */
156 static char *pt_types
[] = {
158 NWAM_NCU_PROP_ACTIVATION_MODE
,
159 NWAM_NCU_PROP_ENABLED
,
162 NWAM_NCU_PROP_PARENT_NCP
,
163 NWAM_NCU_PROP_PRIORITY_GROUP
,
164 NWAM_NCU_PROP_PRIORITY_MODE
,
165 NWAM_NCU_PROP_LINK_MAC_ADDR
,
166 NWAM_NCU_PROP_LINK_AUTOPUSH
,
167 NWAM_NCU_PROP_LINK_MTU
,
168 NWAM_NCU_PROP_IP_VERSION
,
169 NWAM_NCU_PROP_IPV4_ADDRSRC
,
170 NWAM_NCU_PROP_IPV4_ADDR
,
171 NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE
,
172 NWAM_NCU_PROP_IPV6_ADDRSRC
,
173 NWAM_NCU_PROP_IPV6_ADDR
,
174 NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE
,
175 NWAM_LOC_PROP_CONDITIONS
,
179 NWAM_LOC_PROP_NAMESERVICES
,
180 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE
,
181 NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC
,
182 NWAM_LOC_PROP_DNS_NAMESERVICE_DOMAIN
,
183 NWAM_LOC_PROP_DNS_NAMESERVICE_SERVERS
,
184 NWAM_LOC_PROP_DNS_NAMESERVICE_SEARCH
,
185 NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC
,
186 NWAM_LOC_PROP_NIS_NAMESERVICE_SERVERS
,
187 NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
,
188 NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS
,
189 NWAM_LOC_PROP_DEFAULT_DOMAIN
,
190 NWAM_LOC_PROP_NFSV4_DOMAIN
,
191 NWAM_LOC_PROP_IPFILTER_CONFIG_FILE
,
192 NWAM_LOC_PROP_IPFILTER_V6_CONFIG_FILE
,
193 NWAM_LOC_PROP_IPNAT_CONFIG_FILE
,
194 NWAM_LOC_PROP_IPPOOL_CONFIG_FILE
,
195 NWAM_LOC_PROP_IKE_CONFIG_FILE
,
196 NWAM_LOC_PROP_IPSECPOLICY_CONFIG_FILE
,
197 NWAM_KNOWN_WLAN_PROP_BSSIDS
,
198 NWAM_KNOWN_WLAN_PROP_PRIORITY
,
199 NWAM_KNOWN_WLAN_PROP_KEYNAME
,
200 NWAM_KNOWN_WLAN_PROP_KEYSLOT
,
201 NWAM_KNOWN_WLAN_PROP_SECURITY_MODE
204 /* properties table: maps PT_* constants to property names */
205 typedef struct prop_table_entry
{
207 const char *pte_name
;
208 } prop_table_entry_t
;
210 /* NCU properties table */
211 static prop_table_entry_t ncu_prop_table
[] = {
212 { PT_TYPE
, NWAM_NCU_PROP_TYPE
},
213 { PT_CLASS
, NWAM_NCU_PROP_CLASS
},
214 { PT_PARENT
, NWAM_NCU_PROP_PARENT_NCP
},
215 { PT_ACTIVATION_MODE
, NWAM_NCU_PROP_ACTIVATION_MODE
},
216 { PT_ENABLED
, NWAM_NCU_PROP_ENABLED
},
217 { PT_PRIORITY_GROUP
, NWAM_NCU_PROP_PRIORITY_GROUP
},
218 { PT_PRIORITY_MODE
, NWAM_NCU_PROP_PRIORITY_MODE
},
219 { PT_LINK_MACADDR
, NWAM_NCU_PROP_LINK_MAC_ADDR
},
220 { PT_LINK_AUTOPUSH
, NWAM_NCU_PROP_LINK_AUTOPUSH
},
221 { PT_LINK_MTU
, NWAM_NCU_PROP_LINK_MTU
},
222 { PT_IP_VERSION
, NWAM_NCU_PROP_IP_VERSION
},
223 { PT_IPV4_ADDRSRC
, NWAM_NCU_PROP_IPV4_ADDRSRC
},
224 { PT_IPV4_ADDR
, NWAM_NCU_PROP_IPV4_ADDR
},
225 { PT_IPV4_DEFAULT_ROUTE
, NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE
},
226 { PT_IPV6_ADDRSRC
, NWAM_NCU_PROP_IPV6_ADDRSRC
},
227 { PT_IPV6_ADDR
, NWAM_NCU_PROP_IPV6_ADDR
},
228 { PT_IPV6_DEFAULT_ROUTE
, NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE
},
232 /* ENM properties table */
233 static prop_table_entry_t enm_prop_table
[] = {
234 { PT_ENM_FMRI
, NWAM_ENM_PROP_FMRI
},
235 { PT_ENM_START
, NWAM_ENM_PROP_START
},
236 { PT_ENM_STOP
, NWAM_ENM_PROP_STOP
},
237 { PT_ACTIVATION_MODE
, NWAM_ENM_PROP_ACTIVATION_MODE
},
238 { PT_CONDITIONS
, NWAM_ENM_PROP_CONDITIONS
},
239 { PT_ENABLED
, NWAM_ENM_PROP_ENABLED
},
243 /* LOCation properties table */
244 static prop_table_entry_t loc_prop_table
[] = {
245 { PT_ACTIVATION_MODE
, NWAM_LOC_PROP_ACTIVATION_MODE
},
246 { PT_CONDITIONS
, NWAM_LOC_PROP_CONDITIONS
},
247 { PT_ENABLED
, NWAM_LOC_PROP_ENABLED
},
248 { PT_LOC_NAMESERVICES
, NWAM_LOC_PROP_NAMESERVICES
},
249 { PT_LOC_NAMESERVICES_CONFIG
, NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE
},
250 { PT_LOC_DNS_CONFIGSRC
, NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC
},
251 { PT_LOC_DNS_DOMAIN
, NWAM_LOC_PROP_DNS_NAMESERVICE_DOMAIN
},
252 { PT_LOC_DNS_SERVERS
, NWAM_LOC_PROP_DNS_NAMESERVICE_SERVERS
},
253 { PT_LOC_DNS_SEARCH
, NWAM_LOC_PROP_DNS_NAMESERVICE_SEARCH
},
254 { PT_LOC_NIS_CONFIGSRC
, NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC
},
255 { PT_LOC_NIS_SERVERS
, NWAM_LOC_PROP_NIS_NAMESERVICE_SERVERS
},
256 { PT_LOC_LDAP_CONFIGSRC
, NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
},
257 { PT_LOC_LDAP_SERVERS
, NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS
},
258 { PT_LOC_DEFAULT_DOMAIN
, NWAM_LOC_PROP_DEFAULT_DOMAIN
},
259 { PT_LOC_NFSV4_DOMAIN
, NWAM_LOC_PROP_NFSV4_DOMAIN
},
260 { PT_LOC_IPF_CONFIG
, NWAM_LOC_PROP_IPFILTER_CONFIG_FILE
},
261 { PT_LOC_IPF_V6_CONFIG
, NWAM_LOC_PROP_IPFILTER_V6_CONFIG_FILE
},
262 { PT_LOC_IPNAT_CONFIG
, NWAM_LOC_PROP_IPNAT_CONFIG_FILE
},
263 { PT_LOC_IPPOOL_CONFIG
, NWAM_LOC_PROP_IPPOOL_CONFIG_FILE
},
264 { PT_LOC_IKE_CONFIG
, NWAM_LOC_PROP_IKE_CONFIG_FILE
},
265 { PT_LOC_IPSECPOL_CONFIG
, NWAM_LOC_PROP_IPSECPOLICY_CONFIG_FILE
},
269 /* Known WLAN properties table */
270 static prop_table_entry_t wlan_prop_table
[] = {
271 { PT_WLAN_BSSIDS
, NWAM_KNOWN_WLAN_PROP_BSSIDS
},
272 { PT_WLAN_PRIORITY
, NWAM_KNOWN_WLAN_PROP_PRIORITY
},
273 { PT_WLAN_KEYNAME
, NWAM_KNOWN_WLAN_PROP_KEYNAME
},
274 { PT_WLAN_KEYSLOT
, NWAM_KNOWN_WLAN_PROP_KEYSLOT
},
275 { PT_WLAN_SECURITY_MODE
, NWAM_KNOWN_WLAN_PROP_SECURITY_MODE
},
279 /* Returns the appropriate properties table for the given object type */
280 static prop_table_entry_t
*
281 get_prop_table(nwam_object_type_t object_type
)
283 switch (object_type
) {
284 case NWAM_OBJECT_TYPE_NCU
:
285 return (ncu_prop_table
);
286 case NWAM_OBJECT_TYPE_LOC
:
287 return (loc_prop_table
);
288 case NWAM_OBJECT_TYPE_ENM
:
289 return (enm_prop_table
);
290 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
291 return (wlan_prop_table
);
296 /* Global variables */
298 /* set early in main(), never modified thereafter, used all over the place */
299 static char *execname
;
301 /* set in modifying functions, checked in read_input() */
302 boolean_t saw_error
= B_FALSE
;
304 /* set in yacc parser, checked in read_input() */
305 boolean_t newline_terminated
;
307 /* set in main(), checked in lex error handler */
308 boolean_t cmd_file_mode
= B_FALSE
;
310 /* set in exit_func(), checked in read_input() */
311 static boolean_t time_to_exit
= B_FALSE
;
313 /* used in nerr() and nwamerr() */
314 static char *cmd_file_name
= NULL
;
316 /* used with cmd_file to destroy all configurations */
317 static boolean_t remove_all_configurations
= B_FALSE
;
319 /* checked in read_input() and other places */
320 static boolean_t ok_to_prompt
= B_FALSE
;
322 /* initialized in do_interactive(), checked in initialize() */
323 static boolean_t interactive_mode
;
325 static boolean_t need_to_commit
= B_FALSE
;
327 /* The gl_get_line() resource object */
330 /* set when create or read objects, used by other func */
331 static nwam_loc_handle_t loc_h
= NULL
;
332 static nwam_enm_handle_t enm_h
= NULL
;
333 static nwam_known_wlan_handle_t wlan_h
= NULL
;
334 static nwam_ncu_handle_t ncu_h
= NULL
;
335 static nwam_ncp_handle_t ncp_h
= NULL
;
337 static int current_scope
= NWAM_SCOPE_GBL
;
339 /* obj1_* are used in NWAM_SCOPE_{NCP,LOC,ENM,WLAN} */
340 static int obj1_type
;
341 static char obj1_name
[NWAM_MAX_NAME_LEN
+ 1];
343 /* obj2_* are used in NWAM_SCOPE_NCU only */
344 static int obj2_type
;
345 static char obj2_name
[NWAM_MAX_NAME_LEN
+ 1];
347 /* arrays for tab-completion */
348 /* commands at NWAM_SCOPE_GBL */
349 static const char *global_scope_cmds
[] = {
361 static const char *global_create_cmds
[] = {
366 "create -t ", /* template */
370 static const char *global_destroy_cmds
[] = {
379 static const char *global_export_cmds
[] = {
381 "export -d ", /* add destroy -a */
382 "export -f ", /* to file */
383 "export -d -f ", /* add destroy -a to file */
391 static const char *global_list_cmds
[] = {
403 static const char *global_select_cmds
[] = {
411 /* commands at NWAM_SCOPE_LOC, _ENM, _WLAN and _NCU */
412 static const char *non_ncp_scope_cmds
[] = {
421 "get -V ", /* value only */
424 "list -a ", /* all properties */
429 "walkprop -a ", /* all properties */
433 /* commands at NWAM_SCOPE_NCP */
434 static const char *ncp_scope_cmds
[] = {
447 static const char *ncp_create_cmds
[] = {
450 "create -t ", /* template */
454 static const char *ncp_destroy_cmds
[] = {
461 static const char *ncp_export_cmds
[] = {
463 "export -f ", /* to file */
470 static const char *ncp_list_cmds
[] = {
481 static const char *ncp_select_cmds
[] = {
488 /* Functions begin here */
493 cmd_t
*cmd
= calloc(1, sizeof (cmd_t
));
495 nerr("Out of memory");
499 cmd
->cmd_argv
[0] = NULL
;
509 for (i
= 0; i
< cmd
->cmd_argc
; i
++)
510 free(cmd
->cmd_argv
[i
]);
515 array_free(void **array
, int nelem
)
518 for (i
= 0; i
< nelem
; i
++)
524 initial_match(const char *line1
, const char *line2
, int word_end
)
528 return (strncmp(line1
, line2
, word_end
) == 0);
532 add_stuff(WordCompletion
*cpl
, const char *line1
, const char **list
,
537 for (i
= 0; list
[i
] != NULL
; i
++) {
538 if (initial_match(line1
, list
[i
], word_end
)) {
539 err
= cpl_add_completion(cpl
, line1
, 0, word_end
,
540 list
[i
] + word_end
, "", "");
549 * To fill in the rest of a string when user types the tab key.
550 * First digital number is the length of the string, the second digital number
551 * is the min number of chars that is needed to uniquely identify a string.
553 #define MINI_STR(l, s, m, n) strncmp(l, s, MAX(MIN(sizeof (s) - 1, m), n))
557 CPL_MATCH_FN(cmd_cpl_fn
)
559 /* tab-complete according to the current scope */
560 switch (current_scope
) {
562 if (MINI_STR(line
, "create ", word_end
, 2) == 0)
563 return (add_stuff(cpl
, line
, global_create_cmds
,
565 if (MINI_STR(line
, "destroy ", word_end
, 1) == 0)
566 return (add_stuff(cpl
, line
, global_destroy_cmds
,
568 if (MINI_STR(line
, "export ", word_end
, 3) == 0)
569 return (add_stuff(cpl
, line
, global_export_cmds
,
571 if (MINI_STR(line
, "list ", word_end
, 1) == 0)
572 return (add_stuff(cpl
, line
, global_list_cmds
,
574 if (MINI_STR(line
, "select ", word_end
, 1) == 0)
575 return (add_stuff(cpl
, line
, global_select_cmds
,
577 return (add_stuff(cpl
, line
, global_scope_cmds
, word_end
));
580 case NWAM_SCOPE_WLAN
:
582 return (add_stuff(cpl
, line
, non_ncp_scope_cmds
, word_end
));
584 if (MINI_STR(line
, "create ", word_end
, 2) == 0)
585 return (add_stuff(cpl
, line
, ncp_create_cmds
,
587 if (MINI_STR(line
, "destroy ", word_end
, 1) == 0)
588 return (add_stuff(cpl
, line
, ncp_destroy_cmds
,
590 if (MINI_STR(line
, "export ", word_end
, 3) == 0)
591 return (add_stuff(cpl
, line
, ncp_export_cmds
,
593 if (MINI_STR(line
, "list ", word_end
, 1) == 0)
594 return (add_stuff(cpl
, line
, ncp_list_cmds
, word_end
));
595 if (MINI_STR(line
, "select ", word_end
, 1) == 0)
596 return (add_stuff(cpl
, line
, ncp_select_cmds
,
598 return (add_stuff(cpl
, line
, ncp_scope_cmds
, word_end
));
600 /* should never get here */
605 cmd_to_str(int cmd_num
)
607 assert(cmd_num
>= CMD_MIN
&& cmd_num
<= CMD_MAX
);
608 return (helptab
[cmd_num
].cmd_name
);
611 /* Returns "loc", "enm", "wlan" or "ncp" as string */
613 rt1_to_str(int res_type
)
615 assert(res_type
>= RT1_MIN
&& res_type
<= RT1_MAX
);
616 return (res1_types
[res_type
]);
619 /* Returns "ncu" as string */
621 rt2_to_str(int res_type
)
623 assert(res_type
>= RT2_MIN
&& res_type
<= RT2_MAX
);
624 return (res2_types
[res_type
]);
627 /* Returns "ncp, "ncu", "loc", "enm", or "wlan" according to the scope */
629 scope_to_str(int scope
) {
641 case NWAM_SCOPE_WLAN
:
648 /* Given an enm property and value, returns it as a string */
650 propval_to_str(const char *propname
, uint64_t value
)
654 if (nwam_uint64_get_value_string(propname
, value
, &str
) == NWAM_SUCCESS
)
659 /* Given an int for a prop, returns it as string */
661 pt_to_str(int prop_type
)
663 assert(prop_type
>= PT_MIN
&& prop_type
<= PT_MAX
);
664 return (pt_types
[prop_type
]);
667 /* Return B_TRUE if string starts with "t" or is 1, B_FALSE otherwise */
669 str_to_boolean(const char *str
)
671 if (strncasecmp(str
, "t", 1) == 0 || atoi(str
) == 1)
678 * This is a separate function rather than a set of define's because of the
679 * gettext() wrapping.
684 * Each string below should have \t follow \n whenever needed; the
685 * initial \t and the terminal \n will be provided by the calling function.
689 long_help(int cmd_num
)
691 assert(cmd_num
>= CMD_MIN
&& cmd_num
<= CMD_MAX
);
694 return (gettext("Cancels the current configuration "
697 return (gettext("Clears the value for the specified "
700 return (gettext("Commits the current configuration."));
702 return (gettext("Creates a new profile or resource."));
704 return (gettext("Destroys the specified profile or "
707 return (gettext("Ends specification of a resource."));
709 return (gettext("Exits the program."));
711 return (gettext("Exports the configuration."));
713 return (gettext("Gets the value of the specified "
716 return (gettext("Prints help message."));
718 return (gettext("Lists existing objects."));
720 return (gettext("Reverts to the previous "
723 return (gettext("Selects a resource to modify."));
725 return (gettext("Sets the value of the specified "
728 return (gettext("Verifies an object."));
730 return (gettext("Iterates over properties."));
732 return (gettext("Unknown command."));
737 command_usage(int command
)
739 if (command
< CMD_MIN
|| command
> CMD_MAX
) {
740 nerr("Unknown command");
742 nerr("%s: %s: %s", gettext("Error"), gettext("usage"),
743 helptab
[command
].cmd_usage
);
748 long_usage(uint_t cmd_num
)
750 (void) printf("%s: %s\n", gettext("usage"),
751 helptab
[cmd_num
].cmd_usage
);
752 (void) printf("\t%s\n", long_help(cmd_num
));
755 /* Prints usage for command line options */
759 (void) printf("%s:\t%s\t\t\t\t(%s)\n", gettext("usage"), execname
,
760 gettext("interactive-mode"));
761 (void) printf("\t%s <%s> [%s...]\n", execname
, gettext("command"),
763 (void) printf("\t%s [-d] -f <%s>\n", execname
, gettext("command-file"));
764 (void) printf("\t%s %s [<%s>]\n", execname
, cmd_to_str(CMD_HELP
),
768 /* Prints the line number of the current command if in command-file mode */
772 static int last_lineno
;
774 /* lex_lineno has already been incremented in the lexer; compensate */
775 if (cmd_file_mode
&& lex_lineno
> last_lineno
) {
776 if (strcmp(cmd_file_name
, "-") == 0)
777 (void) fprintf(stderr
, gettext("On line %d:\n"),
780 (void) fprintf(stderr
, gettext("On line %d of %s:\n"),
781 lex_lineno
- 1, cmd_file_name
);
782 last_lineno
= lex_lineno
;
788 nerr(const char *format
, ...)
794 format
= gettext(format
);
795 va_start(alist
, format
);
796 (void) vfprintf(stderr
, format
, alist
);
798 (void) fprintf(stderr
, "\n");
805 nwamerr(nwam_error_t err
, const char *format
, ...)
811 format
= gettext(format
);
812 va_start(alist
, format
);
813 (void) vfprintf(stderr
, format
, alist
);
815 (void) fprintf(stderr
, ": %s\n", nwam_strerror(err
));
821 properr(const char *prop
)
823 nerr("Invalid property: '%s'", prop
);
827 * If free_ncu_only == B_TRUE, only ncu handle is freed, ncp handle remains the
828 * same. Since nwam_ncp_free() takes care of its ncus, no need to explicitly
829 * call nwam_ncu_free() afterwards.
832 free_handle(boolean_t free_ncu_only
)
835 if (!free_ncu_only
) {
836 nwam_ncp_free(ncp_h
);
839 } else if (ncu_h
!= NULL
) {
840 nwam_ncu_free(ncu_h
);
846 nwam_enm_free(enm_h
);
851 nwam_loc_free(loc_h
);
855 if (wlan_h
!= NULL
) {
856 nwam_known_wlan_free(wlan_h
);
862 * On input, TRUE => yes, FALSE => no.
863 * On return, TRUE => 1, FALSE => no, could not ask => -1.
866 ask_yesno(boolean_t default_answer
, const char *question
)
868 char line
[64]; /* should be enough to answer yes or no */
875 if (printf("%s (%s)? ", gettext(question
),
876 default_answer
? "[y]/n" : "y/[n]") < 0)
878 if (fgets(line
, sizeof (line
), stdin
) == NULL
)
882 return (default_answer
? 1 : 0);
883 if (tolower(line
[0]) == 'y')
885 if (tolower(line
[0]) == 'n')
890 /* This is the back-end helper function for read_input() below. */
896 if (!interactive_mode
&& !cmd_file_mode
) {
898 * If we're not in interactive mode, and we're not in command
899 * file mode, then we must be in commands-from-the-command-line
900 * mode. As such, we can't loop back and ask for more input.
901 * It was OK to prompt for such things as whether or not to
902 * really delete something in the command handler called from
903 * yyparse() above, but "really quit?" makes no sense in this
904 * context. So disable prompting.
906 ok_to_prompt
= B_FALSE
;
908 if (need_to_commit
) {
909 answer
= ask_yesno(B_FALSE
,
910 "Configuration not saved; really quit");
913 /* issue error here */
917 * don't want to save, just exit. handles are freed at
918 * end_func() or exit_func().
922 /* loop back to read input */
923 time_to_exit
= B_FALSE
;
925 return (NWAM_REPEAT
);
928 return (saw_error
? NWAM_ERR
: NWAM_OK
);
932 string_to_yyin(char *string
)
934 if ((yyin
= tmpfile()) == NULL
)
936 if (fwrite(string
, strlen(string
), 1, yyin
) != 1)
938 if (fseek(yyin
, 0, SEEK_SET
) != 0)
944 nerr("problem creating temporary file");
949 * read_input() is the driver of this program. It is a wrapper around
950 * yyparse(), printing appropriate prompts when needed, checking for
951 * exit conditions and reacting appropriately. This function is
952 * called when in interactive mode or command-file mode.
957 boolean_t yyin_is_a_tty
= isatty(fileno(yyin
));
959 * The prompt is "e> " or "e:t1:o1> " or "e:t1:o1:t2:o2> " where e is
960 * execname, t is resource type, o is object name.
962 char prompt
[MAXPATHLEN
+ (2 * (NWAM_MAX_TYPE_LEN
+ NWAM_MAX_NAME_LEN
))
963 + sizeof ("::::> ")];
966 /* yyin should have been set to the appropriate (FILE *) if not stdin */
967 newline_terminated
= B_TRUE
;
970 if (newline_terminated
) {
971 switch (current_scope
) {
973 (void) snprintf(prompt
, sizeof (prompt
),
978 case NWAM_SCOPE_WLAN
:
980 (void) snprintf(prompt
, sizeof (prompt
),
981 "%s:%s:%s> ", execname
,
982 rt1_to_str(obj1_type
), obj1_name
);
986 (void) snprintf(prompt
, sizeof (prompt
),
987 "%s:%s:%s:%s:%s> ", execname
,
988 rt1_to_str(obj1_type
), obj1_name
,
989 rt2_to_str(obj2_type
), obj2_name
);
993 * If the user hits ^C then we want to catch it and
994 * start over. If the user hits EOF then we want to
997 line
= gl_get_line(gl
, prompt
, NULL
, -1);
998 if (gl_return_status(gl
) == GLR_SIGNAL
) {
1004 if (string_to_yyin(line
) != NWAM_OK
)
1006 while (!feof(yyin
)) {
1010 * If any command on a list of commands
1011 * give an error, don't continue with the
1012 * remaining commands.
1014 if (saw_error
|| time_to_exit
)
1021 /* Bail out on an error in command-file mode. */
1022 if (saw_error
&& cmd_file_mode
&& !interactive_mode
)
1023 time_to_exit
= B_TRUE
;
1024 if (time_to_exit
|| (!yyin_is_a_tty
&& feof(yyin
)))
1031 * This function is used in the interactive-mode scenario: it just calls
1032 * read_input() until we are done.
1035 do_interactive(void)
1039 interactive_mode
= B_TRUE
;
1042 } while (err
== NWAM_REPEAT
);
1046 /* Calls the help_func() to print the usage of all commands */
1052 if ((help_cmd
= alloc_cmd()) == NULL
)
1054 help_func(help_cmd
);
1058 /* Check if the given command is allowed in the current scope */
1060 check_scope(int cmd
)
1062 /* allowed in all scopes */
1071 /* scope-specific */
1072 switch (current_scope
) {
1073 case NWAM_SCOPE_GBL
:
1081 case NWAM_SCOPE_LOC
:
1082 case NWAM_SCOPE_ENM
:
1083 case NWAM_SCOPE_WLAN
:
1084 case NWAM_SCOPE_NCU
:
1097 case NWAM_SCOPE_NCP
:
1107 nerr("Invalid scope");
1109 nerr("'%s' is not allowed at this scope", cmd_to_str(cmd
));
1113 /* Returns the active object type depending on which handle is not NULL */
1114 static nwam_object_type_t
1115 active_object_type()
1117 /* Check ncu_h before ncp_h, ncp_h must be loaded before ncu_h */
1119 return (NWAM_OBJECT_TYPE_NCU
);
1120 else if (ncp_h
!= NULL
)
1121 return (NWAM_OBJECT_TYPE_NCP
);
1122 else if (loc_h
!= NULL
)
1123 return (NWAM_OBJECT_TYPE_LOC
);
1124 else if (enm_h
!= NULL
)
1125 return (NWAM_OBJECT_TYPE_ENM
);
1126 else if (wlan_h
!= NULL
)
1127 return (NWAM_OBJECT_TYPE_KNOWN_WLAN
);
1129 return (NWAM_OBJECT_TYPE_UNKNOWN
);
1132 /* Retrive the name of the object from its handle */
1134 object_name_from_handle(nwam_object_type_t object_type
, void *handle
,
1137 switch (object_type
) {
1138 case NWAM_OBJECT_TYPE_NCP
:
1139 return (nwam_ncp_get_name(handle
, namep
));
1140 case NWAM_OBJECT_TYPE_NCU
:
1141 return (nwam_ncu_get_name(handle
, namep
));
1142 case NWAM_OBJECT_TYPE_LOC
:
1143 return (nwam_loc_get_name(handle
, namep
));
1144 case NWAM_OBJECT_TYPE_ENM
:
1145 return (nwam_enm_get_name(handle
, namep
));
1146 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
1147 return (nwam_known_wlan_get_name(handle
, namep
));
1149 return (NWAM_INVALID_ARG
);
1155 nwam_error_t ret
= NWAM_SUCCESS
;
1156 const char *errprop
;
1158 if (!need_to_commit
)
1161 switch (active_object_type()) {
1162 case NWAM_OBJECT_TYPE_NCU
:
1163 ret
= nwam_ncu_commit(ncu_h
, 0);
1165 case NWAM_OBJECT_TYPE_ENM
:
1166 ret
= nwam_enm_commit(enm_h
, 0);
1168 case NWAM_OBJECT_TYPE_LOC
:
1169 ret
= nwam_loc_commit(loc_h
, 0);
1171 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
1172 ret
= nwam_known_wlan_commit(wlan_h
, 0);
1176 if (ret
== NWAM_SUCCESS
) {
1177 need_to_commit
= B_FALSE
;
1178 if (interactive_mode
)
1179 (void) printf(gettext("Committed changes\n"));
1183 /* Find property that caused failure */
1184 switch (active_object_type()) {
1185 case NWAM_OBJECT_TYPE_NCU
:
1186 verr
= nwam_ncu_validate(ncu_h
, &errprop
);
1188 case NWAM_OBJECT_TYPE_ENM
:
1189 verr
= nwam_enm_validate(enm_h
, &errprop
);
1191 case NWAM_OBJECT_TYPE_LOC
:
1192 verr
= nwam_loc_validate(loc_h
, &errprop
);
1194 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
1195 verr
= nwam_known_wlan_validate(wlan_h
, &errprop
);
1199 if (verr
!= NWAM_SUCCESS
)
1200 nwamerr(ret
, "Commit error on property '%s'", errprop
);
1202 nwamerr(ret
, "Commit error");
1207 * Saves the current configuration to persistent storage.
1211 commit_func(cmd_t
*cmd
)
1213 if (!need_to_commit
) {
1214 if (interactive_mode
)
1215 (void) printf(gettext("Nothing to commit\n"));
1224 switch (current_scope
) {
1225 case NWAM_SCOPE_NCU
:
1226 current_scope
= NWAM_SCOPE_NCP
;
1228 free_handle(B_TRUE
);
1230 case NWAM_SCOPE_NCP
:
1231 case NWAM_SCOPE_ENM
:
1232 case NWAM_SCOPE_WLAN
:
1233 case NWAM_SCOPE_LOC
:
1234 current_scope
= NWAM_SCOPE_GBL
;
1236 free_handle(B_FALSE
);
1238 case NWAM_SCOPE_GBL
:
1239 free_handle(B_FALSE
);
1242 nerr("Invalid scope");
1245 need_to_commit
= B_FALSE
;
1249 * End operation on current scope and go up one scope.
1250 * Changes are not saved, no prompt either.
1254 cancel_func(cmd_t
*cmd
)
1260 * Removes leading and trailing quotes from a string.
1261 * Caller must free returned string.
1264 trim_quotes(const char *quoted_str
)
1269 /* export_func() and list_func() can pass NULL here */
1270 if (quoted_str
== NULL
)
1273 /* remove leading quote */
1274 if (quoted_str
[0] == '"')
1275 str
= strdup(quoted_str
+ 1);
1277 str
= strdup(quoted_str
);
1281 /* remove trailing quote and newline */
1282 end
= strlen(str
) - 1;
1283 while (end
>= 0 && (str
[end
] == '"' || str
[end
] == '\n'))
1291 * Creates a new resource and enters the scope of that resource.
1292 * The new resource can also be a copy of an existing resource (-t option).
1293 * If in interactive mode, then after creation call walkprop_func()
1294 * to do walk the properties for the new object.
1297 create_func(cmd_t
*cmd
)
1299 nwam_error_t ret
= NWAM_SUCCESS
;
1301 boolean_t
template = B_FALSE
;
1302 char *newname
= NULL
, *oldname
= NULL
;
1303 cmd_t
*walkprop_cmd
;
1305 /* make sure right command at the right scope */
1306 if (current_scope
== NWAM_SCOPE_GBL
&&
1307 cmd
->cmd_res2_type
== RT2_NCU
) {
1308 nerr("cannot create ncu at global scope");
1311 if (current_scope
== NWAM_SCOPE_NCP
&&
1312 cmd
->cmd_res2_type
!= RT2_NCU
) {
1313 nerr("Cannot create given object at this scope");
1317 assert(cmd
->cmd_argc
> 0);
1319 while ((c
= getopt(cmd
->cmd_argc
, cmd
->cmd_argv
, "t:")) != EOF
) {
1325 command_usage(CMD_CREATE
);
1331 /* no template given */
1332 /* argv[0] is name */
1333 newname
= trim_quotes(cmd
->cmd_argv
[0]);
1334 if (cmd
->cmd_res1_type
== RT1_ENM
) {
1335 ret
= nwam_enm_create(newname
, NULL
, &enm_h
);
1336 } else if (cmd
->cmd_res1_type
== RT1_LOC
) {
1337 ret
= nwam_loc_create(newname
, &loc_h
);
1338 } else if (cmd
->cmd_res1_type
== RT1_WLAN
) {
1339 ret
= nwam_known_wlan_create(newname
, &wlan_h
);
1340 } else if (cmd
->cmd_res1_type
== RT1_NCP
&&
1341 current_scope
== NWAM_SCOPE_GBL
) {
1342 ret
= nwam_ncp_create(newname
, 0, &ncp_h
);
1343 } else if (cmd
->cmd_res2_type
== RT2_NCU
) {
1344 nwam_ncu_type_t ncu_type
;
1345 nwam_ncu_class_t ncu_class
;
1347 /* ncp must already be read */
1348 if (ncp_h
== NULL
) {
1349 nerr("Create error: NCP has not been read");
1353 ncu_class
= (nwam_ncu_class_t
)cmd
->cmd_ncu_class_type
;
1354 ncu_type
= nwam_ncu_class_to_type(ncu_class
);
1355 ret
= nwam_ncu_create(ncp_h
, newname
, ncu_type
,
1359 if (ret
!= NWAM_SUCCESS
) {
1360 nwamerr(ret
, "Create error");
1365 /* template given */
1366 /* argv[0] is -t, argv[1] is old name, argv[2] is new name */
1367 oldname
= trim_quotes(cmd
->cmd_argv
[1]);
1368 newname
= trim_quotes(cmd
->cmd_argv
[2]);
1369 if (cmd
->cmd_res1_type
== RT1_ENM
) {
1370 nwam_enm_handle_t oldenm_h
;
1372 ret
= nwam_enm_read(oldname
, 0, &oldenm_h
);
1373 if (ret
!= NWAM_SUCCESS
)
1375 ret
= nwam_enm_copy(oldenm_h
, newname
, &enm_h
);
1376 nwam_enm_free(oldenm_h
);
1377 } else if (cmd
->cmd_res1_type
== RT1_LOC
) {
1378 nwam_loc_handle_t oldloc_h
;
1380 ret
= nwam_loc_read(oldname
, 0, &oldloc_h
);
1381 if (ret
!= NWAM_SUCCESS
)
1383 ret
= nwam_loc_copy(oldloc_h
, newname
, &loc_h
);
1384 nwam_loc_free(oldloc_h
);
1385 } else if (cmd
->cmd_res1_type
== RT1_WLAN
) {
1386 nwam_known_wlan_handle_t oldwlan_h
;
1388 ret
= nwam_known_wlan_read(oldname
, 0, &oldwlan_h
);
1389 if (ret
!= NWAM_SUCCESS
)
1391 ret
= nwam_known_wlan_copy(oldwlan_h
, newname
, &wlan_h
);
1392 nwam_known_wlan_free(oldwlan_h
);
1393 } else if (cmd
->cmd_res1_type
== RT1_NCP
&&
1394 current_scope
== NWAM_SCOPE_GBL
) {
1395 nwam_ncp_handle_t oldncp_h
;
1397 ret
= nwam_ncp_read(oldname
, 0, &oldncp_h
);
1398 if (ret
!= NWAM_SUCCESS
)
1400 ret
= nwam_ncp_copy(oldncp_h
, newname
, &ncp_h
);
1401 nwam_ncp_free(oldncp_h
);
1402 } else if (cmd
->cmd_res2_type
== RT2_NCU
) {
1403 nwam_ncu_handle_t oldncu_h
;
1404 nwam_ncu_type_t ncu_type
;
1405 nwam_ncu_class_t ncu_class
;
1407 /* ncp must already be read */
1408 if (ncp_h
== NULL
) {
1409 nerr("Copy error: NCP has not been read");
1412 ncu_class
= (nwam_ncu_class_t
)cmd
->cmd_ncu_class_type
;
1413 ncu_type
= nwam_ncu_class_to_type(ncu_class
);
1414 ret
= nwam_ncu_read(ncp_h
, oldname
, ncu_type
, 0,
1416 if (ret
!= NWAM_SUCCESS
)
1418 ret
= nwam_ncu_copy(oldncu_h
, newname
, &ncu_h
);
1419 nwam_ncu_free(oldncu_h
);
1422 if (ret
!= NWAM_SUCCESS
) {
1423 nwamerr(ret
, "Copy error");
1428 if (current_scope
== NWAM_SCOPE_GBL
) {
1429 (void) strlcpy(obj1_name
, newname
, sizeof (obj1_name
));
1430 obj1_type
= cmd
->cmd_res1_type
;
1431 if (obj1_type
== RT1_ENM
)
1432 current_scope
= NWAM_SCOPE_ENM
;
1433 else if (obj1_type
== RT1_LOC
)
1434 current_scope
= NWAM_SCOPE_LOC
;
1435 else if (obj1_type
== RT1_WLAN
)
1436 current_scope
= NWAM_SCOPE_WLAN
;
1437 else if (obj1_type
== RT1_NCP
)
1438 current_scope
= NWAM_SCOPE_NCP
;
1440 (void) strlcpy(obj2_name
, newname
, sizeof (obj2_name
));
1441 current_scope
= NWAM_SCOPE_NCU
;
1442 obj2_type
= cmd
->cmd_res2_type
;
1444 if (current_scope
!= NWAM_SCOPE_NCP
)
1445 need_to_commit
= B_TRUE
;
1447 /* do a walk of the properties if in interactive mode */
1448 if (interactive_mode
&& current_scope
!= NWAM_SCOPE_NCP
) {
1449 (void) printf(gettext("Created %s '%s'. "
1450 "Walking properties ...\n"),
1451 scope_to_str(current_scope
), newname
);
1452 if ((walkprop_cmd
= alloc_cmd()) == NULL
)
1454 walkprop_func(walkprop_cmd
);
1459 if (ret
!= NWAM_SUCCESS
)
1460 nwamerr(ret
, "Copy error reading '%s'", oldname
);
1467 /* Processing of return value for destroy_*_callback() */
1469 destroy_ret(nwam_object_type_t object_type
, nwam_error_t ret
, void *handle
)
1471 if (ret
== NWAM_ENTITY_NOT_DESTROYABLE
) {
1472 /* log a message to stderr, but don't consider it an error */
1474 if (object_name_from_handle(object_type
, handle
, &name
)
1476 (void) fprintf(stderr
,
1477 gettext("%s '%s' cannot be removed\n"),
1478 nwam_object_type_to_string(object_type
), name
);
1484 if (ret
== NWAM_SUCCESS
|| ret
== NWAM_ENTITY_IN_USE
)
1491 * NWAM_FLAG_DO_NOT_FREE is passed to nwam_*_destory() so that it does not
1492 * free the handle. The calling nwam_walk_*() function frees this handle
1493 * as it is the function that created the handle.
1495 * Objects that are not destroyable or are active cannot be destroyed.
1496 * Don't return error in these situations so the walk can continue.
1500 destroy_ncp_callback(nwam_ncp_handle_t ncp
, void *arg
)
1502 /* The file is deleted, so NCUs are also removed */
1503 nwam_error_t ret
= nwam_ncp_destroy(ncp
, NWAM_FLAG_DO_NOT_FREE
);
1504 return (destroy_ret(NWAM_OBJECT_TYPE_NCP
, ret
, ncp
));
1509 destroy_loc_callback(nwam_loc_handle_t loc
, void *arg
)
1511 nwam_error_t ret
= nwam_loc_destroy(loc
, NWAM_FLAG_DO_NOT_FREE
);
1512 return (destroy_ret(NWAM_OBJECT_TYPE_LOC
, ret
, loc
));
1517 destroy_enm_callback(nwam_enm_handle_t enm
, void *arg
)
1519 nwam_error_t ret
= nwam_enm_destroy(enm
, NWAM_FLAG_DO_NOT_FREE
);
1520 return (destroy_ret(NWAM_OBJECT_TYPE_ENM
, ret
, enm
));
1525 destroy_wlan_callback(nwam_known_wlan_handle_t wlan
, void *arg
)
1527 nwam_error_t ret
= nwam_known_wlan_destroy(wlan
, NWAM_FLAG_DO_NOT_FREE
);
1528 return (destroy_ret(NWAM_OBJECT_TYPE_KNOWN_WLAN
, ret
, wlan
));
1532 * Remove all existing configuration that are not read-only.
1533 * walk through all ncps, locs, enms, wlans and destroy each one.
1540 assert(remove_all_configurations
);
1542 ret
= nwam_walk_ncps(destroy_ncp_callback
, NULL
, 0, NULL
);
1543 if (ret
!= NWAM_SUCCESS
)
1546 ret
= nwam_walk_enms(destroy_enm_callback
, NULL
,
1547 NWAM_FLAG_ACTIVATION_MODE_ALL
, NULL
);
1548 if (ret
!= NWAM_SUCCESS
)
1551 ret
= nwam_walk_locs(destroy_loc_callback
, NULL
,
1552 NWAM_FLAG_ACTIVATION_MODE_ALL
, NULL
);
1553 if (ret
!= NWAM_SUCCESS
)
1556 ret
= nwam_walk_known_wlans(destroy_wlan_callback
, NULL
, 0, NULL
);
1557 if (ret
!= NWAM_SUCCESS
)
1560 if (interactive_mode
)
1561 (void) printf(gettext("All user-defined entities destroyed\n"));
1562 remove_all_configurations
= B_FALSE
;
1565 if (ret
!= NWAM_SUCCESS
) {
1566 nwamerr(ret
, "Destroy error: "
1567 "could not destroy all configurations");
1573 * Destroys an instance in persistent repository, and is permanent.
1574 * If interactive mode, it is allowed at global scope only
1575 * option -a destroys everything.
1578 destroy_func(cmd_t
*cmd
)
1581 char *name
, *realname
= NULL
;
1583 if (current_scope
== NWAM_SCOPE_NCP
&&
1584 (cmd
->cmd_res1_type
== RT1_ENM
|| cmd
->cmd_res1_type
== RT1_LOC
||
1585 cmd
->cmd_res1_type
== RT1_WLAN
)) {
1586 nerr("Destroy error: only NCUs can be destroyed in NCP scope");
1590 assert(cmd
->cmd_argc
> 0);
1592 /* res1_type is -1 if -a flag is used */
1593 if (cmd
->cmd_res1_type
== -1) {
1596 if (current_scope
!= NWAM_SCOPE_GBL
) {
1597 nerr("Cannot destroy all configurations in a "
1598 "non-global scope");
1603 while ((c
= getopt(cmd
->cmd_argc
, cmd
->cmd_argv
, "a")) != EOF
) {
1606 remove_all_configurations
= B_TRUE
;
1609 command_usage(CMD_DESTROY
);
1613 if (remove_all_configurations
) {
1614 (void) destroy_all();
1619 /* argv[0] is name */
1620 name
= trim_quotes(cmd
->cmd_argv
[0]);
1621 if (cmd
->cmd_res2_type
== RT2_NCU
) {
1622 nwam_ncu_type_t ncu_type
;
1623 nwam_ncu_class_t ncu_class
;
1625 /* ncp must already be read */
1626 if (ncp_h
== NULL
) {
1627 nerr("Destroy ncu error: NCP has not been read");
1630 ncu_class
= (nwam_ncu_class_t
)cmd
->cmd_ncu_class_type
;
1631 ncu_type
= nwam_ncu_class_to_type(ncu_class
);
1632 ret
= nwam_ncu_read(ncp_h
, name
, ncu_type
, 0, &ncu_h
);
1633 if (ret
!= NWAM_SUCCESS
)
1635 (void) object_name_from_handle(NWAM_OBJECT_TYPE_NCU
, ncu_h
,
1637 ret
= nwam_ncu_destroy(ncu_h
, 0);
1639 } else if (cmd
->cmd_res1_type
== RT1_ENM
) {
1640 if ((ret
= nwam_enm_read(name
, 0, &enm_h
)) != NWAM_SUCCESS
)
1642 (void) object_name_from_handle(NWAM_OBJECT_TYPE_ENM
, enm_h
,
1644 ret
= nwam_enm_destroy(enm_h
, 0);
1646 } else if (cmd
->cmd_res1_type
== RT1_LOC
) {
1647 if ((ret
= nwam_loc_read(name
, 0, &loc_h
)) != NWAM_SUCCESS
)
1649 (void) object_name_from_handle(NWAM_OBJECT_TYPE_LOC
, loc_h
,
1651 ret
= nwam_loc_destroy(loc_h
, 0);
1653 } else if (cmd
->cmd_res1_type
== RT1_WLAN
) {
1654 if ((ret
= nwam_known_wlan_read(name
, 0, &wlan_h
))
1657 (void) object_name_from_handle(NWAM_OBJECT_TYPE_KNOWN_WLAN
,
1659 ret
= nwam_known_wlan_destroy(wlan_h
, 0);
1661 } else if (cmd
->cmd_res1_type
== RT1_NCP
) {
1662 if ((ret
= nwam_ncp_read(name
, 0, &ncp_h
)) != NWAM_SUCCESS
)
1664 (void) object_name_from_handle(NWAM_OBJECT_TYPE_NCP
, ncp_h
,
1666 ret
= nwam_ncp_destroy(ncp_h
, 0);
1669 nerr("Destroy error: unknown object-type");
1673 if (ret
== NWAM_ENTITY_IN_USE
) {
1674 nerr("Destroy error: active entity cannot be destroyed");
1675 } else if (ret
!= NWAM_SUCCESS
) {
1676 nwamerr(ret
, "Destroy error");
1677 } else if (interactive_mode
) {
1678 (void) printf(gettext("Destroyed %s '%s'\n"),
1679 (cmd
->cmd_res2_type
== RT2_NCU
?
1680 rt2_to_str(cmd
->cmd_res2_type
) :
1681 rt1_to_str(cmd
->cmd_res1_type
)),
1682 realname
!= NULL
? realname
: name
);
1689 * End operation on current scope and go up one scope.
1690 * Changes are saved.
1694 end_func(cmd_t
*cmd
)
1696 /* if need_to_commit is set, commit changes */
1701 * Call do_cancel() to go up one scope. If commit fails,
1702 * need_to_commit is not reset and users are asked if they want to end.
1704 if (!need_to_commit
||
1705 (need_to_commit
&& (ask_yesno(B_FALSE
,
1706 "Configuration not saved; really end")) == 1)) {
1707 /* set time_to_exit if in global scope */
1708 if (current_scope
== NWAM_SCOPE_GBL
)
1709 time_to_exit
= B_TRUE
;
1710 /* call do_cancel() to go up one scope */
1716 * Exit immediately. Configuration changes are saved by calling end_func().
1720 exit_func(cmd_t
*cmd
)
1724 if (need_to_commit
) {
1725 if ((end_cmd
= alloc_cmd()) == NULL
) {
1734 * If need_to_commit is still set, then the commit failed.
1737 if (!need_to_commit
)
1738 time_to_exit
= B_TRUE
;
1742 help_func(cmd_t
*cmd
)
1746 if (cmd
->cmd_argc
== 0) {
1747 (void) printf(gettext("commands:\n"));
1748 for (i
= CMD_MIN
; i
<= CMD_MAX
; i
++)
1749 (void) printf("\t%s\n", helptab
[i
].cmd_usage
);
1753 for (i
= CMD_MIN
; i
<= CMD_MAX
; i
++) {
1754 if (strcmp(cmd
->cmd_argv
[0], cmd_to_str(i
)) == 0) {
1759 (void) fprintf(stderr
, gettext("Unknown command: '%s'\n"),
1765 * Revert configuration of an instance to latest previous version.
1766 * Free the handle and read again.
1770 revert_func(cmd_t
*cmd
)
1774 nwam_ncu_type_t ncu_type
;
1775 nwam_object_type_t object_type
= active_object_type();
1777 switch (object_type
) {
1778 case NWAM_OBJECT_TYPE_NCU
:
1779 /* retrieve name and type to use later */
1780 if ((ret
= nwam_ncu_get_ncu_type(ncu_h
, &ncu_type
))
1782 nwamerr(ret
, "Revert error: Get ncu type error");
1785 if ((ret
= nwam_ncu_get_name(ncu_h
, &name
)) != NWAM_SUCCESS
)
1787 nwam_ncu_free(ncu_h
);
1789 ret
= nwam_ncu_read(ncp_h
, name
, ncu_type
, 0, &ncu_h
);
1791 case NWAM_OBJECT_TYPE_ENM
:
1792 if ((ret
= nwam_enm_get_name(enm_h
, &name
)) != NWAM_SUCCESS
)
1794 nwam_enm_free(enm_h
);
1796 ret
= nwam_enm_read(name
, 0, &enm_h
);
1798 case NWAM_OBJECT_TYPE_LOC
:
1799 if ((ret
= nwam_loc_get_name(loc_h
, &name
)) != NWAM_SUCCESS
)
1801 nwam_loc_free(loc_h
);
1803 ret
= nwam_loc_read(name
, 0, &loc_h
);
1805 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
1806 if ((ret
= nwam_known_wlan_get_name(wlan_h
, &name
))
1809 nwam_known_wlan_free(wlan_h
);
1811 ret
= nwam_known_wlan_read(name
, 0, &wlan_h
);
1815 /* Exit this scope because handle already freed (call do_cancel()) */
1816 need_to_commit
= B_FALSE
;
1818 if (ret
!= NWAM_SUCCESS
) {
1819 if (ret
== NWAM_ENTITY_NOT_FOUND
) {
1820 nerr("%s '%s' does not exist to revert to, removing it",
1821 nwam_object_type_to_string(object_type
), name
);
1823 nwamerr(ret
, "Revert error");
1831 if (ret
!= NWAM_SUCCESS
)
1832 nwamerr(ret
, "Revert error: get name error");
1836 * Load a resource from persistent repository and enter the scope
1840 select_func(cmd_t
*cmd
)
1843 char *name
, *realname
= NULL
;
1845 assert(cmd
->cmd_argc
> 0);
1846 if (current_scope
== NWAM_SCOPE_NCP
&& cmd
->cmd_res2_type
!= RT2_NCU
) {
1847 nerr("cannot select '%s' at this scope",
1848 rt1_to_str(cmd
->cmd_res1_type
));
1852 /* argv[0] is name */
1853 name
= trim_quotes(cmd
->cmd_argv
[0]);
1854 switch (cmd
->cmd_res1_type
) {
1856 ret
= nwam_loc_read(name
, 0, &loc_h
);
1857 if (ret
== NWAM_SUCCESS
) {
1858 current_scope
= NWAM_SCOPE_LOC
;
1859 (void) object_name_from_handle(NWAM_OBJECT_TYPE_LOC
,
1864 ret
= nwam_enm_read(name
, 0, &enm_h
);
1865 if (ret
== NWAM_SUCCESS
) {
1866 current_scope
= NWAM_SCOPE_ENM
;
1867 (void) object_name_from_handle(NWAM_OBJECT_TYPE_ENM
,
1872 ret
= nwam_known_wlan_read(name
, 0, &wlan_h
);
1873 if (ret
== NWAM_SUCCESS
) {
1874 current_scope
= NWAM_SCOPE_WLAN
;
1875 (void) object_name_from_handle
1876 (NWAM_OBJECT_TYPE_KNOWN_WLAN
, wlan_h
, &realname
);
1880 if (cmd
->cmd_res2_type
== RT2_NCU
) {
1881 nwam_ncu_type_t ncu_type
;
1882 nwam_ncu_class_t ncu_class
;
1884 /* ncp must already be read */
1885 if (ncp_h
== NULL
) {
1886 nerr("Select error: NCP has not been read");
1890 ncu_class
= (nwam_ncu_class_t
)cmd
->cmd_ncu_class_type
;
1891 ncu_type
= nwam_ncu_class_to_type(ncu_class
);
1892 ret
= nwam_ncu_read(ncp_h
, name
, ncu_type
, 0, &ncu_h
);
1893 if (ret
== NWAM_SUCCESS
) {
1894 current_scope
= NWAM_SCOPE_NCU
;
1895 (void) object_name_from_handle
1896 (NWAM_OBJECT_TYPE_NCU
, ncu_h
, &realname
);
1899 ret
= nwam_ncp_read(name
, 0, &ncp_h
);
1900 if (ret
== NWAM_SUCCESS
) {
1901 current_scope
= NWAM_SCOPE_NCP
;
1902 (void) object_name_from_handle
1903 (NWAM_OBJECT_TYPE_NCP
, ncp_h
, &realname
);
1908 nerr("Select error: unknown object-type");
1913 if (ret
!= NWAM_SUCCESS
) {
1914 nwamerr(ret
, "Select error");
1916 /* set the obj*_name or obj*_type depending on current scope */
1917 if (current_scope
== NWAM_SCOPE_NCU
) {
1918 obj2_type
= RT2_NCU
;
1919 (void) strlcpy(obj2_name
,
1920 realname
!= NULL
? realname
: name
,
1921 sizeof (obj2_name
));
1923 (void) strlcpy(obj1_name
,
1924 realname
!= NULL
? realname
: name
,
1925 sizeof (obj1_name
));
1926 obj1_type
= cmd
->cmd_res1_type
;
1933 /* Given an int for prop, returns it as string */
1935 pt_to_prop_name(nwam_object_type_t object_type
, int pt_type
)
1938 prop_table_entry_t
*prop_table
= get_prop_table(object_type
);
1940 for (i
= 0; prop_table
[i
].pte_name
!= NULL
; i
++) {
1941 if (pt_type
== prop_table
[i
].pte_type
)
1942 return (prop_table
[i
].pte_name
);
1947 /* Given a prop as a string, returns it as an int */
1949 prop_to_pt(nwam_object_type_t object_type
, const char *prop
)
1952 prop_table_entry_t
*prop_table
= get_prop_table(object_type
);
1954 for (i
= 0; prop_table
[i
].pte_name
!= NULL
; i
++) {
1955 if (strcmp(prop
, prop_table
[i
].pte_name
) == 0)
1956 return (prop_table
[i
].pte_type
);
1961 /* Given a prop as an int, returns its type (nwam_value_type_t) */
1962 static nwam_value_type_t
1963 prop_value_type(nwam_object_type_t object_type
, const char *prop
)
1966 nwam_value_type_t value_type
;
1968 switch (object_type
) {
1969 case NWAM_OBJECT_TYPE_NCU
:
1970 ret
= nwam_ncu_get_prop_type(prop
, &value_type
);
1972 case NWAM_OBJECT_TYPE_LOC
:
1973 ret
= nwam_loc_get_prop_type(prop
, &value_type
);
1975 case NWAM_OBJECT_TYPE_ENM
:
1976 ret
= nwam_enm_get_prop_type(prop
, &value_type
);
1978 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
1979 ret
= nwam_known_wlan_get_prop_type(prop
, &value_type
);
1983 if (ret
!= NWAM_SUCCESS
)
1984 value_type
= NWAM_VALUE_TYPE_UNKNOWN
;
1986 return (value_type
);
1990 * Converts input_str to an array nwam_value.
1991 * If is_list_prop, break input_str into array of strings first.
1994 str_to_nwam_value(nwam_object_type_t object_type
, char *input_str
, int pt_type
,
1995 boolean_t is_list_prop
)
2002 nwam_value_type_t value_type
;
2004 uint64_t *uint_vals
;
2005 boolean_t
*boolean_vals
;
2008 * Worst case is that each char separated by DELIMITER, so the
2009 * max number of sub strings is half of string length + 1.
2011 max_str_num
= strlen(input_str
) / 2 + 1;
2013 val
= calloc(max_str_num
, sizeof (char *));
2015 nerr("Out of memory");
2022 * Break down input_str and save as array of sub strings.
2023 * Set num as the number of the sub strings.
2024 * Use nwam_tokenize_by_unescaped_delim() rather than strtok()
2025 * because DELIMITER may be escaped
2027 tmp
= (char *)input_str
;
2028 while ((tmp
= nwam_tokenize_by_unescaped_delim(tmp
,
2029 NWAM_VALUE_DELIMITER_CHAR
, &next
)) != NULL
) {
2030 val
[n
++] = trim_quotes(tmp
);
2034 val
[n
++] = trim_quotes(input_str
);
2037 /* initialize int_vals or booleans_vals depending on pt_type */
2038 value_type
= prop_value_type(object_type
,
2039 pt_to_prop_name(object_type
, pt_type
));
2040 if (value_type
== NWAM_VALUE_TYPE_INT64
) {
2041 int_vals
= calloc(n
, sizeof (int64_t));
2042 if (int_vals
== NULL
) {
2043 nerr("Out of memory");
2044 array_free((void **)val
, max_str_num
);
2047 } else if (value_type
== NWAM_VALUE_TYPE_UINT64
) {
2048 uint_vals
= calloc(n
, sizeof (uint64_t));
2049 if (uint_vals
== NULL
) {
2050 nerr("Out of memory");
2051 array_free((void **)val
, max_str_num
);
2054 } else if (value_type
== NWAM_VALUE_TYPE_BOOLEAN
) {
2055 boolean_vals
= calloc(n
, sizeof (boolean_t
));
2056 if (boolean_vals
== NULL
) {
2057 nerr("Out of memory");
2058 array_free((void **)val
, max_str_num
);
2062 /* set the appropriate array */
2063 for (i
= 0; i
< n
; i
++) {
2064 switch (value_type
) {
2065 case NWAM_VALUE_TYPE_STRING
:
2066 /* nothing to do - val already has the char** array */
2068 case NWAM_VALUE_TYPE_INT64
:
2070 int_vals
[i
] = (int64_t)atoi(val
[i
]);
2073 case NWAM_VALUE_TYPE_UINT64
:
2075 uint64_t str_as_enum
;
2078 ret
= nwam_value_string_get_uint64(
2079 pt_to_prop_name(object_type
, pt_type
),
2080 val
[i
], &str_as_enum
);
2082 * Returns _SUCCESS if value for enum is valid.
2083 * Returns _INVALID_ARG if property is not an enum.
2085 if (ret
== NWAM_SUCCESS
) {
2086 uint_vals
[i
] = str_as_enum
;
2087 } else if (ret
== NWAM_INVALID_ARG
) {
2088 uint_vals
[i
] = strtoul(val
[i
], &endptr
, 10);
2089 /* verify conversion is valid */
2090 if (endptr
== val
[i
]) {
2092 array_free((void **)val
, max_str_num
);
2097 array_free((void **)val
, max_str_num
);
2102 case NWAM_VALUE_TYPE_BOOLEAN
:
2103 boolean_vals
[i
] = str_to_boolean(val
[i
]);
2106 array_free((void **)val
, max_str_num
);
2111 /* create nwam_value_t */
2112 if (value_type
== NWAM_VALUE_TYPE_STRING
) {
2113 ret
= nwam_value_create_string_array(val
, n
, &data
);
2114 } else if (value_type
== NWAM_VALUE_TYPE_INT64
) {
2115 ret
= nwam_value_create_int64_array(int_vals
, n
, &data
);
2117 } else if (value_type
== NWAM_VALUE_TYPE_UINT64
) {
2118 ret
= nwam_value_create_uint64_array(uint_vals
, n
, &data
);
2120 } else if (value_type
== NWAM_VALUE_TYPE_BOOLEAN
) {
2121 ret
= nwam_value_create_boolean_array(boolean_vals
, n
, &data
);
2124 array_free((void **)val
, max_str_num
);
2126 if (ret
!= NWAM_SUCCESS
) {
2127 nwamerr(ret
, "Failed creating nwam_value");
2135 * Displaying/Skipping of properties
2136 * ---------------------------------
2138 * This table shows if a specific property should be shown if some
2139 * other property has a specific value. This table is used by
2140 * show_prop_test(), which is called by set_func() and walkprop_func().
2142 * An entry in the table looks like:
2143 * { property1, property2, { val1, val2, -1 } }
2145 * "show property1 only if property2 has value val1 or val2"
2147 * NB: If a property does not appear in this table, then that implies
2148 * that the property is always shown.
2150 * A property can have more than one rule. In such a case, the property is
2151 * displayed only any of the rules is satisfied. This checking, however,
2152 * is recursive. If a rule says that a property can be displayed, then the
2153 * property that's checked should also satisfy its rules. In the above
2154 * example, if property1 is to be displayed, then property2 should also
2155 * satisfy its rules and be displayable. This recursion is necessary as
2156 * properties that are not displayed (because rules are not satisfied) are
2160 /* The most number of values in pde_checkvals below */
2161 #define NWAM_CHECKVALS_MAX 5
2163 typedef struct prop_display_entry
{
2164 const char *pde_name
; /* property to show */
2165 const char *pde_checkname
; /* property to check */
2166 int64_t pde_checkvals
[NWAM_CHECKVALS_MAX
]; /* show prop for these */
2167 } prop_display_entry_t
;
2169 /* Rules for showing properties: commented for clarity */
2173 * NB: There is no need to have an entry if a property is for IP only.
2174 * This is taken care of in libnwam_ncp.c
2176 static prop_display_entry_t ncu_prop_display_entry_table
[] = {
2177 /* show priority-{group,mode} if activation == prioritized */
2178 { NWAM_NCU_PROP_PRIORITY_GROUP
, NWAM_NCU_PROP_ACTIVATION_MODE
,
2179 { NWAM_ACTIVATION_MODE_PRIORITIZED
, -1 } },
2180 { NWAM_NCU_PROP_PRIORITY_MODE
, NWAM_NCU_PROP_ACTIVATION_MODE
,
2181 { NWAM_ACTIVATION_MODE_PRIORITIZED
, -1 } },
2182 /* show ipv4-addrsrc if ip-version == ipv4 */
2183 { NWAM_NCU_PROP_IPV4_ADDRSRC
, NWAM_NCU_PROP_IP_VERSION
,
2184 { IPV4_VERSION
, -1 } },
2185 /* show ipv4-addr if ipv4-addrsrc == static */
2186 { NWAM_NCU_PROP_IPV4_ADDR
, NWAM_NCU_PROP_IPV4_ADDRSRC
,
2187 { NWAM_ADDRSRC_STATIC
, -1 } },
2188 /* show ipv4-default-route if ip-version == ipv4 */
2189 { NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE
, NWAM_NCU_PROP_IP_VERSION
,
2190 { IPV4_VERSION
, -1 } },
2191 /* show ipv6-addrsrc if ip-version == ipv6 */
2192 { NWAM_NCU_PROP_IPV6_ADDRSRC
, NWAM_NCU_PROP_IP_VERSION
,
2193 { IPV6_VERSION
, -1 } },
2194 /* show ipv6-addr if ipv6-addrsrc == static */
2195 { NWAM_NCU_PROP_IPV6_ADDR
, NWAM_NCU_PROP_IPV6_ADDRSRC
,
2196 { NWAM_ADDRSRC_STATIC
, -1 } },
2197 /* show ipv6-default-route if ip-version == ipv6 */
2198 { NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE
, NWAM_NCU_PROP_IP_VERSION
,
2199 { IPV6_VERSION
, -1 } },
2200 { NULL
, NULL
, { -1 } }
2203 /* Rules for ENMs */
2204 static prop_display_entry_t enm_prop_display_entry_table
[] = {
2205 /* show conditions if activation-mode == conditional-{all,any} */
2206 { NWAM_ENM_PROP_CONDITIONS
, NWAM_ENM_PROP_ACTIVATION_MODE
,
2207 { NWAM_ACTIVATION_MODE_CONDITIONAL_ALL
,
2208 NWAM_ACTIVATION_MODE_CONDITIONAL_ANY
, -1 } },
2209 { NULL
, NULL
, { -1 } }
2212 /* Rules for LOCations */
2213 static prop_display_entry_t loc_prop_display_entry_table
[] = {
2214 /* show conditions if activation-mode == conditional-{all,any} */
2215 { NWAM_LOC_PROP_CONDITIONS
, NWAM_LOC_PROP_ACTIVATION_MODE
,
2216 { NWAM_ACTIVATION_MODE_CONDITIONAL_ALL
,
2217 NWAM_ACTIVATION_MODE_CONDITIONAL_ANY
, -1 } },
2218 /* show dns-nameservice-configsrc if nameservices == dns */
2219 { NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC
, NWAM_LOC_PROP_NAMESERVICES
,
2220 { NWAM_NAMESERVICES_DNS
, -1 } },
2221 /* show other DNS options if dns-nameservices-configsrc == manual */
2222 { NWAM_LOC_PROP_DNS_NAMESERVICE_DOMAIN
,
2223 NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC
,
2224 { NWAM_CONFIGSRC_MANUAL
, -1 } },
2225 { NWAM_LOC_PROP_DNS_NAMESERVICE_SERVERS
,
2226 NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC
,
2227 { NWAM_CONFIGSRC_MANUAL
, -1 } },
2228 { NWAM_LOC_PROP_DNS_NAMESERVICE_SEARCH
,
2229 NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC
,
2230 { NWAM_CONFIGSRC_MANUAL
, -1 } },
2231 /* show nis-nameservice-configsrc if nameservices == nis */
2232 { NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC
, NWAM_LOC_PROP_NAMESERVICES
,
2233 { NWAM_NAMESERVICES_NIS
, -1 } },
2234 /* show nis-nameservice-servers if nis-nameservice-configsrc = manual */
2235 { NWAM_LOC_PROP_NIS_NAMESERVICE_SERVERS
,
2236 NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC
,
2237 { NWAM_CONFIGSRC_MANUAL
, -1 } },
2238 /* show ldap-nameservice-configsrc if nameservices == ldap */
2239 { NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
, NWAM_LOC_PROP_NAMESERVICES
,
2240 { NWAM_NAMESERVICES_LDAP
, -1 } },
2241 /* show ldap-nameservice-servers if ldap-nameservice-configsrc=manual */
2242 { NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS
,
2243 NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
,
2244 { NWAM_CONFIGSRC_MANUAL
, -1 } },
2245 /* show default-domain if {nis,ldap}-nameservice-configsrc == manual */
2246 { NWAM_LOC_PROP_DEFAULT_DOMAIN
, NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC
,
2247 { NWAM_CONFIGSRC_MANUAL
, -1 } },
2248 { NWAM_LOC_PROP_DEFAULT_DOMAIN
,
2249 NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
,
2250 { NWAM_CONFIGSRC_MANUAL
, -1 } },
2251 { NULL
, NULL
, { -1 } }
2254 /* Rules for Known WLANs */
2255 static prop_display_entry_t wlan_prop_display_entry_table
[] = {
2256 /* no rules for WLANs */
2257 { NULL
, NULL
, { -1 } }
2260 /* Returns the appropriate rules table for the given object type */
2261 static prop_display_entry_t
*
2262 get_prop_display_table(nwam_object_type_t object_type
)
2264 switch (object_type
) {
2265 case NWAM_OBJECT_TYPE_NCU
:
2266 return (ncu_prop_display_entry_table
);
2267 case NWAM_OBJECT_TYPE_LOC
:
2268 return (loc_prop_display_entry_table
);
2269 case NWAM_OBJECT_TYPE_ENM
:
2270 return (enm_prop_display_entry_table
);
2271 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
2272 return (wlan_prop_display_entry_table
);
2278 * Tests whether prop must be shown during a walk depending on the
2279 * value of a different property.
2281 * This function is also used by set_func() to determine whether the
2282 * property being set should be allowed or not. If the property
2283 * would not be displayed in a walk, then it should not be set.
2285 * The checked_props and num_checked arguments are used to avoid circular
2286 * dependencies between properties. When this function recursively calls
2287 * itself, it adds the property that it just checked to the checked_props
2291 show_prop_test(nwam_object_type_t object_type
, const char *prop
,
2292 prop_display_entry_t
*display_list
, char **checked_props
, int num_checked
)
2295 nwam_value_t prop_val
;
2296 nwam_value_type_t prop_type
;
2298 boolean_t prop_found
= B_FALSE
, show_prop
= B_FALSE
;
2301 * Check if this property has already been checked previously in
2302 * the recursion. If so, return B_FALSE so that the initial prop
2305 for (i
= 0; i
< num_checked
; i
++) {
2306 if (strcmp(prop
, checked_props
[i
]) == 0) {
2307 free(checked_props
);
2312 for (i
= 0; display_list
[i
].pde_name
!= NULL
; i
++) {
2313 if (strcmp(prop
, display_list
[i
].pde_name
) != 0)
2315 prop_found
= B_TRUE
;
2317 /* get the value(s) of the (other) property to check */
2318 switch (object_type
) {
2319 case NWAM_OBJECT_TYPE_NCU
:
2320 ret
= nwam_ncu_get_prop_value(ncu_h
,
2321 display_list
[i
].pde_checkname
, &prop_val
);
2323 case NWAM_OBJECT_TYPE_LOC
:
2324 ret
= nwam_loc_get_prop_value(loc_h
,
2325 display_list
[i
].pde_checkname
, &prop_val
);
2327 case NWAM_OBJECT_TYPE_ENM
:
2328 ret
= nwam_enm_get_prop_value(enm_h
,
2329 display_list
[i
].pde_checkname
, &prop_val
);
2331 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
2334 if (ret
!= NWAM_SUCCESS
)
2337 /* prop_val may contain a uint64 array or a boolean */
2338 if (nwam_value_get_type(prop_val
, &prop_type
) != NWAM_SUCCESS
)
2341 if (prop_type
== NWAM_VALUE_TYPE_UINT64
) {
2342 uint64_t *prop_uvals
;
2343 int64_t *check_uvals
;
2346 if (nwam_value_get_uint64_array(prop_val
, &prop_uvals
,
2347 &numvals
) != NWAM_SUCCESS
) {
2348 nwam_value_free(prop_val
);
2352 /* for each value in uvals, check each value in table */
2353 for (j
= 0; j
< numvals
; j
++) {
2354 check_uvals
= display_list
[i
].pde_checkvals
;
2355 for (k
= 0; check_uvals
[k
] != -1; k
++) {
2356 /* show if uvals[j] matches */
2357 if (prop_uvals
[j
] ==
2358 (uint64_t)check_uvals
[k
]) {
2364 } else if (prop_type
== NWAM_VALUE_TYPE_BOOLEAN
) {
2367 if (nwam_value_get_boolean(prop_val
, &bval
) !=
2369 nwam_value_free(prop_val
);
2374 display_list
[i
].pde_checkvals
[k
] != -1;
2376 /* show if bval matches */
2377 if (bval
== (boolean_t
)
2378 display_list
[i
].pde_checkvals
[k
]) {
2386 nwam_value_free(prop_val
);
2388 * If show_prop is set, then a rule is satisfied; no need to
2389 * check other rules for this prop. However, recursively
2390 * check if the checked prop (pde_checkname) satisfies its
2391 * rules. Also, update the check_props array with this prop.
2394 char **newprops
= reallocarray(checked_props
,
2395 ++num_checked
, sizeof (char *));
2396 if (newprops
== NULL
) {
2397 free(checked_props
);
2400 checked_props
= newprops
;
2401 checked_props
[num_checked
- 1] = (char *)prop
;
2403 return (show_prop_test(object_type
,
2404 display_list
[i
].pde_checkname
, display_list
,
2405 checked_props
, num_checked
));
2410 * If we are here and prop_found is set, it means that no rules were
2411 * satisfied by prop; return B_FALSE. If prop_found is not set, then
2412 * prop did not have a rule so it must be displayed; return B_TRUE.
2414 free(checked_props
);
2422 * Returns true if the given property is read-only and cannot be modified.
2425 is_prop_read_only(nwam_object_type_t object_type
, const char *prop
)
2429 switch (object_type
) {
2430 case NWAM_OBJECT_TYPE_NCU
:
2431 if (nwam_ncu_prop_read_only(prop
, &ro
) == NWAM_SUCCESS
&& ro
)
2434 case NWAM_OBJECT_TYPE_ENM
:
2435 if (nwam_enm_prop_read_only(prop
, &ro
) == NWAM_SUCCESS
&& ro
)
2438 case NWAM_OBJECT_TYPE_LOC
:
2439 if (nwam_loc_prop_read_only(prop
, &ro
) == NWAM_SUCCESS
&& ro
)
2442 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
2443 /* no read-only properties for WLANs */
2449 /* Returns true if the property is multi-valued */
2451 is_prop_multivalued(nwam_object_type_t object_type
, const char *prop
)
2456 switch (object_type
) {
2457 case NWAM_OBJECT_TYPE_NCU
:
2458 ret
= nwam_ncu_prop_multivalued(prop
, &multi
);
2460 case NWAM_OBJECT_TYPE_LOC
:
2461 ret
= nwam_loc_prop_multivalued(prop
, &multi
);
2463 case NWAM_OBJECT_TYPE_ENM
:
2464 ret
= nwam_enm_prop_multivalued(prop
, &multi
);
2466 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
2467 ret
= nwam_known_wlan_prop_multivalued(prop
, &multi
);
2471 if (ret
!= NWAM_SUCCESS
)
2477 * Prints out error message specific to property that could not be set.
2478 * Property description is used to help guide user in entering correct value.
2481 invalid_set_prop_msg(const char *prop
, nwam_error_t err
)
2483 const char *description
;
2485 if (err
== NWAM_SUCCESS
)
2488 if (err
!= NWAM_ENTITY_INVALID_VALUE
) {
2489 nwamerr(err
, "Set error");
2493 switch (active_object_type()) {
2494 case NWAM_OBJECT_TYPE_NCU
:
2495 (void) nwam_ncu_get_prop_description(prop
, &description
);
2497 case NWAM_OBJECT_TYPE_LOC
:
2498 (void) nwam_loc_get_prop_description(prop
, &description
);
2500 case NWAM_OBJECT_TYPE_ENM
:
2501 (void) nwam_enm_get_prop_description(prop
, &description
);
2503 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
2504 (void) nwam_known_wlan_get_prop_description(prop
,
2508 nerr("Set error: invalid value\n'%s' %s", prop
, description
);
2512 * Sets the property value.
2513 * Read-only properties and objects cannot be set.
2514 * "read-only" is a special in that it can be set on a read-only object.
2515 * The object has to be committed before other properties can be set.
2516 * Also uses show_prop_test() to test if the property being set would
2517 * be skipped during a walk (as determined by the value of some other
2518 * property). If so, then it cannot be set.
2521 set_func(cmd_t
*cmd
)
2523 int pt_type
= cmd
->cmd_prop_type
;
2524 nwam_error_t ret
= NWAM_SUCCESS
;
2525 nwam_value_t prop_value
;
2527 boolean_t is_listprop
= B_FALSE
;
2528 nwam_object_type_t object_type
;
2529 prop_display_entry_t
*prop_table
;
2530 char **checked
= NULL
;
2532 assert(cmd
->cmd_argc
> 0);
2534 object_type
= active_object_type();
2535 prop_table
= get_prop_display_table(object_type
);
2537 /* argv[0] is property value */
2538 if ((prop
= pt_to_prop_name(object_type
, pt_type
)) == NULL
) {
2539 nerr("Set error: invalid %s property: '%s'",
2540 scope_to_str(current_scope
), pt_to_str(pt_type
));
2544 /* check if property can be set */
2545 if (is_prop_read_only(object_type
, prop
)) {
2546 nerr("Set error: property '%s' is read-only", prop
);
2549 if (!show_prop_test(object_type
, prop
, prop_table
, checked
, 0)) {
2550 if (interactive_mode
) {
2551 (void) printf(gettext("setting property '%s' "
2552 "has no effect\n"), prop
);
2556 is_listprop
= is_prop_multivalued(object_type
, prop
);
2557 prop_value
= str_to_nwam_value(object_type
, cmd
->cmd_argv
[0], pt_type
,
2559 if (prop_value
== NULL
) {
2560 invalid_set_prop_msg(prop
, NWAM_ENTITY_INVALID_VALUE
);
2564 /* set the property value */
2565 switch (object_type
) {
2566 case NWAM_OBJECT_TYPE_NCU
:
2567 ret
= nwam_ncu_set_prop_value(ncu_h
, prop
, prop_value
);
2569 case NWAM_OBJECT_TYPE_LOC
:
2570 ret
= nwam_loc_set_prop_value(loc_h
, prop
, prop_value
);
2572 case NWAM_OBJECT_TYPE_ENM
:
2573 ret
= nwam_enm_set_prop_value(enm_h
, prop
, prop_value
);
2575 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
2576 ret
= nwam_known_wlan_set_prop_value(wlan_h
, prop
, prop_value
);
2579 nwam_value_free(prop_value
);
2581 /* delete other properties if needed */
2582 if (ret
== NWAM_SUCCESS
)
2583 need_to_commit
= B_TRUE
;
2585 invalid_set_prop_msg(prop
, ret
);
2589 list_callback(nwam_object_type_t object_type
, void *handle
,
2590 boolean_t
*list_msgp
, const char *msg
)
2594 nwam_ncu_class_t
class;
2597 (void) printf("%s:\n", msg
);
2598 *list_msgp
= B_FALSE
;
2601 ret
= object_name_from_handle(object_type
, handle
, &name
);
2602 if (ret
!= NWAM_SUCCESS
) {
2603 nwamerr(ret
, "List error: failed to get name");
2607 /* If NCU, get its class and print */
2608 if (object_type
== NWAM_OBJECT_TYPE_NCU
) {
2609 if ((ret
= nwam_ncu_get_ncu_class(handle
, &class))
2611 nwamerr(ret
, "List error: failed to get ncu class");
2615 (void) printf("\t%s",
2616 propval_to_str(NWAM_NCU_PROP_CLASS
, class));
2619 (void) printf("\t%s\n", name
);
2625 /* Print out name, type and status */
2627 list_loc_callback(nwam_loc_handle_t loc
, void *arg
)
2629 return (list_callback(NWAM_OBJECT_TYPE_LOC
, loc
, arg
, "Locations"));
2633 list_enm_callback(nwam_enm_handle_t enm
, void *arg
)
2635 return (list_callback(NWAM_OBJECT_TYPE_ENM
, enm
, arg
, "ENMs"));
2639 list_wlan_callback(nwam_known_wlan_handle_t wlan
, void *arg
)
2641 return (list_callback(NWAM_OBJECT_TYPE_KNOWN_WLAN
, wlan
, arg
, "WLANs"));
2645 list_ncp_callback(nwam_ncp_handle_t ncp
, void *arg
)
2647 return (list_callback(NWAM_OBJECT_TYPE_NCP
, ncp
, arg
, "NCPs"));
2651 list_ncu_callback(nwam_ncu_handle_t ncu
, void *arg
)
2653 return (list_callback(NWAM_OBJECT_TYPE_NCU
, ncu
, arg
, "NCUs"));
2656 /* functions to convert a value to a string */
2659 str2str(void *s
, const char *prop
, char *str
)
2661 (void) snprintf(str
, NWAM_MAX_VALUE_LEN
, "%s", s
);
2667 str2qstr(void *s
, const char *prop
, char *qstr
)
2669 /* quoted strings */
2670 (void) snprintf(qstr
, NWAM_MAX_VALUE_LEN
, "\"%s\"", s
);
2676 int2str(void *in
, const char *prop
, char *instr
)
2678 (void) snprintf(instr
, NWAM_MAX_VALUE_LEN
, "%lld", *((int64_t *)in
));
2683 uint2str(void *uin
, const char *prop
, char *uintstr
)
2685 /* returns NWAM_SUCCESS if prop is enum with string in uintstr */
2686 if (nwam_uint64_get_value_string(prop
, *((uint64_t *)uin
),
2687 (const char **)&uintstr
) != NWAM_SUCCESS
) {
2688 (void) snprintf(uintstr
, NWAM_MAX_VALUE_LEN
, "%lld",
2689 *((uint64_t *)uin
));
2696 bool2str(void *bool, const char *prop
, char *boolstr
)
2698 (void) snprintf(boolstr
, NWAM_MAX_VALUE_LEN
, "%s",
2699 *((boolean_t
*)bool) ? "true" : "false");
2704 * Print the value (enums are converted to string), use DELIMITER for
2705 * array. If strings are to be "quoted", pass B_TRUE for quoted_strings.
2708 output_prop_val(const char *prop_name
, nwam_value_t value
, FILE *wf
,
2709 boolean_t quoted_strings
)
2711 nwam_value_type_t value_type
;
2714 /* arrays for values retrieved according to the type of value */
2720 /* pointer to function to generate string representation of value */
2721 const char *(*tostr
)(void *, const char *, char *);
2722 char str
[NWAM_MAX_VALUE_LEN
]; /* to store the string */
2725 if (nwam_value_get_type(value
, &value_type
) != NWAM_SUCCESS
) {
2726 nerr("Get value type error");
2730 if (value_type
== NWAM_VALUE_TYPE_STRING
) {
2731 if (nwam_value_get_string_array(value
, &svals
, &num
) !=
2733 nerr("Get string array error");
2736 tostr
= quoted_strings
? str2qstr
: str2str
;
2737 } else if (value_type
== NWAM_VALUE_TYPE_INT64
) {
2738 if (nwam_value_get_int64_array(value
, &ivals
, &num
) !=
2740 nerr("Get int64 array error");
2744 } else if (value_type
== NWAM_VALUE_TYPE_UINT64
) {
2745 if (nwam_value_get_uint64_array(value
, &uvals
, &num
) !=
2747 nerr("Get uint64 array error");
2751 } else if (value_type
== NWAM_VALUE_TYPE_BOOLEAN
) {
2752 if (nwam_value_get_boolean_array(value
, &bvals
, &num
) !=
2754 nerr("Get boolean array error");
2760 /* now, loop and print each value */
2761 for (i
= 0; i
< num
; i
++) {
2764 /* get the pointer to the ith value to pass to func() */
2765 if (value_type
== NWAM_VALUE_TYPE_STRING
)
2767 else if (value_type
== NWAM_VALUE_TYPE_UINT64
)
2769 else if (value_type
== NWAM_VALUE_TYPE_INT64
)
2771 else if (value_type
== NWAM_VALUE_TYPE_BOOLEAN
)
2774 (void) fprintf(wf
, "%s%s", tostr(val
, prop_name
, str
),
2775 i
!= num
-1 ? NWAM_VALUE_DELIMITER_STR
: "");
2779 /* Prints the property names aligned (for list/get) or "prop=" (for export) */
2781 output_propname_common(const char *prop
, nwam_value_t values
, void *arg
,
2784 FILE *of
= (arg
== NULL
) ? stdout
: arg
;
2786 /* arg is NULL for list/get, not NULL for export */
2788 (void) fprintf(of
, "\t%-*s\t", width
, prop
);
2790 (void) fprintf(of
, "%s=", prop
);
2793 output_prop_val(prop
, values
, of
, B_TRUE
);
2795 (void) fprintf(of
, "\n");
2800 output_propname(const char *prop
, nwam_value_t values
, void *arg
)
2802 return (output_propname_common(prop
, values
, arg
, 16));
2805 /* For locations because of longer property names */
2807 output_loc_propname(const char *prop
, nwam_value_t values
, void *arg
)
2809 return (output_propname_common(prop
, values
, arg
, 25));
2813 * all_props specifies whether properties that have not been set should be
2814 * printed or not. ncp and ncu_type are used only when the object_type is
2818 listprop(nwam_object_type_t object_type
, void *handle
, const char *name
,
2819 boolean_t all_props
, nwam_ncp_handle_t ncp
, nwam_ncu_type_t ncu_type
)
2822 char *lname
= NULL
, *realname
= NULL
;
2823 boolean_t lhandle
= B_FALSE
;
2824 const char **props
= NULL
;
2830 * handle is NULL if called from a scope higher than the object's
2831 * scope, but name must be given; so get the handle.
2833 if (handle
== NULL
) {
2834 lname
= trim_quotes(name
); /* name may have quotes */
2835 switch (object_type
) {
2836 case NWAM_OBJECT_TYPE_NCP
:
2837 if ((ret
= nwam_ncp_read(lname
, 0,
2838 (nwam_ncp_handle_t
*)&handle
)) != NWAM_SUCCESS
)
2841 case NWAM_OBJECT_TYPE_NCU
:
2842 ret
= nwam_ncu_read(ncp
, lname
, ncu_type
, 0,
2843 (nwam_ncu_handle_t
*)&handle
);
2844 if (ret
== NWAM_ENTITY_MULTIPLE_VALUES
) {
2846 * Multiple NCUs with the given name exists.
2847 * Call listprop() for each NCU type.
2849 if ((ret
= listprop(object_type
, NULL
, lname
,
2850 all_props
, ncp
, NWAM_NCU_TYPE_LINK
))
2853 ret
= listprop(object_type
, NULL
, lname
,
2854 all_props
, ncp
, NWAM_NCU_TYPE_INTERFACE
);
2856 } else if (ret
!= NWAM_SUCCESS
) {
2860 case NWAM_OBJECT_TYPE_LOC
:
2861 if ((ret
= nwam_loc_read(lname
, 0,
2862 (nwam_loc_handle_t
*)&handle
)) != NWAM_SUCCESS
)
2865 case NWAM_OBJECT_TYPE_ENM
:
2866 if ((ret
= nwam_enm_read(lname
, 0,
2867 (nwam_enm_handle_t
*)&handle
)) != NWAM_SUCCESS
)
2870 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
2871 if ((ret
= nwam_known_wlan_read(lname
, 0,
2872 (nwam_known_wlan_handle_t
*)&handle
))
2880 if ((ret
= object_name_from_handle(object_type
, handle
, &realname
))
2884 /* get the property list */
2885 switch (object_type
) {
2886 case NWAM_OBJECT_TYPE_NCP
:
2889 boolean_t list_msg
= B_TRUE
;
2890 ret
= nwam_ncp_walk_ncus(handle
, list_ncu_callback
, &list_msg
,
2891 NWAM_FLAG_NCU_TYPE_CLASS_ALL
, NULL
);
2894 case NWAM_OBJECT_TYPE_NCU
:
2896 nwam_ncu_type_t ncu_type
;
2897 nwam_ncu_class_t ncu_class
;
2899 if ((ret
= nwam_ncu_get_ncu_type(handle
, &ncu_type
))
2902 if ((ret
= nwam_ncu_get_ncu_class(handle
, &ncu_class
))
2906 ret
= nwam_ncu_get_default_proplist(ncu_type
, ncu_class
, &props
,
2910 case NWAM_OBJECT_TYPE_LOC
:
2911 ret
= nwam_loc_get_default_proplist(&props
, &prop_num
);
2913 case NWAM_OBJECT_TYPE_ENM
:
2914 ret
= nwam_enm_get_default_proplist(&props
, &prop_num
);
2916 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
2917 ret
= nwam_known_wlan_get_default_proplist(&props
, &prop_num
);
2920 if (ret
!= NWAM_SUCCESS
)
2923 /* print object type and name */
2924 (void) printf("%s:%s\n", nwam_object_type_to_string(object_type
),
2927 /* Loop through the properties and print */
2928 for (i
= 0; i
< prop_num
; i
++) {
2929 /* get the existing value for this property */
2930 switch (object_type
) {
2931 case NWAM_OBJECT_TYPE_NCU
:
2932 ret
= nwam_ncu_get_prop_value(handle
, props
[i
], &vals
);
2934 case NWAM_OBJECT_TYPE_LOC
:
2935 ret
= nwam_loc_get_prop_value(handle
, props
[i
], &vals
);
2937 case NWAM_OBJECT_TYPE_ENM
:
2938 ret
= nwam_enm_get_prop_value(handle
, props
[i
], &vals
);
2940 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
2941 ret
= nwam_known_wlan_get_prop_value(handle
, props
[i
],
2945 if (ret
!= NWAM_SUCCESS
) {
2946 /* _ENTITY_NOT_FOUND is ok if listing for all props */
2949 else if (ret
!= NWAM_ENTITY_NOT_FOUND
)
2953 /* print property and value */
2954 if (object_type
== NWAM_OBJECT_TYPE_LOC
)
2955 output_loc_propname(props
[i
], vals
, NULL
);
2957 output_propname(props
[i
], vals
, NULL
);
2958 nwam_value_free(vals
);
2966 switch (object_type
) {
2967 case NWAM_OBJECT_TYPE_NCP
:
2968 nwam_ncp_free(handle
);
2970 case NWAM_OBJECT_TYPE_NCU
:
2971 nwam_ncu_free(handle
);
2973 case NWAM_OBJECT_TYPE_LOC
:
2974 nwam_loc_free(handle
);
2976 case NWAM_OBJECT_TYPE_ENM
:
2977 nwam_enm_free(handle
);
2979 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
2980 nwam_known_wlan_free(handle
);
2984 /* don't treat _ENTITY_NOT_FOUND as an error */
2985 if (ret
== NWAM_ENTITY_NOT_FOUND
)
2990 /* When nwam_*_read() fails */
2996 * List profiles or property and its values.
2997 * If the -a option is specified, all properties are listed.
3000 list_func(cmd_t
*cmd
)
3002 nwam_error_t ret
= NWAM_SUCCESS
;
3003 boolean_t list_msg
= B_TRUE
;
3005 boolean_t list_loc
= B_FALSE
, list_enm
= B_FALSE
;
3006 boolean_t list_ncp
= B_FALSE
, list_ncu
= B_FALSE
;
3007 boolean_t list_wlan
= B_FALSE
;
3009 /* whether all properties should be listed, given by the -a option */
3010 boolean_t all_props
= B_FALSE
;
3013 * list_props says whether the properties should be listed.
3014 * Note that, here NCUs are treated as properties of NCPs.
3016 boolean_t list_props
= B_FALSE
;
3018 /* determine which properties to list, also validity tests */
3019 if (current_scope
== NWAM_SCOPE_GBL
) {
3020 /* res1_type is -1 if only "list -a" is used */
3021 if (cmd
->cmd_res1_type
== -1) {
3022 nerr("'list' requires an object to be specified with "
3023 "the -a option in the global scope");
3026 if (cmd
->cmd_res1_type
== RT1_LOC
) {
3027 list_props
= B_TRUE
;
3029 } else if (cmd
->cmd_res1_type
== RT1_ENM
) {
3030 list_props
= B_TRUE
;
3032 } else if (cmd
->cmd_res1_type
== RT1_WLAN
) {
3033 list_props
= B_TRUE
;
3035 } else if (cmd
->cmd_res1_type
== RT1_NCP
) {
3037 list_props
= B_TRUE
;
3045 if ((current_scope
== NWAM_SCOPE_LOC
||
3046 current_scope
== NWAM_SCOPE_ENM
||
3047 current_scope
== NWAM_SCOPE_WLAN
||
3048 current_scope
== NWAM_SCOPE_NCU
) &&
3049 (cmd
->cmd_argc
>= 1 && cmd
->cmd_res1_type
!= -1)) {
3050 nerr("Additional options are not allowed with the -a option "
3054 if (current_scope
== NWAM_SCOPE_LOC
) {
3056 list_props
= B_TRUE
;
3058 if (current_scope
== NWAM_SCOPE_ENM
) {
3060 list_props
= B_TRUE
;
3062 if (current_scope
== NWAM_SCOPE_WLAN
) {
3064 list_props
= B_TRUE
;
3066 if (current_scope
== NWAM_SCOPE_NCP
) {
3067 if (cmd
->cmd_res1_type
== RT1_ENM
||
3068 cmd
->cmd_res1_type
== RT1_LOC
||
3069 cmd
->cmd_res1_type
== RT1_WLAN
) {
3070 nerr("only ncu can be listed at this scope");
3073 if (cmd
->cmd_res2_type
== RT2_NCU
) {
3075 list_props
= B_TRUE
;
3078 list_props
= B_TRUE
;
3081 if (current_scope
== NWAM_SCOPE_NCU
) {
3083 list_props
= B_TRUE
;
3086 /* Check if the -a option is specified to list all properties */
3087 if (cmd
->cmd_res1_type
== -1 || cmd
->cmd_argc
== 2) {
3092 /* if res1_type is -1, option is in argv[0], else in argv[1] */
3093 if (cmd
->cmd_res1_type
== -1)
3094 argv
= cmd
->cmd_argv
;
3096 argv
= &(cmd
->cmd_argv
[1]);
3097 while ((c
= getopt(argc
, argv
, "a")) != EOF
) {
3103 command_usage(CMD_LIST
);
3107 if (cmd
->cmd_res1_type
== -1)
3108 cmd
->cmd_argv
[0] = NULL
;
3112 * Now, print objects and/or according to the flags set.
3113 * name, if requested, is in argv[0].
3118 ret
= listprop(NWAM_OBJECT_TYPE_NCP
, ncp_h
,
3119 cmd
->cmd_argv
[0], all_props
, NULL
, -1);
3121 ret
= nwam_walk_ncps(list_ncp_callback
, &list_msg
, 0,
3124 if (ret
!= NWAM_SUCCESS
)
3130 if (ncp_h
== NULL
) {
3131 nerr("NCP has not been read");
3135 nwam_ncu_class_t ncu_class
;
3136 nwam_ncu_type_t ncu_type
;
3138 /* determine the NCU type first */
3139 if (ncu_h
== NULL
) {
3140 ncu_class
= (nwam_ncu_class_t
)
3141 cmd
->cmd_ncu_class_type
;
3142 ncu_type
= nwam_ncu_class_to_type(ncu_class
);
3144 if ((ret
= nwam_ncu_get_ncu_type(ncu_h
,
3145 &ncu_type
)) != NWAM_SUCCESS
)
3148 ret
= listprop(NWAM_OBJECT_TYPE_NCU
, ncu_h
,
3149 cmd
->cmd_argv
[0], all_props
, ncp_h
, ncu_type
);
3150 if (ret
!= NWAM_SUCCESS
)
3158 ret
= listprop(NWAM_OBJECT_TYPE_LOC
, loc_h
,
3159 cmd
->cmd_argv
[0], all_props
, NULL
, -1);
3161 ret
= nwam_walk_locs(list_loc_callback
, &list_msg
,
3162 NWAM_FLAG_ACTIVATION_MODE_ALL
, NULL
);
3164 if (ret
!= NWAM_SUCCESS
)
3171 ret
= listprop(NWAM_OBJECT_TYPE_ENM
, enm_h
,
3172 cmd
->cmd_argv
[0], all_props
, NULL
, -1);
3174 ret
= nwam_walk_enms(list_enm_callback
, &list_msg
,
3175 NWAM_FLAG_ACTIVATION_MODE_ALL
, NULL
);
3177 if (ret
!= NWAM_SUCCESS
)
3184 ret
= listprop(NWAM_OBJECT_TYPE_KNOWN_WLAN
, wlan_h
,
3185 cmd
->cmd_argv
[0], all_props
, NULL
, -1);
3187 ret
= nwam_walk_known_wlans(list_wlan_callback
,
3188 &list_msg
, NWAM_FLAG_KNOWN_WLAN_WALK_PRIORITY_ORDER
,
3191 if (ret
!= NWAM_SUCCESS
)
3196 if (ret
!= NWAM_SUCCESS
)
3197 nwamerr(ret
, "List error");
3201 write_export_command(nwam_object_type_t object_type
, const char *prop
,
3202 nwam_value_t values
, FILE *of
)
3204 /* exclude read-only properties */
3205 if (is_prop_read_only(object_type
, prop
))
3208 (void) fprintf(of
, "set ");
3209 output_propname(prop
, values
, of
);
3214 export_ncu_callback(nwam_ncu_handle_t ncu
, void *arg
)
3218 nwam_ncu_type_t type
;
3219 nwam_ncu_class_t
class;
3228 /* get the NCU's type and class */
3229 if ((ret
= nwam_ncu_get_ncu_type(ncu
, &type
)) != NWAM_SUCCESS
)
3231 if ((ret
= nwam_ncu_get_ncu_class(ncu
, &class)) != NWAM_SUCCESS
)
3234 if ((ret
= nwam_ncu_get_name(ncu
, &name
)) != NWAM_SUCCESS
)
3237 (void) fprintf(of
, "create ncu %s \"%s\"\n",
3238 propval_to_str(NWAM_NCU_PROP_CLASS
, class), name
);
3241 * Because of dependencies between properties, they have to be
3242 * exported in the same order as when they are walked.
3244 if ((ret
= nwam_ncu_get_default_proplist(type
, class, &props
, &num
))
3247 for (i
= 0; i
< num
; i
++) {
3248 ret
= nwam_ncu_get_prop_value(ncu
, props
[i
], &vals
);
3249 if (ret
== NWAM_SUCCESS
) {
3250 write_export_command(NWAM_OBJECT_TYPE_NCU
, props
[i
],
3252 nwam_value_free(vals
);
3255 (void) fprintf(of
, "end\n");
3262 export_ncp_callback(nwam_ncp_handle_t ncp
, void *arg
)
3270 if ((ret
= nwam_ncp_get_name(ncp
, &name
)) != NWAM_SUCCESS
)
3273 /* Do not export "automatic" NCP */
3274 if (NWAM_NCP_AUTOMATIC(name
)) {
3279 (void) fprintf(of
, "create ncp \"%s\"\n", name
);
3282 /* now walk NCUs for this ncp */
3283 ret
= nwam_ncp_walk_ncus(ncp
, export_ncu_callback
, of
,
3284 NWAM_FLAG_NCU_TYPE_CLASS_ALL
, NULL
);
3285 if (ret
!= NWAM_SUCCESS
) {
3286 nwamerr(ret
, "Export ncp error: failed to walk ncus");
3289 (void) fprintf(of
, "end\n");
3294 export_enm_callback(nwam_enm_handle_t enm
, void *arg
)
3306 if ((ret
= nwam_enm_get_name(enm
, &name
)) != NWAM_SUCCESS
)
3309 (void) fprintf(of
, "create enm \"%s\"\n", name
);
3312 * Because of dependencies between properties, they have to be
3313 * exported in the same order as when they are walked.
3315 if ((ret
= nwam_enm_get_default_proplist(&props
, &num
)) != NWAM_SUCCESS
)
3317 for (i
= 0; i
< num
; i
++) {
3318 ret
= nwam_enm_get_prop_value(enm
, props
[i
], &vals
);
3319 if (ret
== NWAM_SUCCESS
) {
3320 write_export_command(NWAM_OBJECT_TYPE_ENM
, props
[i
],
3322 nwam_value_free(vals
);
3325 (void) fprintf(of
, "end\n");
3332 export_loc_callback(nwam_loc_handle_t loc
, void *arg
)
3344 if ((ret
= nwam_loc_get_name(loc
, &name
)) != NWAM_SUCCESS
)
3347 /* Do not export Automatic, NoNet or Legacy locations */
3348 if (NWAM_LOC_NAME_PRE_DEFINED(name
)) {
3353 (void) fprintf(of
, "create loc \"%s\"\n", name
);
3356 * Because of dependencies between properties, they have to be
3357 * exported in the same order as when they are walked.
3359 if ((ret
= nwam_loc_get_default_proplist(&props
, &num
)) != NWAM_SUCCESS
)
3361 for (i
= 0; i
< num
; i
++) {
3362 ret
= nwam_loc_get_prop_value(loc
, props
[i
], &vals
);
3363 if (ret
== NWAM_SUCCESS
) {
3364 write_export_command(NWAM_OBJECT_TYPE_LOC
, props
[i
],
3366 nwam_value_free(vals
);
3369 (void) fprintf(of
, "end\n");
3376 export_wlan_callback(nwam_known_wlan_handle_t wlan
, void *arg
)
3388 if ((ret
= nwam_known_wlan_get_name(wlan
, &name
)) != NWAM_SUCCESS
)
3391 (void) fprintf(of
, "create wlan \"%s\"\n", name
);
3394 * Because of dependencies between properties, they have to be
3395 * exported in the same order as when they are walked.
3397 if ((ret
= nwam_known_wlan_get_default_proplist(&props
, &num
))
3400 for (i
= 0; i
< num
; i
++) {
3401 ret
= nwam_known_wlan_get_prop_value(wlan
, props
[i
], &vals
);
3402 if (ret
== NWAM_SUCCESS
) {
3403 write_export_command(NWAM_OBJECT_TYPE_KNOWN_WLAN
,
3404 props
[i
], vals
, of
);
3405 nwam_value_free(vals
);
3408 (void) fprintf(of
, "end\n");
3415 * Writes configuration to screen or file (with -f option).
3416 * Writes a "destroy -a" if option -d is given.
3419 export_func(cmd_t
*cmd
)
3422 boolean_t need_to_close
= B_FALSE
, write_to_file
= B_FALSE
;
3423 boolean_t add_destroy
= B_FALSE
, lhandle
= B_FALSE
;
3424 char filepath
[MAXPATHLEN
];
3425 nwam_error_t ret
= NWAM_SUCCESS
;
3426 FILE *of
= NULL
; /* either filename or stdout */
3428 /* what to export */
3429 boolean_t export_ncp
= B_FALSE
, export_ncu
= B_FALSE
;
3430 boolean_t export_loc
= B_FALSE
, export_enm
= B_FALSE
;
3431 boolean_t export_wlan
= B_FALSE
;
3434 /* check for -d and -f flags */
3437 while ((c
= getopt(cmd
->cmd_argc
, cmd
->cmd_argv
, "df:")) != EOF
) {
3440 write_to_file
= B_TRUE
;
3443 add_destroy
= B_TRUE
;
3446 command_usage(CMD_EXPORT
);
3451 /* determine where to export */
3452 if (!write_to_file
) {
3456 * If -d was specified with -f, then argv[2] is filename,
3457 * otherwise, argv[1] is filename.
3459 (void) strlcpy(filepath
,
3460 (add_destroy
? cmd
->cmd_argv
[2] : cmd
->cmd_argv
[1]),
3462 if ((of
= fopen(filepath
, "w")) == NULL
) {
3463 nerr(gettext("opening file '%s': %s"), filepath
,
3468 need_to_close
= B_TRUE
;
3472 /* only possible in global scope */
3473 if (current_scope
== NWAM_SCOPE_GBL
) {
3474 (void) fprintf(of
, "destroy -a\n");
3476 nerr("Option -d is not allowed in non-global scope");
3481 /* In the following scopes, only the -f argument is valid */
3482 if (((current_scope
== NWAM_SCOPE_LOC
||
3483 current_scope
== NWAM_SCOPE_ENM
||
3484 current_scope
== NWAM_SCOPE_WLAN
||
3485 current_scope
== NWAM_SCOPE_NCU
) &&
3486 cmd
->cmd_argc
!= 0 && !write_to_file
)) {
3487 nerr("'export' does not take arguments at this scope");
3490 if (current_scope
== NWAM_SCOPE_NCP
) {
3491 if (cmd
->cmd_res1_type
== RT1_ENM
||
3492 cmd
->cmd_res1_type
== RT1_LOC
||
3493 cmd
->cmd_res1_type
== RT1_WLAN
) {
3494 nerr("only ncu can be exported at this scope");
3500 * Determine what objects to export depending on scope and command
3501 * arguments. If -f is specified, then the object name is argv[2].
3502 * Otherwise, argv[0] is name, unless exporting all in global
3503 * scope in which case name is set back to NULL.
3505 switch (current_scope
) {
3506 case NWAM_SCOPE_GBL
:
3507 name
= (write_to_file
? trim_quotes(cmd
->cmd_argv
[2]) :
3508 trim_quotes(cmd
->cmd_argv
[0]));
3509 switch (cmd
->cmd_res1_type
) {
3511 export_loc
= B_TRUE
;
3514 export_enm
= B_TRUE
;
3517 export_wlan
= B_TRUE
;
3520 export_ncp
= B_TRUE
;
3521 if (cmd
->cmd_res2_type
== RT2_NCU
) {
3522 nerr("cannot export ncu at from global scope");
3527 /* export everything */
3528 export_loc
= B_TRUE
;
3529 export_enm
= B_TRUE
;
3530 export_wlan
= B_TRUE
;
3531 export_ncp
= B_TRUE
; /* NCP will export the NCUs */
3533 name
= NULL
; /* exporting all, undo name */
3537 case NWAM_SCOPE_LOC
:
3538 export_loc
= B_TRUE
;
3539 ret
= nwam_loc_get_name(loc_h
, &name
);
3540 if (ret
!= NWAM_SUCCESS
)
3543 case NWAM_SCOPE_ENM
:
3544 export_enm
= B_TRUE
;
3545 ret
= nwam_enm_get_name(enm_h
, &name
);
3546 if (ret
!= NWAM_SUCCESS
)
3549 case NWAM_SCOPE_WLAN
:
3550 export_wlan
= B_TRUE
;
3551 ret
= nwam_known_wlan_get_name(wlan_h
, &name
);
3552 if (ret
!= NWAM_SUCCESS
)
3555 case NWAM_SCOPE_NCP
:
3556 if (cmd
->cmd_res2_type
== RT2_NCU
) {
3557 export_ncu
= B_TRUE
;
3558 name
= (write_to_file
? trim_quotes(cmd
->cmd_argv
[2]) :
3559 trim_quotes(cmd
->cmd_argv
[0]));
3561 export_ncp
= B_TRUE
;
3562 ret
= nwam_ncp_get_name(ncp_h
, &name
);
3563 if (ret
!= NWAM_SUCCESS
)
3567 case NWAM_SCOPE_NCU
:
3568 export_ncu
= B_TRUE
;
3569 ret
= nwam_ncu_get_name(ncu_h
, &name
);
3570 if (ret
!= NWAM_SUCCESS
)
3574 nerr("Invalid scope");
3578 /* Now, export objects according to the flags set */
3582 /* export all NCPs */
3583 ret
= nwam_walk_ncps(export_ncp_callback
, of
, 0, NULL
);
3584 } else if (NWAM_NCP_AUTOMATIC(name
)) {
3585 nerr("'%s' ncp cannot be exported", name
);
3588 if (ncp_h
== NULL
) {
3589 ret
= nwam_ncp_read(name
, 0, &ncp_h
);
3590 if (ret
!= NWAM_SUCCESS
)
3594 /* will export NCUs also */
3595 ret
= export_ncp_callback(ncp_h
, of
);
3597 nwam_ncp_free(ncp_h
);
3601 if (ret
!= NWAM_SUCCESS
)
3607 /* export all NCUs */
3608 ret
= nwam_ncp_walk_ncus(ncp_h
, export_ncu_callback
, of
,
3609 NWAM_FLAG_NCU_TYPE_CLASS_ALL
, NULL
);
3611 if (ncu_h
== NULL
) {
3612 /* no NCU handle -> called from NCP scope */
3613 nwam_ncu_type_t ncu_type
;
3614 nwam_ncu_class_t ncu_class
;
3616 ncu_class
= (nwam_ncu_class_t
)
3617 cmd
->cmd_ncu_class_type
;
3618 ncu_type
= nwam_ncu_class_to_type(ncu_class
);
3619 ret
= nwam_ncu_read(ncp_h
, name
,
3620 ncu_type
, 0, &ncu_h
);
3621 if (ret
== NWAM_SUCCESS
) {
3622 /* one NCU with given name */
3623 ret
= export_ncu_callback(ncu_h
, of
);
3624 nwam_ncu_free(ncu_h
);
3626 } else if (ret
== NWAM_ENTITY_MULTIPLE_VALUES
) {
3627 /* multiple NCUs with given name */
3628 ret
= nwam_ncu_read(ncp_h
, name
,
3629 NWAM_NCU_TYPE_LINK
, 0, &ncu_h
);
3630 if (ret
!= NWAM_SUCCESS
)
3632 ret
= export_ncu_callback(ncu_h
, of
);
3633 nwam_ncu_free(ncu_h
);
3636 ret
= nwam_ncu_read(ncp_h
, name
,
3637 NWAM_NCU_TYPE_INTERFACE
, 0, &ncu_h
);
3638 if (ret
!= NWAM_SUCCESS
)
3640 ret
= export_ncu_callback(ncu_h
, of
);
3641 nwam_ncu_free(ncu_h
);
3647 /* NCU handle exists */
3648 ret
= export_ncu_callback(ncu_h
, of
);
3651 if (ret
!= NWAM_SUCCESS
)
3658 /* export all locations */
3659 ret
= nwam_walk_locs(export_loc_callback
, of
,
3660 NWAM_FLAG_ACTIVATION_MODE_ALL
, NULL
);
3661 } else if (NWAM_LOC_NAME_PRE_DEFINED(name
)) {
3662 nerr("'%s' loc cannot be exported", name
);
3665 if (loc_h
== NULL
) {
3666 ret
= nwam_loc_read(name
, 0, &loc_h
);
3667 if (ret
!= NWAM_SUCCESS
)
3671 ret
= export_loc_callback(loc_h
, of
);
3673 nwam_loc_free(loc_h
);
3677 if (ret
!= NWAM_SUCCESS
)
3684 /* export all ENMs */
3685 ret
= nwam_walk_enms(export_enm_callback
, of
,
3686 NWAM_FLAG_ACTIVATION_MODE_ALL
, NULL
);
3688 if (enm_h
== NULL
) {
3689 ret
= nwam_enm_read(name
, 0, &enm_h
);
3690 if (ret
!= NWAM_SUCCESS
)
3694 ret
= export_enm_callback(enm_h
, of
);
3696 nwam_enm_free(enm_h
);
3700 if (ret
!= NWAM_SUCCESS
)
3707 /* export all WLANs */
3708 ret
= nwam_walk_known_wlans(export_wlan_callback
, of
,
3709 NWAM_FLAG_KNOWN_WLAN_WALK_PRIORITY_ORDER
, NULL
);
3711 if (wlan_h
== NULL
) {
3712 ret
= nwam_known_wlan_read(name
, 0,
3714 if (ret
!= NWAM_SUCCESS
)
3718 ret
= export_wlan_callback(wlan_h
, of
);
3720 nwam_known_wlan_free(wlan_h
);
3724 if (ret
!= NWAM_SUCCESS
)
3730 if (ret
!= NWAM_SUCCESS
)
3731 nwamerr(ret
, "Export error");
3739 * Get property value. If the -V option is specified, only the value is
3740 * printed without the property name.
3743 get_func(cmd_t
*cmd
)
3745 nwam_error_t ret
= NWAM_SUCCESS
;
3746 nwam_value_t prop_value
;
3748 boolean_t value_only
= B_FALSE
;
3749 nwam_object_type_t object_type
= active_object_type();
3751 /* check if option is -V to print value only */
3752 if (cmd
->cmd_argc
== 1) {
3756 while ((c
= getopt(cmd
->cmd_argc
, cmd
->cmd_argv
, "V")) != EOF
) {
3759 value_only
= B_TRUE
;
3762 command_usage(CMD_GET
);
3768 /* property to get is in cmd->cmd_prop_type */
3769 if ((prop
= pt_to_prop_name(object_type
, cmd
->cmd_prop_type
)) == NULL
) {
3770 nerr("Get error: invalid %s property: '%s'",
3771 scope_to_str(current_scope
), pt_to_str(cmd
->cmd_prop_type
));
3775 switch (object_type
) {
3776 case NWAM_OBJECT_TYPE_NCU
:
3777 ret
= nwam_ncu_get_prop_value(ncu_h
, prop
, &prop_value
);
3779 case NWAM_OBJECT_TYPE_LOC
:
3780 ret
= nwam_loc_get_prop_value(loc_h
, prop
, &prop_value
);
3782 case NWAM_OBJECT_TYPE_ENM
:
3783 ret
= nwam_enm_get_prop_value(enm_h
, prop
, &prop_value
);
3785 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
3786 ret
= nwam_known_wlan_get_prop_value(wlan_h
, prop
, &prop_value
);
3790 if (ret
!= NWAM_SUCCESS
) {
3791 if (ret
== NWAM_ENTITY_NOT_FOUND
)
3792 nerr("Get error: property '%s' has not been set", prop
);
3794 nwamerr(ret
, "Get error");
3799 output_prop_val(prop
, prop_value
, stdout
, B_FALSE
);
3800 (void) printf("\n");
3802 output_propname(prop
, prop_value
, NULL
);
3804 nwam_value_free(prop_value
);
3808 * Clears value of a property.
3809 * Read-only properties cannot be cleared.
3810 * If clearing a property invalidates the object, then that property
3811 * cannot be cleared.
3814 clear_func(cmd_t
*cmd
)
3818 nwam_object_type_t object_type
= active_object_type();
3820 /* property to clear is in cmd->cmd_prop_type */
3821 if ((prop
= pt_to_prop_name(object_type
, cmd
->cmd_prop_type
)) == NULL
) {
3822 nerr("Clear error: invalid %s property: '%s'",
3823 scope_to_str(current_scope
), pt_to_str(cmd
->cmd_prop_type
));
3826 if (is_prop_read_only(object_type
, prop
)) {
3827 nerr("Clear error: property '%s' is read-only", prop
);
3831 switch (object_type
) {
3832 case NWAM_OBJECT_TYPE_NCU
:
3833 ret
= nwam_ncu_delete_prop(ncu_h
, prop
);
3835 case NWAM_OBJECT_TYPE_LOC
:
3836 ret
= nwam_loc_delete_prop(loc_h
, prop
);
3838 case NWAM_OBJECT_TYPE_ENM
:
3839 ret
= nwam_enm_delete_prop(enm_h
, prop
);
3841 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
3842 ret
= nwam_known_wlan_delete_prop(wlan_h
, prop
);
3846 if (ret
!= NWAM_SUCCESS
) {
3847 if (ret
== NWAM_INVALID_ARG
|| ret
== NWAM_ENTITY_NOT_FOUND
) {
3848 nerr("Clear error: property '%s' has not been set",
3851 nwamerr(ret
, "Clear error");
3856 need_to_commit
= B_TRUE
;
3860 * Prints all the choices available for an enum property [c1|c2|c3].
3861 * Prints [true|false] for a boolean property.
3864 print_all_prop_choices(nwam_object_type_t object_type
, const char *prop
)
3868 boolean_t choices
= B_FALSE
;
3869 nwam_value_type_t value_type
;
3872 /* Special case: print object-specific options for activation-mode */
3873 if (strcmp(prop
, NWAM_NCU_PROP_ACTIVATION_MODE
) == 0) {
3874 /* "manual" for all objects */
3875 (void) printf(" [%s|",
3876 propval_to_str(NWAM_NCU_PROP_ACTIVATION_MODE
,
3877 NWAM_ACTIVATION_MODE_MANUAL
));
3878 if (object_type
== NWAM_OBJECT_TYPE_NCU
) {
3879 (void) printf("%s]",
3880 propval_to_str(NWAM_NCU_PROP_ACTIVATION_MODE
,
3881 NWAM_ACTIVATION_MODE_PRIORITIZED
));
3883 (void) printf("%s|%s]",
3884 propval_to_str(NWAM_NCU_PROP_ACTIVATION_MODE
,
3885 NWAM_ACTIVATION_MODE_CONDITIONAL_ANY
),
3886 propval_to_str(NWAM_NCU_PROP_ACTIVATION_MODE
,
3887 NWAM_ACTIVATION_MODE_CONDITIONAL_ALL
));
3892 /* Special case: only "manual" configsrc is allowed for LDAP */
3893 if (strcmp(prop
, NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
) == 0) {
3894 (void) printf(" [%s]",
3895 propval_to_str(NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
,
3896 NWAM_CONFIGSRC_MANUAL
));
3900 value_type
= prop_value_type(object_type
, prop
);
3901 switch (value_type
) {
3902 case NWAM_VALUE_TYPE_UINT64
:
3903 /* uint64 may be an enum, will print nothing if not an enum */
3904 while ((ret
= nwam_uint64_get_value_string(prop
, i
++, &str
))
3905 == NWAM_SUCCESS
|| ret
== NWAM_ENTITY_INVALID_VALUE
) {
3906 /* No string representation for i, continue. */
3907 if (ret
== NWAM_ENTITY_INVALID_VALUE
)
3911 (void) printf("%s", " [");
3912 (void) printf("%s%s", choices
? "|" : "", str
);
3916 (void) putchar(']');
3918 case NWAM_VALUE_TYPE_BOOLEAN
:
3919 (void) printf(" [%s|%s]", "true", "false");
3921 case NWAM_VALUE_TYPE_STRING
:
3927 * Walk through object properties.
3928 * For newly-created object, the property name with no value is displayed, and
3929 * the user can input a value for each property.
3930 * For existing object, the current value is displayed and user input overwrites
3931 * the existing one. If no input is given, the existing value remains.
3932 * Read-only properties are not displayed.
3933 * Read-only objects cannot be walked.
3934 * If the -a option is specified, no properties are skipped.
3937 walkprop_func(cmd_t
*cmd
)
3939 nwam_error_t ret
= NWAM_SUCCESS
;
3940 nwam_value_t vals
= NULL
; /* freed in _wait_input() */
3944 boolean_t read_only
= B_FALSE
, all_props
= B_FALSE
;
3946 nwam_object_type_t object_type
;
3947 prop_display_entry_t
*prop_table
;
3949 if (!interactive_mode
) {
3950 nerr("'walkprop' is only allowed in interactive mode");
3954 /* check if option -a is specified to show all properties */
3955 if (cmd
->cmd_argc
== 1) {
3958 while ((c
= getopt(cmd
->cmd_argc
, cmd
->cmd_argv
, "a")) != EOF
) {
3964 command_usage(CMD_WALKPROP
);
3970 /* read-only objects cannot be walked */
3971 if (obj1_type
== RT1_NCP
) {
3972 /* must be in NCU scope, NCP scope doesn't get here */
3973 (void) nwam_ncu_get_read_only(ncu_h
, &read_only
);
3976 nerr("'walkprop' cannot be used in read-only objects");
3980 /* get the current object type and the prop_display_table */
3981 object_type
= active_object_type();
3982 prop_table
= get_prop_display_table(object_type
);
3984 /* get the property list depending on the object type */
3985 switch (object_type
) {
3986 case NWAM_OBJECT_TYPE_NCU
:
3988 nwam_ncu_type_t ncu_type
;
3989 nwam_ncu_class_t ncu_class
;
3991 if ((ret
= nwam_ncu_get_ncu_type(ncu_h
, &ncu_type
))
3994 if ((ret
= nwam_ncu_get_ncu_class(ncu_h
, &ncu_class
))
3998 ret
= nwam_ncu_get_default_proplist(ncu_type
, ncu_class
, &props
,
4002 case NWAM_OBJECT_TYPE_LOC
:
4003 ret
= nwam_loc_get_default_proplist(&props
, &prop_num
);
4005 case NWAM_OBJECT_TYPE_ENM
:
4006 ret
= nwam_enm_get_default_proplist(&props
, &prop_num
);
4008 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
4009 ret
= nwam_known_wlan_get_default_proplist(&props
, &prop_num
);
4012 if (ret
!= NWAM_SUCCESS
) {
4013 nwamerr(ret
, "Walkprop error: could not get property list");
4017 /* Loop through the properties */
4019 (void) printf(gettext("Walking all properties ...\n"));
4020 for (i
= 0; i
< prop_num
; i
++) {
4021 char line
[NWAM_MAX_VALUE_LEN
];
4022 char **checked
= NULL
;
4024 /* check if this property should be displayed */
4025 if (is_prop_read_only(object_type
, props
[i
]))
4028 !show_prop_test(object_type
, props
[i
], prop_table
,
4032 /* get the existing value for this property */
4033 switch (object_type
) {
4034 case NWAM_OBJECT_TYPE_NCU
:
4035 ret
= nwam_ncu_get_prop_value(ncu_h
, props
[i
], &vals
);
4037 case NWAM_OBJECT_TYPE_LOC
:
4038 ret
= nwam_loc_get_prop_value(loc_h
, props
[i
], &vals
);
4040 case NWAM_OBJECT_TYPE_ENM
:
4041 ret
= nwam_enm_get_prop_value(enm_h
, props
[i
], &vals
);
4043 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
4044 ret
= nwam_known_wlan_get_prop_value(wlan_h
, props
[i
],
4048 /* returns NWAM_ENTITY_NOT_FOUND if no existing value */
4049 if (ret
!= NWAM_SUCCESS
&& ret
!= NWAM_ENTITY_NOT_FOUND
)
4052 /* print property */
4053 (void) printf("%s", props
[i
]);
4054 /* print the existing value(s) if they exist */
4055 if (ret
== NWAM_SUCCESS
) {
4056 (void) printf(" (");
4057 output_prop_val(props
[i
], vals
, stdout
, B_TRUE
);
4058 (void) putchar(')');
4059 nwam_value_free(vals
);
4061 /* print choices, won't print anything if there aren't any */
4062 print_all_prop_choices(object_type
, props
[i
]);
4063 (void) printf("> ");
4065 /* wait for user input */
4066 if (fgets(line
, sizeof (line
), stdin
) == NULL
)
4069 /* if user input new value, existing value is overrode */
4070 if (line
[0] != '\n') {
4071 boolean_t is_listprop
;
4072 int pt_type
= prop_to_pt(object_type
, props
[i
]);
4074 is_listprop
= is_prop_multivalued(object_type
,
4076 vals
= str_to_nwam_value(object_type
, line
, pt_type
,
4079 ret
= NWAM_ENTITY_INVALID_VALUE
;
4083 /* set the new value for the property */
4084 switch (object_type
) {
4085 case NWAM_OBJECT_TYPE_NCU
:
4086 ret
= nwam_ncu_set_prop_value(ncu_h
, props
[i
],
4089 case NWAM_OBJECT_TYPE_LOC
:
4090 ret
= nwam_loc_set_prop_value(loc_h
, props
[i
],
4093 case NWAM_OBJECT_TYPE_ENM
:
4094 ret
= nwam_enm_set_prop_value(enm_h
, props
[i
],
4097 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
4098 ret
= nwam_known_wlan_set_prop_value(wlan_h
,
4102 nwam_value_free(vals
);
4104 if (ret
!= NWAM_SUCCESS
)
4107 need_to_commit
= B_TRUE
;
4111 invalid_set_prop_msg(props
[i
], ret
);
4112 i
--; /* decrement i to repeat */
4120 * Verify whether all properties of a resource are valid.
4124 verify_func(cmd_t
*cmd
)
4127 const char *errprop
;
4129 switch (active_object_type()) {
4130 case NWAM_OBJECT_TYPE_NCU
:
4131 ret
= nwam_ncu_validate(ncu_h
, &errprop
);
4133 case NWAM_OBJECT_TYPE_LOC
:
4134 ret
= nwam_loc_validate(loc_h
, &errprop
);
4136 case NWAM_OBJECT_TYPE_ENM
:
4137 ret
= nwam_enm_validate(enm_h
, &errprop
);
4139 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
4140 ret
= nwam_known_wlan_validate(wlan_h
, &errprop
);
4143 if (ret
!= NWAM_SUCCESS
)
4144 nwamerr(ret
, "Verify error on property '%s'", errprop
);
4145 else if (interactive_mode
)
4146 (void) printf(gettext("All properties verified\n"));
4150 * command-line mode (# nwamcfg list or # nwamcfg "select loc test; list")
4153 one_command_at_a_time(int argc
, char *argv
[])
4156 size_t len
= 2; /* terminal \n\0 */
4159 for (i
= 0; i
< argc
; i
++)
4160 len
+= strlen(argv
[i
]) + 1;
4161 if ((command
= malloc(len
)) == NULL
) {
4162 nerr("Out of memory");
4165 (void) strlcpy(command
, argv
[0], len
);
4166 for (i
= 1; i
< argc
; i
++) {
4167 (void) strlcat(command
, " ", len
);
4168 (void) strlcat(command
, argv
[i
], len
);
4170 (void) strlcat(command
, "\n", len
);
4171 err
= string_to_yyin(command
);
4175 while (!feof(yyin
)) {
4179 * If any command on a list of commands give an error,
4180 * don't continue with the remaining commands.
4182 if (saw_error
|| time_to_exit
)
4186 /* if there are changes to commit, commit it */
4187 if (need_to_commit
) {
4189 /* if need_to_commit is not set, then there was a error */
4194 if (!interactive_mode
)
4198 return (read_input());
4203 * cmd_file is slightly more complicated, as it has to open the command file
4204 * and set yyin appropriately. Once that is done, though, it just calls
4205 * read_input(), and only once, since prompting is not possible.
4208 cmd_file(char *file
)
4212 struct stat statbuf
;
4213 boolean_t using_real_file
= (strcmp(file
, "-") != 0);
4215 if (using_real_file
) {
4217 * nerr() prints a line number in cmd_file_mode, which we do
4218 * not want here, so temporarily unset it.
4220 cmd_file_mode
= B_FALSE
;
4221 if ((infile
= fopen(file
, "r")) == NULL
) {
4222 nerr(gettext("could not open file '%s': %s"),
4223 file
, strerror(errno
));
4226 if ((err
= fstat(fileno(infile
), &statbuf
)) != 0) {
4227 nerr(gettext("could not stat file '%s': %s"),
4228 file
, strerror(errno
));
4232 if (!S_ISREG(statbuf
.st_mode
)) {
4233 nerr(gettext("'%s' is not a regular file."), file
);
4239 * If -d was passed on the command-line, we need to
4240 * start by removing any existing configuration.
4241 * Alternatively, the file may begin with 'destroy -a';
4242 * but in that case, the line will go through the lexer
4243 * and be processed as it's encountered in the file.
4245 if (remove_all_configurations
&& destroy_all() != NWAM_SUCCESS
)
4248 /* set up for lexer */
4250 cmd_file_mode
= B_TRUE
;
4251 ok_to_prompt
= B_FALSE
;
4254 * "-f -" is essentially the same as interactive mode,
4255 * so treat it that way.
4257 interactive_mode
= B_TRUE
;
4259 /* NWAM_REPEAT is for interactive mode; treat it like NWAM_ERR here. */
4260 if ((err
= read_input()) == NWAM_REPEAT
)
4263 (void) printf(gettext("Configuration read.\n"));
4266 if (using_real_file
)
4267 (void) fclose(infile
);
4272 main(int argc
, char *argv
[])
4277 /* This must be before anything goes to stdout. */
4278 setbuf(stdout
, NULL
);
4280 if ((execname
= strrchr(argv
[0], '/')) == NULL
)
4285 (void) setlocale(LC_ALL
, "");
4286 (void) textdomain(TEXT_DOMAIN
);
4288 while ((c
= getopt(argc
, argv
, "?hf:d")) != EOF
) {
4291 cmd_file_name
= optarg
;
4292 cmd_file_mode
= B_TRUE
;
4299 remove_all_configurations
= B_TRUE
;
4306 /* -d can only be used with -f */
4307 if (remove_all_configurations
&& !cmd_file_mode
) {
4308 nerr("Option -d can only be used with -f");
4313 * This may get set back to FALSE again in cmd_file() if cmd_file_name
4314 * is a "real" file as opposed to "-" (i.e. meaning use stdin).
4316 if (isatty(STDIN_FILENO
))
4317 ok_to_prompt
= B_TRUE
;
4318 if ((gl
= new_GetLine(MAX_LINE_LEN
, MAX_CMD_HIST
)) == NULL
)
4320 if (gl_customize_completion(gl
, NULL
, cmd_cpl_fn
) != 0)
4322 (void) sigset(SIGINT
, SIG_IGN
);
4324 if (optind
== argc
) {
4325 /* interactive or command-file mode */
4327 err
= do_interactive();
4329 err
= cmd_file(cmd_file_name
);
4331 /* command-line mode */
4332 err
= one_command_at_a_time(argc
- optind
, &(argv
[optind
]));
4334 (void) del_GetLine(gl
);