Print this page
7388 Support DHCP Client FQDN. Allow IAID/DUID for all v4.
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/cmd-inet/usr.sbin/nwamcfg/nwamcfg.c
+++ new/usr/src/cmd/cmd-inet/usr.sbin/nwamcfg/nwamcfg.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 + * Copyright (c) 2016, Chris Fraire <cfraire@me.com>.
24 25 */
25 26
26 27 /*
27 28 * nwamcfg is a lex/yacc based command interpreter used to manage network
28 29 * configurations. The lexer (see nwamcfg_lex.l) builds up tokens, which
29 30 * the grammar (see nwamcfg_grammar.y) builds up into commands, some of
30 31 * which takes resources and/or properties as arguments.
31 32 */
32 33
33 34 #include <arpa/inet.h>
34 35 #include <assert.h>
35 36 #include <ctype.h>
36 37 #include <errno.h>
37 38 #include <libnwam.h>
38 39 #include <libtecla.h>
39 40 #include <locale.h>
40 41 #include <stdarg.h>
41 42 #include <stdio.h>
42 43 #include <string.h>
43 44 #include <sys/stat.h>
44 45 #include <sys/sysmacros.h>
45 46 #include <sys/types.h>
46 47 #include <unistd.h>
47 48
48 49 #include "nwamcfg.h"
49 50
50 51 #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */
51 52 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
52 53 #endif
53 54
54 55 struct help {
55 56 uint_t cmd_num;
56 57 const char *cmd_name;
57 58 const char *cmd_usage;
58 59 };
59 60
60 61 extern int yyparse(void);
61 62 extern int lex_lineno;
62 63
63 64 #define MAX_LINE_LEN 1024
64 65 #define MAX_CMD_HIST 1024
65 66
66 67 /* usage of commands */
67 68 #define SHELP_CANCEL "cancel"
68 69 #define SHELP_CLEAR "clear <prop-name>"
69 70 #define SHELP_COMMIT "commit"
70 71 #define SHELP_CREATE "create [-t <template>] <object-type> [<class>] " \
71 72 "<object-name>"
72 73 #define SHELP_DESTROY "destroy {-a | <object-type> [<class>] <object-name>}"
73 74 #define SHELP_END "end"
74 75 #define SHELP_EXIT "exit"
75 76 #define SHELP_EXPORT "export [-d] [-f <output-file>] " \
76 77 "[<object-type> [<class>] <object-name>]"
77 78 #define SHELP_GET "get [-V] <prop-name>"
78 79 #define SHELP_HELP "help [command-name]"
79 80 #define SHELP_LIST "list [-a] [<object-type> [<class>] <object-name>]"
80 81 #define SHELP_REVERT "revert"
81 82 #define SHELP_SELECT "select <object-type> [<class>] <object-name>"
82 83 #define SHELP_SET "set <prop-name>=<value1>[,<value2>...]"
83 84 #define SHELP_VERIFY "verify"
84 85 #define SHELP_WALK "walkprop [-a]"
85 86
86 87 /*
87 88 * Scope Definitions:
88 89 * Locations, ENMs, NCPs and Known WLANs are one scope level below global (GBL).
89 90 * NCUs are one more level beneath the NCP scope.
90 91 * Because the commands in Locations/ENM/Known WLAN and NCP level are different,
91 92 * the scope are divided accordingly.
92 93 * GBL->LOC, GBL->ENM, GBL->WLAN or GBL->NCP->NCU
93 94 */
94 95 #define NWAM_SCOPE_GBL 0
95 96 #define NWAM_SCOPE_LOC 1
96 97 #define NWAM_SCOPE_ENM 2
97 98 #define NWAM_SCOPE_WLAN 3
98 99 #define NWAM_SCOPE_NCP 4
99 100 #define NWAM_SCOPE_NCU 5
100 101
101 102 /* delimiter used for list of values */
102 103 #define NWAM_VALUE_DELIMITER_CHAR ','
103 104 #define NWAM_VALUE_DELIMITER_STR ","
104 105
105 106 /* the max number of values for an enum used by some properties in libnwam */
106 107
107 108 /*
108 109 * All arrays/tables are null-terminated, rather than defining the length of
109 110 * the array. When looping, check for NULL rather than using the size.
110 111 */
111 112
112 113 static struct help helptab[] = {
113 114 { CMD_CANCEL, "cancel", SHELP_CANCEL },
114 115 { CMD_CLEAR, "clear", SHELP_CLEAR },
115 116 { CMD_COMMIT, "commit", SHELP_COMMIT },
116 117 { CMD_CREATE, "create", SHELP_CREATE },
117 118 { CMD_DESTROY, "destroy", SHELP_DESTROY },
118 119 { CMD_END, "end", SHELP_END },
119 120 { CMD_EXIT, "exit", SHELP_EXIT },
120 121 { CMD_EXPORT, "export", SHELP_EXPORT },
121 122 { CMD_GET, "get", SHELP_GET },
122 123 { CMD_HELP, "help", SHELP_HELP },
123 124 { CMD_LIST, "list", SHELP_LIST },
124 125 { CMD_REVERT, "revert", SHELP_REVERT },
125 126 { CMD_SELECT, "select", SHELP_SELECT },
126 127 { CMD_SET, "set", SHELP_SET },
127 128 { CMD_VERIFY, "verify", SHELP_VERIFY },
128 129 { CMD_WALKPROP, "walkprop", SHELP_WALK },
129 130 { 0, NULL, NULL }
130 131 };
131 132
132 133 /* These *must* match the order of the RT1_ define's from nwamcfg.h */
133 134 static char *res1_types[] = {
134 135 "unknown",
135 136 "loc",
136 137 "ncp",
137 138 "enm",
138 139 "wlan",
139 140 NULL
140 141 };
141 142
142 143 /* These *must* match the order of the RT2_ define's from nwamcfg.h */
143 144 static char *res2_types[] = {
144 145 "unknown",
145 146 "ncu",
146 147 NULL
147 148 };
148 149
149 150 /*
150 151 * No array for NCU_CLASS_. The #define's in nwamcfg.h matches the
151 152 * enum nwam_ncu_class_t in libnwam and thus uses libnwam functions to
152 153 * retrieve the string representation.
153 154 */
154 155
155 156 /* These *MUST* match the order of the PT_ define's from nwamcfg.h */
156 157 static char *pt_types[] = {
157 158 "unknown",
158 159 NWAM_NCU_PROP_ACTIVATION_MODE,
159 160 NWAM_NCU_PROP_ENABLED,
160 161 NWAM_NCU_PROP_TYPE,
161 162 NWAM_NCU_PROP_CLASS,
162 163 NWAM_NCU_PROP_PARENT_NCP,
163 164 NWAM_NCU_PROP_PRIORITY_GROUP,
164 165 NWAM_NCU_PROP_PRIORITY_MODE,
165 166 NWAM_NCU_PROP_LINK_MAC_ADDR,
166 167 NWAM_NCU_PROP_LINK_AUTOPUSH,
167 168 NWAM_NCU_PROP_LINK_MTU,
168 169 NWAM_NCU_PROP_IP_VERSION,
169 170 NWAM_NCU_PROP_IPV4_ADDRSRC,
170 171 NWAM_NCU_PROP_IPV4_ADDR,
171 172 NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE,
172 173 NWAM_NCU_PROP_IPV6_ADDRSRC,
173 174 NWAM_NCU_PROP_IPV6_ADDR,
174 175 NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE,
175 176 NWAM_LOC_PROP_CONDITIONS,
176 177 NWAM_ENM_PROP_FMRI,
177 178 NWAM_ENM_PROP_START,
178 179 NWAM_ENM_PROP_STOP,
179 180 NWAM_LOC_PROP_NAMESERVICES,
180 181 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE,
181 182 NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC,
182 183 NWAM_LOC_PROP_DNS_NAMESERVICE_DOMAIN,
183 184 NWAM_LOC_PROP_DNS_NAMESERVICE_SERVERS,
184 185 NWAM_LOC_PROP_DNS_NAMESERVICE_SEARCH,
185 186 NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC,
186 187 NWAM_LOC_PROP_NIS_NAMESERVICE_SERVERS,
187 188 NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC,
188 189 NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS,
189 190 NWAM_LOC_PROP_DEFAULT_DOMAIN,
190 191 NWAM_LOC_PROP_NFSV4_DOMAIN,
|
↓ open down ↓ |
157 lines elided |
↑ open up ↑ |
191 192 NWAM_LOC_PROP_IPFILTER_CONFIG_FILE,
192 193 NWAM_LOC_PROP_IPFILTER_V6_CONFIG_FILE,
193 194 NWAM_LOC_PROP_IPNAT_CONFIG_FILE,
194 195 NWAM_LOC_PROP_IPPOOL_CONFIG_FILE,
195 196 NWAM_LOC_PROP_IKE_CONFIG_FILE,
196 197 NWAM_LOC_PROP_IPSECPOLICY_CONFIG_FILE,
197 198 NWAM_KNOWN_WLAN_PROP_BSSIDS,
198 199 NWAM_KNOWN_WLAN_PROP_PRIORITY,
199 200 NWAM_KNOWN_WLAN_PROP_KEYNAME,
200 201 NWAM_KNOWN_WLAN_PROP_KEYSLOT,
201 - NWAM_KNOWN_WLAN_PROP_SECURITY_MODE
202 + NWAM_KNOWN_WLAN_PROP_SECURITY_MODE,
203 + NWAM_NCU_PROP_IP_PRIMARY,
204 + NWAM_NCU_PROP_IP_REQHOST
202 205 };
203 206
204 207 /* properties table: maps PT_* constants to property names */
205 208 typedef struct prop_table_entry {
206 209 int pte_type;
207 210 const char *pte_name;
208 211 } prop_table_entry_t;
209 212
210 213 /* NCU properties table */
211 214 static prop_table_entry_t ncu_prop_table[] = {
212 215 { PT_TYPE, NWAM_NCU_PROP_TYPE },
213 216 { PT_CLASS, NWAM_NCU_PROP_CLASS },
214 217 { PT_PARENT, NWAM_NCU_PROP_PARENT_NCP },
215 218 { PT_ACTIVATION_MODE, NWAM_NCU_PROP_ACTIVATION_MODE },
216 219 { PT_ENABLED, NWAM_NCU_PROP_ENABLED },
217 220 { PT_PRIORITY_GROUP, NWAM_NCU_PROP_PRIORITY_GROUP },
218 221 { PT_PRIORITY_MODE, NWAM_NCU_PROP_PRIORITY_MODE },
|
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
219 222 { PT_LINK_MACADDR, NWAM_NCU_PROP_LINK_MAC_ADDR },
220 223 { PT_LINK_AUTOPUSH, NWAM_NCU_PROP_LINK_AUTOPUSH },
221 224 { PT_LINK_MTU, NWAM_NCU_PROP_LINK_MTU },
222 225 { PT_IP_VERSION, NWAM_NCU_PROP_IP_VERSION },
223 226 { PT_IPV4_ADDRSRC, NWAM_NCU_PROP_IPV4_ADDRSRC },
224 227 { PT_IPV4_ADDR, NWAM_NCU_PROP_IPV4_ADDR },
225 228 { PT_IPV4_DEFAULT_ROUTE, NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE },
226 229 { PT_IPV6_ADDRSRC, NWAM_NCU_PROP_IPV6_ADDRSRC },
227 230 { PT_IPV6_ADDR, NWAM_NCU_PROP_IPV6_ADDR },
228 231 { PT_IPV6_DEFAULT_ROUTE, NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE },
232 + { PT_IP_PRIMARY, NWAM_NCU_PROP_IP_PRIMARY },
233 + { PT_IP_REQHOST, NWAM_NCU_PROP_IP_REQHOST },
229 234 { 0, NULL }
230 235 };
231 236
232 237 /* ENM properties table */
233 238 static prop_table_entry_t enm_prop_table[] = {
234 239 { PT_ENM_FMRI, NWAM_ENM_PROP_FMRI },
235 240 { PT_ENM_START, NWAM_ENM_PROP_START },
236 241 { PT_ENM_STOP, NWAM_ENM_PROP_STOP },
237 242 { PT_ACTIVATION_MODE, NWAM_ENM_PROP_ACTIVATION_MODE },
238 243 { PT_CONDITIONS, NWAM_ENM_PROP_CONDITIONS },
239 244 { PT_ENABLED, NWAM_ENM_PROP_ENABLED },
240 245 { 0, NULL }
241 246 };
242 247
243 248 /* LOCation properties table */
244 249 static prop_table_entry_t loc_prop_table[] = {
245 250 { PT_ACTIVATION_MODE, NWAM_LOC_PROP_ACTIVATION_MODE },
246 251 { PT_CONDITIONS, NWAM_LOC_PROP_CONDITIONS },
247 252 { PT_ENABLED, NWAM_LOC_PROP_ENABLED },
248 253 { PT_LOC_NAMESERVICES, NWAM_LOC_PROP_NAMESERVICES },
249 254 { PT_LOC_NAMESERVICES_CONFIG, NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE },
250 255 { PT_LOC_DNS_CONFIGSRC, NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC },
251 256 { PT_LOC_DNS_DOMAIN, NWAM_LOC_PROP_DNS_NAMESERVICE_DOMAIN },
252 257 { PT_LOC_DNS_SERVERS, NWAM_LOC_PROP_DNS_NAMESERVICE_SERVERS },
253 258 { PT_LOC_DNS_SEARCH, NWAM_LOC_PROP_DNS_NAMESERVICE_SEARCH },
254 259 { PT_LOC_NIS_CONFIGSRC, NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC },
255 260 { PT_LOC_NIS_SERVERS, NWAM_LOC_PROP_NIS_NAMESERVICE_SERVERS },
256 261 { PT_LOC_LDAP_CONFIGSRC, NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC },
257 262 { PT_LOC_LDAP_SERVERS, NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS },
258 263 { PT_LOC_DEFAULT_DOMAIN, NWAM_LOC_PROP_DEFAULT_DOMAIN },
259 264 { PT_LOC_NFSV4_DOMAIN, NWAM_LOC_PROP_NFSV4_DOMAIN },
260 265 { PT_LOC_IPF_CONFIG, NWAM_LOC_PROP_IPFILTER_CONFIG_FILE },
261 266 { PT_LOC_IPF_V6_CONFIG, NWAM_LOC_PROP_IPFILTER_V6_CONFIG_FILE },
262 267 { PT_LOC_IPNAT_CONFIG, NWAM_LOC_PROP_IPNAT_CONFIG_FILE },
263 268 { PT_LOC_IPPOOL_CONFIG, NWAM_LOC_PROP_IPPOOL_CONFIG_FILE },
264 269 { PT_LOC_IKE_CONFIG, NWAM_LOC_PROP_IKE_CONFIG_FILE },
265 270 { PT_LOC_IPSECPOL_CONFIG, NWAM_LOC_PROP_IPSECPOLICY_CONFIG_FILE },
266 271 { 0, NULL }
267 272 };
268 273
269 274 /* Known WLAN properties table */
270 275 static prop_table_entry_t wlan_prop_table[] = {
271 276 { PT_WLAN_BSSIDS, NWAM_KNOWN_WLAN_PROP_BSSIDS },
272 277 { PT_WLAN_PRIORITY, NWAM_KNOWN_WLAN_PROP_PRIORITY },
273 278 { PT_WLAN_KEYNAME, NWAM_KNOWN_WLAN_PROP_KEYNAME },
274 279 { PT_WLAN_KEYSLOT, NWAM_KNOWN_WLAN_PROP_KEYSLOT },
275 280 { PT_WLAN_SECURITY_MODE, NWAM_KNOWN_WLAN_PROP_SECURITY_MODE },
276 281 { 0, NULL }
277 282 };
278 283
279 284 /* Returns the appropriate properties table for the given object type */
280 285 static prop_table_entry_t *
281 286 get_prop_table(nwam_object_type_t object_type)
282 287 {
283 288 switch (object_type) {
284 289 case NWAM_OBJECT_TYPE_NCU:
285 290 return (ncu_prop_table);
286 291 case NWAM_OBJECT_TYPE_LOC:
287 292 return (loc_prop_table);
288 293 case NWAM_OBJECT_TYPE_ENM:
289 294 return (enm_prop_table);
290 295 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
291 296 return (wlan_prop_table);
292 297 }
293 298 return (NULL);
294 299 }
295 300
296 301 /* Global variables */
297 302
298 303 /* set early in main(), never modified thereafter, used all over the place */
299 304 static char *execname;
300 305
301 306 /* set in modifying functions, checked in read_input() */
302 307 boolean_t saw_error = B_FALSE;
303 308
304 309 /* set in yacc parser, checked in read_input() */
305 310 boolean_t newline_terminated;
306 311
307 312 /* set in main(), checked in lex error handler */
308 313 boolean_t cmd_file_mode = B_FALSE;
309 314
310 315 /* set in exit_func(), checked in read_input() */
311 316 static boolean_t time_to_exit = B_FALSE;
312 317
313 318 /* used in nerr() and nwamerr() */
314 319 static char *cmd_file_name = NULL;
315 320
316 321 /* used with cmd_file to destroy all configurations */
317 322 static boolean_t remove_all_configurations = B_FALSE;
318 323
319 324 /* checked in read_input() and other places */
320 325 static boolean_t ok_to_prompt = B_FALSE;
321 326
322 327 /* initialized in do_interactive(), checked in initialize() */
323 328 static boolean_t interactive_mode;
324 329
325 330 static boolean_t need_to_commit = B_FALSE;
326 331
327 332 /* The gl_get_line() resource object */
328 333 static GetLine *gl;
329 334
330 335 /* set when create or read objects, used by other func */
331 336 static nwam_loc_handle_t loc_h = NULL;
332 337 static nwam_enm_handle_t enm_h = NULL;
333 338 static nwam_known_wlan_handle_t wlan_h = NULL;
334 339 static nwam_ncu_handle_t ncu_h = NULL;
335 340 static nwam_ncp_handle_t ncp_h = NULL;
336 341
337 342 static int current_scope = NWAM_SCOPE_GBL;
338 343
339 344 /* obj1_* are used in NWAM_SCOPE_{NCP,LOC,ENM,WLAN} */
340 345 static int obj1_type;
341 346 static char obj1_name[NWAM_MAX_NAME_LEN + 1];
342 347
343 348 /* obj2_* are used in NWAM_SCOPE_NCU only */
344 349 static int obj2_type;
345 350 static char obj2_name[NWAM_MAX_NAME_LEN + 1];
346 351
347 352 /* arrays for tab-completion */
348 353 /* commands at NWAM_SCOPE_GBL */
349 354 static const char *global_scope_cmds[] = {
350 355 "create ",
351 356 "destroy ",
352 357 "end ",
353 358 "exit ",
354 359 "export ",
355 360 "help ",
356 361 "list ",
357 362 "select ",
358 363 NULL
359 364 };
360 365
361 366 static const char *global_create_cmds[] = {
362 367 "create loc ",
363 368 "create enm ",
364 369 "create ncp ",
365 370 "create wlan ",
366 371 "create -t ", /* template */
367 372 NULL
368 373 };
369 374
370 375 static const char *global_destroy_cmds[] = {
371 376 "destroy -a ",
372 377 "destroy loc ",
373 378 "destroy enm ",
374 379 "destroy ncp ",
375 380 "destroy wlan ",
376 381 NULL
377 382 };
378 383
379 384 static const char *global_export_cmds[] = {
380 385 "export ",
381 386 "export -d ", /* add destroy -a */
382 387 "export -f ", /* to file */
383 388 "export -d -f ", /* add destroy -a to file */
384 389 "export loc ",
385 390 "export enm ",
386 391 "export ncp ",
387 392 "export wlan ",
388 393 NULL
389 394 };
390 395
391 396 static const char *global_list_cmds[] = {
392 397 "list ",
393 398 "list loc ",
394 399 "list enm ",
395 400 "list ncp ",
396 401 "list wlan ",
397 402 "list -a loc ",
398 403 "list -a enm ",
399 404 "list -a wlan ",
400 405 NULL
401 406 };
402 407
403 408 static const char *global_select_cmds[] = {
404 409 "select loc ",
405 410 "select enm ",
406 411 "select ncp ",
407 412 "select wlan ",
408 413 NULL
409 414 };
410 415
411 416 /* commands at NWAM_SCOPE_LOC, _ENM, _WLAN and _NCU */
412 417 static const char *non_ncp_scope_cmds[] = {
413 418 "cancel ",
414 419 "clear ",
415 420 "commit ",
416 421 "end ",
417 422 "exit ",
418 423 "export ",
419 424 "export -f ",
420 425 "get ",
421 426 "get -V ", /* value only */
422 427 "help ",
423 428 "list ",
424 429 "list -a ", /* all properties */
425 430 "revert ",
426 431 "set ",
427 432 "verify ",
428 433 "walkprop ",
429 434 "walkprop -a ", /* all properties */
430 435 NULL
431 436 };
432 437
433 438 /* commands at NWAM_SCOPE_NCP */
434 439 static const char *ncp_scope_cmds[] = {
435 440 "cancel ",
436 441 "create ",
437 442 "destroy ",
438 443 "end ",
439 444 "exit ",
440 445 "export ",
441 446 "help ",
442 447 "list ",
443 448 "select ",
444 449 NULL
445 450 };
446 451
447 452 static const char *ncp_create_cmds[] = {
448 453 "create ncu ip ",
449 454 "create ncu phys ",
450 455 "create -t ", /* template */
451 456 NULL
452 457 };
453 458
454 459 static const char *ncp_destroy_cmds[] = {
455 460 "destroy ncu ",
456 461 "destroy ncu ip ",
457 462 "destroy ncu phys ",
458 463 NULL
459 464 };
460 465
461 466 static const char *ncp_export_cmds[] = {
462 467 "export ",
463 468 "export -f ", /* to file */
464 469 "export ncu ",
465 470 "export ncu ip ",
466 471 "export ncu phys ",
467 472 NULL
468 473 };
469 474
470 475 static const char *ncp_list_cmds[] = {
471 476 "list ",
472 477 "list ncu ",
473 478 "list ncu ip ",
474 479 "list ncu phys ",
475 480 "list -a ncu ",
476 481 "list -a ncu ip ",
477 482 "list -a ncu phys ",
478 483 NULL
479 484 };
480 485
481 486 static const char *ncp_select_cmds[] = {
482 487 "select ncu ",
483 488 "select ncu ip ",
484 489 "select ncu phys ",
485 490 NULL
486 491 };
487 492
488 493 /* Functions begin here */
489 494
490 495 cmd_t *
491 496 alloc_cmd(void)
492 497 {
493 498 cmd_t *cmd = calloc(1, sizeof (cmd_t));
494 499 if (cmd == NULL) {
495 500 nerr("Out of memory");
496 501 return (NULL);
497 502 }
498 503 cmd->cmd_argc = 0;
499 504 cmd->cmd_argv[0] = NULL;
500 505
501 506 return (cmd);
502 507 }
503 508
504 509 void
505 510 free_cmd(cmd_t *cmd)
506 511 {
507 512 int i;
508 513
509 514 for (i = 0; i < cmd->cmd_argc; i++)
510 515 free(cmd->cmd_argv[i]);
511 516 free(cmd);
512 517 }
513 518
514 519 void
515 520 array_free(void **array, int nelem)
516 521 {
517 522 int i;
518 523 for (i = 0; i < nelem; i++)
519 524 free(array[i]);
520 525 free(array);
521 526 }
522 527
523 528 static boolean_t
524 529 initial_match(const char *line1, const char *line2, int word_end)
525 530 {
526 531 if (word_end <= 0)
527 532 return (B_TRUE);
528 533 return (strncmp(line1, line2, word_end) == 0);
529 534 }
530 535
531 536 static int
532 537 add_stuff(WordCompletion *cpl, const char *line1, const char **list,
533 538 int word_end)
534 539 {
535 540 int i, err;
536 541
537 542 for (i = 0; list[i] != NULL; i++) {
538 543 if (initial_match(line1, list[i], word_end)) {
539 544 err = cpl_add_completion(cpl, line1, 0, word_end,
540 545 list[i] + word_end, "", "");
541 546 if (err != 0)
542 547 return (err);
543 548 }
544 549 }
545 550 return (0);
546 551 }
547 552
548 553 /*
549 554 * To fill in the rest of a string when user types the tab key.
550 555 * First digital number is the length of the string, the second digital number
551 556 * is the min number of chars that is needed to uniquely identify a string.
552 557 */
553 558 #define MINI_STR(l, s, m, n) strncmp(l, s, MAX(MIN(sizeof (s) - 1, m), n))
554 559
555 560 /* ARGSUSED */
556 561 static
557 562 CPL_MATCH_FN(cmd_cpl_fn)
558 563 {
559 564 /* tab-complete according to the current scope */
560 565 switch (current_scope) {
561 566 case NWAM_SCOPE_GBL:
562 567 if (MINI_STR(line, "create ", word_end, 2) == 0)
563 568 return (add_stuff(cpl, line, global_create_cmds,
564 569 word_end));
565 570 if (MINI_STR(line, "destroy ", word_end, 1) == 0)
566 571 return (add_stuff(cpl, line, global_destroy_cmds,
567 572 word_end));
568 573 if (MINI_STR(line, "export ", word_end, 3) == 0)
569 574 return (add_stuff(cpl, line, global_export_cmds,
570 575 word_end));
571 576 if (MINI_STR(line, "list ", word_end, 1) == 0)
572 577 return (add_stuff(cpl, line, global_list_cmds,
573 578 word_end));
574 579 if (MINI_STR(line, "select ", word_end, 1) == 0)
575 580 return (add_stuff(cpl, line, global_select_cmds,
576 581 word_end));
577 582 return (add_stuff(cpl, line, global_scope_cmds, word_end));
578 583 case NWAM_SCOPE_LOC:
579 584 case NWAM_SCOPE_ENM:
580 585 case NWAM_SCOPE_WLAN:
581 586 case NWAM_SCOPE_NCU:
582 587 return (add_stuff(cpl, line, non_ncp_scope_cmds, word_end));
583 588 case NWAM_SCOPE_NCP:
584 589 if (MINI_STR(line, "create ", word_end, 2) == 0)
585 590 return (add_stuff(cpl, line, ncp_create_cmds,
586 591 word_end));
587 592 if (MINI_STR(line, "destroy ", word_end, 1) == 0)
588 593 return (add_stuff(cpl, line, ncp_destroy_cmds,
589 594 word_end));
590 595 if (MINI_STR(line, "export ", word_end, 3) == 0)
591 596 return (add_stuff(cpl, line, ncp_export_cmds,
592 597 word_end));
593 598 if (MINI_STR(line, "list ", word_end, 1) == 0)
594 599 return (add_stuff(cpl, line, ncp_list_cmds, word_end));
595 600 if (MINI_STR(line, "select ", word_end, 1) == 0)
596 601 return (add_stuff(cpl, line, ncp_select_cmds,
597 602 word_end));
598 603 return (add_stuff(cpl, line, ncp_scope_cmds, word_end));
599 604 }
600 605 /* should never get here */
601 606 return (NULL);
602 607 }
603 608
604 609 const char *
605 610 cmd_to_str(int cmd_num)
606 611 {
607 612 assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
608 613 return (helptab[cmd_num].cmd_name);
609 614 }
610 615
611 616 /* Returns "loc", "enm", "wlan" or "ncp" as string */
612 617 static const char *
613 618 rt1_to_str(int res_type)
614 619 {
615 620 assert(res_type >= RT1_MIN && res_type <= RT1_MAX);
616 621 return (res1_types[res_type]);
617 622 }
618 623
619 624 /* Returns "ncu" as string */
620 625 static const char *
621 626 rt2_to_str(int res_type)
622 627 {
623 628 assert(res_type >= RT2_MIN && res_type <= RT2_MAX);
624 629 return (res2_types[res_type]);
625 630 }
626 631
627 632 /* Returns "ncp, "ncu", "loc", "enm", or "wlan" according to the scope */
628 633 static const char *
629 634 scope_to_str(int scope) {
630 635 switch (scope) {
631 636 case NWAM_SCOPE_GBL:
632 637 return ("global");
633 638 case NWAM_SCOPE_NCP:
634 639 return ("ncp");
635 640 case NWAM_SCOPE_NCU:
636 641 return ("ncu");
637 642 case NWAM_SCOPE_LOC:
638 643 return ("loc");
639 644 case NWAM_SCOPE_ENM:
640 645 return ("enm");
641 646 case NWAM_SCOPE_WLAN:
642 647 return ("wlan");
643 648 default:
644 649 return ("invalid");
645 650 }
646 651 }
647 652
648 653 /* Given an enm property and value, returns it as a string */
649 654 static const char *
650 655 propval_to_str(const char *propname, uint64_t value)
651 656 {
652 657 const char *str;
653 658
654 659 if (nwam_uint64_get_value_string(propname, value, &str) == NWAM_SUCCESS)
655 660 return (str);
656 661 return (NULL);
|
↓ open down ↓ |
418 lines elided |
↑ open up ↑ |
657 662 }
658 663
659 664 /* Given an int for a prop, returns it as string */
660 665 static const char *
661 666 pt_to_str(int prop_type)
662 667 {
663 668 assert(prop_type >= PT_MIN && prop_type <= PT_MAX);
664 669 return (pt_types[prop_type]);
665 670 }
666 671
667 -/* Return B_TRUE if string starts with "t" or is 1, B_FALSE otherwise */
672 +/*
673 + * Return B_TRUE if string starts with "t" or "on" or is 1;
674 + * B_FALSE otherwise
675 + */
668 676 static boolean_t
669 677 str_to_boolean(const char *str)
670 678 {
671 - if (strncasecmp(str, "t", 1) == 0 || atoi(str) == 1)
679 + if (strncasecmp(str, "t", 1) == 0 || strncasecmp(str, "on", 2) == 0 ||
680 + atoi(str) == 1)
672 681 return (B_TRUE);
673 682 else
674 683 return (B_FALSE);
675 684 }
676 685
677 686 /*
678 687 * This is a separate function rather than a set of define's because of the
679 688 * gettext() wrapping.
680 689 */
681 690
682 691 /*
683 692 * TRANSLATION_NOTE
684 693 * Each string below should have \t follow \n whenever needed; the
685 694 * initial \t and the terminal \n will be provided by the calling function.
686 695 */
687 696
688 697 static const char *
689 698 long_help(int cmd_num)
690 699 {
691 700 assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
692 701 switch (cmd_num) {
693 702 case CMD_CANCEL:
694 703 return (gettext("Cancels the current configuration "
695 704 "changes."));
696 705 case CMD_CLEAR:
697 706 return (gettext("Clears the value for the specified "
698 707 "property."));
699 708 case CMD_COMMIT:
700 709 return (gettext("Commits the current configuration."));
701 710 case CMD_CREATE:
702 711 return (gettext("Creates a new profile or resource."));
703 712 case CMD_DESTROY:
704 713 return (gettext("Destroys the specified profile or "
705 714 "resource."));
706 715 case CMD_END:
707 716 return (gettext("Ends specification of a resource."));
708 717 case CMD_EXIT:
709 718 return (gettext("Exits the program."));
710 719 case CMD_EXPORT:
711 720 return (gettext("Exports the configuration."));
712 721 case CMD_GET:
713 722 return (gettext("Gets the value of the specified "
714 723 "property."));
715 724 case CMD_HELP:
716 725 return (gettext("Prints help message."));
717 726 case CMD_LIST:
718 727 return (gettext("Lists existing objects."));
719 728 case CMD_REVERT:
720 729 return (gettext("Reverts to the previous "
721 730 "configuration."));
722 731 case CMD_SELECT:
723 732 return (gettext("Selects a resource to modify."));
724 733 case CMD_SET:
725 734 return (gettext("Sets the value of the specified "
726 735 "property."));
727 736 case CMD_VERIFY:
728 737 return (gettext("Verifies an object."));
729 738 case CMD_WALKPROP:
730 739 return (gettext("Iterates over properties."));
731 740 default:
732 741 return (gettext("Unknown command."));
733 742 }
734 743 }
735 744
736 745 void
737 746 command_usage(int command)
738 747 {
739 748 if (command < CMD_MIN || command > CMD_MAX) {
740 749 nerr("Unknown command");
741 750 } else {
742 751 nerr("%s: %s: %s", gettext("Error"), gettext("usage"),
743 752 helptab[command].cmd_usage);
744 753 }
745 754 }
746 755
747 756 static void
748 757 long_usage(uint_t cmd_num)
749 758 {
750 759 (void) printf("%s: %s\n", gettext("usage"),
751 760 helptab[cmd_num].cmd_usage);
752 761 (void) printf("\t%s\n", long_help(cmd_num));
753 762 }
754 763
755 764 /* Prints usage for command line options */
756 765 static void
757 766 cmd_line_usage()
758 767 {
759 768 (void) printf("%s:\t%s\t\t\t\t(%s)\n", gettext("usage"), execname,
760 769 gettext("interactive-mode"));
761 770 (void) printf("\t%s <%s> [%s...]\n", execname, gettext("command"),
762 771 gettext("options"));
763 772 (void) printf("\t%s [-d] -f <%s>\n", execname, gettext("command-file"));
764 773 (void) printf("\t%s %s [<%s>]\n", execname, cmd_to_str(CMD_HELP),
765 774 gettext("command"));
766 775 }
767 776
768 777 /* Prints the line number of the current command if in command-file mode */
769 778 static void
770 779 print_lineno()
771 780 {
772 781 static int last_lineno;
773 782
774 783 /* lex_lineno has already been incremented in the lexer; compensate */
775 784 if (cmd_file_mode && lex_lineno > last_lineno) {
776 785 if (strcmp(cmd_file_name, "-") == 0)
777 786 (void) fprintf(stderr, gettext("On line %d:\n"),
778 787 lex_lineno - 1);
779 788 else
780 789 (void) fprintf(stderr, gettext("On line %d of %s:\n"),
781 790 lex_lineno - 1, cmd_file_name);
782 791 last_lineno = lex_lineno;
783 792 }
784 793 }
785 794
786 795 /* PRINTFLIKE1 */
787 796 void
788 797 nerr(const char *format, ...)
789 798 {
790 799 va_list alist;
791 800
792 801 print_lineno();
793 802
794 803 format = gettext(format);
795 804 va_start(alist, format);
796 805 (void) vfprintf(stderr, format, alist);
797 806 va_end(alist);
798 807 (void) fprintf(stderr, "\n");
799 808
800 809 saw_error = B_TRUE;
801 810 }
802 811
803 812 /* PRINTFLIKE2 */
804 813 static void
805 814 nwamerr(nwam_error_t err, const char *format, ...)
806 815 {
807 816 va_list alist;
808 817
809 818 print_lineno();
810 819
811 820 format = gettext(format);
812 821 va_start(alist, format);
813 822 (void) vfprintf(stderr, format, alist);
814 823 va_end(alist);
815 824 (void) fprintf(stderr, ": %s\n", nwam_strerror(err));
816 825
817 826 saw_error = B_TRUE;
818 827 }
819 828
820 829 void
821 830 properr(const char *prop)
822 831 {
823 832 nerr("Invalid property: '%s'", prop);
824 833 }
825 834
826 835 /*
827 836 * If free_ncu_only == B_TRUE, only ncu handle is freed, ncp handle remains the
828 837 * same. Since nwam_ncp_free() takes care of its ncus, no need to explicitly
829 838 * call nwam_ncu_free() afterwards.
830 839 */
831 840 static void
832 841 free_handle(boolean_t free_ncu_only)
833 842 {
834 843 if (ncp_h != NULL) {
835 844 if (!free_ncu_only) {
836 845 nwam_ncp_free(ncp_h);
837 846 ncp_h = NULL;
838 847 ncu_h = NULL;
839 848 } else if (ncu_h != NULL) {
840 849 nwam_ncu_free(ncu_h);
841 850 ncu_h = NULL;
842 851 }
843 852 }
844 853
845 854 if (enm_h != NULL) {
846 855 nwam_enm_free(enm_h);
847 856 enm_h = NULL;
848 857 }
849 858
850 859 if (loc_h != NULL) {
851 860 nwam_loc_free(loc_h);
852 861 loc_h = NULL;
853 862 }
854 863
855 864 if (wlan_h != NULL) {
856 865 nwam_known_wlan_free(wlan_h);
857 866 wlan_h = NULL;
858 867 }
859 868 }
860 869
861 870 /*
862 871 * On input, TRUE => yes, FALSE => no.
863 872 * On return, TRUE => 1, FALSE => no, could not ask => -1.
864 873 */
865 874 static int
866 875 ask_yesno(boolean_t default_answer, const char *question)
867 876 {
868 877 char line[64]; /* should be enough to answer yes or no */
869 878
870 879 if (!ok_to_prompt) {
871 880 saw_error = B_TRUE;
872 881 return (-1);
873 882 }
874 883 for (;;) {
875 884 if (printf("%s (%s)? ", gettext(question),
876 885 default_answer ? "[y]/n" : "y/[n]") < 0)
877 886 return (-1);
878 887 if (fgets(line, sizeof (line), stdin) == NULL)
879 888 return (-1);
880 889
881 890 if (line[0] == '\n')
882 891 return (default_answer ? 1 : 0);
883 892 if (tolower(line[0]) == 'y')
884 893 return (1);
885 894 if (tolower(line[0]) == 'n')
886 895 return (0);
887 896 }
888 897 }
889 898
890 899 /* This is the back-end helper function for read_input() below. */
891 900 static int
892 901 cleanup()
893 902 {
894 903 int answer;
895 904
896 905 if (!interactive_mode && !cmd_file_mode) {
897 906 /*
898 907 * If we're not in interactive mode, and we're not in command
899 908 * file mode, then we must be in commands-from-the-command-line
900 909 * mode. As such, we can't loop back and ask for more input.
901 910 * It was OK to prompt for such things as whether or not to
902 911 * really delete something in the command handler called from
903 912 * yyparse() above, but "really quit?" makes no sense in this
904 913 * context. So disable prompting.
905 914 */
906 915 ok_to_prompt = B_FALSE;
907 916 }
908 917 if (need_to_commit) {
909 918 answer = ask_yesno(B_FALSE,
910 919 "Configuration not saved; really quit");
911 920 switch (answer) {
912 921 case -1:
913 922 /* issue error here */
914 923 return (NWAM_ERR);
915 924 case 1:
916 925 /*
917 926 * don't want to save, just exit. handles are freed at
918 927 * end_func() or exit_func().
919 928 */
920 929 return (NWAM_OK);
921 930 default:
922 931 /* loop back to read input */
923 932 time_to_exit = B_FALSE;
924 933 yyin = stdin;
925 934 return (NWAM_REPEAT);
926 935 }
927 936 }
928 937 return (saw_error ? NWAM_ERR : NWAM_OK);
929 938 }
930 939
931 940 static int
932 941 string_to_yyin(char *string)
933 942 {
934 943 if ((yyin = tmpfile()) == NULL)
935 944 goto error;
936 945 if (fwrite(string, strlen(string), 1, yyin) != 1)
937 946 goto error;
938 947 if (fseek(yyin, 0, SEEK_SET) != 0)
939 948 goto error;
940 949
941 950 return (NWAM_OK);
942 951
943 952 error:
944 953 nerr("problem creating temporary file");
945 954 return (NWAM_ERR);
946 955 }
947 956
948 957 /*
949 958 * read_input() is the driver of this program. It is a wrapper around
950 959 * yyparse(), printing appropriate prompts when needed, checking for
951 960 * exit conditions and reacting appropriately. This function is
952 961 * called when in interactive mode or command-file mode.
953 962 */
954 963 static int
955 964 read_input(void)
956 965 {
957 966 boolean_t yyin_is_a_tty = isatty(fileno(yyin));
958 967 /*
959 968 * The prompt is "e> " or "e:t1:o1> " or "e:t1:o1:t2:o2> " where e is
960 969 * execname, t is resource type, o is object name.
961 970 */
962 971 char prompt[MAXPATHLEN + (2 * (NWAM_MAX_TYPE_LEN + NWAM_MAX_NAME_LEN))
963 972 + sizeof ("::::> ")];
964 973 char *line;
965 974
966 975 /* yyin should have been set to the appropriate (FILE *) if not stdin */
967 976 newline_terminated = B_TRUE;
968 977 for (;;) {
969 978 if (yyin_is_a_tty) {
970 979 if (newline_terminated) {
971 980 switch (current_scope) {
972 981 case NWAM_SCOPE_GBL:
973 982 (void) snprintf(prompt, sizeof (prompt),
974 983 "%s> ", execname);
975 984 break;
976 985 case NWAM_SCOPE_LOC:
977 986 case NWAM_SCOPE_ENM:
978 987 case NWAM_SCOPE_WLAN:
979 988 case NWAM_SCOPE_NCP:
980 989 (void) snprintf(prompt, sizeof (prompt),
981 990 "%s:%s:%s> ", execname,
982 991 rt1_to_str(obj1_type), obj1_name);
983 992
984 993 break;
985 994 case NWAM_SCOPE_NCU:
986 995 (void) snprintf(prompt, sizeof (prompt),
987 996 "%s:%s:%s:%s:%s> ", execname,
988 997 rt1_to_str(obj1_type), obj1_name,
989 998 rt2_to_str(obj2_type), obj2_name);
990 999 }
991 1000 }
992 1001 /*
993 1002 * If the user hits ^C then we want to catch it and
994 1003 * start over. If the user hits EOF then we want to
995 1004 * bail out.
996 1005 */
997 1006 line = gl_get_line(gl, prompt, NULL, -1);
998 1007 if (gl_return_status(gl) == GLR_SIGNAL) {
999 1008 gl_abandon_line(gl);
1000 1009 continue;
1001 1010 }
1002 1011 if (line == NULL)
1003 1012 break;
1004 1013 if (string_to_yyin(line) != NWAM_OK)
1005 1014 break;
1006 1015 while (!feof(yyin)) {
1007 1016 yyparse();
1008 1017
1009 1018 /*
1010 1019 * If any command on a list of commands
1011 1020 * give an error, don't continue with the
1012 1021 * remaining commands.
1013 1022 */
1014 1023 if (saw_error || time_to_exit)
1015 1024 break;
1016 1025 }
1017 1026 } else {
1018 1027 yyparse();
1019 1028 }
1020 1029
1021 1030 /* Bail out on an error in command-file mode. */
1022 1031 if (saw_error && cmd_file_mode && !interactive_mode)
1023 1032 time_to_exit = B_TRUE;
1024 1033 if (time_to_exit || (!yyin_is_a_tty && feof(yyin)))
1025 1034 break;
1026 1035 }
1027 1036 return (cleanup());
1028 1037 }
1029 1038
1030 1039 /*
1031 1040 * This function is used in the interactive-mode scenario: it just calls
1032 1041 * read_input() until we are done.
1033 1042 */
1034 1043 static int
1035 1044 do_interactive(void)
1036 1045 {
1037 1046 int err;
1038 1047
1039 1048 interactive_mode = B_TRUE;
1040 1049 do {
1041 1050 err = read_input();
1042 1051 } while (err == NWAM_REPEAT);
1043 1052 return (err);
1044 1053 }
1045 1054
1046 1055 /* Calls the help_func() to print the usage of all commands */
1047 1056 void
1048 1057 help_wrap()
1049 1058 {
1050 1059 cmd_t *help_cmd;
1051 1060
1052 1061 if ((help_cmd = alloc_cmd()) == NULL)
1053 1062 exit(NWAM_ERR);
1054 1063 help_func(help_cmd);
1055 1064 free_cmd(help_cmd);
1056 1065 }
1057 1066
1058 1067 /* Check if the given command is allowed in the current scope */
1059 1068 boolean_t
1060 1069 check_scope(int cmd)
1061 1070 {
1062 1071 /* allowed in all scopes */
1063 1072 switch (cmd) {
1064 1073 case CMD_END:
1065 1074 case CMD_EXIT:
1066 1075 case CMD_HELP:
1067 1076 case CMD_LIST:
1068 1077 case CMD_EXPORT:
1069 1078 return (B_TRUE);
1070 1079 }
1071 1080 /* scope-specific */
1072 1081 switch (current_scope) {
1073 1082 case NWAM_SCOPE_GBL:
1074 1083 switch (cmd) {
1075 1084 case CMD_CREATE:
1076 1085 case CMD_DESTROY:
1077 1086 case CMD_SELECT:
1078 1087 return (B_TRUE);
1079 1088 }
1080 1089 break;
1081 1090 case NWAM_SCOPE_LOC:
1082 1091 case NWAM_SCOPE_ENM:
1083 1092 case NWAM_SCOPE_WLAN:
1084 1093 case NWAM_SCOPE_NCU:
1085 1094 switch (cmd) {
1086 1095 case CMD_CANCEL:
1087 1096 case CMD_CLEAR:
1088 1097 case CMD_COMMIT:
1089 1098 case CMD_GET:
1090 1099 case CMD_REVERT:
1091 1100 case CMD_SET:
1092 1101 case CMD_VERIFY:
1093 1102 case CMD_WALKPROP:
1094 1103 return (B_TRUE);
1095 1104 }
1096 1105 break;
1097 1106 case NWAM_SCOPE_NCP:
1098 1107 switch (cmd) {
1099 1108 case CMD_CANCEL:
1100 1109 case CMD_CREATE:
1101 1110 case CMD_DESTROY:
1102 1111 case CMD_SELECT:
1103 1112 return (B_TRUE);
1104 1113 }
1105 1114 break;
1106 1115 default:
1107 1116 nerr("Invalid scope");
1108 1117 }
1109 1118 nerr("'%s' is not allowed at this scope", cmd_to_str(cmd));
1110 1119 return (B_FALSE);
1111 1120 }
1112 1121
1113 1122 /* Returns the active object type depending on which handle is not NULL */
1114 1123 static nwam_object_type_t
1115 1124 active_object_type()
1116 1125 {
1117 1126 /* Check ncu_h before ncp_h, ncp_h must be loaded before ncu_h */
1118 1127 if (ncu_h != NULL)
1119 1128 return (NWAM_OBJECT_TYPE_NCU);
1120 1129 else if (ncp_h != NULL)
1121 1130 return (NWAM_OBJECT_TYPE_NCP);
1122 1131 else if (loc_h != NULL)
1123 1132 return (NWAM_OBJECT_TYPE_LOC);
1124 1133 else if (enm_h != NULL)
1125 1134 return (NWAM_OBJECT_TYPE_ENM);
1126 1135 else if (wlan_h != NULL)
1127 1136 return (NWAM_OBJECT_TYPE_KNOWN_WLAN);
1128 1137 else
1129 1138 return (NWAM_OBJECT_TYPE_UNKNOWN);
1130 1139 }
1131 1140
1132 1141 /* Retrive the name of the object from its handle */
1133 1142 static nwam_error_t
1134 1143 object_name_from_handle(nwam_object_type_t object_type, void *handle,
1135 1144 char **namep)
1136 1145 {
1137 1146 switch (object_type) {
1138 1147 case NWAM_OBJECT_TYPE_NCP:
1139 1148 return (nwam_ncp_get_name(handle, namep));
1140 1149 case NWAM_OBJECT_TYPE_NCU:
1141 1150 return (nwam_ncu_get_name(handle, namep));
1142 1151 case NWAM_OBJECT_TYPE_LOC:
1143 1152 return (nwam_loc_get_name(handle, namep));
1144 1153 case NWAM_OBJECT_TYPE_ENM:
1145 1154 return (nwam_enm_get_name(handle, namep));
1146 1155 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
1147 1156 return (nwam_known_wlan_get_name(handle, namep));
1148 1157 }
1149 1158 return (NWAM_INVALID_ARG);
1150 1159 }
1151 1160
1152 1161 static void
1153 1162 do_commit()
1154 1163 {
1155 1164 nwam_error_t ret = NWAM_SUCCESS;
1156 1165 const char *errprop;
1157 1166
1158 1167 if (!need_to_commit)
1159 1168 return;
1160 1169
1161 1170 switch (active_object_type()) {
1162 1171 case NWAM_OBJECT_TYPE_NCU:
1163 1172 ret = nwam_ncu_commit(ncu_h, 0);
1164 1173 break;
1165 1174 case NWAM_OBJECT_TYPE_ENM:
1166 1175 ret = nwam_enm_commit(enm_h, 0);
1167 1176 break;
1168 1177 case NWAM_OBJECT_TYPE_LOC:
1169 1178 ret = nwam_loc_commit(loc_h, 0);
1170 1179 break;
1171 1180 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
1172 1181 ret = nwam_known_wlan_commit(wlan_h, 0);
1173 1182 break;
1174 1183 }
1175 1184
1176 1185 if (ret == NWAM_SUCCESS) {
1177 1186 need_to_commit = B_FALSE;
1178 1187 if (interactive_mode)
1179 1188 (void) printf(gettext("Committed changes\n"));
1180 1189 } else {
1181 1190 nwam_error_t verr;
1182 1191
1183 1192 /* Find property that caused failure */
1184 1193 switch (active_object_type()) {
1185 1194 case NWAM_OBJECT_TYPE_NCU:
1186 1195 verr = nwam_ncu_validate(ncu_h, &errprop);
1187 1196 break;
1188 1197 case NWAM_OBJECT_TYPE_ENM:
1189 1198 verr = nwam_enm_validate(enm_h, &errprop);
1190 1199 break;
1191 1200 case NWAM_OBJECT_TYPE_LOC:
1192 1201 verr = nwam_loc_validate(loc_h, &errprop);
1193 1202 break;
1194 1203 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
1195 1204 verr = nwam_known_wlan_validate(wlan_h, &errprop);
1196 1205 break;
1197 1206 }
1198 1207
1199 1208 if (verr != NWAM_SUCCESS)
1200 1209 nwamerr(ret, "Commit error on property '%s'", errprop);
1201 1210 else
1202 1211 nwamerr(ret, "Commit error");
1203 1212 }
1204 1213 }
1205 1214
1206 1215 /*
1207 1216 * Saves the current configuration to persistent storage.
1208 1217 */
1209 1218 /* ARGSUSED */
1210 1219 void
1211 1220 commit_func(cmd_t *cmd)
1212 1221 {
1213 1222 if (!need_to_commit) {
1214 1223 if (interactive_mode)
1215 1224 (void) printf(gettext("Nothing to commit\n"));
1216 1225 } else {
1217 1226 do_commit();
1218 1227 }
1219 1228 }
1220 1229
1221 1230 static void
1222 1231 do_cancel()
1223 1232 {
1224 1233 switch (current_scope) {
1225 1234 case NWAM_SCOPE_NCU:
1226 1235 current_scope = NWAM_SCOPE_NCP;
1227 1236 obj2_type = 0;
1228 1237 free_handle(B_TRUE);
1229 1238 break;
1230 1239 case NWAM_SCOPE_NCP:
1231 1240 case NWAM_SCOPE_ENM:
1232 1241 case NWAM_SCOPE_WLAN:
1233 1242 case NWAM_SCOPE_LOC:
1234 1243 current_scope = NWAM_SCOPE_GBL;
1235 1244 obj1_type = 0;
1236 1245 free_handle(B_FALSE);
1237 1246 break;
1238 1247 case NWAM_SCOPE_GBL:
1239 1248 free_handle(B_FALSE);
1240 1249 break;
1241 1250 default:
1242 1251 nerr("Invalid scope");
1243 1252 return;
1244 1253 }
1245 1254 need_to_commit = B_FALSE;
1246 1255 }
1247 1256
1248 1257 /*
1249 1258 * End operation on current scope and go up one scope.
1250 1259 * Changes are not saved, no prompt either.
1251 1260 */
1252 1261 /* ARGSUSED */
1253 1262 void
1254 1263 cancel_func(cmd_t *cmd)
1255 1264 {
1256 1265 do_cancel();
1257 1266 }
1258 1267
1259 1268 /*
1260 1269 * Removes leading and trailing quotes from a string.
1261 1270 * Caller must free returned string.
1262 1271 */
1263 1272 static char *
1264 1273 trim_quotes(const char *quoted_str)
1265 1274 {
1266 1275 char *str;
1267 1276 int end;
1268 1277
1269 1278 /* export_func() and list_func() can pass NULL here */
1270 1279 if (quoted_str == NULL)
1271 1280 return (NULL);
1272 1281
1273 1282 /* remove leading quote */
1274 1283 if (quoted_str[0] == '"')
1275 1284 str = strdup(quoted_str + 1);
1276 1285 else
1277 1286 str = strdup(quoted_str);
1278 1287 if (str == NULL)
1279 1288 return (NULL);
1280 1289
1281 1290 /* remove trailing quote and newline */
1282 1291 end = strlen(str) - 1;
1283 1292 while (end >= 0 && (str[end] == '"' || str[end] == '\n'))
1284 1293 end--;
1285 1294 str[end+1] = 0;
1286 1295
1287 1296 return (str);
1288 1297 }
1289 1298
1290 1299 /*
1291 1300 * Creates a new resource and enters the scope of that resource.
1292 1301 * The new resource can also be a copy of an existing resource (-t option).
1293 1302 * If in interactive mode, then after creation call walkprop_func()
1294 1303 * to do walk the properties for the new object.
1295 1304 */
1296 1305 void
1297 1306 create_func(cmd_t *cmd)
1298 1307 {
1299 1308 nwam_error_t ret = NWAM_SUCCESS;
1300 1309 int c;
1301 1310 boolean_t template = B_FALSE;
1302 1311 char *newname = NULL, *oldname = NULL;
1303 1312 cmd_t *walkprop_cmd;
1304 1313
1305 1314 /* make sure right command at the right scope */
1306 1315 if (current_scope == NWAM_SCOPE_GBL &&
1307 1316 cmd->cmd_res2_type == RT2_NCU) {
1308 1317 nerr("cannot create ncu at global scope");
1309 1318 return;
1310 1319 }
1311 1320 if (current_scope == NWAM_SCOPE_NCP &&
1312 1321 cmd->cmd_res2_type != RT2_NCU) {
1313 1322 nerr("Cannot create given object at this scope");
1314 1323 return;
1315 1324 }
1316 1325
1317 1326 assert(cmd->cmd_argc > 0);
1318 1327 optind = 0;
1319 1328 while ((c = getopt(cmd->cmd_argc, cmd->cmd_argv, "t:")) != EOF) {
1320 1329 switch (c) {
1321 1330 case 't':
1322 1331 template = B_TRUE;
1323 1332 break;
1324 1333 default:
1325 1334 command_usage(CMD_CREATE);
1326 1335 return;
1327 1336 }
1328 1337 }
1329 1338
1330 1339 if (!template) {
1331 1340 /* no template given */
1332 1341 /* argv[0] is name */
1333 1342 newname = trim_quotes(cmd->cmd_argv[0]);
1334 1343 if (cmd->cmd_res1_type == RT1_ENM) {
1335 1344 ret = nwam_enm_create(newname, NULL, &enm_h);
1336 1345 } else if (cmd->cmd_res1_type == RT1_LOC) {
1337 1346 ret = nwam_loc_create(newname, &loc_h);
1338 1347 } else if (cmd->cmd_res1_type == RT1_WLAN) {
1339 1348 ret = nwam_known_wlan_create(newname, &wlan_h);
1340 1349 } else if (cmd->cmd_res1_type == RT1_NCP &&
1341 1350 current_scope == NWAM_SCOPE_GBL) {
1342 1351 ret = nwam_ncp_create(newname, 0, &ncp_h);
1343 1352 } else if (cmd->cmd_res2_type == RT2_NCU) {
1344 1353 nwam_ncu_type_t ncu_type;
1345 1354 nwam_ncu_class_t ncu_class;
1346 1355
1347 1356 /* ncp must already be read */
1348 1357 if (ncp_h == NULL) {
1349 1358 nerr("Create error: NCP has not been read");
1350 1359 goto done;
1351 1360 }
1352 1361
1353 1362 ncu_class = (nwam_ncu_class_t)cmd->cmd_ncu_class_type;
1354 1363 ncu_type = nwam_ncu_class_to_type(ncu_class);
1355 1364 ret = nwam_ncu_create(ncp_h, newname, ncu_type,
1356 1365 ncu_class, &ncu_h);
1357 1366 }
1358 1367
1359 1368 if (ret != NWAM_SUCCESS) {
1360 1369 nwamerr(ret, "Create error");
1361 1370 goto done;
1362 1371 }
1363 1372
1364 1373 } else {
1365 1374 /* template given */
1366 1375 /* argv[0] is -t, argv[1] is old name, argv[2] is new name */
1367 1376 oldname = trim_quotes(cmd->cmd_argv[1]);
1368 1377 newname = trim_quotes(cmd->cmd_argv[2]);
1369 1378 if (cmd->cmd_res1_type == RT1_ENM) {
1370 1379 nwam_enm_handle_t oldenm_h;
1371 1380
1372 1381 ret = nwam_enm_read(oldname, 0, &oldenm_h);
1373 1382 if (ret != NWAM_SUCCESS)
1374 1383 goto read_error;
1375 1384 ret = nwam_enm_copy(oldenm_h, newname, &enm_h);
1376 1385 nwam_enm_free(oldenm_h);
1377 1386 } else if (cmd->cmd_res1_type == RT1_LOC) {
1378 1387 nwam_loc_handle_t oldloc_h;
1379 1388
1380 1389 ret = nwam_loc_read(oldname, 0, &oldloc_h);
1381 1390 if (ret != NWAM_SUCCESS)
1382 1391 goto read_error;
1383 1392 ret = nwam_loc_copy(oldloc_h, newname, &loc_h);
1384 1393 nwam_loc_free(oldloc_h);
1385 1394 } else if (cmd->cmd_res1_type == RT1_WLAN) {
1386 1395 nwam_known_wlan_handle_t oldwlan_h;
1387 1396
1388 1397 ret = nwam_known_wlan_read(oldname, 0, &oldwlan_h);
1389 1398 if (ret != NWAM_SUCCESS)
1390 1399 goto read_error;
1391 1400 ret = nwam_known_wlan_copy(oldwlan_h, newname, &wlan_h);
1392 1401 nwam_known_wlan_free(oldwlan_h);
1393 1402 } else if (cmd->cmd_res1_type == RT1_NCP &&
1394 1403 current_scope == NWAM_SCOPE_GBL) {
1395 1404 nwam_ncp_handle_t oldncp_h;
1396 1405
1397 1406 ret = nwam_ncp_read(oldname, 0, &oldncp_h);
1398 1407 if (ret != NWAM_SUCCESS)
1399 1408 goto read_error;
1400 1409 ret = nwam_ncp_copy(oldncp_h, newname, &ncp_h);
1401 1410 nwam_ncp_free(oldncp_h);
1402 1411 } else if (cmd->cmd_res2_type == RT2_NCU) {
1403 1412 nwam_ncu_handle_t oldncu_h;
1404 1413 nwam_ncu_type_t ncu_type;
1405 1414 nwam_ncu_class_t ncu_class;
1406 1415
1407 1416 /* ncp must already be read */
1408 1417 if (ncp_h == NULL) {
1409 1418 nerr("Copy error: NCP has not been read");
1410 1419 goto done;
1411 1420 }
1412 1421 ncu_class = (nwam_ncu_class_t)cmd->cmd_ncu_class_type;
1413 1422 ncu_type = nwam_ncu_class_to_type(ncu_class);
1414 1423 ret = nwam_ncu_read(ncp_h, oldname, ncu_type, 0,
1415 1424 &oldncu_h);
1416 1425 if (ret != NWAM_SUCCESS)
1417 1426 goto read_error;
1418 1427 ret = nwam_ncu_copy(oldncu_h, newname, &ncu_h);
1419 1428 nwam_ncu_free(oldncu_h);
1420 1429 }
1421 1430
1422 1431 if (ret != NWAM_SUCCESS) {
1423 1432 nwamerr(ret, "Copy error");
1424 1433 goto done;
1425 1434 }
1426 1435 }
1427 1436
1428 1437 if (current_scope == NWAM_SCOPE_GBL) {
1429 1438 (void) strlcpy(obj1_name, newname, sizeof (obj1_name));
1430 1439 obj1_type = cmd->cmd_res1_type;
1431 1440 if (obj1_type == RT1_ENM)
1432 1441 current_scope = NWAM_SCOPE_ENM;
1433 1442 else if (obj1_type == RT1_LOC)
1434 1443 current_scope = NWAM_SCOPE_LOC;
1435 1444 else if (obj1_type == RT1_WLAN)
1436 1445 current_scope = NWAM_SCOPE_WLAN;
1437 1446 else if (obj1_type == RT1_NCP)
1438 1447 current_scope = NWAM_SCOPE_NCP;
1439 1448 } else {
1440 1449 (void) strlcpy(obj2_name, newname, sizeof (obj2_name));
1441 1450 current_scope = NWAM_SCOPE_NCU;
1442 1451 obj2_type = cmd->cmd_res2_type;
1443 1452 }
1444 1453 if (current_scope != NWAM_SCOPE_NCP)
1445 1454 need_to_commit = B_TRUE;
1446 1455
1447 1456 /* do a walk of the properties if in interactive mode */
1448 1457 if (interactive_mode && current_scope != NWAM_SCOPE_NCP) {
1449 1458 (void) printf(gettext("Created %s '%s'. "
1450 1459 "Walking properties ...\n"),
1451 1460 scope_to_str(current_scope), newname);
1452 1461 if ((walkprop_cmd = alloc_cmd()) == NULL)
1453 1462 goto done;
1454 1463 walkprop_func(walkprop_cmd);
1455 1464 free(walkprop_cmd);
1456 1465 }
1457 1466
1458 1467 read_error:
1459 1468 if (ret != NWAM_SUCCESS)
1460 1469 nwamerr(ret, "Copy error reading '%s'", oldname);
1461 1470
1462 1471 done:
1463 1472 free(oldname);
1464 1473 free(newname);
1465 1474 }
1466 1475
1467 1476 /* Processing of return value for destroy_*_callback() */
1468 1477 static int
1469 1478 destroy_ret(nwam_object_type_t object_type, nwam_error_t ret, void *handle)
1470 1479 {
1471 1480 if (ret == NWAM_ENTITY_NOT_DESTROYABLE) {
1472 1481 /* log a message to stderr, but don't consider it an error */
1473 1482 char *name;
1474 1483 if (object_name_from_handle(object_type, handle, &name)
1475 1484 == NWAM_SUCCESS) {
1476 1485 (void) fprintf(stderr,
1477 1486 gettext("%s '%s' cannot be removed\n"),
1478 1487 nwam_object_type_to_string(object_type), name);
1479 1488 free(name);
1480 1489 }
1481 1490 return (0);
1482 1491 }
1483 1492
1484 1493 if (ret == NWAM_SUCCESS || ret == NWAM_ENTITY_IN_USE)
1485 1494 return (0);
1486 1495
1487 1496 return (1);
1488 1497 }
1489 1498
1490 1499 /*
1491 1500 * NWAM_FLAG_DO_NOT_FREE is passed to nwam_*_destory() so that it does not
1492 1501 * free the handle. The calling nwam_walk_*() function frees this handle
1493 1502 * as it is the function that created the handle.
1494 1503 *
1495 1504 * Objects that are not destroyable or are active cannot be destroyed.
1496 1505 * Don't return error in these situations so the walk can continue.
1497 1506 */
1498 1507 /* ARGSUSED */
1499 1508 static int
1500 1509 destroy_ncp_callback(nwam_ncp_handle_t ncp, void *arg)
1501 1510 {
1502 1511 /* The file is deleted, so NCUs are also removed */
1503 1512 nwam_error_t ret = nwam_ncp_destroy(ncp, NWAM_FLAG_DO_NOT_FREE);
1504 1513 return (destroy_ret(NWAM_OBJECT_TYPE_NCP, ret, ncp));
1505 1514 }
1506 1515
1507 1516 /* ARGSUSED */
1508 1517 static int
1509 1518 destroy_loc_callback(nwam_loc_handle_t loc, void *arg)
1510 1519 {
1511 1520 nwam_error_t ret = nwam_loc_destroy(loc, NWAM_FLAG_DO_NOT_FREE);
1512 1521 return (destroy_ret(NWAM_OBJECT_TYPE_LOC, ret, loc));
1513 1522 }
1514 1523
1515 1524 /* ARGSUSED */
1516 1525 static int
1517 1526 destroy_enm_callback(nwam_enm_handle_t enm, void *arg)
1518 1527 {
1519 1528 nwam_error_t ret = nwam_enm_destroy(enm, NWAM_FLAG_DO_NOT_FREE);
1520 1529 return (destroy_ret(NWAM_OBJECT_TYPE_ENM, ret, enm));
1521 1530 }
1522 1531
1523 1532 /* ARGSUSED */
1524 1533 static int
1525 1534 destroy_wlan_callback(nwam_known_wlan_handle_t wlan, void *arg)
1526 1535 {
1527 1536 nwam_error_t ret = nwam_known_wlan_destroy(wlan, NWAM_FLAG_DO_NOT_FREE);
1528 1537 return (destroy_ret(NWAM_OBJECT_TYPE_KNOWN_WLAN, ret, wlan));
1529 1538 }
1530 1539
1531 1540 /*
1532 1541 * Remove all existing configuration that are not read-only.
1533 1542 * walk through all ncps, locs, enms, wlans and destroy each one.
1534 1543 */
1535 1544 static nwam_error_t
1536 1545 destroy_all(void)
1537 1546 {
1538 1547 nwam_error_t ret;
1539 1548
1540 1549 assert(remove_all_configurations);
1541 1550
1542 1551 ret = nwam_walk_ncps(destroy_ncp_callback, NULL, 0, NULL);
1543 1552 if (ret != NWAM_SUCCESS)
1544 1553 goto done;
1545 1554
1546 1555 ret = nwam_walk_enms(destroy_enm_callback, NULL,
1547 1556 NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
1548 1557 if (ret != NWAM_SUCCESS)
1549 1558 goto done;
1550 1559
1551 1560 ret = nwam_walk_locs(destroy_loc_callback, NULL,
1552 1561 NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
1553 1562 if (ret != NWAM_SUCCESS)
1554 1563 goto done;
1555 1564
1556 1565 ret = nwam_walk_known_wlans(destroy_wlan_callback, NULL, 0, NULL);
1557 1566 if (ret != NWAM_SUCCESS)
1558 1567 goto done;
1559 1568
1560 1569 if (interactive_mode)
1561 1570 (void) printf(gettext("All user-defined entities destroyed\n"));
1562 1571 remove_all_configurations = B_FALSE;
1563 1572
1564 1573 done:
1565 1574 if (ret != NWAM_SUCCESS) {
1566 1575 nwamerr(ret, "Destroy error: "
1567 1576 "could not destroy all configurations");
1568 1577 }
1569 1578 return (ret);
1570 1579 }
1571 1580
1572 1581 /*
1573 1582 * Destroys an instance in persistent repository, and is permanent.
1574 1583 * If interactive mode, it is allowed at global scope only
1575 1584 * option -a destroys everything.
1576 1585 */
1577 1586 void
1578 1587 destroy_func(cmd_t *cmd)
1579 1588 {
1580 1589 nwam_error_t ret;
1581 1590 char *name, *realname = NULL;
1582 1591
1583 1592 if (current_scope == NWAM_SCOPE_NCP &&
1584 1593 (cmd->cmd_res1_type == RT1_ENM || cmd->cmd_res1_type == RT1_LOC ||
1585 1594 cmd->cmd_res1_type == RT1_WLAN)) {
1586 1595 nerr("Destroy error: only NCUs can be destroyed in NCP scope");
1587 1596 return;
1588 1597 }
1589 1598
1590 1599 assert(cmd->cmd_argc > 0);
1591 1600
1592 1601 /* res1_type is -1 if -a flag is used */
1593 1602 if (cmd->cmd_res1_type == -1) {
1594 1603 int c;
1595 1604
1596 1605 if (current_scope != NWAM_SCOPE_GBL) {
1597 1606 nerr("Cannot destroy all configurations in a "
1598 1607 "non-global scope");
1599 1608 return;
1600 1609 }
1601 1610
1602 1611 optind = 0;
1603 1612 while ((c = getopt(cmd->cmd_argc, cmd->cmd_argv, "a")) != EOF) {
1604 1613 switch (c) {
1605 1614 case 'a':
1606 1615 remove_all_configurations = B_TRUE;
1607 1616 break;
1608 1617 default:
1609 1618 command_usage(CMD_DESTROY);
1610 1619 return;
1611 1620 }
1612 1621 }
1613 1622 if (remove_all_configurations) {
1614 1623 (void) destroy_all();
1615 1624 return;
1616 1625 }
1617 1626 }
1618 1627
1619 1628 /* argv[0] is name */
1620 1629 name = trim_quotes(cmd->cmd_argv[0]);
1621 1630 if (cmd->cmd_res2_type == RT2_NCU) {
1622 1631 nwam_ncu_type_t ncu_type;
1623 1632 nwam_ncu_class_t ncu_class;
1624 1633
1625 1634 /* ncp must already be read */
1626 1635 if (ncp_h == NULL) {
1627 1636 nerr("Destroy ncu error: NCP has not been read");
1628 1637 return;
1629 1638 }
1630 1639 ncu_class = (nwam_ncu_class_t)cmd->cmd_ncu_class_type;
1631 1640 ncu_type = nwam_ncu_class_to_type(ncu_class);
1632 1641 ret = nwam_ncu_read(ncp_h, name, ncu_type, 0, &ncu_h);
1633 1642 if (ret != NWAM_SUCCESS)
1634 1643 goto done;
1635 1644 (void) object_name_from_handle(NWAM_OBJECT_TYPE_NCU, ncu_h,
1636 1645 &realname);
1637 1646 ret = nwam_ncu_destroy(ncu_h, 0);
1638 1647 ncu_h = NULL;
1639 1648 } else if (cmd->cmd_res1_type == RT1_ENM) {
1640 1649 if ((ret = nwam_enm_read(name, 0, &enm_h)) != NWAM_SUCCESS)
1641 1650 goto done;
1642 1651 (void) object_name_from_handle(NWAM_OBJECT_TYPE_ENM, enm_h,
1643 1652 &realname);
1644 1653 ret = nwam_enm_destroy(enm_h, 0);
1645 1654 enm_h = NULL;
1646 1655 } else if (cmd->cmd_res1_type == RT1_LOC) {
1647 1656 if ((ret = nwam_loc_read(name, 0, &loc_h)) != NWAM_SUCCESS)
1648 1657 goto done;
1649 1658 (void) object_name_from_handle(NWAM_OBJECT_TYPE_LOC, loc_h,
1650 1659 &realname);
1651 1660 ret = nwam_loc_destroy(loc_h, 0);
1652 1661 loc_h = NULL;
1653 1662 } else if (cmd->cmd_res1_type == RT1_WLAN) {
1654 1663 if ((ret = nwam_known_wlan_read(name, 0, &wlan_h))
1655 1664 != NWAM_SUCCESS)
1656 1665 goto done;
1657 1666 (void) object_name_from_handle(NWAM_OBJECT_TYPE_KNOWN_WLAN,
1658 1667 wlan_h, &realname);
1659 1668 ret = nwam_known_wlan_destroy(wlan_h, 0);
1660 1669 wlan_h = NULL;
1661 1670 } else if (cmd->cmd_res1_type == RT1_NCP) {
1662 1671 if ((ret = nwam_ncp_read(name, 0, &ncp_h)) != NWAM_SUCCESS)
1663 1672 goto done;
1664 1673 (void) object_name_from_handle(NWAM_OBJECT_TYPE_NCP, ncp_h,
1665 1674 &realname);
1666 1675 ret = nwam_ncp_destroy(ncp_h, 0);
1667 1676 ncp_h = NULL;
1668 1677 } else {
1669 1678 nerr("Destroy error: unknown object-type");
1670 1679 }
1671 1680
1672 1681 done:
1673 1682 if (ret == NWAM_ENTITY_IN_USE) {
1674 1683 nerr("Destroy error: active entity cannot be destroyed");
1675 1684 } else if (ret != NWAM_SUCCESS) {
1676 1685 nwamerr(ret, "Destroy error");
1677 1686 } else if (interactive_mode) {
1678 1687 (void) printf(gettext("Destroyed %s '%s'\n"),
1679 1688 (cmd->cmd_res2_type == RT2_NCU ?
1680 1689 rt2_to_str(cmd->cmd_res2_type) :
1681 1690 rt1_to_str(cmd->cmd_res1_type)),
1682 1691 realname != NULL ? realname : name);
1683 1692 }
1684 1693 free(name);
1685 1694 free(realname);
1686 1695 }
1687 1696
1688 1697 /*
1689 1698 * End operation on current scope and go up one scope.
1690 1699 * Changes are saved.
1691 1700 */
1692 1701 /* ARGSUSED */
1693 1702 void
1694 1703 end_func(cmd_t *cmd)
1695 1704 {
1696 1705 /* if need_to_commit is set, commit changes */
1697 1706 if (need_to_commit)
1698 1707 do_commit();
1699 1708
1700 1709 /*
1701 1710 * Call do_cancel() to go up one scope. If commit fails,
1702 1711 * need_to_commit is not reset and users are asked if they want to end.
1703 1712 */
1704 1713 if (!need_to_commit ||
1705 1714 (need_to_commit && (ask_yesno(B_FALSE,
1706 1715 "Configuration not saved; really end")) == 1)) {
1707 1716 /* set time_to_exit if in global scope */
1708 1717 if (current_scope == NWAM_SCOPE_GBL)
1709 1718 time_to_exit = B_TRUE;
1710 1719 /* call do_cancel() to go up one scope */
1711 1720 do_cancel();
1712 1721 }
1713 1722 }
1714 1723
1715 1724 /*
1716 1725 * Exit immediately. Configuration changes are saved by calling end_func().
1717 1726 */
1718 1727 /* ARGSUSED */
1719 1728 void
1720 1729 exit_func(cmd_t *cmd)
1721 1730 {
1722 1731 cmd_t *end_cmd;
1723 1732
1724 1733 if (need_to_commit) {
1725 1734 if ((end_cmd = alloc_cmd()) == NULL) {
1726 1735 nerr("Exit error");
1727 1736 return;
1728 1737 }
1729 1738 end_func(end_cmd);
1730 1739 free_cmd(end_cmd);
1731 1740 }
1732 1741
1733 1742 /*
1734 1743 * If need_to_commit is still set, then the commit failed.
1735 1744 * Otherwise, exit.
1736 1745 */
1737 1746 if (!need_to_commit)
1738 1747 time_to_exit = B_TRUE;
1739 1748 }
1740 1749
1741 1750 void
1742 1751 help_func(cmd_t *cmd)
1743 1752 {
1744 1753 int i;
1745 1754
1746 1755 if (cmd->cmd_argc == 0) {
1747 1756 (void) printf(gettext("commands:\n"));
1748 1757 for (i = CMD_MIN; i <= CMD_MAX; i++)
1749 1758 (void) printf("\t%s\n", helptab[i].cmd_usage);
1750 1759 return;
1751 1760 }
1752 1761
1753 1762 for (i = CMD_MIN; i <= CMD_MAX; i++) {
1754 1763 if (strcmp(cmd->cmd_argv[0], cmd_to_str(i)) == 0) {
1755 1764 long_usage(i);
1756 1765 return;
1757 1766 }
1758 1767 }
1759 1768 (void) fprintf(stderr, gettext("Unknown command: '%s'\n"),
1760 1769 cmd->cmd_argv[0]);
1761 1770 help_wrap();
1762 1771 }
1763 1772
1764 1773 /*
1765 1774 * Revert configuration of an instance to latest previous version.
1766 1775 * Free the handle and read again.
1767 1776 */
1768 1777 /* ARGSUSED */
1769 1778 void
1770 1779 revert_func(cmd_t *cmd)
1771 1780 {
1772 1781 nwam_error_t ret;
1773 1782 char *name = NULL;
1774 1783 nwam_ncu_type_t ncu_type;
1775 1784 nwam_object_type_t object_type = active_object_type();
1776 1785
1777 1786 switch (object_type) {
1778 1787 case NWAM_OBJECT_TYPE_NCU:
1779 1788 /* retrieve name and type to use later */
1780 1789 if ((ret = nwam_ncu_get_ncu_type(ncu_h, &ncu_type))
1781 1790 != NWAM_SUCCESS) {
1782 1791 nwamerr(ret, "Revert error: Get ncu type error");
1783 1792 return;
1784 1793 }
1785 1794 if ((ret = nwam_ncu_get_name(ncu_h, &name)) != NWAM_SUCCESS)
1786 1795 goto name_error;
1787 1796 nwam_ncu_free(ncu_h);
1788 1797 ncu_h = NULL;
1789 1798 ret = nwam_ncu_read(ncp_h, name, ncu_type, 0, &ncu_h);
1790 1799 break;
1791 1800 case NWAM_OBJECT_TYPE_ENM:
1792 1801 if ((ret = nwam_enm_get_name(enm_h, &name)) != NWAM_SUCCESS)
1793 1802 goto name_error;
1794 1803 nwam_enm_free(enm_h);
1795 1804 enm_h = NULL;
1796 1805 ret = nwam_enm_read(name, 0, &enm_h);
1797 1806 break;
1798 1807 case NWAM_OBJECT_TYPE_LOC:
1799 1808 if ((ret = nwam_loc_get_name(loc_h, &name)) != NWAM_SUCCESS)
1800 1809 goto name_error;
1801 1810 nwam_loc_free(loc_h);
1802 1811 loc_h = NULL;
1803 1812 ret = nwam_loc_read(name, 0, &loc_h);
1804 1813 break;
1805 1814 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
1806 1815 if ((ret = nwam_known_wlan_get_name(wlan_h, &name))
1807 1816 != NWAM_SUCCESS)
1808 1817 goto name_error;
1809 1818 nwam_known_wlan_free(wlan_h);
1810 1819 wlan_h = NULL;
1811 1820 ret = nwam_known_wlan_read(name, 0, &wlan_h);
1812 1821 break;
1813 1822 }
1814 1823
1815 1824 /* Exit this scope because handle already freed (call do_cancel()) */
1816 1825 need_to_commit = B_FALSE;
1817 1826
1818 1827 if (ret != NWAM_SUCCESS) {
1819 1828 if (ret == NWAM_ENTITY_NOT_FOUND) {
1820 1829 nerr("%s '%s' does not exist to revert to, removing it",
1821 1830 nwam_object_type_to_string(object_type), name);
1822 1831 } else {
1823 1832 nwamerr(ret, "Revert error");
1824 1833 }
1825 1834 do_cancel();
1826 1835 }
1827 1836 free(name);
1828 1837 return;
1829 1838
1830 1839 name_error:
1831 1840 if (ret != NWAM_SUCCESS)
1832 1841 nwamerr(ret, "Revert error: get name error");
1833 1842 }
1834 1843
1835 1844 /*
1836 1845 * Load a resource from persistent repository and enter the scope
1837 1846 * of that resource.
1838 1847 */
1839 1848 void
1840 1849 select_func(cmd_t *cmd)
1841 1850 {
1842 1851 nwam_error_t ret;
1843 1852 char *name, *realname = NULL;
1844 1853
1845 1854 assert(cmd->cmd_argc > 0);
1846 1855 if (current_scope == NWAM_SCOPE_NCP && cmd->cmd_res2_type != RT2_NCU) {
1847 1856 nerr("cannot select '%s' at this scope",
1848 1857 rt1_to_str(cmd->cmd_res1_type));
1849 1858 return;
1850 1859 }
1851 1860
1852 1861 /* argv[0] is name */
1853 1862 name = trim_quotes(cmd->cmd_argv[0]);
1854 1863 switch (cmd->cmd_res1_type) {
1855 1864 case RT1_LOC:
1856 1865 ret = nwam_loc_read(name, 0, &loc_h);
1857 1866 if (ret == NWAM_SUCCESS) {
1858 1867 current_scope = NWAM_SCOPE_LOC;
1859 1868 (void) object_name_from_handle(NWAM_OBJECT_TYPE_LOC,
1860 1869 loc_h, &realname);
1861 1870 }
1862 1871 break;
1863 1872 case RT1_ENM:
1864 1873 ret = nwam_enm_read(name, 0, &enm_h);
1865 1874 if (ret == NWAM_SUCCESS) {
1866 1875 current_scope = NWAM_SCOPE_ENM;
1867 1876 (void) object_name_from_handle(NWAM_OBJECT_TYPE_ENM,
1868 1877 enm_h, &realname);
1869 1878 }
1870 1879 break;
1871 1880 case RT1_WLAN:
1872 1881 ret = nwam_known_wlan_read(name, 0, &wlan_h);
1873 1882 if (ret == NWAM_SUCCESS) {
1874 1883 current_scope = NWAM_SCOPE_WLAN;
1875 1884 (void) object_name_from_handle
1876 1885 (NWAM_OBJECT_TYPE_KNOWN_WLAN, wlan_h, &realname);
1877 1886 }
1878 1887 break;
1879 1888 case RT1_NCP:
1880 1889 if (cmd->cmd_res2_type == RT2_NCU) {
1881 1890 nwam_ncu_type_t ncu_type;
1882 1891 nwam_ncu_class_t ncu_class;
1883 1892
1884 1893 /* ncp must already be read */
1885 1894 if (ncp_h == NULL) {
1886 1895 nerr("Select error: NCP has not been read");
1887 1896 free(name);
1888 1897 return;
1889 1898 }
1890 1899 ncu_class = (nwam_ncu_class_t)cmd->cmd_ncu_class_type;
1891 1900 ncu_type = nwam_ncu_class_to_type(ncu_class);
1892 1901 ret = nwam_ncu_read(ncp_h, name, ncu_type, 0, &ncu_h);
1893 1902 if (ret == NWAM_SUCCESS) {
1894 1903 current_scope = NWAM_SCOPE_NCU;
1895 1904 (void) object_name_from_handle
1896 1905 (NWAM_OBJECT_TYPE_NCU, ncu_h, &realname);
1897 1906 }
1898 1907 } else {
1899 1908 ret = nwam_ncp_read(name, 0, &ncp_h);
1900 1909 if (ret == NWAM_SUCCESS) {
1901 1910 current_scope = NWAM_SCOPE_NCP;
1902 1911 (void) object_name_from_handle
1903 1912 (NWAM_OBJECT_TYPE_NCP, ncp_h, &realname);
1904 1913 }
1905 1914 }
1906 1915 break;
1907 1916 default:
1908 1917 nerr("Select error: unknown object-type");
1909 1918 free(name);
1910 1919 return;
1911 1920 }
1912 1921
1913 1922 if (ret != NWAM_SUCCESS) {
1914 1923 nwamerr(ret, "Select error");
1915 1924 } else {
1916 1925 /* set the obj*_name or obj*_type depending on current scope */
1917 1926 if (current_scope == NWAM_SCOPE_NCU) {
1918 1927 obj2_type = RT2_NCU;
1919 1928 (void) strlcpy(obj2_name,
1920 1929 realname != NULL ? realname : name,
1921 1930 sizeof (obj2_name));
1922 1931 } else {
1923 1932 (void) strlcpy(obj1_name,
1924 1933 realname != NULL ? realname : name,
1925 1934 sizeof (obj1_name));
1926 1935 obj1_type = cmd->cmd_res1_type;
1927 1936 }
1928 1937 }
1929 1938 free(name);
1930 1939 free(realname);
1931 1940 }
1932 1941
1933 1942 /* Given an int for prop, returns it as string */
1934 1943 static const char *
1935 1944 pt_to_prop_name(nwam_object_type_t object_type, int pt_type)
1936 1945 {
1937 1946 int i;
1938 1947 prop_table_entry_t *prop_table = get_prop_table(object_type);
1939 1948
1940 1949 for (i = 0; prop_table[i].pte_name != NULL; i++) {
1941 1950 if (pt_type == prop_table[i].pte_type)
1942 1951 return (prop_table[i].pte_name);
1943 1952 }
1944 1953 return (NULL);
1945 1954 }
1946 1955
1947 1956 /* Given a prop as a string, returns it as an int */
1948 1957 static int
1949 1958 prop_to_pt(nwam_object_type_t object_type, const char *prop)
1950 1959 {
1951 1960 int i;
1952 1961 prop_table_entry_t *prop_table = get_prop_table(object_type);
1953 1962
1954 1963 for (i = 0; prop_table[i].pte_name != NULL; i++) {
1955 1964 if (strcmp(prop, prop_table[i].pte_name) == 0)
1956 1965 return (prop_table[i].pte_type);
1957 1966 }
1958 1967 return (-1);
1959 1968 }
1960 1969
1961 1970 /* Given a prop as an int, returns its type (nwam_value_type_t) */
1962 1971 static nwam_value_type_t
1963 1972 prop_value_type(nwam_object_type_t object_type, const char *prop)
1964 1973 {
1965 1974 nwam_error_t ret;
1966 1975 nwam_value_type_t value_type;
1967 1976
1968 1977 switch (object_type) {
1969 1978 case NWAM_OBJECT_TYPE_NCU:
1970 1979 ret = nwam_ncu_get_prop_type(prop, &value_type);
1971 1980 break;
1972 1981 case NWAM_OBJECT_TYPE_LOC:
1973 1982 ret = nwam_loc_get_prop_type(prop, &value_type);
1974 1983 break;
1975 1984 case NWAM_OBJECT_TYPE_ENM:
1976 1985 ret = nwam_enm_get_prop_type(prop, &value_type);
1977 1986 break;
1978 1987 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
1979 1988 ret = nwam_known_wlan_get_prop_type(prop, &value_type);
1980 1989 break;
1981 1990 }
1982 1991
1983 1992 if (ret != NWAM_SUCCESS)
1984 1993 value_type = NWAM_VALUE_TYPE_UNKNOWN;
1985 1994
1986 1995 return (value_type);
1987 1996 }
1988 1997
1989 1998 /*
1990 1999 * Converts input_str to an array nwam_value.
1991 2000 * If is_list_prop, break input_str into array of strings first.
1992 2001 */
1993 2002 static nwam_value_t
1994 2003 str_to_nwam_value(nwam_object_type_t object_type, char *input_str, int pt_type,
1995 2004 boolean_t is_list_prop)
1996 2005 {
1997 2006 int i, n = 0, ret;
1998 2007 nwam_value_t data;
1999 2008 char **val;
2000 2009 int max_str_num;
2001 2010
2002 2011 nwam_value_type_t value_type;
2003 2012 int64_t *int_vals;
2004 2013 uint64_t *uint_vals;
2005 2014 boolean_t *boolean_vals;
2006 2015
2007 2016 /*
2008 2017 * Worst case is that each char separated by DELIMITER, so the
2009 2018 * max number of sub strings is half of string length + 1.
2010 2019 */
2011 2020 max_str_num = strlen(input_str) / 2 + 1;
2012 2021
2013 2022 val = calloc(max_str_num, sizeof (char *));
2014 2023 if (val == NULL) {
2015 2024 nerr("Out of memory");
2016 2025 return (NULL);
2017 2026 }
2018 2027
2019 2028 if (is_list_prop) {
2020 2029 char *tmp, *next;
2021 2030 /*
2022 2031 * Break down input_str and save as array of sub strings.
2023 2032 * Set num as the number of the sub strings.
2024 2033 * Use nwam_tokenize_by_unescaped_delim() rather than strtok()
2025 2034 * because DELIMITER may be escaped
2026 2035 */
2027 2036 tmp = (char *)input_str;
2028 2037 while ((tmp = nwam_tokenize_by_unescaped_delim(tmp,
2029 2038 NWAM_VALUE_DELIMITER_CHAR, &next)) != NULL) {
2030 2039 val[n++] = trim_quotes(tmp);
2031 2040 tmp = next;
2032 2041 }
2033 2042 } else {
2034 2043 val[n++] = trim_quotes(input_str);
2035 2044 }
2036 2045
2037 2046 /* initialize int_vals or booleans_vals depending on pt_type */
2038 2047 value_type = prop_value_type(object_type,
2039 2048 pt_to_prop_name(object_type, pt_type));
2040 2049 if (value_type == NWAM_VALUE_TYPE_INT64) {
2041 2050 int_vals = calloc(n, sizeof (int64_t));
2042 2051 if (int_vals == NULL) {
2043 2052 nerr("Out of memory");
2044 2053 array_free((void **)val, max_str_num);
2045 2054 return (NULL);
2046 2055 }
2047 2056 } else if (value_type == NWAM_VALUE_TYPE_UINT64) {
2048 2057 uint_vals = calloc(n, sizeof (uint64_t));
2049 2058 if (uint_vals == NULL) {
2050 2059 nerr("Out of memory");
2051 2060 array_free((void **)val, max_str_num);
2052 2061 return (NULL);
2053 2062 }
2054 2063 } else if (value_type == NWAM_VALUE_TYPE_BOOLEAN) {
2055 2064 boolean_vals = calloc(n, sizeof (boolean_t));
2056 2065 if (boolean_vals == NULL) {
2057 2066 nerr("Out of memory");
2058 2067 array_free((void **)val, max_str_num);
2059 2068 return (NULL);
2060 2069 }
2061 2070 }
2062 2071 /* set the appropriate array */
2063 2072 for (i = 0; i < n; i++) {
2064 2073 switch (value_type) {
2065 2074 case NWAM_VALUE_TYPE_STRING:
2066 2075 /* nothing to do - val already has the char** array */
2067 2076 break;
2068 2077 case NWAM_VALUE_TYPE_INT64:
2069 2078 {
2070 2079 int_vals[i] = (int64_t)atoi(val[i]);
2071 2080 break;
2072 2081 }
2073 2082 case NWAM_VALUE_TYPE_UINT64:
2074 2083 {
2075 2084 uint64_t str_as_enum;
2076 2085 char *endptr;
2077 2086
2078 2087 ret = nwam_value_string_get_uint64(
2079 2088 pt_to_prop_name(object_type, pt_type),
2080 2089 val[i], &str_as_enum);
2081 2090 /*
2082 2091 * Returns _SUCCESS if value for enum is valid.
2083 2092 * Returns _INVALID_ARG if property is not an enum.
2084 2093 */
2085 2094 if (ret == NWAM_SUCCESS) {
2086 2095 uint_vals[i] = str_as_enum;
2087 2096 } else if (ret == NWAM_INVALID_ARG) {
2088 2097 uint_vals[i] = strtoul(val[i], &endptr, 10);
2089 2098 /* verify conversion is valid */
2090 2099 if (endptr == val[i]) {
2091 2100 free(uint_vals);
2092 2101 array_free((void **)val, max_str_num);
2093 2102 return (NULL);
2094 2103 }
2095 2104 } else {
2096 2105 free(uint_vals);
2097 2106 array_free((void **)val, max_str_num);
2098 2107 return (NULL);
2099 2108 }
2100 2109 break;
2101 2110 }
2102 2111 case NWAM_VALUE_TYPE_BOOLEAN:
2103 2112 boolean_vals[i] = str_to_boolean(val[i]);
2104 2113 break;
2105 2114 default:
2106 2115 array_free((void **)val, max_str_num);
2107 2116 return (NULL);
2108 2117 }
2109 2118 }
2110 2119
2111 2120 /* create nwam_value_t */
2112 2121 if (value_type == NWAM_VALUE_TYPE_STRING) {
2113 2122 ret = nwam_value_create_string_array(val, n, &data);
2114 2123 } else if (value_type == NWAM_VALUE_TYPE_INT64) {
2115 2124 ret = nwam_value_create_int64_array(int_vals, n, &data);
2116 2125 free(int_vals);
2117 2126 } else if (value_type == NWAM_VALUE_TYPE_UINT64) {
2118 2127 ret = nwam_value_create_uint64_array(uint_vals, n, &data);
2119 2128 free(uint_vals);
2120 2129 } else if (value_type == NWAM_VALUE_TYPE_BOOLEAN) {
2121 2130 ret = nwam_value_create_boolean_array(boolean_vals, n, &data);
2122 2131 free(boolean_vals);
2123 2132 }
2124 2133 array_free((void **)val, max_str_num);
2125 2134
2126 2135 if (ret != NWAM_SUCCESS) {
2127 2136 nwamerr(ret, "Failed creating nwam_value");
2128 2137 return (NULL);
2129 2138 }
2130 2139
2131 2140 return (data);
2132 2141 }
2133 2142
2134 2143 /*
2135 2144 * Displaying/Skipping of properties
2136 2145 * ---------------------------------
2137 2146 *
2138 2147 * This table shows if a specific property should be shown if some
2139 2148 * other property has a specific value. This table is used by
2140 2149 * show_prop_test(), which is called by set_func() and walkprop_func().
2141 2150 *
2142 2151 * An entry in the table looks like:
2143 2152 * { property1, property2, { val1, val2, -1 } }
2144 2153 * This is read as:
2145 2154 * "show property1 only if property2 has value val1 or val2"
2146 2155 *
2147 2156 * NB: If a property does not appear in this table, then that implies
2148 2157 * that the property is always shown.
2149 2158 *
2150 2159 * A property can have more than one rule. In such a case, the property is
2151 2160 * displayed only any of the rules is satisfied. This checking, however,
2152 2161 * is recursive. If a rule says that a property can be displayed, then the
2153 2162 * property that's checked should also satisfy its rules. In the above
2154 2163 * example, if property1 is to be displayed, then property2 should also
2155 2164 * satisfy its rules and be displayable. This recursion is necessary as
2156 2165 * properties that are not displayed (because rules are not satisfied) are
2157 2166 * not deleted.
2158 2167 */
2159 2168
2160 2169 /* The most number of values in pde_checkvals below */
2161 2170 #define NWAM_CHECKVALS_MAX 5
2162 2171
2163 2172 typedef struct prop_display_entry {
2164 2173 const char *pde_name; /* property to show */
2165 2174 const char *pde_checkname; /* property to check */
2166 2175 int64_t pde_checkvals[NWAM_CHECKVALS_MAX]; /* show prop for these */
2167 2176 } prop_display_entry_t;
2168 2177
2169 2178 /* Rules for showing properties: commented for clarity */
2170 2179
2171 2180 /*
2172 2181 * Rules for NCUs
2173 2182 * NB: There is no need to have an entry if a property is for IP only.
2174 2183 * This is taken care of in libnwam_ncp.c
2175 2184 */
2176 2185 static prop_display_entry_t ncu_prop_display_entry_table[] = {
2177 2186 /* show priority-{group,mode} if activation == prioritized */
2178 2187 { NWAM_NCU_PROP_PRIORITY_GROUP, NWAM_NCU_PROP_ACTIVATION_MODE,
2179 2188 { NWAM_ACTIVATION_MODE_PRIORITIZED, -1 } },
2180 2189 { NWAM_NCU_PROP_PRIORITY_MODE, NWAM_NCU_PROP_ACTIVATION_MODE,
2181 2190 { NWAM_ACTIVATION_MODE_PRIORITIZED, -1 } },
2182 2191 /* show ipv4-addrsrc if ip-version == ipv4 */
2183 2192 { NWAM_NCU_PROP_IPV4_ADDRSRC, NWAM_NCU_PROP_IP_VERSION,
2184 2193 { IPV4_VERSION, -1 } },
2185 2194 /* show ipv4-addr if ipv4-addrsrc == static */
2186 2195 { NWAM_NCU_PROP_IPV4_ADDR, NWAM_NCU_PROP_IPV4_ADDRSRC,
2187 2196 { NWAM_ADDRSRC_STATIC, -1 } },
2188 2197 /* show ipv4-default-route if ip-version == ipv4 */
2189 2198 { NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE, NWAM_NCU_PROP_IP_VERSION,
|
↓ open down ↓ |
1508 lines elided |
↑ open up ↑ |
2190 2199 { IPV4_VERSION, -1 } },
2191 2200 /* show ipv6-addrsrc if ip-version == ipv6 */
2192 2201 { NWAM_NCU_PROP_IPV6_ADDRSRC, NWAM_NCU_PROP_IP_VERSION,
2193 2202 { IPV6_VERSION, -1 } },
2194 2203 /* show ipv6-addr if ipv6-addrsrc == static */
2195 2204 { NWAM_NCU_PROP_IPV6_ADDR, NWAM_NCU_PROP_IPV6_ADDRSRC,
2196 2205 { NWAM_ADDRSRC_STATIC, -1 } },
2197 2206 /* show ipv6-default-route if ip-version == ipv6 */
2198 2207 { NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE, NWAM_NCU_PROP_IP_VERSION,
2199 2208 { IPV6_VERSION, -1 } },
2209 + /* show ip-primary if ipv4-addrsrc == dhcp */
2210 + { NWAM_NCU_PROP_IP_PRIMARY, NWAM_NCU_PROP_IPV4_ADDRSRC,
2211 + { NWAM_ADDRSRC_DHCP, -1 } },
2212 + /* show ip-primary if ipv6-addrsrc == dhcp */
2213 + { NWAM_NCU_PROP_IP_PRIMARY, NWAM_NCU_PROP_IPV6_ADDRSRC,
2214 + { NWAM_ADDRSRC_DHCP, -1 } },
2215 + /* show ip-reqhost if ipv4-addrsrc == dhcp */
2216 + { NWAM_NCU_PROP_IP_REQHOST, NWAM_NCU_PROP_IPV4_ADDRSRC,
2217 + { NWAM_ADDRSRC_DHCP, -1 } },
2218 + /* show ip-reqhost if ipv6-addrsrc == dhcp */
2219 + { NWAM_NCU_PROP_IP_REQHOST, NWAM_NCU_PROP_IPV6_ADDRSRC,
2220 + { NWAM_ADDRSRC_DHCP, -1 } },
2200 2221 { NULL, NULL, { -1 } }
2201 2222 };
2202 2223
2203 2224 /* Rules for ENMs */
2204 2225 static prop_display_entry_t enm_prop_display_entry_table[] = {
2205 2226 /* show conditions if activation-mode == conditional-{all,any} */
2206 2227 { NWAM_ENM_PROP_CONDITIONS, NWAM_ENM_PROP_ACTIVATION_MODE,
2207 2228 { NWAM_ACTIVATION_MODE_CONDITIONAL_ALL,
2208 2229 NWAM_ACTIVATION_MODE_CONDITIONAL_ANY, -1 } },
2209 2230 { NULL, NULL, { -1 } }
2210 2231 };
2211 2232
2212 2233 /* Rules for LOCations */
2213 2234 static prop_display_entry_t loc_prop_display_entry_table[] = {
2214 2235 /* show conditions if activation-mode == conditional-{all,any} */
2215 2236 { NWAM_LOC_PROP_CONDITIONS, NWAM_LOC_PROP_ACTIVATION_MODE,
2216 2237 { NWAM_ACTIVATION_MODE_CONDITIONAL_ALL,
2217 2238 NWAM_ACTIVATION_MODE_CONDITIONAL_ANY, -1 } },
2218 2239 /* show dns-nameservice-configsrc if nameservices == dns */
2219 2240 { NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC, NWAM_LOC_PROP_NAMESERVICES,
2220 2241 { NWAM_NAMESERVICES_DNS, -1 } },
2221 2242 /* show other DNS options if dns-nameservices-configsrc == manual */
2222 2243 { NWAM_LOC_PROP_DNS_NAMESERVICE_DOMAIN,
2223 2244 NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC,
2224 2245 { NWAM_CONFIGSRC_MANUAL, -1 } },
2225 2246 { NWAM_LOC_PROP_DNS_NAMESERVICE_SERVERS,
2226 2247 NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC,
2227 2248 { NWAM_CONFIGSRC_MANUAL, -1 } },
2228 2249 { NWAM_LOC_PROP_DNS_NAMESERVICE_SEARCH,
2229 2250 NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC,
2230 2251 { NWAM_CONFIGSRC_MANUAL, -1 } },
2231 2252 /* show nis-nameservice-configsrc if nameservices == nis */
2232 2253 { NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC, NWAM_LOC_PROP_NAMESERVICES,
2233 2254 { NWAM_NAMESERVICES_NIS, -1 } },
2234 2255 /* show nis-nameservice-servers if nis-nameservice-configsrc = manual */
2235 2256 { NWAM_LOC_PROP_NIS_NAMESERVICE_SERVERS,
2236 2257 NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC,
2237 2258 { NWAM_CONFIGSRC_MANUAL, -1 } },
2238 2259 /* show ldap-nameservice-configsrc if nameservices == ldap */
2239 2260 { NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC, NWAM_LOC_PROP_NAMESERVICES,
2240 2261 { NWAM_NAMESERVICES_LDAP, -1 } },
2241 2262 /* show ldap-nameservice-servers if ldap-nameservice-configsrc=manual */
2242 2263 { NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS,
2243 2264 NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC,
2244 2265 { NWAM_CONFIGSRC_MANUAL, -1 } },
2245 2266 /* show default-domain if {nis,ldap}-nameservice-configsrc == manual */
2246 2267 { NWAM_LOC_PROP_DEFAULT_DOMAIN, NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC,
2247 2268 { NWAM_CONFIGSRC_MANUAL, -1 } },
2248 2269 { NWAM_LOC_PROP_DEFAULT_DOMAIN,
2249 2270 NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC,
2250 2271 { NWAM_CONFIGSRC_MANUAL, -1 } },
2251 2272 { NULL, NULL, { -1 } }
2252 2273 };
2253 2274
2254 2275 /* Rules for Known WLANs */
2255 2276 static prop_display_entry_t wlan_prop_display_entry_table[] = {
2256 2277 /* no rules for WLANs */
2257 2278 { NULL, NULL, { -1 } }
2258 2279 };
2259 2280
2260 2281 /* Returns the appropriate rules table for the given object type */
2261 2282 static prop_display_entry_t *
2262 2283 get_prop_display_table(nwam_object_type_t object_type)
2263 2284 {
2264 2285 switch (object_type) {
2265 2286 case NWAM_OBJECT_TYPE_NCU:
2266 2287 return (ncu_prop_display_entry_table);
2267 2288 case NWAM_OBJECT_TYPE_LOC:
2268 2289 return (loc_prop_display_entry_table);
2269 2290 case NWAM_OBJECT_TYPE_ENM:
2270 2291 return (enm_prop_display_entry_table);
2271 2292 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
2272 2293 return (wlan_prop_display_entry_table);
2273 2294 }
2274 2295 return (NULL);
2275 2296 }
2276 2297
2277 2298 /*
2278 2299 * Tests whether prop must be shown during a walk depending on the
2279 2300 * value of a different property.
2280 2301 *
2281 2302 * This function is also used by set_func() to determine whether the
2282 2303 * property being set should be allowed or not. If the property
2283 2304 * would not be displayed in a walk, then it should not be set.
2284 2305 *
2285 2306 * The checked_props and num_checked arguments are used to avoid circular
2286 2307 * dependencies between properties. When this function recursively calls
2287 2308 * itself, it adds the property that it just checked to the checked_props
2288 2309 * list.
2289 2310 */
2290 2311 static boolean_t
2291 2312 show_prop_test(nwam_object_type_t object_type, const char *prop,
2292 2313 prop_display_entry_t *display_list, char **checked_props, int num_checked)
2293 2314 {
2294 2315 nwam_error_t ret;
2295 2316 nwam_value_t prop_val;
2296 2317 nwam_value_type_t prop_type;
2297 2318 int i, j, k;
2298 2319 boolean_t prop_found = B_FALSE, show_prop = B_FALSE;
2299 2320
2300 2321 /*
2301 2322 * Check if this property has already been checked previously in
2302 2323 * the recursion. If so, return B_FALSE so that the initial prop
2303 2324 * is not displayed.
2304 2325 */
2305 2326 for (i = 0; i < num_checked; i++) {
2306 2327 if (strcmp(prop, checked_props[i]) == 0) {
2307 2328 free(checked_props);
2308 2329 return (B_FALSE);
2309 2330 }
2310 2331 }
2311 2332
2312 2333 for (i = 0; display_list[i].pde_name != NULL; i++) {
2313 2334 if (strcmp(prop, display_list[i].pde_name) != 0)
2314 2335 continue;
2315 2336 prop_found = B_TRUE;
2316 2337
2317 2338 /* get the value(s) of the (other) property to check */
2318 2339 switch (object_type) {
2319 2340 case NWAM_OBJECT_TYPE_NCU:
2320 2341 ret = nwam_ncu_get_prop_value(ncu_h,
2321 2342 display_list[i].pde_checkname, &prop_val);
2322 2343 break;
2323 2344 case NWAM_OBJECT_TYPE_LOC:
2324 2345 ret = nwam_loc_get_prop_value(loc_h,
2325 2346 display_list[i].pde_checkname, &prop_val);
2326 2347 break;
2327 2348 case NWAM_OBJECT_TYPE_ENM:
2328 2349 ret = nwam_enm_get_prop_value(enm_h,
2329 2350 display_list[i].pde_checkname, &prop_val);
2330 2351 break;
2331 2352 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
2332 2353 return (B_TRUE);
2333 2354 }
2334 2355 if (ret != NWAM_SUCCESS)
2335 2356 continue;
2336 2357
2337 2358 /* prop_val may contain a uint64 array or a boolean */
2338 2359 if (nwam_value_get_type(prop_val, &prop_type) != NWAM_SUCCESS)
2339 2360 continue;
2340 2361
2341 2362 if (prop_type == NWAM_VALUE_TYPE_UINT64) {
2342 2363 uint64_t *prop_uvals;
2343 2364 int64_t *check_uvals;
2344 2365 uint_t numvals;
2345 2366
2346 2367 if (nwam_value_get_uint64_array(prop_val, &prop_uvals,
2347 2368 &numvals) != NWAM_SUCCESS) {
2348 2369 nwam_value_free(prop_val);
2349 2370 continue;
2350 2371 }
2351 2372
2352 2373 /* for each value in uvals, check each value in table */
2353 2374 for (j = 0; j < numvals; j++) {
2354 2375 check_uvals = display_list[i].pde_checkvals;
2355 2376 for (k = 0; check_uvals[k] != -1; k++) {
2356 2377 /* show if uvals[j] matches */
2357 2378 if (prop_uvals[j] ==
2358 2379 (uint64_t)check_uvals[k]) {
2359 2380 show_prop = B_TRUE;
2360 2381 goto next_rule;
2361 2382 }
2362 2383 }
2363 2384 }
2364 2385 } else if (prop_type == NWAM_VALUE_TYPE_BOOLEAN) {
2365 2386 boolean_t bval;
2366 2387
2367 2388 if (nwam_value_get_boolean(prop_val, &bval) !=
2368 2389 NWAM_SUCCESS) {
2369 2390 nwam_value_free(prop_val);
2370 2391 continue;
2371 2392 }
2372 2393
2373 2394 for (k = 0;
2374 2395 display_list[i].pde_checkvals[k] != -1;
2375 2396 k++) {
2376 2397 /* show if bval matches */
2377 2398 if (bval == (boolean_t)
2378 2399 display_list[i].pde_checkvals[k]) {
2379 2400 show_prop = B_TRUE;
2380 2401 goto next_rule;
2381 2402 }
2382 2403 }
2383 2404 }
2384 2405
2385 2406 next_rule:
2386 2407 nwam_value_free(prop_val);
2387 2408 /*
2388 2409 * If show_prop is set, then a rule is satisfied; no need to
2389 2410 * check other rules for this prop. However, recursively
2390 2411 * check if the checked prop (pde_checkname) satisfies its
2391 2412 * rules. Also, update the check_props array with this prop.
2392 2413 */
2393 2414 if (show_prop) {
2394 2415 char **newprops = realloc(checked_props,
2395 2416 ++num_checked * sizeof (char *));
2396 2417 if (newprops == NULL) {
2397 2418 free(checked_props);
2398 2419 return (B_FALSE);
2399 2420 }
2400 2421 checked_props = newprops;
2401 2422 checked_props[num_checked - 1] = (char *)prop;
2402 2423
2403 2424 return (show_prop_test(object_type,
2404 2425 display_list[i].pde_checkname, display_list,
2405 2426 checked_props, num_checked));
2406 2427 }
2407 2428 }
2408 2429
2409 2430 /*
2410 2431 * If we are here and prop_found is set, it means that no rules were
2411 2432 * satisfied by prop; return B_FALSE. If prop_found is not set, then
2412 2433 * prop did not have a rule so it must be displayed; return B_TRUE.
2413 2434 */
2414 2435 free(checked_props);
2415 2436 if (prop_found)
2416 2437 return (B_FALSE);
2417 2438 else
2418 2439 return (B_TRUE);
2419 2440 }
2420 2441
2421 2442 /*
2422 2443 * Returns true if the given property is read-only and cannot be modified.
2423 2444 */
2424 2445 static boolean_t
2425 2446 is_prop_read_only(nwam_object_type_t object_type, const char *prop)
2426 2447 {
2427 2448 boolean_t ro;
2428 2449
2429 2450 switch (object_type) {
2430 2451 case NWAM_OBJECT_TYPE_NCU:
2431 2452 if (nwam_ncu_prop_read_only(prop, &ro) == NWAM_SUCCESS && ro)
2432 2453 return (B_TRUE);
2433 2454 break;
2434 2455 case NWAM_OBJECT_TYPE_ENM:
2435 2456 if (nwam_enm_prop_read_only(prop, &ro) == NWAM_SUCCESS && ro)
2436 2457 return (B_TRUE);
2437 2458 break;
2438 2459 case NWAM_OBJECT_TYPE_LOC:
2439 2460 if (nwam_loc_prop_read_only(prop, &ro) == NWAM_SUCCESS && ro)
2440 2461 return (B_TRUE);
2441 2462 break;
2442 2463 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
2443 2464 /* no read-only properties for WLANs */
2444 2465 return (B_FALSE);
2445 2466 }
2446 2467 return (B_FALSE);
2447 2468 }
2448 2469
2449 2470 /* Returns true if the property is multi-valued */
2450 2471 static boolean_t
2451 2472 is_prop_multivalued(nwam_object_type_t object_type, const char *prop)
2452 2473 {
2453 2474 nwam_error_t ret;
2454 2475 boolean_t multi;
2455 2476
2456 2477 switch (object_type) {
2457 2478 case NWAM_OBJECT_TYPE_NCU:
2458 2479 ret = nwam_ncu_prop_multivalued(prop, &multi);
2459 2480 break;
2460 2481 case NWAM_OBJECT_TYPE_LOC:
2461 2482 ret = nwam_loc_prop_multivalued(prop, &multi);
2462 2483 break;
2463 2484 case NWAM_OBJECT_TYPE_ENM:
2464 2485 ret = nwam_enm_prop_multivalued(prop, &multi);
2465 2486 break;
2466 2487 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
2467 2488 ret = nwam_known_wlan_prop_multivalued(prop, &multi);
2468 2489 break;
2469 2490 }
2470 2491
2471 2492 if (ret != NWAM_SUCCESS)
2472 2493 multi = B_FALSE;
2473 2494 return (multi);
2474 2495 }
2475 2496
2476 2497 /*
2477 2498 * Prints out error message specific to property that could not be set.
2478 2499 * Property description is used to help guide user in entering correct value.
2479 2500 */
2480 2501 static void
2481 2502 invalid_set_prop_msg(const char *prop, nwam_error_t err)
2482 2503 {
2483 2504 const char *description;
2484 2505
2485 2506 if (err == NWAM_SUCCESS)
2486 2507 return;
2487 2508
2488 2509 if (err != NWAM_ENTITY_INVALID_VALUE) {
2489 2510 nwamerr(err, "Set error");
2490 2511 return;
2491 2512 }
2492 2513
2493 2514 switch (active_object_type()) {
2494 2515 case NWAM_OBJECT_TYPE_NCU:
2495 2516 (void) nwam_ncu_get_prop_description(prop, &description);
2496 2517 break;
2497 2518 case NWAM_OBJECT_TYPE_LOC:
2498 2519 (void) nwam_loc_get_prop_description(prop, &description);
2499 2520 break;
2500 2521 case NWAM_OBJECT_TYPE_ENM:
2501 2522 (void) nwam_enm_get_prop_description(prop, &description);
2502 2523 break;
2503 2524 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
2504 2525 (void) nwam_known_wlan_get_prop_description(prop,
2505 2526 &description);
2506 2527 break;
2507 2528 }
2508 2529 nerr("Set error: invalid value\n'%s' %s", prop, description);
2509 2530 }
2510 2531
2511 2532 /*
2512 2533 * Sets the property value.
2513 2534 * Read-only properties and objects cannot be set.
2514 2535 * "read-only" is a special in that it can be set on a read-only object.
2515 2536 * The object has to be committed before other properties can be set.
2516 2537 * Also uses show_prop_test() to test if the property being set would
2517 2538 * be skipped during a walk (as determined by the value of some other
2518 2539 * property). If so, then it cannot be set.
2519 2540 */
2520 2541 void
2521 2542 set_func(cmd_t *cmd)
2522 2543 {
2523 2544 int pt_type = cmd->cmd_prop_type;
2524 2545 nwam_error_t ret = NWAM_SUCCESS;
2525 2546 nwam_value_t prop_value;
2526 2547 const char *prop;
2527 2548 boolean_t is_listprop = B_FALSE;
2528 2549 nwam_object_type_t object_type;
2529 2550 prop_display_entry_t *prop_table;
2530 2551 char **checked = NULL;
2531 2552
2532 2553 assert(cmd->cmd_argc > 0);
2533 2554
2534 2555 object_type = active_object_type();
2535 2556 prop_table = get_prop_display_table(object_type);
2536 2557
2537 2558 /* argv[0] is property value */
2538 2559 if ((prop = pt_to_prop_name(object_type, pt_type)) == NULL) {
2539 2560 nerr("Set error: invalid %s property: '%s'",
2540 2561 scope_to_str(current_scope), pt_to_str(pt_type));
2541 2562 return;
2542 2563 }
2543 2564
2544 2565 /* check if property can be set */
2545 2566 if (is_prop_read_only(object_type, prop)) {
2546 2567 nerr("Set error: property '%s' is read-only", prop);
2547 2568 return;
2548 2569 }
2549 2570 if (!show_prop_test(object_type, prop, prop_table, checked, 0)) {
2550 2571 if (interactive_mode) {
2551 2572 (void) printf(gettext("setting property '%s' "
2552 2573 "has no effect\n"), prop);
2553 2574 }
2554 2575 }
2555 2576
2556 2577 is_listprop = is_prop_multivalued(object_type, prop);
2557 2578 prop_value = str_to_nwam_value(object_type, cmd->cmd_argv[0], pt_type,
2558 2579 is_listprop);
2559 2580 if (prop_value == NULL) {
2560 2581 invalid_set_prop_msg(prop, NWAM_ENTITY_INVALID_VALUE);
2561 2582 return;
2562 2583 }
2563 2584
2564 2585 /* set the property value */
2565 2586 switch (object_type) {
2566 2587 case NWAM_OBJECT_TYPE_NCU:
2567 2588 ret = nwam_ncu_set_prop_value(ncu_h, prop, prop_value);
2568 2589 break;
2569 2590 case NWAM_OBJECT_TYPE_LOC:
2570 2591 ret = nwam_loc_set_prop_value(loc_h, prop, prop_value);
2571 2592 break;
2572 2593 case NWAM_OBJECT_TYPE_ENM:
2573 2594 ret = nwam_enm_set_prop_value(enm_h, prop, prop_value);
2574 2595 break;
2575 2596 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
2576 2597 ret = nwam_known_wlan_set_prop_value(wlan_h, prop, prop_value);
2577 2598 break;
2578 2599 }
2579 2600 nwam_value_free(prop_value);
2580 2601
2581 2602 /* delete other properties if needed */
2582 2603 if (ret == NWAM_SUCCESS)
2583 2604 need_to_commit = B_TRUE;
2584 2605 else
2585 2606 invalid_set_prop_msg(prop, ret);
2586 2607 }
2587 2608
2588 2609 static int
2589 2610 list_callback(nwam_object_type_t object_type, void *handle,
2590 2611 boolean_t *list_msgp, const char *msg)
2591 2612 {
2592 2613 nwam_error_t ret;
2593 2614 char *name;
2594 2615 nwam_ncu_class_t class;
2595 2616
2596 2617 if (*list_msgp) {
2597 2618 (void) printf("%s:\n", msg);
2598 2619 *list_msgp = B_FALSE;
2599 2620 }
2600 2621
2601 2622 ret = object_name_from_handle(object_type, handle, &name);
2602 2623 if (ret != NWAM_SUCCESS) {
2603 2624 nwamerr(ret, "List error: failed to get name");
2604 2625 return (1);
2605 2626 }
2606 2627
2607 2628 /* If NCU, get its class and print */
2608 2629 if (object_type == NWAM_OBJECT_TYPE_NCU) {
2609 2630 if ((ret = nwam_ncu_get_ncu_class(handle, &class))
2610 2631 != NWAM_SUCCESS) {
2611 2632 nwamerr(ret, "List error: failed to get ncu class");
2612 2633 free(name);
2613 2634 return (1);
2614 2635 } else {
2615 2636 (void) printf("\t%s",
2616 2637 propval_to_str(NWAM_NCU_PROP_CLASS, class));
2617 2638 }
2618 2639 }
2619 2640 (void) printf("\t%s\n", name);
2620 2641
2621 2642 free(name);
2622 2643 return (0);
2623 2644 }
2624 2645
2625 2646 /* Print out name, type and status */
2626 2647 static int
2627 2648 list_loc_callback(nwam_loc_handle_t loc, void *arg)
2628 2649 {
2629 2650 return (list_callback(NWAM_OBJECT_TYPE_LOC, loc, arg, "Locations"));
2630 2651 }
2631 2652
2632 2653 static int
2633 2654 list_enm_callback(nwam_enm_handle_t enm, void *arg)
2634 2655 {
2635 2656 return (list_callback(NWAM_OBJECT_TYPE_ENM, enm, arg, "ENMs"));
2636 2657 }
2637 2658
2638 2659 static int
2639 2660 list_wlan_callback(nwam_known_wlan_handle_t wlan, void *arg)
2640 2661 {
2641 2662 return (list_callback(NWAM_OBJECT_TYPE_KNOWN_WLAN, wlan, arg, "WLANs"));
2642 2663 }
2643 2664
2644 2665 static int
2645 2666 list_ncp_callback(nwam_ncp_handle_t ncp, void *arg)
2646 2667 {
2647 2668 return (list_callback(NWAM_OBJECT_TYPE_NCP, ncp, arg, "NCPs"));
2648 2669 }
2649 2670
2650 2671 static int
2651 2672 list_ncu_callback(nwam_ncu_handle_t ncu, void *arg)
2652 2673 {
2653 2674 return (list_callback(NWAM_OBJECT_TYPE_NCU, ncu, arg, "NCUs"));
2654 2675 }
2655 2676
2656 2677 /* functions to convert a value to a string */
2657 2678 /* ARGSUSED */
2658 2679 static const char *
2659 2680 str2str(void *s, const char *prop, char *str)
2660 2681 {
2661 2682 (void) snprintf(str, NWAM_MAX_VALUE_LEN, "%s", s);
2662 2683 return (str);
2663 2684 }
2664 2685
2665 2686 /* ARGSUSED */
2666 2687 static const char *
2667 2688 str2qstr(void *s, const char *prop, char *qstr)
2668 2689 {
2669 2690 /* quoted strings */
2670 2691 (void) snprintf(qstr, NWAM_MAX_VALUE_LEN, "\"%s\"", s);
2671 2692 return (qstr);
2672 2693 }
2673 2694
2674 2695 /* ARGSUSED */
2675 2696 static const char *
2676 2697 int2str(void *in, const char *prop, char *instr)
2677 2698 {
2678 2699 (void) snprintf(instr, NWAM_MAX_VALUE_LEN, "%lld", *((int64_t *)in));
2679 2700 return (instr);
2680 2701 }
2681 2702
2682 2703 static const char *
2683 2704 uint2str(void *uin, const char *prop, char *uintstr)
2684 2705 {
2685 2706 /* returns NWAM_SUCCESS if prop is enum with string in uintstr */
2686 2707 if (nwam_uint64_get_value_string(prop, *((uint64_t *)uin),
2687 2708 (const char **)&uintstr) != NWAM_SUCCESS) {
2688 2709 (void) snprintf(uintstr, NWAM_MAX_VALUE_LEN, "%lld",
2689 2710 *((uint64_t *)uin));
2690 2711 }
2691 2712 return (uintstr);
2692 2713 }
2693 2714
2694 2715 /* ARGSUSED */
2695 2716 static const char *
2696 2717 bool2str(void *bool, const char *prop, char *boolstr)
2697 2718 {
2698 2719 (void) snprintf(boolstr, NWAM_MAX_VALUE_LEN, "%s",
2699 2720 *((boolean_t *)bool) ? "true" : "false");
2700 2721 return (boolstr);
2701 2722 }
2702 2723
2703 2724 /*
2704 2725 * Print the value (enums are converted to string), use DELIMITER for
2705 2726 * array. If strings are to be "quoted", pass B_TRUE for quoted_strings.
2706 2727 */
2707 2728 static void
2708 2729 output_prop_val(const char *prop_name, nwam_value_t value, FILE *wf,
2709 2730 boolean_t quoted_strings)
2710 2731 {
2711 2732 nwam_value_type_t value_type;
2712 2733 uint_t num;
2713 2734
2714 2735 /* arrays for values retrieved according to the type of value */
2715 2736 char **svals;
2716 2737 uint64_t *uvals;
2717 2738 int64_t *ivals;
2718 2739 boolean_t *bvals;
2719 2740
2720 2741 /* pointer to function to generate string representation of value */
2721 2742 const char *(*tostr)(void *, const char *, char *);
2722 2743 char str[NWAM_MAX_VALUE_LEN]; /* to store the string */
2723 2744 int i;
2724 2745
2725 2746 if (nwam_value_get_type(value, &value_type) != NWAM_SUCCESS) {
2726 2747 nerr("Get value type error");
2727 2748 return;
2728 2749 }
2729 2750
2730 2751 if (value_type == NWAM_VALUE_TYPE_STRING) {
2731 2752 if (nwam_value_get_string_array(value, &svals, &num) !=
2732 2753 NWAM_SUCCESS) {
2733 2754 nerr("Get string array error");
2734 2755 return;
2735 2756 }
2736 2757 tostr = quoted_strings ? str2qstr : str2str;
2737 2758 } else if (value_type == NWAM_VALUE_TYPE_INT64) {
2738 2759 if (nwam_value_get_int64_array(value, &ivals, &num) !=
2739 2760 NWAM_SUCCESS) {
2740 2761 nerr("Get int64 array error");
2741 2762 return;
2742 2763 }
2743 2764 tostr = int2str;
2744 2765 } else if (value_type == NWAM_VALUE_TYPE_UINT64) {
2745 2766 if (nwam_value_get_uint64_array(value, &uvals, &num) !=
2746 2767 NWAM_SUCCESS) {
2747 2768 nerr("Get uint64 array error");
2748 2769 return;
2749 2770 }
2750 2771 tostr = uint2str;
2751 2772 } else if (value_type == NWAM_VALUE_TYPE_BOOLEAN) {
2752 2773 if (nwam_value_get_boolean_array(value, &bvals, &num) !=
2753 2774 NWAM_SUCCESS) {
2754 2775 nerr("Get boolean array error");
2755 2776 return;
2756 2777 }
2757 2778 tostr = bool2str;
2758 2779 }
2759 2780
2760 2781 /* now, loop and print each value */
2761 2782 for (i = 0; i < num; i++) {
2762 2783 void *val;
2763 2784
2764 2785 /* get the pointer to the ith value to pass to func() */
2765 2786 if (value_type == NWAM_VALUE_TYPE_STRING)
2766 2787 val = svals[i];
2767 2788 else if (value_type == NWAM_VALUE_TYPE_UINT64)
2768 2789 val = &(uvals[i]);
2769 2790 else if (value_type == NWAM_VALUE_TYPE_INT64)
2770 2791 val = &(ivals[i]);
2771 2792 else if (value_type == NWAM_VALUE_TYPE_BOOLEAN)
2772 2793 val = &(bvals[i]);
2773 2794
2774 2795 (void) fprintf(wf, "%s%s", tostr(val, prop_name, str),
2775 2796 i != num-1 ? NWAM_VALUE_DELIMITER_STR : "");
2776 2797 }
2777 2798 }
2778 2799
2779 2800 /* Prints the property names aligned (for list/get) or "prop=" (for export) */
2780 2801 static int
2781 2802 output_propname_common(const char *prop, nwam_value_t values, void *arg,
2782 2803 int width)
2783 2804 {
2784 2805 FILE *of = (arg == NULL) ? stdout : arg;
2785 2806
2786 2807 /* arg is NULL for list/get, not NULL for export */
2787 2808 if (arg == NULL)
2788 2809 (void) fprintf(of, "\t%-*s\t", width, prop);
2789 2810 else
2790 2811 (void) fprintf(of, "%s=", prop);
2791 2812
2792 2813 if (values != NULL)
2793 2814 output_prop_val(prop, values, of, B_TRUE);
2794 2815
2795 2816 (void) fprintf(of, "\n");
2796 2817 return (0);
2797 2818 }
2798 2819
2799 2820 static int
2800 2821 output_propname(const char *prop, nwam_value_t values, void *arg)
2801 2822 {
2802 2823 return (output_propname_common(prop, values, arg, 16));
2803 2824 }
2804 2825
2805 2826 /* For locations because of longer property names */
2806 2827 static int
2807 2828 output_loc_propname(const char *prop, nwam_value_t values, void *arg)
2808 2829 {
2809 2830 return (output_propname_common(prop, values, arg, 25));
2810 2831 }
2811 2832
2812 2833 /*
2813 2834 * all_props specifies whether properties that have not been set should be
2814 2835 * printed or not. ncp and ncu_type are used only when the object_type is
2815 2836 * NCU.
2816 2837 */
2817 2838 static nwam_error_t
2818 2839 listprop(nwam_object_type_t object_type, void *handle, const char *name,
2819 2840 boolean_t all_props, nwam_ncp_handle_t ncp, nwam_ncu_type_t ncu_type)
2820 2841 {
2821 2842 nwam_error_t ret;
2822 2843 char *lname = NULL, *realname = NULL;
2823 2844 boolean_t lhandle = B_FALSE;
2824 2845 const char **props = NULL;
2825 2846 uint_t prop_num;
2826 2847 int i;
2827 2848 nwam_value_t vals;
2828 2849
2829 2850 /*
2830 2851 * handle is NULL if called from a scope higher than the object's
2831 2852 * scope, but name must be given; so get the handle.
2832 2853 */
2833 2854 if (handle == NULL) {
2834 2855 lname = trim_quotes(name); /* name may have quotes */
2835 2856 switch (object_type) {
2836 2857 case NWAM_OBJECT_TYPE_NCP:
2837 2858 if ((ret = nwam_ncp_read(lname, 0,
2838 2859 (nwam_ncp_handle_t *)&handle)) != NWAM_SUCCESS)
2839 2860 goto readfail;
2840 2861 break;
2841 2862 case NWAM_OBJECT_TYPE_NCU:
2842 2863 ret = nwam_ncu_read(ncp, lname, ncu_type, 0,
2843 2864 (nwam_ncu_handle_t *)&handle);
2844 2865 if (ret == NWAM_ENTITY_MULTIPLE_VALUES) {
2845 2866 /*
2846 2867 * Multiple NCUs with the given name exists.
2847 2868 * Call listprop() for each NCU type.
2848 2869 */
2849 2870 if ((ret = listprop(object_type, NULL, lname,
2850 2871 all_props, ncp, NWAM_NCU_TYPE_LINK))
2851 2872 != NWAM_SUCCESS)
2852 2873 goto done;
2853 2874 ret = listprop(object_type, NULL, lname,
2854 2875 all_props, ncp, NWAM_NCU_TYPE_INTERFACE);
2855 2876 goto done;
2856 2877 } else if (ret != NWAM_SUCCESS) {
2857 2878 goto readfail;
2858 2879 }
2859 2880 break;
2860 2881 case NWAM_OBJECT_TYPE_LOC:
2861 2882 if ((ret = nwam_loc_read(lname, 0,
2862 2883 (nwam_loc_handle_t *)&handle)) != NWAM_SUCCESS)
2863 2884 goto readfail;
2864 2885 break;
2865 2886 case NWAM_OBJECT_TYPE_ENM:
2866 2887 if ((ret = nwam_enm_read(lname, 0,
2867 2888 (nwam_enm_handle_t *)&handle)) != NWAM_SUCCESS)
2868 2889 goto readfail;
2869 2890 break;
2870 2891 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
2871 2892 if ((ret = nwam_known_wlan_read(lname, 0,
2872 2893 (nwam_known_wlan_handle_t *)&handle))
2873 2894 != NWAM_SUCCESS)
2874 2895 goto readfail;
2875 2896 break;
2876 2897 }
2877 2898 lhandle = B_TRUE;
2878 2899 }
2879 2900
2880 2901 if ((ret = object_name_from_handle(object_type, handle, &realname))
2881 2902 != NWAM_SUCCESS)
2882 2903 goto done;
2883 2904
2884 2905 /* get the property list */
2885 2906 switch (object_type) {
2886 2907 case NWAM_OBJECT_TYPE_NCP:
2887 2908 {
2888 2909 /* walk NCUs */
2889 2910 boolean_t list_msg = B_TRUE;
2890 2911 ret = nwam_ncp_walk_ncus(handle, list_ncu_callback, &list_msg,
2891 2912 NWAM_FLAG_NCU_TYPE_CLASS_ALL, NULL);
2892 2913 goto done;
2893 2914 }
2894 2915 case NWAM_OBJECT_TYPE_NCU:
2895 2916 {
2896 2917 nwam_ncu_type_t ncu_type;
2897 2918 nwam_ncu_class_t ncu_class;
2898 2919
2899 2920 if ((ret = nwam_ncu_get_ncu_type(handle, &ncu_type))
2900 2921 != NWAM_SUCCESS)
2901 2922 goto done;
2902 2923 if ((ret = nwam_ncu_get_ncu_class(handle, &ncu_class))
2903 2924 != NWAM_SUCCESS)
2904 2925 goto done;
2905 2926
2906 2927 ret = nwam_ncu_get_default_proplist(ncu_type, ncu_class, &props,
2907 2928 &prop_num);
2908 2929 break;
2909 2930 }
2910 2931 case NWAM_OBJECT_TYPE_LOC:
2911 2932 ret = nwam_loc_get_default_proplist(&props, &prop_num);
2912 2933 break;
2913 2934 case NWAM_OBJECT_TYPE_ENM:
2914 2935 ret = nwam_enm_get_default_proplist(&props, &prop_num);
2915 2936 break;
2916 2937 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
2917 2938 ret = nwam_known_wlan_get_default_proplist(&props, &prop_num);
2918 2939 break;
2919 2940 }
2920 2941 if (ret != NWAM_SUCCESS)
2921 2942 goto done;
2922 2943
2923 2944 /* print object type and name */
2924 2945 (void) printf("%s:%s\n", nwam_object_type_to_string(object_type),
2925 2946 realname);
2926 2947
2927 2948 /* Loop through the properties and print */
2928 2949 for (i = 0; i < prop_num; i++) {
2929 2950 /* get the existing value for this property */
2930 2951 switch (object_type) {
2931 2952 case NWAM_OBJECT_TYPE_NCU:
2932 2953 ret = nwam_ncu_get_prop_value(handle, props[i], &vals);
2933 2954 break;
2934 2955 case NWAM_OBJECT_TYPE_LOC:
2935 2956 ret = nwam_loc_get_prop_value(handle, props[i], &vals);
2936 2957 break;
2937 2958 case NWAM_OBJECT_TYPE_ENM:
2938 2959 ret = nwam_enm_get_prop_value(handle, props[i], &vals);
2939 2960 break;
2940 2961 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
2941 2962 ret = nwam_known_wlan_get_prop_value(handle, props[i],
2942 2963 &vals);
2943 2964 break;
2944 2965 }
2945 2966 if (ret != NWAM_SUCCESS) {
2946 2967 /* _ENTITY_NOT_FOUND is ok if listing for all props */
2947 2968 if (!all_props)
2948 2969 continue;
2949 2970 else if (ret != NWAM_ENTITY_NOT_FOUND)
2950 2971 continue;
2951 2972 }
2952 2973
2953 2974 /* print property and value */
2954 2975 if (object_type == NWAM_OBJECT_TYPE_LOC)
2955 2976 output_loc_propname(props[i], vals, NULL);
2956 2977 else
2957 2978 output_propname(props[i], vals, NULL);
2958 2979 nwam_value_free(vals);
2959 2980 }
2960 2981
2961 2982 done:
2962 2983 free(lname);
2963 2984 free(realname);
2964 2985 if (props != NULL)
2965 2986 free(props);
2966 2987 if (lhandle) {
2967 2988 switch (object_type) {
2968 2989 case NWAM_OBJECT_TYPE_NCP:
2969 2990 nwam_ncp_free(handle);
2970 2991 break;
2971 2992 case NWAM_OBJECT_TYPE_NCU:
2972 2993 nwam_ncu_free(handle);
2973 2994 break;
2974 2995 case NWAM_OBJECT_TYPE_LOC:
2975 2996 nwam_loc_free(handle);
2976 2997 break;
2977 2998 case NWAM_OBJECT_TYPE_ENM:
2978 2999 nwam_enm_free(handle);
2979 3000 break;
2980 3001 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
2981 3002 nwam_known_wlan_free(handle);
2982 3003 break;
2983 3004 }
2984 3005 }
2985 3006 /* don't treat _ENTITY_NOT_FOUND as an error */
2986 3007 if (ret == NWAM_ENTITY_NOT_FOUND)
2987 3008 ret = NWAM_SUCCESS;
2988 3009 return (ret);
2989 3010
2990 3011 readfail:
2991 3012 /* When nwam_*_read() fails */
2992 3013 free(lname);
2993 3014 return (ret);
2994 3015 }
2995 3016
2996 3017 /*
2997 3018 * List profiles or property and its values.
2998 3019 * If the -a option is specified, all properties are listed.
2999 3020 */
3000 3021 void
3001 3022 list_func(cmd_t *cmd)
3002 3023 {
3003 3024 nwam_error_t ret = NWAM_SUCCESS;
3004 3025 boolean_t list_msg = B_TRUE;
3005 3026
3006 3027 boolean_t list_loc = B_FALSE, list_enm = B_FALSE;
3007 3028 boolean_t list_ncp = B_FALSE, list_ncu = B_FALSE;
3008 3029 boolean_t list_wlan = B_FALSE;
3009 3030
3010 3031 /* whether all properties should be listed, given by the -a option */
3011 3032 boolean_t all_props = B_FALSE;
3012 3033
3013 3034 /*
3014 3035 * list_props says whether the properties should be listed.
3015 3036 * Note that, here NCUs are treated as properties of NCPs.
3016 3037 */
3017 3038 boolean_t list_props = B_FALSE;
3018 3039
3019 3040 /* determine which properties to list, also validity tests */
3020 3041 if (current_scope == NWAM_SCOPE_GBL) {
3021 3042 /* res1_type is -1 if only "list -a" is used */
3022 3043 if (cmd->cmd_res1_type == -1) {
3023 3044 nerr("'list' requires an object to be specified with "
3024 3045 "the -a option in the global scope");
3025 3046 return;
3026 3047 }
3027 3048 if (cmd->cmd_res1_type == RT1_LOC) {
3028 3049 list_props = B_TRUE;
3029 3050 list_loc = B_TRUE;
3030 3051 } else if (cmd->cmd_res1_type == RT1_ENM) {
3031 3052 list_props = B_TRUE;
3032 3053 list_enm = B_TRUE;
3033 3054 } else if (cmd->cmd_res1_type == RT1_WLAN) {
3034 3055 list_props = B_TRUE;
3035 3056 list_wlan = B_TRUE;
3036 3057 } else if (cmd->cmd_res1_type == RT1_NCP) {
3037 3058 list_ncp = B_TRUE;
3038 3059 list_props = B_TRUE;
3039 3060 } else {
3040 3061 list_loc = B_TRUE;
3041 3062 list_enm = B_TRUE;
3042 3063 list_wlan = B_TRUE;
3043 3064 list_ncp = B_TRUE;
3044 3065 }
3045 3066 }
3046 3067 if ((current_scope == NWAM_SCOPE_LOC ||
3047 3068 current_scope == NWAM_SCOPE_ENM ||
3048 3069 current_scope == NWAM_SCOPE_WLAN ||
3049 3070 current_scope == NWAM_SCOPE_NCU) &&
3050 3071 (cmd->cmd_argc >= 1 && cmd->cmd_res1_type != -1)) {
3051 3072 nerr("Additional options are not allowed with the -a option "
3052 3073 "at this scope");
3053 3074 return;
3054 3075 }
3055 3076 if (current_scope == NWAM_SCOPE_LOC) {
3056 3077 list_loc = B_TRUE;
3057 3078 list_props = B_TRUE;
3058 3079 }
3059 3080 if (current_scope == NWAM_SCOPE_ENM) {
3060 3081 list_enm = B_TRUE;
3061 3082 list_props = B_TRUE;
3062 3083 }
3063 3084 if (current_scope == NWAM_SCOPE_WLAN) {
3064 3085 list_wlan = B_TRUE;
3065 3086 list_props = B_TRUE;
3066 3087 }
3067 3088 if (current_scope == NWAM_SCOPE_NCP) {
3068 3089 if (cmd->cmd_res1_type == RT1_ENM ||
3069 3090 cmd->cmd_res1_type == RT1_LOC ||
3070 3091 cmd->cmd_res1_type == RT1_WLAN) {
3071 3092 nerr("only ncu can be listed at this scope");
3072 3093 return;
3073 3094 }
3074 3095 if (cmd->cmd_res2_type == RT2_NCU) {
3075 3096 list_ncu = B_TRUE;
3076 3097 list_props = B_TRUE;
3077 3098 } else {
3078 3099 list_ncp = B_TRUE;
3079 3100 list_props = B_TRUE;
3080 3101 }
3081 3102 }
3082 3103 if (current_scope == NWAM_SCOPE_NCU) {
3083 3104 list_ncu = B_TRUE;
3084 3105 list_props = B_TRUE;
3085 3106 }
3086 3107
3087 3108 /* Check if the -a option is specified to list all properties */
3088 3109 if (cmd->cmd_res1_type == -1 || cmd->cmd_argc == 2) {
3089 3110 int c, argc = 1;
3090 3111 char **argv;
3091 3112 optind = 0;
3092 3113
3093 3114 /* if res1_type is -1, option is in argv[0], else in argv[1] */
3094 3115 if (cmd->cmd_res1_type == -1)
3095 3116 argv = cmd->cmd_argv;
3096 3117 else
3097 3118 argv = &(cmd->cmd_argv[1]);
3098 3119 while ((c = getopt(argc, argv, "a")) != EOF) {
3099 3120 switch (c) {
3100 3121 case 'a':
3101 3122 all_props = B_TRUE;
3102 3123 break;
3103 3124 default:
3104 3125 command_usage(CMD_LIST);
3105 3126 return;
3106 3127 }
3107 3128 }
3108 3129 if (cmd->cmd_res1_type == -1)
3109 3130 cmd->cmd_argv[0] = NULL;
3110 3131 }
3111 3132
3112 3133 /*
3113 3134 * Now, print objects and/or according to the flags set.
3114 3135 * name, if requested, is in argv[0].
3115 3136 */
3116 3137 if (list_ncp) {
3117 3138 list_msg = B_TRUE;
3118 3139 if (list_props) {
3119 3140 ret = listprop(NWAM_OBJECT_TYPE_NCP, ncp_h,
3120 3141 cmd->cmd_argv[0], all_props, NULL, -1);
3121 3142 } else {
3122 3143 ret = nwam_walk_ncps(list_ncp_callback, &list_msg, 0,
3123 3144 NULL);
3124 3145 }
3125 3146 if (ret != NWAM_SUCCESS)
3126 3147 goto done;
3127 3148 }
3128 3149
3129 3150 if (list_ncu) {
3130 3151 list_msg = B_TRUE;
3131 3152 if (ncp_h == NULL) {
3132 3153 nerr("NCP has not been read");
3133 3154 return;
3134 3155 }
3135 3156 if (list_props) {
3136 3157 nwam_ncu_class_t ncu_class;
3137 3158 nwam_ncu_type_t ncu_type;
3138 3159
3139 3160 /* determine the NCU type first */
3140 3161 if (ncu_h == NULL) {
3141 3162 ncu_class = (nwam_ncu_class_t)
3142 3163 cmd->cmd_ncu_class_type;
3143 3164 ncu_type = nwam_ncu_class_to_type(ncu_class);
3144 3165 } else {
3145 3166 if ((ret = nwam_ncu_get_ncu_type(ncu_h,
3146 3167 &ncu_type)) != NWAM_SUCCESS)
3147 3168 goto done;
3148 3169 }
3149 3170 ret = listprop(NWAM_OBJECT_TYPE_NCU, ncu_h,
3150 3171 cmd->cmd_argv[0], all_props, ncp_h, ncu_type);
3151 3172 if (ret != NWAM_SUCCESS)
3152 3173 goto done;
3153 3174 }
3154 3175 }
3155 3176
3156 3177 if (list_loc) {
3157 3178 list_msg = B_TRUE;
3158 3179 if (list_props) {
3159 3180 ret = listprop(NWAM_OBJECT_TYPE_LOC, loc_h,
3160 3181 cmd->cmd_argv[0], all_props, NULL, -1);
3161 3182 } else {
3162 3183 ret = nwam_walk_locs(list_loc_callback, &list_msg,
3163 3184 NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
3164 3185 }
3165 3186 if (ret != NWAM_SUCCESS)
3166 3187 goto done;
3167 3188 }
3168 3189
3169 3190 if (list_enm) {
3170 3191 list_msg = B_TRUE;
3171 3192 if (list_props) {
3172 3193 ret = listprop(NWAM_OBJECT_TYPE_ENM, enm_h,
3173 3194 cmd->cmd_argv[0], all_props, NULL, -1);
3174 3195 } else {
3175 3196 ret = nwam_walk_enms(list_enm_callback, &list_msg,
3176 3197 NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
3177 3198 }
3178 3199 if (ret != NWAM_SUCCESS)
3179 3200 goto done;
3180 3201 }
3181 3202
3182 3203 if (list_wlan) {
3183 3204 list_msg = B_TRUE;
3184 3205 if (list_props) {
3185 3206 ret = listprop(NWAM_OBJECT_TYPE_KNOWN_WLAN, wlan_h,
3186 3207 cmd->cmd_argv[0], all_props, NULL, -1);
3187 3208 } else {
3188 3209 ret = nwam_walk_known_wlans(list_wlan_callback,
3189 3210 &list_msg, NWAM_FLAG_KNOWN_WLAN_WALK_PRIORITY_ORDER,
3190 3211 NULL);
3191 3212 }
3192 3213 if (ret != NWAM_SUCCESS)
3193 3214 goto done;
3194 3215 }
3195 3216
3196 3217 done:
3197 3218 if (ret != NWAM_SUCCESS)
3198 3219 nwamerr(ret, "List error");
3199 3220 }
3200 3221
3201 3222 static int
3202 3223 write_export_command(nwam_object_type_t object_type, const char *prop,
3203 3224 nwam_value_t values, FILE *of)
3204 3225 {
3205 3226 /* exclude read-only properties */
3206 3227 if (is_prop_read_only(object_type, prop))
3207 3228 return (0);
3208 3229
3209 3230 (void) fprintf(of, "set ");
3210 3231 output_propname(prop, values, of);
3211 3232 return (0);
3212 3233 }
3213 3234
3214 3235 static int
3215 3236 export_ncu_callback(nwam_ncu_handle_t ncu, void *arg)
3216 3237 {
3217 3238 char *name;
3218 3239 const char **props;
3219 3240 nwam_ncu_type_t type;
3220 3241 nwam_ncu_class_t class;
3221 3242 nwam_value_t vals;
3222 3243 nwam_error_t ret;
3223 3244 uint_t num;
3224 3245 int i;
3225 3246 FILE *of = arg;
3226 3247
3227 3248 assert(of != NULL);
3228 3249
3229 3250 /* get the NCU's type and class */
3230 3251 if ((ret = nwam_ncu_get_ncu_type(ncu, &type)) != NWAM_SUCCESS)
3231 3252 return (ret);
3232 3253 if ((ret = nwam_ncu_get_ncu_class(ncu, &class)) != NWAM_SUCCESS)
3233 3254 return (ret);
3234 3255
3235 3256 if ((ret = nwam_ncu_get_name(ncu, &name)) != NWAM_SUCCESS)
3236 3257 return (ret);
3237 3258
3238 3259 (void) fprintf(of, "create ncu %s \"%s\"\n",
3239 3260 propval_to_str(NWAM_NCU_PROP_CLASS, class), name);
3240 3261 free(name);
3241 3262 /*
3242 3263 * Because of dependencies between properties, they have to be
3243 3264 * exported in the same order as when they are walked.
3244 3265 */
3245 3266 if ((ret = nwam_ncu_get_default_proplist(type, class, &props, &num))
3246 3267 != NWAM_SUCCESS)
3247 3268 return (ret);
3248 3269 for (i = 0; i < num; i++) {
3249 3270 ret = nwam_ncu_get_prop_value(ncu, props[i], &vals);
3250 3271 if (ret == NWAM_SUCCESS) {
3251 3272 write_export_command(NWAM_OBJECT_TYPE_NCU, props[i],
3252 3273 vals, of);
3253 3274 nwam_value_free(vals);
3254 3275 }
3255 3276 }
3256 3277 (void) fprintf(of, "end\n");
3257 3278
3258 3279 free(props);
3259 3280 return (0);
3260 3281 }
3261 3282
3262 3283 static int
3263 3284 export_ncp_callback(nwam_ncp_handle_t ncp, void *arg)
3264 3285 {
3265 3286 char *name;
3266 3287 nwam_error_t ret;
3267 3288 FILE *of = arg;
3268 3289
3269 3290 assert(of != NULL);
3270 3291
3271 3292 if ((ret = nwam_ncp_get_name(ncp, &name)) != NWAM_SUCCESS)
3272 3293 return (ret);
3273 3294
3274 3295 /* Do not export "automatic" NCP */
3275 3296 if (NWAM_NCP_AUTOMATIC(name)) {
3276 3297 free(name);
3277 3298 return (0);
3278 3299 }
3279 3300
3280 3301 (void) fprintf(of, "create ncp \"%s\"\n", name);
3281 3302 free(name);
3282 3303
3283 3304 /* now walk NCUs for this ncp */
3284 3305 ret = nwam_ncp_walk_ncus(ncp, export_ncu_callback, of,
3285 3306 NWAM_FLAG_NCU_TYPE_CLASS_ALL, NULL);
3286 3307 if (ret != NWAM_SUCCESS) {
3287 3308 nwamerr(ret, "Export ncp error: failed to walk ncus");
3288 3309 return (ret);
3289 3310 }
3290 3311 (void) fprintf(of, "end\n");
3291 3312 return (0);
3292 3313 }
3293 3314
3294 3315 static int
3295 3316 export_enm_callback(nwam_enm_handle_t enm, void *arg)
3296 3317 {
3297 3318 char *name;
3298 3319 const char **props;
3299 3320 nwam_value_t vals;
3300 3321 nwam_error_t ret;
3301 3322 uint_t num;
3302 3323 int i;
3303 3324 FILE *of = arg;
3304 3325
3305 3326 assert(of != NULL);
3306 3327
3307 3328 if ((ret = nwam_enm_get_name(enm, &name)) != NWAM_SUCCESS)
3308 3329 return (ret);
3309 3330
3310 3331 (void) fprintf(of, "create enm \"%s\"\n", name);
3311 3332 free(name);
3312 3333 /*
3313 3334 * Because of dependencies between properties, they have to be
3314 3335 * exported in the same order as when they are walked.
3315 3336 */
3316 3337 if ((ret = nwam_enm_get_default_proplist(&props, &num)) != NWAM_SUCCESS)
3317 3338 return (ret);
3318 3339 for (i = 0; i < num; i++) {
3319 3340 ret = nwam_enm_get_prop_value(enm, props[i], &vals);
3320 3341 if (ret == NWAM_SUCCESS) {
3321 3342 write_export_command(NWAM_OBJECT_TYPE_ENM, props[i],
3322 3343 vals, of);
3323 3344 nwam_value_free(vals);
3324 3345 }
3325 3346 }
3326 3347 (void) fprintf(of, "end\n");
3327 3348
3328 3349 free(props);
3329 3350 return (0);
3330 3351 }
3331 3352
3332 3353 static int
3333 3354 export_loc_callback(nwam_loc_handle_t loc, void *arg)
3334 3355 {
3335 3356 char *name;
3336 3357 const char **props;
3337 3358 nwam_value_t vals;
3338 3359 nwam_error_t ret;
3339 3360 uint_t num;
3340 3361 int i;
3341 3362 FILE *of = arg;
3342 3363
3343 3364 assert(of != NULL);
3344 3365
3345 3366 if ((ret = nwam_loc_get_name(loc, &name)) != NWAM_SUCCESS)
3346 3367 return (ret);
3347 3368
3348 3369 /* Do not export Automatic, NoNet or Legacy locations */
3349 3370 if (NWAM_LOC_NAME_PRE_DEFINED(name)) {
3350 3371 free(name);
3351 3372 return (0);
3352 3373 }
3353 3374
3354 3375 (void) fprintf(of, "create loc \"%s\"\n", name);
3355 3376 free(name);
3356 3377 /*
3357 3378 * Because of dependencies between properties, they have to be
3358 3379 * exported in the same order as when they are walked.
3359 3380 */
3360 3381 if ((ret = nwam_loc_get_default_proplist(&props, &num)) != NWAM_SUCCESS)
3361 3382 return (ret);
3362 3383 for (i = 0; i < num; i++) {
3363 3384 ret = nwam_loc_get_prop_value(loc, props[i], &vals);
3364 3385 if (ret == NWAM_SUCCESS) {
3365 3386 write_export_command(NWAM_OBJECT_TYPE_LOC, props[i],
3366 3387 vals, of);
3367 3388 nwam_value_free(vals);
3368 3389 }
3369 3390 }
3370 3391 (void) fprintf(of, "end\n");
3371 3392
3372 3393 free(props);
3373 3394 return (0);
3374 3395 }
3375 3396
3376 3397 static int
3377 3398 export_wlan_callback(nwam_known_wlan_handle_t wlan, void *arg)
3378 3399 {
3379 3400 char *name;
3380 3401 const char **props;
3381 3402 nwam_value_t vals;
3382 3403 nwam_error_t ret;
3383 3404 uint_t num;
3384 3405 int i;
3385 3406 FILE *of = arg;
3386 3407
3387 3408 assert(of != NULL);
3388 3409
3389 3410 if ((ret = nwam_known_wlan_get_name(wlan, &name)) != NWAM_SUCCESS)
3390 3411 return (ret);
3391 3412
3392 3413 (void) fprintf(of, "create wlan \"%s\"\n", name);
3393 3414 free(name);
3394 3415 /*
3395 3416 * Because of dependencies between properties, they have to be
3396 3417 * exported in the same order as when they are walked.
3397 3418 */
3398 3419 if ((ret = nwam_known_wlan_get_default_proplist(&props, &num))
3399 3420 != NWAM_SUCCESS)
3400 3421 return (ret);
3401 3422 for (i = 0; i < num; i++) {
3402 3423 ret = nwam_known_wlan_get_prop_value(wlan, props[i], &vals);
3403 3424 if (ret == NWAM_SUCCESS) {
3404 3425 write_export_command(NWAM_OBJECT_TYPE_KNOWN_WLAN,
3405 3426 props[i], vals, of);
3406 3427 nwam_value_free(vals);
3407 3428 }
3408 3429 }
3409 3430 (void) fprintf(of, "end\n");
3410 3431
3411 3432 free(props);
3412 3433 return (0);
3413 3434 }
3414 3435
3415 3436 /*
3416 3437 * Writes configuration to screen or file (with -f option).
3417 3438 * Writes a "destroy -a" if option -d is given.
3418 3439 */
3419 3440 void
3420 3441 export_func(cmd_t *cmd)
3421 3442 {
3422 3443 int c;
3423 3444 boolean_t need_to_close = B_FALSE, write_to_file = B_FALSE;
3424 3445 boolean_t add_destroy = B_FALSE, lhandle = B_FALSE;
3425 3446 char filepath[MAXPATHLEN];
3426 3447 nwam_error_t ret = NWAM_SUCCESS;
3427 3448 FILE *of = NULL; /* either filename or stdout */
3428 3449
3429 3450 /* what to export */
3430 3451 boolean_t export_ncp = B_FALSE, export_ncu = B_FALSE;
3431 3452 boolean_t export_loc = B_FALSE, export_enm = B_FALSE;
3432 3453 boolean_t export_wlan = B_FALSE;
3433 3454 char *name = NULL;
3434 3455
3435 3456 /* check for -d and -f flags */
3436 3457 filepath[0] = '\0';
3437 3458 optind = 0;
3438 3459 while ((c = getopt(cmd->cmd_argc, cmd->cmd_argv, "df:")) != EOF) {
3439 3460 switch (c) {
3440 3461 case 'f':
3441 3462 write_to_file = B_TRUE;
3442 3463 break;
3443 3464 case 'd':
3444 3465 add_destroy = B_TRUE;
3445 3466 break;
3446 3467 default:
3447 3468 command_usage(CMD_EXPORT);
3448 3469 return;
3449 3470 }
3450 3471 }
3451 3472
3452 3473 /* determine where to export */
3453 3474 if (!write_to_file) {
3454 3475 of = stdout;
3455 3476 } else {
3456 3477 /*
3457 3478 * If -d was specified with -f, then argv[2] is filename,
3458 3479 * otherwise, argv[1] is filename.
3459 3480 */
3460 3481 (void) strlcpy(filepath,
3461 3482 (add_destroy ? cmd->cmd_argv[2] : cmd->cmd_argv[1]),
3462 3483 sizeof (filepath));
3463 3484 if ((of = fopen(filepath, "w")) == NULL) {
3464 3485 nerr(gettext("opening file '%s': %s"), filepath,
3465 3486 strerror(errno));
3466 3487 goto done;
3467 3488 }
3468 3489 setbuf(of, NULL);
3469 3490 need_to_close = B_TRUE;
3470 3491 }
3471 3492
3472 3493 if (add_destroy) {
3473 3494 /* only possible in global scope */
3474 3495 if (current_scope == NWAM_SCOPE_GBL) {
3475 3496 (void) fprintf(of, "destroy -a\n");
3476 3497 } else {
3477 3498 nerr("Option -d is not allowed in non-global scope");
3478 3499 goto done;
3479 3500 }
3480 3501 }
3481 3502
3482 3503 /* In the following scopes, only the -f argument is valid */
3483 3504 if (((current_scope == NWAM_SCOPE_LOC ||
3484 3505 current_scope == NWAM_SCOPE_ENM ||
3485 3506 current_scope == NWAM_SCOPE_WLAN ||
3486 3507 current_scope == NWAM_SCOPE_NCU) &&
3487 3508 cmd->cmd_argc != 0 && !write_to_file)) {
3488 3509 nerr("'export' does not take arguments at this scope");
3489 3510 goto done;
3490 3511 }
3491 3512 if (current_scope == NWAM_SCOPE_NCP) {
3492 3513 if (cmd->cmd_res1_type == RT1_ENM ||
3493 3514 cmd->cmd_res1_type == RT1_LOC ||
3494 3515 cmd->cmd_res1_type == RT1_WLAN) {
3495 3516 nerr("only ncu can be exported at this scope");
3496 3517 goto done;
3497 3518 }
3498 3519 }
3499 3520
3500 3521 /*
3501 3522 * Determine what objects to export depending on scope and command
3502 3523 * arguments. If -f is specified, then the object name is argv[2].
3503 3524 * Otherwise, argv[0] is name, unless exporting all in global
3504 3525 * scope in which case name is set back to NULL.
3505 3526 */
3506 3527 switch (current_scope) {
3507 3528 case NWAM_SCOPE_GBL:
3508 3529 name = (write_to_file ? trim_quotes(cmd->cmd_argv[2]) :
3509 3530 trim_quotes(cmd->cmd_argv[0]));
3510 3531 switch (cmd->cmd_res1_type) {
3511 3532 case RT1_LOC:
3512 3533 export_loc = B_TRUE;
3513 3534 break;
3514 3535 case RT1_ENM:
3515 3536 export_enm = B_TRUE;
3516 3537 break;
3517 3538 case RT1_WLAN:
3518 3539 export_wlan = B_TRUE;
3519 3540 break;
3520 3541 case RT1_NCP:
3521 3542 export_ncp = B_TRUE;
3522 3543 if (cmd->cmd_res2_type == RT2_NCU) {
3523 3544 nerr("cannot export ncu at from global scope");
3524 3545 goto done;
3525 3546 }
3526 3547 break;
3527 3548 default:
3528 3549 /* export everything */
3529 3550 export_loc = B_TRUE;
3530 3551 export_enm = B_TRUE;
3531 3552 export_wlan = B_TRUE;
3532 3553 export_ncp = B_TRUE; /* NCP will export the NCUs */
3533 3554 free(name);
3534 3555 name = NULL; /* exporting all, undo name */
3535 3556 break;
3536 3557 }
3537 3558 break;
3538 3559 case NWAM_SCOPE_LOC:
3539 3560 export_loc = B_TRUE;
3540 3561 ret = nwam_loc_get_name(loc_h, &name);
3541 3562 if (ret != NWAM_SUCCESS)
3542 3563 goto fail;
3543 3564 break;
3544 3565 case NWAM_SCOPE_ENM:
3545 3566 export_enm = B_TRUE;
3546 3567 ret = nwam_enm_get_name(enm_h, &name);
3547 3568 if (ret != NWAM_SUCCESS)
3548 3569 goto fail;
3549 3570 break;
3550 3571 case NWAM_SCOPE_WLAN:
3551 3572 export_wlan = B_TRUE;
3552 3573 ret = nwam_known_wlan_get_name(wlan_h, &name);
3553 3574 if (ret != NWAM_SUCCESS)
3554 3575 goto fail;
3555 3576 break;
3556 3577 case NWAM_SCOPE_NCP:
3557 3578 if (cmd->cmd_res2_type == RT2_NCU) {
3558 3579 export_ncu = B_TRUE;
3559 3580 name = (write_to_file ? trim_quotes(cmd->cmd_argv[2]) :
3560 3581 trim_quotes(cmd->cmd_argv[0]));
3561 3582 } else {
3562 3583 export_ncp = B_TRUE;
3563 3584 ret = nwam_ncp_get_name(ncp_h, &name);
3564 3585 if (ret != NWAM_SUCCESS)
3565 3586 goto fail;
3566 3587 }
3567 3588 break;
3568 3589 case NWAM_SCOPE_NCU:
3569 3590 export_ncu = B_TRUE;
3570 3591 ret = nwam_ncu_get_name(ncu_h, &name);
3571 3592 if (ret != NWAM_SUCCESS)
3572 3593 goto fail;
3573 3594 break;
3574 3595 default:
3575 3596 nerr("Invalid scope");
3576 3597 goto done;
3577 3598 }
3578 3599
3579 3600 /* Now, export objects according to the flags set */
3580 3601 if (export_ncp) {
3581 3602 lhandle = B_FALSE;
3582 3603 if (name == NULL) {
3583 3604 /* export all NCPs */
3584 3605 ret = nwam_walk_ncps(export_ncp_callback, of, 0, NULL);
3585 3606 } else if (NWAM_NCP_AUTOMATIC(name)) {
3586 3607 nerr("'%s' ncp cannot be exported", name);
3587 3608 goto fail;
3588 3609 } else {
3589 3610 if (ncp_h == NULL) {
3590 3611 ret = nwam_ncp_read(name, 0, &ncp_h);
3591 3612 if (ret != NWAM_SUCCESS)
3592 3613 goto fail;
3593 3614 lhandle = B_TRUE;
3594 3615 }
3595 3616 /* will export NCUs also */
3596 3617 ret = export_ncp_callback(ncp_h, of);
3597 3618 if (lhandle) {
3598 3619 nwam_ncp_free(ncp_h);
3599 3620 ncp_h = NULL;
3600 3621 }
3601 3622 }
3602 3623 if (ret != NWAM_SUCCESS)
3603 3624 goto fail;
3604 3625 }
3605 3626
3606 3627 if (export_ncu) {
3607 3628 if (name == NULL) {
3608 3629 /* export all NCUs */
3609 3630 ret = nwam_ncp_walk_ncus(ncp_h, export_ncu_callback, of,
3610 3631 NWAM_FLAG_NCU_TYPE_CLASS_ALL, NULL);
3611 3632 } else {
3612 3633 if (ncu_h == NULL) {
3613 3634 /* no NCU handle -> called from NCP scope */
3614 3635 nwam_ncu_type_t ncu_type;
3615 3636 nwam_ncu_class_t ncu_class;
3616 3637
3617 3638 ncu_class = (nwam_ncu_class_t)
3618 3639 cmd->cmd_ncu_class_type;
3619 3640 ncu_type = nwam_ncu_class_to_type(ncu_class);
3620 3641 ret = nwam_ncu_read(ncp_h, name,
3621 3642 ncu_type, 0, &ncu_h);
3622 3643 if (ret == NWAM_SUCCESS) {
3623 3644 /* one NCU with given name */
3624 3645 ret = export_ncu_callback(ncu_h, of);
3625 3646 nwam_ncu_free(ncu_h);
3626 3647 ncu_h = NULL;
3627 3648 } else if (ret == NWAM_ENTITY_MULTIPLE_VALUES) {
3628 3649 /* multiple NCUs with given name */
3629 3650 ret = nwam_ncu_read(ncp_h, name,
3630 3651 NWAM_NCU_TYPE_LINK, 0, &ncu_h);
3631 3652 if (ret != NWAM_SUCCESS)
3632 3653 goto fail;
3633 3654 ret = export_ncu_callback(ncu_h, of);
3634 3655 nwam_ncu_free(ncu_h);
3635 3656 ncu_h = NULL;
3636 3657
3637 3658 ret = nwam_ncu_read(ncp_h, name,
3638 3659 NWAM_NCU_TYPE_INTERFACE, 0, &ncu_h);
3639 3660 if (ret != NWAM_SUCCESS)
3640 3661 goto fail;
3641 3662 ret = export_ncu_callback(ncu_h, of);
3642 3663 nwam_ncu_free(ncu_h);
3643 3664 ncu_h = NULL;
3644 3665 } else {
3645 3666 goto fail;
3646 3667 }
3647 3668 } else {
3648 3669 /* NCU handle exists */
3649 3670 ret = export_ncu_callback(ncu_h, of);
3650 3671 }
3651 3672 }
3652 3673 if (ret != NWAM_SUCCESS)
3653 3674 goto fail;
3654 3675 }
3655 3676
3656 3677 if (export_loc) {
3657 3678 lhandle = B_FALSE;
3658 3679 if (name == NULL) {
3659 3680 /* export all locations */
3660 3681 ret = nwam_walk_locs(export_loc_callback, of,
3661 3682 NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
3662 3683 } else if (NWAM_LOC_NAME_PRE_DEFINED(name)) {
3663 3684 nerr("'%s' loc cannot be exported", name);
3664 3685 goto fail;
3665 3686 } else {
3666 3687 if (loc_h == NULL) {
3667 3688 ret = nwam_loc_read(name, 0, &loc_h);
3668 3689 if (ret != NWAM_SUCCESS)
3669 3690 goto fail;
3670 3691 lhandle = B_TRUE;
3671 3692 }
3672 3693 ret = export_loc_callback(loc_h, of);
3673 3694 if (lhandle) {
3674 3695 nwam_loc_free(loc_h);
3675 3696 loc_h = NULL;
3676 3697 }
3677 3698 }
3678 3699 if (ret != NWAM_SUCCESS)
3679 3700 goto fail;
3680 3701 }
3681 3702
3682 3703 if (export_enm) {
3683 3704 lhandle = B_FALSE;
3684 3705 if (name == NULL) {
3685 3706 /* export all ENMs */
3686 3707 ret = nwam_walk_enms(export_enm_callback, of,
3687 3708 NWAM_FLAG_ACTIVATION_MODE_ALL, NULL);
3688 3709 } else {
3689 3710 if (enm_h == NULL) {
3690 3711 ret = nwam_enm_read(name, 0, &enm_h);
3691 3712 if (ret != NWAM_SUCCESS)
3692 3713 goto fail;
3693 3714 lhandle = B_TRUE;
3694 3715 }
3695 3716 ret = export_enm_callback(enm_h, of);
3696 3717 if (lhandle) {
3697 3718 nwam_enm_free(enm_h);
3698 3719 enm_h = NULL;
3699 3720 }
3700 3721 }
3701 3722 if (ret != NWAM_SUCCESS)
3702 3723 goto fail;
3703 3724 }
3704 3725
3705 3726 if (export_wlan) {
3706 3727 lhandle = B_FALSE;
3707 3728 if (name == NULL) {
3708 3729 /* export all WLANs */
3709 3730 ret = nwam_walk_known_wlans(export_wlan_callback, of,
3710 3731 NWAM_FLAG_KNOWN_WLAN_WALK_PRIORITY_ORDER, NULL);
3711 3732 } else {
3712 3733 if (wlan_h == NULL) {
3713 3734 ret = nwam_known_wlan_read(name, 0,
3714 3735 &wlan_h);
3715 3736 if (ret != NWAM_SUCCESS)
3716 3737 goto fail;
3717 3738 lhandle = B_TRUE;
3718 3739 }
3719 3740 ret = export_wlan_callback(wlan_h, of);
3720 3741 if (lhandle) {
3721 3742 nwam_known_wlan_free(wlan_h);
3722 3743 wlan_h = NULL;
3723 3744 }
3724 3745 }
3725 3746 if (ret != NWAM_SUCCESS)
3726 3747 goto fail;
3727 3748 }
3728 3749
3729 3750 fail:
3730 3751 free(name);
3731 3752 if (ret != NWAM_SUCCESS)
3732 3753 nwamerr(ret, "Export error");
3733 3754
3734 3755 done:
3735 3756 if (need_to_close)
3736 3757 (void) fclose(of);
3737 3758 }
3738 3759
3739 3760 /*
3740 3761 * Get property value. If the -V option is specified, only the value is
3741 3762 * printed without the property name.
3742 3763 */
3743 3764 void
3744 3765 get_func(cmd_t *cmd)
3745 3766 {
3746 3767 nwam_error_t ret = NWAM_SUCCESS;
3747 3768 nwam_value_t prop_value;
3748 3769 const char *prop;
3749 3770 boolean_t value_only = B_FALSE;
3750 3771 nwam_object_type_t object_type = active_object_type();
3751 3772
3752 3773 /* check if option is -V to print value only */
3753 3774 if (cmd->cmd_argc == 1) {
3754 3775 int c;
3755 3776
3756 3777 optind = 0;
3757 3778 while ((c = getopt(cmd->cmd_argc, cmd->cmd_argv, "V")) != EOF) {
3758 3779 switch (c) {
3759 3780 case 'V':
3760 3781 value_only = B_TRUE;
3761 3782 break;
3762 3783 default:
3763 3784 command_usage(CMD_GET);
3764 3785 return;
3765 3786 }
3766 3787 }
3767 3788 }
3768 3789
3769 3790 /* property to get is in cmd->cmd_prop_type */
3770 3791 if ((prop = pt_to_prop_name(object_type, cmd->cmd_prop_type)) == NULL) {
3771 3792 nerr("Get error: invalid %s property: '%s'",
3772 3793 scope_to_str(current_scope), pt_to_str(cmd->cmd_prop_type));
3773 3794 return;
3774 3795 }
3775 3796
3776 3797 switch (object_type) {
3777 3798 case NWAM_OBJECT_TYPE_NCU:
3778 3799 ret = nwam_ncu_get_prop_value(ncu_h, prop, &prop_value);
3779 3800 break;
3780 3801 case NWAM_OBJECT_TYPE_LOC:
3781 3802 ret = nwam_loc_get_prop_value(loc_h, prop, &prop_value);
3782 3803 break;
3783 3804 case NWAM_OBJECT_TYPE_ENM:
3784 3805 ret = nwam_enm_get_prop_value(enm_h, prop, &prop_value);
3785 3806 break;
3786 3807 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
3787 3808 ret = nwam_known_wlan_get_prop_value(wlan_h, prop, &prop_value);
3788 3809 break;
3789 3810 }
3790 3811
3791 3812 if (ret != NWAM_SUCCESS) {
3792 3813 if (ret == NWAM_ENTITY_NOT_FOUND)
3793 3814 nerr("Get error: property '%s' has not been set", prop);
3794 3815 else
3795 3816 nwamerr(ret, "Get error");
3796 3817 return;
3797 3818 }
3798 3819
3799 3820 if (value_only) {
3800 3821 output_prop_val(prop, prop_value, stdout, B_FALSE);
3801 3822 (void) printf("\n");
3802 3823 } else {
3803 3824 output_propname(prop, prop_value, NULL);
3804 3825 }
3805 3826 nwam_value_free(prop_value);
3806 3827 }
3807 3828
3808 3829 /*
3809 3830 * Clears value of a property.
3810 3831 * Read-only properties cannot be cleared.
3811 3832 * If clearing a property invalidates the object, then that property
3812 3833 * cannot be cleared.
3813 3834 */
3814 3835 void
3815 3836 clear_func(cmd_t *cmd)
3816 3837 {
3817 3838 nwam_error_t ret;
3818 3839 const char *prop;
3819 3840 nwam_object_type_t object_type = active_object_type();
3820 3841
3821 3842 /* property to clear is in cmd->cmd_prop_type */
3822 3843 if ((prop = pt_to_prop_name(object_type, cmd->cmd_prop_type)) == NULL) {
3823 3844 nerr("Clear error: invalid %s property: '%s'",
3824 3845 scope_to_str(current_scope), pt_to_str(cmd->cmd_prop_type));
3825 3846 return;
3826 3847 }
3827 3848 if (is_prop_read_only(object_type, prop)) {
3828 3849 nerr("Clear error: property '%s' is read-only", prop);
3829 3850 return;
3830 3851 }
3831 3852
3832 3853 switch (object_type) {
3833 3854 case NWAM_OBJECT_TYPE_NCU:
3834 3855 ret = nwam_ncu_delete_prop(ncu_h, prop);
3835 3856 break;
3836 3857 case NWAM_OBJECT_TYPE_LOC:
3837 3858 ret = nwam_loc_delete_prop(loc_h, prop);
3838 3859 break;
3839 3860 case NWAM_OBJECT_TYPE_ENM:
3840 3861 ret = nwam_enm_delete_prop(enm_h, prop);
3841 3862 break;
3842 3863 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
3843 3864 ret = nwam_known_wlan_delete_prop(wlan_h, prop);
3844 3865 break;
3845 3866 }
3846 3867
3847 3868 if (ret != NWAM_SUCCESS) {
3848 3869 if (ret == NWAM_INVALID_ARG || ret == NWAM_ENTITY_NOT_FOUND) {
3849 3870 nerr("Clear error: property '%s' has not been set",
3850 3871 prop);
3851 3872 } else {
3852 3873 nwamerr(ret, "Clear error");
3853 3874 }
3854 3875 return;
3855 3876 }
3856 3877
3857 3878 need_to_commit = B_TRUE;
3858 3879 }
3859 3880
3860 3881 /*
3861 3882 * Prints all the choices available for an enum property [c1|c2|c3].
3862 3883 * Prints [true|false] for a boolean property.
3863 3884 */
3864 3885 static void
3865 3886 print_all_prop_choices(nwam_object_type_t object_type, const char *prop)
3866 3887 {
3867 3888 uint64_t i = 0;
3868 3889 const char *str;
3869 3890 boolean_t choices = B_FALSE;
3870 3891 nwam_value_type_t value_type;
3871 3892 nwam_error_t ret;
3872 3893
3873 3894 /* Special case: print object-specific options for activation-mode */
3874 3895 if (strcmp(prop, NWAM_NCU_PROP_ACTIVATION_MODE) == 0) {
3875 3896 /* "manual" for all objects */
3876 3897 (void) printf(" [%s|",
3877 3898 propval_to_str(NWAM_NCU_PROP_ACTIVATION_MODE,
3878 3899 NWAM_ACTIVATION_MODE_MANUAL));
3879 3900 if (object_type == NWAM_OBJECT_TYPE_NCU) {
3880 3901 (void) printf("%s]",
3881 3902 propval_to_str(NWAM_NCU_PROP_ACTIVATION_MODE,
3882 3903 NWAM_ACTIVATION_MODE_PRIORITIZED));
3883 3904 } else {
3884 3905 (void) printf("%s|%s]",
3885 3906 propval_to_str(NWAM_NCU_PROP_ACTIVATION_MODE,
3886 3907 NWAM_ACTIVATION_MODE_CONDITIONAL_ANY),
3887 3908 propval_to_str(NWAM_NCU_PROP_ACTIVATION_MODE,
3888 3909 NWAM_ACTIVATION_MODE_CONDITIONAL_ALL));
3889 3910 }
3890 3911 return;
3891 3912 }
3892 3913
3893 3914 /* Special case: only "manual" configsrc is allowed for LDAP */
3894 3915 if (strcmp(prop, NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC) == 0) {
3895 3916 (void) printf(" [%s]",
3896 3917 propval_to_str(NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC,
3897 3918 NWAM_CONFIGSRC_MANUAL));
3898 3919 return;
3899 3920 }
3900 3921
3901 3922 value_type = prop_value_type(object_type, prop);
3902 3923 switch (value_type) {
3903 3924 case NWAM_VALUE_TYPE_UINT64:
3904 3925 /* uint64 may be an enum, will print nothing if not an enum */
3905 3926 while ((ret = nwam_uint64_get_value_string(prop, i++, &str))
3906 3927 == NWAM_SUCCESS || ret == NWAM_ENTITY_INVALID_VALUE) {
3907 3928 /* No string representation for i, continue. */
3908 3929 if (ret == NWAM_ENTITY_INVALID_VALUE)
3909 3930 continue;
3910 3931
3911 3932 if (!choices)
3912 3933 (void) printf("%s", " [");
3913 3934 (void) printf("%s%s", choices ? "|" : "", str);
3914 3935 choices = B_TRUE;
3915 3936 }
3916 3937 if (choices)
3917 3938 (void) putchar(']');
3918 3939 break;
3919 3940 case NWAM_VALUE_TYPE_BOOLEAN:
3920 3941 (void) printf(" [%s|%s]", "true", "false");
3921 3942 break;
3922 3943 case NWAM_VALUE_TYPE_STRING:
3923 3944 break;
3924 3945 }
3925 3946 }
3926 3947
3927 3948 /*
3928 3949 * Walk through object properties.
3929 3950 * For newly-created object, the property name with no value is displayed, and
3930 3951 * the user can input a value for each property.
3931 3952 * For existing object, the current value is displayed and user input overwrites
3932 3953 * the existing one. If no input is given, the existing value remains.
3933 3954 * Read-only properties are not displayed.
3934 3955 * Read-only objects cannot be walked.
3935 3956 * If the -a option is specified, no properties are skipped.
3936 3957 */
3937 3958 void
3938 3959 walkprop_func(cmd_t *cmd)
3939 3960 {
3940 3961 nwam_error_t ret = NWAM_SUCCESS;
3941 3962 nwam_value_t vals = NULL; /* freed in _wait_input() */
3942 3963 int i;
3943 3964 uint_t prop_num;
3944 3965 const char **props;
3945 3966 boolean_t read_only = B_FALSE, all_props = B_FALSE;
3946 3967
3947 3968 nwam_object_type_t object_type;
3948 3969 prop_display_entry_t *prop_table;
3949 3970
3950 3971 if (!interactive_mode) {
3951 3972 nerr("'walkprop' is only allowed in interactive mode");
3952 3973 return;
3953 3974 }
3954 3975
3955 3976 /* check if option -a is specified to show all properties */
3956 3977 if (cmd->cmd_argc == 1) {
3957 3978 int c;
3958 3979 optind = 0;
3959 3980 while ((c = getopt(cmd->cmd_argc, cmd->cmd_argv, "a")) != EOF) {
3960 3981 switch (c) {
3961 3982 case 'a':
3962 3983 all_props = B_TRUE;
3963 3984 break;
3964 3985 default:
3965 3986 command_usage(CMD_WALKPROP);
3966 3987 return;
3967 3988 }
3968 3989 }
3969 3990 }
3970 3991
3971 3992 /* read-only objects cannot be walked */
3972 3993 if (obj1_type == RT1_NCP) {
3973 3994 /* must be in NCU scope, NCP scope doesn't get here */
3974 3995 (void) nwam_ncu_get_read_only(ncu_h, &read_only);
3975 3996 }
3976 3997 if (read_only) {
3977 3998 nerr("'walkprop' cannot be used in read-only objects");
3978 3999 return;
3979 4000 }
3980 4001
3981 4002 /* get the current object type and the prop_display_table */
3982 4003 object_type = active_object_type();
3983 4004 prop_table = get_prop_display_table(object_type);
3984 4005
3985 4006 /* get the property list depending on the object type */
3986 4007 switch (object_type) {
3987 4008 case NWAM_OBJECT_TYPE_NCU:
3988 4009 {
3989 4010 nwam_ncu_type_t ncu_type;
3990 4011 nwam_ncu_class_t ncu_class;
3991 4012
3992 4013 if ((ret = nwam_ncu_get_ncu_type(ncu_h, &ncu_type))
3993 4014 != NWAM_SUCCESS)
3994 4015 break;
3995 4016 if ((ret = nwam_ncu_get_ncu_class(ncu_h, &ncu_class))
3996 4017 != NWAM_SUCCESS)
3997 4018 break;
3998 4019
3999 4020 ret = nwam_ncu_get_default_proplist(ncu_type, ncu_class, &props,
4000 4021 &prop_num);
4001 4022 break;
4002 4023 }
4003 4024 case NWAM_OBJECT_TYPE_LOC:
4004 4025 ret = nwam_loc_get_default_proplist(&props, &prop_num);
4005 4026 break;
4006 4027 case NWAM_OBJECT_TYPE_ENM:
4007 4028 ret = nwam_enm_get_default_proplist(&props, &prop_num);
4008 4029 break;
4009 4030 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
4010 4031 ret = nwam_known_wlan_get_default_proplist(&props, &prop_num);
4011 4032 break;
4012 4033 }
4013 4034 if (ret != NWAM_SUCCESS) {
4014 4035 nwamerr(ret, "Walkprop error: could not get property list");
4015 4036 return;
4016 4037 }
4017 4038
4018 4039 /* Loop through the properties */
4019 4040 if (all_props)
4020 4041 (void) printf(gettext("Walking all properties ...\n"));
4021 4042 for (i = 0; i < prop_num; i++) {
4022 4043 char line[NWAM_MAX_VALUE_LEN];
4023 4044 char **checked = NULL;
4024 4045
4025 4046 /* check if this property should be displayed */
4026 4047 if (is_prop_read_only(object_type, props[i]))
4027 4048 continue;
4028 4049 if (!all_props &&
4029 4050 !show_prop_test(object_type, props[i], prop_table,
4030 4051 checked, 0))
4031 4052 continue;
4032 4053
4033 4054 /* get the existing value for this property */
4034 4055 switch (object_type) {
4035 4056 case NWAM_OBJECT_TYPE_NCU:
4036 4057 ret = nwam_ncu_get_prop_value(ncu_h, props[i], &vals);
4037 4058 break;
4038 4059 case NWAM_OBJECT_TYPE_LOC:
4039 4060 ret = nwam_loc_get_prop_value(loc_h, props[i], &vals);
4040 4061 break;
4041 4062 case NWAM_OBJECT_TYPE_ENM:
4042 4063 ret = nwam_enm_get_prop_value(enm_h, props[i], &vals);
4043 4064 break;
4044 4065 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
4045 4066 ret = nwam_known_wlan_get_prop_value(wlan_h, props[i],
4046 4067 &vals);
4047 4068 break;
4048 4069 }
4049 4070 /* returns NWAM_ENTITY_NOT_FOUND if no existing value */
4050 4071 if (ret != NWAM_SUCCESS && ret != NWAM_ENTITY_NOT_FOUND)
4051 4072 continue;
4052 4073
4053 4074 /* print property */
4054 4075 (void) printf("%s", props[i]);
4055 4076 /* print the existing value(s) if they exist */
4056 4077 if (ret == NWAM_SUCCESS) {
4057 4078 (void) printf(" (");
4058 4079 output_prop_val(props[i], vals, stdout, B_TRUE);
4059 4080 (void) putchar(')');
4060 4081 nwam_value_free(vals);
4061 4082 }
4062 4083 /* print choices, won't print anything if there aren't any */
4063 4084 print_all_prop_choices(object_type, props[i]);
4064 4085 (void) printf("> ");
4065 4086
4066 4087 /* wait for user input */
4067 4088 if (fgets(line, sizeof (line), stdin) == NULL)
4068 4089 continue;
4069 4090
4070 4091 /* if user input new value, existing value is overrode */
4071 4092 if (line[0] != '\n') {
4072 4093 boolean_t is_listprop;
4073 4094 int pt_type = prop_to_pt(object_type, props[i]);
4074 4095
4075 4096 is_listprop = is_prop_multivalued(object_type,
4076 4097 props[i]);
4077 4098 vals = str_to_nwam_value(object_type, line, pt_type,
4078 4099 is_listprop);
4079 4100 if (vals == NULL) {
4080 4101 ret = NWAM_ENTITY_INVALID_VALUE;
4081 4102 goto repeat;
4082 4103 }
4083 4104
4084 4105 /* set the new value for the property */
4085 4106 switch (object_type) {
4086 4107 case NWAM_OBJECT_TYPE_NCU:
4087 4108 ret = nwam_ncu_set_prop_value(ncu_h, props[i],
4088 4109 vals);
4089 4110 break;
4090 4111 case NWAM_OBJECT_TYPE_LOC:
4091 4112 ret = nwam_loc_set_prop_value(loc_h, props[i],
4092 4113 vals);
4093 4114 break;
4094 4115 case NWAM_OBJECT_TYPE_ENM:
4095 4116 ret = nwam_enm_set_prop_value(enm_h, props[i],
4096 4117 vals);
4097 4118 break;
4098 4119 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
4099 4120 ret = nwam_known_wlan_set_prop_value(wlan_h,
4100 4121 props[i], vals);
4101 4122 break;
4102 4123 }
4103 4124 nwam_value_free(vals);
4104 4125
4105 4126 if (ret != NWAM_SUCCESS)
4106 4127 goto repeat;
4107 4128
4108 4129 need_to_commit = B_TRUE;
4109 4130 continue;
4110 4131
4111 4132 repeat:
4112 4133 invalid_set_prop_msg(props[i], ret);
4113 4134 i--; /* decrement i to repeat */
4114 4135 }
4115 4136 }
4116 4137
4117 4138 free(props);
4118 4139 }
4119 4140
4120 4141 /*
4121 4142 * Verify whether all properties of a resource are valid.
4122 4143 */
4123 4144 /* ARGSUSED */
4124 4145 void
4125 4146 verify_func(cmd_t *cmd)
4126 4147 {
4127 4148 nwam_error_t ret;
4128 4149 const char *errprop;
4129 4150
4130 4151 switch (active_object_type()) {
4131 4152 case NWAM_OBJECT_TYPE_NCU:
4132 4153 ret = nwam_ncu_validate(ncu_h, &errprop);
4133 4154 break;
4134 4155 case NWAM_OBJECT_TYPE_LOC:
4135 4156 ret = nwam_loc_validate(loc_h, &errprop);
4136 4157 break;
4137 4158 case NWAM_OBJECT_TYPE_ENM:
4138 4159 ret = nwam_enm_validate(enm_h, &errprop);
4139 4160 break;
4140 4161 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
4141 4162 ret = nwam_known_wlan_validate(wlan_h, &errprop);
4142 4163 break;
4143 4164 }
4144 4165 if (ret != NWAM_SUCCESS)
4145 4166 nwamerr(ret, "Verify error on property '%s'", errprop);
4146 4167 else if (interactive_mode)
4147 4168 (void) printf(gettext("All properties verified\n"));
4148 4169 }
4149 4170
4150 4171 /*
4151 4172 * command-line mode (# nwamcfg list or # nwamcfg "select loc test; list")
4152 4173 */
4153 4174 static int
4154 4175 one_command_at_a_time(int argc, char *argv[])
4155 4176 {
4156 4177 char *command;
4157 4178 size_t len = 2; /* terminal \n\0 */
4158 4179 int i, err;
4159 4180
4160 4181 for (i = 0; i < argc; i++)
4161 4182 len += strlen(argv[i]) + 1;
4162 4183 if ((command = malloc(len)) == NULL) {
4163 4184 nerr("Out of memory");
4164 4185 return (NWAM_ERR);
4165 4186 }
4166 4187 (void) strlcpy(command, argv[0], len);
4167 4188 for (i = 1; i < argc; i++) {
4168 4189 (void) strlcat(command, " ", len);
4169 4190 (void) strlcat(command, argv[i], len);
4170 4191 }
4171 4192 (void) strlcat(command, "\n", len);
4172 4193 err = string_to_yyin(command);
4173 4194 free(command);
4174 4195 if (err != NWAM_OK)
4175 4196 return (err);
4176 4197 while (!feof(yyin)) {
4177 4198 yyparse();
4178 4199
4179 4200 /*
4180 4201 * If any command on a list of commands give an error,
4181 4202 * don't continue with the remaining commands.
4182 4203 */
4183 4204 if (saw_error || time_to_exit)
4184 4205 return (cleanup());
4185 4206 }
4186 4207
4187 4208 /* if there are changes to commit, commit it */
4188 4209 if (need_to_commit) {
4189 4210 do_commit();
4190 4211 /* if need_to_commit is not set, then there was a error */
4191 4212 if (need_to_commit)
4192 4213 return (NWAM_ERR);
4193 4214 }
4194 4215
4195 4216 if (!interactive_mode)
4196 4217 return (cleanup());
4197 4218 else {
4198 4219 yyin = stdin;
4199 4220 return (read_input());
4200 4221 }
4201 4222 }
4202 4223
4203 4224 /*
4204 4225 * cmd_file is slightly more complicated, as it has to open the command file
4205 4226 * and set yyin appropriately. Once that is done, though, it just calls
4206 4227 * read_input(), and only once, since prompting is not possible.
4207 4228 */
4208 4229 static int
4209 4230 cmd_file(char *file)
4210 4231 {
4211 4232 FILE *infile;
4212 4233 int err;
4213 4234 struct stat statbuf;
4214 4235 boolean_t using_real_file = (strcmp(file, "-") != 0);
4215 4236
4216 4237 if (using_real_file) {
4217 4238 /*
4218 4239 * nerr() prints a line number in cmd_file_mode, which we do
4219 4240 * not want here, so temporarily unset it.
4220 4241 */
4221 4242 cmd_file_mode = B_FALSE;
4222 4243 if ((infile = fopen(file, "r")) == NULL) {
4223 4244 nerr(gettext("could not open file '%s': %s"),
4224 4245 file, strerror(errno));
4225 4246 return (1);
4226 4247 }
4227 4248 if ((err = fstat(fileno(infile), &statbuf)) != 0) {
4228 4249 nerr(gettext("could not stat file '%s': %s"),
4229 4250 file, strerror(errno));
4230 4251 err = 1;
4231 4252 goto done;
4232 4253 }
4233 4254 if (!S_ISREG(statbuf.st_mode)) {
4234 4255 nerr(gettext("'%s' is not a regular file."), file);
4235 4256 err = 1;
4236 4257 goto done;
4237 4258 }
4238 4259
4239 4260 /*
4240 4261 * If -d was passed on the command-line, we need to
4241 4262 * start by removing any existing configuration.
4242 4263 * Alternatively, the file may begin with 'destroy -a';
4243 4264 * but in that case, the line will go through the lexer
4244 4265 * and be processed as it's encountered in the file.
4245 4266 */
4246 4267 if (remove_all_configurations && destroy_all() != NWAM_SUCCESS)
4247 4268 goto done;
4248 4269
4249 4270 /* set up for lexer */
4250 4271 yyin = infile;
4251 4272 cmd_file_mode = B_TRUE;
4252 4273 ok_to_prompt = B_FALSE;
4253 4274 } else {
4254 4275 /*
4255 4276 * "-f -" is essentially the same as interactive mode,
4256 4277 * so treat it that way.
4257 4278 */
4258 4279 interactive_mode = B_TRUE;
4259 4280 }
4260 4281 /* NWAM_REPEAT is for interactive mode; treat it like NWAM_ERR here. */
4261 4282 if ((err = read_input()) == NWAM_REPEAT)
4262 4283 err = NWAM_ERR;
4263 4284 if (err == NWAM_OK)
4264 4285 (void) printf(gettext("Configuration read.\n"));
4265 4286
4266 4287 done:
4267 4288 if (using_real_file)
4268 4289 (void) fclose(infile);
4269 4290 return (err);
4270 4291 }
4271 4292
4272 4293 int
4273 4294 main(int argc, char *argv[])
4274 4295 {
4275 4296 int err;
4276 4297 char c;
4277 4298
4278 4299 /* This must be before anything goes to stdout. */
4279 4300 setbuf(stdout, NULL);
4280 4301
4281 4302 if ((execname = strrchr(argv[0], '/')) == NULL)
4282 4303 execname = argv[0];
4283 4304 else
4284 4305 execname++;
4285 4306
4286 4307 (void) setlocale(LC_ALL, "");
4287 4308 (void) textdomain(TEXT_DOMAIN);
4288 4309
4289 4310 while ((c = getopt(argc, argv, "?hf:d")) != EOF) {
4290 4311 switch (c) {
4291 4312 case 'f':
4292 4313 cmd_file_name = optarg;
4293 4314 cmd_file_mode = B_TRUE;
4294 4315 break;
4295 4316 case '?':
4296 4317 case 'h':
4297 4318 cmd_line_usage();
4298 4319 return (NWAM_OK);
4299 4320 case 'd':
4300 4321 remove_all_configurations = B_TRUE;
4301 4322 break;
4302 4323 default:
4303 4324 cmd_line_usage();
4304 4325 return (NWAM_ERR);
4305 4326 }
4306 4327 }
4307 4328 /* -d can only be used with -f */
4308 4329 if (remove_all_configurations && !cmd_file_mode) {
4309 4330 nerr("Option -d can only be used with -f");
4310 4331 return (NWAM_ERR);
4311 4332 }
4312 4333
4313 4334 /*
4314 4335 * This may get set back to FALSE again in cmd_file() if cmd_file_name
4315 4336 * is a "real" file as opposed to "-" (i.e. meaning use stdin).
4316 4337 */
4317 4338 if (isatty(STDIN_FILENO))
4318 4339 ok_to_prompt = B_TRUE;
4319 4340 if ((gl = new_GetLine(MAX_LINE_LEN, MAX_CMD_HIST)) == NULL)
4320 4341 exit(NWAM_ERR);
4321 4342 if (gl_customize_completion(gl, NULL, cmd_cpl_fn) != 0)
4322 4343 exit(NWAM_ERR);
4323 4344 (void) sigset(SIGINT, SIG_IGN);
4324 4345
4325 4346 if (optind == argc) {
4326 4347 /* interactive or command-file mode */
4327 4348 if (!cmd_file_mode)
4328 4349 err = do_interactive();
4329 4350 else
4330 4351 err = cmd_file(cmd_file_name);
4331 4352 } else {
4332 4353 /* command-line mode */
4333 4354 err = one_command_at_a_time(argc - optind, &(argv[optind]));
4334 4355 }
4335 4356 (void) del_GetLine(gl);
4336 4357
4337 4358 return (err);
4338 4359 }
|
↓ open down ↓ |
2129 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX