libnvpair.c revision 1.4 1 1.1 haad /*
2 1.1 haad * CDDL HEADER START
3 1.1 haad *
4 1.1 haad * The contents of this file are subject to the terms of the
5 1.1 haad * Common Development and Distribution License (the "License").
6 1.1 haad * You may not use this file except in compliance with the License.
7 1.1 haad *
8 1.1 haad * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 1.1 haad * or http://www.opensolaris.org/os/licensing.
10 1.1 haad * See the License for the specific language governing permissions
11 1.1 haad * and limitations under the License.
12 1.1 haad *
13 1.1 haad * When distributing Covered Code, include this CDDL HEADER in each
14 1.1 haad * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 1.1 haad * If applicable, add the following below this CDDL HEADER, with the
16 1.1 haad * fields enclosed by brackets "[]" replaced with your own identifying
17 1.1 haad * information: Portions Copyright [yyyy] [name of copyright owner]
18 1.1 haad *
19 1.1 haad * CDDL HEADER END
20 1.1 haad */
21 1.1 haad /*
22 1.4 chs * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
23 1.4 chs * Copyright (c) 2012 by Delphix. All rights reserved.
24 1.1 haad */
25 1.1 haad
26 1.4 chs #include <solaris.h>
27 1.4 chs #include <inttypes.h>
28 1.1 haad #include <unistd.h>
29 1.4 chs #include <string.h>
30 1.2 dsl #include <libintl.h>
31 1.4 chs #include <stdarg.h>
32 1.4 chs #include <note.h>
33 1.1 haad #include "libnvpair.h"
34 1.1 haad
35 1.1 haad /*
36 1.1 haad * libnvpair - A tools library for manipulating <name, value> pairs.
37 1.1 haad *
38 1.1 haad * This library provides routines packing an unpacking nv pairs
39 1.1 haad * for transporting data across process boundaries, transporting
40 1.1 haad * between kernel and userland, and possibly saving onto disk files.
41 1.1 haad */
42 1.1 haad
43 1.4 chs /*
44 1.4 chs * Print control structure.
45 1.4 chs */
46 1.4 chs
47 1.4 chs #define DEFINEOP(opname, vtype) \
48 1.4 chs struct { \
49 1.4 chs int (*op)(struct nvlist_prtctl *, void *, nvlist_t *, \
50 1.4 chs const char *, vtype); \
51 1.4 chs void *arg; \
52 1.4 chs } opname
53 1.4 chs
54 1.4 chs #define DEFINEARROP(opname, vtype) \
55 1.4 chs struct { \
56 1.4 chs int (*op)(struct nvlist_prtctl *, void *, nvlist_t *, \
57 1.4 chs const char *, vtype, uint_t); \
58 1.4 chs void *arg; \
59 1.4 chs } opname
60 1.4 chs
61 1.4 chs struct nvlist_printops {
62 1.4 chs DEFINEOP(print_boolean, int);
63 1.4 chs DEFINEOP(print_boolean_value, boolean_t);
64 1.4 chs DEFINEOP(print_byte, uchar_t);
65 1.4 chs DEFINEOP(print_int8, int8_t);
66 1.4 chs DEFINEOP(print_uint8, uint8_t);
67 1.4 chs DEFINEOP(print_int16, int16_t);
68 1.4 chs DEFINEOP(print_uint16, uint16_t);
69 1.4 chs DEFINEOP(print_int32, int32_t);
70 1.4 chs DEFINEOP(print_uint32, uint32_t);
71 1.4 chs DEFINEOP(print_int64, int64_t);
72 1.4 chs DEFINEOP(print_uint64, uint64_t);
73 1.4 chs DEFINEOP(print_double, double);
74 1.4 chs DEFINEOP(print_string, char *);
75 1.4 chs DEFINEOP(print_hrtime, hrtime_t);
76 1.4 chs DEFINEOP(print_nvlist, nvlist_t *);
77 1.4 chs DEFINEARROP(print_boolean_array, boolean_t *);
78 1.4 chs DEFINEARROP(print_byte_array, uchar_t *);
79 1.4 chs DEFINEARROP(print_int8_array, int8_t *);
80 1.4 chs DEFINEARROP(print_uint8_array, uint8_t *);
81 1.4 chs DEFINEARROP(print_int16_array, int16_t *);
82 1.4 chs DEFINEARROP(print_uint16_array, uint16_t *);
83 1.4 chs DEFINEARROP(print_int32_array, int32_t *);
84 1.4 chs DEFINEARROP(print_uint32_array, uint32_t *);
85 1.4 chs DEFINEARROP(print_int64_array, int64_t *);
86 1.4 chs DEFINEARROP(print_uint64_array, uint64_t *);
87 1.4 chs DEFINEARROP(print_string_array, char **);
88 1.4 chs DEFINEARROP(print_nvlist_array, nvlist_t **);
89 1.4 chs };
90 1.4 chs
91 1.4 chs struct nvlist_prtctl {
92 1.4 chs FILE *nvprt_fp; /* output destination */
93 1.4 chs enum nvlist_indent_mode nvprt_indent_mode; /* see above */
94 1.4 chs int nvprt_indent; /* absolute indent, or tab depth */
95 1.4 chs int nvprt_indentinc; /* indent or tab increment */
96 1.4 chs const char *nvprt_nmfmt; /* member name format, max one %s */
97 1.4 chs const char *nvprt_eomfmt; /* after member format, e.g. "\n" */
98 1.4 chs const char *nvprt_btwnarrfmt; /* between array members */
99 1.4 chs int nvprt_btwnarrfmt_nl; /* nvprt_eoamfmt includes newline? */
100 1.4 chs struct nvlist_printops *nvprt_dfltops;
101 1.4 chs struct nvlist_printops *nvprt_custops;
102 1.4 chs };
103 1.4 chs
104 1.4 chs #define DFLTPRTOP(pctl, type) \
105 1.4 chs ((pctl)->nvprt_dfltops->print_##type.op)
106 1.4 chs
107 1.4 chs #define DFLTPRTOPARG(pctl, type) \
108 1.4 chs ((pctl)->nvprt_dfltops->print_##type.arg)
109 1.4 chs
110 1.4 chs #define CUSTPRTOP(pctl, type) \
111 1.4 chs ((pctl)->nvprt_custops->print_##type.op)
112 1.4 chs
113 1.4 chs #define CUSTPRTOPARG(pctl, type) \
114 1.4 chs ((pctl)->nvprt_custops->print_##type.arg)
115 1.4 chs
116 1.4 chs #define RENDER(pctl, type, nvl, name, val) \
117 1.4 chs { \
118 1.4 chs int done = 0; \
119 1.4 chs if ((pctl)->nvprt_custops && CUSTPRTOP(pctl, type)) { \
120 1.4 chs done = CUSTPRTOP(pctl, type)(pctl, \
121 1.4 chs CUSTPRTOPARG(pctl, type), nvl, name, val); \
122 1.4 chs } \
123 1.4 chs if (!done) { \
124 1.4 chs (void) DFLTPRTOP(pctl, type)(pctl, \
125 1.4 chs DFLTPRTOPARG(pctl, type), nvl, name, val); \
126 1.4 chs } \
127 1.4 chs (void) fprintf(pctl->nvprt_fp, pctl->nvprt_eomfmt); \
128 1.4 chs }
129 1.4 chs
130 1.4 chs #define ARENDER(pctl, type, nvl, name, arrp, count) \
131 1.4 chs { \
132 1.4 chs int done = 0; \
133 1.4 chs if ((pctl)->nvprt_custops && CUSTPRTOP(pctl, type)) { \
134 1.4 chs done = CUSTPRTOP(pctl, type)(pctl, \
135 1.4 chs CUSTPRTOPARG(pctl, type), nvl, name, arrp, count); \
136 1.4 chs } \
137 1.4 chs if (!done) { \
138 1.4 chs (void) DFLTPRTOP(pctl, type)(pctl, \
139 1.4 chs DFLTPRTOPARG(pctl, type), nvl, name, arrp, count); \
140 1.4 chs } \
141 1.4 chs (void) fprintf(pctl->nvprt_fp, pctl->nvprt_eomfmt); \
142 1.4 chs }
143 1.4 chs
144 1.4 chs static void nvlist_print_with_indent(nvlist_t *, nvlist_prtctl_t);
145 1.4 chs
146 1.4 chs /*
147 1.4 chs * ======================================================================
148 1.4 chs * | |
149 1.4 chs * | Indentation |
150 1.4 chs * | |
151 1.4 chs * ======================================================================
152 1.4 chs */
153 1.4 chs
154 1.4 chs static void
155 1.4 chs indent(nvlist_prtctl_t pctl, int onemore)
156 1.4 chs {
157 1.4 chs int depth;
158 1.4 chs
159 1.4 chs switch (pctl->nvprt_indent_mode) {
160 1.4 chs case NVLIST_INDENT_ABS:
161 1.4 chs (void) fprintf(pctl->nvprt_fp, "%*s",
162 1.4 chs pctl->nvprt_indent + onemore * pctl->nvprt_indentinc, "");
163 1.4 chs break;
164 1.4 chs
165 1.4 chs case NVLIST_INDENT_TABBED:
166 1.4 chs depth = pctl->nvprt_indent + onemore;
167 1.4 chs while (depth-- > 0)
168 1.4 chs (void) fprintf(pctl->nvprt_fp, "\t");
169 1.4 chs }
170 1.4 chs }
171 1.4 chs
172 1.4 chs /*
173 1.4 chs * ======================================================================
174 1.4 chs * | |
175 1.4 chs * | Default nvlist member rendering functions. |
176 1.4 chs * | |
177 1.4 chs * ======================================================================
178 1.4 chs */
179 1.4 chs
180 1.4 chs /*
181 1.4 chs * Generate functions to print single-valued nvlist members.
182 1.4 chs *
183 1.4 chs * type_and_variant - suffix to form function name
184 1.4 chs * vtype - C type for the member value
185 1.4 chs * ptype - C type to cast value to for printing
186 1.4 chs * vfmt - format string for pair value, e.g "%d" or "0x%llx"
187 1.4 chs */
188 1.4 chs
189 1.4 chs #define NVLIST_PRTFUNC(type_and_variant, vtype, ptype, vfmt) \
190 1.4 chs static int \
191 1.4 chs nvprint_##type_and_variant(nvlist_prtctl_t pctl, void *private, \
192 1.4 chs nvlist_t *nvl, const char *name, vtype value) \
193 1.4 chs { \
194 1.4 chs FILE *fp = pctl->nvprt_fp; \
195 1.4 chs NOTE(ARGUNUSED(private)) \
196 1.4 chs NOTE(ARGUNUSED(nvl)) \
197 1.4 chs indent(pctl, 1); \
198 1.4 chs (void) fprintf(fp, pctl->nvprt_nmfmt, name); \
199 1.4 chs (void) fprintf(fp, vfmt, (ptype)value); \
200 1.4 chs return (1); \
201 1.4 chs }
202 1.4 chs
203 1.4 chs NVLIST_PRTFUNC(boolean, int, int, "%d")
204 1.4 chs NVLIST_PRTFUNC(boolean_value, boolean_t, int, "%d")
205 1.4 chs NVLIST_PRTFUNC(byte, uchar_t, uchar_t, "0x%2.2x")
206 1.4 chs NVLIST_PRTFUNC(int8, int8_t, int, "%d")
207 1.4 chs NVLIST_PRTFUNC(uint8, uint8_t, uint8_t, "0x%x")
208 1.4 chs NVLIST_PRTFUNC(int16, int16_t, int16_t, "%d")
209 1.4 chs NVLIST_PRTFUNC(uint16, uint16_t, uint16_t, "0x%x")
210 1.4 chs NVLIST_PRTFUNC(int32, int32_t, int32_t, "%d")
211 1.4 chs NVLIST_PRTFUNC(uint32, uint32_t, uint32_t, "0x%x")
212 1.4 chs NVLIST_PRTFUNC(int64, int64_t, longlong_t, "%lld")
213 1.4 chs NVLIST_PRTFUNC(uint64, uint64_t, u_longlong_t, "0x%llx")
214 1.4 chs NVLIST_PRTFUNC(double, double, double, "0x%f")
215 1.4 chs NVLIST_PRTFUNC(string, char *, char *, "%s")
216 1.4 chs NVLIST_PRTFUNC(hrtime, hrtime_t, hrtime_t, "0x%llx")
217 1.4 chs
218 1.4 chs /*
219 1.4 chs * Generate functions to print array-valued nvlist members.
220 1.4 chs */
221 1.4 chs
222 1.4 chs #define NVLIST_ARRPRTFUNC(type_and_variant, vtype, ptype, vfmt) \
223 1.4 chs static int \
224 1.4 chs nvaprint_##type_and_variant(nvlist_prtctl_t pctl, void *private, \
225 1.4 chs nvlist_t *nvl, const char *name, vtype *valuep, uint_t count) \
226 1.4 chs { \
227 1.4 chs FILE *fp = pctl->nvprt_fp; \
228 1.4 chs uint_t i; \
229 1.4 chs NOTE(ARGUNUSED(private)) \
230 1.4 chs NOTE(ARGUNUSED(nvl)) \
231 1.4 chs for (i = 0; i < count; i++) { \
232 1.4 chs if (i == 0 || pctl->nvprt_btwnarrfmt_nl) { \
233 1.4 chs indent(pctl, 1); \
234 1.4 chs (void) fprintf(fp, pctl->nvprt_nmfmt, name); \
235 1.4 chs if (pctl->nvprt_btwnarrfmt_nl) \
236 1.4 chs (void) fprintf(fp, "[%d]: ", i); \
237 1.4 chs } \
238 1.4 chs if (i != 0) \
239 1.4 chs (void) fprintf(fp, pctl->nvprt_btwnarrfmt); \
240 1.4 chs (void) fprintf(fp, vfmt, (ptype)valuep[i]); \
241 1.4 chs } \
242 1.4 chs return (1); \
243 1.4 chs }
244 1.4 chs
245 1.4 chs NVLIST_ARRPRTFUNC(boolean_array, boolean_t, boolean_t, "%d")
246 1.4 chs NVLIST_ARRPRTFUNC(byte_array, uchar_t, uchar_t, "0x%2.2x")
247 1.4 chs NVLIST_ARRPRTFUNC(int8_array, int8_t, int8_t, "%d")
248 1.4 chs NVLIST_ARRPRTFUNC(uint8_array, uint8_t, uint8_t, "0x%x")
249 1.4 chs NVLIST_ARRPRTFUNC(int16_array, int16_t, int16_t, "%d")
250 1.4 chs NVLIST_ARRPRTFUNC(uint16_array, uint16_t, uint16_t, "0x%x")
251 1.4 chs NVLIST_ARRPRTFUNC(int32_array, int32_t, int32_t, "%d")
252 1.4 chs NVLIST_ARRPRTFUNC(uint32_array, uint32_t, uint32_t, "0x%x")
253 1.4 chs NVLIST_ARRPRTFUNC(int64_array, int64_t, longlong_t, "%lld")
254 1.4 chs NVLIST_ARRPRTFUNC(uint64_array, uint64_t, u_longlong_t, "0x%llx")
255 1.4 chs NVLIST_ARRPRTFUNC(string_array, char *, char *, "%s")
256 1.4 chs
257 1.4 chs /*ARGSUSED*/
258 1.4 chs static int
259 1.4 chs nvprint_nvlist(nvlist_prtctl_t pctl, void *private,
260 1.4 chs nvlist_t *nvl, const char *name, nvlist_t *value)
261 1.4 chs {
262 1.4 chs FILE *fp = pctl->nvprt_fp;
263 1.4 chs
264 1.4 chs indent(pctl, 1);
265 1.4 chs (void) fprintf(fp, "%s = (embedded nvlist)\n", name);
266 1.4 chs
267 1.4 chs pctl->nvprt_indent += pctl->nvprt_indentinc;
268 1.4 chs nvlist_print_with_indent(value, pctl);
269 1.4 chs pctl->nvprt_indent -= pctl->nvprt_indentinc;
270 1.4 chs
271 1.4 chs indent(pctl, 1);
272 1.4 chs (void) fprintf(fp, "(end %s)\n", name);
273 1.4 chs
274 1.4 chs return (1);
275 1.4 chs }
276 1.4 chs
277 1.4 chs /*ARGSUSED*/
278 1.4 chs static int
279 1.4 chs nvaprint_nvlist_array(nvlist_prtctl_t pctl, void *private,
280 1.4 chs nvlist_t *nvl, const char *name, nvlist_t **valuep, uint_t count)
281 1.4 chs {
282 1.4 chs FILE *fp = pctl->nvprt_fp;
283 1.4 chs uint_t i;
284 1.4 chs
285 1.4 chs indent(pctl, 1);
286 1.4 chs (void) fprintf(fp, "%s = (array of embedded nvlists)\n", name);
287 1.4 chs
288 1.4 chs for (i = 0; i < count; i++) {
289 1.4 chs indent(pctl, 1);
290 1.4 chs (void) fprintf(fp, "(start %s[%d])\n", name, i);
291 1.4 chs
292 1.4 chs pctl->nvprt_indent += pctl->nvprt_indentinc;
293 1.4 chs nvlist_print_with_indent(valuep[i], pctl);
294 1.4 chs pctl->nvprt_indent -= pctl->nvprt_indentinc;
295 1.4 chs
296 1.4 chs indent(pctl, 1);
297 1.4 chs (void) fprintf(fp, "(end %s[%d])\n", name, i);
298 1.4 chs }
299 1.4 chs
300 1.4 chs return (1);
301 1.4 chs }
302 1.4 chs
303 1.4 chs /*
304 1.4 chs * ======================================================================
305 1.4 chs * | |
306 1.4 chs * | Interfaces that allow control over formatting. |
307 1.4 chs * | |
308 1.4 chs * ======================================================================
309 1.4 chs */
310 1.4 chs
311 1.4 chs void
312 1.4 chs nvlist_prtctl_setdest(nvlist_prtctl_t pctl, FILE *fp)
313 1.4 chs {
314 1.4 chs pctl->nvprt_fp = fp;
315 1.4 chs }
316 1.4 chs
317 1.4 chs FILE *
318 1.4 chs nvlist_prtctl_getdest(nvlist_prtctl_t pctl)
319 1.4 chs {
320 1.4 chs return (pctl->nvprt_fp);
321 1.4 chs }
322 1.4 chs
323 1.4 chs
324 1.4 chs void
325 1.4 chs nvlist_prtctl_setindent(nvlist_prtctl_t pctl, enum nvlist_indent_mode mode,
326 1.4 chs int start, int inc)
327 1.4 chs {
328 1.4 chs if (mode < NVLIST_INDENT_ABS || mode > NVLIST_INDENT_TABBED)
329 1.4 chs mode = NVLIST_INDENT_TABBED;
330 1.4 chs
331 1.4 chs if (start < 0)
332 1.4 chs start = 0;
333 1.4 chs
334 1.4 chs if (inc < 0)
335 1.4 chs inc = 1;
336 1.4 chs
337 1.4 chs pctl->nvprt_indent_mode = mode;
338 1.4 chs pctl->nvprt_indent = start;
339 1.4 chs pctl->nvprt_indentinc = inc;
340 1.4 chs }
341 1.4 chs
342 1.4 chs void
343 1.4 chs nvlist_prtctl_doindent(nvlist_prtctl_t pctl, int onemore)
344 1.4 chs {
345 1.4 chs indent(pctl, onemore);
346 1.4 chs }
347 1.4 chs
348 1.4 chs
349 1.4 chs void
350 1.4 chs nvlist_prtctl_setfmt(nvlist_prtctl_t pctl, enum nvlist_prtctl_fmt which,
351 1.4 chs const char *fmt)
352 1.4 chs {
353 1.4 chs switch (which) {
354 1.4 chs case NVLIST_FMT_MEMBER_NAME:
355 1.4 chs if (fmt == NULL)
356 1.4 chs fmt = "%s = ";
357 1.4 chs pctl->nvprt_nmfmt = fmt;
358 1.4 chs break;
359 1.4 chs
360 1.4 chs case NVLIST_FMT_MEMBER_POSTAMBLE:
361 1.4 chs if (fmt == NULL)
362 1.4 chs fmt = "\n";
363 1.4 chs pctl->nvprt_eomfmt = fmt;
364 1.4 chs break;
365 1.4 chs
366 1.4 chs case NVLIST_FMT_BTWN_ARRAY:
367 1.4 chs if (fmt == NULL) {
368 1.4 chs pctl->nvprt_btwnarrfmt = " ";
369 1.4 chs pctl->nvprt_btwnarrfmt_nl = 0;
370 1.4 chs } else {
371 1.4 chs pctl->nvprt_btwnarrfmt = fmt;
372 1.4 chs pctl->nvprt_btwnarrfmt_nl = (strstr(fmt, "\n") != NULL);
373 1.4 chs }
374 1.4 chs break;
375 1.4 chs
376 1.4 chs default:
377 1.4 chs break;
378 1.4 chs }
379 1.4 chs }
380 1.4 chs
381 1.4 chs
382 1.4 chs void
383 1.4 chs nvlist_prtctl_dofmt(nvlist_prtctl_t pctl, enum nvlist_prtctl_fmt which, ...)
384 1.4 chs {
385 1.4 chs FILE *fp = pctl->nvprt_fp;
386 1.4 chs va_list ap;
387 1.4 chs char *name;
388 1.4 chs
389 1.4 chs va_start(ap, which);
390 1.4 chs
391 1.4 chs switch (which) {
392 1.4 chs case NVLIST_FMT_MEMBER_NAME:
393 1.4 chs name = va_arg(ap, char *);
394 1.4 chs (void) fprintf(fp, pctl->nvprt_nmfmt, name);
395 1.4 chs break;
396 1.4 chs
397 1.4 chs case NVLIST_FMT_MEMBER_POSTAMBLE:
398 1.4 chs (void) fprintf(fp, pctl->nvprt_eomfmt);
399 1.4 chs break;
400 1.4 chs
401 1.4 chs case NVLIST_FMT_BTWN_ARRAY:
402 1.4 chs (void) fprintf(fp, pctl->nvprt_btwnarrfmt); \
403 1.4 chs break;
404 1.4 chs
405 1.4 chs default:
406 1.4 chs break;
407 1.4 chs }
408 1.4 chs
409 1.4 chs va_end(ap);
410 1.4 chs }
411 1.4 chs
412 1.4 chs /*
413 1.4 chs * ======================================================================
414 1.4 chs * | |
415 1.4 chs * | Interfaces to allow appointment of replacement rendering functions.|
416 1.4 chs * | |
417 1.4 chs * ======================================================================
418 1.4 chs */
419 1.4 chs
420 1.4 chs #define NVLIST_PRINTCTL_REPLACE(type, vtype) \
421 1.4 chs void \
422 1.4 chs nvlist_prtctlop_##type(nvlist_prtctl_t pctl, \
423 1.4 chs int (*func)(nvlist_prtctl_t, void *, nvlist_t *, const char *, vtype), \
424 1.4 chs void *private) \
425 1.4 chs { \
426 1.4 chs CUSTPRTOP(pctl, type) = func; \
427 1.4 chs CUSTPRTOPARG(pctl, type) = private; \
428 1.4 chs }
429 1.4 chs
430 1.4 chs NVLIST_PRINTCTL_REPLACE(boolean, int)
431 1.4 chs NVLIST_PRINTCTL_REPLACE(boolean_value, boolean_t)
432 1.4 chs NVLIST_PRINTCTL_REPLACE(byte, uchar_t)
433 1.4 chs NVLIST_PRINTCTL_REPLACE(int8, int8_t)
434 1.4 chs NVLIST_PRINTCTL_REPLACE(uint8, uint8_t)
435 1.4 chs NVLIST_PRINTCTL_REPLACE(int16, int16_t)
436 1.4 chs NVLIST_PRINTCTL_REPLACE(uint16, uint16_t)
437 1.4 chs NVLIST_PRINTCTL_REPLACE(int32, int32_t)
438 1.4 chs NVLIST_PRINTCTL_REPLACE(uint32, uint32_t)
439 1.4 chs NVLIST_PRINTCTL_REPLACE(int64, int64_t)
440 1.4 chs NVLIST_PRINTCTL_REPLACE(uint64, uint64_t)
441 1.4 chs NVLIST_PRINTCTL_REPLACE(double, double)
442 1.4 chs NVLIST_PRINTCTL_REPLACE(string, char *)
443 1.4 chs NVLIST_PRINTCTL_REPLACE(hrtime, hrtime_t)
444 1.4 chs NVLIST_PRINTCTL_REPLACE(nvlist, nvlist_t *)
445 1.4 chs
446 1.4 chs #define NVLIST_PRINTCTL_AREPLACE(type, vtype) \
447 1.4 chs void \
448 1.4 chs nvlist_prtctlop_##type(nvlist_prtctl_t pctl, \
449 1.4 chs int (*func)(nvlist_prtctl_t, void *, nvlist_t *, const char *, vtype, \
450 1.4 chs uint_t), void *private) \
451 1.4 chs { \
452 1.4 chs CUSTPRTOP(pctl, type) = func; \
453 1.4 chs CUSTPRTOPARG(pctl, type) = private; \
454 1.4 chs }
455 1.4 chs
456 1.4 chs NVLIST_PRINTCTL_AREPLACE(boolean_array, boolean_t *)
457 1.4 chs NVLIST_PRINTCTL_AREPLACE(byte_array, uchar_t *)
458 1.4 chs NVLIST_PRINTCTL_AREPLACE(int8_array, int8_t *)
459 1.4 chs NVLIST_PRINTCTL_AREPLACE(uint8_array, uint8_t *)
460 1.4 chs NVLIST_PRINTCTL_AREPLACE(int16_array, int16_t *)
461 1.4 chs NVLIST_PRINTCTL_AREPLACE(uint16_array, uint16_t *)
462 1.4 chs NVLIST_PRINTCTL_AREPLACE(int32_array, int32_t *)
463 1.4 chs NVLIST_PRINTCTL_AREPLACE(uint32_array, uint32_t *)
464 1.4 chs NVLIST_PRINTCTL_AREPLACE(int64_array, int64_t *)
465 1.4 chs NVLIST_PRINTCTL_AREPLACE(uint64_array, uint64_t *)
466 1.4 chs NVLIST_PRINTCTL_AREPLACE(string_array, char **)
467 1.4 chs NVLIST_PRINTCTL_AREPLACE(nvlist_array, nvlist_t **)
468 1.4 chs
469 1.4 chs /*
470 1.4 chs * ======================================================================
471 1.4 chs * | |
472 1.4 chs * | Interfaces to manage nvlist_prtctl_t cookies. |
473 1.4 chs * | |
474 1.4 chs * ======================================================================
475 1.4 chs */
476 1.4 chs
477 1.4 chs
478 1.4 chs static const struct nvlist_printops defprtops = {
479 1.4 chs { nvprint_boolean, NULL },
480 1.4 chs { nvprint_boolean_value, NULL },
481 1.4 chs { nvprint_byte, NULL },
482 1.4 chs { nvprint_int8, NULL },
483 1.4 chs { nvprint_uint8, NULL },
484 1.4 chs { nvprint_int16, NULL },
485 1.4 chs { nvprint_uint16, NULL },
486 1.4 chs { nvprint_int32, NULL },
487 1.4 chs { nvprint_uint32, NULL },
488 1.4 chs { nvprint_int64, NULL },
489 1.4 chs { nvprint_uint64, NULL },
490 1.4 chs { nvprint_double, NULL },
491 1.4 chs { nvprint_string, NULL },
492 1.4 chs { nvprint_hrtime, NULL },
493 1.4 chs { nvprint_nvlist, NULL },
494 1.4 chs { nvaprint_boolean_array, NULL },
495 1.4 chs { nvaprint_byte_array, NULL },
496 1.4 chs { nvaprint_int8_array, NULL },
497 1.4 chs { nvaprint_uint8_array, NULL },
498 1.4 chs { nvaprint_int16_array, NULL },
499 1.4 chs { nvaprint_uint16_array, NULL },
500 1.4 chs { nvaprint_int32_array, NULL },
501 1.4 chs { nvaprint_uint32_array, NULL },
502 1.4 chs { nvaprint_int64_array, NULL },
503 1.4 chs { nvaprint_uint64_array, NULL },
504 1.4 chs { nvaprint_string_array, NULL },
505 1.4 chs { nvaprint_nvlist_array, NULL },
506 1.4 chs };
507 1.4 chs
508 1.1 haad static void
509 1.4 chs prtctl_defaults(FILE *fp, struct nvlist_prtctl *pctl,
510 1.4 chs struct nvlist_printops *ops)
511 1.1 haad {
512 1.4 chs pctl->nvprt_fp = fp;
513 1.4 chs pctl->nvprt_indent_mode = NVLIST_INDENT_TABBED;
514 1.4 chs pctl->nvprt_indent = 0;
515 1.4 chs pctl->nvprt_indentinc = 1;
516 1.4 chs pctl->nvprt_nmfmt = "%s = ";
517 1.4 chs pctl->nvprt_eomfmt = "\n";
518 1.4 chs pctl->nvprt_btwnarrfmt = " ";
519 1.4 chs pctl->nvprt_btwnarrfmt_nl = 0;
520 1.4 chs
521 1.4 chs pctl->nvprt_dfltops = (struct nvlist_printops *)&defprtops;
522 1.4 chs pctl->nvprt_custops = ops;
523 1.4 chs }
524 1.4 chs
525 1.4 chs nvlist_prtctl_t
526 1.4 chs nvlist_prtctl_alloc(void)
527 1.4 chs {
528 1.4 chs struct nvlist_prtctl *pctl;
529 1.4 chs struct nvlist_printops *ops;
530 1.4 chs
531 1.4 chs if ((pctl = malloc(sizeof (*pctl))) == NULL)
532 1.4 chs return (NULL);
533 1.4 chs
534 1.4 chs if ((ops = calloc(1, sizeof (*ops))) == NULL) {
535 1.4 chs free(pctl);
536 1.4 chs return (NULL);
537 1.4 chs }
538 1.4 chs
539 1.4 chs prtctl_defaults(stdout, pctl, ops);
540 1.4 chs
541 1.4 chs return (pctl);
542 1.4 chs }
543 1.4 chs
544 1.4 chs void
545 1.4 chs nvlist_prtctl_free(nvlist_prtctl_t pctl)
546 1.4 chs {
547 1.4 chs if (pctl != NULL) {
548 1.4 chs free(pctl->nvprt_custops);
549 1.4 chs free(pctl);
550 1.4 chs }
551 1.1 haad }
552 1.1 haad
553 1.1 haad /*
554 1.4 chs * ======================================================================
555 1.4 chs * | |
556 1.4 chs * | Top-level print request interfaces. |
557 1.4 chs * | |
558 1.4 chs * ======================================================================
559 1.4 chs */
560 1.4 chs
561 1.4 chs /*
562 1.1 haad * nvlist_print - Prints elements in an event buffer
563 1.1 haad */
564 1.4 chs static void
565 1.4 chs nvlist_print_with_indent(nvlist_t *nvl, nvlist_prtctl_t pctl)
566 1.1 haad {
567 1.4 chs FILE *fp = pctl->nvprt_fp;
568 1.1 haad char *name;
569 1.1 haad uint_t nelem;
570 1.1 haad nvpair_t *nvp;
571 1.1 haad
572 1.1 haad if (nvl == NULL)
573 1.1 haad return;
574 1.1 haad
575 1.4 chs indent(pctl, 0);
576 1.1 haad (void) fprintf(fp, "nvlist version: %d\n", NVL_VERSION(nvl));
577 1.1 haad
578 1.1 haad nvp = nvlist_next_nvpair(nvl, NULL);
579 1.1 haad
580 1.1 haad while (nvp) {
581 1.1 haad data_type_t type = nvpair_type(nvp);
582 1.1 haad
583 1.1 haad name = nvpair_name(nvp);
584 1.1 haad nelem = 0;
585 1.4 chs
586 1.1 haad switch (type) {
587 1.1 haad case DATA_TYPE_BOOLEAN: {
588 1.4 chs RENDER(pctl, boolean, nvl, name, 1);
589 1.1 haad break;
590 1.1 haad }
591 1.1 haad case DATA_TYPE_BOOLEAN_VALUE: {
592 1.1 haad boolean_t val;
593 1.1 haad (void) nvpair_value_boolean_value(nvp, &val);
594 1.4 chs RENDER(pctl, boolean_value, nvl, name, val);
595 1.1 haad break;
596 1.1 haad }
597 1.1 haad case DATA_TYPE_BYTE: {
598 1.1 haad uchar_t val;
599 1.1 haad (void) nvpair_value_byte(nvp, &val);
600 1.4 chs RENDER(pctl, byte, nvl, name, val);
601 1.1 haad break;
602 1.1 haad }
603 1.1 haad case DATA_TYPE_INT8: {
604 1.1 haad int8_t val;
605 1.1 haad (void) nvpair_value_int8(nvp, &val);
606 1.4 chs RENDER(pctl, int8, nvl, name, val);
607 1.1 haad break;
608 1.1 haad }
609 1.1 haad case DATA_TYPE_UINT8: {
610 1.1 haad uint8_t val;
611 1.1 haad (void) nvpair_value_uint8(nvp, &val);
612 1.4 chs RENDER(pctl, uint8, nvl, name, val);
613 1.1 haad break;
614 1.1 haad }
615 1.1 haad case DATA_TYPE_INT16: {
616 1.1 haad int16_t val;
617 1.1 haad (void) nvpair_value_int16(nvp, &val);
618 1.4 chs RENDER(pctl, int16, nvl, name, val);
619 1.1 haad break;
620 1.1 haad }
621 1.1 haad case DATA_TYPE_UINT16: {
622 1.1 haad uint16_t val;
623 1.1 haad (void) nvpair_value_uint16(nvp, &val);
624 1.4 chs RENDER(pctl, uint16, nvl, name, val);
625 1.1 haad break;
626 1.1 haad }
627 1.1 haad case DATA_TYPE_INT32: {
628 1.1 haad int32_t val;
629 1.1 haad (void) nvpair_value_int32(nvp, &val);
630 1.4 chs RENDER(pctl, int32, nvl, name, val);
631 1.1 haad break;
632 1.1 haad }
633 1.1 haad case DATA_TYPE_UINT32: {
634 1.1 haad uint32_t val;
635 1.1 haad (void) nvpair_value_uint32(nvp, &val);
636 1.4 chs RENDER(pctl, uint32, nvl, name, val);
637 1.1 haad break;
638 1.1 haad }
639 1.1 haad case DATA_TYPE_INT64: {
640 1.1 haad int64_t val;
641 1.1 haad (void) nvpair_value_int64(nvp, &val);
642 1.4 chs RENDER(pctl, int64, nvl, name, val);
643 1.1 haad break;
644 1.1 haad }
645 1.1 haad case DATA_TYPE_UINT64: {
646 1.1 haad uint64_t val;
647 1.1 haad (void) nvpair_value_uint64(nvp, &val);
648 1.4 chs RENDER(pctl, uint64, nvl, name, val);
649 1.1 haad break;
650 1.1 haad }
651 1.1 haad case DATA_TYPE_DOUBLE: {
652 1.1 haad double val;
653 1.1 haad (void) nvpair_value_double(nvp, &val);
654 1.4 chs RENDER(pctl, double, nvl, name, val);
655 1.1 haad break;
656 1.1 haad }
657 1.1 haad case DATA_TYPE_STRING: {
658 1.1 haad char *val;
659 1.1 haad (void) nvpair_value_string(nvp, &val);
660 1.4 chs RENDER(pctl, string, nvl, name, val);
661 1.1 haad break;
662 1.1 haad }
663 1.1 haad case DATA_TYPE_BOOLEAN_ARRAY: {
664 1.1 haad boolean_t *val;
665 1.1 haad (void) nvpair_value_boolean_array(nvp, &val, &nelem);
666 1.4 chs ARENDER(pctl, boolean_array, nvl, name, val, nelem);
667 1.1 haad break;
668 1.1 haad }
669 1.1 haad case DATA_TYPE_BYTE_ARRAY: {
670 1.1 haad uchar_t *val;
671 1.1 haad (void) nvpair_value_byte_array(nvp, &val, &nelem);
672 1.4 chs ARENDER(pctl, byte_array, nvl, name, val, nelem);
673 1.1 haad break;
674 1.1 haad }
675 1.1 haad case DATA_TYPE_INT8_ARRAY: {
676 1.1 haad int8_t *val;
677 1.1 haad (void) nvpair_value_int8_array(nvp, &val, &nelem);
678 1.4 chs ARENDER(pctl, int8_array, nvl, name, val, nelem);
679 1.1 haad break;
680 1.1 haad }
681 1.1 haad case DATA_TYPE_UINT8_ARRAY: {
682 1.1 haad uint8_t *val;
683 1.1 haad (void) nvpair_value_uint8_array(nvp, &val, &nelem);
684 1.4 chs ARENDER(pctl, uint8_array, nvl, name, val, nelem);
685 1.1 haad break;
686 1.1 haad }
687 1.1 haad case DATA_TYPE_INT16_ARRAY: {
688 1.1 haad int16_t *val;
689 1.1 haad (void) nvpair_value_int16_array(nvp, &val, &nelem);
690 1.4 chs ARENDER(pctl, int16_array, nvl, name, val, nelem);
691 1.1 haad break;
692 1.1 haad }
693 1.1 haad case DATA_TYPE_UINT16_ARRAY: {
694 1.1 haad uint16_t *val;
695 1.1 haad (void) nvpair_value_uint16_array(nvp, &val, &nelem);
696 1.4 chs ARENDER(pctl, uint16_array, nvl, name, val, nelem);
697 1.1 haad break;
698 1.1 haad }
699 1.1 haad case DATA_TYPE_INT32_ARRAY: {
700 1.1 haad int32_t *val;
701 1.1 haad (void) nvpair_value_int32_array(nvp, &val, &nelem);
702 1.4 chs ARENDER(pctl, int32_array, nvl, name, val, nelem);
703 1.1 haad break;
704 1.1 haad }
705 1.1 haad case DATA_TYPE_UINT32_ARRAY: {
706 1.1 haad uint32_t *val;
707 1.1 haad (void) nvpair_value_uint32_array(nvp, &val, &nelem);
708 1.4 chs ARENDER(pctl, uint32_array, nvl, name, val, nelem);
709 1.1 haad break;
710 1.1 haad }
711 1.1 haad case DATA_TYPE_INT64_ARRAY: {
712 1.1 haad int64_t *val;
713 1.1 haad (void) nvpair_value_int64_array(nvp, &val, &nelem);
714 1.4 chs ARENDER(pctl, int64_array, nvl, name, val, nelem);
715 1.1 haad break;
716 1.1 haad }
717 1.1 haad case DATA_TYPE_UINT64_ARRAY: {
718 1.1 haad uint64_t *val;
719 1.1 haad (void) nvpair_value_uint64_array(nvp, &val, &nelem);
720 1.4 chs ARENDER(pctl, uint64_array, nvl, name, val, nelem);
721 1.1 haad break;
722 1.1 haad }
723 1.1 haad case DATA_TYPE_STRING_ARRAY: {
724 1.1 haad char **val;
725 1.1 haad (void) nvpair_value_string_array(nvp, &val, &nelem);
726 1.4 chs ARENDER(pctl, string_array, nvl, name, val, nelem);
727 1.1 haad break;
728 1.1 haad }
729 1.1 haad case DATA_TYPE_HRTIME: {
730 1.1 haad hrtime_t val;
731 1.1 haad (void) nvpair_value_hrtime(nvp, &val);
732 1.4 chs RENDER(pctl, hrtime, nvl, name, val);
733 1.1 haad break;
734 1.1 haad }
735 1.1 haad case DATA_TYPE_NVLIST: {
736 1.1 haad nvlist_t *val;
737 1.1 haad (void) nvpair_value_nvlist(nvp, &val);
738 1.4 chs RENDER(pctl, nvlist, nvl, name, val);
739 1.1 haad break;
740 1.1 haad }
741 1.1 haad case DATA_TYPE_NVLIST_ARRAY: {
742 1.1 haad nvlist_t **val;
743 1.1 haad (void) nvpair_value_nvlist_array(nvp, &val, &nelem);
744 1.4 chs ARENDER(pctl, nvlist_array, nvl, name, val, nelem);
745 1.1 haad break;
746 1.1 haad }
747 1.1 haad default:
748 1.1 haad (void) fprintf(fp, " unknown data type (%d)", type);
749 1.1 haad break;
750 1.1 haad }
751 1.1 haad nvp = nvlist_next_nvpair(nvl, nvp);
752 1.1 haad }
753 1.1 haad }
754 1.1 haad
755 1.1 haad void
756 1.1 haad nvlist_print(FILE *fp, nvlist_t *nvl)
757 1.1 haad {
758 1.4 chs struct nvlist_prtctl pc;
759 1.4 chs
760 1.4 chs prtctl_defaults(fp, &pc, NULL);
761 1.4 chs nvlist_print_with_indent(nvl, &pc);
762 1.1 haad }
763 1.1 haad
764 1.4 chs void
765 1.4 chs nvlist_prt(nvlist_t *nvl, nvlist_prtctl_t pctl)
766 1.4 chs {
767 1.4 chs nvlist_print_with_indent(nvl, pctl);
768 1.4 chs }
769 1.2 dsl
770 1.2 dsl #define NVP(elem, type, vtype, ptype, format) { \
771 1.2 dsl vtype value; \
772 1.2 dsl \
773 1.2 dsl (void) nvpair_value_##type(elem, &value); \
774 1.2 dsl (void) printf("%*s%s: " format "\n", indent, "", \
775 1.2 dsl nvpair_name(elem), (ptype)value); \
776 1.2 dsl }
777 1.2 dsl
778 1.2 dsl #define NVPA(elem, type, vtype, ptype, format) { \
779 1.2 dsl uint_t i, count; \
780 1.2 dsl vtype *value; \
781 1.2 dsl \
782 1.2 dsl (void) nvpair_value_##type(elem, &value, &count); \
783 1.2 dsl for (i = 0; i < count; i++) { \
784 1.2 dsl (void) printf("%*s%s[%d]: " format "\n", indent, "", \
785 1.2 dsl nvpair_name(elem), i, (ptype)value[i]); \
786 1.2 dsl } \
787 1.2 dsl }
788 1.2 dsl
789 1.2 dsl /*
790 1.2 dsl * Similar to nvlist_print() but handles arrays slightly differently.
791 1.2 dsl */
792 1.2 dsl void
793 1.2 dsl dump_nvlist(nvlist_t *list, int indent)
794 1.2 dsl {
795 1.2 dsl nvpair_t *elem = NULL;
796 1.2 dsl boolean_t bool_value;
797 1.4 chs boolean_t *bool_array_value;
798 1.2 dsl nvlist_t *nvlist_value;
799 1.2 dsl nvlist_t **nvlist_array_value;
800 1.2 dsl uint_t i, count;
801 1.2 dsl
802 1.2 dsl if (list == NULL) {
803 1.2 dsl return;
804 1.2 dsl }
805 1.2 dsl
806 1.2 dsl while ((elem = nvlist_next_nvpair(list, elem)) != NULL) {
807 1.2 dsl switch (nvpair_type(elem)) {
808 1.4 chs case DATA_TYPE_BOOLEAN:
809 1.4 chs (void) printf("%*s%s\n", indent, "", nvpair_name(elem));
810 1.4 chs break;
811 1.4 chs
812 1.2 dsl case DATA_TYPE_BOOLEAN_VALUE:
813 1.2 dsl (void) nvpair_value_boolean_value(elem, &bool_value);
814 1.2 dsl (void) printf("%*s%s: %s\n", indent, "",
815 1.2 dsl nvpair_name(elem), bool_value ? "true" : "false");
816 1.2 dsl break;
817 1.2 dsl
818 1.2 dsl case DATA_TYPE_BYTE:
819 1.2 dsl NVP(elem, byte, uchar_t, int, "%u");
820 1.2 dsl break;
821 1.2 dsl
822 1.2 dsl case DATA_TYPE_INT8:
823 1.2 dsl NVP(elem, int8, int8_t, int, "%d");
824 1.2 dsl break;
825 1.2 dsl
826 1.2 dsl case DATA_TYPE_UINT8:
827 1.2 dsl NVP(elem, uint8, uint8_t, int, "%u");
828 1.2 dsl break;
829 1.2 dsl
830 1.2 dsl case DATA_TYPE_INT16:
831 1.2 dsl NVP(elem, int16, int16_t, int, "%d");
832 1.2 dsl break;
833 1.2 dsl
834 1.2 dsl case DATA_TYPE_UINT16:
835 1.2 dsl NVP(elem, uint16, uint16_t, int, "%u");
836 1.2 dsl break;
837 1.2 dsl
838 1.2 dsl case DATA_TYPE_INT32:
839 1.2 dsl NVP(elem, int32, int32_t, long, "%ld");
840 1.2 dsl break;
841 1.2 dsl
842 1.2 dsl case DATA_TYPE_UINT32:
843 1.2 dsl NVP(elem, uint32, uint32_t, ulong_t, "%lu");
844 1.2 dsl break;
845 1.2 dsl
846 1.2 dsl case DATA_TYPE_INT64:
847 1.4 chs NVP(elem, int64, int64_t, longlong_t, "%lld");
848 1.2 dsl break;
849 1.2 dsl
850 1.2 dsl case DATA_TYPE_UINT64:
851 1.4 chs NVP(elem, uint64, uint64_t, u_longlong_t, "%llu");
852 1.2 dsl break;
853 1.2 dsl
854 1.2 dsl case DATA_TYPE_STRING:
855 1.2 dsl NVP(elem, string, char *, char *, "'%s'");
856 1.2 dsl break;
857 1.2 dsl
858 1.4 chs case DATA_TYPE_BOOLEAN_ARRAY:
859 1.4 chs (void) nvpair_value_boolean_array(elem,
860 1.4 chs &bool_array_value, &count);
861 1.4 chs for (i = 0; i < count; i++) {
862 1.4 chs (void) printf("%*s%s[%d]: %s\n", indent, "",
863 1.4 chs nvpair_name(elem), i,
864 1.4 chs bool_array_value[i] ? "true" : "false");
865 1.4 chs }
866 1.4 chs break;
867 1.4 chs
868 1.2 dsl case DATA_TYPE_BYTE_ARRAY:
869 1.2 dsl NVPA(elem, byte_array, uchar_t, int, "%u");
870 1.2 dsl break;
871 1.2 dsl
872 1.2 dsl case DATA_TYPE_INT8_ARRAY:
873 1.2 dsl NVPA(elem, int8_array, int8_t, int, "%d");
874 1.2 dsl break;
875 1.2 dsl
876 1.2 dsl case DATA_TYPE_UINT8_ARRAY:
877 1.2 dsl NVPA(elem, uint8_array, uint8_t, int, "%u");
878 1.2 dsl break;
879 1.2 dsl
880 1.2 dsl case DATA_TYPE_INT16_ARRAY:
881 1.2 dsl NVPA(elem, int16_array, int16_t, int, "%d");
882 1.2 dsl break;
883 1.2 dsl
884 1.2 dsl case DATA_TYPE_UINT16_ARRAY:
885 1.2 dsl NVPA(elem, uint16_array, uint16_t, int, "%u");
886 1.2 dsl break;
887 1.2 dsl
888 1.2 dsl case DATA_TYPE_INT32_ARRAY:
889 1.2 dsl NVPA(elem, int32_array, int32_t, long, "%ld");
890 1.2 dsl break;
891 1.2 dsl
892 1.2 dsl case DATA_TYPE_UINT32_ARRAY:
893 1.2 dsl NVPA(elem, uint32_array, uint32_t, ulong_t, "%lu");
894 1.2 dsl break;
895 1.2 dsl
896 1.2 dsl case DATA_TYPE_INT64_ARRAY:
897 1.4 chs NVPA(elem, int64_array, int64_t, longlong_t, "%lld");
898 1.2 dsl break;
899 1.2 dsl
900 1.2 dsl case DATA_TYPE_UINT64_ARRAY:
901 1.4 chs NVPA(elem, uint64_array, uint64_t, u_longlong_t,
902 1.4 chs "%llu");
903 1.2 dsl break;
904 1.2 dsl
905 1.2 dsl case DATA_TYPE_STRING_ARRAY:
906 1.2 dsl NVPA(elem, string_array, char *, char *, "'%s'");
907 1.2 dsl break;
908 1.2 dsl
909 1.2 dsl case DATA_TYPE_NVLIST:
910 1.2 dsl (void) nvpair_value_nvlist(elem, &nvlist_value);
911 1.2 dsl (void) printf("%*s%s:\n", indent, "",
912 1.2 dsl nvpair_name(elem));
913 1.2 dsl dump_nvlist(nvlist_value, indent + 4);
914 1.2 dsl break;
915 1.2 dsl
916 1.2 dsl case DATA_TYPE_NVLIST_ARRAY:
917 1.2 dsl (void) nvpair_value_nvlist_array(elem,
918 1.2 dsl &nvlist_array_value, &count);
919 1.2 dsl for (i = 0; i < count; i++) {
920 1.2 dsl (void) printf("%*s%s[%u]:\n", indent, "",
921 1.2 dsl nvpair_name(elem), i);
922 1.2 dsl dump_nvlist(nvlist_array_value[i], indent + 4);
923 1.2 dsl }
924 1.2 dsl break;
925 1.2 dsl
926 1.2 dsl default:
927 1.2 dsl (void) printf(dgettext(TEXT_DOMAIN, "bad config type "
928 1.2 dsl "%d for %s\n"), nvpair_type(elem),
929 1.2 dsl nvpair_name(elem));
930 1.2 dsl }
931 1.2 dsl }
932 1.2 dsl }
933 1.2 dsl
934 1.1 haad /*
935 1.4 chs * ======================================================================
936 1.4 chs * | |
937 1.4 chs * | Misc private interface. |
938 1.4 chs * | |
939 1.4 chs * ======================================================================
940 1.4 chs */
941 1.4 chs
942 1.4 chs /*
943 1.1 haad * Determine if string 'value' matches 'nvp' value. The 'value' string is
944 1.1 haad * converted, depending on the type of 'nvp', prior to match. For numeric
945 1.1 haad * types, a radix independent sscanf conversion of 'value' is used. If 'nvp'
946 1.1 haad * is an array type, 'ai' is the index into the array against which we are
947 1.1 haad * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass
948 1.1 haad * in a regex_t compilation of value in 'value_regex' to trigger regular
949 1.1 haad * expression string match instead of simple strcmp().
950 1.1 haad *
951 1.1 haad * Return 1 on match, 0 on no-match, and -1 on error. If the error is
952 1.1 haad * related to value syntax error and 'ep' is non-NULL, *ep will point into
953 1.1 haad * the 'value' string at the location where the error exists.
954 1.1 haad *
955 1.1 haad * NOTE: It may be possible to move the non-regex_t version of this into
956 1.1 haad * common code used by library/kernel/boot.
957 1.1 haad */
958 1.1 haad int
959 1.1 haad nvpair_value_match_regex(nvpair_t *nvp, int ai,
960 1.1 haad char *value, regex_t *value_regex, char **ep)
961 1.1 haad {
962 1.1 haad char *evalue;
963 1.1 haad uint_t a_len;
964 1.1 haad int sr;
965 1.1 haad
966 1.1 haad if (ep)
967 1.1 haad *ep = NULL;
968 1.1 haad
969 1.1 haad if ((nvp == NULL) || (value == NULL))
970 1.1 haad return (-1); /* error fail match - invalid args */
971 1.1 haad
972 1.1 haad /* make sure array and index combination make sense */
973 1.1 haad if ((nvpair_type_is_array(nvp) && (ai < 0)) ||
974 1.1 haad (!nvpair_type_is_array(nvp) && (ai >= 0)))
975 1.1 haad return (-1); /* error fail match - bad index */
976 1.1 haad
977 1.1 haad /* non-string values should be single 'chunk' */
978 1.1 haad if ((nvpair_type(nvp) != DATA_TYPE_STRING) &&
979 1.1 haad (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) {
980 1.1 haad value += strspn(value, " \t");
981 1.1 haad evalue = value + strcspn(value, " \t");
982 1.1 haad if (*evalue) {
983 1.1 haad if (ep)
984 1.1 haad *ep = evalue;
985 1.1 haad return (-1); /* error fail match - syntax */
986 1.1 haad }
987 1.1 haad }
988 1.1 haad
989 1.1 haad sr = EOF;
990 1.1 haad switch (nvpair_type(nvp)) {
991 1.1 haad case DATA_TYPE_STRING: {
992 1.1 haad char *val;
993 1.1 haad
994 1.1 haad /* check string value for match */
995 1.1 haad if (nvpair_value_string(nvp, &val) == 0) {
996 1.1 haad if (value_regex) {
997 1.1 haad if (regexec(value_regex, val,
998 1.1 haad (size_t)0, NULL, 0) == 0)
999 1.1 haad return (1); /* match */
1000 1.1 haad } else {
1001 1.1 haad if (strcmp(value, val) == 0)
1002 1.1 haad return (1); /* match */
1003 1.1 haad }
1004 1.1 haad }
1005 1.1 haad break;
1006 1.1 haad }
1007 1.1 haad case DATA_TYPE_STRING_ARRAY: {
1008 1.1 haad char **val_array;
1009 1.1 haad
1010 1.1 haad /* check indexed string value of array for match */
1011 1.1 haad if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) &&
1012 1.1 haad (ai < a_len)) {
1013 1.1 haad if (value_regex) {
1014 1.1 haad if (regexec(value_regex, val_array[ai],
1015 1.1 haad (size_t)0, NULL, 0) == 0)
1016 1.1 haad return (1);
1017 1.1 haad } else {
1018 1.1 haad if (strcmp(value, val_array[ai]) == 0)
1019 1.1 haad return (1);
1020 1.1 haad }
1021 1.1 haad }
1022 1.1 haad break;
1023 1.1 haad }
1024 1.1 haad case DATA_TYPE_BYTE: {
1025 1.1 haad uchar_t val, val_arg;
1026 1.1 haad
1027 1.1 haad /* scanf uchar_t from value and check for match */
1028 1.1 haad sr = sscanf(value, "%c", &val_arg);
1029 1.1 haad if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) &&
1030 1.1 haad (val == val_arg))
1031 1.1 haad return (1);
1032 1.1 haad break;
1033 1.1 haad }
1034 1.1 haad case DATA_TYPE_BYTE_ARRAY: {
1035 1.1 haad uchar_t *val_array, val_arg;
1036 1.1 haad
1037 1.1 haad
1038 1.1 haad /* check indexed value of array for match */
1039 1.1 haad sr = sscanf(value, "%c", &val_arg);
1040 1.1 haad if ((sr == 1) &&
1041 1.1 haad (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) &&
1042 1.1 haad (ai < a_len) &&
1043 1.1 haad (val_array[ai] == val_arg))
1044 1.1 haad return (1);
1045 1.1 haad break;
1046 1.1 haad }
1047 1.1 haad case DATA_TYPE_INT8: {
1048 1.1 haad int8_t val, val_arg;
1049 1.1 haad
1050 1.1 haad /* scanf int8_t from value and check for match */
1051 1.1 haad sr = sscanf(value, "%"SCNi8, &val_arg);
1052 1.1 haad if ((sr == 1) &&
1053 1.1 haad (nvpair_value_int8(nvp, &val) == 0) &&
1054 1.1 haad (val == val_arg))
1055 1.1 haad return (1);
1056 1.1 haad break;
1057 1.1 haad }
1058 1.1 haad case DATA_TYPE_INT8_ARRAY: {
1059 1.1 haad int8_t *val_array, val_arg;
1060 1.1 haad
1061 1.1 haad /* check indexed value of array for match */
1062 1.1 haad sr = sscanf(value, "%"SCNi8, &val_arg);
1063 1.1 haad if ((sr == 1) &&
1064 1.1 haad (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) &&
1065 1.1 haad (ai < a_len) &&
1066 1.1 haad (val_array[ai] == val_arg))
1067 1.1 haad return (1);
1068 1.1 haad break;
1069 1.1 haad }
1070 1.1 haad case DATA_TYPE_UINT8: {
1071 1.1 haad uint8_t val, val_arg;
1072 1.1 haad
1073 1.1 haad /* scanf uint8_t from value and check for match */
1074 1.1 haad sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
1075 1.1 haad if ((sr == 1) &&
1076 1.1 haad (nvpair_value_uint8(nvp, &val) == 0) &&
1077 1.1 haad (val == val_arg))
1078 1.1 haad return (1);
1079 1.1 haad break;
1080 1.1 haad }
1081 1.1 haad case DATA_TYPE_UINT8_ARRAY: {
1082 1.1 haad uint8_t *val_array, val_arg;
1083 1.1 haad
1084 1.1 haad /* check indexed value of array for match */
1085 1.1 haad sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
1086 1.1 haad if ((sr == 1) &&
1087 1.1 haad (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) &&
1088 1.1 haad (ai < a_len) &&
1089 1.1 haad (val_array[ai] == val_arg))
1090 1.1 haad return (1);
1091 1.1 haad break;
1092 1.1 haad }
1093 1.1 haad case DATA_TYPE_INT16: {
1094 1.1 haad int16_t val, val_arg;
1095 1.1 haad
1096 1.1 haad /* scanf int16_t from value and check for match */
1097 1.1 haad sr = sscanf(value, "%"SCNi16, &val_arg);
1098 1.1 haad if ((sr == 1) &&
1099 1.1 haad (nvpair_value_int16(nvp, &val) == 0) &&
1100 1.1 haad (val == val_arg))
1101 1.1 haad return (1);
1102 1.1 haad break;
1103 1.1 haad }
1104 1.1 haad case DATA_TYPE_INT16_ARRAY: {
1105 1.1 haad int16_t *val_array, val_arg;
1106 1.1 haad
1107 1.1 haad /* check indexed value of array for match */
1108 1.1 haad sr = sscanf(value, "%"SCNi16, &val_arg);
1109 1.1 haad if ((sr == 1) &&
1110 1.1 haad (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) &&
1111 1.1 haad (ai < a_len) &&
1112 1.1 haad (val_array[ai] == val_arg))
1113 1.1 haad return (1);
1114 1.1 haad break;
1115 1.1 haad }
1116 1.1 haad case DATA_TYPE_UINT16: {
1117 1.1 haad uint16_t val, val_arg;
1118 1.1 haad
1119 1.1 haad /* scanf uint16_t from value and check for match */
1120 1.1 haad sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
1121 1.1 haad if ((sr == 1) &&
1122 1.1 haad (nvpair_value_uint16(nvp, &val) == 0) &&
1123 1.1 haad (val == val_arg))
1124 1.1 haad return (1);
1125 1.1 haad break;
1126 1.1 haad }
1127 1.1 haad case DATA_TYPE_UINT16_ARRAY: {
1128 1.1 haad uint16_t *val_array, val_arg;
1129 1.1 haad
1130 1.1 haad /* check indexed value of array for match */
1131 1.1 haad sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
1132 1.1 haad if ((sr == 1) &&
1133 1.1 haad (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) &&
1134 1.1 haad (ai < a_len) &&
1135 1.1 haad (val_array[ai] == val_arg))
1136 1.1 haad return (1);
1137 1.1 haad break;
1138 1.1 haad }
1139 1.1 haad case DATA_TYPE_INT32: {
1140 1.1 haad int32_t val, val_arg;
1141 1.1 haad
1142 1.1 haad /* scanf int32_t from value and check for match */
1143 1.1 haad sr = sscanf(value, "%"SCNi32, &val_arg);
1144 1.1 haad if ((sr == 1) &&
1145 1.1 haad (nvpair_value_int32(nvp, &val) == 0) &&
1146 1.1 haad (val == val_arg))
1147 1.1 haad return (1);
1148 1.1 haad break;
1149 1.1 haad }
1150 1.1 haad case DATA_TYPE_INT32_ARRAY: {
1151 1.1 haad int32_t *val_array, val_arg;
1152 1.1 haad
1153 1.1 haad /* check indexed value of array for match */
1154 1.1 haad sr = sscanf(value, "%"SCNi32, &val_arg);
1155 1.1 haad if ((sr == 1) &&
1156 1.1 haad (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) &&
1157 1.1 haad (ai < a_len) &&
1158 1.1 haad (val_array[ai] == val_arg))
1159 1.1 haad return (1);
1160 1.1 haad break;
1161 1.1 haad }
1162 1.1 haad case DATA_TYPE_UINT32: {
1163 1.1 haad uint32_t val, val_arg;
1164 1.1 haad
1165 1.1 haad /* scanf uint32_t from value and check for match */
1166 1.1 haad sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
1167 1.1 haad if ((sr == 1) &&
1168 1.1 haad (nvpair_value_uint32(nvp, &val) == 0) &&
1169 1.1 haad (val == val_arg))
1170 1.1 haad return (1);
1171 1.1 haad break;
1172 1.1 haad }
1173 1.1 haad case DATA_TYPE_UINT32_ARRAY: {
1174 1.1 haad uint32_t *val_array, val_arg;
1175 1.1 haad
1176 1.1 haad /* check indexed value of array for match */
1177 1.1 haad sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
1178 1.1 haad if ((sr == 1) &&
1179 1.1 haad (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) &&
1180 1.1 haad (ai < a_len) &&
1181 1.1 haad (val_array[ai] == val_arg))
1182 1.1 haad return (1);
1183 1.1 haad break;
1184 1.1 haad }
1185 1.1 haad case DATA_TYPE_INT64: {
1186 1.1 haad int64_t val, val_arg;
1187 1.1 haad
1188 1.1 haad /* scanf int64_t from value and check for match */
1189 1.1 haad sr = sscanf(value, "%"SCNi64, &val_arg);
1190 1.1 haad if ((sr == 1) &&
1191 1.1 haad (nvpair_value_int64(nvp, &val) == 0) &&
1192 1.1 haad (val == val_arg))
1193 1.1 haad return (1);
1194 1.1 haad break;
1195 1.1 haad }
1196 1.1 haad case DATA_TYPE_INT64_ARRAY: {
1197 1.1 haad int64_t *val_array, val_arg;
1198 1.1 haad
1199 1.1 haad /* check indexed value of array for match */
1200 1.1 haad sr = sscanf(value, "%"SCNi64, &val_arg);
1201 1.1 haad if ((sr == 1) &&
1202 1.1 haad (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) &&
1203 1.1 haad (ai < a_len) &&
1204 1.1 haad (val_array[ai] == val_arg))
1205 1.1 haad return (1);
1206 1.1 haad break;
1207 1.1 haad }
1208 1.1 haad case DATA_TYPE_UINT64: {
1209 1.1 haad uint64_t val_arg, val;
1210 1.1 haad
1211 1.1 haad /* scanf uint64_t from value and check for match */
1212 1.1 haad sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
1213 1.1 haad if ((sr == 1) &&
1214 1.1 haad (nvpair_value_uint64(nvp, &val) == 0) &&
1215 1.1 haad (val == val_arg))
1216 1.1 haad return (1);
1217 1.1 haad break;
1218 1.1 haad }
1219 1.1 haad case DATA_TYPE_UINT64_ARRAY: {
1220 1.1 haad uint64_t *val_array, val_arg;
1221 1.1 haad
1222 1.1 haad /* check indexed value of array for match */
1223 1.1 haad sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
1224 1.1 haad if ((sr == 1) &&
1225 1.1 haad (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) &&
1226 1.1 haad (ai < a_len) &&
1227 1.1 haad (val_array[ai] == val_arg))
1228 1.1 haad return (1);
1229 1.1 haad break;
1230 1.1 haad }
1231 1.1 haad case DATA_TYPE_BOOLEAN_VALUE: {
1232 1.4 chs int32_t val_arg;
1233 1.4 chs boolean_t val;
1234 1.1 haad
1235 1.1 haad /* scanf boolean_t from value and check for match */
1236 1.1 haad sr = sscanf(value, "%"SCNi32, &val_arg);
1237 1.1 haad if ((sr == 1) &&
1238 1.1 haad (nvpair_value_boolean_value(nvp, &val) == 0) &&
1239 1.1 haad (val == val_arg))
1240 1.1 haad return (1);
1241 1.1 haad break;
1242 1.1 haad }
1243 1.1 haad case DATA_TYPE_BOOLEAN_ARRAY: {
1244 1.4 chs boolean_t *val_array;
1245 1.4 chs int32_t val_arg;
1246 1.1 haad
1247 1.1 haad /* check indexed value of array for match */
1248 1.1 haad sr = sscanf(value, "%"SCNi32, &val_arg);
1249 1.1 haad if ((sr == 1) &&
1250 1.1 haad (nvpair_value_boolean_array(nvp,
1251 1.1 haad &val_array, &a_len) == 0) &&
1252 1.1 haad (ai < a_len) &&
1253 1.1 haad (val_array[ai] == val_arg))
1254 1.1 haad return (1);
1255 1.1 haad break;
1256 1.1 haad }
1257 1.1 haad case DATA_TYPE_HRTIME:
1258 1.1 haad case DATA_TYPE_NVLIST:
1259 1.1 haad case DATA_TYPE_NVLIST_ARRAY:
1260 1.1 haad case DATA_TYPE_BOOLEAN:
1261 1.1 haad case DATA_TYPE_DOUBLE:
1262 1.1 haad case DATA_TYPE_UNKNOWN:
1263 1.1 haad default:
1264 1.1 haad /*
1265 1.1 haad * unknown/unsupported data type
1266 1.1 haad */
1267 1.1 haad return (-1); /* error fail match */
1268 1.1 haad }
1269 1.1 haad
1270 1.1 haad /*
1271 1.1 haad * check to see if sscanf failed conversion, return approximate
1272 1.1 haad * pointer to problem
1273 1.1 haad */
1274 1.1 haad if (sr != 1) {
1275 1.1 haad if (ep)
1276 1.1 haad *ep = value;
1277 1.1 haad return (-1); /* error fail match - syntax */
1278 1.1 haad }
1279 1.1 haad
1280 1.1 haad return (0); /* fail match */
1281 1.1 haad }
1282 1.1 haad
1283 1.1 haad int
1284 1.1 haad nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep)
1285 1.1 haad {
1286 1.1 haad return (nvpair_value_match_regex(nvp, ai, value, NULL, ep));
1287 1.1 haad }
1288