libnvpair.c revision 1.1.1.2.12.2 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.1.1.2 haad * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 1.1 haad * Use is subject to license terms.
24 1.1 haad */
25 1.1 haad
26 1.1 haad #include <unistd.h>
27 1.1 haad #include <strings.h>
28 1.1.1.2 haad #include <libintl.h>
29 1.1 haad #include <sys/types.h>
30 1.1 haad #include <sys/inttypes.h>
31 1.1 haad #include "libnvpair.h"
32 1.1 haad
33 1.1 haad /*
34 1.1 haad * libnvpair - A tools library for manipulating <name, value> pairs.
35 1.1 haad *
36 1.1 haad * This library provides routines packing an unpacking nv pairs
37 1.1 haad * for transporting data across process boundaries, transporting
38 1.1 haad * between kernel and userland, and possibly saving onto disk files.
39 1.1 haad */
40 1.1 haad
41 1.1 haad static void
42 1.1 haad indent(FILE *fp, int depth)
43 1.1 haad {
44 1.1 haad while (depth-- > 0)
45 1.1 haad (void) fprintf(fp, "\t");
46 1.1 haad }
47 1.1 haad
48 1.1 haad /*
49 1.1 haad * nvlist_print - Prints elements in an event buffer
50 1.1 haad */
51 1.1 haad static
52 1.1 haad void
53 1.1 haad nvlist_print_with_indent(FILE *fp, nvlist_t *nvl, int depth)
54 1.1 haad {
55 1.1 haad int i;
56 1.1 haad char *name;
57 1.1 haad uint_t nelem;
58 1.1 haad nvpair_t *nvp;
59 1.1 haad
60 1.1 haad if (nvl == NULL)
61 1.1 haad return;
62 1.1 haad
63 1.1 haad indent(fp, depth);
64 1.1 haad (void) fprintf(fp, "nvlist version: %d\n", NVL_VERSION(nvl));
65 1.1 haad
66 1.1 haad nvp = nvlist_next_nvpair(nvl, NULL);
67 1.1 haad
68 1.1 haad while (nvp) {
69 1.1 haad data_type_t type = nvpair_type(nvp);
70 1.1 haad
71 1.1 haad indent(fp, depth);
72 1.1 haad name = nvpair_name(nvp);
73 1.1 haad (void) fprintf(fp, "\t%s =", name);
74 1.1 haad nelem = 0;
75 1.1 haad switch (type) {
76 1.1 haad case DATA_TYPE_BOOLEAN: {
77 1.1 haad (void) fprintf(fp, " 1");
78 1.1 haad break;
79 1.1 haad }
80 1.1 haad case DATA_TYPE_BOOLEAN_VALUE: {
81 1.1 haad boolean_t val;
82 1.1 haad (void) nvpair_value_boolean_value(nvp, &val);
83 1.1 haad (void) fprintf(fp, " %d", val);
84 1.1 haad break;
85 1.1 haad }
86 1.1 haad case DATA_TYPE_BYTE: {
87 1.1 haad uchar_t val;
88 1.1 haad (void) nvpair_value_byte(nvp, &val);
89 1.1 haad (void) fprintf(fp, " 0x%2.2x", val);
90 1.1 haad break;
91 1.1 haad }
92 1.1 haad case DATA_TYPE_INT8: {
93 1.1 haad int8_t val;
94 1.1 haad (void) nvpair_value_int8(nvp, &val);
95 1.1 haad (void) fprintf(fp, " %d", val);
96 1.1 haad break;
97 1.1 haad }
98 1.1 haad case DATA_TYPE_UINT8: {
99 1.1 haad uint8_t val;
100 1.1 haad (void) nvpair_value_uint8(nvp, &val);
101 1.1 haad (void) fprintf(fp, " 0x%x", val);
102 1.1 haad break;
103 1.1 haad }
104 1.1 haad case DATA_TYPE_INT16: {
105 1.1 haad int16_t val;
106 1.1 haad (void) nvpair_value_int16(nvp, &val);
107 1.1 haad (void) fprintf(fp, " %d", val);
108 1.1 haad break;
109 1.1 haad }
110 1.1 haad case DATA_TYPE_UINT16: {
111 1.1 haad uint16_t val;
112 1.1 haad (void) nvpair_value_uint16(nvp, &val);
113 1.1 haad (void) fprintf(fp, " 0x%x", val);
114 1.1 haad break;
115 1.1 haad }
116 1.1 haad case DATA_TYPE_INT32: {
117 1.1 haad int32_t val;
118 1.1 haad (void) nvpair_value_int32(nvp, &val);
119 1.1 haad (void) fprintf(fp, " %d", val);
120 1.1 haad break;
121 1.1 haad }
122 1.1 haad case DATA_TYPE_UINT32: {
123 1.1 haad uint32_t val;
124 1.1 haad (void) nvpair_value_uint32(nvp, &val);
125 1.1 haad (void) fprintf(fp, " 0x%x", val);
126 1.1 haad break;
127 1.1 haad }
128 1.1 haad case DATA_TYPE_INT64: {
129 1.1 haad int64_t val;
130 1.1 haad (void) nvpair_value_int64(nvp, &val);
131 1.1.1.2.12.2 tls (void) fprintf(fp, " %" PRId64 , val);
132 1.1 haad break;
133 1.1 haad }
134 1.1 haad case DATA_TYPE_UINT64: {
135 1.1 haad uint64_t val;
136 1.1 haad (void) nvpair_value_uint64(nvp, &val);
137 1.1.1.2.12.2 tls (void) fprintf(fp, " 0x%" PRIx64, val);
138 1.1 haad break;
139 1.1 haad }
140 1.1 haad case DATA_TYPE_DOUBLE: {
141 1.1 haad double val;
142 1.1 haad (void) nvpair_value_double(nvp, &val);
143 1.1.1.2.12.1 tls (void) fprintf(fp, " 0x%f", val);
144 1.1 haad break;
145 1.1 haad }
146 1.1 haad case DATA_TYPE_STRING: {
147 1.1 haad char *val;
148 1.1 haad (void) nvpair_value_string(nvp, &val);
149 1.1 haad (void) fprintf(fp, " %s", val);
150 1.1 haad break;
151 1.1 haad }
152 1.1 haad case DATA_TYPE_BOOLEAN_ARRAY: {
153 1.1 haad boolean_t *val;
154 1.1 haad (void) nvpair_value_boolean_array(nvp, &val, &nelem);
155 1.1 haad for (i = 0; i < nelem; i++)
156 1.1 haad (void) fprintf(fp, " %d", val[i]);
157 1.1 haad break;
158 1.1 haad }
159 1.1 haad case DATA_TYPE_BYTE_ARRAY: {
160 1.1 haad uchar_t *val;
161 1.1 haad (void) nvpair_value_byte_array(nvp, &val, &nelem);
162 1.1 haad for (i = 0; i < nelem; i++)
163 1.1 haad (void) fprintf(fp, " 0x%2.2x", val[i]);
164 1.1 haad break;
165 1.1 haad }
166 1.1 haad case DATA_TYPE_INT8_ARRAY: {
167 1.1 haad int8_t *val;
168 1.1 haad (void) nvpair_value_int8_array(nvp, &val, &nelem);
169 1.1 haad for (i = 0; i < nelem; i++)
170 1.1 haad (void) fprintf(fp, " %d", val[i]);
171 1.1 haad break;
172 1.1 haad }
173 1.1 haad case DATA_TYPE_UINT8_ARRAY: {
174 1.1 haad uint8_t *val;
175 1.1 haad (void) nvpair_value_uint8_array(nvp, &val, &nelem);
176 1.1 haad for (i = 0; i < nelem; i++)
177 1.1 haad (void) fprintf(fp, " 0x%x", val[i]);
178 1.1 haad break;
179 1.1 haad }
180 1.1 haad case DATA_TYPE_INT16_ARRAY: {
181 1.1 haad int16_t *val;
182 1.1 haad (void) nvpair_value_int16_array(nvp, &val, &nelem);
183 1.1 haad for (i = 0; i < nelem; i++)
184 1.1 haad (void) fprintf(fp, " %d", val[i]);
185 1.1 haad break;
186 1.1 haad }
187 1.1 haad case DATA_TYPE_UINT16_ARRAY: {
188 1.1 haad uint16_t *val;
189 1.1 haad (void) nvpair_value_uint16_array(nvp, &val, &nelem);
190 1.1 haad for (i = 0; i < nelem; i++)
191 1.1 haad (void) fprintf(fp, " 0x%x", val[i]);
192 1.1 haad break;
193 1.1 haad }
194 1.1 haad case DATA_TYPE_INT32_ARRAY: {
195 1.1 haad int32_t *val;
196 1.1 haad (void) nvpair_value_int32_array(nvp, &val, &nelem);
197 1.1 haad for (i = 0; i < nelem; i++)
198 1.1 haad (void) fprintf(fp, " %d", val[i]);
199 1.1 haad break;
200 1.1 haad }
201 1.1 haad case DATA_TYPE_UINT32_ARRAY: {
202 1.1 haad uint32_t *val;
203 1.1 haad (void) nvpair_value_uint32_array(nvp, &val, &nelem);
204 1.1 haad for (i = 0; i < nelem; i++)
205 1.1 haad (void) fprintf(fp, " 0x%x", val[i]);
206 1.1 haad break;
207 1.1 haad }
208 1.1 haad case DATA_TYPE_INT64_ARRAY: {
209 1.1 haad int64_t *val;
210 1.1 haad (void) nvpair_value_int64_array(nvp, &val, &nelem);
211 1.1 haad for (i = 0; i < nelem; i++)
212 1.1.1.2.12.2 tls (void) fprintf(fp, " %" PRId64, val[i]);
213 1.1 haad break;
214 1.1 haad }
215 1.1 haad case DATA_TYPE_UINT64_ARRAY: {
216 1.1 haad uint64_t *val;
217 1.1 haad (void) nvpair_value_uint64_array(nvp, &val, &nelem);
218 1.1 haad for (i = 0; i < nelem; i++)
219 1.1.1.2.12.2 tls (void) fprintf(fp, " 0x%" PRIx64, val[i]);
220 1.1 haad break;
221 1.1 haad }
222 1.1 haad case DATA_TYPE_STRING_ARRAY: {
223 1.1 haad char **val;
224 1.1 haad (void) nvpair_value_string_array(nvp, &val, &nelem);
225 1.1 haad for (i = 0; i < nelem; i++)
226 1.1 haad (void) fprintf(fp, " %s", val[i]);
227 1.1 haad break;
228 1.1 haad }
229 1.1 haad case DATA_TYPE_HRTIME: {
230 1.1 haad hrtime_t val;
231 1.1 haad (void) nvpair_value_hrtime(nvp, &val);
232 1.1.1.2.12.2 tls (void) fprintf(fp, " 0x%jx", (intmax_t)val);
233 1.1 haad break;
234 1.1 haad }
235 1.1 haad case DATA_TYPE_NVLIST: {
236 1.1 haad nvlist_t *val;
237 1.1 haad (void) nvpair_value_nvlist(nvp, &val);
238 1.1 haad (void) fprintf(fp, " (embedded nvlist)\n");
239 1.1 haad nvlist_print_with_indent(fp, val, depth + 1);
240 1.1 haad indent(fp, depth + 1);
241 1.1 haad (void) fprintf(fp, "(end %s)\n", name);
242 1.1 haad break;
243 1.1 haad }
244 1.1 haad case DATA_TYPE_NVLIST_ARRAY: {
245 1.1 haad nvlist_t **val;
246 1.1 haad (void) nvpair_value_nvlist_array(nvp, &val, &nelem);
247 1.1 haad (void) fprintf(fp, " (array of embedded nvlists)\n");
248 1.1 haad for (i = 0; i < nelem; i++) {
249 1.1 haad indent(fp, depth + 1);
250 1.1 haad (void) fprintf(fp,
251 1.1 haad "(start %s[%d])\n", name, i);
252 1.1 haad nvlist_print_with_indent(fp, val[i], depth + 1);
253 1.1 haad indent(fp, depth + 1);
254 1.1 haad (void) fprintf(fp, "(end %s[%d])\n", name, i);
255 1.1 haad }
256 1.1 haad break;
257 1.1 haad }
258 1.1 haad default:
259 1.1 haad (void) fprintf(fp, " unknown data type (%d)", type);
260 1.1 haad break;
261 1.1 haad }
262 1.1 haad (void) fprintf(fp, "\n");
263 1.1 haad nvp = nvlist_next_nvpair(nvl, nvp);
264 1.1 haad }
265 1.1 haad }
266 1.1 haad
267 1.1 haad void
268 1.1 haad nvlist_print(FILE *fp, nvlist_t *nvl)
269 1.1 haad {
270 1.1 haad nvlist_print_with_indent(fp, nvl, 0);
271 1.1 haad }
272 1.1 haad
273 1.1.1.2 haad
274 1.1.1.2 haad #define NVP(elem, type, vtype, ptype, format) { \
275 1.1.1.2 haad vtype value; \
276 1.1.1.2 haad \
277 1.1.1.2 haad (void) nvpair_value_##type(elem, &value); \
278 1.1.1.2 haad (void) printf("%*s%s: " format "\n", indent, "", \
279 1.1.1.2 haad nvpair_name(elem), (ptype)value); \
280 1.1.1.2 haad }
281 1.1.1.2 haad
282 1.1.1.2 haad #define NVPA(elem, type, vtype, ptype, format) { \
283 1.1.1.2 haad uint_t i, count; \
284 1.1.1.2 haad vtype *value; \
285 1.1.1.2 haad \
286 1.1.1.2 haad (void) nvpair_value_##type(elem, &value, &count); \
287 1.1.1.2 haad for (i = 0; i < count; i++) { \
288 1.1.1.2 haad (void) printf("%*s%s[%d]: " format "\n", indent, "", \
289 1.1.1.2 haad nvpair_name(elem), i, (ptype)value[i]); \
290 1.1.1.2 haad } \
291 1.1.1.2 haad }
292 1.1.1.2 haad
293 1.1.1.2 haad /*
294 1.1.1.2 haad * Similar to nvlist_print() but handles arrays slightly differently.
295 1.1.1.2 haad */
296 1.1.1.2 haad void
297 1.1.1.2 haad dump_nvlist(nvlist_t *list, int indent)
298 1.1.1.2 haad {
299 1.1.1.2 haad nvpair_t *elem = NULL;
300 1.1.1.2 haad boolean_t bool_value;
301 1.1.1.2 haad nvlist_t *nvlist_value;
302 1.1.1.2 haad nvlist_t **nvlist_array_value;
303 1.1.1.2 haad uint_t i, count;
304 1.1.1.2 haad
305 1.1.1.2 haad if (list == NULL) {
306 1.1.1.2 haad return;
307 1.1.1.2 haad }
308 1.1.1.2 haad
309 1.1.1.2 haad while ((elem = nvlist_next_nvpair(list, elem)) != NULL) {
310 1.1.1.2 haad switch (nvpair_type(elem)) {
311 1.1.1.2 haad case DATA_TYPE_BOOLEAN_VALUE:
312 1.1.1.2 haad (void) nvpair_value_boolean_value(elem, &bool_value);
313 1.1.1.2 haad (void) printf("%*s%s: %s\n", indent, "",
314 1.1.1.2 haad nvpair_name(elem), bool_value ? "true" : "false");
315 1.1.1.2 haad break;
316 1.1.1.2 haad
317 1.1.1.2 haad case DATA_TYPE_BYTE:
318 1.1.1.2 haad NVP(elem, byte, uchar_t, int, "%u");
319 1.1.1.2 haad break;
320 1.1.1.2 haad
321 1.1.1.2 haad case DATA_TYPE_INT8:
322 1.1.1.2 haad NVP(elem, int8, int8_t, int, "%d");
323 1.1.1.2 haad break;
324 1.1.1.2 haad
325 1.1.1.2 haad case DATA_TYPE_UINT8:
326 1.1.1.2 haad NVP(elem, uint8, uint8_t, int, "%u");
327 1.1.1.2 haad break;
328 1.1.1.2 haad
329 1.1.1.2 haad case DATA_TYPE_INT16:
330 1.1.1.2 haad NVP(elem, int16, int16_t, int, "%d");
331 1.1.1.2 haad break;
332 1.1.1.2 haad
333 1.1.1.2 haad case DATA_TYPE_UINT16:
334 1.1.1.2 haad NVP(elem, uint16, uint16_t, int, "%u");
335 1.1.1.2 haad break;
336 1.1.1.2 haad
337 1.1.1.2 haad case DATA_TYPE_INT32:
338 1.1.1.2 haad NVP(elem, int32, int32_t, long, "%ld");
339 1.1.1.2 haad break;
340 1.1.1.2 haad
341 1.1.1.2 haad case DATA_TYPE_UINT32:
342 1.1.1.2 haad NVP(elem, uint32, uint32_t, ulong_t, "%lu");
343 1.1.1.2 haad break;
344 1.1.1.2 haad
345 1.1.1.2 haad case DATA_TYPE_INT64:
346 1.1.1.2.12.2 tls NVP(elem, int64, int64_t, int64_t, "%" PRIx64);
347 1.1.1.2 haad break;
348 1.1.1.2 haad
349 1.1.1.2 haad case DATA_TYPE_UINT64:
350 1.1.1.2.12.2 tls NVP(elem, uint64, uint64_t, uint64_t, "%" PRIu64);
351 1.1.1.2 haad break;
352 1.1.1.2 haad
353 1.1.1.2 haad case DATA_TYPE_STRING:
354 1.1.1.2 haad NVP(elem, string, char *, char *, "'%s'");
355 1.1.1.2 haad break;
356 1.1.1.2 haad
357 1.1.1.2 haad case DATA_TYPE_BYTE_ARRAY:
358 1.1.1.2 haad NVPA(elem, byte_array, uchar_t, int, "%u");
359 1.1.1.2 haad break;
360 1.1.1.2 haad
361 1.1.1.2 haad case DATA_TYPE_INT8_ARRAY:
362 1.1.1.2 haad NVPA(elem, int8_array, int8_t, int, "%d");
363 1.1.1.2 haad break;
364 1.1.1.2 haad
365 1.1.1.2 haad case DATA_TYPE_UINT8_ARRAY:
366 1.1.1.2 haad NVPA(elem, uint8_array, uint8_t, int, "%u");
367 1.1.1.2 haad break;
368 1.1.1.2 haad
369 1.1.1.2 haad case DATA_TYPE_INT16_ARRAY:
370 1.1.1.2 haad NVPA(elem, int16_array, int16_t, int, "%d");
371 1.1.1.2 haad break;
372 1.1.1.2 haad
373 1.1.1.2 haad case DATA_TYPE_UINT16_ARRAY:
374 1.1.1.2 haad NVPA(elem, uint16_array, uint16_t, int, "%u");
375 1.1.1.2 haad break;
376 1.1.1.2 haad
377 1.1.1.2 haad case DATA_TYPE_INT32_ARRAY:
378 1.1.1.2 haad NVPA(elem, int32_array, int32_t, long, "%ld");
379 1.1.1.2 haad break;
380 1.1.1.2 haad
381 1.1.1.2 haad case DATA_TYPE_UINT32_ARRAY:
382 1.1.1.2 haad NVPA(elem, uint32_array, uint32_t, ulong_t, "%lu");
383 1.1.1.2 haad break;
384 1.1.1.2 haad
385 1.1.1.2 haad case DATA_TYPE_INT64_ARRAY:
386 1.1.1.2.12.2 tls NVPA(elem, int64_array, int64_t, int64_t, "%" PRId64);
387 1.1.1.2 haad break;
388 1.1.1.2 haad
389 1.1.1.2 haad case DATA_TYPE_UINT64_ARRAY:
390 1.1.1.2.12.2 tls NVPA(elem, uint64_array, uint64_t, uint64_t,
391 1.1.1.2.12.2 tls "%" PRIu64);
392 1.1.1.2 haad break;
393 1.1.1.2 haad
394 1.1.1.2 haad case DATA_TYPE_STRING_ARRAY:
395 1.1.1.2 haad NVPA(elem, string_array, char *, char *, "'%s'");
396 1.1.1.2 haad break;
397 1.1.1.2 haad
398 1.1.1.2 haad case DATA_TYPE_NVLIST:
399 1.1.1.2 haad (void) nvpair_value_nvlist(elem, &nvlist_value);
400 1.1.1.2 haad (void) printf("%*s%s:\n", indent, "",
401 1.1.1.2 haad nvpair_name(elem));
402 1.1.1.2 haad dump_nvlist(nvlist_value, indent + 4);
403 1.1.1.2 haad break;
404 1.1.1.2 haad
405 1.1.1.2 haad case DATA_TYPE_NVLIST_ARRAY:
406 1.1.1.2 haad (void) nvpair_value_nvlist_array(elem,
407 1.1.1.2 haad &nvlist_array_value, &count);
408 1.1.1.2 haad for (i = 0; i < count; i++) {
409 1.1.1.2 haad (void) printf("%*s%s[%u]:\n", indent, "",
410 1.1.1.2 haad nvpair_name(elem), i);
411 1.1.1.2 haad dump_nvlist(nvlist_array_value[i], indent + 4);
412 1.1.1.2 haad }
413 1.1.1.2 haad break;
414 1.1.1.2 haad
415 1.1.1.2 haad default:
416 1.1.1.2 haad (void) printf(dgettext(TEXT_DOMAIN, "bad config type "
417 1.1.1.2 haad "%d for %s\n"), nvpair_type(elem),
418 1.1.1.2 haad nvpair_name(elem));
419 1.1.1.2 haad }
420 1.1.1.2 haad }
421 1.1.1.2 haad }
422 1.1.1.2 haad
423 1.1 haad /*
424 1.1 haad * Determine if string 'value' matches 'nvp' value. The 'value' string is
425 1.1 haad * converted, depending on the type of 'nvp', prior to match. For numeric
426 1.1 haad * types, a radix independent sscanf conversion of 'value' is used. If 'nvp'
427 1.1 haad * is an array type, 'ai' is the index into the array against which we are
428 1.1 haad * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass
429 1.1 haad * in a regex_t compilation of value in 'value_regex' to trigger regular
430 1.1 haad * expression string match instead of simple strcmp().
431 1.1 haad *
432 1.1 haad * Return 1 on match, 0 on no-match, and -1 on error. If the error is
433 1.1 haad * related to value syntax error and 'ep' is non-NULL, *ep will point into
434 1.1 haad * the 'value' string at the location where the error exists.
435 1.1 haad *
436 1.1 haad * NOTE: It may be possible to move the non-regex_t version of this into
437 1.1 haad * common code used by library/kernel/boot.
438 1.1 haad */
439 1.1 haad int
440 1.1 haad nvpair_value_match_regex(nvpair_t *nvp, int ai,
441 1.1 haad char *value, regex_t *value_regex, char **ep)
442 1.1 haad {
443 1.1 haad char *evalue;
444 1.1 haad uint_t a_len;
445 1.1 haad int sr;
446 1.1 haad
447 1.1 haad if (ep)
448 1.1 haad *ep = NULL;
449 1.1 haad
450 1.1 haad if ((nvp == NULL) || (value == NULL))
451 1.1 haad return (-1); /* error fail match - invalid args */
452 1.1 haad
453 1.1 haad /* make sure array and index combination make sense */
454 1.1 haad if ((nvpair_type_is_array(nvp) && (ai < 0)) ||
455 1.1 haad (!nvpair_type_is_array(nvp) && (ai >= 0)))
456 1.1 haad return (-1); /* error fail match - bad index */
457 1.1 haad
458 1.1 haad /* non-string values should be single 'chunk' */
459 1.1 haad if ((nvpair_type(nvp) != DATA_TYPE_STRING) &&
460 1.1 haad (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) {
461 1.1 haad value += strspn(value, " \t");
462 1.1 haad evalue = value + strcspn(value, " \t");
463 1.1 haad if (*evalue) {
464 1.1 haad if (ep)
465 1.1 haad *ep = evalue;
466 1.1 haad return (-1); /* error fail match - syntax */
467 1.1 haad }
468 1.1 haad }
469 1.1 haad
470 1.1 haad sr = EOF;
471 1.1 haad switch (nvpair_type(nvp)) {
472 1.1 haad case DATA_TYPE_STRING: {
473 1.1 haad char *val;
474 1.1 haad
475 1.1 haad /* check string value for match */
476 1.1 haad if (nvpair_value_string(nvp, &val) == 0) {
477 1.1 haad if (value_regex) {
478 1.1 haad if (regexec(value_regex, val,
479 1.1 haad (size_t)0, NULL, 0) == 0)
480 1.1 haad return (1); /* match */
481 1.1 haad } else {
482 1.1 haad if (strcmp(value, val) == 0)
483 1.1 haad return (1); /* match */
484 1.1 haad }
485 1.1 haad }
486 1.1 haad break;
487 1.1 haad }
488 1.1 haad case DATA_TYPE_STRING_ARRAY: {
489 1.1 haad char **val_array;
490 1.1 haad
491 1.1 haad /* check indexed string value of array for match */
492 1.1 haad if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) &&
493 1.1 haad (ai < a_len)) {
494 1.1 haad if (value_regex) {
495 1.1 haad if (regexec(value_regex, val_array[ai],
496 1.1 haad (size_t)0, NULL, 0) == 0)
497 1.1 haad return (1);
498 1.1 haad } else {
499 1.1 haad if (strcmp(value, val_array[ai]) == 0)
500 1.1 haad return (1);
501 1.1 haad }
502 1.1 haad }
503 1.1 haad break;
504 1.1 haad }
505 1.1 haad case DATA_TYPE_BYTE: {
506 1.1 haad uchar_t val, val_arg;
507 1.1 haad
508 1.1 haad /* scanf uchar_t from value and check for match */
509 1.1 haad sr = sscanf(value, "%c", &val_arg);
510 1.1 haad if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) &&
511 1.1 haad (val == val_arg))
512 1.1 haad return (1);
513 1.1 haad break;
514 1.1 haad }
515 1.1 haad case DATA_TYPE_BYTE_ARRAY: {
516 1.1 haad uchar_t *val_array, val_arg;
517 1.1 haad
518 1.1 haad
519 1.1 haad /* check indexed value of array for match */
520 1.1 haad sr = sscanf(value, "%c", &val_arg);
521 1.1 haad if ((sr == 1) &&
522 1.1 haad (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) &&
523 1.1 haad (ai < a_len) &&
524 1.1 haad (val_array[ai] == val_arg))
525 1.1 haad return (1);
526 1.1 haad break;
527 1.1 haad }
528 1.1 haad case DATA_TYPE_INT8: {
529 1.1 haad int8_t val, val_arg;
530 1.1 haad
531 1.1 haad /* scanf int8_t from value and check for match */
532 1.1 haad sr = sscanf(value, "%"SCNi8, &val_arg);
533 1.1 haad if ((sr == 1) &&
534 1.1 haad (nvpair_value_int8(nvp, &val) == 0) &&
535 1.1 haad (val == val_arg))
536 1.1 haad return (1);
537 1.1 haad break;
538 1.1 haad }
539 1.1 haad case DATA_TYPE_INT8_ARRAY: {
540 1.1 haad int8_t *val_array, val_arg;
541 1.1 haad
542 1.1 haad /* check indexed value of array for match */
543 1.1 haad sr = sscanf(value, "%"SCNi8, &val_arg);
544 1.1 haad if ((sr == 1) &&
545 1.1 haad (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) &&
546 1.1 haad (ai < a_len) &&
547 1.1 haad (val_array[ai] == val_arg))
548 1.1 haad return (1);
549 1.1 haad break;
550 1.1 haad }
551 1.1 haad case DATA_TYPE_UINT8: {
552 1.1 haad uint8_t val, val_arg;
553 1.1 haad
554 1.1 haad /* scanf uint8_t from value and check for match */
555 1.1 haad sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
556 1.1 haad if ((sr == 1) &&
557 1.1 haad (nvpair_value_uint8(nvp, &val) == 0) &&
558 1.1 haad (val == val_arg))
559 1.1 haad return (1);
560 1.1 haad break;
561 1.1 haad }
562 1.1 haad case DATA_TYPE_UINT8_ARRAY: {
563 1.1 haad uint8_t *val_array, val_arg;
564 1.1 haad
565 1.1 haad /* check indexed value of array for match */
566 1.1 haad sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
567 1.1 haad if ((sr == 1) &&
568 1.1 haad (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) &&
569 1.1 haad (ai < a_len) &&
570 1.1 haad (val_array[ai] == val_arg))
571 1.1 haad return (1);
572 1.1 haad break;
573 1.1 haad }
574 1.1 haad case DATA_TYPE_INT16: {
575 1.1 haad int16_t val, val_arg;
576 1.1 haad
577 1.1 haad /* scanf int16_t from value and check for match */
578 1.1 haad sr = sscanf(value, "%"SCNi16, &val_arg);
579 1.1 haad if ((sr == 1) &&
580 1.1 haad (nvpair_value_int16(nvp, &val) == 0) &&
581 1.1 haad (val == val_arg))
582 1.1 haad return (1);
583 1.1 haad break;
584 1.1 haad }
585 1.1 haad case DATA_TYPE_INT16_ARRAY: {
586 1.1 haad int16_t *val_array, val_arg;
587 1.1 haad
588 1.1 haad /* check indexed value of array for match */
589 1.1 haad sr = sscanf(value, "%"SCNi16, &val_arg);
590 1.1 haad if ((sr == 1) &&
591 1.1 haad (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) &&
592 1.1 haad (ai < a_len) &&
593 1.1 haad (val_array[ai] == val_arg))
594 1.1 haad return (1);
595 1.1 haad break;
596 1.1 haad }
597 1.1 haad case DATA_TYPE_UINT16: {
598 1.1 haad uint16_t val, val_arg;
599 1.1 haad
600 1.1 haad /* scanf uint16_t from value and check for match */
601 1.1 haad sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
602 1.1 haad if ((sr == 1) &&
603 1.1 haad (nvpair_value_uint16(nvp, &val) == 0) &&
604 1.1 haad (val == val_arg))
605 1.1 haad return (1);
606 1.1 haad break;
607 1.1 haad }
608 1.1 haad case DATA_TYPE_UINT16_ARRAY: {
609 1.1 haad uint16_t *val_array, val_arg;
610 1.1 haad
611 1.1 haad /* check indexed value of array for match */
612 1.1 haad sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
613 1.1 haad if ((sr == 1) &&
614 1.1 haad (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) &&
615 1.1 haad (ai < a_len) &&
616 1.1 haad (val_array[ai] == val_arg))
617 1.1 haad return (1);
618 1.1 haad break;
619 1.1 haad }
620 1.1 haad case DATA_TYPE_INT32: {
621 1.1 haad int32_t val, val_arg;
622 1.1 haad
623 1.1 haad /* scanf int32_t from value and check for match */
624 1.1 haad sr = sscanf(value, "%"SCNi32, &val_arg);
625 1.1 haad if ((sr == 1) &&
626 1.1 haad (nvpair_value_int32(nvp, &val) == 0) &&
627 1.1 haad (val == val_arg))
628 1.1 haad return (1);
629 1.1 haad break;
630 1.1 haad }
631 1.1 haad case DATA_TYPE_INT32_ARRAY: {
632 1.1 haad int32_t *val_array, val_arg;
633 1.1 haad
634 1.1 haad /* check indexed value of array for match */
635 1.1 haad sr = sscanf(value, "%"SCNi32, &val_arg);
636 1.1 haad if ((sr == 1) &&
637 1.1 haad (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) &&
638 1.1 haad (ai < a_len) &&
639 1.1 haad (val_array[ai] == val_arg))
640 1.1 haad return (1);
641 1.1 haad break;
642 1.1 haad }
643 1.1 haad case DATA_TYPE_UINT32: {
644 1.1 haad uint32_t val, val_arg;
645 1.1 haad
646 1.1 haad /* scanf uint32_t from value and check for match */
647 1.1 haad sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
648 1.1 haad if ((sr == 1) &&
649 1.1 haad (nvpair_value_uint32(nvp, &val) == 0) &&
650 1.1 haad (val == val_arg))
651 1.1 haad return (1);
652 1.1 haad break;
653 1.1 haad }
654 1.1 haad case DATA_TYPE_UINT32_ARRAY: {
655 1.1 haad uint32_t *val_array, val_arg;
656 1.1 haad
657 1.1 haad /* check indexed value of array for match */
658 1.1 haad sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
659 1.1 haad if ((sr == 1) &&
660 1.1 haad (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) &&
661 1.1 haad (ai < a_len) &&
662 1.1 haad (val_array[ai] == val_arg))
663 1.1 haad return (1);
664 1.1 haad break;
665 1.1 haad }
666 1.1 haad case DATA_TYPE_INT64: {
667 1.1 haad int64_t val, val_arg;
668 1.1 haad
669 1.1 haad /* scanf int64_t from value and check for match */
670 1.1 haad sr = sscanf(value, "%"SCNi64, &val_arg);
671 1.1 haad if ((sr == 1) &&
672 1.1 haad (nvpair_value_int64(nvp, &val) == 0) &&
673 1.1 haad (val == val_arg))
674 1.1 haad return (1);
675 1.1 haad break;
676 1.1 haad }
677 1.1 haad case DATA_TYPE_INT64_ARRAY: {
678 1.1 haad int64_t *val_array, val_arg;
679 1.1 haad
680 1.1 haad /* check indexed value of array for match */
681 1.1 haad sr = sscanf(value, "%"SCNi64, &val_arg);
682 1.1 haad if ((sr == 1) &&
683 1.1 haad (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) &&
684 1.1 haad (ai < a_len) &&
685 1.1 haad (val_array[ai] == val_arg))
686 1.1 haad return (1);
687 1.1 haad break;
688 1.1 haad }
689 1.1 haad case DATA_TYPE_UINT64: {
690 1.1 haad uint64_t val_arg, val;
691 1.1 haad
692 1.1 haad /* scanf uint64_t from value and check for match */
693 1.1 haad sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
694 1.1 haad if ((sr == 1) &&
695 1.1 haad (nvpair_value_uint64(nvp, &val) == 0) &&
696 1.1 haad (val == val_arg))
697 1.1 haad return (1);
698 1.1 haad break;
699 1.1 haad }
700 1.1 haad case DATA_TYPE_UINT64_ARRAY: {
701 1.1 haad uint64_t *val_array, val_arg;
702 1.1 haad
703 1.1 haad /* check indexed value of array for match */
704 1.1 haad sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
705 1.1 haad if ((sr == 1) &&
706 1.1 haad (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) &&
707 1.1 haad (ai < a_len) &&
708 1.1 haad (val_array[ai] == val_arg))
709 1.1 haad return (1);
710 1.1 haad break;
711 1.1 haad }
712 1.1 haad case DATA_TYPE_BOOLEAN_VALUE: {
713 1.1 haad boolean_t val, val_arg;
714 1.1 haad
715 1.1 haad /* scanf boolean_t from value and check for match */
716 1.1 haad sr = sscanf(value, "%"SCNi32, &val_arg);
717 1.1 haad if ((sr == 1) &&
718 1.1 haad (nvpair_value_boolean_value(nvp, &val) == 0) &&
719 1.1 haad (val == val_arg))
720 1.1 haad return (1);
721 1.1 haad break;
722 1.1 haad }
723 1.1 haad case DATA_TYPE_BOOLEAN_ARRAY: {
724 1.1 haad boolean_t *val_array, val_arg;
725 1.1 haad
726 1.1 haad /* check indexed value of array for match */
727 1.1 haad sr = sscanf(value, "%"SCNi32, &val_arg);
728 1.1 haad if ((sr == 1) &&
729 1.1 haad (nvpair_value_boolean_array(nvp,
730 1.1 haad &val_array, &a_len) == 0) &&
731 1.1 haad (ai < a_len) &&
732 1.1 haad (val_array[ai] == val_arg))
733 1.1 haad return (1);
734 1.1 haad break;
735 1.1 haad }
736 1.1 haad case DATA_TYPE_HRTIME:
737 1.1 haad case DATA_TYPE_NVLIST:
738 1.1 haad case DATA_TYPE_NVLIST_ARRAY:
739 1.1 haad case DATA_TYPE_BOOLEAN:
740 1.1 haad case DATA_TYPE_DOUBLE:
741 1.1 haad case DATA_TYPE_UNKNOWN:
742 1.1 haad default:
743 1.1 haad /*
744 1.1 haad * unknown/unsupported data type
745 1.1 haad */
746 1.1 haad return (-1); /* error fail match */
747 1.1 haad }
748 1.1 haad
749 1.1 haad /*
750 1.1 haad * check to see if sscanf failed conversion, return approximate
751 1.1 haad * pointer to problem
752 1.1 haad */
753 1.1 haad if (sr != 1) {
754 1.1 haad if (ep)
755 1.1 haad *ep = value;
756 1.1 haad return (-1); /* error fail match - syntax */
757 1.1 haad }
758 1.1 haad
759 1.1 haad return (0); /* fail match */
760 1.1 haad }
761 1.1 haad
762 1.1 haad int
763 1.1 haad nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep)
764 1.1 haad {
765 1.1 haad return (nvpair_value_match_regex(nvp, ai, value, NULL, ep));
766 1.1 haad }
767