📄 command.c
字号:
} if (strcmp (symbol, "IFNAME") == 0) { i = 0; lim = strlen (command); while (i < lim) { if (! isalnum ((int) command[i])) return 1; i++; } return 0; } return 0;}/* Completion match types. */enum match_type { no_match, extend_match, ipv4_prefix_match, ipv4_match, ipv6_prefix_match, ipv6_match, range_match, vararg_match, partly_match, exact_match };enum match_typecmd_ipv4_match (char *str){ char *sp; int dots = 0, nums = 0; char buf[4]; if (str == NULL) return partly_match; for (;;) { memset (buf, 0, sizeof (buf)); sp = str; while (*str != '\0') { if (*str == '.') { if (dots >= 3) return no_match; if (*(str + 1) == '.') return no_match; if (*(str + 1) == '\0') return partly_match; dots++; break; } if (!isdigit ((int) *str)) return no_match; str++; } if (str - sp > 3) return no_match; strncpy (buf, sp, str - sp); if (atoi (buf) > 255) return no_match; nums++; if (*str == '\0') break; str++; } if (nums < 4) return partly_match; return exact_match;}enum match_typecmd_ipv4_prefix_match (char *str){ char *sp; int dots = 0; char buf[4]; if (str == NULL) return partly_match; for (;;) { memset (buf, 0, sizeof (buf)); sp = str; while (*str != '\0' && *str != '/') { if (*str == '.') { if (dots == 3) return no_match; if (*(str + 1) == '.' || *(str + 1) == '/') return no_match; if (*(str + 1) == '\0') return partly_match; dots++; break; } if (!isdigit ((int) *str)) return no_match; str++; } if (str - sp > 3) return no_match; strncpy (buf, sp, str - sp); if (atoi (buf) > 255) return no_match; if (dots == 3) { if (*str == '/') { if (*(str + 1) == '\0') return partly_match; str++; break; } else if (*str == '\0') return partly_match; } if (*str == '\0') return partly_match; str++; } sp = str; while (*str != '\0') { if (!isdigit ((int) *str)) return no_match; str++; } if (atoi (sp) > 32) return no_match; return exact_match;}#define IPV6_ADDR_STR "0123456789abcdefABCDEF:.%"#define IPV6_PREFIX_STR "0123456789abcdefABCDEF:.%/"#define STATE_START 1#define STATE_COLON 2#define STATE_DOUBLE 3#define STATE_ADDR 4#define STATE_DOT 5#define STATE_SLASH 6#define STATE_MASK 7enum match_typecmd_ipv6_match (char *str){ int state = STATE_START; int colons = 0, nums = 0, double_colon = 0; char *sp = NULL; if (str == NULL) return partly_match; if (strspn (str, IPV6_ADDR_STR) != strlen (str)) return no_match; while (*str != '\0') { switch (state) { case STATE_START: if (*str == ':') { if (*(str + 1) != ':' && *(str + 1) != '\0') return no_match; colons--; state = STATE_COLON; } else { sp = str; state = STATE_ADDR; } continue; case STATE_COLON: colons++; if (*(str + 1) == ':') state = STATE_DOUBLE; else { sp = str + 1; state = STATE_ADDR; } break; case STATE_DOUBLE: if (double_colon) return no_match; if (*(str + 1) == ':') return no_match; else { if (*(str + 1) != '\0') colons++; sp = str + 1; state = STATE_ADDR; } double_colon++; nums++; break; case STATE_ADDR: if (*(str + 1) == ':' || *(str + 1) == '\0') { if (str - sp > 3) return no_match; nums++; state = STATE_COLON; } if (*(str + 1) == '.') state = STATE_DOT; break; case STATE_DOT: state = STATE_ADDR; break; default: break; } if (nums > 8) return no_match; if (colons > 7) return no_match; str++; }#if 0 if (nums < 11) return partly_match;#endif /* 0 */ return exact_match;}enum match_typecmd_ipv6_prefix_match (char *str){ int state = STATE_START; int colons = 0, nums = 0, double_colon = 0; int mask; char *sp = NULL; char *endptr = NULL; if (str == NULL) return partly_match; if (strspn (str, IPV6_PREFIX_STR) != strlen (str)) return no_match; while (*str != '\0' && state != STATE_MASK) { switch (state) { case STATE_START: if (*str == ':') { if (*(str + 1) != ':' && *(str + 1) != '\0') return no_match; colons--; state = STATE_COLON; } else { sp = str; state = STATE_ADDR; } continue; case STATE_COLON: colons++; if (*(str + 1) == '/') return no_match; else if (*(str + 1) == ':') state = STATE_DOUBLE; else { sp = str + 1; state = STATE_ADDR; } break; case STATE_DOUBLE: if (double_colon) return no_match; if (*(str + 1) == ':') return no_match; else { if (*(str + 1) != '\0' && *(str + 1) != '/') colons++; sp = str + 1; if (*(str + 1) == '/') state = STATE_SLASH; else state = STATE_ADDR; } double_colon++; nums += 1; break; case STATE_ADDR: if (*(str + 1) == ':' || *(str + 1) == '.' || *(str + 1) == '\0' || *(str + 1) == '/') { if (str - sp > 3) return no_match; for (; sp <= str; sp++) if (*sp == '/') return no_match; nums++; if (*(str + 1) == ':') state = STATE_COLON; else if (*(str + 1) == '.') state = STATE_DOT; else if (*(str + 1) == '/') state = STATE_SLASH; } break; case STATE_DOT: state = STATE_ADDR; break; case STATE_SLASH: if (*(str + 1) == '\0') return partly_match; state = STATE_MASK; break; default: break; } if (nums > 11) return no_match; if (colons > 7) return no_match; str++; } if (state < STATE_MASK) return partly_match; mask = strtol (str, &endptr, 10); if (*endptr != '\0') return no_match; if (mask < 0 || mask > 128) return no_match; /* I don't know why mask < 13 makes command match partly. Forgive me to make this comments. I Want to set static default route because of lack of function to originate default in ospf6d; sorry yasu if (mask < 13) return partly_match;*/ return exact_match;}#define DECIMAL_STRLEN_MAX 10intcmd_range_match (char *range, char *str){ char *p; char buf[DECIMAL_STRLEN_MAX + 1]; char *endptr = NULL; unsigned long min, max, val; if (str == NULL) return 1; val = strtoul (str, &endptr, 10); if (*endptr != '\0') return 0; range++; p = strchr (range, '-'); if (p == NULL) return 0; if (p - range > DECIMAL_STRLEN_MAX) return 0; strncpy (buf, range, p - range); buf[p - range] = '\0'; min = strtoul (buf, &endptr, 10); if (*endptr != '\0') return 0; range = p + 1; p = strchr (range, '>'); if (p == NULL) return 0; if (p - range > DECIMAL_STRLEN_MAX) return 0; strncpy (buf, range, p - range); buf[p - range] = '\0'; max = strtoul (buf, &endptr, 10); if (*endptr != '\0') return 0; if (val < min || val > max) return 0; return 1;}/* Make completion match and return match type flag. */enum match_typecmd_filter_by_completion (char *command, vector v, int index){ int i; char *str; struct cmd_element *cmd_element; enum match_type match_type; vector descvec; struct desc *desc; match_type = no_match; /* If command and cmd_element string does not match set NULL to vector */ for (i = 0; i < vector_max (v); i++) if ((cmd_element = vector_slot (v, i)) != NULL) { if (index >= vector_max (cmd_element->strvec)) vector_slot (v, i) = NULL; else { int j; int matched = 0; descvec = vector_slot (cmd_element->strvec, index); for (j = 0; j < vector_max (descvec); j++) { desc = vector_slot (descvec, j); str = desc->cmd; if (CMD_VARARG (str)) { if (match_type < vararg_match) match_type = vararg_match; matched++; } else if (CMD_RANGE (str)) { if (cmd_range_match (str, command)) { if (match_type < range_match) match_type = range_match; matched++; } } else if (CMD_IPV6 (str)) { if (cmd_ipv6_match (command)) { if (match_type < ipv6_match) match_type = ipv6_match; matched++; } } else if (CMD_IPV6_PREFIX (str)) { if (cmd_ipv6_prefix_match (command)) { if (match_type < ipv6_prefix_match) match_type = ipv6_prefix_match; matched++; } } else if (CMD_IPV4 (str)) { if (cmd_ipv4_match (command)) { if (match_type < ipv4_match) match_type = ipv4_match; matched++; } } else if (CMD_IPV4_PREFIX (str)) { if (cmd_ipv4_prefix_match (command)) { if (match_type < ipv4_prefix_match) match_type = ipv4_prefix_match; matched++; } } else /* Check is this point's argument optional ? */ if (CMD_OPTION (str) || CMD_VARIABLE (str)) { if (match_type < extend_match) match_type = extend_match; matched++; } else if (strncmp (command, str, strlen (command)) == 0) { if (strcmp (command, str) == 0) match_type = exact_match; else { if (match_type < partly_match) match_type = partly_match; } matched++; } } if (! matched) vector_slot (v, i) = NULL; } } return match_type;}/* Filter vector by command character with index. */enum match_typecmd_filter_by_string (char *command, vector v, int index){ int i; char *str; struct cmd_element *cmd_element; enum match_type match_type; vector descvec; struct desc *desc; match_type = no_match; /* If command and cmd_element string does not match set NULL to vector */ for (i = 0; i < vector_max (v); i++) if ((cmd_element = vector_slot (v, i)) != NULL) { /* If given index is bigger than max string vector of command, set NULL*/ if (index >= vector_max (cmd_element->strvec)) vector_slot (v, i) = NULL; else { int j; int matched = 0; descvec = vector_slot (cmd_element->strvec, index); for (j = 0; j < vector_max (descvec); j++) { desc = vector_slot (descvec, j); str = desc->cmd; if (CMD_VARARG (str)) { if (match_type < vararg_match) match_type = vararg_match; matched++; } else if (CMD_RANGE (str)) { if (cmd_range_match (str, command))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -