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