const char * nmc_bond_validate_mode (const char *mode, GError **error) { unsigned long mode_int; static const char *valid_modes[] = { "balance-rr", "active-backup", "balance-xor", "broadcast", "802.3ad", "balance-tlb", "balance-alb", NULL }; if (nmc_string_to_uint (mode, TRUE, 0, 6, &mode_int)) { /* Translate bonding mode numbers to mode names: * https://www.kernel.org/doc/Documentation/networking/bonding.txt */ return valid_modes[mode_int]; } else return nmc_string_is_valid (mode, valid_modes, error); }
/* Parses @str for color as string or number */ NmcTermColor nmc_term_color_parse_string (const char *str, GError **error) { unsigned long color_int; static const char *colors[] = { "normal", "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", NULL }; if (nmc_string_to_uint (str, TRUE, 0, 8, &color_int)) { return (NmcTermColor) color_int; } else { const char *color, **p; int i; color = nmc_string_is_valid (str, colors, error); for (p = colors, i = 0; *p != NULL; p++, i++) { if (*p == color) return (NmcTermColor) i; } return -1; } }
static NMCResultCode parse_command_line (NmCli *nmc, int argc, char **argv) { char *base; base = strrchr (argv[0], '/'); if (base == NULL) base = argv[0]; else base++; if (argc > 1 && nm_streq (argv[1], "--complete-args")) { /* We (currently?) support --complete-args for "connection" command only: * ignore any other command when this option is enabled as means we are in * autocompletion mode (so we should just quit and don't print anything). * This would help us to ensure shell autocompletion after NM package downgrade * if we ever will enable --complete-args for other commands */ if ((argc == 2) || !(nm_streq0 (argv[2], "connection") || nm_streq0 (argv[2], "device"))) return nmc->return_value; nmc->complete = TRUE; argv[1] = argv[0]; argc--; argv++; } /* parse options */ while (argc > 1) { char *opt = argv[1]; /* '--' ends options */ if (strcmp (opt, "--") == 0) { argc--; argv++; break; } if (opt[0] != '-') break; if (opt[1] == '-') opt++; if (matches (opt, "-terse") == 0) { if (nmc->print_output == NMC_PRINT_TERSE) { g_string_printf (nmc->return_text, _("Error: Option '--terse' is specified the second time.")); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } else if (nmc->print_output == NMC_PRINT_PRETTY) { g_string_printf (nmc->return_text, _("Error: Option '--terse' is mutually exclusive with '--pretty'.")); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } else nmc->print_output = NMC_PRINT_TERSE; } else if (matches (opt, "-pretty") == 0) { if (nmc->print_output == NMC_PRINT_PRETTY) { g_string_printf (nmc->return_text, _("Error: Option '--pretty' is specified the second time.")); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } else if (nmc->print_output == NMC_PRINT_TERSE) { g_string_printf (nmc->return_text, _("Error: Option '--pretty' is mutually exclusive with '--terse'.")); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } else nmc->print_output = NMC_PRINT_PRETTY; } else if (matches (opt, "-mode") == 0) { nmc->mode_specified = TRUE; next_arg (&argc, &argv); if (argc <= 1) { g_string_printf (nmc->return_text, _("Error: missing argument for '%s' option."), opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } if (matches (argv[1], "tabular") == 0) nmc->multiline_output = FALSE; else if (matches (argv[1], "multiline") == 0) nmc->multiline_output = TRUE; else { g_string_printf (nmc->return_text, _("Error: '%s' is not valid argument for '%s' option."), argv[1], opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } } else if (matches (opt, "-colors") == 0) { next_arg (&argc, &argv); if (argc <= 1) { g_string_printf (nmc->return_text, _("Error: missing argument for '%s' option."), opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } if (matches (argv[1], "auto") == 0) nmc->use_colors = NMC_USE_COLOR_AUTO; else if (matches (argv[1], "yes") == 0) nmc->use_colors = NMC_USE_COLOR_YES; else if (matches (argv[1], "no") == 0) nmc->use_colors = NMC_USE_COLOR_NO; else { g_string_printf (nmc->return_text, _("Error: '%s' is not valid argument for '%s' option."), argv[1], opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } } else if (matches (opt, "-escape") == 0) { next_arg (&argc, &argv); if (argc <= 1) { g_string_printf (nmc->return_text, _("Error: missing argument for '%s' option."), opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } if (matches (argv[1], "yes") == 0) nmc->escape_values = TRUE; else if (matches (argv[1], "no") == 0) nmc->escape_values = FALSE; else { g_string_printf (nmc->return_text, _("Error: '%s' is not valid argument for '%s' option."), argv[1], opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } } else if (matches (opt, "-fields") == 0) { next_arg (&argc, &argv); if (argc <= 1) { g_string_printf (nmc->return_text, _("Error: fields for '%s' options are missing."), opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } nmc->required_fields = g_strdup (argv[1]); } else if (matches (opt, "-nocheck") == 0) { /* ignore for backward compatibility */ } else if (matches (opt, "-ask") == 0) { nmc->ask = TRUE; } else if (matches (opt, "-show-secrets") == 0) { nmc->show_secrets = TRUE; } else if (matches (opt, "-wait") == 0) { unsigned long timeout; next_arg (&argc, &argv); if (argc <= 1) { g_string_printf (nmc->return_text, _("Error: missing argument for '%s' option."), opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } if (!nmc_string_to_uint (argv[1], TRUE, 0, G_MAXINT, &timeout)) { g_string_printf (nmc->return_text, _("Error: '%s' is not a valid timeout for '%s' option."), argv[1], opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } nmc->timeout = (int) timeout; } else if (matches (opt, "-version") == 0) { g_print (_("nmcli tool, version %s\n"), NMCLI_VERSION); return NMC_RESULT_SUCCESS; } else if (matches (opt, "-help") == 0) { usage (base); return NMC_RESULT_SUCCESS; } else { g_string_printf (nmc->return_text, _("Error: Option '%s' is unknown, try 'nmcli -help'."), opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } argc--; argv++; } /* Now run the requested command */ return nmc_do_cmd (nmc, nmcli_cmds, argv[1], argc-1, argv+1); }
static NMCResultCode parse_command_line (NmCli *nmc, int argc, char **argv) { char *base; base = strrchr (argv[0], '/'); if (base == NULL) base = argv[0]; else base++; /* parse options */ while (argc > 1) { char *opt = argv[1]; /* '--' ends options */ if (strcmp (opt, "--") == 0) { argc--; argv++; break; } if (opt[0] != '-') break; if (opt[1] == '-') opt++; if (matches (opt, "-terse") == 0) { if (nmc->print_output == NMC_PRINT_TERSE) { g_string_printf (nmc->return_text, _("Error: Option '--terse' is specified the second time.")); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } else if (nmc->print_output == NMC_PRINT_PRETTY) { g_string_printf (nmc->return_text, _("Error: Option '--terse' is mutually exclusive with '--pretty'.")); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } else nmc->print_output = NMC_PRINT_TERSE; } else if (matches (opt, "-pretty") == 0) { if (nmc->print_output == NMC_PRINT_PRETTY) { g_string_printf (nmc->return_text, _("Error: Option '--pretty' is specified the second time.")); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } else if (nmc->print_output == NMC_PRINT_TERSE) { g_string_printf (nmc->return_text, _("Error: Option '--pretty' is mutually exclusive with '--terse'.")); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } else nmc->print_output = NMC_PRINT_PRETTY; } else if (matches (opt, "-mode") == 0) { nmc->mode_specified = TRUE; next_arg (&argc, &argv); if (argc <= 1) { g_string_printf (nmc->return_text, _("Error: missing argument for '%s' option."), opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } if (matches (argv[1], "tabular") == 0) nmc->multiline_output = FALSE; else if (matches (argv[1], "multiline") == 0) nmc->multiline_output = TRUE; else { g_string_printf (nmc->return_text, _("Error: '%s' is not valid argument for '%s' option."), argv[1], opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } } else if (matches (opt, "-colors") == 0) { next_arg (&argc, &argv); if (argc <= 1) { g_string_printf (nmc->return_text, _("Error: missing argument for '%s' option."), opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } if (matches (argv[1], "auto") == 0) nmc->use_colors = NMC_USE_COLOR_AUTO; else if (matches (argv[1], "yes") == 0) nmc->use_colors = NMC_USE_COLOR_YES; else if (matches (argv[1], "no") == 0) nmc->use_colors = NMC_USE_COLOR_NO; else { g_string_printf (nmc->return_text, _("Error: '%s' is not valid argument for '%s' option."), argv[1], opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } } else if (matches (opt, "-escape") == 0) { next_arg (&argc, &argv); if (argc <= 1) { g_string_printf (nmc->return_text, _("Error: missing argument for '%s' option."), opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } if (matches (argv[1], "yes") == 0) nmc->escape_values = TRUE; else if (matches (argv[1], "no") == 0) nmc->escape_values = FALSE; else { g_string_printf (nmc->return_text, _("Error: '%s' is not valid argument for '%s' option."), argv[1], opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } } else if (matches (opt, "-fields") == 0) { next_arg (&argc, &argv); if (argc <= 1) { g_string_printf (nmc->return_text, _("Error: fields for '%s' options are missing."), opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } nmc->required_fields = g_strdup (argv[1]); } else if (matches (opt, "-nocheck") == 0) { nmc->nocheck_ver = TRUE; } else if (matches (opt, "-ask") == 0) { nmc->ask = TRUE; } else if (matches (opt, "-wait") == 0) { unsigned long timeout; next_arg (&argc, &argv); if (argc <= 1) { g_string_printf (nmc->return_text, _("Error: missing argument for '%s' option."), opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } if (!nmc_string_to_uint (argv[1], TRUE, 0, G_MAXINT, &timeout)) { g_string_printf (nmc->return_text, _("Error: '%s' is not a valid timeout for '%s' option."), argv[1], opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } nmc->timeout = (int) timeout; } else if (matches (opt, "-version") == 0) { g_print (_("nmcli tool, version %s\n"), NMCLI_VERSION); return NMC_RESULT_SUCCESS; } else if (matches (opt, "-help") == 0) { usage (base); return NMC_RESULT_SUCCESS; } else { g_string_printf (nmc->return_text, _("Error: Option '%s' is unknown, try 'nmcli -help'."), opt); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return nmc->return_value; } argc--; argv++; } if (argc > 1) { /* Now run the requested command */ return do_cmd (nmc, argv[1], argc-1, argv+1); } usage (base); return nmc->return_value; }
/* * nmc_parse_and_build_route: * @family: AF_INET or AF_INET6 * @first: the route destination in the form of "address/prefix" (/prefix is optional) * @second: (allow-none): next hop address, if third is not NULL. Otherwise it could be either next hop address or metric. (It can be NULL when @third is NULL). * @third: (allow-none): route metric * @error: location to store GError * * Parse route from strings and return an #NMIPRoute * * Returns: %TRUE on success, %FALSE on failure */ NMIPRoute * nmc_parse_and_build_route (int family, const char *first, const char *second, const char *third, GError **error) { int max_prefix = (family == AF_INET) ? 32 : 128; char *dest = NULL, *plen = NULL; const char *next_hop = NULL; const char *canon_dest; long int prefix = max_prefix; unsigned long int tmp_ulong; NMIPRoute *route = NULL; gboolean success = FALSE; GError *local = NULL; gint64 metric = -1; g_return_val_if_fail (family == AF_INET || family == AF_INET6, FALSE); g_return_val_if_fail (first != NULL, FALSE); g_return_val_if_fail (second || !third, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); dest = g_strdup (first); plen = strchr (dest, '/'); /* prefix delimiter */ if (plen) *plen++ = '\0'; if (plen) { if (!nmc_string_to_int (plen, TRUE, 1, max_prefix, &prefix)) { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, _("invalid prefix '%s'; <1-%d> allowed"), plen, max_prefix); goto finish; } } if (second) { if (third || nm_utils_ipaddr_valid (family, second)) next_hop = second; else { /* 'second' can be a metric */ if (!nmc_string_to_uint (second, TRUE, 0, G_MAXUINT32, &tmp_ulong)) { g_set_error (error, 1, 0, _("the second component of route ('%s') is neither " "a next hop address nor a metric"), second); goto finish; } metric = tmp_ulong; } } if (third) { if (!nmc_string_to_uint (third, TRUE, 0, G_MAXUINT32, &tmp_ulong)) { g_set_error (error, 1, 0, _("invalid metric '%s'"), third); goto finish; } metric = tmp_ulong; } route = nm_ip_route_new (family, dest, prefix, next_hop, metric, &local); if (!route) { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, _("invalid route: %s"), local->message); g_clear_error (&local); goto finish; } /* We don't accept default routes as NetworkManager handles it * itself. But we have to check this after @route has normalized the * dest string. */ canon_dest = nm_ip_route_get_dest (route); if (!strcmp (canon_dest, "0.0.0.0") || !strcmp (canon_dest, "::")) { g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, _("default route cannot be added (NetworkManager handles it by itself)")); g_clear_pointer (&route, nm_ip_route_unref); goto finish; } success = TRUE; finish: g_free (dest); return route; }