xref: /titanic_50/usr/src/lib/libnvpair/libnvpair.c (revision 825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77)
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
5602ca9eaScth  * Common Development and Distribution License (the "License").
6602ca9eaScth  * 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 /*
22602ca9eaScth  * 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>
30602ca9eaScth #include <sys/types.h>
31602ca9eaScth #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 		}
141*825ba0f2Srobj 		case DATA_TYPE_DOUBLE: {
142*825ba0f2Srobj 			double val;
143*825ba0f2Srobj 			(void) nvpair_value_double(nvp, &val);
144*825ba0f2Srobj 			(void) fprintf(fp, " 0x%llf", val);
145*825ba0f2Srobj 			break;
146*825ba0f2Srobj 		}
1477c478bd9Sstevel@tonic-gate 		case DATA_TYPE_STRING: {
1487c478bd9Sstevel@tonic-gate 			char *val;
1497c478bd9Sstevel@tonic-gate 			(void) nvpair_value_string(nvp, &val);
1507c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " %s", val);
1517c478bd9Sstevel@tonic-gate 			break;
1527c478bd9Sstevel@tonic-gate 		}
1537c478bd9Sstevel@tonic-gate 		case DATA_TYPE_BOOLEAN_ARRAY: {
1547c478bd9Sstevel@tonic-gate 			boolean_t *val;
1557c478bd9Sstevel@tonic-gate 			(void) nvpair_value_boolean_array(nvp, &val, &nelem);
1567c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
1577c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " %d", val[i]);
1587c478bd9Sstevel@tonic-gate 			break;
1597c478bd9Sstevel@tonic-gate 		}
1607c478bd9Sstevel@tonic-gate 		case DATA_TYPE_BYTE_ARRAY: {
1617c478bd9Sstevel@tonic-gate 			uchar_t *val;
1627c478bd9Sstevel@tonic-gate 			(void) nvpair_value_byte_array(nvp, &val, &nelem);
1637c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
1647c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " 0x%2.2x", val[i]);
1657c478bd9Sstevel@tonic-gate 			break;
1667c478bd9Sstevel@tonic-gate 		}
1677c478bd9Sstevel@tonic-gate 		case DATA_TYPE_INT8_ARRAY: {
1687c478bd9Sstevel@tonic-gate 			int8_t *val;
1697c478bd9Sstevel@tonic-gate 			(void) nvpair_value_int8_array(nvp, &val, &nelem);
1707c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
1717c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " %d", val[i]);
1727c478bd9Sstevel@tonic-gate 			break;
1737c478bd9Sstevel@tonic-gate 		}
1747c478bd9Sstevel@tonic-gate 		case DATA_TYPE_UINT8_ARRAY: {
1757c478bd9Sstevel@tonic-gate 			uint8_t *val;
1767c478bd9Sstevel@tonic-gate 			(void) nvpair_value_uint8_array(nvp, &val, &nelem);
1777c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
1787c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " 0x%x", val[i]);
1797c478bd9Sstevel@tonic-gate 			break;
1807c478bd9Sstevel@tonic-gate 		}
1817c478bd9Sstevel@tonic-gate 		case DATA_TYPE_INT16_ARRAY: {
1827c478bd9Sstevel@tonic-gate 			int16_t *val;
1837c478bd9Sstevel@tonic-gate 			(void) nvpair_value_int16_array(nvp, &val, &nelem);
1847c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
1857c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " %d", val[i]);
1867c478bd9Sstevel@tonic-gate 			break;
1877c478bd9Sstevel@tonic-gate 		}
1887c478bd9Sstevel@tonic-gate 		case DATA_TYPE_UINT16_ARRAY: {
1897c478bd9Sstevel@tonic-gate 			uint16_t *val;
1907c478bd9Sstevel@tonic-gate 			(void) nvpair_value_uint16_array(nvp, &val, &nelem);
1917c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
1927c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " 0x%x", val[i]);
1937c478bd9Sstevel@tonic-gate 			break;
1947c478bd9Sstevel@tonic-gate 		}
1957c478bd9Sstevel@tonic-gate 		case DATA_TYPE_INT32_ARRAY: {
1967c478bd9Sstevel@tonic-gate 			int32_t *val;
1977c478bd9Sstevel@tonic-gate 			(void) nvpair_value_int32_array(nvp, &val, &nelem);
1987c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
1997c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " %d", val[i]);
2007c478bd9Sstevel@tonic-gate 			break;
2017c478bd9Sstevel@tonic-gate 		}
2027c478bd9Sstevel@tonic-gate 		case DATA_TYPE_UINT32_ARRAY: {
2037c478bd9Sstevel@tonic-gate 			uint32_t *val;
2047c478bd9Sstevel@tonic-gate 			(void) nvpair_value_uint32_array(nvp, &val, &nelem);
2057c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
2067c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " 0x%x", val[i]);
2077c478bd9Sstevel@tonic-gate 			break;
2087c478bd9Sstevel@tonic-gate 		}
2097c478bd9Sstevel@tonic-gate 		case DATA_TYPE_INT64_ARRAY: {
2107c478bd9Sstevel@tonic-gate 			int64_t *val;
2117c478bd9Sstevel@tonic-gate 			(void) nvpair_value_int64_array(nvp, &val, &nelem);
2127c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
2137c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " %lld", (longlong_t)val[i]);
2147c478bd9Sstevel@tonic-gate 			break;
2157c478bd9Sstevel@tonic-gate 		}
2167c478bd9Sstevel@tonic-gate 		case DATA_TYPE_UINT64_ARRAY: {
2177c478bd9Sstevel@tonic-gate 			uint64_t *val;
2187c478bd9Sstevel@tonic-gate 			(void) nvpair_value_uint64_array(nvp, &val, &nelem);
2197c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
2207c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " 0x%llx",
2217c478bd9Sstevel@tonic-gate 				    (u_longlong_t)val[i]);
2227c478bd9Sstevel@tonic-gate 			break;
2237c478bd9Sstevel@tonic-gate 		}
2247c478bd9Sstevel@tonic-gate 		case DATA_TYPE_STRING_ARRAY: {
2257c478bd9Sstevel@tonic-gate 			char **val;
2267c478bd9Sstevel@tonic-gate 			(void) nvpair_value_string_array(nvp, &val, &nelem);
2277c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++)
2287c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, " %s", val[i]);
2297c478bd9Sstevel@tonic-gate 			break;
2307c478bd9Sstevel@tonic-gate 		}
2317c478bd9Sstevel@tonic-gate 		case DATA_TYPE_HRTIME: {
2327c478bd9Sstevel@tonic-gate 			hrtime_t val;
2337c478bd9Sstevel@tonic-gate 			(void) nvpair_value_hrtime(nvp, &val);
2347c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " 0x%llx", val);
2357c478bd9Sstevel@tonic-gate 			break;
2367c478bd9Sstevel@tonic-gate 		}
2377c478bd9Sstevel@tonic-gate 		case DATA_TYPE_NVLIST: {
2387c478bd9Sstevel@tonic-gate 			nvlist_t *val;
2397c478bd9Sstevel@tonic-gate 			(void) nvpair_value_nvlist(nvp, &val);
2407c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " (embedded nvlist)\n");
2417c478bd9Sstevel@tonic-gate 			nvlist_print_with_indent(fp, val, depth + 1);
2427c478bd9Sstevel@tonic-gate 			indent(fp, depth + 1);
2437c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, "(end %s)\n", name);
2447c478bd9Sstevel@tonic-gate 			break;
2457c478bd9Sstevel@tonic-gate 		}
2467c478bd9Sstevel@tonic-gate 		case DATA_TYPE_NVLIST_ARRAY: {
2477c478bd9Sstevel@tonic-gate 			nvlist_t **val;
2487c478bd9Sstevel@tonic-gate 			(void) nvpair_value_nvlist_array(nvp, &val, &nelem);
2497c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " (array of embedded nvlists)\n");
2507c478bd9Sstevel@tonic-gate 			for (i = 0; i < nelem; i++) {
2517c478bd9Sstevel@tonic-gate 				indent(fp, depth + 1);
2527c478bd9Sstevel@tonic-gate 				(void) fprintf(fp,
2537c478bd9Sstevel@tonic-gate 				    "(start %s[%d])\n", name, i);
2547c478bd9Sstevel@tonic-gate 				nvlist_print_with_indent(fp, val[i], depth + 1);
2557c478bd9Sstevel@tonic-gate 				indent(fp, depth + 1);
2567c478bd9Sstevel@tonic-gate 				(void) fprintf(fp, "(end %s[%d])\n", name, i);
2577c478bd9Sstevel@tonic-gate 			}
2587c478bd9Sstevel@tonic-gate 			break;
2597c478bd9Sstevel@tonic-gate 		}
2607c478bd9Sstevel@tonic-gate 		default:
2617c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, " unknown data type (%d)", type);
2627c478bd9Sstevel@tonic-gate 			break;
2637c478bd9Sstevel@tonic-gate 		}
2647c478bd9Sstevel@tonic-gate 		(void) fprintf(fp, "\n");
2657c478bd9Sstevel@tonic-gate 		nvp = nvlist_next_nvpair(nvl, nvp);
2667c478bd9Sstevel@tonic-gate 	}
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate void
2707c478bd9Sstevel@tonic-gate nvlist_print(FILE *fp, nvlist_t *nvl)
2717c478bd9Sstevel@tonic-gate {
2727c478bd9Sstevel@tonic-gate 	nvlist_print_with_indent(fp, nvl, 0);
2737c478bd9Sstevel@tonic-gate }
274602ca9eaScth 
275602ca9eaScth /*
276602ca9eaScth  * Determine if string 'value' matches 'nvp' value.  The 'value' string is
277602ca9eaScth  * converted, depending on the type of 'nvp', prior to match.  For numeric
278602ca9eaScth  * types, a radix independent sscanf conversion of 'value' is used. If 'nvp'
279602ca9eaScth  * is an array type, 'ai' is the index into the array against which we are
280602ca9eaScth  * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass
281602ca9eaScth  * in a regex_t compilation of value in 'value_regex' to trigger regular
282602ca9eaScth  * expression string match instead of simple strcmp().
283602ca9eaScth  *
284602ca9eaScth  * Return 1 on match, 0 on no-match, and -1 on error.  If the error is
285602ca9eaScth  * related to value syntax error and 'ep' is non-NULL, *ep will point into
286602ca9eaScth  * the 'value' string at the location where the error exists.
287602ca9eaScth  *
288602ca9eaScth  * NOTE: It may be possible to move the non-regex_t version of this into
289602ca9eaScth  * common code used by library/kernel/boot.
290602ca9eaScth  */
291602ca9eaScth int
292602ca9eaScth nvpair_value_match_regex(nvpair_t *nvp, int ai,
293602ca9eaScth     char *value, regex_t *value_regex, char **ep)
294602ca9eaScth {
295602ca9eaScth 	char	*evalue;
296602ca9eaScth 	uint_t	a_len;
297602ca9eaScth 	int	sr;
298602ca9eaScth 
299602ca9eaScth 	if (ep)
300602ca9eaScth 		*ep = NULL;
301602ca9eaScth 
302602ca9eaScth 	if ((nvp == NULL) || (value == NULL))
303602ca9eaScth 		return (-1);		/* error fail match - invalid args */
304602ca9eaScth 
305602ca9eaScth 	/* make sure array and index combination make sense */
306602ca9eaScth 	if ((nvpair_type_is_array(nvp) && (ai < 0)) ||
307602ca9eaScth 	    (!nvpair_type_is_array(nvp) && (ai >= 0)))
308602ca9eaScth 		return (-1);		/* error fail match - bad index */
309602ca9eaScth 
310602ca9eaScth 	/* non-string values should be single 'chunk' */
311602ca9eaScth 	if ((nvpair_type(nvp) != DATA_TYPE_STRING) &&
312602ca9eaScth 	    (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) {
313602ca9eaScth 		value += strspn(value, " \t");
314602ca9eaScth 		evalue = value + strcspn(value, " \t");
315602ca9eaScth 		if (*evalue) {
316602ca9eaScth 			if (ep)
317602ca9eaScth 				*ep = evalue;
318602ca9eaScth 			return (-1);	/* error fail match - syntax */
319602ca9eaScth 		}
320602ca9eaScth 	}
321602ca9eaScth 
322602ca9eaScth 	sr = EOF;
323602ca9eaScth 	switch (nvpair_type(nvp)) {
324602ca9eaScth 	case DATA_TYPE_STRING: {
325602ca9eaScth 		char	*val;
326602ca9eaScth 
327602ca9eaScth 		/* check string value for match */
328602ca9eaScth 		if (nvpair_value_string(nvp, &val) == 0) {
329602ca9eaScth 			if (value_regex) {
330602ca9eaScth 				if (regexec(value_regex, val,
331602ca9eaScth 				    (size_t)0, NULL, 0) == 0)
332602ca9eaScth 					return (1);	/* match */
333602ca9eaScth 			} else {
334602ca9eaScth 				if (strcmp(value, val) == 0)
335602ca9eaScth 					return (1);	/* match */
336602ca9eaScth 			}
337602ca9eaScth 		}
338602ca9eaScth 		break;
339602ca9eaScth 	}
340602ca9eaScth 	case DATA_TYPE_STRING_ARRAY: {
341602ca9eaScth 		char **val_array;
342602ca9eaScth 
343602ca9eaScth 		/* check indexed string value of array for match */
344602ca9eaScth 		if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) &&
345602ca9eaScth 		    (ai < a_len)) {
346602ca9eaScth 			if (value_regex) {
347602ca9eaScth 				if (regexec(value_regex, val_array[ai],
348602ca9eaScth 				    (size_t)0, NULL, 0) == 0)
349602ca9eaScth 					return (1);
350602ca9eaScth 			} else {
351602ca9eaScth 				if (strcmp(value, val_array[ai]) == 0)
352602ca9eaScth 					return (1);
353602ca9eaScth 			}
354602ca9eaScth 		}
355602ca9eaScth 		break;
356602ca9eaScth 	}
357602ca9eaScth 	case DATA_TYPE_BYTE: {
358602ca9eaScth 		uchar_t val, val_arg;
359602ca9eaScth 
360602ca9eaScth 		/* scanf uchar_t from value and check for match */
361602ca9eaScth 		sr = sscanf(value, "%c", &val_arg);
362602ca9eaScth 		if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) &&
363602ca9eaScth 		    (val == val_arg))
364602ca9eaScth 			return (1);
365602ca9eaScth 		break;
366602ca9eaScth 	}
367602ca9eaScth 	case DATA_TYPE_BYTE_ARRAY: {
368602ca9eaScth 		uchar_t *val_array, val_arg;
369602ca9eaScth 
370602ca9eaScth 
371602ca9eaScth 		/* check indexed value of array for match */
372602ca9eaScth 		sr = sscanf(value, "%c", &val_arg);
373602ca9eaScth 		if ((sr == 1) &&
374602ca9eaScth 		    (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) &&
375602ca9eaScth 		    (ai < a_len) &&
376602ca9eaScth 		    (val_array[ai] == val_arg))
377602ca9eaScth 			return (1);
378602ca9eaScth 		break;
379602ca9eaScth 	}
380602ca9eaScth 	case DATA_TYPE_INT8: {
381602ca9eaScth 		int8_t val, val_arg;
382602ca9eaScth 
383602ca9eaScth 		/* scanf int8_t from value and check for match */
384602ca9eaScth 		sr = sscanf(value, "%"SCNi8, &val_arg);
385602ca9eaScth 		if ((sr == 1) &&
386602ca9eaScth 		    (nvpair_value_int8(nvp, &val) == 0) &&
387602ca9eaScth 		    (val == val_arg))
388602ca9eaScth 			return (1);
389602ca9eaScth 		break;
390602ca9eaScth 	}
391602ca9eaScth 	case DATA_TYPE_INT8_ARRAY: {
392602ca9eaScth 		int8_t *val_array, val_arg;
393602ca9eaScth 
394602ca9eaScth 		/* check indexed value of array for match */
395602ca9eaScth 		sr = sscanf(value, "%"SCNi8, &val_arg);
396602ca9eaScth 		if ((sr == 1) &&
397602ca9eaScth 		    (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) &&
398602ca9eaScth 		    (ai < a_len) &&
399602ca9eaScth 		    (val_array[ai] == val_arg))
400602ca9eaScth 			return (1);
401602ca9eaScth 		break;
402602ca9eaScth 	}
403602ca9eaScth 	case DATA_TYPE_UINT8: {
404602ca9eaScth 		uint8_t val, val_arg;
405602ca9eaScth 
406602ca9eaScth 		/* scanf uint8_t from value and check for match */
407602ca9eaScth 		sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
408602ca9eaScth 		if ((sr == 1) &&
409602ca9eaScth 		    (nvpair_value_uint8(nvp, &val) == 0) &&
410602ca9eaScth 		    (val == val_arg))
411602ca9eaScth 			return (1);
412602ca9eaScth 		break;
413602ca9eaScth 	}
414602ca9eaScth 	case DATA_TYPE_UINT8_ARRAY: {
415602ca9eaScth 		uint8_t *val_array, val_arg;
416602ca9eaScth 
417602ca9eaScth 		/* check indexed value of array for match */
418602ca9eaScth 		sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
419602ca9eaScth 		if ((sr == 1) &&
420602ca9eaScth 		    (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) &&
421602ca9eaScth 		    (ai < a_len) &&
422602ca9eaScth 		    (val_array[ai] == val_arg))
423602ca9eaScth 			return (1);
424602ca9eaScth 		break;
425602ca9eaScth 	}
426602ca9eaScth 	case DATA_TYPE_INT16: {
427602ca9eaScth 		int16_t val, val_arg;
428602ca9eaScth 
429602ca9eaScth 		/* scanf int16_t from value and check for match */
430602ca9eaScth 		sr = sscanf(value, "%"SCNi16, &val_arg);
431602ca9eaScth 		if ((sr == 1) &&
432602ca9eaScth 		    (nvpair_value_int16(nvp, &val) == 0) &&
433602ca9eaScth 		    (val == val_arg))
434602ca9eaScth 			return (1);
435602ca9eaScth 		break;
436602ca9eaScth 	}
437602ca9eaScth 	case DATA_TYPE_INT16_ARRAY: {
438602ca9eaScth 		int16_t *val_array, val_arg;
439602ca9eaScth 
440602ca9eaScth 		/* check indexed value of array for match */
441602ca9eaScth 		sr = sscanf(value, "%"SCNi16, &val_arg);
442602ca9eaScth 		if ((sr == 1) &&
443602ca9eaScth 		    (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) &&
444602ca9eaScth 		    (ai < a_len) &&
445602ca9eaScth 		    (val_array[ai] == val_arg))
446602ca9eaScth 			return (1);
447602ca9eaScth 		break;
448602ca9eaScth 	}
449602ca9eaScth 	case DATA_TYPE_UINT16: {
450602ca9eaScth 		uint16_t val, val_arg;
451602ca9eaScth 
452602ca9eaScth 		/* scanf uint16_t from value and check for match */
453602ca9eaScth 		sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
454602ca9eaScth 		if ((sr == 1) &&
455602ca9eaScth 		    (nvpair_value_uint16(nvp, &val) == 0) &&
456602ca9eaScth 		    (val == val_arg))
457602ca9eaScth 			return (1);
458602ca9eaScth 		break;
459602ca9eaScth 	}
460602ca9eaScth 	case DATA_TYPE_UINT16_ARRAY: {
461602ca9eaScth 		uint16_t *val_array, val_arg;
462602ca9eaScth 
463602ca9eaScth 		/* check indexed value of array for match */
464602ca9eaScth 		sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
465602ca9eaScth 		if ((sr == 1) &&
466602ca9eaScth 		    (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) &&
467602ca9eaScth 		    (ai < a_len) &&
468602ca9eaScth 		    (val_array[ai] == val_arg))
469602ca9eaScth 			return (1);
470602ca9eaScth 		break;
471602ca9eaScth 	}
472602ca9eaScth 	case DATA_TYPE_INT32: {
473602ca9eaScth 		int32_t val, val_arg;
474602ca9eaScth 
475602ca9eaScth 		/* scanf int32_t from value and check for match */
476602ca9eaScth 		sr = sscanf(value, "%"SCNi32, &val_arg);
477602ca9eaScth 		if ((sr == 1) &&
478602ca9eaScth 		    (nvpair_value_int32(nvp, &val) == 0) &&
479602ca9eaScth 		    (val == val_arg))
480602ca9eaScth 			return (1);
481602ca9eaScth 		break;
482602ca9eaScth 	}
483602ca9eaScth 	case DATA_TYPE_INT32_ARRAY: {
484602ca9eaScth 		int32_t *val_array, val_arg;
485602ca9eaScth 
486602ca9eaScth 		/* check indexed value of array for match */
487602ca9eaScth 		sr = sscanf(value, "%"SCNi32, &val_arg);
488602ca9eaScth 		if ((sr == 1) &&
489602ca9eaScth 		    (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) &&
490602ca9eaScth 		    (ai < a_len) &&
491602ca9eaScth 		    (val_array[ai] == val_arg))
492602ca9eaScth 			return (1);
493602ca9eaScth 		break;
494602ca9eaScth 	}
495602ca9eaScth 	case DATA_TYPE_UINT32: {
496602ca9eaScth 		uint32_t val, val_arg;
497602ca9eaScth 
498602ca9eaScth 		/* scanf uint32_t from value and check for match */
499602ca9eaScth 		sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
500602ca9eaScth 		if ((sr == 1) &&
501602ca9eaScth 		    (nvpair_value_uint32(nvp, &val) == 0) &&
502602ca9eaScth 		    (val == val_arg))
503602ca9eaScth 			return (1);
504602ca9eaScth 		break;
505602ca9eaScth 	}
506602ca9eaScth 	case DATA_TYPE_UINT32_ARRAY: {
507602ca9eaScth 		uint32_t *val_array, val_arg;
508602ca9eaScth 
509602ca9eaScth 		/* check indexed value of array for match */
510602ca9eaScth 		sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
511602ca9eaScth 		if ((sr == 1) &&
512602ca9eaScth 		    (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) &&
513602ca9eaScth 		    (ai < a_len) &&
514602ca9eaScth 		    (val_array[ai] == val_arg))
515602ca9eaScth 			return (1);
516602ca9eaScth 		break;
517602ca9eaScth 	}
518602ca9eaScth 	case DATA_TYPE_INT64: {
519602ca9eaScth 		int64_t val, val_arg;
520602ca9eaScth 
521602ca9eaScth 		/* scanf int64_t from value and check for match */
522602ca9eaScth 		sr = sscanf(value, "%"SCNi64, &val_arg);
523602ca9eaScth 		if ((sr == 1) &&
524602ca9eaScth 		    (nvpair_value_int64(nvp, &val) == 0) &&
525602ca9eaScth 		    (val == val_arg))
526602ca9eaScth 			return (1);
527602ca9eaScth 		break;
528602ca9eaScth 	}
529602ca9eaScth 	case DATA_TYPE_INT64_ARRAY: {
530602ca9eaScth 		int64_t *val_array, val_arg;
531602ca9eaScth 
532602ca9eaScth 		/* check indexed value of array for match */
533602ca9eaScth 		sr = sscanf(value, "%"SCNi64, &val_arg);
534602ca9eaScth 		if ((sr == 1) &&
535602ca9eaScth 		    (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) &&
536602ca9eaScth 		    (ai < a_len) &&
537602ca9eaScth 		    (val_array[ai] == val_arg))
538602ca9eaScth 				return (1);
539602ca9eaScth 		break;
540602ca9eaScth 	}
541602ca9eaScth 	case DATA_TYPE_UINT64: {
542602ca9eaScth 		uint64_t val_arg, val;
543602ca9eaScth 
544602ca9eaScth 		/* scanf uint64_t from value and check for match */
545602ca9eaScth 		sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
546602ca9eaScth 		if ((sr == 1) &&
547602ca9eaScth 		    (nvpair_value_uint64(nvp, &val) == 0) &&
548602ca9eaScth 		    (val == val_arg))
549602ca9eaScth 			return (1);
550602ca9eaScth 		break;
551602ca9eaScth 	}
552602ca9eaScth 	case DATA_TYPE_UINT64_ARRAY: {
553602ca9eaScth 		uint64_t *val_array, val_arg;
554602ca9eaScth 
555602ca9eaScth 		/* check indexed value of array for match */
556602ca9eaScth 		sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
557602ca9eaScth 		if ((sr == 1) &&
558602ca9eaScth 		    (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) &&
559602ca9eaScth 		    (ai < a_len) &&
560602ca9eaScth 		    (val_array[ai] == val_arg))
561602ca9eaScth 			return (1);
562602ca9eaScth 		break;
563602ca9eaScth 	}
564602ca9eaScth 	case DATA_TYPE_BOOLEAN_VALUE: {
565602ca9eaScth 		boolean_t val, val_arg;
566602ca9eaScth 
567602ca9eaScth 		/* scanf boolean_t from value and check for match */
568602ca9eaScth 		sr = sscanf(value, "%"SCNi32, &val_arg);
569602ca9eaScth 		if ((sr == 1) &&
570602ca9eaScth 		    (nvpair_value_boolean_value(nvp, &val) == 0) &&
571602ca9eaScth 		    (val == val_arg))
572602ca9eaScth 			return (1);
573602ca9eaScth 		break;
574602ca9eaScth 	}
575602ca9eaScth 	case DATA_TYPE_BOOLEAN_ARRAY: {
576602ca9eaScth 		boolean_t *val_array, val_arg;
577602ca9eaScth 
578602ca9eaScth 		/* check indexed value of array for match */
579602ca9eaScth 		sr = sscanf(value, "%"SCNi32, &val_arg);
580602ca9eaScth 		if ((sr == 1) &&
581602ca9eaScth 		    (nvpair_value_boolean_array(nvp,
582602ca9eaScth 		    &val_array, &a_len) == 0) &&
583602ca9eaScth 		    (ai < a_len) &&
584602ca9eaScth 		    (val_array[ai] == val_arg))
585602ca9eaScth 			return (1);
586602ca9eaScth 		break;
587602ca9eaScth 	}
588602ca9eaScth 	case DATA_TYPE_HRTIME:
589602ca9eaScth 	case DATA_TYPE_NVLIST:
590602ca9eaScth 	case DATA_TYPE_NVLIST_ARRAY:
591602ca9eaScth 	case DATA_TYPE_BOOLEAN:
592*825ba0f2Srobj 	case DATA_TYPE_DOUBLE:
593602ca9eaScth 	case DATA_TYPE_UNKNOWN:
594602ca9eaScth 	default:
595602ca9eaScth 		/*
596602ca9eaScth 		 * unknown/unsupported data type
597602ca9eaScth 		 */
598602ca9eaScth 		return (-1);		/* error fail match */
599602ca9eaScth 	}
600602ca9eaScth 
601602ca9eaScth 	/*
602602ca9eaScth 	 * check to see if sscanf failed conversion, return approximate
603602ca9eaScth 	 * pointer to problem
604602ca9eaScth 	 */
605602ca9eaScth 	if (sr != 1) {
606602ca9eaScth 		if (ep)
607602ca9eaScth 			*ep = value;
608602ca9eaScth 		return (-1);		/* error fail match  - syntax */
609602ca9eaScth 	}
610602ca9eaScth 
611602ca9eaScth 	return (0);			/* fail match */
612602ca9eaScth }
613602ca9eaScth 
614602ca9eaScth int
615602ca9eaScth nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep)
616602ca9eaScth {
617602ca9eaScth 	return (nvpair_value_match_regex(nvp, ai, value, NULL, ep));
618602ca9eaScth }
619