Home | History | Annotate | Line # | Download | only in libnvpair
libnvpair.c revision 1.1.1.2.12.2
      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, " %" PRId64 , 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%" PRIx64, 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, " %" PRId64, 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%" PRIx64, val[i]);
    220 			break;
    221 		}
    222 		case DATA_TYPE_STRING_ARRAY: {
    223 			char **val;
    224 			(void) nvpair_value_string_array(nvp, &val, &nelem);
    225 			for (i = 0; i < nelem; i++)
    226 				(void) fprintf(fp, " %s", val[i]);
    227 			break;
    228 		}
    229 		case DATA_TYPE_HRTIME: {
    230 			hrtime_t val;
    231 			(void) nvpair_value_hrtime(nvp, &val);
    232 			(void) fprintf(fp, " 0x%jx", (intmax_t)val);
    233 			break;
    234 		}
    235 		case DATA_TYPE_NVLIST: {
    236 			nvlist_t *val;
    237 			(void) nvpair_value_nvlist(nvp, &val);
    238 			(void) fprintf(fp, " (embedded nvlist)\n");
    239 			nvlist_print_with_indent(fp, val, depth + 1);
    240 			indent(fp, depth + 1);
    241 			(void) fprintf(fp, "(end %s)\n", name);
    242 			break;
    243 		}
    244 		case DATA_TYPE_NVLIST_ARRAY: {
    245 			nvlist_t **val;
    246 			(void) nvpair_value_nvlist_array(nvp, &val, &nelem);
    247 			(void) fprintf(fp, " (array of embedded nvlists)\n");
    248 			for (i = 0; i < nelem; i++) {
    249 				indent(fp, depth + 1);
    250 				(void) fprintf(fp,
    251 				    "(start %s[%d])\n", name, i);
    252 				nvlist_print_with_indent(fp, val[i], depth + 1);
    253 				indent(fp, depth + 1);
    254 				(void) fprintf(fp, "(end %s[%d])\n", name, i);
    255 			}
    256 			break;
    257 		}
    258 		default:
    259 			(void) fprintf(fp, " unknown data type (%d)", type);
    260 			break;
    261 		}
    262 		(void) fprintf(fp, "\n");
    263 		nvp = nvlist_next_nvpair(nvl, nvp);
    264 	}
    265 }
    266 
    267 void
    268 nvlist_print(FILE *fp, nvlist_t *nvl)
    269 {
    270 	nvlist_print_with_indent(fp, nvl, 0);
    271 }
    272 
    273 
    274 #define	NVP(elem, type, vtype, ptype, format) { \
    275 	vtype	value; \
    276 \
    277 	(void) nvpair_value_##type(elem, &value); \
    278 	(void) printf("%*s%s: " format "\n", indent, "", \
    279 	    nvpair_name(elem), (ptype)value); \
    280 }
    281 
    282 #define	NVPA(elem, type, vtype, ptype, format) { \
    283 	uint_t	i, count; \
    284 	vtype	*value;  \
    285 \
    286 	(void) nvpair_value_##type(elem, &value, &count); \
    287 	for (i = 0; i < count; i++) { \
    288 		(void) printf("%*s%s[%d]: " format "\n", indent, "", \
    289 		    nvpair_name(elem), i, (ptype)value[i]); \
    290 	} \
    291 }
    292 
    293 /*
    294  * Similar to nvlist_print() but handles arrays slightly differently.
    295  */
    296 void
    297 dump_nvlist(nvlist_t *list, int indent)
    298 {
    299 	nvpair_t	*elem = NULL;
    300 	boolean_t	bool_value;
    301 	nvlist_t	*nvlist_value;
    302 	nvlist_t	**nvlist_array_value;
    303 	uint_t		i, count;
    304 
    305 	if (list == NULL) {
    306 		return;
    307 	}
    308 
    309 	while ((elem = nvlist_next_nvpair(list, elem)) != NULL) {
    310 		switch (nvpair_type(elem)) {
    311 		case DATA_TYPE_BOOLEAN_VALUE:
    312 			(void) nvpair_value_boolean_value(elem, &bool_value);
    313 			(void) printf("%*s%s: %s\n", indent, "",
    314 			    nvpair_name(elem), bool_value ? "true" : "false");
    315 			break;
    316 
    317 		case DATA_TYPE_BYTE:
    318 			NVP(elem, byte, uchar_t, int, "%u");
    319 			break;
    320 
    321 		case DATA_TYPE_INT8:
    322 			NVP(elem, int8, int8_t, int, "%d");
    323 			break;
    324 
    325 		case DATA_TYPE_UINT8:
    326 			NVP(elem, uint8, uint8_t, int, "%u");
    327 			break;
    328 
    329 		case DATA_TYPE_INT16:
    330 			NVP(elem, int16, int16_t, int, "%d");
    331 			break;
    332 
    333 		case DATA_TYPE_UINT16:
    334 			NVP(elem, uint16, uint16_t, int, "%u");
    335 			break;
    336 
    337 		case DATA_TYPE_INT32:
    338 			NVP(elem, int32, int32_t, long, "%ld");
    339 			break;
    340 
    341 		case DATA_TYPE_UINT32:
    342 			NVP(elem, uint32, uint32_t, ulong_t, "%lu");
    343 			break;
    344 
    345 		case DATA_TYPE_INT64:
    346 			NVP(elem, int64, int64_t, int64_t, "%" PRIx64);
    347 			break;
    348 
    349 		case DATA_TYPE_UINT64:
    350 			NVP(elem, uint64, uint64_t, uint64_t, "%" PRIu64);
    351 			break;
    352 
    353 		case DATA_TYPE_STRING:
    354 			NVP(elem, string, char *, char *, "'%s'");
    355 			break;
    356 
    357 		case DATA_TYPE_BYTE_ARRAY:
    358 			NVPA(elem, byte_array, uchar_t, int, "%u");
    359 			break;
    360 
    361 		case DATA_TYPE_INT8_ARRAY:
    362 			NVPA(elem, int8_array, int8_t, int, "%d");
    363 			break;
    364 
    365 		case DATA_TYPE_UINT8_ARRAY:
    366 			NVPA(elem, uint8_array, uint8_t, int, "%u");
    367 			break;
    368 
    369 		case DATA_TYPE_INT16_ARRAY:
    370 			NVPA(elem, int16_array, int16_t, int, "%d");
    371 			break;
    372 
    373 		case DATA_TYPE_UINT16_ARRAY:
    374 			NVPA(elem, uint16_array, uint16_t, int, "%u");
    375 			break;
    376 
    377 		case DATA_TYPE_INT32_ARRAY:
    378 			NVPA(elem, int32_array, int32_t, long, "%ld");
    379 			break;
    380 
    381 		case DATA_TYPE_UINT32_ARRAY:
    382 			NVPA(elem, uint32_array, uint32_t, ulong_t, "%lu");
    383 			break;
    384 
    385 		case DATA_TYPE_INT64_ARRAY:
    386 			NVPA(elem, int64_array, int64_t, int64_t, "%" PRId64);
    387 			break;
    388 
    389 		case DATA_TYPE_UINT64_ARRAY:
    390 			NVPA(elem, uint64_array, uint64_t, uint64_t,
    391 			    "%" PRIu64);
    392 			break;
    393 
    394 		case DATA_TYPE_STRING_ARRAY:
    395 			NVPA(elem, string_array, char *, char *, "'%s'");
    396 			break;
    397 
    398 		case DATA_TYPE_NVLIST:
    399 			(void) nvpair_value_nvlist(elem, &nvlist_value);
    400 			(void) printf("%*s%s:\n", indent, "",
    401 			    nvpair_name(elem));
    402 			dump_nvlist(nvlist_value, indent + 4);
    403 			break;
    404 
    405 		case DATA_TYPE_NVLIST_ARRAY:
    406 			(void) nvpair_value_nvlist_array(elem,
    407 			    &nvlist_array_value, &count);
    408 			for (i = 0; i < count; i++) {
    409 				(void) printf("%*s%s[%u]:\n", indent, "",
    410 				    nvpair_name(elem), i);
    411 				dump_nvlist(nvlist_array_value[i], indent + 4);
    412 			}
    413 			break;
    414 
    415 		default:
    416 			(void) printf(dgettext(TEXT_DOMAIN, "bad config type "
    417 			    "%d for %s\n"), nvpair_type(elem),
    418 			    nvpair_name(elem));
    419 		}
    420 	}
    421 }
    422 
    423 /*
    424  * Determine if string 'value' matches 'nvp' value.  The 'value' string is
    425  * converted, depending on the type of 'nvp', prior to match.  For numeric
    426  * types, a radix independent sscanf conversion of 'value' is used. If 'nvp'
    427  * is an array type, 'ai' is the index into the array against which we are
    428  * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass
    429  * in a regex_t compilation of value in 'value_regex' to trigger regular
    430  * expression string match instead of simple strcmp().
    431  *
    432  * Return 1 on match, 0 on no-match, and -1 on error.  If the error is
    433  * related to value syntax error and 'ep' is non-NULL, *ep will point into
    434  * the 'value' string at the location where the error exists.
    435  *
    436  * NOTE: It may be possible to move the non-regex_t version of this into
    437  * common code used by library/kernel/boot.
    438  */
    439 int
    440 nvpair_value_match_regex(nvpair_t *nvp, int ai,
    441     char *value, regex_t *value_regex, char **ep)
    442 {
    443 	char	*evalue;
    444 	uint_t	a_len;
    445 	int	sr;
    446 
    447 	if (ep)
    448 		*ep = NULL;
    449 
    450 	if ((nvp == NULL) || (value == NULL))
    451 		return (-1);		/* error fail match - invalid args */
    452 
    453 	/* make sure array and index combination make sense */
    454 	if ((nvpair_type_is_array(nvp) && (ai < 0)) ||
    455 	    (!nvpair_type_is_array(nvp) && (ai >= 0)))
    456 		return (-1);		/* error fail match - bad index */
    457 
    458 	/* non-string values should be single 'chunk' */
    459 	if ((nvpair_type(nvp) != DATA_TYPE_STRING) &&
    460 	    (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) {
    461 		value += strspn(value, " \t");
    462 		evalue = value + strcspn(value, " \t");
    463 		if (*evalue) {
    464 			if (ep)
    465 				*ep = evalue;
    466 			return (-1);	/* error fail match - syntax */
    467 		}
    468 	}
    469 
    470 	sr = EOF;
    471 	switch (nvpair_type(nvp)) {
    472 	case DATA_TYPE_STRING: {
    473 		char	*val;
    474 
    475 		/* check string value for match */
    476 		if (nvpair_value_string(nvp, &val) == 0) {
    477 			if (value_regex) {
    478 				if (regexec(value_regex, val,
    479 				    (size_t)0, NULL, 0) == 0)
    480 					return (1);	/* match */
    481 			} else {
    482 				if (strcmp(value, val) == 0)
    483 					return (1);	/* match */
    484 			}
    485 		}
    486 		break;
    487 	}
    488 	case DATA_TYPE_STRING_ARRAY: {
    489 		char **val_array;
    490 
    491 		/* check indexed string value of array for match */
    492 		if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) &&
    493 		    (ai < a_len)) {
    494 			if (value_regex) {
    495 				if (regexec(value_regex, val_array[ai],
    496 				    (size_t)0, NULL, 0) == 0)
    497 					return (1);
    498 			} else {
    499 				if (strcmp(value, val_array[ai]) == 0)
    500 					return (1);
    501 			}
    502 		}
    503 		break;
    504 	}
    505 	case DATA_TYPE_BYTE: {
    506 		uchar_t val, val_arg;
    507 
    508 		/* scanf uchar_t from value and check for match */
    509 		sr = sscanf(value, "%c", &val_arg);
    510 		if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) &&
    511 		    (val == val_arg))
    512 			return (1);
    513 		break;
    514 	}
    515 	case DATA_TYPE_BYTE_ARRAY: {
    516 		uchar_t *val_array, val_arg;
    517 
    518 
    519 		/* check indexed value of array for match */
    520 		sr = sscanf(value, "%c", &val_arg);
    521 		if ((sr == 1) &&
    522 		    (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) &&
    523 		    (ai < a_len) &&
    524 		    (val_array[ai] == val_arg))
    525 			return (1);
    526 		break;
    527 	}
    528 	case DATA_TYPE_INT8: {
    529 		int8_t val, val_arg;
    530 
    531 		/* scanf int8_t from value and check for match */
    532 		sr = sscanf(value, "%"SCNi8, &val_arg);
    533 		if ((sr == 1) &&
    534 		    (nvpair_value_int8(nvp, &val) == 0) &&
    535 		    (val == val_arg))
    536 			return (1);
    537 		break;
    538 	}
    539 	case DATA_TYPE_INT8_ARRAY: {
    540 		int8_t *val_array, val_arg;
    541 
    542 		/* check indexed value of array for match */
    543 		sr = sscanf(value, "%"SCNi8, &val_arg);
    544 		if ((sr == 1) &&
    545 		    (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) &&
    546 		    (ai < a_len) &&
    547 		    (val_array[ai] == val_arg))
    548 			return (1);
    549 		break;
    550 	}
    551 	case DATA_TYPE_UINT8: {
    552 		uint8_t val, val_arg;
    553 
    554 		/* scanf uint8_t from value and check for match */
    555 		sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
    556 		if ((sr == 1) &&
    557 		    (nvpair_value_uint8(nvp, &val) == 0) &&
    558 		    (val == val_arg))
    559 			return (1);
    560 		break;
    561 	}
    562 	case DATA_TYPE_UINT8_ARRAY: {
    563 		uint8_t *val_array, val_arg;
    564 
    565 		/* check indexed value of array for match */
    566 		sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
    567 		if ((sr == 1) &&
    568 		    (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) &&
    569 		    (ai < a_len) &&
    570 		    (val_array[ai] == val_arg))
    571 			return (1);
    572 		break;
    573 	}
    574 	case DATA_TYPE_INT16: {
    575 		int16_t val, val_arg;
    576 
    577 		/* scanf int16_t from value and check for match */
    578 		sr = sscanf(value, "%"SCNi16, &val_arg);
    579 		if ((sr == 1) &&
    580 		    (nvpair_value_int16(nvp, &val) == 0) &&
    581 		    (val == val_arg))
    582 			return (1);
    583 		break;
    584 	}
    585 	case DATA_TYPE_INT16_ARRAY: {
    586 		int16_t *val_array, val_arg;
    587 
    588 		/* check indexed value of array for match */
    589 		sr = sscanf(value, "%"SCNi16, &val_arg);
    590 		if ((sr == 1) &&
    591 		    (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) &&
    592 		    (ai < a_len) &&
    593 		    (val_array[ai] == val_arg))
    594 			return (1);
    595 		break;
    596 	}
    597 	case DATA_TYPE_UINT16: {
    598 		uint16_t val, val_arg;
    599 
    600 		/* scanf uint16_t from value and check for match */
    601 		sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
    602 		if ((sr == 1) &&
    603 		    (nvpair_value_uint16(nvp, &val) == 0) &&
    604 		    (val == val_arg))
    605 			return (1);
    606 		break;
    607 	}
    608 	case DATA_TYPE_UINT16_ARRAY: {
    609 		uint16_t *val_array, val_arg;
    610 
    611 		/* check indexed value of array for match */
    612 		sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
    613 		if ((sr == 1) &&
    614 		    (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) &&
    615 		    (ai < a_len) &&
    616 		    (val_array[ai] == val_arg))
    617 			return (1);
    618 		break;
    619 	}
    620 	case DATA_TYPE_INT32: {
    621 		int32_t val, val_arg;
    622 
    623 		/* scanf int32_t from value and check for match */
    624 		sr = sscanf(value, "%"SCNi32, &val_arg);
    625 		if ((sr == 1) &&
    626 		    (nvpair_value_int32(nvp, &val) == 0) &&
    627 		    (val == val_arg))
    628 			return (1);
    629 		break;
    630 	}
    631 	case DATA_TYPE_INT32_ARRAY: {
    632 		int32_t *val_array, val_arg;
    633 
    634 		/* check indexed value of array for match */
    635 		sr = sscanf(value, "%"SCNi32, &val_arg);
    636 		if ((sr == 1) &&
    637 		    (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) &&
    638 		    (ai < a_len) &&
    639 		    (val_array[ai] == val_arg))
    640 			return (1);
    641 		break;
    642 	}
    643 	case DATA_TYPE_UINT32: {
    644 		uint32_t val, val_arg;
    645 
    646 		/* scanf uint32_t from value and check for match */
    647 		sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
    648 		if ((sr == 1) &&
    649 		    (nvpair_value_uint32(nvp, &val) == 0) &&
    650 		    (val == val_arg))
    651 			return (1);
    652 		break;
    653 	}
    654 	case DATA_TYPE_UINT32_ARRAY: {
    655 		uint32_t *val_array, val_arg;
    656 
    657 		/* check indexed value of array for match */
    658 		sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
    659 		if ((sr == 1) &&
    660 		    (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) &&
    661 		    (ai < a_len) &&
    662 		    (val_array[ai] == val_arg))
    663 			return (1);
    664 		break;
    665 	}
    666 	case DATA_TYPE_INT64: {
    667 		int64_t val, val_arg;
    668 
    669 		/* scanf int64_t from value and check for match */
    670 		sr = sscanf(value, "%"SCNi64, &val_arg);
    671 		if ((sr == 1) &&
    672 		    (nvpair_value_int64(nvp, &val) == 0) &&
    673 		    (val == val_arg))
    674 			return (1);
    675 		break;
    676 	}
    677 	case DATA_TYPE_INT64_ARRAY: {
    678 		int64_t *val_array, val_arg;
    679 
    680 		/* check indexed value of array for match */
    681 		sr = sscanf(value, "%"SCNi64, &val_arg);
    682 		if ((sr == 1) &&
    683 		    (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) &&
    684 		    (ai < a_len) &&
    685 		    (val_array[ai] == val_arg))
    686 				return (1);
    687 		break;
    688 	}
    689 	case DATA_TYPE_UINT64: {
    690 		uint64_t val_arg, val;
    691 
    692 		/* scanf uint64_t from value and check for match */
    693 		sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
    694 		if ((sr == 1) &&
    695 		    (nvpair_value_uint64(nvp, &val) == 0) &&
    696 		    (val == val_arg))
    697 			return (1);
    698 		break;
    699 	}
    700 	case DATA_TYPE_UINT64_ARRAY: {
    701 		uint64_t *val_array, val_arg;
    702 
    703 		/* check indexed value of array for match */
    704 		sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
    705 		if ((sr == 1) &&
    706 		    (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) &&
    707 		    (ai < a_len) &&
    708 		    (val_array[ai] == val_arg))
    709 			return (1);
    710 		break;
    711 	}
    712 	case DATA_TYPE_BOOLEAN_VALUE: {
    713 		boolean_t val, val_arg;
    714 
    715 		/* scanf boolean_t from value and check for match */
    716 		sr = sscanf(value, "%"SCNi32, &val_arg);
    717 		if ((sr == 1) &&
    718 		    (nvpair_value_boolean_value(nvp, &val) == 0) &&
    719 		    (val == val_arg))
    720 			return (1);
    721 		break;
    722 	}
    723 	case DATA_TYPE_BOOLEAN_ARRAY: {
    724 		boolean_t *val_array, val_arg;
    725 
    726 		/* check indexed value of array for match */
    727 		sr = sscanf(value, "%"SCNi32, &val_arg);
    728 		if ((sr == 1) &&
    729 		    (nvpair_value_boolean_array(nvp,
    730 		    &val_array, &a_len) == 0) &&
    731 		    (ai < a_len) &&
    732 		    (val_array[ai] == val_arg))
    733 			return (1);
    734 		break;
    735 	}
    736 	case DATA_TYPE_HRTIME:
    737 	case DATA_TYPE_NVLIST:
    738 	case DATA_TYPE_NVLIST_ARRAY:
    739 	case DATA_TYPE_BOOLEAN:
    740 	case DATA_TYPE_DOUBLE:
    741 	case DATA_TYPE_UNKNOWN:
    742 	default:
    743 		/*
    744 		 * unknown/unsupported data type
    745 		 */
    746 		return (-1);		/* error fail match */
    747 	}
    748 
    749 	/*
    750 	 * check to see if sscanf failed conversion, return approximate
    751 	 * pointer to problem
    752 	 */
    753 	if (sr != 1) {
    754 		if (ep)
    755 			*ep = value;
    756 		return (-1);		/* error fail match  - syntax */
    757 	}
    758 
    759 	return (0);			/* fail match */
    760 }
    761 
    762 int
    763 nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep)
    764 {
    765 	return (nvpair_value_match_regex(nvp, ai, value, NULL, ep));
    766 }
    767