diff options
| author | Michael Biebl <biebl@debian.org> | 2016-08-26 02:18:32 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2016-08-26 02:18:32 +0200 |
| commit | 7514efc2f38c9ace4557d4e69d68e7d380389030 (patch) | |
| tree | 7fb00fda86cfcc2ca377f191633a7cfdbfea7ca3 /clients/cli/common.c | |
| parent | d6201f5d8daada3d64a0a3e0038e14eebec683ce (diff) | |
Imported Upstream version 1.4.0 upstream/1.4.0
Diffstat (limited to 'clients/cli/common.c')
| -rw-r--r-- | clients/cli/common.c | 167 |
1 files changed, 151 insertions, 16 deletions
diff --git a/clients/cli/common.c b/clients/cli/common.c index 05b76564..f1ec46a1 100644 --- a/clients/cli/common.c +++ b/clients/cli/common.c @@ -872,6 +872,7 @@ nmc_team_check_config (const char *config, char **out_config, GError **error) * @filter_val: connection to find (connection name, UUID or path) * @start: where to start in @list. The location is updated so that the function * can be called multiple times (for connections with the same name). + * @complete: print possible completions * * Find a connection in @list according to @filter_val. @filter_type determines * what property is used for comparison. When @filter_type is NULL, compare @@ -885,7 +886,8 @@ NMConnection * nmc_find_connection (const GPtrArray *connections, const char *filter_type, const char *filter_val, - int *start) + int *start, + gboolean complete) { NMConnection *connection; NMConnection *found = NULL; @@ -907,20 +909,36 @@ nmc_find_connection (const GPtrArray *connections, * type. If 'path' filter type is specified, comparison against * numeric index (in addition to the whole path) is allowed. */ - if ( ( (!filter_type || strcmp (filter_type, "id") == 0) - && strcmp (filter_val, id) == 0) - || ( (!filter_type || strcmp (filter_type, "uuid") == 0) - && strcmp (filter_val, uuid) == 0) - || ( (!filter_type || strcmp (filter_type, "path") == 0) - && (g_strcmp0 (filter_val, path) == 0 || (filter_type && g_strcmp0 (filter_val, path_num) == 0)))) { - if (!start) - return connection; - if (found) { - *start = i; - return found; - } - found = connection; + if (!filter_type || strcmp (filter_type, "id") == 0) { + if (complete) + nmc_complete_strings (filter_val, id, NULL); + if (strcmp (filter_val, id) == 0) + goto found; + } + + if (!filter_type || strcmp (filter_type, "uuid") == 0) { + if (complete && (filter_type || *filter_val)) + nmc_complete_strings (filter_val, uuid, NULL); + if (strcmp (filter_val, uuid) == 0) + goto found; + } + + if (!filter_type || strcmp (filter_type, "path") == 0) { + if (complete && (filter_type || *filter_val)) + nmc_complete_strings (filter_val, path, filter_type ? path_num : NULL, NULL); + if (g_strcmp0 (filter_val, path) == 0 || (filter_type && g_strcmp0 (filter_val, path_num) == 0)) + goto found; + } + + continue; +found: + if (!start) + return connection; + if (found) { + *start = i; + return found; } + found = connection; } if (start) @@ -1041,7 +1059,8 @@ get_secrets_from_user (const char *request_id, } } g_print ("%s\n", msg); - pwd = nmc_readline_echo (echo_on, "%s (%s): ", secret->name, secret->prop_name); + pwd = nmc_readline_echo (secret->password ? echo_on : TRUE, + "%s (%s): ", secret->name, secret->prop_name); if (!pwd) pwd = g_strdup (""); } else { @@ -1096,7 +1115,7 @@ nmc_secrets_requested (NMSecretAgentSimple *agent, p = strrchr (path, '/'); if (p) *p = '\0'; - connection = nmc_find_connection (nmc->connections, "path", path, NULL); + connection = nmc_find_connection (nmc->connections, "path", path, NULL, FALSE); g_free (path); } @@ -1393,3 +1412,119 @@ nmc_parse_lldp_capabilities (guint value) return g_string_free (str, FALSE); } + +/** + * nmc_do_cmd: + * @nmc: Client instance + * @cmds: Command table + * @cmd: Command + * @argc: Argument count + * @argv: Arguments vector + * + * Picks the right callback to handle command from the command table. + * If --help argument follows and the usage callback is specified for the command + * it calls the usage callback. + * + * The command table is terminated with a %NULL command. The terminating + * entry's handlers are called if the command is empty. + * + * Returns: a nmcli return code + */ +NMCResultCode +nmc_do_cmd (NmCli *nmc, const NMCCommand cmds[], const char *cmd, int argc, char **argv) +{ + const NMCCommand *c; + + if (argc == 0 && nmc->complete) + return nmc->return_value; + + if (argc == 1 && nmc->complete) { + for (c = cmds; c->cmd; ++c) { + if (!*cmd || matches (cmd, c->cmd) == 0) + g_print ("%s\n", c->cmd); + } + return nmc->return_value; + } + + for (c = cmds; c->cmd; ++c) { + if (cmd && matches (cmd, c->cmd) == 0) + break; + } + + if (c->cmd) { + /* A valid command was specified. */ + if (c->usage && nmc_arg_is_help (*(argv+1))) + c->usage (); + else + nmc->return_value = c->func (nmc, argc-1, argv+1); + } else if (cmd) { + /* Not a known command. */ + if (nmc_arg_is_help (cmd) && c->usage) { + c->usage (); + } else { + g_string_printf (nmc->return_text, _("Error: argument '%s' not understood. Try passing --help instead."), cmd); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + } + } else if (c->func) { + /* No command, run the default handler. */ + nmc->return_value = c->func (nmc, argc, argv); + } else { + /* No command and no default handler. */ + g_string_printf (nmc->return_text, _("Error: missing argument. Try passing --help.")); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + } + + return nmc->return_value; +} + +/** + * nmc_complete_strings: + * @prefix: a string to match + * @...: a %NULL-terminated list of candidate strings + * + * Prints all the matching candidates for completion. Useful when there's + * no better way to suggest completion other than a hardcoded string list. + */ +void +nmc_complete_strings (const char *prefix, ...) +{ + va_list args; + const char *candidate; + + va_start (args, prefix); + while ((candidate = va_arg (args, const char *))) { + if (!*prefix || matches (prefix, candidate) == 0) + g_print ("%s\n", candidate); + } + va_end (args); +} + +/** + * nmc_complete_bool: + * @prefix: a string to match + * @...: a %NULL-terminated list of candidate strings + * + * Prints all the matching possible boolean values for completion. + */ +void +nmc_complete_bool (const char *prefix) +{ + nmc_complete_strings (prefix, "true", "yes", "on", + "false", "no", "off", NULL); +} + +/** + * nmc_error_get_simple_message: + * @error: a GError + * + * Returns a simplified message for some errors hard to understand. + */ +const char * +nmc_error_get_simple_message (GError *error) +{ + /* Return a clear message instead of the obscure D-Bus policy error */ + if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED)) + return _("access denied"); + else + return error->message; +} |