xref: /titanic_51/usr/src/lib/libnvpair/libnvpair.c (revision 602ca9ea8f9ce0933f0944601cc5d230e91a950d)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*602ca9eaScth  * Common Development and Distribution License (the "License").
6*602ca9eaScth  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*602ca9eaScth  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <unistd.h>
297c478bd9Sstevel@tonic-gate #include <strings.h>
30*602ca9eaScth #include <sys/types.h>
31*602ca9eaScth #include <sys/inttypes.h>
327c478bd9Sstevel@tonic-gate #include "libnvpair.h"
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate  * libnvpair - A tools library for manipulating <name, value> pairs.
367c478bd9Sstevel@tonic-gate  *
377c478bd9Sstevel@tonic-gate  *	This library provides routines packing an unpacking nv pairs
387c478bd9Sstevel@tonic-gate  *	for transporting data across process boundaries, transporting
397c478bd9Sstevel@tonic-gate  *	between kernel and userland, and possibly saving onto disk files.
407c478bd9Sstevel@tonic-gate  */
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate static void
437c478bd9Sstevel@tonic-gate indent(FILE *fp, int depth)
447c478bd9Sstevel@tonic-gate {
457c478bd9Sstevel@tonic-gate 	while (depth-- > 0)
467c478bd9Sstevel@tonic-gate 		(void) fprintf(fp, "\t");
477c478bd9Sstevel@tonic-gate }
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate /*
507c478bd9Sstevel@tonic-gate  * nvlist_print - Prints elements in an event buffer
517c478bd9Sstevel@tonic-gate  */
527c478bd9Sstevel@tonic-gate static
537c478bd9Sstevel@tonic-gate void
547c478bd9Sstevel@tonic-gate nvlist_print_with_indent(FILE *fp, nvlist_t *nvl, int depth)
557c478bd9Sstevel@tonic-gate {
567c478bd9Sstevel@tonic-gate 	int i;
577c478bd9Sstevel@tonic-gate 	char *name;
587c478bd9Sstevel@tonic-gate 	uint_t nelem;
597c478bd9Sstevel@tonic-gate 	nvpair_t *nvp;
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate 	if (nvl == NULL)
627c478bd9Sstevel@tonic-gate 		return;
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate 	indent(fp, depth);
657c478bd9Sstevel@tonic-gate 	(void) fprintf(fp, "nvlist version: %d\n", NVL_VERSION(nvl));
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate 	nvp = nvlist_next_nvpair(nvl, NULL);
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate 	while (nvp) {
707c478bd9Sstevel@tonic-gate 		data_type_t type = nvpair_type(nvp);
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate 		indent(fp, depth);
737c478bd9Sstevel@tonic-gate 		name = nvpair_name(nvp);
747c478bd9Sstevel@tonic-gate 		(void) fprintf(fp, "\t%s =", name);
757c478bd9Sstevel@tonic-gate 		nelem = 0;
767c478bd9Sstevel@tonic-gate 		switch (type) {
777c478bd9Sstevel@tonic-gate 		case DATA_TYPE_BOOLEAN: {
787c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " 1");
797c478bd9Sstevel@tonic-gate 			break;
807c478bd9Sstevel@tonic-gate 		}
817c478bd9Sstevel@tonic-gate 		case DATA_TYPE_BOOLEAN_VALUE: {
827c478bd9Sstevel@tonic-gate 			boolean_t val;
837c478bd9Sstevel@tonic-gate 			(void) nvpair_value_boolean_value(nvp, &val);
847c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " %d", val);
857c478bd9Sstevel@tonic-gate 			break;
867c478bd9Sstevel@tonic-gate 		}
877c478bd9Sstevel@tonic-gate 		case DATA_TYPE_BYTE: {
887c478bd9Sstevel@tonic-gate 			uchar_t val;
897c478bd9Sstevel@tonic-gate 			(void) nvpair_value_byte(nvp, &val);
907c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " 0x%2.2x", val);
917c478bd9Sstevel@tonic-gate 			break;
927c478bd9Sstevel@tonic-gate 		}
937c478bd9Sstevel@tonic-gate 		case DATA_TYPE_INT8: {
947c478bd9Sstevel@tonic-gate 			int8_t val;
957c478bd9Sstevel@tonic-gate 			(void) nvpair_value_int8(nvp, &val);
967c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " %d", val);
977c478bd9Sstevel@tonic-gate 			break;
987c478bd9Sstevel@tonic-gate 		}
997c478bd9Sstevel@tonic-gate 		case DATA_TYPE_UINT8: {
1007c478bd9Sstevel@tonic-gate 			uint8_t val;
1017c478bd9Sstevel@tonic-gate 			(void) nvpair_value_uint8(nvp, &val);
1027c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " 0x%x", val);
1037c478bd9Sstevel@tonic-gate 			break;
1047c478bd9Sstevel@tonic-gate 		}
1057c478bd9Sstevel@tonic-gate 		case DATA_TYPE_INT16: {
1067c478bd9Sstevel@tonic-gate 			int16_t val;
1077c478bd9Sstevel@tonic-gate 			(void) nvpair_value_int16(nvp, &val);
1087c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " %d", val);
1097c478bd9Sstevel@tonic-gate 			break;
1107c478bd9Sstevel@tonic-gate 		}
1117c478bd9Sstevel@tonic-gate 		case DATA_TYPE_UINT16: {
1127c478bd9Sstevel@tonic-gate 			uint16_t val;
1137c478bd9Sstevel@tonic-gate 			(void) nvpair_value_uint16(nvp, &val);
1147c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " 0x%x", val);
1157c478bd9Sstevel@tonic-gate 			break;
1167c478bd9Sstevel@tonic-gate 		}
1177c478bd9Sstevel@tonic-gate 		case DATA_TYPE_INT32: {
1187c478bd9Sstevel@tonic-gate 			int32_t val;
1197c478bd9Sstevel@tonic-gate 			(void) nvpair_value_int32(nvp, &val);
1207c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " %d", val);
1217c478bd9Sstevel@tonic-gate 			break;
1227c478bd9Sstevel@tonic-gate 		}
1237c478bd9Sstevel@tonic-gate 		case DATA_TYPE_UINT32: {
1247c478bd9Sstevel@tonic-gate 			uint32_t val;
1257c478bd9Sstevel@tonic-gate 			(void) nvpair_value_uint32(nvp, &val);
1267c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " 0x%x", val);
1277c478bd9Sstevel@tonic-gate 			break;
1287c478bd9Sstevel@tonic-gate 		}
1297c478bd9Sstevel@tonic-gate 		case DATA_TYPE_INT64: {
1307c478bd9Sstevel@tonic-gate 			int64_t val;
1317c478bd9Sstevel@tonic-gate 			(void) nvpair_value_int64(nvp, &val);
1327c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " %lld", (longlong_t)val);
1337c478bd9Sstevel@tonic-gate 			break;
1347c478bd9Sstevel@tonic-gate 		}
1357c478bd9Sstevel@tonic-gate 		case DATA_TYPE_UINT64: {
1367c478bd9Sstevel@tonic-gate 			uint64_t val;
1377c478bd9Sstevel@tonic-gate 			(void) nvpair_value_uint64(nvp, &val);
1387c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " 0x%llx", (u_longlong_t)val);
1397c478bd9Sstevel@tonic-gate 			break;
1407c478bd9Sstevel@tonic-gate 		}
1417c478bd9Sstevel@tonic-gate 		case DATA_TYPE_STRING: {
1427c478bd9Sstevel@tonic-gate 			char *val;
1437c478bd9Sstevel@tonic-gate 			(void) nvpair_value_string(nvp, &val);
1447c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " %s", val);
1457c478bd9Sstevel@tonic-gate 			break;
1467c478bd9Sstevel@tonic-gate 		}
1477c478bd9Sstevel@tonic-gate 		case DATA_TYPE_BOOLEAN_ARRAY: {
1487c478bd9Sstevel@tonic-gate 			boolean_t *val;
1497c478bd9Sstevel@tonic-gate 			(void) nvpair_value_boolean_array(nvp, &val, &nelem);
1507c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
1517c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " %d", val[i]);
1527c478bd9Sstevel@tonic-gate 			break;
1537c478bd9Sstevel@tonic-gate 		}
1547c478bd9Sstevel@tonic-gate 		case DATA_TYPE_BYTE_ARRAY: {
1557c478bd9Sstevel@tonic-gate 			uchar_t *val;
1567c478bd9Sstevel@tonic-gate 			(void) nvpair_value_byte_array(nvp, &val, &nelem);
1577c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
1587c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " 0x%2.2x", val[i]);
1597c478bd9Sstevel@tonic-gate 			break;
1607c478bd9Sstevel@tonic-gate 		}
1617c478bd9Sstevel@tonic-gate 		case DATA_TYPE_INT8_ARRAY: {
1627c478bd9Sstevel@tonic-gate 			int8_t *val;
1637c478bd9Sstevel@tonic-gate 			(void) nvpair_value_int8_array(nvp, &val, &nelem);
1647c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
1657c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " %d", val[i]);
1667c478bd9Sstevel@tonic-gate 			break;
1677c478bd9Sstevel@tonic-gate 		}
1687c478bd9Sstevel@tonic-gate 		case DATA_TYPE_UINT8_ARRAY: {
1697c478bd9Sstevel@tonic-gate 			uint8_t *val;
1707c478bd9Sstevel@tonic-gate 			(void) nvpair_value_uint8_array(nvp, &val, &nelem);
1717c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
1727c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " 0x%x", val[i]);
1737c478bd9Sstevel@tonic-gate 			break;
1747c478bd9Sstevel@tonic-gate 		}
1757c478bd9Sstevel@tonic-gate 		case DATA_TYPE_INT16_ARRAY: {
1767c478bd9Sstevel@tonic-gate 			int16_t *val;
1777c478bd9Sstevel@tonic-gate 			(void) nvpair_value_int16_array(nvp, &val, &nelem);
1787c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
1797c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " %d", val[i]);
1807c478bd9Sstevel@tonic-gate 			break;
1817c478bd9Sstevel@tonic-gate 		}
1827c478bd9Sstevel@tonic-gate 		case DATA_TYPE_UINT16_ARRAY: {
1837c478bd9Sstevel@tonic-gate 			uint16_t *val;
1847c478bd9Sstevel@tonic-gate 			(void) nvpair_value_uint16_array(nvp, &val, &nelem);
1857c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
1867c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " 0x%x", val[i]);
1877c478bd9Sstevel@tonic-gate 			break;
1887c478bd9Sstevel@tonic-gate 		}
1897c478bd9Sstevel@tonic-gate 		case DATA_TYPE_INT32_ARRAY: {
1907c478bd9Sstevel@tonic-gate 			int32_t *val;
1917c478bd9Sstevel@tonic-gate 			(void) nvpair_value_int32_array(nvp, &val, &nelem);
1927c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
1937c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " %d", val[i]);
1947c478bd9Sstevel@tonic-gate 			break;
1957c478bd9Sstevel@tonic-gate 		}
1967c478bd9Sstevel@tonic-gate 		case DATA_TYPE_UINT32_ARRAY: {
1977c478bd9Sstevel@tonic-gate 			uint32_t *val;
1987c478bd9Sstevel@tonic-gate 			(void) nvpair_value_uint32_array(nvp, &val, &nelem);
1997c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
2007c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " 0x%x", val[i]);
2017c478bd9Sstevel@tonic-gate 			break;
2027c478bd9Sstevel@tonic-gate 		}
2037c478bd9Sstevel@tonic-gate 		case DATA_TYPE_INT64_ARRAY: {
2047c478bd9Sstevel@tonic-gate 			int64_t *val;
2057c478bd9Sstevel@tonic-gate 			(void) nvpair_value_int64_array(nvp, &val, &nelem);
2067c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
2077c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " %lld", (longlong_t)val[i]);
2087c478bd9Sstevel@tonic-gate 			break;
2097c478bd9Sstevel@tonic-gate 		}
2107c478bd9Sstevel@tonic-gate 		case DATA_TYPE_UINT64_ARRAY: {
2117c478bd9Sstevel@tonic-gate 			uint64_t *val;
2127c478bd9Sstevel@tonic-gate 			(void) nvpair_value_uint64_array(nvp, &val, &nelem);
2137c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
2147c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " 0x%llx",
2157c478bd9Sstevel@tonic-gate 				    (u_longlong_t)val[i]);
2167c478bd9Sstevel@tonic-gate 			break;
2177c478bd9Sstevel@tonic-gate 		}
2187c478bd9Sstevel@tonic-gate 		case DATA_TYPE_STRING_ARRAY: {
2197c478bd9Sstevel@tonic-gate 			char **val;
2207c478bd9Sstevel@tonic-gate 			(void) nvpair_value_string_array(nvp, &val, &nelem);
2217c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
2227c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " %s", val[i]);
2237c478bd9Sstevel@tonic-gate 			break;
2247c478bd9Sstevel@tonic-gate 		}
2257c478bd9Sstevel@tonic-gate 		case DATA_TYPE_HRTIME: {
2267c478bd9Sstevel@tonic-gate 			hrtime_t val;
2277c478bd9Sstevel@tonic-gate 			(void) nvpair_value_hrtime(nvp, &val);
2287c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " 0x%llx", val);
2297c478bd9Sstevel@tonic-gate 			break;
2307c478bd9Sstevel@tonic-gate 		}
2317c478bd9Sstevel@tonic-gate 		case DATA_TYPE_NVLIST: {
2327c478bd9Sstevel@tonic-gate 			nvlist_t *val;
2337c478bd9Sstevel@tonic-gate 			(void) nvpair_value_nvlist(nvp, &val);
2347c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " (embedded nvlist)\n");
2357c478bd9Sstevel@tonic-gate 			nvlist_print_with_indent(fp, val, depth + 1);
2367c478bd9Sstevel@tonic-gate 			indent(fp, depth + 1);
2377c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, "(end %s)\n", name);
2387c478bd9Sstevel@tonic-gate 			break;
2397c478bd9Sstevel@tonic-gate 		}
2407c478bd9Sstevel@tonic-gate 		case DATA_TYPE_NVLIST_ARRAY: {
2417c478bd9Sstevel@tonic-gate 			nvlist_t **val;
2427c478bd9Sstevel@tonic-gate 			(void) nvpair_value_nvlist_array(nvp, &val, &nelem);
2437c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " (array of embedded nvlists)\n");
2447c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++) {
2457c478bd9Sstevel@tonic-gate 				indent(fp, depth + 1);
2467c478bd9Sstevel@tonic-gate 				(void) fprintf(fp,
2477c478bd9Sstevel@tonic-gate 				    "(start %s[%d])\n", name, i);
2487c478bd9Sstevel@tonic-gate 				nvlist_print_with_indent(fp, val[i], depth + 1);
2497c478bd9Sstevel@tonic-gate 				indent(fp, depth + 1);
2507c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, "(end %s[%d])\n", name, i);
2517c478bd9Sstevel@tonic-gate 			}
2527c478bd9Sstevel@tonic-gate 			break;
2537c478bd9Sstevel@tonic-gate 		}
2547c478bd9Sstevel@tonic-gate 		default:
2557c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " unknown data type (%d)", type);
2567c478bd9Sstevel@tonic-gate 			break;
2577c478bd9Sstevel@tonic-gate 		}
2587c478bd9Sstevel@tonic-gate 		(void) fprintf(fp, "\n");
2597c478bd9Sstevel@tonic-gate 		nvp = nvlist_next_nvpair(nvl, nvp);
2607c478bd9Sstevel@tonic-gate 	}
2617c478bd9Sstevel@tonic-gate }
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate void
2647c478bd9Sstevel@tonic-gate nvlist_print(FILE *fp, nvlist_t *nvl)
2657c478bd9Sstevel@tonic-gate {
2667c478bd9Sstevel@tonic-gate 	nvlist_print_with_indent(fp, nvl, 0);
2677c478bd9Sstevel@tonic-gate }
268*602ca9eaScth 
269*602ca9eaScth /*
270*602ca9eaScth  * Determine if string 'value' matches 'nvp' value.  The 'value' string is
271*602ca9eaScth  * converted, depending on the type of 'nvp', prior to match.  For numeric
272*602ca9eaScth  * types, a radix independent sscanf conversion of 'value' is used. If 'nvp'
273*602ca9eaScth  * is an array type, 'ai' is the index into the array against which we are
274*602ca9eaScth  * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass
275*602ca9eaScth  * in a regex_t compilation of value in 'value_regex' to trigger regular
276*602ca9eaScth  * expression string match instead of simple strcmp().
277*602ca9eaScth  *
278*602ca9eaScth  * Return 1 on match, 0 on no-match, and -1 on error.  If the error is
279*602ca9eaScth  * related to value syntax error and 'ep' is non-NULL, *ep will point into
280*602ca9eaScth  * the 'value' string at the location where the error exists.
281*602ca9eaScth  *
282*602ca9eaScth  * NOTE: It may be possible to move the non-regex_t version of this into
283*602ca9eaScth  * common code used by library/kernel/boot.
284*602ca9eaScth  */
285*602ca9eaScth int
286*602ca9eaScth nvpair_value_match_regex(nvpair_t *nvp, int ai,
287*602ca9eaScth     char *value, regex_t *value_regex, char **ep)
288*602ca9eaScth {
289*602ca9eaScth 	char	*evalue;
290*602ca9eaScth 	uint_t	a_len;
291*602ca9eaScth 	int	sr;
292*602ca9eaScth 
293*602ca9eaScth 	if (ep)
294*602ca9eaScth 		*ep = NULL;
295*602ca9eaScth 
296*602ca9eaScth 	if ((nvp == NULL) || (value == NULL))
297*602ca9eaScth 		return (-1);		/* error fail match - invalid args */
298*602ca9eaScth 
299*602ca9eaScth 	/* make sure array and index combination make sense */
300*602ca9eaScth 	if ((nvpair_type_is_array(nvp) && (ai < 0)) ||
301*602ca9eaScth 	    (!nvpair_type_is_array(nvp) && (ai >= 0)))
302*602ca9eaScth 		return (-1);		/* error fail match - bad index */
303*602ca9eaScth 
304*602ca9eaScth 	/* non-string values should be single 'chunk' */
305*602ca9eaScth 	if ((nvpair_type(nvp) != DATA_TYPE_STRING) &&
306*602ca9eaScth 	    (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) {
307*602ca9eaScth 		value += strspn(value, " \t");
308*602ca9eaScth 		evalue = value + strcspn(value, " \t");
309*602ca9eaScth 		if (*evalue) {
310*602ca9eaScth 			if (ep)
311*602ca9eaScth 				*ep = evalue;
312*602ca9eaScth 			return (-1);	/* error fail match - syntax */
313*602ca9eaScth 		}
314*602ca9eaScth 	}
315*602ca9eaScth 
316*602ca9eaScth 	sr = EOF;
317*602ca9eaScth 	switch (nvpair_type(nvp)) {
318*602ca9eaScth 	case DATA_TYPE_STRING: {
319*602ca9eaScth 		char	*val;
320*602ca9eaScth 
321*602ca9eaScth 		/* check string value for match */
322*602ca9eaScth 		if (nvpair_value_string(nvp, &val) == 0) {
323*602ca9eaScth 			if (value_regex) {
324*602ca9eaScth 				if (regexec(value_regex, val,
325*602ca9eaScth 				    (size_t)0, NULL, 0) == 0)
326*602ca9eaScth 					return (1);	/* match */
327*602ca9eaScth 			} else {
328*602ca9eaScth 				if (strcmp(value, val) == 0)
329*602ca9eaScth 					return (1);	/* match */
330*602ca9eaScth 			}
331*602ca9eaScth 		}
332*602ca9eaScth 		break;
333*602ca9eaScth 	}
334*602ca9eaScth 	case DATA_TYPE_STRING_ARRAY: {
335*602ca9eaScth 		char **val_array;
336*602ca9eaScth 
337*602ca9eaScth 		/* check indexed string value of array for match */
338*602ca9eaScth 		if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) &&
339*602ca9eaScth 		    (ai < a_len)) {
340*602ca9eaScth 			if (value_regex) {
341*602ca9eaScth 				if (regexec(value_regex, val_array[ai],
342*602ca9eaScth 				    (size_t)0, NULL, 0) == 0)
343*602ca9eaScth 					return (1);
344*602ca9eaScth 			} else {
345*602ca9eaScth 				if (strcmp(value, val_array[ai]) == 0)
346*602ca9eaScth 					return (1);
347*602ca9eaScth 			}
348*602ca9eaScth 		}
349*602ca9eaScth 		break;
350*602ca9eaScth 	}
351*602ca9eaScth 	case DATA_TYPE_BYTE: {
352*602ca9eaScth 		uchar_t val, val_arg;
353*602ca9eaScth 
354*602ca9eaScth 		/* scanf uchar_t from value and check for match */
355*602ca9eaScth 		sr = sscanf(value, "%c", &val_arg);
356*602ca9eaScth 		if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) &&
357*602ca9eaScth 		    (val == val_arg))
358*602ca9eaScth 			return (1);
359*602ca9eaScth 		break;
360*602ca9eaScth 	}
361*602ca9eaScth 	case DATA_TYPE_BYTE_ARRAY: {
362*602ca9eaScth 		uchar_t *val_array, val_arg;
363*602ca9eaScth 
364*602ca9eaScth 
365*602ca9eaScth 		/* check indexed value of array for match */
366*602ca9eaScth 		sr = sscanf(value, "%c", &val_arg);
367*602ca9eaScth 		if ((sr == 1) &&
368*602ca9eaScth 		    (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) &&
369*602ca9eaScth 		    (ai < a_len) &&
370*602ca9eaScth 		    (val_array[ai] == val_arg))
371*602ca9eaScth 			return (1);
372*602ca9eaScth 		break;
373*602ca9eaScth 	}
374*602ca9eaScth 	case DATA_TYPE_INT8: {
375*602ca9eaScth 		int8_t val, val_arg;
376*602ca9eaScth 
377*602ca9eaScth 		/* scanf int8_t from value and check for match */
378*602ca9eaScth 		sr = sscanf(value, "%"SCNi8, &val_arg);
379*602ca9eaScth 		if ((sr == 1) &&
380*602ca9eaScth 		    (nvpair_value_int8(nvp, &val) == 0) &&
381*602ca9eaScth 		    (val == val_arg))
382*602ca9eaScth 			return (1);
383*602ca9eaScth 		break;
384*602ca9eaScth 	}
385*602ca9eaScth 	case DATA_TYPE_INT8_ARRAY: {
386*602ca9eaScth 		int8_t *val_array, val_arg;
387*602ca9eaScth 
388*602ca9eaScth 		/* check indexed value of array for match */
389*602ca9eaScth 		sr = sscanf(value, "%"SCNi8, &val_arg);
390*602ca9eaScth 		if ((sr == 1) &&
391*602ca9eaScth 		    (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) &&
392*602ca9eaScth 		    (ai < a_len) &&
393*602ca9eaScth 		    (val_array[ai] == val_arg))
394*602ca9eaScth 			return (1);
395*602ca9eaScth 		break;
396*602ca9eaScth 	}
397*602ca9eaScth 	case DATA_TYPE_UINT8: {
398*602ca9eaScth 		uint8_t val, val_arg;
399*602ca9eaScth 
400*602ca9eaScth 		/* scanf uint8_t from value and check for match */
401*602ca9eaScth 		sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
402*602ca9eaScth 		if ((sr == 1) &&
403*602ca9eaScth 		    (nvpair_value_uint8(nvp, &val) == 0) &&
404*602ca9eaScth 		    (val == val_arg))
405*602ca9eaScth 			return (1);
406*602ca9eaScth 		break;
407*602ca9eaScth 	}
408*602ca9eaScth 	case DATA_TYPE_UINT8_ARRAY: {
409*602ca9eaScth 		uint8_t *val_array, val_arg;
410*602ca9eaScth 
411*602ca9eaScth 		/* check indexed value of array for match */
412*602ca9eaScth 		sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
413*602ca9eaScth 		if ((sr == 1) &&
414*602ca9eaScth 		    (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) &&
415*602ca9eaScth 		    (ai < a_len) &&
416*602ca9eaScth 		    (val_array[ai] == val_arg))
417*602ca9eaScth 			return (1);
418*602ca9eaScth 		break;
419*602ca9eaScth 	}
420*602ca9eaScth 	case DATA_TYPE_INT16: {
421*602ca9eaScth 		int16_t val, val_arg;
422*602ca9eaScth 
423*602ca9eaScth 		/* scanf int16_t from value and check for match */
424*602ca9eaScth 		sr = sscanf(value, "%"SCNi16, &val_arg);
425*602ca9eaScth 		if ((sr == 1) &&
426*602ca9eaScth 		    (nvpair_value_int16(nvp, &val) == 0) &&
427*602ca9eaScth 		    (val == val_arg))
428*602ca9eaScth 			return (1);
429*602ca9eaScth 		break;
430*602ca9eaScth 	}
431*602ca9eaScth 	case DATA_TYPE_INT16_ARRAY: {
432*602ca9eaScth 		int16_t *val_array, val_arg;
433*602ca9eaScth 
434*602ca9eaScth 		/* check indexed value of array for match */
435*602ca9eaScth 		sr = sscanf(value, "%"SCNi16, &val_arg);
436*602ca9eaScth 		if ((sr == 1) &&
437*602ca9eaScth 		    (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) &&
438*602ca9eaScth 		    (ai < a_len) &&
439*602ca9eaScth 		    (val_array[ai] == val_arg))
440*602ca9eaScth 			return (1);
441*602ca9eaScth 		break;
442*602ca9eaScth 	}
443*602ca9eaScth 	case DATA_TYPE_UINT16: {
444*602ca9eaScth 		uint16_t val, val_arg;
445*602ca9eaScth 
446*602ca9eaScth 		/* scanf uint16_t from value and check for match */
447*602ca9eaScth 		sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
448*602ca9eaScth 		if ((sr == 1) &&
449*602ca9eaScth 		    (nvpair_value_uint16(nvp, &val) == 0) &&
450*602ca9eaScth 		    (val == val_arg))
451*602ca9eaScth 			return (1);
452*602ca9eaScth 		break;
453*602ca9eaScth 	}
454*602ca9eaScth 	case DATA_TYPE_UINT16_ARRAY: {
455*602ca9eaScth 		uint16_t *val_array, val_arg;
456*602ca9eaScth 
457*602ca9eaScth 		/* check indexed value of array for match */
458*602ca9eaScth 		sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
459*602ca9eaScth 		if ((sr == 1) &&
460*602ca9eaScth 		    (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) &&
461*602ca9eaScth 		    (ai < a_len) &&
462*602ca9eaScth 		    (val_array[ai] == val_arg))
463*602ca9eaScth 			return (1);
464*602ca9eaScth 		break;
465*602ca9eaScth 	}
466*602ca9eaScth 	case DATA_TYPE_INT32: {
467*602ca9eaScth 		int32_t val, val_arg;
468*602ca9eaScth 
469*602ca9eaScth 		/* scanf int32_t from value and check for match */
470*602ca9eaScth 		sr = sscanf(value, "%"SCNi32, &val_arg);
471*602ca9eaScth 		if ((sr == 1) &&
472*602ca9eaScth 		    (nvpair_value_int32(nvp, &val) == 0) &&
473*602ca9eaScth 		    (val == val_arg))
474*602ca9eaScth 			return (1);
475*602ca9eaScth 		break;
476*602ca9eaScth 	}
477*602ca9eaScth 	case DATA_TYPE_INT32_ARRAY: {
478*602ca9eaScth 		int32_t *val_array, val_arg;
479*602ca9eaScth 
480*602ca9eaScth 		/* check indexed value of array for match */
481*602ca9eaScth 		sr = sscanf(value, "%"SCNi32, &val_arg);
482*602ca9eaScth 		if ((sr == 1) &&
483*602ca9eaScth 		    (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) &&
484*602ca9eaScth 		    (ai < a_len) &&
485*602ca9eaScth 		    (val_array[ai] == val_arg))
486*602ca9eaScth 			return (1);
487*602ca9eaScth 		break;
488*602ca9eaScth 	}
489*602ca9eaScth 	case DATA_TYPE_UINT32: {
490*602ca9eaScth 		uint32_t val, val_arg;
491*602ca9eaScth 
492*602ca9eaScth 		/* scanf uint32_t from value and check for match */
493*602ca9eaScth 		sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
494*602ca9eaScth 		if ((sr == 1) &&
495*602ca9eaScth 		    (nvpair_value_uint32(nvp, &val) == 0) &&
496*602ca9eaScth 		    (val == val_arg))
497*602ca9eaScth 			return (1);
498*602ca9eaScth 		break;
499*602ca9eaScth 	}
500*602ca9eaScth 	case DATA_TYPE_UINT32_ARRAY: {
501*602ca9eaScth 		uint32_t *val_array, val_arg;
502*602ca9eaScth 
503*602ca9eaScth 		/* check indexed value of array for match */
504*602ca9eaScth 		sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
505*602ca9eaScth 		if ((sr == 1) &&
506*602ca9eaScth 		    (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) &&
507*602ca9eaScth 		    (ai < a_len) &&
508*602ca9eaScth 		    (val_array[ai] == val_arg))
509*602ca9eaScth 			return (1);
510*602ca9eaScth 		break;
511*602ca9eaScth 	}
512*602ca9eaScth 	case DATA_TYPE_INT64: {
513*602ca9eaScth 		int64_t val, val_arg;
514*602ca9eaScth 
515*602ca9eaScth 		/* scanf int64_t from value and check for match */
516*602ca9eaScth 		sr = sscanf(value, "%"SCNi64, &val_arg);
517*602ca9eaScth 		if ((sr == 1) &&
518*602ca9eaScth 		    (nvpair_value_int64(nvp, &val) == 0) &&
519*602ca9eaScth 		    (val == val_arg))
520*602ca9eaScth 			return (1);
521*602ca9eaScth 		break;
522*602ca9eaScth 	}
523*602ca9eaScth 	case DATA_TYPE_INT64_ARRAY: {
524*602ca9eaScth 		int64_t *val_array, val_arg;
525*602ca9eaScth 
526*602ca9eaScth 		/* check indexed value of array for match */
527*602ca9eaScth 		sr = sscanf(value, "%"SCNi64, &val_arg);
528*602ca9eaScth 		if ((sr == 1) &&
529*602ca9eaScth 		    (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) &&
530*602ca9eaScth 		    (ai < a_len) &&
531*602ca9eaScth 		    (val_array[ai] == val_arg))
532*602ca9eaScth 				return (1);
533*602ca9eaScth 		break;
534*602ca9eaScth 	}
535*602ca9eaScth 	case DATA_TYPE_UINT64: {
536*602ca9eaScth 		uint64_t val_arg, val;
537*602ca9eaScth 
538*602ca9eaScth 		/* scanf uint64_t from value and check for match */
539*602ca9eaScth 		sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
540*602ca9eaScth 		if ((sr == 1) &&
541*602ca9eaScth 		    (nvpair_value_uint64(nvp, &val) == 0) &&
542*602ca9eaScth 		    (val == val_arg))
543*602ca9eaScth 			return (1);
544*602ca9eaScth 		break;
545*602ca9eaScth 	}
546*602ca9eaScth 	case DATA_TYPE_UINT64_ARRAY: {
547*602ca9eaScth 		uint64_t *val_array, val_arg;
548*602ca9eaScth 
549*602ca9eaScth 		/* check indexed value of array for match */
550*602ca9eaScth 		sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
551*602ca9eaScth 		if ((sr == 1) &&
552*602ca9eaScth 		    (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) &&
553*602ca9eaScth 		    (ai < a_len) &&
554*602ca9eaScth 		    (val_array[ai] == val_arg))
555*602ca9eaScth 			return (1);
556*602ca9eaScth 		break;
557*602ca9eaScth 	}
558*602ca9eaScth 	case DATA_TYPE_BOOLEAN_VALUE: {
559*602ca9eaScth 		boolean_t val, val_arg;
560*602ca9eaScth 
561*602ca9eaScth 		/* scanf boolean_t from value and check for match */
562*602ca9eaScth 		sr = sscanf(value, "%"SCNi32, &val_arg);
563*602ca9eaScth 		if ((sr == 1) &&
564*602ca9eaScth 		    (nvpair_value_boolean_value(nvp, &val) == 0) &&
565*602ca9eaScth 		    (val == val_arg))
566*602ca9eaScth 			return (1);
567*602ca9eaScth 		break;
568*602ca9eaScth 	}
569*602ca9eaScth 	case DATA_TYPE_BOOLEAN_ARRAY: {
570*602ca9eaScth 		boolean_t *val_array, val_arg;
571*602ca9eaScth 
572*602ca9eaScth 		/* check indexed value of array for match */
573*602ca9eaScth 		sr = sscanf(value, "%"SCNi32, &val_arg);
574*602ca9eaScth 		if ((sr == 1) &&
575*602ca9eaScth 		    (nvpair_value_boolean_array(nvp,
576*602ca9eaScth 		    &val_array, &a_len) == 0) &&
577*602ca9eaScth 		    (ai < a_len) &&
578*602ca9eaScth 		    (val_array[ai] == val_arg))
579*602ca9eaScth 			return (1);
580*602ca9eaScth 		break;
581*602ca9eaScth 	}
582*602ca9eaScth 	case DATA_TYPE_HRTIME:
583*602ca9eaScth 	case DATA_TYPE_NVLIST:
584*602ca9eaScth 	case DATA_TYPE_NVLIST_ARRAY:
585*602ca9eaScth 	case DATA_TYPE_BOOLEAN:
586*602ca9eaScth 	case DATA_TYPE_UNKNOWN:
587*602ca9eaScth 	default:
588*602ca9eaScth 		/*
589*602ca9eaScth 		 * unknown/unsupported data type
590*602ca9eaScth 		 */
591*602ca9eaScth 		return (-1);		/* error fail match */
592*602ca9eaScth 	}
593*602ca9eaScth 
594*602ca9eaScth 	/*
595*602ca9eaScth 	 * check to see if sscanf failed conversion, return approximate
596*602ca9eaScth 	 * pointer to problem
597*602ca9eaScth 	 */
598*602ca9eaScth 	if (sr != 1) {
599*602ca9eaScth 		if (ep)
600*602ca9eaScth 			*ep = value;
601*602ca9eaScth 		return (-1);		/* error fail match  - syntax */
602*602ca9eaScth 	}
603*602ca9eaScth 
604*602ca9eaScth 	return (0);			/* fail match */
605*602ca9eaScth }
606*602ca9eaScth 
607*602ca9eaScth int
608*602ca9eaScth nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep)
609*602ca9eaScth {
610*602ca9eaScth 	return (nvpair_value_match_regex(nvp, ai, value, NULL, ep));
611*602ca9eaScth }
612