diff options
Diffstat (limited to 'lib/command.c')
| -rw-r--r-- | lib/command.c | 87 |
1 files changed, 71 insertions, 16 deletions
diff --git a/lib/command.c b/lib/command.c index c8fbf22721..eecca2a5f5 100644 --- a/lib/command.c +++ b/lib/command.c @@ -89,7 +89,6 @@ const char *node_names[] = { "aaa", // AAA_NODE, "keychain", // KEYCHAIN_NODE, "keychain key", // KEYCHAIN_KEY_NODE, - "logical-router", // LOGICALROUTER_NODE, "static ip", // IP_NODE, "vrf", // VRF_NODE, "interface", // INTERFACE_NODE, @@ -152,6 +151,7 @@ const char *node_names[] = { "bfd peer", /* BFD_PEER_NODE */ "openfabric", // OPENFABRIC_NODE "vrrp", /* VRRP_NODE */ + "bmp", /* BMP_NODE */ }; /* clang-format on */ @@ -290,7 +290,7 @@ vector cmd_make_strvec(const char *string) const char *copy = string; /* skip leading whitespace */ - while (isspace((int)*copy) && *copy != '\0') + while (isspace((unsigned char)*copy) && *copy != '\0') copy++; /* if the entire string was whitespace or a comment, return */ @@ -976,6 +976,7 @@ enum node_type node_parent(enum node_type node) case BGP_IPV6M_NODE: case BGP_EVPN_NODE: case BGP_IPV6L_NODE: + case BMP_NODE: ret = BGP_NODE; break; case BGP_EVPN_VNI_NODE: @@ -1060,8 +1061,10 @@ static int cmd_execute_command_real(vector vline, enum cmd_filter_type filter, vty->num_cfg_changes = 0; memset(&vty->cfg_changes, 0, sizeof(vty->cfg_changes)); - /* Regenerate candidate configuration. */ - if (frr_get_cli_mode() == FRR_CLI_CLASSIC) + /* Regenerate candidate configuration if necessary. */ + if (frr_get_cli_mode() == FRR_CLI_CLASSIC + && running_config->version + > vty->candidate_config->version) nb_config_replace(vty->candidate_config, running_config, true); } @@ -1456,7 +1459,6 @@ void cmd_exit(struct vty *vty) break; case INTERFACE_NODE: case PW_NODE: - case LOGICALROUTER_NODE: case VRF_NODE: case NH_GROUP_NODE: case ZEBRA_NODE: @@ -1493,6 +1495,7 @@ void cmd_exit(struct vty *vty) case BGP_IPV6M_NODE: case BGP_EVPN_NODE: case BGP_IPV6L_NODE: + case BMP_NODE: vty->node = BGP_NODE; break; case BGP_EVPN_VNI_NODE: @@ -1936,7 +1939,7 @@ DEFUN(config_domainname, { struct cmd_token *word = argv[1]; - if (!isalpha((int)word->arg[0])) { + if (!isalpha((unsigned char)word->arg[0])) { vty_out(vty, "Please specify string starting with alphabet\n"); return CMD_WARNING_CONFIG_FAILED; } @@ -1970,7 +1973,7 @@ DEFUN (config_hostname, { struct cmd_token *word = argv[1]; - if (!isalnum((int)word->arg[0])) { + if (!isalnum((unsigned char)word->arg[0])) { vty_out(vty, "Please specify string starting with alphabet or number\n"); return CMD_WARNING_CONFIG_FAILED; @@ -2018,7 +2021,7 @@ DEFUN (config_password, return CMD_SUCCESS; } - if (!isalnum((int)argv[idx_8]->arg[0])) { + if (!isalnum((unsigned char)argv[idx_8]->arg[0])) { vty_out(vty, "Please specify string starting with alphanumeric\n"); return CMD_WARNING_CONFIG_FAILED; @@ -2098,7 +2101,7 @@ DEFUN (config_enable_password, } } - if (!isalnum((int)argv[idx_8]->arg[0])) { + if (!isalnum((unsigned char)argv[idx_8]->arg[0])) { vty_out(vty, "Please specify string starting with alphanumeric\n"); return CMD_WARNING_CONFIG_FAILED; @@ -2710,15 +2713,66 @@ DEFUN (no_banner_motd, DEFUN(find, find_cmd, - "find COMMAND...", - "Find CLI command containing text\n" - "Text to search for\n") + "find REGEX", + "Find CLI command matching a regular expression\n" + "Search pattern (POSIX regex)\n") { - char *text = argv_concat(argv, argc, 1); + char *pattern = argv[1]->arg; const struct cmd_node *node; const struct cmd_element *cli; vector clis; + regex_t exp = {}; + + int cr = regcomp(&exp, pattern, REG_NOSUB | REG_EXTENDED); + + if (cr != 0) { + switch (cr) { + case REG_BADBR: + vty_out(vty, "%% Invalid {...} expression\n"); + break; + case REG_BADRPT: + vty_out(vty, "%% Bad repetition operator\n"); + break; + case REG_BADPAT: + vty_out(vty, "%% Regex syntax error\n"); + break; + case REG_ECOLLATE: + vty_out(vty, "%% Invalid collating element\n"); + break; + case REG_ECTYPE: + vty_out(vty, "%% Invalid character class name\n"); + break; + case REG_EESCAPE: + vty_out(vty, + "%% Regex ended with escape character (\\)\n"); + break; + case REG_ESUBREG: + vty_out(vty, + "%% Invalid number in \\digit construction\n"); + break; + case REG_EBRACK: + vty_out(vty, "%% Unbalanced square brackets\n"); + break; + case REG_EPAREN: + vty_out(vty, "%% Unbalanced parentheses\n"); + break; + case REG_EBRACE: + vty_out(vty, "%% Unbalanced braces\n"); + break; + case REG_ERANGE: + vty_out(vty, + "%% Invalid endpoint in range expression\n"); + break; + case REG_ESPACE: + vty_out(vty, "%% Failed to compile (out of memory)\n"); + break; + } + + goto done; + } + + for (unsigned int i = 0; i < vector_active(cmdvec); i++) { node = vector_slot(cmdvec, i); if (!node) @@ -2726,14 +2780,15 @@ DEFUN(find, clis = node->cmd_vector; for (unsigned int j = 0; j < vector_active(clis); j++) { cli = vector_slot(clis, j); - if (strcasestr(cli->string, text)) + + if (regexec(&exp, cli->string, 0, NULL, 0) == 0) vty_out(vty, " (%s) %s\n", node_names[node->node], cli->string); } } - XFREE(MTYPE_TMP, text); - +done: + regfree(&exp); return CMD_SUCCESS; } |
