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