/* * Determine if string 'value' matches 'nvp' value. The 'value' string is * converted, depending on the type of 'nvp', prior to match. For numeric * types, a radix independent sscanf conversion of 'value' is used. If 'nvp' * is an array type, 'ai' is the index into the array against which we are * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass * in a regex_t compilation of value in 'value_regex' to trigger regular * expression string match instead of simple strcmp(). * * Return 1 on match, 0 on no-match, and -1 on error. If the error is * related to value syntax error and 'ep' is non-NULL, *ep will point into * the 'value' string at the location where the error exists. * * NOTE: It may be possible to move the non-regex_t version of this into * common code used by library/kernel/boot. */ int nvpair_value_match_regex(nvpair_t *nvp, int ai, char *value, regex_t *value_regex, char **ep) { char *evalue; uint_t a_len; int sr; if (ep) *ep = NULL; if ((nvp == NULL) || (value == NULL)) return (-1); /* error fail match - invalid args */ /* make sure array and index combination make sense */ if ((nvpair_type_is_array(nvp) && (ai < 0)) || (!nvpair_type_is_array(nvp) && (ai >= 0))) return (-1); /* error fail match - bad index */ /* non-string values should be single 'chunk' */ if ((nvpair_type(nvp) != DATA_TYPE_STRING) && (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) { value += strspn(value, " \t"); evalue = value + strcspn(value, " \t"); if (*evalue) { if (ep) *ep = evalue; return (-1); /* error fail match - syntax */ } } sr = EOF; switch (nvpair_type(nvp)) { case DATA_TYPE_STRING: { char *val; /* check string value for match */ if (nvpair_value_string(nvp, &val) == 0) { if (value_regex) { if (regexec(value_regex, val, (size_t)0, NULL, 0) == 0) return (1); /* match */ } else { if (strcmp(value, val) == 0) return (1); /* match */ } } break; } case DATA_TYPE_STRING_ARRAY: { char **val_array; /* check indexed string value of array for match */ if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) && (ai < a_len)) { if (value_regex) { if (regexec(value_regex, val_array[ai], (size_t)0, NULL, 0) == 0) return (1); } else { if (strcmp(value, val_array[ai]) == 0) return (1); } } break; } case DATA_TYPE_BYTE: { uchar_t val, val_arg; /* scanf uchar_t from value and check for match */ sr = sscanf(value, "%c", &val_arg); if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_BYTE_ARRAY: { uchar_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%c", &val_arg); if ((sr == 1) && (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_INT8: { int8_t val, val_arg; /* scanf int8_t from value and check for match */ sr = sscanf(value, "%"SCNi8, &val_arg); if ((sr == 1) && (nvpair_value_int8(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_INT8_ARRAY: { int8_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi8, &val_arg); if ((sr == 1) && (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_UINT8: { uint8_t val, val_arg; /* scanf uint8_t from value and check for match */ sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint8(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_UINT8_ARRAY: { uint8_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_INT16: { int16_t val, val_arg; /* scanf int16_t from value and check for match */ sr = sscanf(value, "%"SCNi16, &val_arg); if ((sr == 1) && (nvpair_value_int16(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_INT16_ARRAY: { int16_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi16, &val_arg); if ((sr == 1) && (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_UINT16: { uint16_t val, val_arg; /* scanf uint16_t from value and check for match */ sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint16(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_UINT16_ARRAY: { uint16_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_INT32: { int32_t val, val_arg; /* scanf int32_t from value and check for match */ sr = sscanf(value, "%"SCNi32, &val_arg); if ((sr == 1) && (nvpair_value_int32(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_INT32_ARRAY: { int32_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi32, &val_arg); if ((sr == 1) && (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_UINT32: { uint32_t val, val_arg; /* scanf uint32_t from value and check for match */ sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint32(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_UINT32_ARRAY: { uint32_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_INT64: { int64_t val, val_arg; /* scanf int64_t from value and check for match */ sr = sscanf(value, "%"SCNi64, &val_arg); if ((sr == 1) && (nvpair_value_int64(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_INT64_ARRAY: { int64_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi64, &val_arg); if ((sr == 1) && (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_UINT64: { uint64_t val_arg, val; /* scanf uint64_t from value and check for match */ sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint64(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_UINT64_ARRAY: { uint64_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg); if ((sr == 1) && (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_BOOLEAN_VALUE: { boolean_t val, val_arg; /* scanf boolean_t from value and check for match */ sr = sscanf(value, "%"SCNi32, (int *) &val_arg); if ((sr == 1) && (nvpair_value_boolean_value(nvp, &val) == 0) && (val == val_arg)) return (1); break; } case DATA_TYPE_BOOLEAN_ARRAY: { boolean_t *val_array, val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi32, (int *) &val_arg); if ((sr == 1) && (nvpair_value_boolean_array(nvp, &val_array, &a_len) == 0) && (ai < a_len) && (val_array[ai] == val_arg)) return (1); break; } case DATA_TYPE_HRTIME: case DATA_TYPE_NVLIST: case DATA_TYPE_NVLIST_ARRAY: case DATA_TYPE_BOOLEAN: case DATA_TYPE_DOUBLE: case DATA_TYPE_UNKNOWN: default: /* * unknown/unsupported data type */ return (-1); /* error fail match */ } /* * check to see if sscanf failed conversion, return approximate * pointer to problem */ if (sr != 1) { if (ep) *ep = value; return (-1); /* error fail match - syntax */ } return (0); /* fail match */ }
/* * Dump a JSON-formatted representation of an nvlist to the provided FILE *. * This routine does not output any new-lines or additional whitespace other * than that contained in strings, nor does it call fflush(3C). */ int bunyan_nvlist_print_json(FILE *fp, nvlist_t *nvl) { nvpair_t *curr; boolean_t first = B_TRUE; FPRINTF(fp, "{"); for (curr = nvlist_next_nvpair(nvl, NULL); curr; curr = nvlist_next_nvpair(nvl, curr)) { data_type_t type = nvpair_type(curr); if (!first) FPRINTF(fp, ","); else first = B_FALSE; if (bunyan_nvlist_print_json_string(fp, nvpair_name(curr)) == -1) { return (-1); } FPRINTF(fp, ":"); switch (type) { case DATA_TYPE_STRING: { char *string = fnvpair_value_string(curr); if (bunyan_nvlist_print_json_string(fp, string) == -1) return (-1); break; } case DATA_TYPE_BOOLEAN: { FPRINTF(fp, "true"); break; } case DATA_TYPE_BOOLEAN_VALUE: { FPRINTF(fp, "%s", fnvpair_value_boolean_value(curr) == B_TRUE ? "true" : "false"); break; } case DATA_TYPE_BYTE: { FPRINTF(fp, "%hhu", fnvpair_value_byte(curr)); break; } case DATA_TYPE_INT8: { FPRINTF(fp, "%hhd", fnvpair_value_int8(curr)); break; } case DATA_TYPE_UINT8: { FPRINTF(fp, "%hhu", fnvpair_value_uint8_t(curr)); break; } case DATA_TYPE_INT16: { FPRINTF(fp, "%hd", fnvpair_value_int16(curr)); break; } case DATA_TYPE_UINT16: { FPRINTF(fp, "%hu", fnvpair_value_uint16(curr)); break; } case DATA_TYPE_INT32: { FPRINTF(fp, "%d", fnvpair_value_int32(curr)); break; } case DATA_TYPE_UINT32: { FPRINTF(fp, "%u", fnvpair_value_uint32(curr)); break; } case DATA_TYPE_INT64: { FPRINTF(fp, "%lld", (long long)fnvpair_value_int64(curr)); break; } case DATA_TYPE_UINT64: { FPRINTF(fp, "%llu", (unsigned long long)fnvpair_value_uint64(curr)); break; } case DATA_TYPE_HRTIME: { hrtime_t val; VERIFY0(nvpair_value_hrtime(curr, &val)); FPRINTF(fp, "%llu", (unsigned long long)val); break; } case DATA_TYPE_DOUBLE: { double val; VERIFY0(nvpair_value_double(curr, &val)); FPRINTF(fp, "%f", val); break; } case DATA_TYPE_NVLIST: { if (nvlist_print_json(fp, fnvpair_value_nvlist(curr)) == -1) return (-1); break; } case DATA_TYPE_STRING_ARRAY: { char **val; uint_t valsz, i; VERIFY0(nvpair_value_string_array(curr, &val, &valsz)); FPRINTF(fp, "["); for (i = 0; i < valsz; i++) { if (i > 0) FPRINTF(fp, ","); if (bunyan_nvlist_print_json_string(fp, val[i]) == -1) { return (-1); } } FPRINTF(fp, "]"); break; } case DATA_TYPE_NVLIST_ARRAY: { nvlist_t **val; uint_t valsz, i; VERIFY0(nvpair_value_nvlist_array(curr, &val, &valsz)); FPRINTF(fp, "["); for (i = 0; i < valsz; i++) { if (i > 0) FPRINTF(fp, ","); if (nvlist_print_json(fp, val[i]) == -1) return (-1); } FPRINTF(fp, "]"); break; } case DATA_TYPE_BOOLEAN_ARRAY: { boolean_t *val; uint_t valsz, i; VERIFY0(nvpair_value_boolean_array(curr, &val, &valsz)); FPRINTF(fp, "["); for (i = 0; i < valsz; i++) { if (i > 0) FPRINTF(fp, ","); FPRINTF(fp, val[i] == B_TRUE ? "true" : "false"); } FPRINTF(fp, "]"); break; } case DATA_TYPE_BYTE_ARRAY: { uchar_t *val; uint_t valsz, i; VERIFY0(nvpair_value_byte_array(curr, &val, &valsz)); FPRINTF(fp, "["); for (i = 0; i < valsz; i++) { if (i > 0) FPRINTF(fp, ","); FPRINTF(fp, "%hhu", val[i]); } FPRINTF(fp, "]"); break; } case DATA_TYPE_UINT8_ARRAY: { uint8_t *val; uint_t valsz, i; VERIFY0(nvpair_value_uint8_array(curr, &val, &valsz)); FPRINTF(fp, "["); for (i = 0; i < valsz; i++) { if (i > 0) FPRINTF(fp, ","); FPRINTF(fp, "%hhu", val[i]); } FPRINTF(fp, "]"); break; } case DATA_TYPE_INT8_ARRAY: { int8_t *val; uint_t valsz, i; VERIFY0(nvpair_value_int8_array(curr, &val, &valsz)); FPRINTF(fp, "["); for (i = 0; i < valsz; i++) { if (i > 0) FPRINTF(fp, ","); FPRINTF(fp, "%hd", val[i]); } FPRINTF(fp, "]"); break; } case DATA_TYPE_UINT16_ARRAY: { uint16_t *val; uint_t valsz, i; VERIFY0(nvpair_value_uint16_array(curr, &val, &valsz)); FPRINTF(fp, "["); for (i = 0; i < valsz; i++) { if (i > 0) FPRINTF(fp, ","); FPRINTF(fp, "%hu", val[i]); } FPRINTF(fp, "]"); break; } case DATA_TYPE_INT16_ARRAY: { int16_t *val; uint_t valsz, i; VERIFY0(nvpair_value_int16_array(curr, &val, &valsz)); FPRINTF(fp, "["); for (i = 0; i < valsz; i++) { if (i > 0) FPRINTF(fp, ","); FPRINTF(fp, "%hhd", val[i]); } FPRINTF(fp, "]"); break; } case DATA_TYPE_UINT32_ARRAY: { uint32_t *val; uint_t valsz, i; VERIFY0(nvpair_value_uint32_array(curr, &val, &valsz)); FPRINTF(fp, "["); for (i = 0; i < valsz; i++) { if (i > 0) FPRINTF(fp, ","); FPRINTF(fp, "%u", val[i]); } FPRINTF(fp, "]"); break; } case DATA_TYPE_INT32_ARRAY: { int32_t *val; uint_t valsz, i; VERIFY0(nvpair_value_int32_array(curr, &val, &valsz)); FPRINTF(fp, "["); for (i = 0; i < valsz; i++) { if (i > 0) FPRINTF(fp, ","); FPRINTF(fp, "%d", val[i]); } FPRINTF(fp, "]"); break; } case DATA_TYPE_UINT64_ARRAY: { uint64_t *val; uint_t valsz, i; VERIFY0(nvpair_value_uint64_array(curr, &val, &valsz)); FPRINTF(fp, "["); for (i = 0; i < valsz; i++) { if (i > 0) FPRINTF(fp, ","); FPRINTF(fp, "%llu", (unsigned long long)val[i]); } FPRINTF(fp, "]"); break; } case DATA_TYPE_INT64_ARRAY: { int64_t *val; uint_t valsz, i; VERIFY0(nvpair_value_int64_array(curr, &val, &valsz)); FPRINTF(fp, "["); for (i = 0; i < valsz; i++) { if (i > 0) FPRINTF(fp, ","); FPRINTF(fp, "%lld", (long long)val[i]); } FPRINTF(fp, "]"); break; } case DATA_TYPE_UNKNOWN: return (-1); } } FPRINTF(fp, "}"); return (0); }