xref: /onnv-gate/usr/src/lib/libnvpair/libnvpair.c (revision 12967:ab9ae749152f)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
56640Scth  * Common Development and Distribution License (the "License").
66640Scth  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*12967Sgavin.maltby@oracle.com  * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate  */
240Sstevel@tonic-gate 
250Sstevel@tonic-gate #include <unistd.h>
260Sstevel@tonic-gate #include <strings.h>
2710594SGeorge.Wilson@Sun.COM #include <libintl.h>
286640Scth #include <sys/types.h>
296640Scth #include <sys/inttypes.h>
30*12967Sgavin.maltby@oracle.com #include <stdarg.h>
31*12967Sgavin.maltby@oracle.com #include <note.h>
320Sstevel@tonic-gate #include "libnvpair.h"
330Sstevel@tonic-gate 
340Sstevel@tonic-gate /*
350Sstevel@tonic-gate  * libnvpair - A tools library for manipulating <name, value> pairs.
360Sstevel@tonic-gate  *
370Sstevel@tonic-gate  *	This library provides routines packing an unpacking nv pairs
380Sstevel@tonic-gate  *	for transporting data across process boundaries, transporting
390Sstevel@tonic-gate  *	between kernel and userland, and possibly saving onto disk files.
400Sstevel@tonic-gate  */
410Sstevel@tonic-gate 
42*12967Sgavin.maltby@oracle.com /*
43*12967Sgavin.maltby@oracle.com  * Print control structure.
44*12967Sgavin.maltby@oracle.com  */
45*12967Sgavin.maltby@oracle.com 
46*12967Sgavin.maltby@oracle.com #define	DEFINEOP(opname, vtype) \
47*12967Sgavin.maltby@oracle.com 	struct { \
48*12967Sgavin.maltby@oracle.com 		int (*op)(struct nvlist_prtctl *, void *, nvlist_t *, \
49*12967Sgavin.maltby@oracle.com 		    const char *, vtype); \
50*12967Sgavin.maltby@oracle.com 		void *arg; \
51*12967Sgavin.maltby@oracle.com 	} opname
52*12967Sgavin.maltby@oracle.com 
53*12967Sgavin.maltby@oracle.com #define	DEFINEARROP(opname, vtype) \
54*12967Sgavin.maltby@oracle.com 	struct { \
55*12967Sgavin.maltby@oracle.com 		int (*op)(struct nvlist_prtctl *, void *, nvlist_t *, \
56*12967Sgavin.maltby@oracle.com 		    const char *, vtype, uint_t); \
57*12967Sgavin.maltby@oracle.com 		void *arg; \
58*12967Sgavin.maltby@oracle.com 	} opname
59*12967Sgavin.maltby@oracle.com 
60*12967Sgavin.maltby@oracle.com struct nvlist_printops {
61*12967Sgavin.maltby@oracle.com 	DEFINEOP(print_boolean, int);
62*12967Sgavin.maltby@oracle.com 	DEFINEOP(print_boolean_value, boolean_t);
63*12967Sgavin.maltby@oracle.com 	DEFINEOP(print_byte, uchar_t);
64*12967Sgavin.maltby@oracle.com 	DEFINEOP(print_int8, int8_t);
65*12967Sgavin.maltby@oracle.com 	DEFINEOP(print_uint8, uint8_t);
66*12967Sgavin.maltby@oracle.com 	DEFINEOP(print_int16, int16_t);
67*12967Sgavin.maltby@oracle.com 	DEFINEOP(print_uint16, uint16_t);
68*12967Sgavin.maltby@oracle.com 	DEFINEOP(print_int32, int32_t);
69*12967Sgavin.maltby@oracle.com 	DEFINEOP(print_uint32, uint32_t);
70*12967Sgavin.maltby@oracle.com 	DEFINEOP(print_int64, int64_t);
71*12967Sgavin.maltby@oracle.com 	DEFINEOP(print_uint64, uint64_t);
72*12967Sgavin.maltby@oracle.com 	DEFINEOP(print_double, double);
73*12967Sgavin.maltby@oracle.com 	DEFINEOP(print_string, char *);
74*12967Sgavin.maltby@oracle.com 	DEFINEOP(print_hrtime, hrtime_t);
75*12967Sgavin.maltby@oracle.com 	DEFINEOP(print_nvlist, nvlist_t *);
76*12967Sgavin.maltby@oracle.com 	DEFINEARROP(print_boolean_array, boolean_t *);
77*12967Sgavin.maltby@oracle.com 	DEFINEARROP(print_byte_array, uchar_t *);
78*12967Sgavin.maltby@oracle.com 	DEFINEARROP(print_int8_array, int8_t *);
79*12967Sgavin.maltby@oracle.com 	DEFINEARROP(print_uint8_array, uint8_t *);
80*12967Sgavin.maltby@oracle.com 	DEFINEARROP(print_int16_array, int16_t *);
81*12967Sgavin.maltby@oracle.com 	DEFINEARROP(print_uint16_array, uint16_t *);
82*12967Sgavin.maltby@oracle.com 	DEFINEARROP(print_int32_array, int32_t *);
83*12967Sgavin.maltby@oracle.com 	DEFINEARROP(print_uint32_array, uint32_t *);
84*12967Sgavin.maltby@oracle.com 	DEFINEARROP(print_int64_array, int64_t *);
85*12967Sgavin.maltby@oracle.com 	DEFINEARROP(print_uint64_array, uint64_t *);
86*12967Sgavin.maltby@oracle.com 	DEFINEARROP(print_string_array, char **);
87*12967Sgavin.maltby@oracle.com 	DEFINEARROP(print_nvlist_array, nvlist_t **);
88*12967Sgavin.maltby@oracle.com };
89*12967Sgavin.maltby@oracle.com 
90*12967Sgavin.maltby@oracle.com struct nvlist_prtctl {
91*12967Sgavin.maltby@oracle.com 	FILE *nvprt_fp;			/* output destination */
92*12967Sgavin.maltby@oracle.com 	enum nvlist_indent_mode nvprt_indent_mode; /* see above */
93*12967Sgavin.maltby@oracle.com 	int nvprt_indent;		/* absolute indent, or tab depth */
94*12967Sgavin.maltby@oracle.com 	int nvprt_indentinc;		/* indent or tab increment */
95*12967Sgavin.maltby@oracle.com 	const char *nvprt_nmfmt;	/* member name format, max one %s */
96*12967Sgavin.maltby@oracle.com 	const char *nvprt_eomfmt;	/* after member format, e.g. "\n" */
97*12967Sgavin.maltby@oracle.com 	const char *nvprt_btwnarrfmt;	/* between array members */
98*12967Sgavin.maltby@oracle.com 	int nvprt_btwnarrfmt_nl;	/* nvprt_eoamfmt includes newline? */
99*12967Sgavin.maltby@oracle.com 	struct nvlist_printops *nvprt_dfltops;
100*12967Sgavin.maltby@oracle.com 	struct nvlist_printops *nvprt_custops;
101*12967Sgavin.maltby@oracle.com };
102*12967Sgavin.maltby@oracle.com 
103*12967Sgavin.maltby@oracle.com #define	DFLTPRTOP(pctl, type) \
104*12967Sgavin.maltby@oracle.com 	((pctl)->nvprt_dfltops->print_##type.op)
105*12967Sgavin.maltby@oracle.com 
106*12967Sgavin.maltby@oracle.com #define	DFLTPRTOPARG(pctl, type) \
107*12967Sgavin.maltby@oracle.com 	((pctl)->nvprt_dfltops->print_##type.arg)
108*12967Sgavin.maltby@oracle.com 
109*12967Sgavin.maltby@oracle.com #define	CUSTPRTOP(pctl, type) \
110*12967Sgavin.maltby@oracle.com 	((pctl)->nvprt_custops->print_##type.op)
111*12967Sgavin.maltby@oracle.com 
112*12967Sgavin.maltby@oracle.com #define	CUSTPRTOPARG(pctl, type) \
113*12967Sgavin.maltby@oracle.com 	((pctl)->nvprt_custops->print_##type.arg)
114*12967Sgavin.maltby@oracle.com 
115*12967Sgavin.maltby@oracle.com #define	RENDER(pctl, type, nvl, name, val) \
116*12967Sgavin.maltby@oracle.com 	{ \
117*12967Sgavin.maltby@oracle.com 		int done = 0; \
118*12967Sgavin.maltby@oracle.com 		if ((pctl)->nvprt_custops && CUSTPRTOP(pctl, type)) { \
119*12967Sgavin.maltby@oracle.com 			done = CUSTPRTOP(pctl, type)(pctl, \
120*12967Sgavin.maltby@oracle.com 			    CUSTPRTOPARG(pctl, type), nvl, name, val); \
121*12967Sgavin.maltby@oracle.com 		} \
122*12967Sgavin.maltby@oracle.com 		if (!done) { \
123*12967Sgavin.maltby@oracle.com 			(void) DFLTPRTOP(pctl, type)(pctl, \
124*12967Sgavin.maltby@oracle.com 			    DFLTPRTOPARG(pctl, type), nvl, name, val); \
125*12967Sgavin.maltby@oracle.com 		} \
126*12967Sgavin.maltby@oracle.com 		(void) fprintf(pctl->nvprt_fp, pctl->nvprt_eomfmt); \
127*12967Sgavin.maltby@oracle.com 	}
128*12967Sgavin.maltby@oracle.com 
129*12967Sgavin.maltby@oracle.com #define	ARENDER(pctl, type, nvl, name, arrp, count) \
130*12967Sgavin.maltby@oracle.com 	{ \
131*12967Sgavin.maltby@oracle.com 		int done = 0; \
132*12967Sgavin.maltby@oracle.com 		if ((pctl)->nvprt_custops && CUSTPRTOP(pctl, type)) { \
133*12967Sgavin.maltby@oracle.com 			done = CUSTPRTOP(pctl, type)(pctl, \
134*12967Sgavin.maltby@oracle.com 			    CUSTPRTOPARG(pctl, type), nvl, name, arrp, count); \
135*12967Sgavin.maltby@oracle.com 		} \
136*12967Sgavin.maltby@oracle.com 		if (!done) { \
137*12967Sgavin.maltby@oracle.com 			(void) DFLTPRTOP(pctl, type)(pctl, \
138*12967Sgavin.maltby@oracle.com 			    DFLTPRTOPARG(pctl, type), nvl, name, arrp, count); \
139*12967Sgavin.maltby@oracle.com 		} \
140*12967Sgavin.maltby@oracle.com 		(void) fprintf(pctl->nvprt_fp, pctl->nvprt_eomfmt); \
141*12967Sgavin.maltby@oracle.com 	}
142*12967Sgavin.maltby@oracle.com 
143*12967Sgavin.maltby@oracle.com static void nvlist_print_with_indent(nvlist_t *, nvlist_prtctl_t);
144*12967Sgavin.maltby@oracle.com 
145*12967Sgavin.maltby@oracle.com /*
146*12967Sgavin.maltby@oracle.com  * ======================================================================
147*12967Sgavin.maltby@oracle.com  * |									|
148*12967Sgavin.maltby@oracle.com  * | Indentation							|
149*12967Sgavin.maltby@oracle.com  * |									|
150*12967Sgavin.maltby@oracle.com  * ======================================================================
151*12967Sgavin.maltby@oracle.com  */
152*12967Sgavin.maltby@oracle.com 
1530Sstevel@tonic-gate static void
indent(nvlist_prtctl_t pctl,int onemore)154*12967Sgavin.maltby@oracle.com indent(nvlist_prtctl_t pctl, int onemore)
155*12967Sgavin.maltby@oracle.com {
156*12967Sgavin.maltby@oracle.com 	int depth;
157*12967Sgavin.maltby@oracle.com 
158*12967Sgavin.maltby@oracle.com 	switch (pctl->nvprt_indent_mode) {
159*12967Sgavin.maltby@oracle.com 	case NVLIST_INDENT_ABS:
160*12967Sgavin.maltby@oracle.com 		(void) fprintf(pctl->nvprt_fp, "%*s",
161*12967Sgavin.maltby@oracle.com 		    pctl->nvprt_indent + onemore * pctl->nvprt_indentinc, "");
162*12967Sgavin.maltby@oracle.com 		break;
163*12967Sgavin.maltby@oracle.com 
164*12967Sgavin.maltby@oracle.com 	case NVLIST_INDENT_TABBED:
165*12967Sgavin.maltby@oracle.com 		depth = pctl->nvprt_indent + onemore;
166*12967Sgavin.maltby@oracle.com 		while (depth-- > 0)
167*12967Sgavin.maltby@oracle.com 			(void) fprintf(pctl->nvprt_fp, "\t");
168*12967Sgavin.maltby@oracle.com 	}
169*12967Sgavin.maltby@oracle.com }
170*12967Sgavin.maltby@oracle.com 
171*12967Sgavin.maltby@oracle.com /*
172*12967Sgavin.maltby@oracle.com  * ======================================================================
173*12967Sgavin.maltby@oracle.com  * |									|
174*12967Sgavin.maltby@oracle.com  * | Default nvlist member rendering functions.				|
175*12967Sgavin.maltby@oracle.com  * |									|
176*12967Sgavin.maltby@oracle.com  * ======================================================================
177*12967Sgavin.maltby@oracle.com  */
178*12967Sgavin.maltby@oracle.com 
179*12967Sgavin.maltby@oracle.com /*
180*12967Sgavin.maltby@oracle.com  * Generate functions to print single-valued nvlist members.
181*12967Sgavin.maltby@oracle.com  *
182*12967Sgavin.maltby@oracle.com  * type_and_variant - suffix to form function name
183*12967Sgavin.maltby@oracle.com  * vtype - C type for the member value
184*12967Sgavin.maltby@oracle.com  * ptype - C type to cast value to for printing
185*12967Sgavin.maltby@oracle.com  * vfmt - format string for pair value, e.g "%d" or "0x%llx"
186*12967Sgavin.maltby@oracle.com  */
187*12967Sgavin.maltby@oracle.com 
188*12967Sgavin.maltby@oracle.com #define	NVLIST_PRTFUNC(type_and_variant, vtype, ptype, vfmt) \
189*12967Sgavin.maltby@oracle.com static int \
190*12967Sgavin.maltby@oracle.com nvprint_##type_and_variant(nvlist_prtctl_t pctl, void *private, \
191*12967Sgavin.maltby@oracle.com     nvlist_t *nvl, const char *name, vtype value) \
192*12967Sgavin.maltby@oracle.com { \
193*12967Sgavin.maltby@oracle.com 	FILE *fp = pctl->nvprt_fp; \
194*12967Sgavin.maltby@oracle.com 	NOTE(ARGUNUSED(private)) \
195*12967Sgavin.maltby@oracle.com 	NOTE(ARGUNUSED(nvl)) \
196*12967Sgavin.maltby@oracle.com 	indent(pctl, 1); \
197*12967Sgavin.maltby@oracle.com 	(void) fprintf(fp, pctl->nvprt_nmfmt, name); \
198*12967Sgavin.maltby@oracle.com 	(void) fprintf(fp, vfmt, (ptype)value); \
199*12967Sgavin.maltby@oracle.com 	return (1); \
200*12967Sgavin.maltby@oracle.com }
201*12967Sgavin.maltby@oracle.com 
202*12967Sgavin.maltby@oracle.com NVLIST_PRTFUNC(boolean, int, int, "%d")
203*12967Sgavin.maltby@oracle.com NVLIST_PRTFUNC(boolean_value, boolean_t, int, "%d")
204*12967Sgavin.maltby@oracle.com NVLIST_PRTFUNC(byte, uchar_t, uchar_t, "0x%2.2x")
205*12967Sgavin.maltby@oracle.com NVLIST_PRTFUNC(int8, int8_t, int, "%d")
206*12967Sgavin.maltby@oracle.com NVLIST_PRTFUNC(uint8, uint8_t, uint8_t, "0x%x")
207*12967Sgavin.maltby@oracle.com NVLIST_PRTFUNC(int16, int16_t, int16_t, "%d")
208*12967Sgavin.maltby@oracle.com NVLIST_PRTFUNC(uint16, uint16_t, uint16_t, "0x%x")
209*12967Sgavin.maltby@oracle.com NVLIST_PRTFUNC(int32, int32_t, int32_t, "%d")
210*12967Sgavin.maltby@oracle.com NVLIST_PRTFUNC(uint32, uint32_t, uint32_t, "0x%x")
211*12967Sgavin.maltby@oracle.com NVLIST_PRTFUNC(int64, int64_t, longlong_t, "%lld")
212*12967Sgavin.maltby@oracle.com NVLIST_PRTFUNC(uint64, uint64_t, u_longlong_t, "0x%llx")
213*12967Sgavin.maltby@oracle.com NVLIST_PRTFUNC(double, double, double, "0x%llf")
214*12967Sgavin.maltby@oracle.com NVLIST_PRTFUNC(string, char *, char *, "%s")
215*12967Sgavin.maltby@oracle.com NVLIST_PRTFUNC(hrtime, hrtime_t, hrtime_t, "0x%llx")
216*12967Sgavin.maltby@oracle.com 
217*12967Sgavin.maltby@oracle.com /*
218*12967Sgavin.maltby@oracle.com  * Generate functions to print array-valued nvlist members.
219*12967Sgavin.maltby@oracle.com  */
220*12967Sgavin.maltby@oracle.com 
221*12967Sgavin.maltby@oracle.com #define	NVLIST_ARRPRTFUNC(type_and_variant, vtype, ptype, vfmt) \
222*12967Sgavin.maltby@oracle.com static int \
223*12967Sgavin.maltby@oracle.com nvaprint_##type_and_variant(nvlist_prtctl_t pctl, void *private, \
224*12967Sgavin.maltby@oracle.com     nvlist_t *nvl, const char *name, vtype *valuep, uint_t count) \
225*12967Sgavin.maltby@oracle.com { \
226*12967Sgavin.maltby@oracle.com 	FILE *fp = pctl->nvprt_fp; \
227*12967Sgavin.maltby@oracle.com 	uint_t i; \
228*12967Sgavin.maltby@oracle.com 	NOTE(ARGUNUSED(private)) \
229*12967Sgavin.maltby@oracle.com 	NOTE(ARGUNUSED(nvl)) \
230*12967Sgavin.maltby@oracle.com 	for (i = 0; i < count; i++) { \
231*12967Sgavin.maltby@oracle.com 		if (i == 0 || pctl->nvprt_btwnarrfmt_nl) { \
232*12967Sgavin.maltby@oracle.com 			indent(pctl, 1); \
233*12967Sgavin.maltby@oracle.com 			(void) fprintf(fp, pctl->nvprt_nmfmt, name); \
234*12967Sgavin.maltby@oracle.com 			if (pctl->nvprt_btwnarrfmt_nl) \
235*12967Sgavin.maltby@oracle.com 				(void) fprintf(fp, "[%d]: ", i); \
236*12967Sgavin.maltby@oracle.com 		} \
237*12967Sgavin.maltby@oracle.com 		if (i != 0) \
238*12967Sgavin.maltby@oracle.com 			(void) fprintf(fp, pctl->nvprt_btwnarrfmt); \
239*12967Sgavin.maltby@oracle.com 		(void) fprintf(fp, vfmt, (ptype)valuep[i]); \
240*12967Sgavin.maltby@oracle.com 	} \
241*12967Sgavin.maltby@oracle.com 	return (1); \
242*12967Sgavin.maltby@oracle.com }
243*12967Sgavin.maltby@oracle.com 
244*12967Sgavin.maltby@oracle.com NVLIST_ARRPRTFUNC(boolean_array, boolean_t, boolean_t, "%d")
245*12967Sgavin.maltby@oracle.com NVLIST_ARRPRTFUNC(byte_array, uchar_t, uchar_t, "0x%2.2x")
246*12967Sgavin.maltby@oracle.com NVLIST_ARRPRTFUNC(int8_array, int8_t, int8_t, "%d")
247*12967Sgavin.maltby@oracle.com NVLIST_ARRPRTFUNC(uint8_array, uint8_t, uint8_t, "0x%x")
248*12967Sgavin.maltby@oracle.com NVLIST_ARRPRTFUNC(int16_array, int16_t, int16_t, "%d")
249*12967Sgavin.maltby@oracle.com NVLIST_ARRPRTFUNC(uint16_array, uint16_t, uint16_t, "0x%x")
250*12967Sgavin.maltby@oracle.com NVLIST_ARRPRTFUNC(int32_array, int32_t, int32_t, "%d")
251*12967Sgavin.maltby@oracle.com NVLIST_ARRPRTFUNC(uint32_array, uint32_t, uint32_t, "0x%x")
252*12967Sgavin.maltby@oracle.com NVLIST_ARRPRTFUNC(int64_array, int64_t, longlong_t, "%lld")
253*12967Sgavin.maltby@oracle.com NVLIST_ARRPRTFUNC(uint64_array, uint64_t, u_longlong_t, "0x%llx")
254*12967Sgavin.maltby@oracle.com NVLIST_ARRPRTFUNC(string_array, char *, char *, "%s")
255*12967Sgavin.maltby@oracle.com 
256*12967Sgavin.maltby@oracle.com /*ARGSUSED*/
257*12967Sgavin.maltby@oracle.com static int
nvprint_nvlist(nvlist_prtctl_t pctl,void * private,nvlist_t * nvl,const char * name,nvlist_t * value)258*12967Sgavin.maltby@oracle.com nvprint_nvlist(nvlist_prtctl_t pctl, void *private,
259*12967Sgavin.maltby@oracle.com     nvlist_t *nvl, const char *name, nvlist_t *value)
260*12967Sgavin.maltby@oracle.com {
261*12967Sgavin.maltby@oracle.com 	FILE *fp = pctl->nvprt_fp;
262*12967Sgavin.maltby@oracle.com 
263*12967Sgavin.maltby@oracle.com 	indent(pctl, 1);
264*12967Sgavin.maltby@oracle.com 	(void) fprintf(fp, "%s = (embedded nvlist)\n", name);
265*12967Sgavin.maltby@oracle.com 
266*12967Sgavin.maltby@oracle.com 	pctl->nvprt_indent += pctl->nvprt_indentinc;
267*12967Sgavin.maltby@oracle.com 	nvlist_print_with_indent(value, pctl);
268*12967Sgavin.maltby@oracle.com 	pctl->nvprt_indent -= pctl->nvprt_indentinc;
269*12967Sgavin.maltby@oracle.com 
270*12967Sgavin.maltby@oracle.com 	indent(pctl, 1);
271*12967Sgavin.maltby@oracle.com 	(void) fprintf(fp, "(end %s)\n", name);
272*12967Sgavin.maltby@oracle.com 
273*12967Sgavin.maltby@oracle.com 	return (1);
274*12967Sgavin.maltby@oracle.com }
275*12967Sgavin.maltby@oracle.com 
276*12967Sgavin.maltby@oracle.com /*ARGSUSED*/
277*12967Sgavin.maltby@oracle.com static int
nvaprint_nvlist_array(nvlist_prtctl_t pctl,void * private,nvlist_t * nvl,const char * name,nvlist_t ** valuep,uint_t count)278*12967Sgavin.maltby@oracle.com nvaprint_nvlist_array(nvlist_prtctl_t pctl, void *private,
279*12967Sgavin.maltby@oracle.com     nvlist_t *nvl, const char *name, nvlist_t **valuep, uint_t count)
2800Sstevel@tonic-gate {
281*12967Sgavin.maltby@oracle.com 	FILE *fp = pctl->nvprt_fp;
282*12967Sgavin.maltby@oracle.com 	uint_t i;
283*12967Sgavin.maltby@oracle.com 
284*12967Sgavin.maltby@oracle.com 	indent(pctl, 1);
285*12967Sgavin.maltby@oracle.com 	(void) fprintf(fp, "%s = (array of embedded nvlists)\n", name);
286*12967Sgavin.maltby@oracle.com 
287*12967Sgavin.maltby@oracle.com 	for (i = 0; i < count; i++) {
288*12967Sgavin.maltby@oracle.com 		indent(pctl, 1);
289*12967Sgavin.maltby@oracle.com 		(void) fprintf(fp, "(start %s[%d])\n", name, i);
290*12967Sgavin.maltby@oracle.com 
291*12967Sgavin.maltby@oracle.com 		pctl->nvprt_indent += pctl->nvprt_indentinc;
292*12967Sgavin.maltby@oracle.com 		nvlist_print_with_indent(valuep[i], pctl);
293*12967Sgavin.maltby@oracle.com 		pctl->nvprt_indent -= pctl->nvprt_indentinc;
294*12967Sgavin.maltby@oracle.com 
295*12967Sgavin.maltby@oracle.com 		indent(pctl, 1);
296*12967Sgavin.maltby@oracle.com 		(void) fprintf(fp, "(end %s[%d])\n", name, i);
297*12967Sgavin.maltby@oracle.com 	}
298*12967Sgavin.maltby@oracle.com 
299*12967Sgavin.maltby@oracle.com 	return (1);
300*12967Sgavin.maltby@oracle.com }
301*12967Sgavin.maltby@oracle.com 
302*12967Sgavin.maltby@oracle.com /*
303*12967Sgavin.maltby@oracle.com  * ======================================================================
304*12967Sgavin.maltby@oracle.com  * |									|
305*12967Sgavin.maltby@oracle.com  * | Interfaces that allow control over formatting.			|
306*12967Sgavin.maltby@oracle.com  * |									|
307*12967Sgavin.maltby@oracle.com  * ======================================================================
308*12967Sgavin.maltby@oracle.com  */
309*12967Sgavin.maltby@oracle.com 
310*12967Sgavin.maltby@oracle.com void
nvlist_prtctl_setdest(nvlist_prtctl_t pctl,FILE * fp)311*12967Sgavin.maltby@oracle.com nvlist_prtctl_setdest(nvlist_prtctl_t pctl, FILE *fp)
312*12967Sgavin.maltby@oracle.com {
313*12967Sgavin.maltby@oracle.com 	pctl->nvprt_fp = fp;
314*12967Sgavin.maltby@oracle.com }
315*12967Sgavin.maltby@oracle.com 
316*12967Sgavin.maltby@oracle.com FILE *
nvlist_prtctl_getdest(nvlist_prtctl_t pctl)317*12967Sgavin.maltby@oracle.com nvlist_prtctl_getdest(nvlist_prtctl_t pctl)
318*12967Sgavin.maltby@oracle.com {
319*12967Sgavin.maltby@oracle.com 	return (pctl->nvprt_fp);
320*12967Sgavin.maltby@oracle.com }
321*12967Sgavin.maltby@oracle.com 
322*12967Sgavin.maltby@oracle.com 
323*12967Sgavin.maltby@oracle.com void
nvlist_prtctl_setindent(nvlist_prtctl_t pctl,enum nvlist_indent_mode mode,int start,int inc)324*12967Sgavin.maltby@oracle.com nvlist_prtctl_setindent(nvlist_prtctl_t pctl, enum nvlist_indent_mode mode,
325*12967Sgavin.maltby@oracle.com     int start, int inc)
326*12967Sgavin.maltby@oracle.com {
327*12967Sgavin.maltby@oracle.com 	if (mode < NVLIST_INDENT_ABS || mode > NVLIST_INDENT_TABBED)
328*12967Sgavin.maltby@oracle.com 		mode = NVLIST_INDENT_TABBED;
329*12967Sgavin.maltby@oracle.com 
330*12967Sgavin.maltby@oracle.com 	if (start < 0)
331*12967Sgavin.maltby@oracle.com 		start = 0;
332*12967Sgavin.maltby@oracle.com 
333*12967Sgavin.maltby@oracle.com 	if (inc < 0)
334*12967Sgavin.maltby@oracle.com 		inc = 1;
335*12967Sgavin.maltby@oracle.com 
336*12967Sgavin.maltby@oracle.com 	pctl->nvprt_indent_mode = mode;
337*12967Sgavin.maltby@oracle.com 	pctl->nvprt_indent = start;
338*12967Sgavin.maltby@oracle.com 	pctl->nvprt_indentinc = inc;
339*12967Sgavin.maltby@oracle.com }
340*12967Sgavin.maltby@oracle.com 
341*12967Sgavin.maltby@oracle.com void
nvlist_prtctl_doindent(nvlist_prtctl_t pctl,int onemore)342*12967Sgavin.maltby@oracle.com nvlist_prtctl_doindent(nvlist_prtctl_t pctl, int onemore)
343*12967Sgavin.maltby@oracle.com {
344*12967Sgavin.maltby@oracle.com 	indent(pctl, onemore);
345*12967Sgavin.maltby@oracle.com }
346*12967Sgavin.maltby@oracle.com 
347*12967Sgavin.maltby@oracle.com 
348*12967Sgavin.maltby@oracle.com void
nvlist_prtctl_setfmt(nvlist_prtctl_t pctl,enum nvlist_prtctl_fmt which,const char * fmt)349*12967Sgavin.maltby@oracle.com nvlist_prtctl_setfmt(nvlist_prtctl_t pctl, enum nvlist_prtctl_fmt which,
350*12967Sgavin.maltby@oracle.com     const char *fmt)
351*12967Sgavin.maltby@oracle.com {
352*12967Sgavin.maltby@oracle.com 	switch (which) {
353*12967Sgavin.maltby@oracle.com 	case NVLIST_FMT_MEMBER_NAME:
354*12967Sgavin.maltby@oracle.com 		if (fmt == NULL)
355*12967Sgavin.maltby@oracle.com 			fmt = "%s = ";
356*12967Sgavin.maltby@oracle.com 		pctl->nvprt_nmfmt = fmt;
357*12967Sgavin.maltby@oracle.com 		break;
358*12967Sgavin.maltby@oracle.com 
359*12967Sgavin.maltby@oracle.com 	case NVLIST_FMT_MEMBER_POSTAMBLE:
360*12967Sgavin.maltby@oracle.com 		if (fmt == NULL)
361*12967Sgavin.maltby@oracle.com 			fmt = "\n";
362*12967Sgavin.maltby@oracle.com 		pctl->nvprt_eomfmt = fmt;
363*12967Sgavin.maltby@oracle.com 		break;
364*12967Sgavin.maltby@oracle.com 
365*12967Sgavin.maltby@oracle.com 	case NVLIST_FMT_BTWN_ARRAY:
366*12967Sgavin.maltby@oracle.com 		if (fmt == NULL) {
367*12967Sgavin.maltby@oracle.com 			pctl->nvprt_btwnarrfmt = " ";
368*12967Sgavin.maltby@oracle.com 			pctl->nvprt_btwnarrfmt_nl = 0;
369*12967Sgavin.maltby@oracle.com 		} else {
370*12967Sgavin.maltby@oracle.com 			pctl->nvprt_btwnarrfmt = fmt;
371*12967Sgavin.maltby@oracle.com 			pctl->nvprt_btwnarrfmt_nl = (strstr(fmt, "\n") != NULL);
372*12967Sgavin.maltby@oracle.com 		}
373*12967Sgavin.maltby@oracle.com 		break;
374*12967Sgavin.maltby@oracle.com 
375*12967Sgavin.maltby@oracle.com 	default:
376*12967Sgavin.maltby@oracle.com 		break;
377*12967Sgavin.maltby@oracle.com 	}
378*12967Sgavin.maltby@oracle.com }
379*12967Sgavin.maltby@oracle.com 
380*12967Sgavin.maltby@oracle.com 
381*12967Sgavin.maltby@oracle.com void
nvlist_prtctl_dofmt(nvlist_prtctl_t pctl,enum nvlist_prtctl_fmt which,...)382*12967Sgavin.maltby@oracle.com nvlist_prtctl_dofmt(nvlist_prtctl_t pctl, enum nvlist_prtctl_fmt which, ...)
383*12967Sgavin.maltby@oracle.com {
384*12967Sgavin.maltby@oracle.com 	FILE *fp = pctl->nvprt_fp;
385*12967Sgavin.maltby@oracle.com 	va_list ap;
386*12967Sgavin.maltby@oracle.com 	char *name;
387*12967Sgavin.maltby@oracle.com 
388*12967Sgavin.maltby@oracle.com 	va_start(ap, which);
389*12967Sgavin.maltby@oracle.com 
390*12967Sgavin.maltby@oracle.com 	switch (which) {
391*12967Sgavin.maltby@oracle.com 	case NVLIST_FMT_MEMBER_NAME:
392*12967Sgavin.maltby@oracle.com 		name = va_arg(ap, char *);
393*12967Sgavin.maltby@oracle.com 		(void) fprintf(fp, pctl->nvprt_nmfmt, name);
394*12967Sgavin.maltby@oracle.com 		break;
395*12967Sgavin.maltby@oracle.com 
396*12967Sgavin.maltby@oracle.com 	case NVLIST_FMT_MEMBER_POSTAMBLE:
397*12967Sgavin.maltby@oracle.com 		(void) fprintf(fp, pctl->nvprt_eomfmt);
398*12967Sgavin.maltby@oracle.com 		break;
399*12967Sgavin.maltby@oracle.com 
400*12967Sgavin.maltby@oracle.com 	case NVLIST_FMT_BTWN_ARRAY:
401*12967Sgavin.maltby@oracle.com 		(void) fprintf(fp, pctl->nvprt_btwnarrfmt); \
402*12967Sgavin.maltby@oracle.com 		break;
403*12967Sgavin.maltby@oracle.com 
404*12967Sgavin.maltby@oracle.com 	default:
405*12967Sgavin.maltby@oracle.com 		break;
406*12967Sgavin.maltby@oracle.com 	}
407*12967Sgavin.maltby@oracle.com 
408*12967Sgavin.maltby@oracle.com 	va_end(ap);
4090Sstevel@tonic-gate }
4100Sstevel@tonic-gate 
4110Sstevel@tonic-gate /*
412*12967Sgavin.maltby@oracle.com  * ======================================================================
413*12967Sgavin.maltby@oracle.com  * |									|
414*12967Sgavin.maltby@oracle.com  * | Interfaces to allow appointment of replacement rendering functions.|
415*12967Sgavin.maltby@oracle.com  * |									|
416*12967Sgavin.maltby@oracle.com  * ======================================================================
417*12967Sgavin.maltby@oracle.com  */
418*12967Sgavin.maltby@oracle.com 
419*12967Sgavin.maltby@oracle.com #define	NVLIST_PRINTCTL_REPLACE(type, vtype) \
420*12967Sgavin.maltby@oracle.com void \
421*12967Sgavin.maltby@oracle.com nvlist_prtctlop_##type(nvlist_prtctl_t pctl, \
422*12967Sgavin.maltby@oracle.com     int (*func)(nvlist_prtctl_t, void *, nvlist_t *, const char *, vtype), \
423*12967Sgavin.maltby@oracle.com     void *private) \
424*12967Sgavin.maltby@oracle.com { \
425*12967Sgavin.maltby@oracle.com 	CUSTPRTOP(pctl, type) = func; \
426*12967Sgavin.maltby@oracle.com 	CUSTPRTOPARG(pctl, type) = private; \
427*12967Sgavin.maltby@oracle.com }
428*12967Sgavin.maltby@oracle.com 
429*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_REPLACE(boolean, int)
430*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_REPLACE(boolean_value, boolean_t)
431*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_REPLACE(byte, uchar_t)
432*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_REPLACE(int8, int8_t)
433*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_REPLACE(uint8, uint8_t)
434*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_REPLACE(int16, int16_t)
435*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_REPLACE(uint16, uint16_t)
436*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_REPLACE(int32, int32_t)
437*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_REPLACE(uint32, uint32_t)
438*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_REPLACE(int64, int64_t)
439*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_REPLACE(uint64, uint64_t)
440*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_REPLACE(double, double)
441*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_REPLACE(string, char *)
442*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_REPLACE(hrtime, hrtime_t)
443*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_REPLACE(nvlist, nvlist_t *)
444*12967Sgavin.maltby@oracle.com 
445*12967Sgavin.maltby@oracle.com #define	NVLIST_PRINTCTL_AREPLACE(type, vtype) \
446*12967Sgavin.maltby@oracle.com void \
447*12967Sgavin.maltby@oracle.com nvlist_prtctlop_##type(nvlist_prtctl_t pctl, \
448*12967Sgavin.maltby@oracle.com     int (*func)(nvlist_prtctl_t, void *, nvlist_t *, const char *, vtype, \
449*12967Sgavin.maltby@oracle.com     uint_t), void *private) \
450*12967Sgavin.maltby@oracle.com { \
451*12967Sgavin.maltby@oracle.com 	CUSTPRTOP(pctl, type) = func; \
452*12967Sgavin.maltby@oracle.com 	CUSTPRTOPARG(pctl, type) = private; \
453*12967Sgavin.maltby@oracle.com }
454*12967Sgavin.maltby@oracle.com 
455*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_AREPLACE(boolean_array, boolean_t *)
456*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_AREPLACE(byte_array, uchar_t *)
457*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_AREPLACE(int8_array, int8_t *)
458*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_AREPLACE(uint8_array, uint8_t *)
459*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_AREPLACE(int16_array, int16_t *)
460*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_AREPLACE(uint16_array, uint16_t *)
461*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_AREPLACE(int32_array, int32_t *)
462*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_AREPLACE(uint32_array, uint32_t *)
463*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_AREPLACE(int64_array, int64_t *)
464*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_AREPLACE(uint64_array, uint64_t *)
465*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_AREPLACE(string_array, char **)
466*12967Sgavin.maltby@oracle.com NVLIST_PRINTCTL_AREPLACE(nvlist_array, nvlist_t **)
467*12967Sgavin.maltby@oracle.com 
468*12967Sgavin.maltby@oracle.com /*
469*12967Sgavin.maltby@oracle.com  * ======================================================================
470*12967Sgavin.maltby@oracle.com  * |									|
471*12967Sgavin.maltby@oracle.com  * | Interfaces to manage nvlist_prtctl_t cookies.			|
472*12967Sgavin.maltby@oracle.com  * |									|
473*12967Sgavin.maltby@oracle.com  * ======================================================================
474*12967Sgavin.maltby@oracle.com  */
475*12967Sgavin.maltby@oracle.com 
476*12967Sgavin.maltby@oracle.com 
477*12967Sgavin.maltby@oracle.com static const struct nvlist_printops defprtops = {
478*12967Sgavin.maltby@oracle.com 	{ nvprint_boolean, NULL },
479*12967Sgavin.maltby@oracle.com 	{ nvprint_boolean_value, NULL },
480*12967Sgavin.maltby@oracle.com 	{ nvprint_byte, NULL },
481*12967Sgavin.maltby@oracle.com 	{ nvprint_int8, NULL },
482*12967Sgavin.maltby@oracle.com 	{ nvprint_uint8, NULL },
483*12967Sgavin.maltby@oracle.com 	{ nvprint_int16, NULL },
484*12967Sgavin.maltby@oracle.com 	{ nvprint_uint16, NULL },
485*12967Sgavin.maltby@oracle.com 	{ nvprint_int32, NULL },
486*12967Sgavin.maltby@oracle.com 	{ nvprint_uint32, NULL },
487*12967Sgavin.maltby@oracle.com 	{ nvprint_int64, NULL },
488*12967Sgavin.maltby@oracle.com 	{ nvprint_uint64, NULL },
489*12967Sgavin.maltby@oracle.com 	{ nvprint_double, NULL },
490*12967Sgavin.maltby@oracle.com 	{ nvprint_string, NULL },
491*12967Sgavin.maltby@oracle.com 	{ nvprint_hrtime, NULL },
492*12967Sgavin.maltby@oracle.com 	{ nvprint_nvlist, NULL },
493*12967Sgavin.maltby@oracle.com 	{ nvaprint_boolean_array, NULL },
494*12967Sgavin.maltby@oracle.com 	{ nvaprint_byte_array, NULL },
495*12967Sgavin.maltby@oracle.com 	{ nvaprint_int8_array, NULL },
496*12967Sgavin.maltby@oracle.com 	{ nvaprint_uint8_array, NULL },
497*12967Sgavin.maltby@oracle.com 	{ nvaprint_int16_array, NULL },
498*12967Sgavin.maltby@oracle.com 	{ nvaprint_uint16_array, NULL },
499*12967Sgavin.maltby@oracle.com 	{ nvaprint_int32_array, NULL },
500*12967Sgavin.maltby@oracle.com 	{ nvaprint_uint32_array, NULL },
501*12967Sgavin.maltby@oracle.com 	{ nvaprint_int64_array, NULL },
502*12967Sgavin.maltby@oracle.com 	{ nvaprint_uint64_array, NULL },
503*12967Sgavin.maltby@oracle.com 	{ nvaprint_string_array, NULL },
504*12967Sgavin.maltby@oracle.com 	{ nvaprint_nvlist_array, NULL },
505*12967Sgavin.maltby@oracle.com };
506*12967Sgavin.maltby@oracle.com 
507*12967Sgavin.maltby@oracle.com static void
prtctl_defaults(FILE * fp,struct nvlist_prtctl * pctl,struct nvlist_printops * ops)508*12967Sgavin.maltby@oracle.com prtctl_defaults(FILE *fp, struct nvlist_prtctl *pctl,
509*12967Sgavin.maltby@oracle.com     struct nvlist_printops *ops)
510*12967Sgavin.maltby@oracle.com {
511*12967Sgavin.maltby@oracle.com 	pctl->nvprt_fp = fp;
512*12967Sgavin.maltby@oracle.com 	pctl->nvprt_indent_mode = NVLIST_INDENT_TABBED;
513*12967Sgavin.maltby@oracle.com 	pctl->nvprt_indent = 0;
514*12967Sgavin.maltby@oracle.com 	pctl->nvprt_indentinc = 1;
515*12967Sgavin.maltby@oracle.com 	pctl->nvprt_nmfmt = "%s = ";
516*12967Sgavin.maltby@oracle.com 	pctl->nvprt_eomfmt = "\n";
517*12967Sgavin.maltby@oracle.com 	pctl->nvprt_btwnarrfmt = " ";
518*12967Sgavin.maltby@oracle.com 	pctl->nvprt_btwnarrfmt_nl = 0;
519*12967Sgavin.maltby@oracle.com 
520*12967Sgavin.maltby@oracle.com 	pctl->nvprt_dfltops = (struct nvlist_printops *)&defprtops;
521*12967Sgavin.maltby@oracle.com 	pctl->nvprt_custops = ops;
522*12967Sgavin.maltby@oracle.com }
523*12967Sgavin.maltby@oracle.com 
524*12967Sgavin.maltby@oracle.com nvlist_prtctl_t
nvlist_prtctl_alloc(void)525*12967Sgavin.maltby@oracle.com nvlist_prtctl_alloc(void)
526*12967Sgavin.maltby@oracle.com {
527*12967Sgavin.maltby@oracle.com 	struct nvlist_prtctl *pctl;
528*12967Sgavin.maltby@oracle.com 	struct nvlist_printops *ops;
529*12967Sgavin.maltby@oracle.com 
530*12967Sgavin.maltby@oracle.com 	if ((pctl = malloc(sizeof (*pctl))) == NULL)
531*12967Sgavin.maltby@oracle.com 		return (NULL);
532*12967Sgavin.maltby@oracle.com 
533*12967Sgavin.maltby@oracle.com 	if ((ops = calloc(1, sizeof (*ops))) == NULL) {
534*12967Sgavin.maltby@oracle.com 		free(pctl);
535*12967Sgavin.maltby@oracle.com 		return (NULL);
536*12967Sgavin.maltby@oracle.com 	}
537*12967Sgavin.maltby@oracle.com 
538*12967Sgavin.maltby@oracle.com 	prtctl_defaults(stdout, pctl, ops);
539*12967Sgavin.maltby@oracle.com 
540*12967Sgavin.maltby@oracle.com 	return (pctl);
541*12967Sgavin.maltby@oracle.com }
542*12967Sgavin.maltby@oracle.com 
543*12967Sgavin.maltby@oracle.com void
nvlist_prtctl_free(nvlist_prtctl_t pctl)544*12967Sgavin.maltby@oracle.com nvlist_prtctl_free(nvlist_prtctl_t pctl)
545*12967Sgavin.maltby@oracle.com {
546*12967Sgavin.maltby@oracle.com 	if (pctl != NULL) {
547*12967Sgavin.maltby@oracle.com 		free(pctl->nvprt_custops);
548*12967Sgavin.maltby@oracle.com 		free(pctl);
549*12967Sgavin.maltby@oracle.com 	}
550*12967Sgavin.maltby@oracle.com }
551*12967Sgavin.maltby@oracle.com 
552*12967Sgavin.maltby@oracle.com /*
553*12967Sgavin.maltby@oracle.com  * ======================================================================
554*12967Sgavin.maltby@oracle.com  * |									|
555*12967Sgavin.maltby@oracle.com  * | Top-level print request interfaces.				|
556*12967Sgavin.maltby@oracle.com  * |									|
557*12967Sgavin.maltby@oracle.com  * ======================================================================
558*12967Sgavin.maltby@oracle.com  */
559*12967Sgavin.maltby@oracle.com 
560*12967Sgavin.maltby@oracle.com /*
5610Sstevel@tonic-gate  * nvlist_print - Prints elements in an event buffer
5620Sstevel@tonic-gate  */
563*12967Sgavin.maltby@oracle.com static void
nvlist_print_with_indent(nvlist_t * nvl,nvlist_prtctl_t pctl)564*12967Sgavin.maltby@oracle.com nvlist_print_with_indent(nvlist_t *nvl, nvlist_prtctl_t pctl)
5650Sstevel@tonic-gate {
566*12967Sgavin.maltby@oracle.com 	FILE *fp = pctl->nvprt_fp;
5670Sstevel@tonic-gate 	char *name;
5680Sstevel@tonic-gate 	uint_t nelem;
5690Sstevel@tonic-gate 	nvpair_t *nvp;
5700Sstevel@tonic-gate 
5710Sstevel@tonic-gate 	if (nvl == NULL)
5720Sstevel@tonic-gate 		return;
5730Sstevel@tonic-gate 
574*12967Sgavin.maltby@oracle.com 	indent(pctl, 0);
5750Sstevel@tonic-gate 	(void) fprintf(fp, "nvlist version: %d\n", NVL_VERSION(nvl));
5760Sstevel@tonic-gate 
5770Sstevel@tonic-gate 	nvp = nvlist_next_nvpair(nvl, NULL);
5780Sstevel@tonic-gate 
5790Sstevel@tonic-gate 	while (nvp) {
5800Sstevel@tonic-gate 		data_type_t type = nvpair_type(nvp);
5810Sstevel@tonic-gate 
5820Sstevel@tonic-gate 		name = nvpair_name(nvp);
5830Sstevel@tonic-gate 		nelem = 0;
584*12967Sgavin.maltby@oracle.com 
5850Sstevel@tonic-gate 		switch (type) {
5860Sstevel@tonic-gate 		case DATA_TYPE_BOOLEAN: {
587*12967Sgavin.maltby@oracle.com 			RENDER(pctl, boolean, nvl, name, 1);
5880Sstevel@tonic-gate 			break;
5890Sstevel@tonic-gate 		}
5900Sstevel@tonic-gate 		case DATA_TYPE_BOOLEAN_VALUE: {
5910Sstevel@tonic-gate 			boolean_t val;
5920Sstevel@tonic-gate 			(void) nvpair_value_boolean_value(nvp, &val);
593*12967Sgavin.maltby@oracle.com 			RENDER(pctl, boolean_value, nvl, name, val);
5940Sstevel@tonic-gate 			break;
5950Sstevel@tonic-gate 		}
5960Sstevel@tonic-gate 		case DATA_TYPE_BYTE: {
5970Sstevel@tonic-gate 			uchar_t val;
5980Sstevel@tonic-gate 			(void) nvpair_value_byte(nvp, &val);
599*12967Sgavin.maltby@oracle.com 			RENDER(pctl, byte, nvl, name, val);
6000Sstevel@tonic-gate 			break;
6010Sstevel@tonic-gate 		}
6020Sstevel@tonic-gate 		case DATA_TYPE_INT8: {
6030Sstevel@tonic-gate 			int8_t val;
6040Sstevel@tonic-gate 			(void) nvpair_value_int8(nvp, &val);
605*12967Sgavin.maltby@oracle.com 			RENDER(pctl, int8, nvl, name, val);
6060Sstevel@tonic-gate 			break;
6070Sstevel@tonic-gate 		}
6080Sstevel@tonic-gate 		case DATA_TYPE_UINT8: {
6090Sstevel@tonic-gate 			uint8_t val;
6100Sstevel@tonic-gate 			(void) nvpair_value_uint8(nvp, &val);
611*12967Sgavin.maltby@oracle.com 			RENDER(pctl, uint8, nvl, name, val);
6120Sstevel@tonic-gate 			break;
6130Sstevel@tonic-gate 		}
6140Sstevel@tonic-gate 		case DATA_TYPE_INT16: {
6150Sstevel@tonic-gate 			int16_t val;
6160Sstevel@tonic-gate 			(void) nvpair_value_int16(nvp, &val);
617*12967Sgavin.maltby@oracle.com 			RENDER(pctl, int16, nvl, name, val);
6180Sstevel@tonic-gate 			break;
6190Sstevel@tonic-gate 		}
6200Sstevel@tonic-gate 		case DATA_TYPE_UINT16: {
6210Sstevel@tonic-gate 			uint16_t val;
6220Sstevel@tonic-gate 			(void) nvpair_value_uint16(nvp, &val);
623*12967Sgavin.maltby@oracle.com 			RENDER(pctl, uint16, nvl, name, val);
6240Sstevel@tonic-gate 			break;
6250Sstevel@tonic-gate 		}
6260Sstevel@tonic-gate 		case DATA_TYPE_INT32: {
6270Sstevel@tonic-gate 			int32_t val;
6280Sstevel@tonic-gate 			(void) nvpair_value_int32(nvp, &val);
629*12967Sgavin.maltby@oracle.com 			RENDER(pctl, int32, nvl, name, val);
6300Sstevel@tonic-gate 			break;
6310Sstevel@tonic-gate 		}
6320Sstevel@tonic-gate 		case DATA_TYPE_UINT32: {
6330Sstevel@tonic-gate 			uint32_t val;
6340Sstevel@tonic-gate 			(void) nvpair_value_uint32(nvp, &val);
635*12967Sgavin.maltby@oracle.com 			RENDER(pctl, uint32, nvl, name, val);
6360Sstevel@tonic-gate 			break;
6370Sstevel@tonic-gate 		}
6380Sstevel@tonic-gate 		case DATA_TYPE_INT64: {
6390Sstevel@tonic-gate 			int64_t val;
6400Sstevel@tonic-gate 			(void) nvpair_value_int64(nvp, &val);
641*12967Sgavin.maltby@oracle.com 			RENDER(pctl, int64, nvl, name, val);
6420Sstevel@tonic-gate 			break;
6430Sstevel@tonic-gate 		}
6440Sstevel@tonic-gate 		case DATA_TYPE_UINT64: {
6450Sstevel@tonic-gate 			uint64_t val;
6460Sstevel@tonic-gate 			(void) nvpair_value_uint64(nvp, &val);
647*12967Sgavin.maltby@oracle.com 			RENDER(pctl, uint64, nvl, name, val);
6480Sstevel@tonic-gate 			break;
6490Sstevel@tonic-gate 		}
6507243Srobj 		case DATA_TYPE_DOUBLE: {
6517243Srobj 			double val;
6527243Srobj 			(void) nvpair_value_double(nvp, &val);
653*12967Sgavin.maltby@oracle.com 			RENDER(pctl, double, nvl, name, val);
6547243Srobj 			break;
6557243Srobj 		}
6560Sstevel@tonic-gate 		case DATA_TYPE_STRING: {
6570Sstevel@tonic-gate 			char *val;
6580Sstevel@tonic-gate 			(void) nvpair_value_string(nvp, &val);
659*12967Sgavin.maltby@oracle.com 			RENDER(pctl, string, nvl, name, val);
6600Sstevel@tonic-gate 			break;
6610Sstevel@tonic-gate 		}
6620Sstevel@tonic-gate 		case DATA_TYPE_BOOLEAN_ARRAY: {
6630Sstevel@tonic-gate 			boolean_t *val;
6640Sstevel@tonic-gate 			(void) nvpair_value_boolean_array(nvp, &val, &nelem);
665*12967Sgavin.maltby@oracle.com 			ARENDER(pctl, boolean_array, nvl, name, val, nelem);
6660Sstevel@tonic-gate 			break;
6670Sstevel@tonic-gate 		}
6680Sstevel@tonic-gate 		case DATA_TYPE_BYTE_ARRAY: {
6690Sstevel@tonic-gate 			uchar_t *val;
6700Sstevel@tonic-gate 			(void) nvpair_value_byte_array(nvp, &val, &nelem);
671*12967Sgavin.maltby@oracle.com 			ARENDER(pctl, byte_array, nvl, name, val, nelem);
6720Sstevel@tonic-gate 			break;
6730Sstevel@tonic-gate 		}
6740Sstevel@tonic-gate 		case DATA_TYPE_INT8_ARRAY: {
6750Sstevel@tonic-gate 			int8_t *val;
6760Sstevel@tonic-gate 			(void) nvpair_value_int8_array(nvp, &val, &nelem);
677*12967Sgavin.maltby@oracle.com 			ARENDER(pctl, int8_array, nvl, name, val, nelem);
6780Sstevel@tonic-gate 			break;
6790Sstevel@tonic-gate 		}
6800Sstevel@tonic-gate 		case DATA_TYPE_UINT8_ARRAY: {
6810Sstevel@tonic-gate 			uint8_t *val;
6820Sstevel@tonic-gate 			(void) nvpair_value_uint8_array(nvp, &val, &nelem);
683*12967Sgavin.maltby@oracle.com 			ARENDER(pctl, uint8_array, nvl, name, val, nelem);
6840Sstevel@tonic-gate 			break;
6850Sstevel@tonic-gate 		}
6860Sstevel@tonic-gate 		case DATA_TYPE_INT16_ARRAY: {
6870Sstevel@tonic-gate 			int16_t *val;
6880Sstevel@tonic-gate 			(void) nvpair_value_int16_array(nvp, &val, &nelem);
689*12967Sgavin.maltby@oracle.com 			ARENDER(pctl, int16_array, nvl, name, val, nelem);
6900Sstevel@tonic-gate 			break;
6910Sstevel@tonic-gate 		}
6920Sstevel@tonic-gate 		case DATA_TYPE_UINT16_ARRAY: {
6930Sstevel@tonic-gate 			uint16_t *val;
6940Sstevel@tonic-gate 			(void) nvpair_value_uint16_array(nvp, &val, &nelem);
695*12967Sgavin.maltby@oracle.com 			ARENDER(pctl, uint16_array, nvl, name, val, nelem);
6960Sstevel@tonic-gate 			break;
6970Sstevel@tonic-gate 		}
6980Sstevel@tonic-gate 		case DATA_TYPE_INT32_ARRAY: {
6990Sstevel@tonic-gate 			int32_t *val;
7000Sstevel@tonic-gate 			(void) nvpair_value_int32_array(nvp, &val, &nelem);
701*12967Sgavin.maltby@oracle.com 			ARENDER(pctl, int32_array, nvl, name, val, nelem);
7020Sstevel@tonic-gate 			break;
7030Sstevel@tonic-gate 		}
7040Sstevel@tonic-gate 		case DATA_TYPE_UINT32_ARRAY: {
7050Sstevel@tonic-gate 			uint32_t *val;
7060Sstevel@tonic-gate 			(void) nvpair_value_uint32_array(nvp, &val, &nelem);
707*12967Sgavin.maltby@oracle.com 			ARENDER(pctl, uint32_array, nvl, name, val, nelem);
7080Sstevel@tonic-gate 			break;
7090Sstevel@tonic-gate 		}
7100Sstevel@tonic-gate 		case DATA_TYPE_INT64_ARRAY: {
7110Sstevel@tonic-gate 			int64_t *val;
7120Sstevel@tonic-gate 			(void) nvpair_value_int64_array(nvp, &val, &nelem);
713*12967Sgavin.maltby@oracle.com 			ARENDER(pctl, int64_array, nvl, name, val, nelem);
7140Sstevel@tonic-gate 			break;
7150Sstevel@tonic-gate 		}
7160Sstevel@tonic-gate 		case DATA_TYPE_UINT64_ARRAY: {
7170Sstevel@tonic-gate 			uint64_t *val;
7180Sstevel@tonic-gate 			(void) nvpair_value_uint64_array(nvp, &val, &nelem);
719*12967Sgavin.maltby@oracle.com 			ARENDER(pctl, uint64_array, nvl, name, val, nelem);
7200Sstevel@tonic-gate 			break;
7210Sstevel@tonic-gate 		}
7220Sstevel@tonic-gate 		case DATA_TYPE_STRING_ARRAY: {
7230Sstevel@tonic-gate 			char **val;
7240Sstevel@tonic-gate 			(void) nvpair_value_string_array(nvp, &val, &nelem);
725*12967Sgavin.maltby@oracle.com 			ARENDER(pctl, string_array, nvl, name, val, nelem);
7260Sstevel@tonic-gate 			break;
7270Sstevel@tonic-gate 		}
7280Sstevel@tonic-gate 		case DATA_TYPE_HRTIME: {
7290Sstevel@tonic-gate 			hrtime_t val;
7300Sstevel@tonic-gate 			(void) nvpair_value_hrtime(nvp, &val);
731*12967Sgavin.maltby@oracle.com 			RENDER(pctl, hrtime, nvl, name, val);
7320Sstevel@tonic-gate 			break;
7330Sstevel@tonic-gate 		}
7340Sstevel@tonic-gate 		case DATA_TYPE_NVLIST: {
7350Sstevel@tonic-gate 			nvlist_t *val;
7360Sstevel@tonic-gate 			(void) nvpair_value_nvlist(nvp, &val);
737*12967Sgavin.maltby@oracle.com 			RENDER(pctl, nvlist, nvl, name, val);
7380Sstevel@tonic-gate 			break;
7390Sstevel@tonic-gate 		}
7400Sstevel@tonic-gate 		case DATA_TYPE_NVLIST_ARRAY: {
7410Sstevel@tonic-gate 			nvlist_t **val;
7420Sstevel@tonic-gate 			(void) nvpair_value_nvlist_array(nvp, &val, &nelem);
743*12967Sgavin.maltby@oracle.com 			ARENDER(pctl, nvlist_array, nvl, name, val, nelem);
7440Sstevel@tonic-gate 			break;
7450Sstevel@tonic-gate 		}
7460Sstevel@tonic-gate 		default:
7470Sstevel@tonic-gate 			(void) fprintf(fp, " unknown data type (%d)", type);
7480Sstevel@tonic-gate 			break;
7490Sstevel@tonic-gate 		}
7500Sstevel@tonic-gate 		nvp = nvlist_next_nvpair(nvl, nvp);
7510Sstevel@tonic-gate 	}
7520Sstevel@tonic-gate }
7530Sstevel@tonic-gate 
7540Sstevel@tonic-gate void
nvlist_print(FILE * fp,nvlist_t * nvl)7550Sstevel@tonic-gate nvlist_print(FILE *fp, nvlist_t *nvl)
7560Sstevel@tonic-gate {
757*12967Sgavin.maltby@oracle.com 	struct nvlist_prtctl pc;
758*12967Sgavin.maltby@oracle.com 
759*12967Sgavin.maltby@oracle.com 	prtctl_defaults(fp, &pc, NULL);
760*12967Sgavin.maltby@oracle.com 	nvlist_print_with_indent(nvl, &pc);
7610Sstevel@tonic-gate }
7626640Scth 
763*12967Sgavin.maltby@oracle.com void
nvlist_prt(nvlist_t * nvl,nvlist_prtctl_t pctl)764*12967Sgavin.maltby@oracle.com nvlist_prt(nvlist_t *nvl, nvlist_prtctl_t pctl)
765*12967Sgavin.maltby@oracle.com {
766*12967Sgavin.maltby@oracle.com 	nvlist_print_with_indent(nvl, pctl);
767*12967Sgavin.maltby@oracle.com }
76810594SGeorge.Wilson@Sun.COM 
76910594SGeorge.Wilson@Sun.COM #define	NVP(elem, type, vtype, ptype, format) { \
77010594SGeorge.Wilson@Sun.COM 	vtype	value; \
77110594SGeorge.Wilson@Sun.COM \
77210594SGeorge.Wilson@Sun.COM 	(void) nvpair_value_##type(elem, &value); \
77310594SGeorge.Wilson@Sun.COM 	(void) printf("%*s%s: " format "\n", indent, "", \
77410594SGeorge.Wilson@Sun.COM 	    nvpair_name(elem), (ptype)value); \
77510594SGeorge.Wilson@Sun.COM }
77610594SGeorge.Wilson@Sun.COM 
77710594SGeorge.Wilson@Sun.COM #define	NVPA(elem, type, vtype, ptype, format) { \
77810594SGeorge.Wilson@Sun.COM 	uint_t	i, count; \
77910594SGeorge.Wilson@Sun.COM 	vtype	*value;  \
78010594SGeorge.Wilson@Sun.COM \
78110594SGeorge.Wilson@Sun.COM 	(void) nvpair_value_##type(elem, &value, &count); \
78210594SGeorge.Wilson@Sun.COM 	for (i = 0; i < count; i++) { \
78310594SGeorge.Wilson@Sun.COM 		(void) printf("%*s%s[%d]: " format "\n", indent, "", \
78410594SGeorge.Wilson@Sun.COM 		    nvpair_name(elem), i, (ptype)value[i]); \
78510594SGeorge.Wilson@Sun.COM 	} \
78610594SGeorge.Wilson@Sun.COM }
78710594SGeorge.Wilson@Sun.COM 
78810594SGeorge.Wilson@Sun.COM /*
78910594SGeorge.Wilson@Sun.COM  * Similar to nvlist_print() but handles arrays slightly differently.
79010594SGeorge.Wilson@Sun.COM  */
79110594SGeorge.Wilson@Sun.COM void
dump_nvlist(nvlist_t * list,int indent)79210594SGeorge.Wilson@Sun.COM dump_nvlist(nvlist_t *list, int indent)
79310594SGeorge.Wilson@Sun.COM {
79410594SGeorge.Wilson@Sun.COM 	nvpair_t	*elem = NULL;
79510594SGeorge.Wilson@Sun.COM 	boolean_t	bool_value;
79610594SGeorge.Wilson@Sun.COM 	nvlist_t	*nvlist_value;
79710594SGeorge.Wilson@Sun.COM 	nvlist_t	**nvlist_array_value;
79810594SGeorge.Wilson@Sun.COM 	uint_t		i, count;
79910594SGeorge.Wilson@Sun.COM 
80010594SGeorge.Wilson@Sun.COM 	if (list == NULL) {
80110594SGeorge.Wilson@Sun.COM 		return;
80210594SGeorge.Wilson@Sun.COM 	}
80310594SGeorge.Wilson@Sun.COM 
80410594SGeorge.Wilson@Sun.COM 	while ((elem = nvlist_next_nvpair(list, elem)) != NULL) {
80510594SGeorge.Wilson@Sun.COM 		switch (nvpair_type(elem)) {
80610594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_BOOLEAN_VALUE:
80710594SGeorge.Wilson@Sun.COM 			(void) nvpair_value_boolean_value(elem, &bool_value);
80810594SGeorge.Wilson@Sun.COM 			(void) printf("%*s%s: %s\n", indent, "",
80910594SGeorge.Wilson@Sun.COM 			    nvpair_name(elem), bool_value ? "true" : "false");
81010594SGeorge.Wilson@Sun.COM 			break;
81110594SGeorge.Wilson@Sun.COM 
81210594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_BYTE:
81310594SGeorge.Wilson@Sun.COM 			NVP(elem, byte, uchar_t, int, "%u");
81410594SGeorge.Wilson@Sun.COM 			break;
81510594SGeorge.Wilson@Sun.COM 
81610594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_INT8:
81710594SGeorge.Wilson@Sun.COM 			NVP(elem, int8, int8_t, int, "%d");
81810594SGeorge.Wilson@Sun.COM 			break;
81910594SGeorge.Wilson@Sun.COM 
82010594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_UINT8:
82110594SGeorge.Wilson@Sun.COM 			NVP(elem, uint8, uint8_t, int, "%u");
82210594SGeorge.Wilson@Sun.COM 			break;
82310594SGeorge.Wilson@Sun.COM 
82410594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_INT16:
82510594SGeorge.Wilson@Sun.COM 			NVP(elem, int16, int16_t, int, "%d");
82610594SGeorge.Wilson@Sun.COM 			break;
82710594SGeorge.Wilson@Sun.COM 
82810594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_UINT16:
82910594SGeorge.Wilson@Sun.COM 			NVP(elem, uint16, uint16_t, int, "%u");
83010594SGeorge.Wilson@Sun.COM 			break;
83110594SGeorge.Wilson@Sun.COM 
83210594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_INT32:
83310594SGeorge.Wilson@Sun.COM 			NVP(elem, int32, int32_t, long, "%ld");
83410594SGeorge.Wilson@Sun.COM 			break;
83510594SGeorge.Wilson@Sun.COM 
83610594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_UINT32:
83710594SGeorge.Wilson@Sun.COM 			NVP(elem, uint32, uint32_t, ulong_t, "%lu");
83810594SGeorge.Wilson@Sun.COM 			break;
83910594SGeorge.Wilson@Sun.COM 
84010594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_INT64:
84110594SGeorge.Wilson@Sun.COM 			NVP(elem, int64, int64_t, longlong_t, "%lld");
84210594SGeorge.Wilson@Sun.COM 			break;
84310594SGeorge.Wilson@Sun.COM 
84410594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_UINT64:
84510594SGeorge.Wilson@Sun.COM 			NVP(elem, uint64, uint64_t, u_longlong_t, "%llu");
84610594SGeorge.Wilson@Sun.COM 			break;
84710594SGeorge.Wilson@Sun.COM 
84810594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_STRING:
84910594SGeorge.Wilson@Sun.COM 			NVP(elem, string, char *, char *, "'%s'");
85010594SGeorge.Wilson@Sun.COM 			break;
85110594SGeorge.Wilson@Sun.COM 
85210594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_BYTE_ARRAY:
85310594SGeorge.Wilson@Sun.COM 			NVPA(elem, byte_array, uchar_t, int, "%u");
85410594SGeorge.Wilson@Sun.COM 			break;
85510594SGeorge.Wilson@Sun.COM 
85610594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_INT8_ARRAY:
85710594SGeorge.Wilson@Sun.COM 			NVPA(elem, int8_array, int8_t, int, "%d");
85810594SGeorge.Wilson@Sun.COM 			break;
85910594SGeorge.Wilson@Sun.COM 
86010594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_UINT8_ARRAY:
86110594SGeorge.Wilson@Sun.COM 			NVPA(elem, uint8_array, uint8_t, int, "%u");
86210594SGeorge.Wilson@Sun.COM 			break;
86310594SGeorge.Wilson@Sun.COM 
86410594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_INT16_ARRAY:
86510594SGeorge.Wilson@Sun.COM 			NVPA(elem, int16_array, int16_t, int, "%d");
86610594SGeorge.Wilson@Sun.COM 			break;
86710594SGeorge.Wilson@Sun.COM 
86810594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_UINT16_ARRAY:
86910594SGeorge.Wilson@Sun.COM 			NVPA(elem, uint16_array, uint16_t, int, "%u");
87010594SGeorge.Wilson@Sun.COM 			break;
87110594SGeorge.Wilson@Sun.COM 
87210594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_INT32_ARRAY:
87310594SGeorge.Wilson@Sun.COM 			NVPA(elem, int32_array, int32_t, long, "%ld");
87410594SGeorge.Wilson@Sun.COM 			break;
87510594SGeorge.Wilson@Sun.COM 
87610594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_UINT32_ARRAY:
87710594SGeorge.Wilson@Sun.COM 			NVPA(elem, uint32_array, uint32_t, ulong_t, "%lu");
87810594SGeorge.Wilson@Sun.COM 			break;
87910594SGeorge.Wilson@Sun.COM 
88010594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_INT64_ARRAY:
88110594SGeorge.Wilson@Sun.COM 			NVPA(elem, int64_array, int64_t, longlong_t, "%lld");
88210594SGeorge.Wilson@Sun.COM 			break;
88310594SGeorge.Wilson@Sun.COM 
88410594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_UINT64_ARRAY:
88510594SGeorge.Wilson@Sun.COM 			NVPA(elem, uint64_array, uint64_t, u_longlong_t,
88610594SGeorge.Wilson@Sun.COM 			    "%llu");
88710594SGeorge.Wilson@Sun.COM 			break;
88810594SGeorge.Wilson@Sun.COM 
88910594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_STRING_ARRAY:
89010594SGeorge.Wilson@Sun.COM 			NVPA(elem, string_array, char *, char *, "'%s'");
89110594SGeorge.Wilson@Sun.COM 			break;
89210594SGeorge.Wilson@Sun.COM 
89310594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_NVLIST:
89410594SGeorge.Wilson@Sun.COM 			(void) nvpair_value_nvlist(elem, &nvlist_value);
89510594SGeorge.Wilson@Sun.COM 			(void) printf("%*s%s:\n", indent, "",
89610594SGeorge.Wilson@Sun.COM 			    nvpair_name(elem));
89710594SGeorge.Wilson@Sun.COM 			dump_nvlist(nvlist_value, indent + 4);
89810594SGeorge.Wilson@Sun.COM 			break;
89910594SGeorge.Wilson@Sun.COM 
90010594SGeorge.Wilson@Sun.COM 		case DATA_TYPE_NVLIST_ARRAY:
90110594SGeorge.Wilson@Sun.COM 			(void) nvpair_value_nvlist_array(elem,
90210594SGeorge.Wilson@Sun.COM 			    &nvlist_array_value, &count);
90310594SGeorge.Wilson@Sun.COM 			for (i = 0; i < count; i++) {
90410594SGeorge.Wilson@Sun.COM 				(void) printf("%*s%s[%u]:\n", indent, "",
90510594SGeorge.Wilson@Sun.COM 				    nvpair_name(elem), i);
90610594SGeorge.Wilson@Sun.COM 				dump_nvlist(nvlist_array_value[i], indent + 4);
90710594SGeorge.Wilson@Sun.COM 			}
90810594SGeorge.Wilson@Sun.COM 			break;
90910594SGeorge.Wilson@Sun.COM 
91010594SGeorge.Wilson@Sun.COM 		default:
91110594SGeorge.Wilson@Sun.COM 			(void) printf(dgettext(TEXT_DOMAIN, "bad config type "
91210594SGeorge.Wilson@Sun.COM 			    "%d for %s\n"), nvpair_type(elem),
91310594SGeorge.Wilson@Sun.COM 			    nvpair_name(elem));
91410594SGeorge.Wilson@Sun.COM 		}
91510594SGeorge.Wilson@Sun.COM 	}
91610594SGeorge.Wilson@Sun.COM }
91710594SGeorge.Wilson@Sun.COM 
9186640Scth /*
919*12967Sgavin.maltby@oracle.com  * ======================================================================
920*12967Sgavin.maltby@oracle.com  * |									|
921*12967Sgavin.maltby@oracle.com  * | Misc private interface.						|
922*12967Sgavin.maltby@oracle.com  * |									|
923*12967Sgavin.maltby@oracle.com  * ======================================================================
924*12967Sgavin.maltby@oracle.com  */
925*12967Sgavin.maltby@oracle.com 
926*12967Sgavin.maltby@oracle.com /*
9276640Scth  * Determine if string 'value' matches 'nvp' value.  The 'value' string is
9286640Scth  * converted, depending on the type of 'nvp', prior to match.  For numeric
9296640Scth  * types, a radix independent sscanf conversion of 'value' is used. If 'nvp'
9306640Scth  * is an array type, 'ai' is the index into the array against which we are
9316640Scth  * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass
9326640Scth  * in a regex_t compilation of value in 'value_regex' to trigger regular
9336640Scth  * expression string match instead of simple strcmp().
9346640Scth  *
9356640Scth  * Return 1 on match, 0 on no-match, and -1 on error.  If the error is
9366640Scth  * related to value syntax error and 'ep' is non-NULL, *ep will point into
9376640Scth  * the 'value' string at the location where the error exists.
9386640Scth  *
9396640Scth  * NOTE: It may be possible to move the non-regex_t version of this into
9406640Scth  * common code used by library/kernel/boot.
9416640Scth  */
9426640Scth int
nvpair_value_match_regex(nvpair_t * nvp,int ai,char * value,regex_t * value_regex,char ** ep)9436640Scth nvpair_value_match_regex(nvpair_t *nvp, int ai,
9446640Scth     char *value, regex_t *value_regex, char **ep)
9456640Scth {
9466640Scth 	char	*evalue;
9476640Scth 	uint_t	a_len;
9486640Scth 	int	sr;
9496640Scth 
9506640Scth 	if (ep)
9516640Scth 		*ep = NULL;
9526640Scth 
9536640Scth 	if ((nvp == NULL) || (value == NULL))
9546640Scth 		return (-1);		/* error fail match - invalid args */
9556640Scth 
9566640Scth 	/* make sure array and index combination make sense */
9576640Scth 	if ((nvpair_type_is_array(nvp) && (ai < 0)) ||
9586640Scth 	    (!nvpair_type_is_array(nvp) && (ai >= 0)))
9596640Scth 		return (-1);		/* error fail match - bad index */
9606640Scth 
9616640Scth 	/* non-string values should be single 'chunk' */
9626640Scth 	if ((nvpair_type(nvp) != DATA_TYPE_STRING) &&
9636640Scth 	    (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) {
9646640Scth 		value += strspn(value, " \t");
9656640Scth 		evalue = value + strcspn(value, " \t");
9666640Scth 		if (*evalue) {
9676640Scth 			if (ep)
9686640Scth 				*ep = evalue;
9696640Scth 			return (-1);	/* error fail match - syntax */
9706640Scth 		}
9716640Scth 	}
9726640Scth 
9736640Scth 	sr = EOF;
9746640Scth 	switch (nvpair_type(nvp)) {
9756640Scth 	case DATA_TYPE_STRING: {
9766640Scth 		char	*val;
9776640Scth 
9786640Scth 		/* check string value for match */
9796640Scth 		if (nvpair_value_string(nvp, &val) == 0) {
9806640Scth 			if (value_regex) {
9816640Scth 				if (regexec(value_regex, val,
9826640Scth 				    (size_t)0, NULL, 0) == 0)
9836640Scth 					return (1);	/* match */
9846640Scth 			} else {
9856640Scth 				if (strcmp(value, val) == 0)
9866640Scth 					return (1);	/* match */
9876640Scth 			}
9886640Scth 		}
9896640Scth 		break;
9906640Scth 	}
9916640Scth 	case DATA_TYPE_STRING_ARRAY: {
9926640Scth 		char **val_array;
9936640Scth 
9946640Scth 		/* check indexed string value of array for match */
9956640Scth 		if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) &&
9966640Scth 		    (ai < a_len)) {
9976640Scth 			if (value_regex) {
9986640Scth 				if (regexec(value_regex, val_array[ai],
9996640Scth 				    (size_t)0, NULL, 0) == 0)
10006640Scth 					return (1);
10016640Scth 			} else {
10026640Scth 				if (strcmp(value, val_array[ai]) == 0)
10036640Scth 					return (1);
10046640Scth 			}
10056640Scth 		}
10066640Scth 		break;
10076640Scth 	}
10086640Scth 	case DATA_TYPE_BYTE: {
10096640Scth 		uchar_t val, val_arg;
10106640Scth 
10116640Scth 		/* scanf uchar_t from value and check for match */
10126640Scth 		sr = sscanf(value, "%c", &val_arg);
10136640Scth 		if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) &&
10146640Scth 		    (val == val_arg))
10156640Scth 			return (1);
10166640Scth 		break;
10176640Scth 	}
10186640Scth 	case DATA_TYPE_BYTE_ARRAY: {
10196640Scth 		uchar_t *val_array, val_arg;
10206640Scth 
10216640Scth 
10226640Scth 		/* check indexed value of array for match */
10236640Scth 		sr = sscanf(value, "%c", &val_arg);
10246640Scth 		if ((sr == 1) &&
10256640Scth 		    (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) &&
10266640Scth 		    (ai < a_len) &&
10276640Scth 		    (val_array[ai] == val_arg))
10286640Scth 			return (1);
10296640Scth 		break;
10306640Scth 	}
10316640Scth 	case DATA_TYPE_INT8: {
10326640Scth 		int8_t val, val_arg;
10336640Scth 
10346640Scth 		/* scanf int8_t from value and check for match */
10356640Scth 		sr = sscanf(value, "%"SCNi8, &val_arg);
10366640Scth 		if ((sr == 1) &&
10376640Scth 		    (nvpair_value_int8(nvp, &val) == 0) &&
10386640Scth 		    (val == val_arg))
10396640Scth 			return (1);
10406640Scth 		break;
10416640Scth 	}
10426640Scth 	case DATA_TYPE_INT8_ARRAY: {
10436640Scth 		int8_t *val_array, val_arg;
10446640Scth 
10456640Scth 		/* check indexed value of array for match */
10466640Scth 		sr = sscanf(value, "%"SCNi8, &val_arg);
10476640Scth 		if ((sr == 1) &&
10486640Scth 		    (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) &&
10496640Scth 		    (ai < a_len) &&
10506640Scth 		    (val_array[ai] == val_arg))
10516640Scth 			return (1);
10526640Scth 		break;
10536640Scth 	}
10546640Scth 	case DATA_TYPE_UINT8: {
10556640Scth 		uint8_t val, val_arg;
10566640Scth 
10576640Scth 		/* scanf uint8_t from value and check for match */
10586640Scth 		sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
10596640Scth 		if ((sr == 1) &&
10606640Scth 		    (nvpair_value_uint8(nvp, &val) == 0) &&
10616640Scth 		    (val == val_arg))
10626640Scth 			return (1);
10636640Scth 		break;
10646640Scth 	}
10656640Scth 	case DATA_TYPE_UINT8_ARRAY: {
10666640Scth 		uint8_t *val_array, val_arg;
10676640Scth 
10686640Scth 		/* check indexed value of array for match */
10696640Scth 		sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
10706640Scth 		if ((sr == 1) &&
10716640Scth 		    (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) &&
10726640Scth 		    (ai < a_len) &&
10736640Scth 		    (val_array[ai] == val_arg))
10746640Scth 			return (1);
10756640Scth 		break;
10766640Scth 	}
10776640Scth 	case DATA_TYPE_INT16: {
10786640Scth 		int16_t val, val_arg;
10796640Scth 
10806640Scth 		/* scanf int16_t from value and check for match */
10816640Scth 		sr = sscanf(value, "%"SCNi16, &val_arg);
10826640Scth 		if ((sr == 1) &&
10836640Scth 		    (nvpair_value_int16(nvp, &val) == 0) &&
10846640Scth 		    (val == val_arg))
10856640Scth 			return (1);
10866640Scth 		break;
10876640Scth 	}
10886640Scth 	case DATA_TYPE_INT16_ARRAY: {
10896640Scth 		int16_t *val_array, val_arg;
10906640Scth 
10916640Scth 		/* check indexed value of array for match */
10926640Scth 		sr = sscanf(value, "%"SCNi16, &val_arg);
10936640Scth 		if ((sr == 1) &&
10946640Scth 		    (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) &&
10956640Scth 		    (ai < a_len) &&
10966640Scth 		    (val_array[ai] == val_arg))
10976640Scth 			return (1);
10986640Scth 		break;
10996640Scth 	}
11006640Scth 	case DATA_TYPE_UINT16: {
11016640Scth 		uint16_t val, val_arg;
11026640Scth 
11036640Scth 		/* scanf uint16_t from value and check for match */
11046640Scth 		sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
11056640Scth 		if ((sr == 1) &&
11066640Scth 		    (nvpair_value_uint16(nvp, &val) == 0) &&
11076640Scth 		    (val == val_arg))
11086640Scth 			return (1);
11096640Scth 		break;
11106640Scth 	}
11116640Scth 	case DATA_TYPE_UINT16_ARRAY: {
11126640Scth 		uint16_t *val_array, val_arg;
11136640Scth 
11146640Scth 		/* check indexed value of array for match */
11156640Scth 		sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
11166640Scth 		if ((sr == 1) &&
11176640Scth 		    (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) &&
11186640Scth 		    (ai < a_len) &&
11196640Scth 		    (val_array[ai] == val_arg))
11206640Scth 			return (1);
11216640Scth 		break;
11226640Scth 	}
11236640Scth 	case DATA_TYPE_INT32: {
11246640Scth 		int32_t val, val_arg;
11256640Scth 
11266640Scth 		/* scanf int32_t from value and check for match */
11276640Scth 		sr = sscanf(value, "%"SCNi32, &val_arg);
11286640Scth 		if ((sr == 1) &&
11296640Scth 		    (nvpair_value_int32(nvp, &val) == 0) &&
11306640Scth 		    (val == val_arg))
11316640Scth 			return (1);
11326640Scth 		break;
11336640Scth 	}
11346640Scth 	case DATA_TYPE_INT32_ARRAY: {
11356640Scth 		int32_t *val_array, val_arg;
11366640Scth 
11376640Scth 		/* check indexed value of array for match */
11386640Scth 		sr = sscanf(value, "%"SCNi32, &val_arg);
11396640Scth 		if ((sr == 1) &&
11406640Scth 		    (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) &&
11416640Scth 		    (ai < a_len) &&
11426640Scth 		    (val_array[ai] == val_arg))
11436640Scth 			return (1);
11446640Scth 		break;
11456640Scth 	}
11466640Scth 	case DATA_TYPE_UINT32: {
11476640Scth 		uint32_t val, val_arg;
11486640Scth 
11496640Scth 		/* scanf uint32_t from value and check for match */
11506640Scth 		sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
11516640Scth 		if ((sr == 1) &&
11526640Scth 		    (nvpair_value_uint32(nvp, &val) == 0) &&
11536640Scth 		    (val == val_arg))
11546640Scth 			return (1);
11556640Scth 		break;
11566640Scth 	}
11576640Scth 	case DATA_TYPE_UINT32_ARRAY: {
11586640Scth 		uint32_t *val_array, val_arg;
11596640Scth 
11606640Scth 		/* check indexed value of array for match */
11616640Scth 		sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
11626640Scth 		if ((sr == 1) &&
11636640Scth 		    (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) &&
11646640Scth 		    (ai < a_len) &&
11656640Scth 		    (val_array[ai] == val_arg))
11666640Scth 			return (1);
11676640Scth 		break;
11686640Scth 	}
11696640Scth 	case DATA_TYPE_INT64: {
11706640Scth 		int64_t val, val_arg;
11716640Scth 
11726640Scth 		/* scanf int64_t from value and check for match */
11736640Scth 		sr = sscanf(value, "%"SCNi64, &val_arg);
11746640Scth 		if ((sr == 1) &&
11756640Scth 		    (nvpair_value_int64(nvp, &val) == 0) &&
11766640Scth 		    (val == val_arg))
11776640Scth 			return (1);
11786640Scth 		break;
11796640Scth 	}
11806640Scth 	case DATA_TYPE_INT64_ARRAY: {
11816640Scth 		int64_t *val_array, val_arg;
11826640Scth 
11836640Scth 		/* check indexed value of array for match */
11846640Scth 		sr = sscanf(value, "%"SCNi64, &val_arg);
11856640Scth 		if ((sr == 1) &&
11866640Scth 		    (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) &&
11876640Scth 		    (ai < a_len) &&
11886640Scth 		    (val_array[ai] == val_arg))
11896640Scth 				return (1);
11906640Scth 		break;
11916640Scth 	}
11926640Scth 	case DATA_TYPE_UINT64: {
11936640Scth 		uint64_t val_arg, val;
11946640Scth 
11956640Scth 		/* scanf uint64_t from value and check for match */
11966640Scth 		sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
11976640Scth 		if ((sr == 1) &&
11986640Scth 		    (nvpair_value_uint64(nvp, &val) == 0) &&
11996640Scth 		    (val == val_arg))
12006640Scth 			return (1);
12016640Scth 		break;
12026640Scth 	}
12036640Scth 	case DATA_TYPE_UINT64_ARRAY: {
12046640Scth 		uint64_t *val_array, val_arg;
12056640Scth 
12066640Scth 		/* check indexed value of array for match */
12076640Scth 		sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
12086640Scth 		if ((sr == 1) &&
12096640Scth 		    (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) &&
12106640Scth 		    (ai < a_len) &&
12116640Scth 		    (val_array[ai] == val_arg))
12126640Scth 			return (1);
12136640Scth 		break;
12146640Scth 	}
12156640Scth 	case DATA_TYPE_BOOLEAN_VALUE: {
12166640Scth 		boolean_t val, val_arg;
12176640Scth 
12186640Scth 		/* scanf boolean_t from value and check for match */
12196640Scth 		sr = sscanf(value, "%"SCNi32, &val_arg);
12206640Scth 		if ((sr == 1) &&
12216640Scth 		    (nvpair_value_boolean_value(nvp, &val) == 0) &&
12226640Scth 		    (val == val_arg))
12236640Scth 			return (1);
12246640Scth 		break;
12256640Scth 	}
12266640Scth 	case DATA_TYPE_BOOLEAN_ARRAY: {
12276640Scth 		boolean_t *val_array, val_arg;
12286640Scth 
12296640Scth 		/* check indexed value of array for match */
12306640Scth 		sr = sscanf(value, "%"SCNi32, &val_arg);
12316640Scth 		if ((sr == 1) &&
12326640Scth 		    (nvpair_value_boolean_array(nvp,
12336640Scth 		    &val_array, &a_len) == 0) &&
12346640Scth 		    (ai < a_len) &&
12356640Scth 		    (val_array[ai] == val_arg))
12366640Scth 			return (1);
12376640Scth 		break;
12386640Scth 	}
12396640Scth 	case DATA_TYPE_HRTIME:
12406640Scth 	case DATA_TYPE_NVLIST:
12416640Scth 	case DATA_TYPE_NVLIST_ARRAY:
12426640Scth 	case DATA_TYPE_BOOLEAN:
12437243Srobj 	case DATA_TYPE_DOUBLE:
12446640Scth 	case DATA_TYPE_UNKNOWN:
12456640Scth 	default:
12466640Scth 		/*
12476640Scth 		 * unknown/unsupported data type
12486640Scth 		 */
12496640Scth 		return (-1);		/* error fail match */
12506640Scth 	}
12516640Scth 
12526640Scth 	/*
12536640Scth 	 * check to see if sscanf failed conversion, return approximate
12546640Scth 	 * pointer to problem
12556640Scth 	 */
12566640Scth 	if (sr != 1) {
12576640Scth 		if (ep)
12586640Scth 			*ep = value;
12596640Scth 		return (-1);		/* error fail match  - syntax */
12606640Scth 	}
12616640Scth 
12626640Scth 	return (0);			/* fail match */
12636640Scth }
12646640Scth 
12656640Scth int
nvpair_value_match(nvpair_t * nvp,int ai,char * value,char ** ep)12666640Scth nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep)
12676640Scth {
12686640Scth 	return (nvpair_value_match_regex(nvp, ai, value, NULL, ep));
12696640Scth }
1270