diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2014-10-04 17:07:42 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2014-10-23 18:34:39 +0200 |
commit | 1c9b16b2f2b6d3e925155d058134efc620766f0e (patch) | |
tree | 9531850bbaa17af765fd84299dbe30c143e77a31 | |
parent | 3a6c618a4a9459462115740652bffcfd62f98011 (diff) | |
download | NetworkManager-1c9b16b2f2b6d3e925155d058134efc620766f0e.tar.gz |
cli: Add mode option for wifi connecitons
Only default (infrastructure) mode connections can be created and as it's not
possible to write mode=ap connections with ifcfg-rh plugins, they can't be
switched to mode=ap.
-rw-r--r-- | clients/cli/connections.c | 123 | ||||
-rw-r--r-- | clients/cli/nmcli-completion | 11 | ||||
-rw-r--r-- | clients/cli/utils.c | 25 | ||||
-rw-r--r-- | clients/cli/utils.h | 3 | ||||
-rw-r--r-- | man/nmcli.1.in | 2 |
5 files changed, 140 insertions, 24 deletions
diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 5c239563bf..7e7a8121e5 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -336,7 +336,8 @@ usage_connection_add (void) " wifi: ssid <SSID>\n" " [mac <MAC address>]\n" " [cloned-mac <cloned MAC address>]\n" - " [mtu <MTU>]\n\n" + " [mtu <MTU>]\n" + " [mode infrastructure|ap|adhoc]\n\n" " wimax: [mac <MAC address>]\n" " [nsp <NSP>]\n\n" " pppoe: username <PPPoE username>\n" @@ -2565,29 +2566,66 @@ check_infiniband_p_key (const char *p_key, guint32 *p_key_int, GError **error) return TRUE; } -/* Checks InfiniBand mode. - * It accepts shortcuts and normalizes them ('mode' argument is modified on success). +/** + * check_valid_enumeration: + * @str: string to check against string array @strings + * @strings: string array to check @str againt + * @what: what parameter @str belongs to (used in error message) + * @what_desc: longer description of @what parameter (used in error message) + * @error: location to store an error, or %NULL + * + * Check whether @str is one of the string of @strings array. It accepts + * shortcuts and normalizes them (@str argument is modified on success). + * + * Returns: %TRUE on success, %FALSE on failure */ static gboolean -check_infiniband_mode (char **mode, GError **error) +check_valid_enumeration (char **str, + const char *strings[], + const char *what, + const char *what_desc, + GError **error) { char *tmp; - const char *checked_mode; - const char *modes[] = { "datagram", "connected", NULL }; + const char *checked_str; - if (!mode || !*mode) + if (!str || !*str) return TRUE; - tmp = g_strstrip (g_strdup (*mode)); - checked_mode = nmc_string_is_valid (tmp, modes, NULL); + tmp = g_strstrip (g_strdup (*str)); + checked_str = nmc_string_is_valid (tmp, strings, NULL); g_free (tmp); - if (checked_mode) { - g_free (*mode); - *mode = g_strdup (checked_mode); - } else + if (checked_str) { + g_free (*str); + *str = g_strdup (checked_str); + } else { + char *options; + + options = nmc_util_strv_for_display (strings); g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'mode': '%s' is not a valid InfiniBand transport mode [datagram, connected]."), *mode); - return !!checked_mode; + _("Error: '%s': '%s' is not a valid %s %s."), + what, *str, what_desc, options); + g_free (options); + } + return !!checked_str; +} + +/* Checks Wi-Fi mode. */ +static gboolean +check_wifi_mode (char **mode, GError **error) +{ + const char *modes[] = { "infrastructure", "ap", "adhoc", NULL }; + + return check_valid_enumeration (mode, modes, "mode", _("Wi-Fi mode"), error); +} + +/* Checks InfiniBand mode. */ +static gboolean +check_infiniband_mode (char **mode, GError **error) +{ + const char *modes[] = { "datagram", "connected", NULL }; + + return check_valid_enumeration (mode, modes, "mode", _("InfiniBand transport mode"), error); } static gboolean @@ -2879,10 +2917,9 @@ do_questionnaire_ethernet (gboolean ethernet, char **mtu, char **mac, char **clo { gboolean once_more; GError *error = NULL; - const char *type = ethernet ? _("ethernet") : _("Wi-Fi"); /* Ask for optional arguments */ - if (!want_provide_opt_args (type, 3)) + if (ethernet && !want_provide_opt_args (_("ethernet"), 3)) return; if (!*mtu) { @@ -2997,11 +3034,36 @@ do_questionnaire_infiniband (char **mtu, char **mac, char **mode, char **parent, } } +#define WORD_INFRA "infrastructure" +#define WORD_AP "ap" +#define WORD_ADHOC "adhoc" +#define PROMPT_WIFI_MODE "(" WORD_INFRA "/" WORD_AP "/" WORD_ADHOC ") [" WORD_INFRA "]: " static void -do_questionnaire_wifi (char **mtu, char **mac, char **cloned_mac) +do_questionnaire_wifi (char **mtu, char **mac, char **cloned_mac, char **mode) { - /* At present, the optional Wi-Fi arguments are the same as for ethernet. */ - return do_questionnaire_ethernet (FALSE, mtu, mac, cloned_mac); + gboolean once_more; + GError *error = NULL; + + /* Ask for optional arguments */ + if (!want_provide_opt_args (_("Wi-Fi"), 4)) + return; + + /* Most optional Wi-Fi arguments are the same as for ethernet. */ + do_questionnaire_ethernet (FALSE, mtu, mac, cloned_mac); + + if (!*mode) { + do { + *mode = nmc_readline (_("Mode %s"), PROMPT_WIFI_MODE); + if (!*mode) + *mode = g_strdup ("infrastructure"); + once_more = !check_wifi_mode (mode, &error); + if (once_more) { + g_print ("%s\n", error->message); + g_clear_error (&error); + g_free (*mode); + } + } while (once_more); + } } static void @@ -3802,10 +3864,13 @@ cleanup_ib: char *mac = NULL; const char *cloned_mac_c = NULL; char *cloned_mac = NULL; + const char *mode_c = NULL; + char *mode = NULL; nmc_arg_t exp_args[] = { {"ssid", TRUE, &ssid, !ask}, {"mtu", TRUE, &mtu_c, FALSE}, {"mac", TRUE, &mac_c, FALSE}, {"cloned-mac", TRUE, &cloned_mac_c, FALSE}, + {"mode", TRUE, &mode_c, FALSE}, {NULL} }; if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) @@ -3823,8 +3888,9 @@ cleanup_ib: mtu = mtu_c ? g_strdup (mtu_c) : NULL; mac = mac_c ? g_strdup (mac_c) : NULL; cloned_mac = cloned_mac_c ? g_strdup (cloned_mac_c) : NULL; + mode = mode_c ? g_strdup (mode_c) : NULL; if (ask) - do_questionnaire_wifi (&mtu, &mac, &cloned_mac); + do_questionnaire_wifi (&mtu, &mac, &cloned_mac, &mode); if (!check_and_convert_mtu (mtu, &mtu_int, error)) goto cleanup_wifi; @@ -3832,6 +3898,8 @@ cleanup_ib: goto cleanup_wifi; if (!check_mac (cloned_mac, ARPHRD_ETHER, "cloned-mac", error)) goto cleanup_wifi; + if (!check_wifi_mode (&mode, error)) + goto cleanup_wifi; /* Add wifi setting */ s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); @@ -3846,6 +3914,9 @@ cleanup_ib: g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, mac, NULL); if (cloned_mac) g_object_set (s_wifi, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, cloned_mac, NULL); + if (mode) + g_object_set (s_wifi, NM_SETTING_WIRELESS_MODE, mode, NULL); + g_bytes_unref (ssid_bytes); success = TRUE; @@ -3854,6 +3925,7 @@ cleanup_wifi: g_free (mtu); g_free (mac); g_free (cloned_mac); + g_free (mode); if (!success) return FALSE; @@ -5009,6 +5081,13 @@ gen_func_bool_values_l10n (const char *text, int state) } static char * +gen_func_wifi_mode (const char *text, int state) +{ + const char *words[] = { "infrastructure", "ap", "adhoc", NULL }; + return nmc_rl_gen_func_basic (text, state, words); +} + +static char * gen_func_ib_type (const char *text, int state) { const char *words[] = { "datagram", "connected", NULL }; @@ -5114,6 +5193,8 @@ nmcli_con_add_tab_completion (const char *text, int start, int end) || g_str_has_suffix (rl_prompt, prompt_yes_no (FALSE, NULL)) || g_str_has_suffix (rl_prompt, prompt_yes_no (FALSE, ":"))) generator_func = gen_func_bool_values_l10n; + else if (g_str_has_suffix (rl_prompt, PROMPT_WIFI_MODE)) + generator_func = gen_func_wifi_mode; else if (g_str_has_suffix (rl_prompt, PROMPT_IB_MODE)) generator_func = gen_func_ib_type; else if (g_str_has_suffix (rl_prompt, PROMPT_BT_TYPE)) diff --git a/clients/cli/nmcli-completion b/clients/cli/nmcli-completion index 8c1cfaa713..ea37973669 100644 --- a/clients/cli/nmcli-completion +++ b/clients/cli/nmcli-completion @@ -407,7 +407,14 @@ _nmcli_compl_ARGS() ;; mode) if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list "balance-rr active-backup balance-xor broadcast 802.3ad balance-tlb balance-alb" + case "$OPTIONS_TYPE" in + "wifi") + _nmcli_list "infrastructure ap adhoc" + ;; + "bond"| \ + *) + _nmcli_list "balance-rr active-backup balance-xor broadcast 802.3ad balance-tlb balance-alb" + esac return 0 fi ;; @@ -915,7 +922,7 @@ _nmcli() 802-11-w|802-11-wi|802-11-wir|802-11-wire|802-11-wirel|802-11-wirele|802-11-wireles|802-11-wireless| \ wif|wifi) OPTIONS_TYPE=wifi - OPTIONS_TYPED=(ssid mac cloned-mac mtu) + OPTIONS_TYPED=(ssid mac cloned-mac mtu mode) OPTIONS_MANDATORY=(ssid) ;; wim|wima|wimax) diff --git a/clients/cli/utils.c b/clients/cli/utils.c index 3152fe4de2..cb8fbf018a 100644 --- a/clients/cli/utils.c +++ b/clients/cli/utils.c @@ -541,6 +541,31 @@ nmc_util_strv_to_slist (char **strv) } /* + * Convert string array (char **) to description string in the form of: + * "[string1, string2, ]" + * + * Returns: a newly allocated string. Caller must free it with g_free(). + */ +char * +nmc_util_strv_for_display (const char **strv) +{ + GString *result; + guint i = 0; + + result = g_string_sized_new (150); + g_string_append_c (result, '['); + while (strv && strv[i]) { + if (result->len > 1) + g_string_append (result, ", "); + g_string_append (result, strv[i]); + i++; + } + g_string_append_c (result, ']'); + + return g_string_free (result, FALSE); +} + +/* * Wrapper function for g_strsplit_set() that removes empty strings * from the vector as they are not useful in most cases. */ diff --git a/clients/cli/utils.h b/clients/cli/utils.h index ea59c4ed55..fc43b0ed92 100644 --- a/clients/cli/utils.h +++ b/clients/cli/utils.h @@ -14,7 +14,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2010 - 2014 Red Hat, Inc. + * Copyright 2010 - 2014 Red Hat, Inc. */ #ifndef NMC_UTILS_H @@ -72,6 +72,7 @@ char *nmc_get_user_input (const char *ask_str); int nmc_string_to_arg_array (const char *line, const char *delim, char ***argv, int *argc); const char *nmc_string_is_valid (const char *input, const char **allowed, GError **error); GSList *nmc_util_strv_to_slist (char **strv); +char * nmc_util_strv_for_display (const char **strv); char **nmc_strsplit_set (const char *str, const char *delimiter, int max_tokens); int nmc_string_screen_width (const char *start, const char *end); void set_val_str (NmcOutputField fields_array[], guint32 index, char *value); diff --git a/man/nmcli.1.in b/man/nmcli.1.in index 308dbeccc2..fbaf0458e1 100644 --- a/man/nmcli.1.in +++ b/man/nmcli.1.in @@ -418,6 +418,8 @@ Note: use quotes around \fB*\fP to suppress shell expansion. \(en MAC address of the device this connection is locked to .IP "\fI[cloned-mac <cloned MAC address>]\fP" 42 \(en cloned MAC +.IP "\fI[mode infrastructure|ap|adhoc]\fP" 42 +\(en Wi-Fi network mode. If blank, \fIinfrastructure\fP is assumed. .IP "\fI[mtu <MTU>]\fP" 42 \(en MTU .RE |