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