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