/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/*
* configurations. The lexer (see nwamcfg_lex.l) builds up tokens, which
* the grammar (see nwamcfg_grammar.y) builds up into commands, some of
*/
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <libnwam.h>
#include <libtecla.h>
#include <locale.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <sys/sysmacros.h>
#include <unistd.h>
#include "nwamcfg.h"
#if !defined(TEXT_DOMAIN) /* should be defined by cc -D */
#endif
struct help {
const char *cmd_name;
const char *cmd_usage;
};
extern int yyparse(void);
extern int lex_lineno;
/* usage of commands */
"<object-name>"
"[<object-type> [<class>] <object-name>]"
/*
* Scope Definitions:
* Locations, ENMs, NCPs and Known WLANs are one scope level below global (GBL).
* NCUs are one more level beneath the NCP scope.
* the scope are divided accordingly.
* GBL->LOC, GBL->ENM, GBL->WLAN or GBL->NCP->NCU
*/
#define NWAM_SCOPE_GBL 0
/* delimiter used for list of values */
/* the max number of values for an enum used by some properties in libnwam */
/*
* the array. When looping, check for NULL rather than using the size.
*/
};
/* These *must* match the order of the RT1_ define's from nwamcfg.h */
static char *res1_types[] = {
"unknown",
"loc",
"ncp",
"enm",
"wlan",
};
/* These *must* match the order of the RT2_ define's from nwamcfg.h */
static char *res2_types[] = {
"unknown",
"ncu",
};
/*
* No array for NCU_CLASS_. The #define's in nwamcfg.h matches the
* enum nwam_ncu_class_t in libnwam and thus uses libnwam functions to
* retrieve the string representation.
*/
/* These *MUST* match the order of the PT_ define's from nwamcfg.h */
static char *pt_types[] = {
"unknown",
};
/* properties table: maps PT_* constants to property names */
typedef struct prop_table_entry {
int pte_type;
const char *pte_name;
/* NCU properties table */
{ PT_TYPE, NWAM_NCU_PROP_TYPE },
{ PT_CLASS, NWAM_NCU_PROP_CLASS },
{ 0, NULL }
};
/* ENM properties table */
{ 0, NULL }
};
/* LOCation properties table */
{ 0, NULL }
};
/* Known WLAN properties table */
{ 0, NULL }
};
/* Returns the appropriate properties table for the given object type */
static prop_table_entry_t *
{
switch (object_type) {
case NWAM_OBJECT_TYPE_NCU:
return (ncu_prop_table);
case NWAM_OBJECT_TYPE_LOC:
return (loc_prop_table);
case NWAM_OBJECT_TYPE_ENM:
return (enm_prop_table);
return (wlan_prop_table);
}
return (NULL);
}
/* Global variables */
/* set early in main(), never modified thereafter, used all over the place */
static char *execname;
/* set in modifying functions, checked in read_input() */
/* set in yacc parser, checked in read_input() */
/* set in main(), checked in lex error handler */
/* set in exit_func(), checked in read_input() */
/* used in nerr() and nwamerr() */
/* used with cmd_file to destroy all configurations */
/* checked in read_input() and other places */
/* initialized in do_interactive(), checked in initialize() */
/* The gl_get_line() resource object */
/* set when create or read objects, used by other func */
/* obj1_* are used in NWAM_SCOPE_{NCP,LOC,ENM,WLAN} */
static int obj1_type;
/* obj2_* are used in NWAM_SCOPE_NCU only */
static int obj2_type;
/* arrays for tab-completion */
/* commands at NWAM_SCOPE_GBL */
static const char *global_scope_cmds[] = {
"create ",
"destroy ",
"end ",
"exit ",
"export ",
"help ",
"list ",
"select ",
};
static const char *global_create_cmds[] = {
"create loc ",
"create enm ",
"create ncp ",
"create wlan ",
"create -t ", /* template */
};
static const char *global_destroy_cmds[] = {
"destroy -a ",
"destroy loc ",
"destroy enm ",
"destroy ncp ",
"destroy wlan ",
};
static const char *global_export_cmds[] = {
"export ",
"export -d ", /* add destroy -a */
"export -f ", /* to file */
"export -d -f ", /* add destroy -a to file */
"export loc ",
"export enm ",
"export ncp ",
"export wlan ",
};
static const char *global_list_cmds[] = {
"list ",
"list loc ",
"list enm ",
"list ncp ",
"list wlan ",
"list -a loc ",
"list -a enm ",
"list -a wlan ",
};
static const char *global_select_cmds[] = {
"select loc ",
"select enm ",
"select ncp ",
"select wlan ",
};
/* commands at NWAM_SCOPE_LOC, _ENM, _WLAN and _NCU */
static const char *non_ncp_scope_cmds[] = {
"cancel ",
"clear ",
"commit ",
"end ",
"exit ",
"export ",
"export -f ",
"get ",
"get -V ", /* value only */
"help ",
"list ",
"list -a ", /* all properties */
"revert ",
"set ",
"verify ",
"walkprop ",
"walkprop -a ", /* all properties */
};
/* commands at NWAM_SCOPE_NCP */
static const char *ncp_scope_cmds[] = {
"cancel ",
"create ",
"destroy ",
"end ",
"exit ",
"export ",
"help ",
"list ",
"select ",
};
static const char *ncp_create_cmds[] = {
"create ncu ip ",
"create ncu phys ",
"create -t ", /* template */
};
static const char *ncp_destroy_cmds[] = {
"destroy ncu ",
"destroy ncu ip ",
"destroy ncu phys ",
};
static const char *ncp_export_cmds[] = {
"export ",
"export -f ", /* to file */
"export ncu ",
"export ncu ip ",
"export ncu phys ",
};
static const char *ncp_list_cmds[] = {
"list ",
"list ncu ",
"list ncu ip ",
"list ncu phys ",
"list -a ncu ",
"list -a ncu ip ",
"list -a ncu phys ",
};
static const char *ncp_select_cmds[] = {
"select ncu ",
"select ncu ip ",
"select ncu phys ",
};
/* Functions begin here */
cmd_t *
alloc_cmd(void)
{
nerr("Out of memory");
return (NULL);
}
return (cmd);
}
void
{
int i;
}
void
{
int i;
for (i = 0; i < nelem; i++)
}
static boolean_t
{
if (word_end <= 0)
return (B_TRUE);
}
static int
int word_end)
{
int i, err;
if (err != 0)
return (err);
}
}
return (0);
}
/*
* To fill in the rest of a string when user types the tab key.
* First digital number is the length of the string, the second digital number
* is the min number of chars that is needed to uniquely identify a string.
*/
/* ARGSUSED */
static
{
/* tab-complete according to the current scope */
switch (current_scope) {
case NWAM_SCOPE_GBL:
word_end));
word_end));
word_end));
word_end));
word_end));
case NWAM_SCOPE_LOC:
case NWAM_SCOPE_ENM:
case NWAM_SCOPE_WLAN:
case NWAM_SCOPE_NCU:
case NWAM_SCOPE_NCP:
word_end));
word_end));
word_end));
word_end));
}
/* should never get here */
return (NULL);
}
const char *
{
}
/* Returns "loc", "enm", "wlan" or "ncp" as string */
static const char *
{
return (res1_types[res_type]);
}
/* Returns "ncu" as string */
static const char *
{
return (res2_types[res_type]);
}
/* Returns "ncp, "ncu", "loc", "enm", or "wlan" according to the scope */
static const char *
switch (scope) {
case NWAM_SCOPE_GBL:
return ("global");
case NWAM_SCOPE_NCP:
return ("ncp");
case NWAM_SCOPE_NCU:
return ("ncu");
case NWAM_SCOPE_LOC:
return ("loc");
case NWAM_SCOPE_ENM:
return ("enm");
case NWAM_SCOPE_WLAN:
return ("wlan");
default:
return ("invalid");
}
}
/* Given an enm property and value, returns it as a string */
static const char *
{
const char *str;
return (str);
return (NULL);
}
/* Given an int for a prop, returns it as string */
static const char *
{
}
/* Return B_TRUE if string starts with "t" or is 1, B_FALSE otherwise */
static boolean_t
{
return (B_TRUE);
else
return (B_FALSE);
}
/*
* This is a separate function rather than a set of define's because of the
* gettext() wrapping.
*/
/*
* TRANSLATION_NOTE
* Each string below should have \t follow \n whenever needed; the
* initial \t and the terminal \n will be provided by the calling function.
*/
static const char *
{
switch (cmd_num) {
case CMD_CANCEL:
return (gettext("Cancels the current configuration "
"changes."));
case CMD_CLEAR:
return (gettext("Clears the value for the specified "
"property."));
case CMD_COMMIT:
return (gettext("Commits the current configuration."));
case CMD_CREATE:
return (gettext("Creates a new profile or resource."));
case CMD_DESTROY:
return (gettext("Destroys the specified profile or "
"resource."));
case CMD_END:
return (gettext("Ends specification of a resource."));
case CMD_EXIT:
return (gettext("Exits the program."));
case CMD_EXPORT:
return (gettext("Exports the configuration."));
case CMD_GET:
return (gettext("Gets the value of the specified "
"property."));
case CMD_HELP:
return (gettext("Prints help message."));
case CMD_LIST:
return (gettext("Lists existing objects."));
case CMD_REVERT:
return (gettext("Reverts to the previous "
"configuration."));
case CMD_SELECT:
return (gettext("Selects a resource to modify."));
case CMD_SET:
return (gettext("Sets the value of the specified "
"property."));
case CMD_VERIFY:
return (gettext("Verifies an object."));
case CMD_WALKPROP:
return (gettext("Iterates over properties."));
default:
return (gettext("Unknown command."));
}
}
void
{
nerr("Unknown command");
} else {
}
}
static void
{
}
/* Prints usage for command line options */
static void
{
gettext("interactive-mode"));
gettext("options"));
gettext("command"));
}
/* Prints the line number of the current command if in command-file mode */
static void
{
static int last_lineno;
/* lex_lineno has already been incremented in the lexer; compensate */
lex_lineno - 1);
else
}
}
/* PRINTFLIKE1 */
void
{
print_lineno();
}
/* PRINTFLIKE2 */
static void
{
print_lineno();
}
void
{
}
/*
* If free_ncu_only == B_TRUE, only ncu handle is freed, ncp handle remains the
* same. Since nwam_ncp_free() takes care of its ncus, no need to explicitly
* call nwam_ncu_free() afterwards.
*/
static void
{
if (!free_ncu_only) {
}
}
}
}
}
}
/*
* On input, TRUE => yes, FALSE => no.
* On return, TRUE => 1, FALSE => no, could not ask => -1.
*/
static int
{
if (!ok_to_prompt) {
return (-1);
}
for (;;) {
return (-1);
return (-1);
if (line[0] == '\n')
return (default_answer ? 1 : 0);
return (1);
return (0);
}
}
/* This is the back-end helper function for read_input() below. */
static int
cleanup()
{
int answer;
if (!interactive_mode && !cmd_file_mode) {
/*
* If we're not in interactive mode, and we're not in command
* file mode, then we must be in commands-from-the-command-line
* mode. As such, we can't loop back and ask for more input.
* It was OK to prompt for such things as whether or not to
* really delete something in the command handler called from
* yyparse() above, but "really quit?" makes no sense in this
* context. So disable prompting.
*/
}
if (need_to_commit) {
"Configuration not saved; really quit");
switch (answer) {
case -1:
/* issue error here */
return (NWAM_ERR);
case 1:
/*
* don't want to save, just exit. handles are freed at
* end_func() or exit_func().
*/
return (NWAM_OK);
default:
/* loop back to read input */
return (NWAM_REPEAT);
}
}
}
static int
{
goto error;
goto error;
goto error;
return (NWAM_OK);
nerr("problem creating temporary file");
return (NWAM_ERR);
}
/*
* read_input() is the driver of this program. It is a wrapper around
* yyparse(), printing appropriate prompts when needed, checking for
* exit conditions and reacting appropriately. This function is
* called when in interactive mode or command-file mode.
*/
static int
read_input(void)
{
/*
* The prompt is "e> " or "e:t1:o1> " or "e:t1:o1:t2:o2> " where e is
* execname, t is resource type, o is object name.
*/
+ sizeof ("::::> ")];
char *line;
/* yyin should have been set to the appropriate (FILE *) if not stdin */
for (;;) {
if (yyin_is_a_tty) {
if (newline_terminated) {
switch (current_scope) {
case NWAM_SCOPE_GBL:
"%s> ", execname);
break;
case NWAM_SCOPE_LOC:
case NWAM_SCOPE_ENM:
case NWAM_SCOPE_WLAN:
case NWAM_SCOPE_NCP:
"%s:%s:%s> ", execname,
break;
case NWAM_SCOPE_NCU:
"%s:%s:%s:%s:%s> ", execname,
}
}
/*
* If the user hits ^C then we want to catch it and
* start over. If the user hits EOF then we want to
* bail out.
*/
continue;
}
break;
break;
yyparse();
/*
* If any command on a list of commands
* give an error, don't continue with the
* remaining commands.
*/
if (saw_error || time_to_exit)
break;
}
} else {
yyparse();
}
/* Bail out on an error in command-file mode. */
break;
}
return (cleanup());
}
/*
* This function is used in the interactive-mode scenario: it just calls
* read_input() until we are done.
*/
static int
do_interactive(void)
{
int err;
do {
err = read_input();
} while (err == NWAM_REPEAT);
return (err);
}
/* Calls the help_func() to print the usage of all commands */
void
{
}
/* Check if the given command is allowed in the current scope */
{
/* allowed in all scopes */
switch (cmd) {
case CMD_END:
case CMD_EXIT:
case CMD_HELP:
case CMD_LIST:
case CMD_EXPORT:
return (B_TRUE);
}
/* scope-specific */
switch (current_scope) {
case NWAM_SCOPE_GBL:
switch (cmd) {
case CMD_CREATE:
case CMD_DESTROY:
case CMD_SELECT:
return (B_TRUE);
}
break;
case NWAM_SCOPE_LOC:
case NWAM_SCOPE_ENM:
case NWAM_SCOPE_WLAN:
case NWAM_SCOPE_NCU:
switch (cmd) {
case CMD_CANCEL:
case CMD_CLEAR:
case CMD_COMMIT:
case CMD_GET:
case CMD_REVERT:
case CMD_SET:
case CMD_VERIFY:
case CMD_WALKPROP:
return (B_TRUE);
}
break;
case NWAM_SCOPE_NCP:
switch (cmd) {
case CMD_CANCEL:
case CMD_CREATE:
case CMD_DESTROY:
case CMD_SELECT:
return (B_TRUE);
}
break;
default:
nerr("Invalid scope");
}
return (B_FALSE);
}
/* Returns the active object type depending on which handle is not NULL */
static nwam_object_type_t
{
/* Check ncu_h before ncp_h, ncp_h must be loaded before ncu_h */
return (NWAM_OBJECT_TYPE_NCU);
return (NWAM_OBJECT_TYPE_NCP);
return (NWAM_OBJECT_TYPE_LOC);
return (NWAM_OBJECT_TYPE_ENM);
return (NWAM_OBJECT_TYPE_KNOWN_WLAN);
else
return (NWAM_OBJECT_TYPE_UNKNOWN);
}
/* Retrive the name of the object from its handle */
static nwam_error_t
char **namep)
{
switch (object_type) {
case NWAM_OBJECT_TYPE_NCP:
case NWAM_OBJECT_TYPE_NCU:
case NWAM_OBJECT_TYPE_LOC:
case NWAM_OBJECT_TYPE_ENM:
}
return (NWAM_INVALID_ARG);
}
static void
{
const char *errprop;
if (!need_to_commit)
return;
switch (active_object_type()) {
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_ENM:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
break;
}
if (ret == NWAM_SUCCESS) {
if (interactive_mode)
} else {
/* Find property that caused failure */
switch (active_object_type()) {
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_ENM:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
break;
}
if (verr != NWAM_SUCCESS)
else
}
}
/*
* Saves the current configuration to persistent storage.
*/
/* ARGSUSED */
void
{
if (!need_to_commit) {
if (interactive_mode)
} else {
do_commit();
}
}
static void
{
switch (current_scope) {
case NWAM_SCOPE_NCU:
obj2_type = 0;
break;
case NWAM_SCOPE_NCP:
case NWAM_SCOPE_ENM:
case NWAM_SCOPE_WLAN:
case NWAM_SCOPE_LOC:
obj1_type = 0;
break;
case NWAM_SCOPE_GBL:
break;
default:
nerr("Invalid scope");
return;
}
}
/*
* End operation on current scope and go up one scope.
* Changes are not saved, no prompt either.
*/
/* ARGSUSED */
void
{
do_cancel();
}
/*
* Removes leading and trailing quotes from a string.
* Caller must free returned string.
*/
static char *
{
char *str;
int end;
/* export_func() and list_func() can pass NULL here */
if (quoted_str == NULL)
return (NULL);
/* remove leading quote */
if (quoted_str[0] == '"')
else
return (NULL);
/* remove trailing quote and newline */
end--;
return (str);
}
/*
* Creates a new resource and enters the scope of that resource.
* The new resource can also be a copy of an existing resource (-t option).
* If in interactive mode, then after creation call walkprop_func()
* to do walk the properties for the new object.
*/
void
{
int c;
/* make sure right command at the right scope */
if (current_scope == NWAM_SCOPE_GBL &&
nerr("cannot create ncu at global scope");
return;
}
if (current_scope == NWAM_SCOPE_NCP &&
nerr("Cannot create given object at this scope");
return;
}
optind = 0;
switch (c) {
case 't':
break;
default:
return;
}
}
if (!template) {
/* no template given */
/* argv[0] is name */
current_scope == NWAM_SCOPE_GBL) {
/* ncp must already be read */
nerr("Create error: NCP has not been read");
goto done;
}
}
if (ret != NWAM_SUCCESS) {
goto done;
}
} else {
/* template given */
/* argv[0] is -t, argv[1] is old name, argv[2] is new name */
if (ret != NWAM_SUCCESS)
goto read_error;
if (ret != NWAM_SUCCESS)
goto read_error;
if (ret != NWAM_SUCCESS)
goto read_error;
current_scope == NWAM_SCOPE_GBL) {
if (ret != NWAM_SUCCESS)
goto read_error;
/* ncp must already be read */
nerr("Copy error: NCP has not been read");
goto done;
}
&oldncu_h);
if (ret != NWAM_SUCCESS)
goto read_error;
}
if (ret != NWAM_SUCCESS) {
goto done;
}
}
if (current_scope == NWAM_SCOPE_GBL) {
} else {
}
if (current_scope != NWAM_SCOPE_NCP)
/* do a walk of the properties if in interactive mode */
"Walking properties ...\n"),
goto done;
}
if (ret != NWAM_SUCCESS)
done:
}
/* Processing of return value for destroy_*_callback() */
static int
{
if (ret == NWAM_ENTITY_NOT_DESTROYABLE) {
/* log a message to stderr, but don't consider it an error */
char *name;
== NWAM_SUCCESS) {
gettext("%s '%s' cannot be removed\n"),
}
return (0);
}
return (0);
return (1);
}
/*
* NWAM_FLAG_DO_NOT_FREE is passed to nwam_*_destory() so that it does not
* free the handle. The calling nwam_walk_*() function frees this handle
* as it is the function that created the handle.
*
* Objects that are not destroyable or are active cannot be destroyed.
* Don't return error in these situations so the walk can continue.
*/
/* ARGSUSED */
static int
{
/* The file is deleted, so NCUs are also removed */
}
/* ARGSUSED */
static int
{
}
/* ARGSUSED */
static int
{
}
/* ARGSUSED */
static int
{
}
/*
* Remove all existing configuration that are not read-only.
* walk through all ncps, locs, enms, wlans and destroy each one.
*/
static nwam_error_t
destroy_all(void)
{
if (ret != NWAM_SUCCESS)
goto done;
if (ret != NWAM_SUCCESS)
goto done;
if (ret != NWAM_SUCCESS)
goto done;
if (ret != NWAM_SUCCESS)
goto done;
if (interactive_mode)
done:
if (ret != NWAM_SUCCESS) {
"could not destroy all configurations");
}
return (ret);
}
/*
* Destroys an instance in persistent repository, and is permanent.
* If interactive mode, it is allowed at global scope only
* option -a destroys everything.
*/
void
{
if (current_scope == NWAM_SCOPE_NCP &&
nerr("Destroy error: only NCUs can be destroyed in NCP scope");
return;
}
/* res1_type is -1 if -a flag is used */
int c;
if (current_scope != NWAM_SCOPE_GBL) {
nerr("Cannot destroy all configurations in a "
"non-global scope");
return;
}
optind = 0;
switch (c) {
case 'a':
break;
default:
return;
}
}
if (remove_all_configurations) {
(void) destroy_all();
return;
}
}
/* argv[0] is name */
/* ncp must already be read */
nerr("Destroy ncu error: NCP has not been read");
return;
}
if (ret != NWAM_SUCCESS)
goto done;
&realname);
goto done;
&realname);
goto done;
&realname);
!= NWAM_SUCCESS)
goto done;
goto done;
&realname);
} else {
nerr("Destroy error: unknown object-type");
}
done:
if (ret == NWAM_ENTITY_IN_USE) {
nerr("Destroy error: active entity cannot be destroyed");
} else if (ret != NWAM_SUCCESS) {
} else if (interactive_mode) {
}
}
/*
* End operation on current scope and go up one scope.
* Changes are saved.
*/
/* ARGSUSED */
void
{
/* if need_to_commit is set, commit changes */
if (need_to_commit)
do_commit();
/*
* Call do_cancel() to go up one scope. If commit fails,
* need_to_commit is not reset and users are asked if they want to end.
*/
if (!need_to_commit ||
"Configuration not saved; really end")) == 1)) {
/* set time_to_exit if in global scope */
if (current_scope == NWAM_SCOPE_GBL)
/* call do_cancel() to go up one scope */
do_cancel();
}
}
/*
* Exit immediately. Configuration changes are saved by calling end_func().
*/
/* ARGSUSED */
void
{
if (need_to_commit) {
nerr("Exit error");
return;
}
}
/*
* If need_to_commit is still set, then the commit failed.
* Otherwise, exit.
*/
if (!need_to_commit)
}
void
{
int i;
return;
}
long_usage(i);
return;
}
}
help_wrap();
}
/*
* Revert configuration of an instance to latest previous version.
* Free the handle and read again.
*/
/* ARGSUSED */
void
{
switch (object_type) {
case NWAM_OBJECT_TYPE_NCU:
/* retrieve name and type to use later */
!= NWAM_SUCCESS) {
return;
}
goto name_error;
break;
case NWAM_OBJECT_TYPE_ENM:
goto name_error;
break;
case NWAM_OBJECT_TYPE_LOC:
goto name_error;
break;
!= NWAM_SUCCESS)
goto name_error;
break;
}
/* Exit this scope because handle already freed (call do_cancel()) */
if (ret != NWAM_SUCCESS) {
if (ret == NWAM_ENTITY_NOT_FOUND) {
nerr("%s '%s' does not exist to revert to, removing it",
} else {
}
do_cancel();
}
return;
if (ret != NWAM_SUCCESS)
}
/*
* Load a resource from persistent repository and enter the scope
* of that resource.
*/
void
{
nerr("cannot select '%s' at this scope",
return;
}
/* argv[0] is name */
switch (cmd->cmd_res1_type) {
case RT1_LOC:
if (ret == NWAM_SUCCESS) {
}
break;
case RT1_ENM:
if (ret == NWAM_SUCCESS) {
}
break;
case RT1_WLAN:
if (ret == NWAM_SUCCESS) {
(void) object_name_from_handle
}
break;
case RT1_NCP:
/* ncp must already be read */
nerr("Select error: NCP has not been read");
return;
}
if (ret == NWAM_SUCCESS) {
(void) object_name_from_handle
}
} else {
if (ret == NWAM_SUCCESS) {
(void) object_name_from_handle
}
}
break;
default:
nerr("Select error: unknown object-type");
return;
}
if (ret != NWAM_SUCCESS) {
} else {
/* set the obj*_name or obj*_type depending on current scope */
if (current_scope == NWAM_SCOPE_NCU) {
sizeof (obj2_name));
} else {
sizeof (obj1_name));
}
}
}
/* Given an int for prop, returns it as string */
static const char *
{
int i;
return (prop_table[i].pte_name);
}
return (NULL);
}
/* Given a prop as a string, returns it as an int */
static int
{
int i;
return (prop_table[i].pte_type);
}
return (-1);
}
/* Given a prop as an int, returns its type (nwam_value_type_t) */
static nwam_value_type_t
{
switch (object_type) {
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
case NWAM_OBJECT_TYPE_ENM:
break;
break;
}
if (ret != NWAM_SUCCESS)
return (value_type);
}
/*
* Converts input_str to an array nwam_value.
* If is_list_prop, break input_str into array of strings first.
*/
static nwam_value_t
{
int i, n = 0, ret;
char **val;
int max_str_num;
/*
* Worst case is that each char separated by DELIMITER, so the
* max number of sub strings is half of string length + 1.
*/
nerr("Out of memory");
return (NULL);
}
if (is_list_prop) {
/*
* Break down input_str and save as array of sub strings.
* Set num as the number of the sub strings.
* Use nwam_tokenize_by_unescaped_delim() rather than strtok()
* because DELIMITER may be escaped
*/
}
} else {
}
/* initialize int_vals or booleans_vals depending on pt_type */
if (value_type == NWAM_VALUE_TYPE_INT64) {
nerr("Out of memory");
return (NULL);
}
} else if (value_type == NWAM_VALUE_TYPE_UINT64) {
nerr("Out of memory");
return (NULL);
}
} else if (value_type == NWAM_VALUE_TYPE_BOOLEAN) {
if (boolean_vals == NULL) {
nerr("Out of memory");
return (NULL);
}
}
/* set the appropriate array */
for (i = 0; i < n; i++) {
switch (value_type) {
case NWAM_VALUE_TYPE_STRING:
/* nothing to do - val already has the char** array */
break;
case NWAM_VALUE_TYPE_INT64:
{
break;
}
case NWAM_VALUE_TYPE_UINT64:
{
char *endptr;
val[i], &str_as_enum);
/*
* Returns _SUCCESS if value for enum is valid.
* Returns _INVALID_ARG if property is not an enum.
*/
if (ret == NWAM_SUCCESS) {
uint_vals[i] = str_as_enum;
} else if (ret == NWAM_INVALID_ARG) {
/* verify conversion is valid */
return (NULL);
}
} else {
return (NULL);
}
break;
}
case NWAM_VALUE_TYPE_BOOLEAN:
break;
default:
return (NULL);
}
}
/* create nwam_value_t */
if (value_type == NWAM_VALUE_TYPE_STRING) {
} else if (value_type == NWAM_VALUE_TYPE_INT64) {
} else if (value_type == NWAM_VALUE_TYPE_UINT64) {
} else if (value_type == NWAM_VALUE_TYPE_BOOLEAN) {
}
if (ret != NWAM_SUCCESS) {
return (NULL);
}
return (data);
}
/*
* Displaying/Skipping of properties
* ---------------------------------
*
* This table shows if a specific property should be shown if some
* other property has a specific value. This table is used by
* show_prop_test(), which is called by set_func() and walkprop_func().
*
* An entry in the table looks like:
* { property1, property2, { val1, val2, -1 } }
* This is read as:
* "show property1 only if property2 has value val1 or val2"
*
* NB: If a property does not appear in this table, then that implies
* that the property is always shown.
*
* A property can have more than one rule. In such a case, the property is
* displayed only any of the rules is satisfied. This checking, however,
* is recursive. If a rule says that a property can be displayed, then the
* property that's checked should also satisfy its rules. In the above
* example, if property1 is to be displayed, then property2 should also
* satisfy its rules and be displayable. This recursion is necessary as
* properties that are not displayed (because rules are not satisfied) are
* not deleted.
*/
/* The most number of values in pde_checkvals below */
typedef struct prop_display_entry {
/* Rules for showing properties: commented for clarity */
/*
* Rules for NCUs
* NB: There is no need to have an entry if a property is for IP only.
* This is taken care of in libnwam_ncp.c
*/
/* show priority-{group,mode} if activation == prioritized */
{ NWAM_ACTIVATION_MODE_PRIORITIZED, -1 } },
{ NWAM_ACTIVATION_MODE_PRIORITIZED, -1 } },
/* show ipv4-addrsrc if ip-version == ipv4 */
{ IPV4_VERSION, -1 } },
/* show ipv4-addr if ipv4-addrsrc == static */
{ NWAM_ADDRSRC_STATIC, -1 } },
/* show ipv4-default-route if ip-version == ipv4 */
{ IPV4_VERSION, -1 } },
/* show ipv6-addrsrc if ip-version == ipv6 */
{ IPV6_VERSION, -1 } },
/* show ipv6-addr if ipv6-addrsrc == static */
{ NWAM_ADDRSRC_STATIC, -1 } },
/* show ipv6-default-route if ip-version == ipv6 */
{ IPV6_VERSION, -1 } },
};
/* Rules for ENMs */
/* show conditions if activation-mode == conditional-{all,any} */
NWAM_ACTIVATION_MODE_CONDITIONAL_ANY, -1 } },
};
/* Rules for LOCations */
/* show conditions if activation-mode == conditional-{all,any} */
NWAM_ACTIVATION_MODE_CONDITIONAL_ANY, -1 } },
/* show dns-nameservice-configsrc if nameservices == dns */
{ NWAM_NAMESERVICES_DNS, -1 } },
/* show other DNS options if dns-nameservices-configsrc == manual */
{ NWAM_CONFIGSRC_MANUAL, -1 } },
{ NWAM_CONFIGSRC_MANUAL, -1 } },
{ NWAM_CONFIGSRC_MANUAL, -1 } },
/* show nis-nameservice-configsrc if nameservices == nis */
{ NWAM_NAMESERVICES_NIS, -1 } },
/* show nis-nameservice-servers if nis-nameservice-configsrc = manual */
{ NWAM_CONFIGSRC_MANUAL, -1 } },
/* show ldap-nameservice-configsrc if nameservices == ldap */
{ NWAM_NAMESERVICES_LDAP, -1 } },
/* show ldap-nameservice-servers if ldap-nameservice-configsrc=manual */
{ NWAM_CONFIGSRC_MANUAL, -1 } },
/* show default-domain if {nis,ldap}-nameservice-configsrc == manual */
{ NWAM_CONFIGSRC_MANUAL, -1 } },
{ NWAM_CONFIGSRC_MANUAL, -1 } },
};
/* Rules for Known WLANs */
/* no rules for WLANs */
};
/* Returns the appropriate rules table for the given object type */
static prop_display_entry_t *
{
switch (object_type) {
case NWAM_OBJECT_TYPE_NCU:
return (ncu_prop_display_entry_table);
case NWAM_OBJECT_TYPE_LOC:
return (loc_prop_display_entry_table);
case NWAM_OBJECT_TYPE_ENM:
return (enm_prop_display_entry_table);
return (wlan_prop_display_entry_table);
}
return (NULL);
}
/*
* Tests whether prop must be shown during a walk depending on the
* value of a different property.
*
* This function is also used by set_func() to determine whether the
* property being set should be allowed or not. If the property
* would not be displayed in a walk, then it should not be set.
*
* The checked_props and num_checked arguments are used to avoid circular
* dependencies between properties. When this function recursively calls
* itself, it adds the property that it just checked to the checked_props
* list.
*/
static boolean_t
{
int i, j, k;
/*
* Check if this property has already been checked previously in
* the recursion. If so, return B_FALSE so that the initial prop
* is not displayed.
*/
for (i = 0; i < num_checked; i++) {
return (B_FALSE);
}
}
continue;
prop_found = B_TRUE;
/* get the value(s) of the (other) property to check */
switch (object_type) {
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
case NWAM_OBJECT_TYPE_ENM:
break;
return (B_TRUE);
}
if (ret != NWAM_SUCCESS)
continue;
/* prop_val may contain a uint64 array or a boolean */
continue;
if (prop_type == NWAM_VALUE_TYPE_UINT64) {
&numvals) != NWAM_SUCCESS) {
continue;
}
/* for each value in uvals, check each value in table */
for (j = 0; j < numvals; j++) {
for (k = 0; check_uvals[k] != -1; k++) {
/* show if uvals[j] matches */
if (prop_uvals[j] ==
(uint64_t)check_uvals[k]) {
goto next_rule;
}
}
}
} else if (prop_type == NWAM_VALUE_TYPE_BOOLEAN) {
NWAM_SUCCESS) {
continue;
}
for (k = 0;
k++) {
/* show if bval matches */
display_list[i].pde_checkvals[k]) {
goto next_rule;
}
}
}
/*
* If show_prop is set, then a rule is satisfied; no need to
* check other rules for this prop. However, recursively
* check if the checked prop (pde_checkname) satisfies its
* rules. Also, update the check_props array with this prop.
*/
if (show_prop) {
++num_checked * sizeof (char *));
return (B_FALSE);
}
return (show_prop_test(object_type,
}
}
/*
* If we are here and prop_found is set, it means that no rules were
* satisfied by prop; return B_FALSE. If prop_found is not set, then
* prop did not have a rule so it must be displayed; return B_TRUE.
*/
if (prop_found)
return (B_FALSE);
else
return (B_TRUE);
}
/*
* Returns true if the given property is read-only and cannot be modified.
*/
static boolean_t
{
switch (object_type) {
case NWAM_OBJECT_TYPE_NCU:
return (B_TRUE);
break;
case NWAM_OBJECT_TYPE_ENM:
return (B_TRUE);
break;
case NWAM_OBJECT_TYPE_LOC:
return (B_TRUE);
break;
/* no read-only properties for WLANs */
return (B_FALSE);
}
return (B_FALSE);
}
/* Returns true if the property is multi-valued */
static boolean_t
{
switch (object_type) {
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
case NWAM_OBJECT_TYPE_ENM:
break;
break;
}
if (ret != NWAM_SUCCESS)
return (multi);
}
/*
* Prints out error message specific to property that could not be set.
* Property description is used to help guide user in entering correct value.
*/
static void
{
const char *description;
if (err == NWAM_SUCCESS)
return;
if (err != NWAM_ENTITY_INVALID_VALUE) {
return;
}
switch (active_object_type()) {
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
case NWAM_OBJECT_TYPE_ENM:
break;
&description);
break;
}
}
/*
* Sets the property value.
* Read-only properties and objects cannot be set.
* "read-only" is a special in that it can be set on a read-only object.
* The object has to be committed before other properties can be set.
* Also uses show_prop_test() to test if the property being set would
* be skipped during a walk (as determined by the value of some other
* property). If so, then it cannot be set.
*/
void
{
const char *prop;
/* argv[0] is property value */
nerr("Set error: invalid %s property: '%s'",
return;
}
/* check if property can be set */
return;
}
if (interactive_mode) {
"has no effect\n"), prop);
}
}
if (prop_value == NULL) {
return;
}
/* set the property value */
switch (object_type) {
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
case NWAM_OBJECT_TYPE_ENM:
break;
break;
}
/* delete other properties if needed */
if (ret == NWAM_SUCCESS)
else
}
static int
{
char *name;
if (*list_msgp) {
}
if (ret != NWAM_SUCCESS) {
return (1);
}
/* If NCU, get its class and print */
if (object_type == NWAM_OBJECT_TYPE_NCU) {
!= NWAM_SUCCESS) {
return (1);
} else {
(void) printf("\t%s",
}
}
return (0);
}
/* Print out name, type and status */
static int
{
}
static int
{
}
static int
{
}
static int
{
}
static int
{
}
/* functions to convert a value to a string */
/* ARGSUSED */
static const char *
{
return (str);
}
/* ARGSUSED */
static const char *
{
/* quoted strings */
return (qstr);
}
/* ARGSUSED */
static const char *
{
return (instr);
}
static const char *
{
/* returns NWAM_SUCCESS if prop is enum with string in uintstr */
(const char **)&uintstr) != NWAM_SUCCESS) {
}
return (uintstr);
}
/* ARGSUSED */
static const char *
{
return (boolstr);
}
/*
* Print the value (enums are converted to string), use DELIMITER for
* array. If strings are to be "quoted", pass B_TRUE for quoted_strings.
*/
static void
{
/* arrays for values retrieved according to the type of value */
char **svals;
/* pointer to function to generate string representation of value */
const char *(*tostr)(void *, const char *, char *);
int i;
nerr("Get value type error");
return;
}
if (value_type == NWAM_VALUE_TYPE_STRING) {
NWAM_SUCCESS) {
nerr("Get string array error");
return;
}
} else if (value_type == NWAM_VALUE_TYPE_INT64) {
NWAM_SUCCESS) {
nerr("Get int64 array error");
return;
}
} else if (value_type == NWAM_VALUE_TYPE_UINT64) {
NWAM_SUCCESS) {
nerr("Get uint64 array error");
return;
}
} else if (value_type == NWAM_VALUE_TYPE_BOOLEAN) {
NWAM_SUCCESS) {
nerr("Get boolean array error");
return;
}
}
/* now, loop and print each value */
for (i = 0; i < num; i++) {
void *val;
/* get the pointer to the ith value to pass to func() */
if (value_type == NWAM_VALUE_TYPE_STRING)
else if (value_type == NWAM_VALUE_TYPE_UINT64)
else if (value_type == NWAM_VALUE_TYPE_INT64)
else if (value_type == NWAM_VALUE_TYPE_BOOLEAN)
}
}
static int
int width)
{
else
return (0);
}
static int
{
}
/* For locations because of longer property names */
static int
{
}
/*
* all_props specifies whether properties that have not been set should be
* printed or not. ncp and ncu_type are used only when the object_type is
* NCU.
*/
static nwam_error_t
{
int i;
/*
* handle is NULL if called from a scope higher than the object's
* scope, but name must be given; so get the handle.
*/
switch (object_type) {
case NWAM_OBJECT_TYPE_NCP:
goto readfail;
break;
case NWAM_OBJECT_TYPE_NCU:
(nwam_ncu_handle_t *)&handle);
if (ret == NWAM_ENTITY_MULTIPLE_VALUES) {
/*
* Multiple NCUs with the given name exists.
* Call listprop() for each NCU type.
*/
!= NWAM_SUCCESS)
goto done;
goto done;
} else if (ret != NWAM_SUCCESS) {
goto readfail;
}
break;
case NWAM_OBJECT_TYPE_LOC:
goto readfail;
break;
case NWAM_OBJECT_TYPE_ENM:
goto readfail;
break;
!= NWAM_SUCCESS)
goto readfail;
break;
}
}
!= NWAM_SUCCESS)
goto done;
/* get the property list */
switch (object_type) {
case NWAM_OBJECT_TYPE_NCP:
{
/* walk NCUs */
goto done;
}
case NWAM_OBJECT_TYPE_NCU:
{
!= NWAM_SUCCESS)
goto done;
!= NWAM_SUCCESS)
goto done;
&prop_num);
break;
}
case NWAM_OBJECT_TYPE_LOC:
break;
case NWAM_OBJECT_TYPE_ENM:
break;
break;
}
if (ret != NWAM_SUCCESS)
goto done;
/* print object type and name */
realname);
/* Loop through the properties and print */
for (i = 0; i < prop_num; i++) {
/* get the existing value for this property */
switch (object_type) {
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
case NWAM_OBJECT_TYPE_ENM:
break;
&vals);
break;
}
if (ret != NWAM_SUCCESS) {
/* _ENTITY_NOT_FOUND is ok if listing for all props */
if (!all_props)
continue;
else if (ret != NWAM_ENTITY_NOT_FOUND)
continue;
}
/* print property and value */
if (object_type == NWAM_OBJECT_TYPE_LOC)
else
}
done:
if (lhandle) {
switch (object_type) {
case NWAM_OBJECT_TYPE_NCP:
break;
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
case NWAM_OBJECT_TYPE_ENM:
break;
break;
}
}
/* don't treat _ENTITY_NOT_FOUND as an error */
if (ret == NWAM_ENTITY_NOT_FOUND)
ret = NWAM_SUCCESS;
return (ret);
/* When nwam_*_read() fails */
return (ret);
}
/*
* List profiles or property and its values.
* If the -a option is specified, all properties are listed.
*/
void
{
/* whether all properties should be listed, given by the -a option */
/*
* list_props says whether the properties should be listed.
* Note that, here NCUs are treated as properties of NCPs.
*/
/* determine which properties to list, also validity tests */
if (current_scope == NWAM_SCOPE_GBL) {
/* res1_type is -1 if only "list -a" is used */
nerr("'list' requires an object to be specified with "
"the -a option in the global scope");
return;
}
list_props = B_TRUE;
list_props = B_TRUE;
list_props = B_TRUE;
list_props = B_TRUE;
} else {
}
}
if ((current_scope == NWAM_SCOPE_LOC ||
current_scope == NWAM_SCOPE_ENM ||
current_scope == NWAM_SCOPE_WLAN ||
current_scope == NWAM_SCOPE_NCU) &&
nerr("Additional options are not allowed with the -a option "
"at this scope");
return;
}
if (current_scope == NWAM_SCOPE_LOC) {
list_props = B_TRUE;
}
if (current_scope == NWAM_SCOPE_ENM) {
list_props = B_TRUE;
}
if (current_scope == NWAM_SCOPE_WLAN) {
list_props = B_TRUE;
}
if (current_scope == NWAM_SCOPE_NCP) {
nerr("only ncu can be listed at this scope");
return;
}
list_props = B_TRUE;
} else {
list_props = B_TRUE;
}
}
if (current_scope == NWAM_SCOPE_NCU) {
list_props = B_TRUE;
}
/* Check if the -a option is specified to list all properties */
char **argv;
optind = 0;
/* if res1_type is -1, option is in argv[0], else in argv[1] */
else
switch (c) {
case 'a':
break;
default:
return;
}
}
}
/*
* name, if requested, is in argv[0].
*/
if (list_ncp) {
if (list_props) {
} else {
NULL);
}
if (ret != NWAM_SUCCESS)
goto done;
}
if (list_ncu) {
nerr("NCP has not been read");
return;
}
if (list_props) {
/* determine the NCU type first */
} else {
&ncu_type)) != NWAM_SUCCESS)
goto done;
}
if (ret != NWAM_SUCCESS)
goto done;
}
}
if (list_loc) {
if (list_props) {
} else {
}
if (ret != NWAM_SUCCESS)
goto done;
}
if (list_enm) {
if (list_props) {
} else {
}
if (ret != NWAM_SUCCESS)
goto done;
}
if (list_wlan) {
if (list_props) {
} else {
NULL);
}
if (ret != NWAM_SUCCESS)
goto done;
}
done:
if (ret != NWAM_SUCCESS)
}
static int
{
/* exclude read-only properties */
return (0);
return (0);
}
static int
{
char *name;
const char **props;
int i;
/* get the NCU's type and class */
return (ret);
return (ret);
return (ret);
/*
* Because of dependencies between properties, they have to be
* exported in the same order as when they are walked.
*/
!= NWAM_SUCCESS)
return (ret);
for (i = 0; i < num; i++) {
if (ret == NWAM_SUCCESS) {
}
}
return (0);
}
static int
{
char *name;
return (ret);
/* Do not export "automatic" NCP */
if (NWAM_NCP_AUTOMATIC(name)) {
return (0);
}
/* now walk NCUs for this ncp */
if (ret != NWAM_SUCCESS) {
return (ret);
}
return (0);
}
static int
{
char *name;
const char **props;
int i;
return (ret);
/*
* Because of dependencies between properties, they have to be
* exported in the same order as when they are walked.
*/
return (ret);
for (i = 0; i < num; i++) {
if (ret == NWAM_SUCCESS) {
}
}
return (0);
}
static int
{
char *name;
const char **props;
int i;
return (ret);
/* Do not export Automatic, NoNet or Legacy locations */
if (NWAM_LOC_NAME_PRE_DEFINED(name)) {
return (0);
}
/*
* Because of dependencies between properties, they have to be
* exported in the same order as when they are walked.
*/
return (ret);
for (i = 0; i < num; i++) {
if (ret == NWAM_SUCCESS) {
}
}
return (0);
}
static int
{
char *name;
const char **props;
int i;
return (ret);
/*
* Because of dependencies between properties, they have to be
* exported in the same order as when they are walked.
*/
!= NWAM_SUCCESS)
return (ret);
for (i = 0; i < num; i++) {
if (ret == NWAM_SUCCESS) {
}
}
return (0);
}
/*
* Writes configuration to screen or file (with -f option).
* Writes a "destroy -a" if option -d is given.
*/
void
{
int c;
/* what to export */
/* check for -d and -f flags */
filepath[0] = '\0';
optind = 0;
switch (c) {
case 'f':
break;
case 'd':
break;
default:
return;
}
}
/* determine where to export */
if (!write_to_file) {
} else {
/*
* If -d was specified with -f, then argv[2] is filename,
* otherwise, argv[1] is filename.
*/
sizeof (filepath));
goto done;
}
}
if (add_destroy) {
/* only possible in global scope */
if (current_scope == NWAM_SCOPE_GBL) {
} else {
nerr("Option -d is not allowed in non-global scope");
goto done;
}
}
/* In the following scopes, only the -f argument is valid */
if (((current_scope == NWAM_SCOPE_LOC ||
current_scope == NWAM_SCOPE_ENM ||
current_scope == NWAM_SCOPE_WLAN ||
current_scope == NWAM_SCOPE_NCU) &&
nerr("'export' does not take arguments at this scope");
goto done;
}
if (current_scope == NWAM_SCOPE_NCP) {
nerr("only ncu can be exported at this scope");
goto done;
}
}
/*
* Determine what objects to export depending on scope and command
* arguments. If -f is specified, then the object name is argv[2].
* Otherwise, argv[0] is name, unless exporting all in global
* scope in which case name is set back to NULL.
*/
switch (current_scope) {
case NWAM_SCOPE_GBL:
switch (cmd->cmd_res1_type) {
case RT1_LOC:
export_loc = B_TRUE;
break;
case RT1_ENM:
export_enm = B_TRUE;
break;
case RT1_WLAN:
break;
case RT1_NCP:
export_ncp = B_TRUE;
nerr("cannot export ncu at from global scope");
goto done;
}
break;
default:
/* export everything */
export_loc = B_TRUE;
export_enm = B_TRUE;
break;
}
break;
case NWAM_SCOPE_LOC:
export_loc = B_TRUE;
if (ret != NWAM_SUCCESS)
goto fail;
break;
case NWAM_SCOPE_ENM:
export_enm = B_TRUE;
if (ret != NWAM_SUCCESS)
goto fail;
break;
case NWAM_SCOPE_WLAN:
if (ret != NWAM_SUCCESS)
goto fail;
break;
case NWAM_SCOPE_NCP:
export_ncu = B_TRUE;
} else {
export_ncp = B_TRUE;
if (ret != NWAM_SUCCESS)
goto fail;
}
break;
case NWAM_SCOPE_NCU:
export_ncu = B_TRUE;
if (ret != NWAM_SUCCESS)
goto fail;
break;
default:
nerr("Invalid scope");
goto done;
}
/* Now, export objects according to the flags set */
if (export_ncp) {
/* export all NCPs */
} else if (NWAM_NCP_AUTOMATIC(name)) {
goto fail;
} else {
if (ret != NWAM_SUCCESS)
goto fail;
}
/* will export NCUs also */
if (lhandle) {
}
}
if (ret != NWAM_SUCCESS)
goto fail;
}
if (export_ncu) {
/* export all NCUs */
} else {
/* no NCU handle -> called from NCP scope */
if (ret == NWAM_SUCCESS) {
/* one NCU with given name */
} else if (ret == NWAM_ENTITY_MULTIPLE_VALUES) {
/* multiple NCUs with given name */
NWAM_NCU_TYPE_LINK, 0, &ncu_h);
if (ret != NWAM_SUCCESS)
goto fail;
NWAM_NCU_TYPE_INTERFACE, 0, &ncu_h);
if (ret != NWAM_SUCCESS)
goto fail;
} else {
goto fail;
}
} else {
/* NCU handle exists */
}
}
if (ret != NWAM_SUCCESS)
goto fail;
}
if (export_loc) {
/* export all locations */
} else if (NWAM_LOC_NAME_PRE_DEFINED(name)) {
goto fail;
} else {
if (ret != NWAM_SUCCESS)
goto fail;
}
if (lhandle) {
}
}
if (ret != NWAM_SUCCESS)
goto fail;
}
if (export_enm) {
/* export all ENMs */
} else {
if (ret != NWAM_SUCCESS)
goto fail;
}
if (lhandle) {
}
}
if (ret != NWAM_SUCCESS)
goto fail;
}
if (export_wlan) {
/* export all WLANs */
} else {
&wlan_h);
if (ret != NWAM_SUCCESS)
goto fail;
}
if (lhandle) {
}
}
if (ret != NWAM_SUCCESS)
goto fail;
}
fail:
if (ret != NWAM_SUCCESS)
done:
if (need_to_close)
}
/*
* Get property value. If the -V option is specified, only the value is
* printed without the property name.
*/
void
{
const char *prop;
/* check if option is -V to print value only */
int c;
optind = 0;
switch (c) {
case 'V':
value_only = B_TRUE;
break;
default:
return;
}
}
}
/* property to get is in cmd->cmd_prop_type */
nerr("Get error: invalid %s property: '%s'",
return;
}
switch (object_type) {
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
case NWAM_OBJECT_TYPE_ENM:
break;
break;
}
if (ret != NWAM_SUCCESS) {
if (ret == NWAM_ENTITY_NOT_FOUND)
else
return;
}
if (value_only) {
(void) printf("\n");
} else {
}
}
/*
* Clears value of a property.
* Read-only properties cannot be cleared.
* If clearing a property invalidates the object, then that property
* cannot be cleared.
*/
void
{
const char *prop;
/* property to clear is in cmd->cmd_prop_type */
nerr("Clear error: invalid %s property: '%s'",
return;
}
return;
}
switch (object_type) {
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
case NWAM_OBJECT_TYPE_ENM:
break;
break;
}
if (ret != NWAM_SUCCESS) {
nerr("Clear error: property '%s' has not been set",
prop);
} else {
}
return;
}
}
/*
* Prints all the choices available for an enum property [c1|c2|c3].
* Prints [true|false] for a boolean property.
*/
static void
{
uint64_t i = 0;
const char *str;
/* Special case: print object-specific options for activation-mode */
/* "manual" for all objects */
(void) printf(" [%s|",
if (object_type == NWAM_OBJECT_TYPE_NCU) {
(void) printf("%s]",
} else {
(void) printf("%s|%s]",
}
return;
}
/* Special case: only "manual" configsrc is allowed for LDAP */
(void) printf(" [%s]",
return;
}
switch (value_type) {
case NWAM_VALUE_TYPE_UINT64:
/* uint64 may be an enum, will print nothing if not an enum */
/* No string representation for i, continue. */
if (ret == NWAM_ENTITY_INVALID_VALUE)
continue;
if (!choices)
}
if (choices)
(void) putchar(']');
break;
case NWAM_VALUE_TYPE_BOOLEAN:
break;
case NWAM_VALUE_TYPE_STRING:
break;
}
}
/*
* Walk through object properties.
* For newly-created object, the property name with no value is displayed, and
* the user can input a value for each property.
* For existing object, the current value is displayed and user input overwrites
* the existing one. If no input is given, the existing value remains.
* Read-only properties are not displayed.
* Read-only objects cannot be walked.
* If the -a option is specified, no properties are skipped.
*/
void
{
int i;
const char **props;
if (!interactive_mode) {
nerr("'walkprop' is only allowed in interactive mode");
return;
}
/* check if option -a is specified to show all properties */
int c;
optind = 0;
switch (c) {
case 'a':
break;
default:
return;
}
}
}
/* read-only objects cannot be walked */
/* must be in NCU scope, NCP scope doesn't get here */
}
if (read_only) {
nerr("'walkprop' cannot be used in read-only objects");
return;
}
/* get the current object type and the prop_display_table */
/* get the property list depending on the object type */
switch (object_type) {
case NWAM_OBJECT_TYPE_NCU:
{
!= NWAM_SUCCESS)
break;
!= NWAM_SUCCESS)
break;
&prop_num);
break;
}
case NWAM_OBJECT_TYPE_LOC:
break;
case NWAM_OBJECT_TYPE_ENM:
break;
break;
}
if (ret != NWAM_SUCCESS) {
return;
}
/* Loop through the properties */
if (all_props)
for (i = 0; i < prop_num; i++) {
/* check if this property should be displayed */
continue;
if (!all_props &&
checked, 0))
continue;
/* get the existing value for this property */
switch (object_type) {
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
case NWAM_OBJECT_TYPE_ENM:
break;
&vals);
break;
}
/* returns NWAM_ENTITY_NOT_FOUND if no existing value */
continue;
/* print property */
/* print the existing value(s) if they exist */
if (ret == NWAM_SUCCESS) {
(void) printf(" (");
(void) putchar(')');
}
/* print choices, won't print anything if there aren't any */
(void) printf("> ");
/* wait for user input */
continue;
/* if user input new value, existing value is overrode */
if (line[0] != '\n') {
props[i]);
goto repeat;
}
/* set the new value for the property */
switch (object_type) {
case NWAM_OBJECT_TYPE_NCU:
vals);
break;
case NWAM_OBJECT_TYPE_LOC:
vals);
break;
case NWAM_OBJECT_TYPE_ENM:
vals);
break;
break;
}
if (ret != NWAM_SUCCESS)
goto repeat;
continue;
i--; /* decrement i to repeat */
}
}
}
/*
* Verify whether all properties of a resource are valid.
*/
/* ARGSUSED */
void
{
const char *errprop;
switch (active_object_type()) {
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
case NWAM_OBJECT_TYPE_ENM:
break;
break;
}
if (ret != NWAM_SUCCESS)
else if (interactive_mode)
}
/*
* command-line mode (# nwamcfg list or # nwamcfg "select loc test; list")
*/
static int
{
char *command;
int i, err;
for (i = 0; i < argc; i++)
nerr("Out of memory");
return (NWAM_ERR);
}
for (i = 1; i < argc; i++) {
}
return (err);
yyparse();
/*
* If any command on a list of commands give an error,
* don't continue with the remaining commands.
*/
if (saw_error || time_to_exit)
return (cleanup());
}
/* if there are changes to commit, commit it */
if (need_to_commit) {
do_commit();
/* if need_to_commit is not set, then there was a error */
if (need_to_commit)
return (NWAM_ERR);
}
if (!interactive_mode)
return (cleanup());
else {
return (read_input());
}
}
/*
* cmd_file is slightly more complicated, as it has to open the command file
* and set yyin appropriately. Once that is done, though, it just calls
* read_input(), and only once, since prompting is not possible.
*/
static int
{
int err;
if (using_real_file) {
/*
* nerr() prints a line number in cmd_file_mode, which we do
* not want here, so temporarily unset it.
*/
return (1);
}
err = 1;
goto done;
}
err = 1;
goto done;
}
/*
* If -d was passed on the command-line, we need to
* start by removing any existing configuration.
* Alternatively, the file may begin with 'destroy -a';
* but in that case, the line will go through the lexer
* and be processed as it's encountered in the file.
*/
goto done;
/* set up for lexer */
} else {
/*
* "-f -" is essentially the same as interactive mode,
* so treat it that way.
*/
}
/* NWAM_REPEAT is for interactive mode; treat it like NWAM_ERR here. */
done:
if (using_real_file)
return (err);
}
int
{
int err;
char c;
/* This must be before anything goes to stdout. */
else
execname++;
(void) textdomain(TEXT_DOMAIN);
switch (c) {
case 'f':
break;
case '?':
case 'h':
return (NWAM_OK);
case 'd':
break;
default:
return (NWAM_ERR);
}
}
/* -d can only be used with -f */
if (remove_all_configurations && !cmd_file_mode) {
nerr("Option -d can only be used with -f");
return (NWAM_ERR);
}
/*
* This may get set back to FALSE again in cmd_file() if cmd_file_name
* is a "real" file as opposed to "-" (i.e. meaning use stdin).
*/
if (isatty(STDIN_FILENO))
/* interactive or command-file mode */
if (!cmd_file_mode)
err = do_interactive();
else
} else {
/* command-line mode */
}
(void) del_GetLine(gl);
return (err);
}