diff --git a/clients/cli/agent.c b/clients/cli/agent.c index 183679a48..601e0ca44 100644 --- a/clients/cli/agent.c +++ b/clients/cli/agent.c @@ -139,6 +139,7 @@ secrets_requested (NMSecretAgentSimple *agent, static NMCResultCode do_agent_secret (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); if (nmc->complete) return nmc->return_value; @@ -167,6 +168,7 @@ do_agent_polkit (NmCli *nmc, int argc, char **argv) { GError *error = NULL; + next_arg (nmc, &argc, &argv, NULL); if (nmc->complete) return nmc->return_value; @@ -192,6 +194,7 @@ do_agent_all (NmCli *nmc, int argc, char **argv) { NMCResultCode secret_res; + next_arg (nmc, &argc, &argv, NULL); if (nmc->complete) return nmc->return_value; @@ -218,6 +221,7 @@ static const NMCCommand agent_cmds[] = { NMCResultCode do_agent (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); nmc_do_cmd (nmc, agent_cmds, *argv, argc, argv); return nmc->return_value; diff --git a/clients/cli/common.c b/clients/cli/common.c index c17bc8194..39b314f0a 100644 --- a/clients/cli/common.c +++ b/clients/cli/common.c @@ -1333,7 +1333,6 @@ nmc_do_cmd (NmCli *nmc, const NMCCommand cmds[], const char *cmd, int argc, char g_simple_async_result_complete_in_idle (simple); g_object_unref (simple); } else { - next_arg (nmc, &argc, &argv); call_cmd (nmc, simple, c, argc, argv); } } else if (cmd) { diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 17f821978..5bca13889 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -1750,7 +1750,7 @@ get_connection (NmCli *nmc, int *argc, char ***argv, int *pos, GError **error) * don't switch to next argument. */ if (!pos || !*pos) - next_arg (nmc, argc, argv); + next_arg (nmc, argc, argv, NULL); return connection; } @@ -1763,19 +1763,15 @@ do_connections_show (NmCli *nmc, int argc, char **argv) GPtrArray *invisibles, *sorted_cons; gboolean active_only = FALSE; GArray *order = NULL; - int i; + int i, option; - /* check connection show options [--active] */ - while (argc) { - if (argc == 1 && nmc->complete) { - nmc_complete_strings (*argv, "--active", - "--order", NULL); - } - - if (!active_only && nmc_arg_is_option (*argv, "active")) { + /* check connection show options [--active] [--order ] */ + while ((option = next_arg (nmc, &argc, &argv, "--active", "--order", NULL)) > 0) { + switch (option) { + case 1: /* --active */ active_only = TRUE; - next_arg (nmc, &argc, &argv); - } else if (!order && nmc_arg_is_option (*argv, "order")) { + break; + case 2: /* --order */ argc--; argv++; if (!argc) { @@ -1783,12 +1779,12 @@ do_connections_show (NmCli *nmc, int argc, char **argv) _("'--order' argument is missing")); goto finish; } - /* TODO: complete --order */ order = parse_preferred_connection_order (*argv, &err); if (err) goto finish; - next_arg (nmc, &argc, &argv); - } else { + break; + default: + g_assert_not_reached(); break; } } @@ -1908,12 +1904,12 @@ do_connections_show (NmCli *nmc, int argc, char **argv) if (!acon) acon = get_ac_for_connection (active_cons, con); if (active_only && !acon) { - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); continue; } if (nmc->complete) { - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); continue; } @@ -1951,7 +1947,7 @@ do_connections_show (NmCli *nmc, int argc, char **argv) * so process the same argument again. */ if (!pos) - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); } } @@ -2576,8 +2572,8 @@ do_connection_up (NmCli *nmc, int argc, char **argv) gs_free_error GError *error = NULL; char **arg_arr = NULL; int arg_num; - char ***argv_ptr = &argv; - int *argc_ptr = &argc; + char ***argv_ptr; + int *argc_ptr; /* * Set default timeout for connection activation. @@ -2586,6 +2582,10 @@ do_connection_up (NmCli *nmc, int argc, char **argv) if (nmc->timeout == -1) nmc->timeout = 90; + next_arg (nmc, &argc, &argv, NULL); + argv_ptr = &argv; + argc_ptr = &argc; + if (argc == 0 && nmc->ask) { char *line; @@ -2652,7 +2652,7 @@ do_connection_up (NmCli *nmc, int argc, char **argv) g_printerr (_("Unknown parameter: %s\n"), *argv); } - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); } if (nmc->complete) @@ -2769,13 +2769,17 @@ do_connection_down (NmCli *nmc, int argc, char **argv) const GPtrArray *active_cons; GSList *queue = NULL, *iter; char **arg_arr = NULL; - char **arg_ptr = argv; - int arg_num = argc; + char **arg_ptr; + int arg_num; int idx = 0; if (nmc->timeout == -1) nmc->timeout = 10; + next_arg (nmc, &argc, &argv, NULL); + arg_ptr = argv; + arg_num = argc; + if (argc == 0) { /* nmc_do_cmd() should not call this with argc=0. */ g_assert (!nmc->complete); @@ -2834,7 +2838,7 @@ do_connection_down (NmCli *nmc, int argc, char **argv) } if (idx == 0) - next_arg (nmc->ask ? NULL : nmc, &arg_num, &arg_ptr); + next_arg (nmc->ask ? NULL : nmc, &arg_num, &arg_ptr, NULL); } if (!queue) { @@ -4960,6 +4964,8 @@ do_connection_add (NmCli *nmc, int argc, char **argv) OptionInfo *candidate; gboolean seen_dash_dash = FALSE; + next_arg (nmc, &argc, &argv, NULL); + rl_attempted_completion_function = (rl_completion_func_t *) nmcli_con_add_tab_completion; nmc->return_value = NMC_RESULT_SUCCESS; @@ -4979,7 +4985,7 @@ read_properties: * options and properties to be separated with "--" */ g_clear_error (&error); seen_dash_dash = TRUE; - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); goto read_properties; } else if (g_strcmp0 (*argv, "save") == 0) { /* It would be better if "save" was a separate argument and not @@ -5001,7 +5007,7 @@ read_properties: g_clear_error (&error); goto finish; } - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); goto read_properties; } @@ -7921,6 +7927,7 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) {"path", TRUE, &con_path, FALSE}, {NULL} }; + next_arg (nmc, &argc, &argv, NULL); if (argc == 1 && nmc->complete) nmc_complete_strings (*argv, "type", "con-name", "id", "uuid", "path", NULL); @@ -8124,11 +8131,10 @@ do_connection_modify (NmCli *nmc, GError *error = NULL; gboolean temporary = FALSE; - if (argc && nmc_arg_is_option (*argv, "temporary")) { - if (nmc->complete) - goto finish; + /* Check --temporary */ + if (next_arg (nmc, &argc, &argv, "--temporary", NULL) > 0) { temporary = TRUE; - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); } connection = get_connection (nmc, &argc, &argv, NULL, &error); @@ -8217,12 +8223,17 @@ do_connection_clone (NmCli *nmc, int argc, char **argv) gboolean temporary = FALSE; char **arg_arr = NULL; int arg_num; - char ***argv_ptr = &argv; - int *argc_ptr = &argc; + char ***argv_ptr; + int *argc_ptr; GError *error = NULL; - if (argc == 1 && nmc->complete) - nmc_complete_strings (*argv, "temporary", NULL); + if (next_arg (nmc, &argc, &argv, "--temporary", NULL) > 0) { + temporary = TRUE; + next_arg (nmc, &argc, &argv, NULL); + } + + argv_ptr = &argv; + argc_ptr = &argc; if (argc == 0 && nmc->ask) { char *line; @@ -8235,9 +8246,6 @@ do_connection_clone (NmCli *nmc, int argc, char **argv) g_free (line); argv_ptr = &arg_arr; argc_ptr = &arg_num; - } else if (nmc_arg_is_option (*argv, "temporary")) { - temporary = TRUE; - next_arg (nmc, &argc, &argv); } connection = get_connection (nmc, argc_ptr, argv_ptr, NULL, &error); @@ -8260,7 +8268,7 @@ do_connection_clone (NmCli *nmc, int argc, char **argv) goto finish; } - if (next_arg (nmc->ask ? NULL : nmc, argc_ptr, argv_ptr) == 0) { + if (next_arg (nmc->ask ? NULL : nmc, argc_ptr, argv_ptr, NULL) == 0) { g_string_printf (nmc->return_text, _("Error: unknown extra argument: '%s'."), *argv); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; goto finish; @@ -8331,8 +8339,8 @@ do_connection_delete (NmCli *nmc, int argc, char **argv) ConnectionCbInfo *info = NULL; GSList *queue = NULL, *iter; char **arg_arr = NULL, *old_arg; - char **arg_ptr = argv; - int arg_num = argc; + char **arg_ptr; + int arg_num; GString *invalid_cons = NULL; int pos = 0; GError *error = NULL; @@ -8340,6 +8348,10 @@ do_connection_delete (NmCli *nmc, int argc, char **argv) if (nmc->timeout == -1) nmc->timeout = 10; + next_arg (nmc, &argc, &argv, NULL); + arg_ptr = argv; + arg_num = argc; + if (argc == 0) { if (nmc->ask) { char *line; @@ -8470,6 +8482,7 @@ do_connection_monitor (NmCli *nmc, int argc, char **argv) { GError *error = NULL; + next_arg (nmc, &argc, &argv, NULL); if (argc == 0) { /* No connections specified. Monitor all. */ const GPtrArray *connections; @@ -8518,6 +8531,7 @@ do_connection_reload (NmCli *nmc, int argc, char **argv) { GError *error = NULL; + next_arg (nmc, &argc, &argv, NULL); if (nmc->complete) return nmc->return_value; @@ -8538,6 +8552,7 @@ do_connection_load (NmCli *nmc, int argc, char **argv) char **filenames, **failures = NULL; int i; + next_arg (nmc, &argc, &argv, NULL); if (argc == 0) { g_string_printf (nmc->return_text, _("Error: No connection specified.")); return NMC_RESULT_ERROR_USER_INPUT; @@ -8601,6 +8616,13 @@ do_connection_import (NmCli *nmc, int argc, char **argv) gs_free char *service_type = NULL; gboolean temporary = FALSE; + /* Check --temporary */ + if (next_arg (nmc, &argc, &argv, "--temporary", NULL) > 0) { + temporary = TRUE; + next_arg (nmc, &argc, &argv, NULL); + } + + if (argc == 0) { /* nmc_do_cmd() should not call this with argc=0. */ g_assert (!nmc->complete); @@ -8619,11 +8641,7 @@ do_connection_import (NmCli *nmc, int argc, char **argv) while (argc > 0) { if (argc == 1 && nmc->complete) - nmc_complete_strings (*argv, "temporary", "type", "file", NULL); - if (nmc_arg_is_option (*argv, "temporary")) { - temporary = TRUE; - next_arg (nmc, &argc, &argv); - } + nmc_complete_strings (*argv, "type", "file", NULL); if (strcmp (*argv, "type") == 0) { argc--; @@ -8662,7 +8680,7 @@ do_connection_import (NmCli *nmc, int argc, char **argv) goto finish; } - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); } if (nmc->complete) @@ -8738,8 +8756,12 @@ do_connection_export (NmCli *nmc, int argc, char **argv) char tmpfile[] = "/tmp/nmcli-export-temp-XXXXXX"; char **arg_arr = NULL; int arg_num; - char ***argv_ptr = &argv; - int *argc_ptr = &argc; + char ***argv_ptr; + int *argc_ptr; + + next_arg (nmc, &argc, &argv, NULL); + argv_ptr = &argv; + argc_ptr = &argc; if (argc == 0 && nmc->ask) { char *line; @@ -8770,7 +8792,7 @@ do_connection_export (NmCli *nmc, int argc, char **argv) argv++; } - if (next_arg (nmc->ask ? NULL : nmc, argc_ptr, argv_ptr) == 0) { + if (next_arg (nmc->ask ? NULL : nmc, argc_ptr, argv_ptr, NULL) == 0) { g_string_printf (nmc->return_text, _("Error: unknown extra argument: '%s'."), *argv); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; goto finish; @@ -8946,6 +8968,8 @@ static const NMCCommand connection_cmds[] = { NMCResultCode do_connections (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); + /* Register polkit agent */ nmc_start_polkit_agent_start_try (nmc); diff --git a/clients/cli/devices.c b/clients/cli/devices.c index 18ba15d3b..f05f2ca99 100644 --- a/clients/cli/devices.c +++ b/clients/cli/devices.c @@ -618,7 +618,7 @@ get_device_list (NmCli *nmc, int argc, char **argv) } /* Take next argument */ - next_arg (nmc->ask ? NULL : nmc, &arg_num, &arg_ptr); + next_arg (nmc->ask ? NULL : nmc, &arg_num, &arg_ptr, NULL); } g_free (devices); @@ -647,7 +647,7 @@ get_device (NmCli *nmc, int *argc, char ***argv, GError **error) } } else { ifname = **argv; - next_arg (nmc, argc, argv); + next_arg (nmc, argc, argv, NULL); } devices = nmc_get_devices_sorted (nmc->client); @@ -1527,13 +1527,15 @@ do_devices_status (NmCli *nmc, int argc, char **argv) size_t tmpl_len; NMC_OUTPUT_DATA_DEFINE_SCOPED (out); + next_arg (nmc, &argc, &argv, NULL); + /* Nothing to complete */ if (nmc->complete) return nmc->return_value; while (argc > 0) { g_printerr (_("Unknown parameter: %s\n"), *argv); - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); } if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0) @@ -1575,6 +1577,7 @@ do_device_show (NmCli *nmc, int argc, char **argv) { gs_free_error GError *error = NULL; + next_arg (nmc, &argc, &argv, NULL); if (!nmc->mode_specified) nmc->nmc_config_mutable.multiline_output = TRUE; /* multiline mode is default for 'device show' */ @@ -1866,6 +1869,7 @@ do_device_connect (NmCli *nmc, int argc, char **argv) if (nmc->timeout == -1) nmc->timeout = 90; + next_arg (nmc, &argc, &argv, NULL); device = get_device (nmc, &argc, &argv, &error); if (!device) { g_string_printf (nmc->return_text, _("Error: %s."), error->message); @@ -2034,6 +2038,7 @@ do_device_reapply (NmCli *nmc, int argc, char **argv) if (nmc->timeout == -1) nmc->timeout = 10; + next_arg (nmc, &argc, &argv, NULL); device = get_device (nmc, &argc, &argv, &error); if (!device) { g_string_printf (nmc->return_text, _("Error: %s."), error->message); @@ -2141,6 +2146,7 @@ do_device_modify (NmCli *nmc, int argc, char **argv) ModifyInfo *info = NULL; gs_free_error GError *error = NULL; + next_arg (nmc, &argc, &argv, NULL); device = get_device (nmc, &argc, &argv, &error); if (!device) { g_string_printf (nmc->return_text, _("Error: %s."), error->message); @@ -2207,6 +2213,7 @@ do_devices_disconnect (NmCli *nmc, int argc, char **argv) if (nmc->timeout == -1) nmc->timeout = 10; + next_arg (nmc, &argc, &argv, NULL); queue = get_device_list (nmc, argc, argv); if (!queue) return nmc->return_value; @@ -2276,6 +2283,7 @@ do_devices_delete (NmCli *nmc, int argc, char **argv) if (nmc->timeout == -1) nmc->timeout = 10; + next_arg (nmc, &argc, &argv, NULL); queue = get_device_list (nmc, argc, argv); if (!queue) return nmc->return_value; @@ -2324,9 +2332,9 @@ do_device_set (NmCli *nmc, int argc, char **argv) }; gs_free_error GError *error = NULL; - if (argc >= 1 && g_strcmp0 (*argv, "ifname") == 0) { - next_arg (nmc, &argc, &argv); - } + next_arg (nmc, &argc, &argv, NULL); + if (argc >= 1 && g_strcmp0 (*argv, "ifname") == 0) + next_arg (nmc, &argc, &argv, NULL); device = get_device (nmc, &argc, &argv, &error); if (!device) { @@ -2384,7 +2392,7 @@ do_device_set (NmCli *nmc, int argc, char **argv) g_string_printf (nmc->return_text, _("Error: property '%s' is not known."), *argv); return NMC_RESULT_ERROR_USER_INPUT; } - } while (next_arg (nmc, &argc, &argv) == 0); + } while (next_arg (nmc, &argc, &argv, NULL) == 0); if (nmc->complete) return nmc->return_value; @@ -2477,6 +2485,7 @@ do_devices_monitor (NmCli *nmc, int argc, char **argv) if (nmc->complete) return nmc->return_value; + next_arg (nmc, &argc, &argv, NULL); if (argc == 0) { /* No devices specified. Monitor all. */ const GPtrArray *devices = nm_client_get_devices (nmc->client); @@ -2669,6 +2678,7 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv) devices = nmc_get_devices_sorted (nmc->client); + next_arg (nmc, &argc, &argv, NULL); while (argc > 0) { if (argc == 1 && nmc->complete) nmc_complete_strings (*argv, "ifname", "bssid", NULL); @@ -2697,7 +2707,7 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv) g_printerr (_("Unknown parameter: %s\n"), *argv); } - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); } if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0) @@ -2889,6 +2899,7 @@ do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv) devices = nmc_get_devices_sorted (nmc->client); + next_arg (nmc, &argc, &argv, NULL); /* Get the first compulsory argument (SSID or BSSID) */ if (argc > 0) { param_user = *argv; @@ -2897,7 +2908,7 @@ do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv) if (argc == 1 && nmc->complete) complete_aps (devices, NULL, param_user, param_user); - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); } else { /* nmc_do_cmd() should not call this with argc=0. */ g_assert (!nmc->complete); @@ -3028,7 +3039,7 @@ do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv) g_printerr (_("Unknown parameter: %s\n"), *argv); } - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); } if (nmc->complete) @@ -3122,7 +3133,7 @@ do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv) if (con_name) g_object_set (s_con, NM_SETTING_CONNECTION_ID, con_name, NULL); - /* Connection will only be visible to this user when '--private' is specified */ + /* Connection will only be visible to this user when 'private' is specified */ if (private) nm_setting_connection_add_permission (s_con, "user", g_get_user_name (), NULL); } @@ -3379,6 +3390,7 @@ do_device_wifi_hotspot (NmCli *nmc, int argc, char **argv) devices = nmc_get_devices_sorted (nmc->client); + next_arg (nmc, &argc, &argv, NULL); while (argc > 0) { if (argc == 1 && nmc->complete) { nmc_complete_strings (*argv, "ifname", "con-name", "ssid", "band", @@ -3455,7 +3467,7 @@ do_device_wifi_hotspot (NmCli *nmc, int argc, char **argv) return NMC_RESULT_ERROR_USER_INPUT; } - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); } show_password = nmc->show_secrets || show_password; @@ -3601,6 +3613,7 @@ do_device_wifi_rescan (NmCli *nmc, int argc, char **argv) ssids = g_ptr_array_new (); devices = nmc_get_devices_sorted (nmc->client); + next_arg (nmc, &argc, &argv, NULL); /* Get the parameters */ while (argc > 0) { if (argc == 1 && nmc->complete) @@ -3634,7 +3647,7 @@ do_device_wifi_rescan (NmCli *nmc, int argc, char **argv) } else if (!nmc->complete) g_printerr (_("Unknown parameter: %s\n"), *argv); - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); } if (nmc->complete) @@ -3689,6 +3702,7 @@ static NMCCommand device_wifi_cmds[] = { static NMCResultCode do_device_wifi (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); nmc_do_cmd (nmc, device_wifi_cmds, *argv, argc, argv); return nmc->return_value; @@ -3788,6 +3802,7 @@ do_device_lldp_list (NmCli *nmc, int argc, char **argv) int counter = 0; NMC_OUTPUT_DATA_DEFINE_SCOPED (out); + next_arg (nmc, &argc, &argv, NULL); while (argc > 0) { if (argc == 1 && nmc->complete) nmc_complete_strings (*argv, "ifname", NULL); @@ -3810,7 +3825,7 @@ do_device_lldp_list (NmCli *nmc, int argc, char **argv) return NMC_RESULT_ERROR_USER_INPUT; } - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); } if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0) @@ -3856,6 +3871,7 @@ do_device_lldp (NmCli *nmc, int argc, char **argv) if (!nmc->mode_specified) nmc->nmc_config_mutable.multiline_output = TRUE; /* multiline mode is default for 'device lldp' */ + next_arg (nmc, &argc, &argv, NULL); nmc_do_cmd (nmc, device_lldp_cmds, *argv, argc, argv); return nmc->return_value; @@ -3921,6 +3937,8 @@ static const NMCCommand device_cmds[] = { NMCResultCode do_devices (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); + /* Register polkit agent */ nmc_start_polkit_agent_start_try (nmc); diff --git a/clients/cli/general.c b/clients/cli/general.c index 5bffa9270..71f3a626a 100644 --- a/clients/cli/general.c +++ b/clients/cli/general.c @@ -391,6 +391,7 @@ show_nm_status (NmCli *nmc, const char *pretty_header_name, const char *print_fl static NMCResultCode do_general_status (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); if (nmc->complete) return nmc->return_value; @@ -567,6 +568,7 @@ show_nm_permissions (NmCli *nmc) static NMCResultCode do_general_permissions (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); if (nmc->complete) return nmc->return_value; @@ -650,6 +652,7 @@ do_general_logging (NmCli *nmc, int argc, char **argv) { gs_free_error GError *error = NULL; + next_arg (nmc, &argc, &argv, NULL); if (argc == 0) { if (nmc->complete) return nmc->return_value; @@ -697,7 +700,7 @@ do_general_logging (NmCli *nmc, int argc, char **argv) g_string_printf (nmc->return_text, _("Error: property '%s' is not known."), *argv); return NMC_RESULT_ERROR_USER_INPUT; } - } while (next_arg (nmc, &argc, &argv) == 0); + } while (next_arg (nmc, &argc, &argv, NULL) == 0); if (nmc->complete) return nmc->return_value; @@ -732,6 +735,7 @@ save_hostname_cb (GObject *object, GAsyncResult *result, gpointer user_data) static NMCResultCode do_general_hostname (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); if (nmc->complete) return nmc->return_value; @@ -747,7 +751,7 @@ do_general_hostname (NmCli *nmc, int argc, char **argv) /* hostname provided -> set it */ const char *hostname = *argv; - if (next_arg (nmc, &argc, &argv) == 0) + if (next_arg (nmc, &argc, &argv, NULL) == 0) g_print ("Warning: ignoring extra garbage after '%s' hostname\n", hostname); nmc->should_wait++; @@ -772,6 +776,8 @@ static const NMCCommand general_cmds[] = { NMCResultCode do_general (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); + /* Register polkit agent */ nmc_start_polkit_agent_start_try (nmc); @@ -837,18 +843,21 @@ do_networking_on_off (NmCli *nmc, int argc, char **argv, gboolean enable) static NMCResultCode do_networking_on (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); return do_networking_on_off (nmc, argc, argv, TRUE); } static NMCResultCode do_networking_off (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); return do_networking_on_off (nmc, argc, argv, FALSE); } static NMCResultCode do_networking_connectivity (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); if (nmc->complete) { if (argc == 1) nmc_complete_strings (*argv, "check", NULL); @@ -882,6 +891,7 @@ do_networking_connectivity (NmCli *nmc, int argc, char **argv) static NMCResultCode do_networking_show (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); if (nmc->complete) return nmc->return_value; @@ -903,6 +913,7 @@ static const NMCCommand networking_cmds[] = { NMCResultCode do_networking (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); nmc_do_cmd (nmc, networking_cmds, *argv, argc, argv); return nmc->return_value; @@ -913,6 +924,7 @@ do_radio_all (NmCli *nmc, int argc, char **argv) { gboolean enable_flag; + next_arg (nmc, &argc, &argv, NULL); if (argc == 0) { if (nmc->complete) return nmc->return_value; @@ -942,6 +954,7 @@ do_radio_wifi (NmCli *nmc, int argc, char **argv) { gboolean enable_flag; + next_arg (nmc, &argc, &argv, NULL); if (argc == 0) { if (nmc->complete) return nmc->return_value; @@ -968,6 +981,7 @@ do_radio_wwan (NmCli *nmc, int argc, char **argv) { gboolean enable_flag; + next_arg (nmc, &argc, &argv, NULL); if (argc == 0) { if (nmc->complete) return nmc->return_value; @@ -1002,6 +1016,8 @@ static const NMCCommand radio_cmds[] = { NMCResultCode do_radio (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); + /* Register polkit agent */ nmc_start_polkit_agent_start_try (nmc); @@ -1227,6 +1243,8 @@ do_overview (NmCli *nmc, int argc, char **argv) char *tmp; int i; + next_arg (nmc, &argc, &argv, NULL); + /* Register polkit agent */ nmc_start_polkit_agent_start_try (nmc); @@ -1326,6 +1344,8 @@ do_overview (NmCli *nmc, int argc, char **argv) NMCResultCode do_monitor (NmCli *nmc, int argc, char **argv) { + next_arg (nmc, &argc, &argv, NULL); + if (nmc->complete) return nmc->return_value; diff --git a/clients/cli/nmcli.c b/clients/cli/nmcli.c index 255359645..3c01828a7 100644 --- a/clients/cli/nmcli.c +++ b/clients/cli/nmcli.c @@ -209,9 +209,9 @@ process_command_line (NmCli *nmc, int argc, char **argv) if (argc > 1 && nm_streq (argv[1], "--complete-args")) { nmc->complete = TRUE; argv[1] = argv[0]; - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); } - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); /* parse options */ while (argc) { @@ -229,7 +229,7 @@ process_command_line (NmCli *nmc, int argc, char **argv) opt++; /* '--' ends options */ if (opt[1] == '\0') { - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); break; } } @@ -380,7 +380,7 @@ process_command_line (NmCli *nmc, int argc, char **argv) nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return FALSE; } - next_arg (nmc, &argc, &argv); + next_arg (nmc, &argc, &argv, NULL); } /* Now run the requested command */ diff --git a/clients/cli/utils.c b/clients/cli/utils.c index 30d04b6f1..e197e9a66 100644 --- a/clients/cli/utils.c +++ b/clients/cli/utils.c @@ -45,21 +45,66 @@ parse_global_arg (NmCli *nmc, const char *arg) return TRUE; } - +/** + * next_arg: + * @nmc: NmCli data + * @*argc: pointer to left number of arguments to parse + * @***argv: pointer to const char *array of arguments still to parse + * @...: a %NULL terminated list of cmd options to match (e.g., "--active") + * + * Takes care of autocompleting options when needed and performs + * match against passed options while moving forward the pointer + * to the remaining arguments. + * + * Returns: the number of the matched option if a match is found against + * one of the custom options passed; 0 if no custom option matched and still + * some args need to be processed or autocompletion has been performed; + * -1 otherwise (no more args). + */ int -next_arg (NmCli *nmc, int *argc, char ***argv) +next_arg (NmCli *nmc, int *argc, char ***argv, ...) { - int arg_num = *argc; + va_list args; + const char *cmd_option; + + g_assert (*argc >= 0); do { - if (arg_num > 0) { + int cmd_option_pos = 1; + + if (*argc > 0) { (*argc)--; (*argv)++; } - if (nmc && nmc->complete && *argc == 1 && ***argv == '-') - nmc_complete_strings (**argv, "--ask", "--show-secrets", NULL); - if (arg_num <= 1) + if (*argc == 0) return -1; + + + va_start (args, argv); + + if (nmc && nmc->complete && *argc == 1) { + while ((cmd_option = va_arg (args, const char *))) + nmc_complete_strings (**argv, cmd_option, NULL); + + if (***argv == '-') + nmc_complete_strings (**argv, "--ask", "--show-secrets", NULL); + + va_end (args); + return 0; + } + + /* Check command dependent options first */ + while ((cmd_option = va_arg (args, const char *))) { + /* strip heading "--" form cmd_option */ + if (nmc_arg_is_option (**argv, cmd_option + 2)) { + va_end (args); + return cmd_option_pos; + } + cmd_option_pos++; + } + + va_end (args); + } while (nmc && parse_global_arg (nmc, **argv)); return 0; @@ -164,7 +209,7 @@ nmc_parse_args (nmc_arg_t *arg_arr, gboolean last, int *argc, char ***argv, GErr return FALSE; } - next_arg (NULL, argc, argv); + next_arg (NULL, argc, argv, NULL); } return TRUE; diff --git a/clients/cli/utils.h b/clients/cli/utils.h index cc7bc1f2f..0f8c2949a 100644 --- a/clients/cli/utils.h +++ b/clients/cli/utils.h @@ -33,7 +33,7 @@ typedef struct { } nmc_arg_t; /* === Functions === */ -int next_arg (NmCli *nmc, int *argc, char ***argv); +int next_arg (NmCli *nmc, int *argc, char ***argv, ...); gboolean nmc_arg_is_help (const char *arg); gboolean nmc_arg_is_option (const char *arg, const char *opt_name); gboolean nmc_parse_args (nmc_arg_t *arg_arr, gboolean last, int *argc, char ***argv, GError **error);