Home | History | Annotate | Line # | Download | only in libnvpair
libnvpair.c revision 1.1.1.2.6.1
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #include <unistd.h>
     27 #include <strings.h>
     28 #include <libintl.h>
     29 #include <sys/types.h>
     30 #include <sys/inttypes.h>
     31 #include "libnvpair.h"
     32 
     33 /*
     34  * libnvpair - A tools library for manipulating <name, value> pairs.
     35  *
     36  *	This library provides routines packing an unpacking nv pairs
     37  *	for transporting data across process boundaries, transporting
     38  *	between kernel and userland, and possibly saving onto disk files.
     39  */
     40 
     41 static void
     42 indent(FILE *fp, int depth)
     43 {
     44 	while (depth-- > 0)
     45 		(void) fprintf(fp, "\t");
     46 }
     47 
     48 /*
     49  * nvlist_print - Prints elements in an event buffer
     50  */
     51 static
     52 void
     53 nvlist_print_with_indent(FILE *fp, nvlist_t *nvl, int depth)
     54 {
     55 	int i;
     56 	char *name;
     57 	uint_t nelem;
     58 	nvpair_t *nvp;
     59 
     60 	if (nvl == NULL)
     61 		return;
     62 
     63 	indent(fp, depth);
     64 	(void) fprintf(fp, "nvlist version: %d\n", NVL_VERSION(nvl));
     65 
     66 	nvp = nvlist_next_nvpair(nvl, NULL);
     67 
     68 	while (nvp) {
     69 		data_type_t type = nvpair_type(nvp);
     70 
     71 		indent(fp, depth);
     72 		name = nvpair_name(nvp);
     73 		(void) fprintf(fp, "\t%s =", name);
     74 		nelem = 0;
     75 		switch (type) {
     76 		case DATA_TYPE_BOOLEAN: {
     77 			(void) fprintf(fp, " 1");
     78 			break;
     79 		}
     80 		case DATA_TYPE_BOOLEAN_VALUE: {
     81 			boolean_t val;
     82 			(void) nvpair_value_boolean_value(nvp, &val);
     83 			(void) fprintf(fp, " %d", val);
     84 			break;
     85 		}
     86 		case DATA_TYPE_BYTE: {
     87 			uchar_t val;
     88 			(void) nvpair_value_byte(nvp, &val);
     89 			(void) fprintf(fp, " 0x%2.2x", val);
     90 			break;
     91 		}
     92 		case DATA_TYPE_INT8: {
     93 			int8_t val;
     94 			(void) nvpair_value_int8(nvp, &val);
     95 			(void) fprintf(fp, " %d", val);
     96 			break;
     97 		}
     98 		case DATA_TYPE_UINT8: {
     99 			uint8_t val;
    100 			(void) nvpair_value_uint8(nvp, &val);
    101 			(void) fprintf(fp, " 0x%x", val);
    102 			break;
    103 		}
    104 		case DATA_TYPE_INT16: {
    105 			int16_t val;
    106 			(void) nvpair_value_int16(nvp, &val);
    107 			(void) fprintf(fp, " %d", val);
    108 			break;
    109 		}
    110 		case DATA_TYPE_UINT16: {
    111 			uint16_t val;
    112 			(void) nvpair_value_uint16(nvp, &val);
    113 			(void) fprintf(fp, " 0x%x", val);
    114 			break;
    115 		}
    116 		case DATA_TYPE_INT32: {
    117 			int32_t val;
    118 			(void) nvpair_value_int32(nvp, &val);
    119 			(void) fprintf(fp, " %d", val);
    120 			break;
    121 		}
    122 		case DATA_TYPE_UINT32: {
    123 			uint32_t val;
    124 			(void) nvpair_value_uint32(nvp, &val);
    125 			(void) fprintf(fp, " 0x%x", val);
    126 			break;
    127 		}
    128 		case DATA_TYPE_INT64: {
    129 			int64_t val;
    130 			(void) nvpair_value_int64(nvp, &val);
    131 			(void) fprintf(fp, " %lld", (longlong_t)val);
    132 			break;
    133 		}
    134 		case DATA_TYPE_UINT64: {
    135 			uint64_t val;
    136 			(void) nvpair_value_uint64(nvp, &val);
    137 			(void) fprintf(fp, " 0x%llx", (u_longlong_t)val);
    138 			break;
    139 		}
    140 		case DATA_TYPE_DOUBLE: {
    141 			double val;
    142 			(void) nvpair_value_double(nvp, &val);
    143 			(void) fprintf(fp, " 0x%f", val);
    144 			break;
    145 		}
    146 		case DATA_TYPE_STRING: {
    147 			char *val;
    148 			(void) nvpair_value_string(nvp, &val);
    149 			(void) fprintf(fp, " %s", val);
    150 			break;
    151 		}
    152 		case DATA_TYPE_BOOLEAN_ARRAY: {
    153 			boolean_t *val;
    154 			(void) nvpair_value_boolean_array(nvp, &val, &nelem);
    155 			for (i = 0; i < nelem; i++)
    156 				(void) fprintf(fp, " %d", val[i]);
    157 			break;
    158 		}
    159 		case DATA_TYPE_BYTE_ARRAY: {
    160 			uchar_t *val;
    161 			(void) nvpair_value_byte_array(nvp, &val, &nelem);
    162 			for (i = 0; i < nelem; i++)
    163 				(void) fprintf(fp, " 0x%2.2x", val[i]);
    164 			break;
    165 		}
    166 		case DATA_TYPE_INT8_ARRAY: {
    167 			int8_t *val;
    168 			(void) nvpair_value_int8_array(nvp, &val, &nelem);
    169 			for (i = 0; i < nelem; i++)
    170 				(void) fprintf(fp, " %d", val[i]);
    171 			break;
    172 		}
    173 		case DATA_TYPE_UINT8_ARRAY: {
    174 			uint8_t *val;
    175 			(void) nvpair_value_uint8_array(nvp, &val, &nelem);
    176 			for (i = 0; i < nelem; i++)
    177 				(void) fprintf(fp, " 0x%x", val[i]);
    178 			break;
    179 		}
    180 		case DATA_TYPE_INT16_ARRAY: {
    181 			int16_t *val;
    182 			(void) nvpair_value_int16_array(nvp, &val, &nelem);
    183 			for (i = 0; i < nelem; i++)
    184 				(void) fprintf(fp, " %d", val[i]);
    185 			break;
    186 		}
    187 		case DATA_TYPE_UINT16_ARRAY: {
    188 			uint16_t *val;
    189 			(void) nvpair_value_uint16_array(nvp, &val, &nelem);
    190 			for (i = 0; i < nelem; i++)
    191 				(void) fprintf(fp, " 0x%x", val[i]);
    192 			break;
    193 		}
    194 		case DATA_TYPE_INT32_ARRAY: {
    195 			int32_t *val;
    196 			(void) nvpair_value_int32_array(nvp, &val, &nelem);
    197 			for (i = 0; i < nelem; i++)
    198 				(void) fprintf(fp, " %d", val[i]);
    199 			break;
    200 		}
    201 		case DATA_TYPE_UINT32_ARRAY: {
    202 			uint32_t *val;
    203 			(void) nvpair_value_uint32_array(nvp, &val, &nelem);
    204 			for (i = 0; i < nelem; i++)
    205 				(void) fprintf(fp, " 0x%x", val[i]);
    206 			break;
    207 		}
    208 		case DATA_TYPE_INT64_ARRAY: {
    209 			int64_t *val;
    210 			(void) nvpair_value_int64_array(nvp, &val, &nelem);
    211 			for (i = 0; i < nelem; i++)
    212 				(void) fprintf(fp, " %lld", (longlong_t)val[i]);
    213 			break;
    214 		}
    215 		case DATA_TYPE_UINT64_ARRAY: {
    216 			uint64_t *val;
    217 			(void) nvpair_value_uint64_array(nvp, &val, &nelem);
    218 			for (i = 0; i < nelem; i++)
    219 				(void) fprintf(fp, " 0x%llx",
    220 				    (u_longlong_t)val[i]);
    221 			break;
    222 		}
    223 		case DATA_TYPE_STRING_ARRAY: {
    224 			char **val;
    225 			(void) nvpair_value_string_array(nvp, &val, &nelem);
    226 			for (i = 0; i < nelem; i++)
    227 				(void) fprintf(fp, " %s", val[i]);
    228 			break;
    229 		}
    230 		case DATA_TYPE_HRTIME: {
    231 			hrtime_t val;
    232 			(void) nvpair_value_hrtime(nvp, &val);
    233 			(void) fprintf(fp, " 0x%llx", val);
    234 			break;
    235 		}
    236 		case DATA_TYPE_NVLIST: {
    237 			nvlist_t *val;
    238 			(void) nvpair_value_nvlist(nvp, &val);
    239 			(void) fprintf(fp, " (embedded nvlist)\n");
    240 			nvlist_print_with_indent(fp, val, depth + 1);
    241 			indent(fp, depth + 1);
    242 			(void) fprintf(fp, "(end %s)\n", name);
    243 			break;
    244 		}
    245 		case DATA_TYPE_NVLIST_ARRAY: {
    246 			nvlist_t **val;
    247 			(void) nvpair_value_nvlist_array(nvp, &val, &nelem);
    248 			(void) fprintf(fp, " (array of embedded nvlists)\n");
    249 			for (i = 0; i < nelem; i++) {
    250 				indent(fp, depth + 1);
    251 				(void) fprintf(fp,
    252 				    "(start %s[%d])\n", name, i);
    253 				nvlist_print_with_indent(fp, val[i], depth + 1);
    254 				indent(fp, depth + 1);
    255 				(void) fprintf(fp, "(end %s[%d])\n", name, i);
    256 			}
    257 			break;
    258 		}
    259 		default:
    260 			(void) fprintf(fp, " unknown data type (%d)", type);
    261 			break;
    262 		}
    263 		(void) fprintf(fp, "\n");
    264 		nvp = nvlist_next_nvpair(nvl, nvp);
    265 	}
    266 }
    267 
    268 void
    269 nvlist_print(FILE *fp, nvlist_t *nvl)
    270 {
    271 	nvlist_print_with_indent(fp, nvl, 0);
    272 }
    273 
    274 
    275 #define	NVP(elem, type, vtype, ptype, format) { \
    276 	vtype	value; \
    277 \
    278 	(void) nvpair_value_##type(elem, &value); \
    279 	(void) printf("%*s%s: " format "\n", indent, "", \
    280 	    nvpair_name(elem), (ptype)value); \
    281 }
    282 
    283 #define	NVPA(elem, type, vtype, ptype, format) { \
    284 	uint_t	i, count; \
    285 	vtype	*value;  \
    286 \
    287 	(void) nvpair_value_##type(elem, &value, &count); \
    288 	for (i = 0; i < count; i++) { \
    289 		(void) printf("%*s%s[%d]: " format "\n", indent, "", \
    290 		    nvpair_name(elem), i, (ptype)value[i]); \
    291 	} \
    292 }
    293 
    294 /*
    295  * Similar to nvlist_print() but handles arrays slightly differently.
    296  */
    297 void
    298 dump_nvlist(nvlist_t *list, int indent)
    299 {
    300 	nvpair_t	*elem = NULL;
    301 	boolean_t	bool_value;
    302 	nvlist_t	*nvlist_value;
    303 	nvlist_t	**nvlist_array_value;
    304 	uint_t		i, count;
    305 
    306 	if (list == NULL) {
    307 		return;
    308 	}
    309 
    310 	while ((elem = nvlist_next_nvpair(list, elem)) != NULL) {
    311 		switch (nvpair_type(elem)) {
    312 		case DATA_TYPE_BOOLEAN_VALUE:
    313 			(void) nvpair_value_boolean_value(elem, &bool_value);
    314 			(void) printf("%*s%s: %s\n", indent, "",
    315 			    nvpair_name(elem), bool_value ? "true" : "false");
    316 			break;
    317 
    318 		case DATA_TYPE_BYTE:
    319 			NVP(elem, byte, uchar_t, int, "%u");
    320 			break;
    321 
    322 		case DATA_TYPE_INT8:
    323 			NVP(elem, int8, int8_t, int, "%d");
    324 			break;
    325 
    326 		case DATA_TYPE_UINT8:
    327 			NVP(elem, uint8, uint8_t, int, "%u");
    328 			break;
    329 
    330 		case DATA_TYPE_INT16:
    331 			NVP(elem, int16, int16_t, int, "%d");
    332 			break;
    333 
    334 		case DATA_TYPE_UINT16:
    335 			NVP(elem, uint16, uint16_t, int, "%u");
    336 			break;
    337 
    338 		case DATA_TYPE_INT32:
    339 			NVP(elem, int32, int32_t, long, "%ld");
    340 			break;
    341 
    342 		case DATA_TYPE_UINT32:
    343 			NVP(elem, uint32, uint32_t, ulong_t, "%lu");
    344 			break;
    345 
    346 		case DATA_TYPE_INT64:
    347 			NVP(elem, int64, int64_t, longlong_t, "%lld");
    348 			break;
    349 
    350 		case DATA_TYPE_UINT64:
    351 			NVP(elem, uint64, uint64_t, u_longlong_t, "%llu");
    352 			break;
    353 
    354 		case DATA_TYPE_STRING:
    355 			NVP(elem, string, char *, char *, "'%s'");
    356 			break;
    357 
    358 		case DATA_TYPE_BYTE_ARRAY:
    359 			NVPA(elem, byte_array, uchar_t, int, "%u");
    360 			break;
    361 
    362 		case DATA_TYPE_INT8_ARRAY:
    363 			NVPA(elem, int8_array, int8_t, int, "%d");
    364 			break;
    365 
    366 		case DATA_TYPE_UINT8_ARRAY:
    367 			NVPA(elem, uint8_array, uint8_t, int, "%u");
    368 			break;
    369 
    370 		case DATA_TYPE_INT16_ARRAY:
    371 			NVPA(elem, int16_array, int16_t, int, "%d");
    372 			break;
    373 
    374 		case DATA_TYPE_UINT16_ARRAY:
    375 			NVPA(elem, uint16_array, uint16_t, int, "%u");
    376 			break;
    377 
    378 		case DATA_TYPE_INT32_ARRAY:
    379 			NVPA(elem, int32_array, int32_t, long, "%ld");
    380 			break;
    381 
    382 		case DATA_TYPE_UINT32_ARRAY:
    383 			NVPA(elem, uint32_array, uint32_t, ulong_t, "%lu");
    384 			break;
    385 
    386 		case DATA_TYPE_INT64_ARRAY:
    387 			NVPA(elem, int64_array, int64_t, longlong_t, "%lld");
    388 			break;
    389 
    390 		case DATA_TYPE_UINT64_ARRAY:
    391 			NVPA(elem, uint64_array, uint64_t, u_longlong_t,
    392 			    "%llu");
    393 			break;
    394 
    395 		case DATA_TYPE_STRING_ARRAY:
    396 			NVPA(elem, string_array, char *, char *, "'%s'");
    397 			break;
    398 
    399 		case DATA_TYPE_NVLIST:
    400 			(void) nvpair_value_nvlist(elem, &nvlist_value);
    401 			(void) printf("%*s%s:\n", indent, "",
    402 			    nvpair_name(elem));
    403 			dump_nvlist(nvlist_value, indent + 4);
    404 			break;
    405 
    406 		case DATA_TYPE_NVLIST_ARRAY:
    407 			(void) nvpair_value_nvlist_array(elem,
    408 			    &nvlist_array_value, &count);
    409 			for (i = 0; i < count; i++) {
    410 				(void) printf("%*s%s[%u]:\n", indent, "",
    411 				    nvpair_name(elem), i);
    412 				dump_nvlist(nvlist_array_value[i], indent + 4);
    413 			}
    414 			break;
    415 
    416 		default:
    417 			(void) printf(dgettext(TEXT_DOMAIN, "bad config type "
    418 			    "%d for %s\n"), nvpair_type(elem),
    419 			    nvpair_name(elem));
    420 		}
    421 	}
    422 }
    423 
    424 /*
    425  * Determine if string 'value' matches 'nvp' value.  The 'value' string is
    426  * converted, depending on the type of 'nvp', prior to match.  For numeric
    427  * types, a radix independent sscanf conversion of 'value' is used. If 'nvp'
    428  * is an array type, 'ai' is the index into the array against which we are
    429  * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass
    430  * in a regex_t compilation of value in 'value_regex' to trigger regular
    431  * expression string match instead of simple strcmp().
    432  *
    433  * Return 1 on match, 0 on no-match, and -1 on error.  If the error is
    434  * related to value syntax error and 'ep' is non-NULL, *ep will point into
    435  * the 'value' string at the location where the error exists.
    436  *
    437  * NOTE: It may be possible to move the non-regex_t version of this into
    438  * common code used by library/kernel/boot.
    439  */
    440 int
    441 nvpair_value_match_regex(nvpair_t *nvp, int ai,
    442     char *value, regex_t *value_regex, char **ep)
    443 {
    444 	char	*evalue;
    445 	uint_t	a_len;
    446 	int	sr;
    447 
    448 	if (ep)
    449 		*ep = NULL;
    450 
    451 	if ((nvp == NULL) || (value == NULL))
    452 		return (-1);		/* error fail match - invalid args */
    453 
    454 	/* make sure array and index combination make sense */
    455 	if ((nvpair_type_is_array(nvp) && (ai < 0)) ||
    456 	    (!nvpair_type_is_array(nvp) && (ai >= 0)))
    457 		return (-1);		/* error fail match - bad index */
    458 
    459 	/* non-string values should be single 'chunk' */
    460 	if ((nvpair_type(nvp) != DATA_TYPE_STRING) &&
    461 	    (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) {
    462 		value += strspn(value, " \t");
    463 		evalue = value + strcspn(value, " \t");
    464 		if (*evalue) {
    465 			if (ep)
    466 				*ep = evalue;
    467 			return (-1);	/* error fail match - syntax */
    468 		}
    469 	}
    470 
    471 	sr = EOF;
    472 	switch (nvpair_type(nvp)) {
    473 	case DATA_TYPE_STRING: {
    474 		char	*val;
    475 
    476 		/* check string value for match */
    477 		if (nvpair_value_string(nvp, &val) == 0) {
    478 			if (value_regex) {
    479 				if (regexec(value_regex, val,
    480 				    (size_t)0, NULL, 0) == 0)
    481 					return (1);	/* match */
    482 			} else {
    483 				if (strcmp(value, val) == 0)
    484 					return (1);	/* match */
    485 			}
    486 		}
    487 		break;
    488 	}
    489 	case DATA_TYPE_STRING_ARRAY: {
    490 		char **val_array;
    491 
    492 		/* check indexed string value of array for match */
    493 		if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) &&
    494 		    (ai < a_len)) {
    495 			if (value_regex) {
    496 				if (regexec(value_regex, val_array[ai],
    497 				    (size_t)0, NULL, 0) == 0)
    498 					return (1);
    499 			} else {
    500 				if (strcmp(value, val_array[ai]) == 0)
    501 					return (1);
    502 			}
    503 		}
    504 		break;
    505 	}
    506 	case DATA_TYPE_BYTE: {
    507 		uchar_t val, val_arg;
    508 
    509 		/* scanf uchar_t from value and check for match */
    510 		sr = sscanf(value, "%c", &val_arg);
    511 		if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) &&
    512 		    (val == val_arg))
    513 			return (1);
    514 		break;
    515 	}
    516 	case DATA_TYPE_BYTE_ARRAY: {
    517 		uchar_t *val_array, val_arg;
    518 
    519 
    520 		/* check indexed value of array for match */
    521 		sr = sscanf(value, "%c", &val_arg);
    522 		if ((sr == 1) &&
    523 		    (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) &&
    524 		    (ai < a_len) &&
    525 		    (val_array[ai] == val_arg))
    526 			return (1);
    527 		break;
    528 	}
    529 	case DATA_TYPE_INT8: {
    530 		int8_t val, val_arg;
    531 
    532 		/* scanf int8_t from value and check for match */
    533 		sr = sscanf(value, "%"SCNi8, &val_arg);
    534 		if ((sr == 1) &&
    535 		    (nvpair_value_int8(nvp, &val) == 0) &&
    536 		    (val == val_arg))
    537 			return (1);
    538 		break;
    539 	}
    540 	case DATA_TYPE_INT8_ARRAY: {
    541 		int8_t *val_array, val_arg;
    542 
    543 		/* check indexed value of array for match */
    544 		sr = sscanf(value, "%"SCNi8, &val_arg);
    545 		if ((sr == 1) &&
    546 		    (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) &&
    547 		    (ai < a_len) &&
    548 		    (val_array[ai] == val_arg))
    549 			return (1);
    550 		break;
    551 	}
    552 	case DATA_TYPE_UINT8: {
    553 		uint8_t val, val_arg;
    554 
    555 		/* scanf uint8_t from value and check for match */
    556 		sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
    557 		if ((sr == 1) &&
    558 		    (nvpair_value_uint8(nvp, &val) == 0) &&
    559 		    (val == val_arg))
    560 			return (1);
    561 		break;
    562 	}
    563 	case DATA_TYPE_UINT8_ARRAY: {
    564 		uint8_t *val_array, val_arg;
    565 
    566 		/* check indexed value of array for match */
    567 		sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
    568 		if ((sr == 1) &&
    569 		    (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) &&
    570 		    (ai < a_len) &&
    571 		    (val_array[ai] == val_arg))
    572 			return (1);
    573 		break;
    574 	}
    575 	case DATA_TYPE_INT16: {
    576 		int16_t val, val_arg;
    577 
    578 		/* scanf int16_t from value and check for match */
    579 		sr = sscanf(value, "%"SCNi16, &val_arg);
    580 		if ((sr == 1) &&
    581 		    (nvpair_value_int16(nvp, &val) == 0) &&
    582 		    (val == val_arg))
    583 			return (1);
    584 		break;
    585 	}
    586 	case DATA_TYPE_INT16_ARRAY: {
    587 		int16_t *val_array, val_arg;
    588 
    589 		/* check indexed value of array for match */
    590 		sr = sscanf(value, "%"SCNi16, &val_arg);
    591 		if ((sr == 1) &&
    592 		    (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) &&
    593 		    (ai < a_len) &&
    594 		    (val_array[ai] == val_arg))
    595 			return (1);
    596 		break;
    597 	}
    598 	case DATA_TYPE_UINT16: {
    599 		uint16_t val, val_arg;
    600 
    601 		/* scanf uint16_t from value and check for match */
    602 		sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
    603 		if ((sr == 1) &&
    604 		    (nvpair_value_uint16(nvp, &val) == 0) &&
    605 		    (val == val_arg))
    606 			return (1);
    607 		break;
    608 	}
    609 	case DATA_TYPE_UINT16_ARRAY: {
    610 		uint16_t *val_array, val_arg;
    611 
    612 		/* check indexed value of array for match */
    613 		sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
    614 		if ((sr == 1) &&
    615 		    (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) &&
    616 		    (ai < a_len) &&
    617 		    (val_array[ai] == val_arg))
    618 			return (1);
    619 		break;
    620 	}
    621 	case DATA_TYPE_INT32: {
    622 		int32_t val, val_arg;
    623 
    624 		/* scanf int32_t from value and check for match */
    625 		sr = sscanf(value, "%"SCNi32, &val_arg);
    626 		if ((sr == 1) &&
    627 		    (nvpair_value_int32(nvp, &val) == 0) &&
    628 		    (val == val_arg))
    629 			return (1);
    630 		break;
    631 	}
    632 	case DATA_TYPE_INT32_ARRAY: {
    633 		int32_t *val_array, val_arg;
    634 
    635 		/* check indexed value of array for match */
    636 		sr = sscanf(value, "%"SCNi32, &val_arg);
    637 		if ((sr == 1) &&
    638 		    (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) &&
    639 		    (ai < a_len) &&
    640 		    (val_array[ai] == val_arg))
    641 			return (1);
    642 		break;
    643 	}
    644 	case DATA_TYPE_UINT32: {
    645 		uint32_t val, val_arg;
    646 
    647 		/* scanf uint32_t from value and check for match */
    648 		sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
    649 		if ((sr == 1) &&
    650 		    (nvpair_value_uint32(nvp, &val) == 0) &&
    651 		    (val == val_arg))
    652 			return (1);
    653 		break;
    654 	}
    655 	case DATA_TYPE_UINT32_ARRAY: {
    656 		uint32_t *val_array, val_arg;
    657 
    658 		/* check indexed value of array for match */
    659 		sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
    660 		if ((sr == 1) &&
    661 		    (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) &&
    662 		    (ai < a_len) &&
    663 		    (val_array[ai] == val_arg))
    664 			return (1);
    665 		break;
    666 	}
    667 	case DATA_TYPE_INT64: {
    668 		int64_t val, val_arg;
    669 
    670 		/* scanf int64_t from value and check for match */
    671 		sr = sscanf(value, "%"SCNi64, &val_arg);
    672 		if ((sr == 1) &&
    673 		    (nvpair_value_int64(nvp, &val) == 0) &&
    674 		    (val == val_arg))
    675 			return (1);
    676 		break;
    677 	}
    678 	case DATA_TYPE_INT64_ARRAY: {
    679 		int64_t *val_array, val_arg;
    680 
    681 		/* check indexed value of array for match */
    682 		sr = sscanf(value, "%"SCNi64, &val_arg);
    683 		if ((sr == 1) &&
    684 		    (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) &&
    685 		    (ai < a_len) &&
    686 		    (val_array[ai] == val_arg))
    687 				return (1);
    688 		break;
    689 	}
    690 	case DATA_TYPE_UINT64: {
    691 		uint64_t val_arg, val;
    692 
    693 		/* scanf uint64_t from value and check for match */
    694 		sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
    695 		if ((sr == 1) &&
    696 		    (nvpair_value_uint64(nvp, &val) == 0) &&
    697 		    (val == val_arg))
    698 			return (1);
    699 		break;
    700 	}
    701 	case DATA_TYPE_UINT64_ARRAY: {
    702 		uint64_t *val_array, val_arg;
    703 
    704 		/* check indexed value of array for match */
    705 		sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
    706 		if ((sr == 1) &&
    707 		    (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) &&
    708 		    (ai < a_len) &&
    709 		    (val_array[ai] == val_arg))
    710 			return (1);
    711 		break;
    712 	}
    713 	case DATA_TYPE_BOOLEAN_VALUE: {
    714 		boolean_t val, val_arg;
    715 
    716 		/* scanf boolean_t from value and check for match */
    717 		sr = sscanf(value, "%"SCNi32, &val_arg);
    718 		if ((sr == 1) &&
    719 		    (nvpair_value_boolean_value(nvp, &val) == 0) &&
    720 		    (val == val_arg))
    721 			return (1);
    722 		break;
    723 	}
    724 	case DATA_TYPE_BOOLEAN_ARRAY: {
    725 		boolean_t *val_array, val_arg;
    726 
    727 		/* check indexed value of array for match */
    728 		sr = sscanf(value, "%"SCNi32, &val_arg);
    729 		if ((sr == 1) &&
    730 		    (nvpair_value_boolean_array(nvp,
    731 		    &val_array, &a_len) == 0) &&
    732 		    (ai < a_len) &&
    733 		    (val_array[ai] == val_arg))
    734 			return (1);
    735 		break;
    736 	}
    737 	case DATA_TYPE_HRTIME:
    738 	case DATA_TYPE_NVLIST:
    739 	case DATA_TYPE_NVLIST_ARRAY:
    740 	case DATA_TYPE_BOOLEAN:
    741 	case DATA_TYPE_DOUBLE:
    742 	case DATA_TYPE_UNKNOWN:
    743 	default:
    744 		/*
    745 		 * unknown/unsupported data type
    746 		 */
    747 		return (-1);		/* error fail match */
    748 	}
    749 
    750 	/*
    751 	 * check to see if sscanf failed conversion, return approximate
    752 	 * pointer to problem
    753 	 */
    754 	if (sr != 1) {
    755 		if (ep)
    756 			*ep = value;
    757 		return (-1);		/* error fail match  - syntax */
    758 	}
    759 
    760 	return (0);			/* fail match */
    761 }
    762 
    763 int
    764 nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep)
    765 {
    766 	return (nvpair_value_match_regex(nvp, ai, value, NULL, ep));
    767 }
    768