showvar.c revision 1.5 1 1.5 riastrad /* $NetBSD: showvar.c,v 1.5 2025/03/02 01:07:11 riastradh Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * Redistribution and use in source and binary forms, with or without
5 1.1 christos * modification, are permitted provided that the following conditions
6 1.1 christos * are met:
7 1.1 christos * 1. Redistributions of source code must retain the above copyright
8 1.1 christos * notice, this list of conditions and the following disclaimer.
9 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright
10 1.1 christos * notice, this list of conditions and the following disclaimer in the
11 1.1 christos * documentation and/or other materials provided with the distribution.
12 1.1 christos *
13 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
14 1.1 christos * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 1.1 christos * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 1.1 christos * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 1.1 christos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 1.1 christos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 1.1 christos * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 1.1 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 1.1 christos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 1.1 christos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 1.1 christos * SUCH DAMAGE.
24 1.1 christos */
25 1.1 christos
26 1.1 christos #include <sys/cdefs.h>
27 1.1 christos #ifndef lint
28 1.5 riastrad __RCSID("$NetBSD: showvar.c,v 1.5 2025/03/02 01:07:11 riastradh Exp $");
29 1.1 christos #endif /* not lint */
30 1.1 christos
31 1.1 christos #include <sys/efiio.h>
32 1.1 christos #include <sys/ioctl.h>
33 1.1 christos #include <sys/uuid.h>
34 1.1 christos
35 1.1 christos #include <assert.h>
36 1.1 christos #include <ctype.h>
37 1.1 christos #include <err.h>
38 1.1 christos #include <errno.h>
39 1.1 christos #include <fcntl.h>
40 1.1 christos #include <getopt.h>
41 1.1 christos #include <limits.h>
42 1.1 christos #include <regex.h>
43 1.1 christos #include <stdarg.h>
44 1.1 christos #include <stdbool.h>
45 1.1 christos #include <stddef.h>
46 1.1 christos #include <stdio.h>
47 1.1 christos #include <stdlib.h>
48 1.1 christos #include <string.h>
49 1.1 christos #include <unistd.h>
50 1.1 christos #include <util.h>
51 1.1 christos
52 1.1 christos #include "efiio.h"
53 1.1 christos #include "defs.h"
54 1.1 christos #include "bootvar.h"
55 1.1 christos #include "certs.h"
56 1.1 christos #include "devpath.h"
57 1.1 christos #include "getvars.h"
58 1.1 christos #include "showvar.h"
59 1.1 christos #include "utils.h"
60 1.1 christos
61 1.1 christos #define EFI_OS_INDICATIONS_BOOT_TO_FW_UI __BIT(0)
62 1.1 christos #define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION __BIT(1)
63 1.1 christos #define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED __BIT(2)
64 1.1 christos #define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED __BIT(3)
65 1.1 christos #define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED __BIT(4)
66 1.1 christos #define EFI_OS_INDICATIONS_START_OS_RECOVERY __BIT(5)
67 1.1 christos #define EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY __BIT(6)
68 1.1 christos #define EFI_OS_INDICATIONS_JSON_CONFIG_DATA_REFRESH __BIT(7)
69 1.1 christos #define OS_INDICATIONS_BITS \
70 1.1 christos "\177\020" \
71 1.1 christos "b\x0""BootFWui\0" \
72 1.1 christos "b\x1""TimeStamp\0" \
73 1.1 christos "b\x2""FileCap\0" \
74 1.1 christos "b\x3""FMPCap\0" \
75 1.1 christos "b\x4""CapResVar\0" \
76 1.1 christos "b\x5""StartOsRecovery\0" \
77 1.1 christos "b\x6""StartPltformRec\0" \
78 1.1 christos "b\x7""JSONConfig\0" \
79 1.1 christos
80 1.1 christos //********************************************************
81 1.1 christos // Boot Option Attributes
82 1.1 christos //********************************************************
83 1.1 christos #define EFI_BOOT_OPTION_SUPPORT_KEY __BIT(0) // 0x00000001
84 1.1 christos #define EFI_BOOT_OPTION_SUPPORT_APP __BIT(1) // 0x00000002
85 1.1 christos #define EFI_BOOT_OPTION_SUPPORT_SYSPREP __BIT(4) // 0x00000010
86 1.1 christos #define EFI_BOOT_OPTION_SUPPORT_COUNT __BITS(8,9) // 0x00000300
87 1.1 christos // All values 0x00000200-0x00001F00 are reserved
88 1.1 christos #define BOOT_OPTION_SUPPORT_BITS \
89 1.1 christos "\177\020" \
90 1.1 christos "b\x0""Key\0" \
91 1.1 christos "b\x1""App\0" \
92 1.1 christos "b\x4""SysPrep\0" \
93 1.1 christos "f\x8\x2""Count\0"
94 1.1 christos
95 1.1 christos /************************************************************************/
96 1.1 christos
97 1.1 christos static int
98 1.1 christos show_filelist_data(efi_var_t *v, bool dbg)
99 1.1 christos {
100 1.1 christos char *dmsg, *path;
101 1.1 christos
102 1.1 christos path = devpath_parse(v->ev.data, v->ev.datasize, dbg ? &dmsg : NULL);
103 1.1 christos printf("%s: %s\n", v->name, path);
104 1.1 christos free(path);
105 1.1 christos if (dbg) {
106 1.1 christos printf("%s", dmsg);
107 1.1 christos free(dmsg);
108 1.1 christos }
109 1.1 christos return 0;
110 1.1 christos }
111 1.1 christos
112 1.1 christos static int
113 1.2 christos show_asciiz_data(efi_var_t *v, bool dbg __unused)
114 1.1 christos {
115 1.1 christos char *cp, *ep;
116 1.1 christos
117 1.1 christos printf("%s: ", v->name);
118 1.1 christos
119 1.1 christos cp = v->ev.data;
120 1.1 christos ep = cp + v->ev.datasize;
121 1.1 christos for (/*EMPTY*/; cp < ep; cp += strlen(cp) + 1) {
122 1.1 christos printf("%s\n", cp);
123 1.1 christos }
124 1.1 christos if (cp != ep)
125 1.1 christos warnx("short asciiz data\n");
126 1.1 christos return 0;
127 1.1 christos }
128 1.1 christos
129 1.1 christos static int
130 1.2 christos show_array8_data(efi_var_t *v, bool dbg __unused)
131 1.1 christos {
132 1.1 christos size_t cnt, i;
133 1.1 christos uint8_t *array = v->ev.data;
134 1.1 christos
135 1.1 christos printf("%s: ", v->name);
136 1.1 christos
137 1.1 christos cnt = v->ev.datasize / sizeof(array[0]);
138 1.1 christos i = 0;
139 1.1 christos for (;;) {
140 1.1 christos printf("%02x", array[i]);
141 1.1 christos if (++i == cnt) {
142 1.1 christos printf("\n");
143 1.1 christos break;
144 1.1 christos }
145 1.1 christos printf(",");
146 1.1 christos }
147 1.1 christos return 0;
148 1.1 christos }
149 1.1 christos
150 1.1 christos static int
151 1.2 christos show_array16_data(efi_var_t *v, bool dbg __unused)
152 1.1 christos {
153 1.1 christos size_t cnt, i;
154 1.1 christos uint16_t *array = v->ev.data;
155 1.1 christos
156 1.1 christos printf("%s: ", v->name);
157 1.1 christos
158 1.1 christos cnt = v->ev.datasize / sizeof(array[0]);
159 1.1 christos i = 0;
160 1.1 christos for (;;) {
161 1.1 christos printf("%04X", array[i]);
162 1.1 christos if (++i == cnt) {
163 1.1 christos printf("\n");
164 1.1 christos break;
165 1.1 christos }
166 1.1 christos printf(",");
167 1.1 christos }
168 1.1 christos return 0;
169 1.1 christos }
170 1.1 christos
171 1.1 christos static int
172 1.1 christos show_uuid_array_data(efi_var_t *v, bool dbg)
173 1.1 christos {
174 1.1 christos size_t cnt, i;
175 1.1 christos uuid_t *array = v->ev.data;
176 1.1 christos const char *name;
177 1.1 christos
178 1.1 christos printf("%s: ", v->name);
179 1.1 christos
180 1.1 christos cnt = v->ev.datasize / sizeof(array[0]);
181 1.1 christos
182 1.1 christos for (i = 0; i < cnt; i++) {
183 1.1 christos name = get_cert_name(&array[i]);
184 1.1 christos printf("%s%c", name, i + 1 < cnt ? ' ' : '\n');
185 1.1 christos }
186 1.1 christos
187 1.1 christos if (dbg) {
188 1.1 christos for (i = 0; i < cnt; i++) {
189 1.1 christos printf(" ");
190 1.1 christos uuid_printf(&array[i]);
191 1.1 christos name = get_cert_name(&array[i]);
192 1.1 christos printf(" %s\n", name ? name : "unknown");
193 1.1 christos }
194 1.1 christos }
195 1.1 christos return 0;
196 1.1 christos }
197 1.1 christos
198 1.1 christos /************************************************************************/
199 1.1 christos
200 1.1 christos static int
201 1.1 christos show_key_data(efi_var_t *v, bool dbg)
202 1.1 christos {
203 1.1 christos typedef union {
204 1.1 christos struct {
205 1.1 christos uint32_t Revision : 8;
206 1.1 christos uint32_t ShiftPressed : 1;
207 1.1 christos uint32_t ControlPressed : 1;
208 1.1 christos uint32_t AltPressed : 1;
209 1.1 christos uint32_t LogoPressed : 1;
210 1.1 christos uint32_t MenuPressed : 1;
211 1.1 christos uint32_t SysReqPressed : 1;
212 1.1 christos uint32_t Reserved : 16;
213 1.1 christos uint32_t InputKeyCount : 2;
214 1.1 christos #define BOOT_KEY_OPTION_BITS \
215 1.1 christos "\177\020" \
216 1.1 christos "f\x00\x08""Rev\0" \
217 1.1 christos "b\x08""SHFT\0" \
218 1.1 christos "b\x09""CTRL\0" \
219 1.1 christos "b\x0a""ALT\0" \
220 1.1 christos "b\x0b""LOGO\0" \
221 1.1 christos "b\x0c""MENU\0" \
222 1.1 christos "b\x0d""SysReq\0" \
223 1.1 christos /* "f\x0e\x10""Rsvd\0" */ \
224 1.1 christos "f\x1e\x02""KeyCnt\0"
225 1.1 christos } Options;
226 1.1 christos uint32_t PackedValue;
227 1.1 christos } __packed EFI_BOOT_KEY_DATA;
228 1.1 christos typedef struct {
229 1.1 christos uint16_t ScanCode;
230 1.1 christos uint16_t UnicodeChar;
231 1.1 christos } __packed EFI_INPUT_KEY;
232 1.1 christos typedef struct _EFI_KEY_OPTION {
233 1.1 christos EFI_BOOT_KEY_DATA KeyData;
234 1.1 christos uint32_t BootOptionCrc;
235 1.1 christos uint16_t BootOption;
236 1.1 christos EFI_INPUT_KEY Keys[3];
237 1.1 christos uint16_t DescLocation; /* XXX: a guess! Not documented */
238 1.1 christos uint8_t UndocData[];
239 1.1 christos } __packed EFI_KEY_OPTION;
240 1.1 christos union {
241 1.1 christos EFI_KEY_OPTION *ko;
242 1.1 christos uint8_t *bp;
243 1.1 christos } u = { .bp = v->ev.data, };
244 1.1 christos char buf[256], c, *cp, *desc;
245 1.5 riastrad uint i;
246 1.1 christos
247 1.1 christos printf("%s:", v->name);
248 1.1 christos
249 1.1 christos /*
250 1.1 christos * Note: DescLocation is not documented in the UEFI spec, so
251 1.1 christos * do some sanity checking before using it.
252 1.1 christos */
253 1.1 christos desc = NULL;
254 1.1 christos if (offsetof(EFI_KEY_OPTION, UndocData) < v->ev.datasize &&
255 1.1 christos u.ko->DescLocation + sizeof(uint16_t) < v->ev.datasize) {
256 1.1 christos size_t sz = v->ev.datasize - u.ko->DescLocation;
257 1.1 christos desc = ucs2_to_utf8((uint16_t *)&u.bp[u.ko->DescLocation],
258 1.1 christos sz, NULL, NULL);
259 1.1 christos printf(" %s", desc);
260 1.1 christos }
261 1.1 christos
262 1.1 christos /*
263 1.1 christos * Parse the KeyData
264 1.1 christos */
265 1.1 christos snprintb(buf, sizeof(buf), BOOT_KEY_OPTION_BITS,
266 1.1 christos u.ko->KeyData.PackedValue);
267 1.1 christos
268 1.1 christos /*
269 1.1 christos * Skip over the raw value
270 1.1 christos */
271 1.1 christos c = '\0';
272 1.1 christos if ((cp = strchr(buf, ',')) || (cp = strchr(buf, '<'))) {
273 1.1 christos c = *cp;
274 1.1 christos *cp = '<';
275 1.1 christos }
276 1.1 christos else
277 1.1 christos cp = buf;
278 1.1 christos
279 1.1 christos printf("\tBoot%04X \t%s", u.ko->BootOption, cp);
280 1.1 christos
281 1.1 christos if (c != '\0')
282 1.1 christos *cp = c; /* restore the buffer */
283 1.4 riastrad
284 1.5 riastrad for (i = 0; i < u.ko->KeyData.Options.InputKeyCount; i++)
285 1.1 christos printf(" {%04x, %04x}", u.ko->Keys[i].ScanCode,
286 1.1 christos u.ko->Keys[i].UnicodeChar);
287 1.1 christos printf("\n");
288 1.1 christos
289 1.1 christos if (dbg) {
290 1.1 christos printf(" KeyData: %s\n", buf);
291 1.1 christos printf(" BootOptionCrc: 0x%08x\n", u.ko->BootOptionCrc);
292 1.1 christos printf(" BootOption: Boot%04X\n", u.ko->BootOption);
293 1.5 riastrad for (i = 0; i < u.ko->KeyData.Options.InputKeyCount; i++) {
294 1.1 christos printf(" Keys[%u].ScanCode: 0x%04x\n", i,
295 1.4 riastrad u.ko->Keys[i].ScanCode);
296 1.1 christos printf(" Keys[%u].UnicodeChar: 0x%04x\n", i,
297 1.4 riastrad u.ko->Keys[i].UnicodeChar);
298 1.1 christos }
299 1.1 christos if (desc)
300 1.1 christos printf(" Desc: %s\n", desc);
301 1.1 christos }
302 1.1 christos free(desc);
303 1.1 christos return 0;
304 1.1 christos }
305 1.1 christos
306 1.1 christos /************************************************************************/
307 1.1 christos
308 1.1 christos static char *
309 1.1 christos format_optional_data(char *od, size_t sz)
310 1.1 christos {
311 1.1 christos char *bp;
312 1.1 christos size_t i;
313 1.1 christos
314 1.1 christos bp = emalloc(sz + 1);
315 1.1 christos
316 1.1 christos for (i = 0; i < sz; i++) {
317 1.1 christos char c = od[i];
318 1.2 christos bp[i] = isprint((unsigned char)c) ? c : '.';
319 1.1 christos }
320 1.1 christos bp[i] = '\0';
321 1.1 christos return bp;
322 1.1 christos }
323 1.1 christos
324 1.1 christos static int
325 1.3 christos show_boot_data(efi_var_t *v, uint debug, uint max_namelen)
326 1.1 christos {
327 1.1 christos struct {
328 1.1 christos char *name;
329 1.1 christos uint32_t Attributes;
330 1.1 christos char *Description;
331 1.1 christos devpath_t *devpath;
332 1.1 christos char *OptionalData;
333 1.1 christos size_t OptionalDataSize;
334 1.1 christos } info;
335 1.1 christos union {
336 1.1 christos char *cp;
337 1.1 christos boot_var_t *bb;
338 1.1 christos } u = { .cp = v->ev.data, };
339 1.1 christos char *args, *dmsg, *path;
340 1.1 christos size_t sz;
341 1.1 christos bool dbg = debug & DEBUG_STRUCT_BIT;
342 1.1 christos bool verbose = debug & (DEBUG_MASK | DEBUG_VERBOSE_BIT);
343 1.1 christos
344 1.1 christos memset(&info, 0, sizeof(info));
345 1.1 christos info.name = v->name;
346 1.1 christos info.Attributes = u.bb->Attributes;
347 1.1 christos sz = (v->ev.datasize - sizeof(*u.bb)) / sizeof(uint16_t);
348 1.1 christos sz = (ucs2nlen(u.bb->Description, sz) + 1) * sizeof(uint16_t);
349 1.1 christos info.Description = ucs2_to_utf8(u.bb->Description, sz, NULL, NULL);
350 1.1 christos info.devpath = (devpath_t *)((uint8_t *)u.bb->Description + sz);
351 1.1 christos info.OptionalData = (char *)info.devpath + u.bb->FilePathListLength;
352 1.1 christos
353 1.1 christos char *ep = u.cp + v->ev.datasize;
354 1.1 christos
355 1.1 christos assert(info.OptionalData <= u.cp + v->ev.datasize);
356 1.1 christos
357 1.1 christos if (info.OptionalData <= u.cp + v->ev.datasize) {
358 1.1 christos info.OptionalDataSize = (size_t)(ep - info.OptionalData);
359 1.1 christos }
360 1.1 christos else {
361 1.1 christos printf("ARG!!! "
362 1.1 christos "FilePahList[] extends past end of data by %zd bytes\n",
363 1.1 christos info.OptionalData - ep);
364 1.1 christos info.OptionalDataSize = 0;
365 1.1 christos }
366 1.1 christos printf("%s%c %-*s", v->name,
367 1.1 christos IS_ACTIVE(info.Attributes) ? '*' : ' ',
368 1.1 christos max_namelen, info.Description);
369 1.1 christos
370 1.1 christos dmsg = NULL;
371 1.1 christos if (verbose) {
372 1.1 christos path = devpath_parse(info.devpath, u.bb->FilePathListLength,
373 1.1 christos dbg ? &dmsg : NULL);
374 1.1 christos
375 1.1 christos args = format_optional_data(info.OptionalData,
376 1.1 christos info.OptionalDataSize);
377 1.4 riastrad
378 1.1 christos printf("\t%s%s", path, args);/* XXX: make this conditional on verbose? */
379 1.1 christos free(args);
380 1.1 christos free(path);
381 1.1 christos }
382 1.1 christos
383 1.1 christos printf("\n");
384 1.1 christos
385 1.1 christos if (dbg) {
386 1.1 christos char attr_str[256];
387 1.4 riastrad
388 1.1 christos snprintb(attr_str, sizeof(attr_str),
389 1.1 christos LOAD_OPTION_BITS, info.Attributes);
390 1.1 christos printf(" Attr: %s\n", attr_str);
391 1.1 christos printf(" Description: %s\n", info.Description);
392 1.1 christos assert(dmsg != NULL);
393 1.1 christos printf("%s", dmsg);
394 1.1 christos if (info.OptionalDataSize > 0) {
395 1.1 christos show_data((void *)info.OptionalData,
396 1.1 christos info.OptionalDataSize, " ExtraData: ");
397 1.1 christos }
398 1.1 christos free(dmsg);
399 1.1 christos }
400 1.1 christos
401 1.1 christos free(info.Description);
402 1.1 christos return 0;
403 1.4 riastrad }
404 1.1 christos
405 1.1 christos /************************************************************************/
406 1.1 christos
407 1.1 christos static int
408 1.2 christos show_OsIndications_data(efi_var_t *e, bool dbg __unused)
409 1.1 christos {
410 1.1 christos uint64_t OsIndications;
411 1.1 christos char buf[256];
412 1.1 christos
413 1.1 christos assert(e->ev.datasize == 8);
414 1.1 christos OsIndications = *(uint64_t *)e->ev.data;
415 1.1 christos snprintb(buf, sizeof(buf), OS_INDICATIONS_BITS, OsIndications);
416 1.1 christos printf("%s:\t%s\n", e->name, buf);
417 1.1 christos return 0;
418 1.1 christos }
419 1.1 christos
420 1.1 christos static int
421 1.2 christos show_BootOptionSupport_data(efi_var_t *e, bool dbg __unused)
422 1.1 christos {
423 1.1 christos uint32_t boot_option_support;
424 1.1 christos char buf[256];
425 1.1 christos
426 1.1 christos assert(e->ev.datasize == 4);
427 1.1 christos boot_option_support = *(uint32_t *)e->ev.data;
428 1.1 christos snprintb(buf, sizeof(buf), BOOT_OPTION_SUPPORT_BITS,
429 1.1 christos boot_option_support);
430 1.1 christos printf("%s:\t%s\n", e->name, buf);
431 1.1 christos return 0;
432 1.1 christos }
433 1.1 christos
434 1.1 christos static int
435 1.2 christos show_Timeout_data(efi_var_t *e, bool dbg __unused)
436 1.1 christos {
437 1.1 christos uint16_t *timeout = e->ev.data;
438 1.1 christos
439 1.1 christos if (e->ev.datasize != 2)
440 1.1 christos printf("bad timeout datasize: %zu\n", e->ev.datasize);
441 1.1 christos else
442 1.1 christos printf("Timeout: %u seconds\n", *timeout);
443 1.1 christos return 0;
444 1.1 christos }
445 1.1 christos
446 1.1 christos PUBLIC int
447 1.1 christos show_generic_data(efi_var_t *e, uint var_width)
448 1.1 christos {
449 1.1 christos char uuid_str[UUID_STR_LEN];
450 1.1 christos char attr_str[256];
451 1.1 christos
452 1.1 christos uuid_snprintf(uuid_str, sizeof(uuid_str), &e->ev.vendor);
453 1.1 christos snprintb(attr_str, sizeof(attr_str), EFI_VAR_ATTR_BITS, e->ev.attrib);
454 1.1 christos printf("%-*s %s %5zu %s\n", var_width, e->name, uuid_str,
455 1.1 christos e->ev.datasize, attr_str);
456 1.1 christos
457 1.1 christos return 0;
458 1.1 christos }
459 1.1 christos
460 1.1 christos /************************************************************************/
461 1.1 christos
462 1.1 christos struct vartbl {
463 1.1 christos const char *name;
464 1.1 christos int (*fn)(efi_var_t *, bool);
465 1.1 christos };
466 1.1 christos
467 1.1 christos static int
468 1.1 christos varcmpsortfn(const void *a, const void *b)
469 1.1 christos {
470 1.1 christos const struct vartbl *p = a;
471 1.1 christos const struct vartbl *q = b;
472 1.1 christos
473 1.1 christos return strcmp(p->name, q->name);
474 1.1 christos }
475 1.1 christos
476 1.1 christos static int
477 1.1 christos varcmpsrchfn(const void *a, const void *b)
478 1.1 christos {
479 1.1 christos const struct vartbl *q = b;
480 1.1 christos
481 1.1 christos return strcmp(a, q->name);
482 1.1 christos }
483 1.1 christos
484 1.1 christos PUBLIC int
485 1.3 christos show_variable(efi_var_t *v, uint debug, uint max_namelen)
486 1.1 christos {
487 1.1 christos #define REGEXP_BOOTXXXX "^((Key)|(Boot)|(lBoot)|(Driver)|(SysPrep)|(OsRecovery))[0-9,A-F]{4}$"
488 1.1 christos static regex_t preg = { .re_magic = 0, };
489 1.1 christos static struct vartbl *tp, tbl[] = {
490 1.1 christos { "AuditMode", show_array8_data, },
491 1.1 christos { "BootCurrent", show_array16_data, },
492 1.1 christos { "BootNext", show_array16_data, },
493 1.1 christos { "BootOptionSupport", show_BootOptionSupport_data, },
494 1.1 christos { "BootOrder", show_array16_data, },
495 1.1 christos { "BootOrderDefault", show_array16_data, },
496 1.1 christos { "db", show_cert_data, },
497 1.1 christos { "dbDefault", show_cert_data, },
498 1.1 christos { "dbr", show_cert_data, },
499 1.1 christos { "dbrDefault", show_cert_data, },
500 1.1 christos { "dbt", show_cert_data, },
501 1.1 christos { "dbtDefault", show_cert_data, },
502 1.1 christos { "dbx", show_cert_data, },
503 1.1 christos { "dbxDefault", show_cert_data, },
504 1.1 christos { "devdbDefault", show_cert_data, },
505 1.1 christos { "ConIn", show_filelist_data, },
506 1.1 christos { "ConInDev", show_filelist_data, },
507 1.1 christos { "ConOut", show_filelist_data, },
508 1.1 christos { "ConOutDev", show_filelist_data, },
509 1.1 christos { "DriverOrder", show_array16_data, },
510 1.1 christos { "ErrOut", show_filelist_data, },
511 1.1 christos { "ErrOutDev", show_filelist_data, },
512 1.1 christos { "KEK", show_cert_data, },
513 1.1 christos { "KEKDefault", show_cert_data, },
514 1.1 christos { "OsIndications", show_OsIndications_data, },
515 1.1 christos { "OsIndicationsSupported", show_OsIndications_data, },
516 1.1 christos { "PK", show_cert_data, },
517 1.1 christos { "PKDefault", show_cert_data, },
518 1.1 christos { "PlatformLang", show_asciiz_data, },
519 1.1 christos { "PlatformLangCodes", show_asciiz_data, },
520 1.1 christos { "ProtectedBootOptions", show_array16_data, },
521 1.1 christos { "SecureBoot", show_array8_data, },
522 1.1 christos { "SetupMode", show_array8_data, },
523 1.1 christos { "SignatureSupport", show_uuid_array_data, },
524 1.1 christos { "SysPrepOrder", show_array16_data, },
525 1.1 christos { "Timeout", show_Timeout_data, },
526 1.1 christos { "VendorKeys", show_array8_data, },
527 1.1 christos };
528 1.1 christos bool dbg = debug & DEBUG_STRUCT_BIT;
529 1.1 christos int rv;
530 1.1 christos
531 1.1 christos if (preg.re_magic == 0) {
532 1.1 christos const char *regexp = REGEXP_BOOTXXXX;
533 1.1 christos if (regcomp(&preg, regexp, REG_EXTENDED) != 0)
534 1.1 christos err(EXIT_FAILURE, "regcomp: %s", regexp);
535 1.1 christos
536 1.1 christos qsort(tbl, __arraycount(tbl), sizeof(*tbl), varcmpsortfn);
537 1.1 christos }
538 1.1 christos
539 1.1 christos if (debug & DEBUG_EFI_IOC_BIT) {
540 1.1 christos rv = show_generic_data(v, max_namelen);
541 1.1 christos if (debug & DEBUG_VERBOSE_BIT)
542 1.1 christos return rv;
543 1.1 christos }
544 1.1 christos
545 1.1 christos if (regexec(&preg, v->name, 0, NULL, 0) == 0) { /* matched */
546 1.1 christos if (v->name[0] == 'K')
547 1.1 christos rv = show_key_data(v, dbg);
548 1.1 christos else
549 1.1 christos rv = show_boot_data(v, debug, max_namelen);
550 1.1 christos }
551 1.1 christos else {
552 1.1 christos tp = bsearch(v->name, tbl, __arraycount(tbl), sizeof(*tbl),
553 1.1 christos varcmpsrchfn);
554 1.1 christos
555 1.1 christos if (tp != NULL)
556 1.1 christos rv = tp->fn(v, dbg);
557 1.1 christos else if(!(debug & DEBUG_EFI_IOC_BIT))
558 1.1 christos rv = show_generic_data(v, max_namelen);
559 1.1 christos }
560 1.1 christos if (debug & DEBUG_DATA_BIT)
561 1.1 christos show_data(v->ev.data, v->ev.datasize, " ");
562 1.1 christos
563 1.1 christos return rv;
564 1.1 christos }
565