17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5602ca9eaScth * Common Development and Distribution License (the "License"). 6602ca9eaScth * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*88ecc943SGeorge Wilson * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <unistd.h> 277c478bd9Sstevel@tonic-gate #include <strings.h> 28*88ecc943SGeorge Wilson #include <libintl.h> 29602ca9eaScth #include <sys/types.h> 30602ca9eaScth #include <sys/inttypes.h> 317c478bd9Sstevel@tonic-gate #include "libnvpair.h" 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate /* 347c478bd9Sstevel@tonic-gate * libnvpair - A tools library for manipulating <name, value> pairs. 357c478bd9Sstevel@tonic-gate * 367c478bd9Sstevel@tonic-gate * This library provides routines packing an unpacking nv pairs 377c478bd9Sstevel@tonic-gate * for transporting data across process boundaries, transporting 387c478bd9Sstevel@tonic-gate * between kernel and userland, and possibly saving onto disk files. 397c478bd9Sstevel@tonic-gate */ 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate static void 427c478bd9Sstevel@tonic-gate indent(FILE *fp, int depth) 437c478bd9Sstevel@tonic-gate { 447c478bd9Sstevel@tonic-gate while (depth-- > 0) 457c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t"); 467c478bd9Sstevel@tonic-gate } 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate /* 497c478bd9Sstevel@tonic-gate * nvlist_print - Prints elements in an event buffer 507c478bd9Sstevel@tonic-gate */ 517c478bd9Sstevel@tonic-gate static 527c478bd9Sstevel@tonic-gate void 537c478bd9Sstevel@tonic-gate nvlist_print_with_indent(FILE *fp, nvlist_t *nvl, int depth) 547c478bd9Sstevel@tonic-gate { 557c478bd9Sstevel@tonic-gate int i; 567c478bd9Sstevel@tonic-gate char *name; 577c478bd9Sstevel@tonic-gate uint_t nelem; 587c478bd9Sstevel@tonic-gate nvpair_t *nvp; 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate if (nvl == NULL) 617c478bd9Sstevel@tonic-gate return; 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate indent(fp, depth); 647c478bd9Sstevel@tonic-gate (void) fprintf(fp, "nvlist version: %d\n", NVL_VERSION(nvl)); 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate nvp = nvlist_next_nvpair(nvl, NULL); 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate while (nvp) { 697c478bd9Sstevel@tonic-gate data_type_t type = nvpair_type(nvp); 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate indent(fp, depth); 727c478bd9Sstevel@tonic-gate name = nvpair_name(nvp); 737c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s =", name); 747c478bd9Sstevel@tonic-gate nelem = 0; 757c478bd9Sstevel@tonic-gate switch (type) { 767c478bd9Sstevel@tonic-gate case DATA_TYPE_BOOLEAN: { 777c478bd9Sstevel@tonic-gate (void) fprintf(fp, " 1"); 787c478bd9Sstevel@tonic-gate break; 797c478bd9Sstevel@tonic-gate } 807c478bd9Sstevel@tonic-gate case DATA_TYPE_BOOLEAN_VALUE: { 817c478bd9Sstevel@tonic-gate boolean_t val; 827c478bd9Sstevel@tonic-gate (void) nvpair_value_boolean_value(nvp, &val); 837c478bd9Sstevel@tonic-gate (void) fprintf(fp, " %d", val); 847c478bd9Sstevel@tonic-gate break; 857c478bd9Sstevel@tonic-gate } 867c478bd9Sstevel@tonic-gate case DATA_TYPE_BYTE: { 877c478bd9Sstevel@tonic-gate uchar_t val; 887c478bd9Sstevel@tonic-gate (void) nvpair_value_byte(nvp, &val); 897c478bd9Sstevel@tonic-gate (void) fprintf(fp, " 0x%2.2x", val); 907c478bd9Sstevel@tonic-gate break; 917c478bd9Sstevel@tonic-gate } 927c478bd9Sstevel@tonic-gate case DATA_TYPE_INT8: { 937c478bd9Sstevel@tonic-gate int8_t val; 947c478bd9Sstevel@tonic-gate (void) nvpair_value_int8(nvp, &val); 957c478bd9Sstevel@tonic-gate (void) fprintf(fp, " %d", val); 967c478bd9Sstevel@tonic-gate break; 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate case DATA_TYPE_UINT8: { 997c478bd9Sstevel@tonic-gate uint8_t val; 1007c478bd9Sstevel@tonic-gate (void) nvpair_value_uint8(nvp, &val); 1017c478bd9Sstevel@tonic-gate (void) fprintf(fp, " 0x%x", val); 1027c478bd9Sstevel@tonic-gate break; 1037c478bd9Sstevel@tonic-gate } 1047c478bd9Sstevel@tonic-gate case DATA_TYPE_INT16: { 1057c478bd9Sstevel@tonic-gate int16_t val; 1067c478bd9Sstevel@tonic-gate (void) nvpair_value_int16(nvp, &val); 1077c478bd9Sstevel@tonic-gate (void) fprintf(fp, " %d", val); 1087c478bd9Sstevel@tonic-gate break; 1097c478bd9Sstevel@tonic-gate } 1107c478bd9Sstevel@tonic-gate case DATA_TYPE_UINT16: { 1117c478bd9Sstevel@tonic-gate uint16_t val; 1127c478bd9Sstevel@tonic-gate (void) nvpair_value_uint16(nvp, &val); 1137c478bd9Sstevel@tonic-gate (void) fprintf(fp, " 0x%x", val); 1147c478bd9Sstevel@tonic-gate break; 1157c478bd9Sstevel@tonic-gate } 1167c478bd9Sstevel@tonic-gate case DATA_TYPE_INT32: { 1177c478bd9Sstevel@tonic-gate int32_t val; 1187c478bd9Sstevel@tonic-gate (void) nvpair_value_int32(nvp, &val); 1197c478bd9Sstevel@tonic-gate (void) fprintf(fp, " %d", val); 1207c478bd9Sstevel@tonic-gate break; 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate case DATA_TYPE_UINT32: { 1237c478bd9Sstevel@tonic-gate uint32_t val; 1247c478bd9Sstevel@tonic-gate (void) nvpair_value_uint32(nvp, &val); 1257c478bd9Sstevel@tonic-gate (void) fprintf(fp, " 0x%x", val); 1267c478bd9Sstevel@tonic-gate break; 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate case DATA_TYPE_INT64: { 1297c478bd9Sstevel@tonic-gate int64_t val; 1307c478bd9Sstevel@tonic-gate (void) nvpair_value_int64(nvp, &val); 1317c478bd9Sstevel@tonic-gate (void) fprintf(fp, " %lld", (longlong_t)val); 1327c478bd9Sstevel@tonic-gate break; 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate case DATA_TYPE_UINT64: { 1357c478bd9Sstevel@tonic-gate uint64_t val; 1367c478bd9Sstevel@tonic-gate (void) nvpair_value_uint64(nvp, &val); 1377c478bd9Sstevel@tonic-gate (void) fprintf(fp, " 0x%llx", (u_longlong_t)val); 1387c478bd9Sstevel@tonic-gate break; 1397c478bd9Sstevel@tonic-gate } 140825ba0f2Srobj case DATA_TYPE_DOUBLE: { 141825ba0f2Srobj double val; 142825ba0f2Srobj (void) nvpair_value_double(nvp, &val); 143825ba0f2Srobj (void) fprintf(fp, " 0x%llf", val); 144825ba0f2Srobj break; 145825ba0f2Srobj } 1467c478bd9Sstevel@tonic-gate case DATA_TYPE_STRING: { 1477c478bd9Sstevel@tonic-gate char *val; 1487c478bd9Sstevel@tonic-gate (void) nvpair_value_string(nvp, &val); 1497c478bd9Sstevel@tonic-gate (void) fprintf(fp, " %s", val); 1507c478bd9Sstevel@tonic-gate break; 1517c478bd9Sstevel@tonic-gate } 1527c478bd9Sstevel@tonic-gate case DATA_TYPE_BOOLEAN_ARRAY: { 1537c478bd9Sstevel@tonic-gate boolean_t *val; 1547c478bd9Sstevel@tonic-gate (void) nvpair_value_boolean_array(nvp, &val, &nelem); 1557c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) 1567c478bd9Sstevel@tonic-gate (void) fprintf(fp, " %d", val[i]); 1577c478bd9Sstevel@tonic-gate break; 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate case DATA_TYPE_BYTE_ARRAY: { 1607c478bd9Sstevel@tonic-gate uchar_t *val; 1617c478bd9Sstevel@tonic-gate (void) nvpair_value_byte_array(nvp, &val, &nelem); 1627c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) 1637c478bd9Sstevel@tonic-gate (void) fprintf(fp, " 0x%2.2x", val[i]); 1647c478bd9Sstevel@tonic-gate break; 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate case DATA_TYPE_INT8_ARRAY: { 1677c478bd9Sstevel@tonic-gate int8_t *val; 1687c478bd9Sstevel@tonic-gate (void) nvpair_value_int8_array(nvp, &val, &nelem); 1697c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) 1707c478bd9Sstevel@tonic-gate (void) fprintf(fp, " %d", val[i]); 1717c478bd9Sstevel@tonic-gate break; 1727c478bd9Sstevel@tonic-gate } 1737c478bd9Sstevel@tonic-gate case DATA_TYPE_UINT8_ARRAY: { 1747c478bd9Sstevel@tonic-gate uint8_t *val; 1757c478bd9Sstevel@tonic-gate (void) nvpair_value_uint8_array(nvp, &val, &nelem); 1767c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) 1777c478bd9Sstevel@tonic-gate (void) fprintf(fp, " 0x%x", val[i]); 1787c478bd9Sstevel@tonic-gate break; 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate case DATA_TYPE_INT16_ARRAY: { 1817c478bd9Sstevel@tonic-gate int16_t *val; 1827c478bd9Sstevel@tonic-gate (void) nvpair_value_int16_array(nvp, &val, &nelem); 1837c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) 1847c478bd9Sstevel@tonic-gate (void) fprintf(fp, " %d", val[i]); 1857c478bd9Sstevel@tonic-gate break; 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate case DATA_TYPE_UINT16_ARRAY: { 1887c478bd9Sstevel@tonic-gate uint16_t *val; 1897c478bd9Sstevel@tonic-gate (void) nvpair_value_uint16_array(nvp, &val, &nelem); 1907c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) 1917c478bd9Sstevel@tonic-gate (void) fprintf(fp, " 0x%x", val[i]); 1927c478bd9Sstevel@tonic-gate break; 1937c478bd9Sstevel@tonic-gate } 1947c478bd9Sstevel@tonic-gate case DATA_TYPE_INT32_ARRAY: { 1957c478bd9Sstevel@tonic-gate int32_t *val; 1967c478bd9Sstevel@tonic-gate (void) nvpair_value_int32_array(nvp, &val, &nelem); 1977c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) 1987c478bd9Sstevel@tonic-gate (void) fprintf(fp, " %d", val[i]); 1997c478bd9Sstevel@tonic-gate break; 2007c478bd9Sstevel@tonic-gate } 2017c478bd9Sstevel@tonic-gate case DATA_TYPE_UINT32_ARRAY: { 2027c478bd9Sstevel@tonic-gate uint32_t *val; 2037c478bd9Sstevel@tonic-gate (void) nvpair_value_uint32_array(nvp, &val, &nelem); 2047c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) 2057c478bd9Sstevel@tonic-gate (void) fprintf(fp, " 0x%x", val[i]); 2067c478bd9Sstevel@tonic-gate break; 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate case DATA_TYPE_INT64_ARRAY: { 2097c478bd9Sstevel@tonic-gate int64_t *val; 2107c478bd9Sstevel@tonic-gate (void) nvpair_value_int64_array(nvp, &val, &nelem); 2117c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) 2127c478bd9Sstevel@tonic-gate (void) fprintf(fp, " %lld", (longlong_t)val[i]); 2137c478bd9Sstevel@tonic-gate break; 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate case DATA_TYPE_UINT64_ARRAY: { 2167c478bd9Sstevel@tonic-gate uint64_t *val; 2177c478bd9Sstevel@tonic-gate (void) nvpair_value_uint64_array(nvp, &val, &nelem); 2187c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) 2197c478bd9Sstevel@tonic-gate (void) fprintf(fp, " 0x%llx", 2207c478bd9Sstevel@tonic-gate (u_longlong_t)val[i]); 2217c478bd9Sstevel@tonic-gate break; 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate case DATA_TYPE_STRING_ARRAY: { 2247c478bd9Sstevel@tonic-gate char **val; 2257c478bd9Sstevel@tonic-gate (void) nvpair_value_string_array(nvp, &val, &nelem); 2267c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) 2277c478bd9Sstevel@tonic-gate (void) fprintf(fp, " %s", val[i]); 2287c478bd9Sstevel@tonic-gate break; 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate case DATA_TYPE_HRTIME: { 2317c478bd9Sstevel@tonic-gate hrtime_t val; 2327c478bd9Sstevel@tonic-gate (void) nvpair_value_hrtime(nvp, &val); 2337c478bd9Sstevel@tonic-gate (void) fprintf(fp, " 0x%llx", val); 2347c478bd9Sstevel@tonic-gate break; 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate case DATA_TYPE_NVLIST: { 2377c478bd9Sstevel@tonic-gate nvlist_t *val; 2387c478bd9Sstevel@tonic-gate (void) nvpair_value_nvlist(nvp, &val); 2397c478bd9Sstevel@tonic-gate (void) fprintf(fp, " (embedded nvlist)\n"); 2407c478bd9Sstevel@tonic-gate nvlist_print_with_indent(fp, val, depth + 1); 2417c478bd9Sstevel@tonic-gate indent(fp, depth + 1); 2427c478bd9Sstevel@tonic-gate (void) fprintf(fp, "(end %s)\n", name); 2437c478bd9Sstevel@tonic-gate break; 2447c478bd9Sstevel@tonic-gate } 2457c478bd9Sstevel@tonic-gate case DATA_TYPE_NVLIST_ARRAY: { 2467c478bd9Sstevel@tonic-gate nvlist_t **val; 2477c478bd9Sstevel@tonic-gate (void) nvpair_value_nvlist_array(nvp, &val, &nelem); 2487c478bd9Sstevel@tonic-gate (void) fprintf(fp, " (array of embedded nvlists)\n"); 2497c478bd9Sstevel@tonic-gate for (i = 0; i < nelem; i++) { 2507c478bd9Sstevel@tonic-gate indent(fp, depth + 1); 2517c478bd9Sstevel@tonic-gate (void) fprintf(fp, 2527c478bd9Sstevel@tonic-gate "(start %s[%d])\n", name, i); 2537c478bd9Sstevel@tonic-gate nvlist_print_with_indent(fp, val[i], depth + 1); 2547c478bd9Sstevel@tonic-gate indent(fp, depth + 1); 2557c478bd9Sstevel@tonic-gate (void) fprintf(fp, "(end %s[%d])\n", name, i); 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate break; 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate default: 2607c478bd9Sstevel@tonic-gate (void) fprintf(fp, " unknown data type (%d)", type); 2617c478bd9Sstevel@tonic-gate break; 2627c478bd9Sstevel@tonic-gate } 2637c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\n"); 2647c478bd9Sstevel@tonic-gate nvp = nvlist_next_nvpair(nvl, nvp); 2657c478bd9Sstevel@tonic-gate } 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate void 2697c478bd9Sstevel@tonic-gate nvlist_print(FILE *fp, nvlist_t *nvl) 2707c478bd9Sstevel@tonic-gate { 2717c478bd9Sstevel@tonic-gate nvlist_print_with_indent(fp, nvl, 0); 2727c478bd9Sstevel@tonic-gate } 273602ca9eaScth 274*88ecc943SGeorge Wilson 275*88ecc943SGeorge Wilson #define NVP(elem, type, vtype, ptype, format) { \ 276*88ecc943SGeorge Wilson vtype value; \ 277*88ecc943SGeorge Wilson \ 278*88ecc943SGeorge Wilson (void) nvpair_value_##type(elem, &value); \ 279*88ecc943SGeorge Wilson (void) printf("%*s%s: " format "\n", indent, "", \ 280*88ecc943SGeorge Wilson nvpair_name(elem), (ptype)value); \ 281*88ecc943SGeorge Wilson } 282*88ecc943SGeorge Wilson 283*88ecc943SGeorge Wilson #define NVPA(elem, type, vtype, ptype, format) { \ 284*88ecc943SGeorge Wilson uint_t i, count; \ 285*88ecc943SGeorge Wilson vtype *value; \ 286*88ecc943SGeorge Wilson \ 287*88ecc943SGeorge Wilson (void) nvpair_value_##type(elem, &value, &count); \ 288*88ecc943SGeorge Wilson for (i = 0; i < count; i++) { \ 289*88ecc943SGeorge Wilson (void) printf("%*s%s[%d]: " format "\n", indent, "", \ 290*88ecc943SGeorge Wilson nvpair_name(elem), i, (ptype)value[i]); \ 291*88ecc943SGeorge Wilson } \ 292*88ecc943SGeorge Wilson } 293*88ecc943SGeorge Wilson 294*88ecc943SGeorge Wilson /* 295*88ecc943SGeorge Wilson * Similar to nvlist_print() but handles arrays slightly differently. 296*88ecc943SGeorge Wilson */ 297*88ecc943SGeorge Wilson void 298*88ecc943SGeorge Wilson dump_nvlist(nvlist_t *list, int indent) 299*88ecc943SGeorge Wilson { 300*88ecc943SGeorge Wilson nvpair_t *elem = NULL; 301*88ecc943SGeorge Wilson boolean_t bool_value; 302*88ecc943SGeorge Wilson nvlist_t *nvlist_value; 303*88ecc943SGeorge Wilson nvlist_t **nvlist_array_value; 304*88ecc943SGeorge Wilson uint_t i, count; 305*88ecc943SGeorge Wilson 306*88ecc943SGeorge Wilson if (list == NULL) { 307*88ecc943SGeorge Wilson return; 308*88ecc943SGeorge Wilson } 309*88ecc943SGeorge Wilson 310*88ecc943SGeorge Wilson while ((elem = nvlist_next_nvpair(list, elem)) != NULL) { 311*88ecc943SGeorge Wilson switch (nvpair_type(elem)) { 312*88ecc943SGeorge Wilson case DATA_TYPE_BOOLEAN_VALUE: 313*88ecc943SGeorge Wilson (void) nvpair_value_boolean_value(elem, &bool_value); 314*88ecc943SGeorge Wilson (void) printf("%*s%s: %s\n", indent, "", 315*88ecc943SGeorge Wilson nvpair_name(elem), bool_value ? "true" : "false"); 316*88ecc943SGeorge Wilson break; 317*88ecc943SGeorge Wilson 318*88ecc943SGeorge Wilson case DATA_TYPE_BYTE: 319*88ecc943SGeorge Wilson NVP(elem, byte, uchar_t, int, "%u"); 320*88ecc943SGeorge Wilson break; 321*88ecc943SGeorge Wilson 322*88ecc943SGeorge Wilson case DATA_TYPE_INT8: 323*88ecc943SGeorge Wilson NVP(elem, int8, int8_t, int, "%d"); 324*88ecc943SGeorge Wilson break; 325*88ecc943SGeorge Wilson 326*88ecc943SGeorge Wilson case DATA_TYPE_UINT8: 327*88ecc943SGeorge Wilson NVP(elem, uint8, uint8_t, int, "%u"); 328*88ecc943SGeorge Wilson break; 329*88ecc943SGeorge Wilson 330*88ecc943SGeorge Wilson case DATA_TYPE_INT16: 331*88ecc943SGeorge Wilson NVP(elem, int16, int16_t, int, "%d"); 332*88ecc943SGeorge Wilson break; 333*88ecc943SGeorge Wilson 334*88ecc943SGeorge Wilson case DATA_TYPE_UINT16: 335*88ecc943SGeorge Wilson NVP(elem, uint16, uint16_t, int, "%u"); 336*88ecc943SGeorge Wilson break; 337*88ecc943SGeorge Wilson 338*88ecc943SGeorge Wilson case DATA_TYPE_INT32: 339*88ecc943SGeorge Wilson NVP(elem, int32, int32_t, long, "%ld"); 340*88ecc943SGeorge Wilson break; 341*88ecc943SGeorge Wilson 342*88ecc943SGeorge Wilson case DATA_TYPE_UINT32: 343*88ecc943SGeorge Wilson NVP(elem, uint32, uint32_t, ulong_t, "%lu"); 344*88ecc943SGeorge Wilson break; 345*88ecc943SGeorge Wilson 346*88ecc943SGeorge Wilson case DATA_TYPE_INT64: 347*88ecc943SGeorge Wilson NVP(elem, int64, int64_t, longlong_t, "%lld"); 348*88ecc943SGeorge Wilson break; 349*88ecc943SGeorge Wilson 350*88ecc943SGeorge Wilson case DATA_TYPE_UINT64: 351*88ecc943SGeorge Wilson NVP(elem, uint64, uint64_t, u_longlong_t, "%llu"); 352*88ecc943SGeorge Wilson break; 353*88ecc943SGeorge Wilson 354*88ecc943SGeorge Wilson case DATA_TYPE_STRING: 355*88ecc943SGeorge Wilson NVP(elem, string, char *, char *, "'%s'"); 356*88ecc943SGeorge Wilson break; 357*88ecc943SGeorge Wilson 358*88ecc943SGeorge Wilson case DATA_TYPE_BYTE_ARRAY: 359*88ecc943SGeorge Wilson NVPA(elem, byte_array, uchar_t, int, "%u"); 360*88ecc943SGeorge Wilson break; 361*88ecc943SGeorge Wilson 362*88ecc943SGeorge Wilson case DATA_TYPE_INT8_ARRAY: 363*88ecc943SGeorge Wilson NVPA(elem, int8_array, int8_t, int, "%d"); 364*88ecc943SGeorge Wilson break; 365*88ecc943SGeorge Wilson 366*88ecc943SGeorge Wilson case DATA_TYPE_UINT8_ARRAY: 367*88ecc943SGeorge Wilson NVPA(elem, uint8_array, uint8_t, int, "%u"); 368*88ecc943SGeorge Wilson break; 369*88ecc943SGeorge Wilson 370*88ecc943SGeorge Wilson case DATA_TYPE_INT16_ARRAY: 371*88ecc943SGeorge Wilson NVPA(elem, int16_array, int16_t, int, "%d"); 372*88ecc943SGeorge Wilson break; 373*88ecc943SGeorge Wilson 374*88ecc943SGeorge Wilson case DATA_TYPE_UINT16_ARRAY: 375*88ecc943SGeorge Wilson NVPA(elem, uint16_array, uint16_t, int, "%u"); 376*88ecc943SGeorge Wilson break; 377*88ecc943SGeorge Wilson 378*88ecc943SGeorge Wilson case DATA_TYPE_INT32_ARRAY: 379*88ecc943SGeorge Wilson NVPA(elem, int32_array, int32_t, long, "%ld"); 380*88ecc943SGeorge Wilson break; 381*88ecc943SGeorge Wilson 382*88ecc943SGeorge Wilson case DATA_TYPE_UINT32_ARRAY: 383*88ecc943SGeorge Wilson NVPA(elem, uint32_array, uint32_t, ulong_t, "%lu"); 384*88ecc943SGeorge Wilson break; 385*88ecc943SGeorge Wilson 386*88ecc943SGeorge Wilson case DATA_TYPE_INT64_ARRAY: 387*88ecc943SGeorge Wilson NVPA(elem, int64_array, int64_t, longlong_t, "%lld"); 388*88ecc943SGeorge Wilson break; 389*88ecc943SGeorge Wilson 390*88ecc943SGeorge Wilson case DATA_TYPE_UINT64_ARRAY: 391*88ecc943SGeorge Wilson NVPA(elem, uint64_array, uint64_t, u_longlong_t, 392*88ecc943SGeorge Wilson "%llu"); 393*88ecc943SGeorge Wilson break; 394*88ecc943SGeorge Wilson 395*88ecc943SGeorge Wilson case DATA_TYPE_STRING_ARRAY: 396*88ecc943SGeorge Wilson NVPA(elem, string_array, char *, char *, "'%s'"); 397*88ecc943SGeorge Wilson break; 398*88ecc943SGeorge Wilson 399*88ecc943SGeorge Wilson case DATA_TYPE_NVLIST: 400*88ecc943SGeorge Wilson (void) nvpair_value_nvlist(elem, &nvlist_value); 401*88ecc943SGeorge Wilson (void) printf("%*s%s:\n", indent, "", 402*88ecc943SGeorge Wilson nvpair_name(elem)); 403*88ecc943SGeorge Wilson dump_nvlist(nvlist_value, indent + 4); 404*88ecc943SGeorge Wilson break; 405*88ecc943SGeorge Wilson 406*88ecc943SGeorge Wilson case DATA_TYPE_NVLIST_ARRAY: 407*88ecc943SGeorge Wilson (void) nvpair_value_nvlist_array(elem, 408*88ecc943SGeorge Wilson &nvlist_array_value, &count); 409*88ecc943SGeorge Wilson for (i = 0; i < count; i++) { 410*88ecc943SGeorge Wilson (void) printf("%*s%s[%u]:\n", indent, "", 411*88ecc943SGeorge Wilson nvpair_name(elem), i); 412*88ecc943SGeorge Wilson dump_nvlist(nvlist_array_value[i], indent + 4); 413*88ecc943SGeorge Wilson } 414*88ecc943SGeorge Wilson break; 415*88ecc943SGeorge Wilson 416*88ecc943SGeorge Wilson default: 417*88ecc943SGeorge Wilson (void) printf(dgettext(TEXT_DOMAIN, "bad config type " 418*88ecc943SGeorge Wilson "%d for %s\n"), nvpair_type(elem), 419*88ecc943SGeorge Wilson nvpair_name(elem)); 420*88ecc943SGeorge Wilson } 421*88ecc943SGeorge Wilson } 422*88ecc943SGeorge Wilson } 423*88ecc943SGeorge Wilson 424602ca9eaScth /* 425602ca9eaScth * Determine if string 'value' matches 'nvp' value. The 'value' string is 426602ca9eaScth * converted, depending on the type of 'nvp', prior to match. For numeric 427602ca9eaScth * types, a radix independent sscanf conversion of 'value' is used. If 'nvp' 428602ca9eaScth * is an array type, 'ai' is the index into the array against which we are 429602ca9eaScth * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass 430602ca9eaScth * in a regex_t compilation of value in 'value_regex' to trigger regular 431602ca9eaScth * expression string match instead of simple strcmp(). 432602ca9eaScth * 433602ca9eaScth * Return 1 on match, 0 on no-match, and -1 on error. If the error is 434602ca9eaScth * related to value syntax error and 'ep' is non-NULL, *ep will point into 435602ca9eaScth * the 'value' string at the location where the error exists. 436602ca9eaScth * 437602ca9eaScth * NOTE: It may be possible to move the non-regex_t version of this into 438602ca9eaScth * common code used by library/kernel/boot. 439602ca9eaScth */ 440602ca9eaScth int 441602ca9eaScth nvpair_value_match_regex(nvpair_t *nvp, int ai, 442602ca9eaScth char *value, regex_t *value_regex, char **ep) 443602ca9eaScth { 444602ca9eaScth char *evalue; 445602ca9eaScth uint_t a_len; 446602ca9eaScth int sr; 447602ca9eaScth 448602ca9eaScth if (ep) 449602ca9eaScth *ep = NULL; 450602ca9eaScth 451602ca9eaScth if ((nvp == NULL) || (value == NULL)) 452602ca9eaScth return (-1); /* error fail match - invalid args */ 453602ca9eaScth 454602ca9eaScth /* make sure array and index combination make sense */ 455602ca9eaScth if ((nvpair_type_is_array(nvp) && (ai < 0)) || 456602ca9eaScth (!nvpair_type_is_array(nvp) && (ai >= 0))) 457602ca9eaScth return (-1); /* error fail match - bad index */ 458602ca9eaScth 459602ca9eaScth /* non-string values should be single 'chunk' */ 460602ca9eaScth if ((nvpair_type(nvp) != DATA_TYPE_STRING) && 461602ca9eaScth (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) { 462602ca9eaScth value += strspn(value, " \t"); 463602ca9eaScth evalue = value + strcspn(value, " \t"); 464602ca9eaScth if (*evalue) { 465602ca9eaScth if (ep) 466602ca9eaScth *ep = evalue; 467602ca9eaScth return (-1); /* error fail match - syntax */ 468602ca9eaScth } 469602ca9eaScth } 470602ca9eaScth 471602ca9eaScth sr = EOF; 472602ca9eaScth switch (nvpair_type(nvp)) { 473602ca9eaScth case DATA_TYPE_STRING: { 474602ca9eaScth char *val; 475602ca9eaScth 476602ca9eaScth /* check string value for match */ 477602ca9eaScth if (nvpair_value_string(nvp, &val) == 0) { 478602ca9eaScth if (value_regex) { 479602ca9eaScth if (regexec(value_regex, val, 480602ca9eaScth (size_t)0, NULL, 0) == 0) 481602ca9eaScth return (1); /* match */ 482602ca9eaScth } else { 483602ca9eaScth if (strcmp(value, val) == 0) 484602ca9eaScth return (1); /* match */ 485602ca9eaScth } 486602ca9eaScth } 487602ca9eaScth break; 488602ca9eaScth } 489602ca9eaScth case DATA_TYPE_STRING_ARRAY: { 490602ca9eaScth char **val_array; 491602ca9eaScth 492602ca9eaScth /* check indexed string value of array for match */ 493602ca9eaScth if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) && 494602ca9eaScth (ai < a_len)) { 495602ca9eaScth if (value_regex) { 496602ca9eaScth if (regexec(value_regex, val_array[ai], 497602ca9eaScth (size_t)0, NULL, 0) == 0) 498602ca9eaScth return (1); 499602ca9eaScth } else { 500602ca9eaScth if (strcmp(value, val_array[ai]) == 0) 501602ca9eaScth return (1); 502602ca9eaScth } 503602ca9eaScth } 504602ca9eaScth break; 505602ca9eaScth } 506602ca9eaScth case DATA_TYPE_BYTE: { 507602ca9eaScth uchar_t val, val_arg; 508602ca9eaScth 509602ca9eaScth /* scanf uchar_t from value and check for match */ 510602ca9eaScth sr = sscanf(value, "%c", &val_arg); 511602ca9eaScth if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) && 512602ca9eaScth (val == val_arg)) 513602ca9eaScth return (1); 514602ca9eaScth break; 515602ca9eaScth } 516602ca9eaScth case DATA_TYPE_BYTE_ARRAY: { 517602ca9eaScth uchar_t *val_array, val_arg; 518602ca9eaScth 519602ca9eaScth 520602ca9eaScth /* check indexed value of array for match */ 521602ca9eaScth sr = sscanf(value, "%c", &val_arg); 522602ca9eaScth if ((sr == 1) && 523602ca9eaScth (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) && 524602ca9eaScth (ai < a_len) && 525602ca9eaScth (val_array[ai] == val_arg)) 526602ca9eaScth return (1); 527602ca9eaScth break; 528602ca9eaScth } 529602ca9eaScth case DATA_TYPE_INT8: { 530602ca9eaScth int8_t val, val_arg; 531602ca9eaScth 532602ca9eaScth /* scanf int8_t from value and check for match */ 533602ca9eaScth sr = sscanf(value, "%"SCNi8, &val_arg); 534602ca9eaScth if ((sr == 1) && 535602ca9eaScth (nvpair_value_int8(nvp, &val) == 0) && 536602ca9eaScth (val == val_arg)) 537602ca9eaScth return (1); 538602ca9eaScth break; 539602ca9eaScth } 540602ca9eaScth case DATA_TYPE_INT8_ARRAY: { 541602ca9eaScth int8_t *val_array, val_arg; 542602ca9eaScth 543602ca9eaScth /* check indexed value of array for match */ 544602ca9eaScth sr = sscanf(value, "%"SCNi8, &val_arg); 545602ca9eaScth if ((sr == 1) && 546602ca9eaScth (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) && 547602ca9eaScth (ai < a_len) && 548602ca9eaScth (val_array[ai] == val_arg)) 549602ca9eaScth return (1); 550602ca9eaScth break; 551602ca9eaScth } 552602ca9eaScth case DATA_TYPE_UINT8: { 553602ca9eaScth uint8_t val, val_arg; 554602ca9eaScth 555602ca9eaScth /* scanf uint8_t from value and check for match */ 556602ca9eaScth sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg); 557602ca9eaScth if ((sr == 1) && 558602ca9eaScth (nvpair_value_uint8(nvp, &val) == 0) && 559602ca9eaScth (val == val_arg)) 560602ca9eaScth return (1); 561602ca9eaScth break; 562602ca9eaScth } 563602ca9eaScth case DATA_TYPE_UINT8_ARRAY: { 564602ca9eaScth uint8_t *val_array, val_arg; 565602ca9eaScth 566602ca9eaScth /* check indexed value of array for match */ 567602ca9eaScth sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg); 568602ca9eaScth if ((sr == 1) && 569602ca9eaScth (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) && 570602ca9eaScth (ai < a_len) && 571602ca9eaScth (val_array[ai] == val_arg)) 572602ca9eaScth return (1); 573602ca9eaScth break; 574602ca9eaScth } 575602ca9eaScth case DATA_TYPE_INT16: { 576602ca9eaScth int16_t val, val_arg; 577602ca9eaScth 578602ca9eaScth /* scanf int16_t from value and check for match */ 579602ca9eaScth sr = sscanf(value, "%"SCNi16, &val_arg); 580602ca9eaScth if ((sr == 1) && 581602ca9eaScth (nvpair_value_int16(nvp, &val) == 0) && 582602ca9eaScth (val == val_arg)) 583602ca9eaScth return (1); 584602ca9eaScth break; 585602ca9eaScth } 586602ca9eaScth case DATA_TYPE_INT16_ARRAY: { 587602ca9eaScth int16_t *val_array, val_arg; 588602ca9eaScth 589602ca9eaScth /* check indexed value of array for match */ 590602ca9eaScth sr = sscanf(value, "%"SCNi16, &val_arg); 591602ca9eaScth if ((sr == 1) && 592602ca9eaScth (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) && 593602ca9eaScth (ai < a_len) && 594602ca9eaScth (val_array[ai] == val_arg)) 595602ca9eaScth return (1); 596602ca9eaScth break; 597602ca9eaScth } 598602ca9eaScth case DATA_TYPE_UINT16: { 599602ca9eaScth uint16_t val, val_arg; 600602ca9eaScth 601602ca9eaScth /* scanf uint16_t from value and check for match */ 602602ca9eaScth sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg); 603602ca9eaScth if ((sr == 1) && 604602ca9eaScth (nvpair_value_uint16(nvp, &val) == 0) && 605602ca9eaScth (val == val_arg)) 606602ca9eaScth return (1); 607602ca9eaScth break; 608602ca9eaScth } 609602ca9eaScth case DATA_TYPE_UINT16_ARRAY: { 610602ca9eaScth uint16_t *val_array, val_arg; 611602ca9eaScth 612602ca9eaScth /* check indexed value of array for match */ 613602ca9eaScth sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg); 614602ca9eaScth if ((sr == 1) && 615602ca9eaScth (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) && 616602ca9eaScth (ai < a_len) && 617602ca9eaScth (val_array[ai] == val_arg)) 618602ca9eaScth return (1); 619602ca9eaScth break; 620602ca9eaScth } 621602ca9eaScth case DATA_TYPE_INT32: { 622602ca9eaScth int32_t val, val_arg; 623602ca9eaScth 624602ca9eaScth /* scanf int32_t from value and check for match */ 625602ca9eaScth sr = sscanf(value, "%"SCNi32, &val_arg); 626602ca9eaScth if ((sr == 1) && 627602ca9eaScth (nvpair_value_int32(nvp, &val) == 0) && 628602ca9eaScth (val == val_arg)) 629602ca9eaScth return (1); 630602ca9eaScth break; 631602ca9eaScth } 632602ca9eaScth case DATA_TYPE_INT32_ARRAY: { 633602ca9eaScth int32_t *val_array, val_arg; 634602ca9eaScth 635602ca9eaScth /* check indexed value of array for match */ 636602ca9eaScth sr = sscanf(value, "%"SCNi32, &val_arg); 637602ca9eaScth if ((sr == 1) && 638602ca9eaScth (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) && 639602ca9eaScth (ai < a_len) && 640602ca9eaScth (val_array[ai] == val_arg)) 641602ca9eaScth return (1); 642602ca9eaScth break; 643602ca9eaScth } 644602ca9eaScth case DATA_TYPE_UINT32: { 645602ca9eaScth uint32_t val, val_arg; 646602ca9eaScth 647602ca9eaScth /* scanf uint32_t from value and check for match */ 648602ca9eaScth sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg); 649602ca9eaScth if ((sr == 1) && 650602ca9eaScth (nvpair_value_uint32(nvp, &val) == 0) && 651602ca9eaScth (val == val_arg)) 652602ca9eaScth return (1); 653602ca9eaScth break; 654602ca9eaScth } 655602ca9eaScth case DATA_TYPE_UINT32_ARRAY: { 656602ca9eaScth uint32_t *val_array, val_arg; 657602ca9eaScth 658602ca9eaScth /* check indexed value of array for match */ 659602ca9eaScth sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg); 660602ca9eaScth if ((sr == 1) && 661602ca9eaScth (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) && 662602ca9eaScth (ai < a_len) && 663602ca9eaScth (val_array[ai] == val_arg)) 664602ca9eaScth return (1); 665602ca9eaScth break; 666602ca9eaScth } 667602ca9eaScth case DATA_TYPE_INT64: { 668602ca9eaScth int64_t val, val_arg; 669602ca9eaScth 670602ca9eaScth /* scanf int64_t from value and check for match */ 671602ca9eaScth sr = sscanf(value, "%"SCNi64, &val_arg); 672602ca9eaScth if ((sr == 1) && 673602ca9eaScth (nvpair_value_int64(nvp, &val) == 0) && 674602ca9eaScth (val == val_arg)) 675602ca9eaScth return (1); 676602ca9eaScth break; 677602ca9eaScth } 678602ca9eaScth case DATA_TYPE_INT64_ARRAY: { 679602ca9eaScth int64_t *val_array, val_arg; 680602ca9eaScth 681602ca9eaScth /* check indexed value of array for match */ 682602ca9eaScth sr = sscanf(value, "%"SCNi64, &val_arg); 683602ca9eaScth if ((sr == 1) && 684602ca9eaScth (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) && 685602ca9eaScth (ai < a_len) && 686602ca9eaScth (val_array[ai] == val_arg)) 687602ca9eaScth return (1); 688602ca9eaScth break; 689602ca9eaScth } 690602ca9eaScth case DATA_TYPE_UINT64: { 691602ca9eaScth uint64_t val_arg, val; 692602ca9eaScth 693602ca9eaScth /* scanf uint64_t from value and check for match */ 694602ca9eaScth sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg); 695602ca9eaScth if ((sr == 1) && 696602ca9eaScth (nvpair_value_uint64(nvp, &val) == 0) && 697602ca9eaScth (val == val_arg)) 698602ca9eaScth return (1); 699602ca9eaScth break; 700602ca9eaScth } 701602ca9eaScth case DATA_TYPE_UINT64_ARRAY: { 702602ca9eaScth uint64_t *val_array, val_arg; 703602ca9eaScth 704602ca9eaScth /* check indexed value of array for match */ 705602ca9eaScth sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg); 706602ca9eaScth if ((sr == 1) && 707602ca9eaScth (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) && 708602ca9eaScth (ai < a_len) && 709602ca9eaScth (val_array[ai] == val_arg)) 710602ca9eaScth return (1); 711602ca9eaScth break; 712602ca9eaScth } 713602ca9eaScth case DATA_TYPE_BOOLEAN_VALUE: { 714602ca9eaScth boolean_t val, val_arg; 715602ca9eaScth 716602ca9eaScth /* scanf boolean_t from value and check for match */ 717602ca9eaScth sr = sscanf(value, "%"SCNi32, &val_arg); 718602ca9eaScth if ((sr == 1) && 719602ca9eaScth (nvpair_value_boolean_value(nvp, &val) == 0) && 720602ca9eaScth (val == val_arg)) 721602ca9eaScth return (1); 722602ca9eaScth break; 723602ca9eaScth } 724602ca9eaScth case DATA_TYPE_BOOLEAN_ARRAY: { 725602ca9eaScth boolean_t *val_array, val_arg; 726602ca9eaScth 727602ca9eaScth /* check indexed value of array for match */ 728602ca9eaScth sr = sscanf(value, "%"SCNi32, &val_arg); 729602ca9eaScth if ((sr == 1) && 730602ca9eaScth (nvpair_value_boolean_array(nvp, 731602ca9eaScth &val_array, &a_len) == 0) && 732602ca9eaScth (ai < a_len) && 733602ca9eaScth (val_array[ai] == val_arg)) 734602ca9eaScth return (1); 735602ca9eaScth break; 736602ca9eaScth } 737602ca9eaScth case DATA_TYPE_HRTIME: 738602ca9eaScth case DATA_TYPE_NVLIST: 739602ca9eaScth case DATA_TYPE_NVLIST_ARRAY: 740602ca9eaScth case DATA_TYPE_BOOLEAN: 741825ba0f2Srobj case DATA_TYPE_DOUBLE: 742602ca9eaScth case DATA_TYPE_UNKNOWN: 743602ca9eaScth default: 744602ca9eaScth /* 745602ca9eaScth * unknown/unsupported data type 746602ca9eaScth */ 747602ca9eaScth return (-1); /* error fail match */ 748602ca9eaScth } 749602ca9eaScth 750602ca9eaScth /* 751602ca9eaScth * check to see if sscanf failed conversion, return approximate 752602ca9eaScth * pointer to problem 753602ca9eaScth */ 754602ca9eaScth if (sr != 1) { 755602ca9eaScth if (ep) 756602ca9eaScth *ep = value; 757602ca9eaScth return (-1); /* error fail match - syntax */ 758602ca9eaScth } 759602ca9eaScth 760602ca9eaScth return (0); /* fail match */ 761602ca9eaScth } 762602ca9eaScth 763602ca9eaScth int 764602ca9eaScth nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep) 765602ca9eaScth { 766602ca9eaScth return (nvpair_value_match_regex(nvp, ai, value, NULL, ep)); 767602ca9eaScth } 768