struct token *expect(struct token *token, int op, const char *where) { if (!match_op(token, op)) { static struct token bad_token; if (token != &bad_token) { bad_token.next = token; sparse_error(token->pos, "Expected %s %s", show_special(op), where); sparse_error(token->pos, "got %s", show_token(token)); } if (op == ';') return skip_to(token, op); return &bad_token; } return token->next; }
static int match_set(const char *re, int re_len, const char *s, struct regex_info *info) { int len = 0, result = -1, invert = re[0] == '^'; if (invert) re++, re_len--; while (len <= re_len && re[len] != ']' && result <= 0) { /* Support character range */ if (re[len] != '-' && re[len + 1] == '-' && re[len + 2] != ']' && re[len + 2] != '\0') { result = info->flags && IGNORE_CASE ? *s >= re[len] && *s <= re[len + 2] : tolower(*s) >= tolower(re[len]) && tolower(*s) <= tolower(re[len + 2]); len += 3; } else { result = match_op((unsigned char *) re + len, (unsigned char *) s, info); len += op_len(re + len); } } return (!invert && result > 0) || (invert && result <= 0) ? 1 : -1; }
int main(int argc, char **argv) { char usage_args[1024]; int mgmt_classes[3] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS }; ib_portid_t portid = { 0 }; char *err; op_fn_t *fn; const match_rec_t *r; int n; const struct ibdiag_opt opts[] = { {"combined", 'c', 0, NULL, "use Combined route address argument"}, {"node-name-map", 1, 1, "<file>", "node name map file"}, {"extended", 'x', 0, NULL, "use extended speeds"}, {0} }; const char *usage_examples[] = { "portinfo 3 1\t\t\t\t# portinfo by lid, with port modifier", "-G switchinfo 0x2C9000100D051 1\t# switchinfo by guid", "-D nodeinfo 0\t\t\t\t# nodeinfo by direct route", "-c nodeinfo 6 0,12\t\t\t# nodeinfo by combined route", NULL }; n = sprintf(usage_args, "<op> <dest dr_path|lid|guid> [op params]\n" "\nSupported ops (and aliases, case insensitive):\n"); for (r = match_tbl; r->name; r++) { n += snprintf(usage_args + n, sizeof(usage_args) - n, " %s (%s) <addr>%s\n", r->name, r->alias ? r->alias : "", r->opt_portnum ? " [<portnum>]" : ""); if (n >= sizeof(usage_args)) exit(-1); } ibdiag_process_opts(argc, argv, NULL, NULL, opts, process_opt, usage_args, usage_examples); argc -= optind; argv += optind; if (argc < 2) ibdiag_show_usage(); if (!(fn = match_op(match_tbl, argv[0]))) IBEXIT("operation '%s' not supported", argv[0]); srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3); if (!srcport) IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port); smp_mkey_set(srcport, ibd_mkey); node_name_map = open_node_name_map(node_name_map_file); if (ibd_dest_type != IB_DEST_DRSLID) { if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[1], ibd_dest_type, ibd_sm_id, srcport) < 0) IBEXIT("can't resolve destination port %s", argv[1]); if ((err = fn(&portid, argv + 2, argc - 2))) IBEXIT("operation %s: %s", argv[0], err); } else { char concat[64]; memset(concat, 0, 64); snprintf(concat, sizeof(concat), "%s %s", argv[1], argv[2]); if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, concat, ibd_dest_type, ibd_sm_id, srcport) < 0) IBEXIT("can't resolve destination port %s", concat); if ((err = fn(&portid, argv + 3, argc - 3))) IBEXIT("operation %s: %s", argv[0], err); } close_node_name_map(node_name_map); mad_rpc_close_port(srcport); exit(0); }
int main(int argc, char **argv) { char usage_args[1024]; int mgmt_classes[3] = { IB_SMI_CLASS, IB_SA_CLASS, IB_CC_CLASS }; ib_portid_t portid = { 0 }; char *err; op_fn_t *fn; const match_rec_t *r; int n; const struct ibdiag_opt opts[] = { {"cckey", 'c', 1, "<key>", "CC key"}, {0} }; const char *usage_examples[] = { "SwitchCongestionSetting 2 0x1F 0x1FFFFFFFFF 0x0 0xF 8 0 0:0 1\t# Configure Switch Congestion Settings", "CACongestionSetting 1 0 0x3 150 1 0 0\t\t# Configure CA Congestion Settings to SL 0 and SL 1", "CACongestionSetting 1 0 0x4 200 1 0 0\t\t# Configure CA Congestion Settings to SL 2", "CongestionControlTable 1 63 0 0:0 0:1 ...\t# Configure first block of Congestion Control Table", "CongestionControlTable 1 127 0 0:64 0:65 ...\t# Configure second block of Congestion Control Table", NULL }; n = sprintf(usage_args, "[-c key] <op> <lid|guid>\n" "\nWARNING -- You should understand what you are " "doing before using this tool. Misuse of this " "tool could result in a broken fabric.\n" "\nSupported ops (and aliases, case insensitive):\n"); for (r = match_tbl; r->name; r++) { n += snprintf(usage_args + n, sizeof(usage_args) - n, " %s (%s) <lid|guid>%s%s%s\n", r->name, r->alias ? r->alias : "", r->opt_portnum ? " <portnum>" : "", r->ops_extra ? " " : "", r->ops_extra ? r->ops_extra : ""); if (n >= sizeof(usage_args)) exit(-1); } ibdiag_process_opts(argc, argv, NULL, "DK", opts, process_opt, usage_args, usage_examples); argc -= optind; argv += optind; if (argc < 2) ibdiag_show_usage(); if (!(fn = match_op(match_tbl, argv[0]))) IBEXIT("operation '%s' not supported", argv[0]); srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3); if (!srcport) IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port); smp_mkey_set(srcport, ibd_mkey); if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[1], ibd_dest_type, ibd_sm_id, srcport) < 0) IBEXIT("can't resolve destination %s", argv[1]); if ((err = fn(&portid, argv + 2, argc - 2))) IBEXIT("operation %s: %s", argv[0], err); mad_rpc_close_port(srcport); exit(0); }
static int bar(const char *re, int re_len, const char *s, int s_len, struct regex_info *info, int bi) { /* i is offset in re, j is offset in s, bi is brackets index */ int i, j, n, step; for (i = j = 0; i < re_len && j <= s_len; i += step) { /* Handle quantifiers. Get the length of the chunk. */ step = re[i] == '(' ? info->brackets[bi + 1].len + 2 : get_op_len(re + i, re_len - i); DBG(("%s [%.*s] [%.*s] re_len=%d step=%d i=%d j=%d\n", __func__, re_len - i, re + i, s_len - j, s + j, re_len, step, i, j)); FAIL_IF(is_quantifier(&re[i]), SLRE_UNEXPECTED_QUANTIFIER); FAIL_IF(step <= 0, SLRE_INVALID_CHARACTER_SET); if (i + step < re_len && is_quantifier(re + i + step)) { DBG(("QUANTIFIER: [%.*s]%c [%.*s]\n", step, re + i, re[i + step], s_len - j, s + j)); if (re[i + step] == '?') { int result = bar(re + i, step, s + j, s_len - j, info, bi); j += result > 0 ? result : 0; i++; } else if (re[i + step] == '+' || re[i + step] == '*') { int j2 = j, nj = j, n1, n2 = -1, ni, non_greedy = 0; /* Points to the regexp code after the quantifier */ ni = i + step + 1; if (ni < re_len && re[ni] == '?') { non_greedy = 1; ni++; } do { if ((n1 = bar(re + i, step, s + j2, s_len - j2, info, bi)) > 0) { j2 += n1; } if (re[i + step] == '+' && n1 < 0) break; if (ni >= re_len) { /* After quantifier, there is nothing */ nj = j2; } else if ((n2 = bar(re + ni, re_len - ni, s + j2, s_len - j2, info, bi)) >= 0) { /* Regex after quantifier matched */ nj = j2 + n2; } if (nj > j && non_greedy) break; } while (n1 > 0); if (n1 < 0 && re[i + step] == '*' && (n2 = bar(re + ni, re_len - ni, s + j, s_len - j, info, bi)) > 0) { nj = j + n2; } DBG(("STAR/PLUS END: %d %d %d %d %d\n", j, nj, re_len - ni, n1, n2)); FAIL_IF(re[i + step] == '+' && nj == j, SLRE_NO_MATCH); /* If while loop body above was not executed for the * quantifier, */ /* make sure the rest of the regex matches */ FAIL_IF(nj == j && ni < re_len && n2 < 0, SLRE_NO_MATCH); /* Returning here cause we've matched the rest of RE already */ return nj; } continue; } if (re[i] == '[') { n = match_set(re + i + 1, re_len - (i + 2), s + j, info); DBG(("SET %.*s [%.*s] -> %d\n", step, re + i, s_len - j, s + j, n)); FAIL_IF(n <= 0, SLRE_NO_MATCH); j += n; } else if (re[i] == '(') { n = SLRE_NO_MATCH; bi++; FAIL_IF(bi >= info->num_brackets, SLRE_INTERNAL_ERROR); DBG(("CAPTURING [%.*s] [%.*s] [%s]\n", step, re + i, s_len - j, s + j, re + i + step)); if (re_len - (i + step) <= 0) { /* Nothing follows brackets */ n = doh(s + j, s_len - j, info, bi); } else { int j2; for (j2 = 0; j2 <= s_len - j; j2++) { if ((n = doh(s + j, s_len - (j + j2), info, bi)) >= 0 && bar(re + i + step, re_len - (i + step), s + j + n, s_len - (j + n), info, bi) >= 0) break; } } DBG(("CAPTURED [%.*s] [%.*s]:%d\n", step, re + i, s_len - j, s + j, n)); FAIL_IF(n < 0, n); if (info->caps != NULL) { info->caps[bi - 1].ptr = s + j; info->caps[bi - 1].len = n; } j += n; } else if (re[i] == '^') { FAIL_IF(j != 0, SLRE_NO_MATCH); } else if (re[i] == '$') { FAIL_IF(j != s_len, SLRE_NO_MATCH); } else { FAIL_IF(j >= s_len, SLRE_NO_MATCH); n = match_op((unsigned char *) (re + i), (unsigned char *) (s + j), info); FAIL_IF(n <= 0, n); j += n; } } return j; }
struct token *skip_to(struct token *token, int op) { while (!match_op(token, op) && !eof_token(token)) token = token->next; return token; }
static int bar(const char *re, int re_len, const char *s, int s_len, struct slre_cap *caps, struct regex_info *info, int bi) { /* i is offset in re, j is offset in s, bi is brackets index */ int i, j, n, step; DBG(("%s [%.*s] [%.*s]\n", __func__, re_len, re, s_len, s)); for (i = j = 0; i < re_len && j < s_len; i += step) { /* Handle quantifiers. Get the length of the chunk. */ step = re[i] == '(' ? info->brackets[bi + 1].len + 2 : get_op_len(re + i, re_len - i); DBG(("%s [%.*s] [%.*s] re_len=%d step=%d i=%d j=%d\n", __func__, re_len - i, re + i, s_len - j, s + j, re_len, step, i, j)); FAIL_IF(is_quantifier(&re[i]), static_error_unexpected_quantifier); FAIL_IF(step <= 0, static_error_invalid_set); if (i + step < re_len && is_quantifier(re + i + step)) { DBG(("QUANTIFIER: [%.*s] %c\n", step, re + i, re[i + step])); if (re[i + step] == '?') { j += bar(re + i, step, s + j, s_len - j, caps, info, bi); i++; continue; } else if (re[i + step] == '+' || re[i + step] == '*') { int j2 = j, nj = 0, n1, n2, ni, non_greedy = 0; /* Points to the regexp code after the quantifier */ ni = i + step + 1; if (ni < re_len && re[ni] == '?') { non_greedy = 1; ni++; } while ((n1 = bar(re + i, step, s + j2, s_len - j2, caps, info, bi)) > 0) { if (ni >= re_len) { /* After quantifier, there is nothing */ nj = j2 + n1; } else if ((n2 = bar(re + ni, re_len - ni, s + j2 + n1, s_len - (j2 + n1), caps, info, bi)) > 0) { nj = j2 + n1 + n2; } if (nj > 0 && non_greedy) break; j2 += n1; } FAIL_IF(re[i + step] == '+' && nj == 0, static_error_no_match); return nj; } } if (re[i] == '[') { n = match_set(re + i + 1, re_len - (i + 2), s + j, info); DBG(("SET %.*s [%.*s] -> %d\n", step, re + i, s_len - j, s + j, n)); FAIL_IF(n <= 0, static_error_no_match); j += n; } else if (re[i] == '(') { bi++; FAIL_IF(bi >= info->num_brackets, static_error_internal); DBG(("CAPTURING [%.*s] [%.*s]\n", step, re + i, s_len - j, s + j)); n = doh(s + j, s_len - j, caps, info, bi); DBG(("CAPTURED [%.*s] [%.*s]:%d\n", step, re + i, s_len - j, s + j, n)); FAIL_IF(n <= 0, info->error_msg); if (caps != NULL) { caps[bi - 1].ptr = s + j; caps[bi - 1].len = n; } j += n; } else if (re[i] == '^') { FAIL_IF(j != 0, static_error_no_match); } else { n = match_op((unsigned char *) (re + i), (unsigned char *) (s + j), info); FAIL_IF(n <= 0, info->error_msg); j += n; } } /* * Process $ anchor here. If we've reached the end of the string, * but did not exhaust regexp yet, this is no match. */ FAIL_IF(i < re_len && !(re[i] == '$' && i + 1 == re_len), static_error_no_match); return j; }
int main(int argc, char **argv) { int mgmt_classes[3] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS}; ib_portid_t portid = {0}; ib_portid_t *sm_id = 0, sm_portid = {0}; extern int ibdebug; int timeout = 0, udebug = 0; char *ca = 0; int ca_port = 0; char *err; op_fn_t *fn; static char const str_opts[] = "C:P:t:s:devDcGVhu"; static const struct option long_opts[] = { { "C", 1, 0, 'C'}, { "P", 1, 0, 'P'}, { "debug", 0, 0, 'd'}, { "err_show", 0, 0, 'e'}, { "verbose", 0, 0, 'v'}, { "Direct", 0, 0, 'D'}, { "combined", 0, 0, 'c'}, { "Guid", 0, 0, 'G'}, { "smlid", 1, 0, 's'}, { "timeout", 1, 0, 't'}, { "node-name-map", 1, 0, 1}, { "Version", 0, 0, 'V'}, { "help", 0, 0, 'h'}, { "usage", 0, 0, 'u'}, { } }; argv0 = argv[0]; while (1) { int ch = getopt_long(argc, argv, str_opts, long_opts, NULL); if ( ch == -1 ) break; switch(ch) { case 1: node_name_map_file = strdup(optarg); break; case 'd': ibdebug++; madrpc_show_errors(1); umad_debug(udebug); udebug++; break; case 'e': madrpc_show_errors(1); break; case 'D': dest_type = IB_DEST_DRPATH; break; case 'c': dest_type = IB_DEST_DRSLID; break; case 'G': dest_type = IB_DEST_GUID; break; case 'C': ca = optarg; break; case 'P': ca_port = strtoul(optarg, 0, 0); break; case 's': if (ib_resolve_portid_str(&sm_portid, optarg, IB_DEST_LID, 0) < 0) IBERROR("can't resolve SM destination port %s", optarg); sm_id = &sm_portid; break; case 't': timeout = strtoul(optarg, 0, 0); madrpc_set_timeout(timeout); break; case 'v': verbose++; break; case 'V': fprintf(stderr, "%s %s\n", argv0, get_build_version() ); exit(-1); default: usage(); break; } } argc -= optind; argv += optind; if (argc < 2) usage(); if (!(fn = match_op(argv[0]))) IBERROR("operation '%s' not supported", argv[0]); madrpc_init(ca, ca_port, mgmt_classes, 3); node_name_map = open_node_name_map(node_name_map_file); if (dest_type != IB_DEST_DRSLID) { if (ib_resolve_portid_str(&portid, argv[1], dest_type, sm_id) < 0) IBERROR("can't resolve destination port %s", argv[1]); if ((err = fn(&portid, argv+2, argc-2))) IBERROR("operation %s: %s", argv[0], err); } else { char concat[64]; memset(concat, 0, 64); snprintf(concat, sizeof(concat), "%s %s", argv[1], argv[2]); if (ib_resolve_portid_str(&portid, concat, dest_type, sm_id) < 0) IBERROR("can't resolve destination port %s", concat); if ((err = fn(&portid, argv+3, argc-3))) IBERROR("operation %s: %s", argv[0], err); } close_node_name_map(node_name_map); exit(0); }