Add UCS2->UTF8 option.

Many UEFI variables are UCS2 strings (some NUL terminated, others
not). Add --utf8 (-u) to convert UCS2 strings to UTF8 before printing.

Sponsored by: Netflix
This commit is contained in:
Warner Losh 2017-08-31 17:53:50 +00:00
parent 6b4a1e856f
commit b0da7c79f1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=323066
3 changed files with 37 additions and 2 deletions

View File

@ -5,4 +5,7 @@ MAN= efivar.8
LIBADD= efivar
EFIBOOT=${SRCTOP}/sys/boot/efi
CFLAGS+= -I${EFIBOOT}/include
.include <bsd.prog.mk>

View File

@ -32,7 +32,7 @@
.Nd UEFI environment variable interaction
.Sh SYNOPSIS
.Nm
.Op Fl abdDHlLNpRtw
.Op Fl abdDHlLNpRtuw
.Op Fl n Ar name
.Op Fl f Ar file
.Op Fl -append
@ -51,6 +51,7 @@
.Op Fl -print
.Op Fl -print-decimal
.Op Fl -raw-guid
.Op Fl -utf8
.Op Fl -write
.Sh DESCRIPTION
This program manages
@ -143,6 +144,9 @@ Do not display the variable name.
Print the value of the variable.
.It Fl R Fl -raw-guid
Do not substitute well known names for GUID numeric values in output.
.It Fl u Fl -utf8
Treat the value of the variable as UCS2 and convert it to UTF8 and
print the result.
.It Fl w Fl -write
Write (replace) the variable specified with the value specified from
standard input.

View File

@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "efichar.h"
/* options descriptor */
static struct option longopts[] = {
@ -58,13 +59,14 @@ static struct option longopts[] = {
{ "print", no_argument, NULL, 'p' },
{ "print-decimal", no_argument, NULL, 'd' },
{ "raw-guid", no_argument, NULL, 'R' },
{ "utf8", no_argument, NULL, 'u' },
{ "write", no_argument, NULL, 'w' },
{ NULL, 0, NULL, 0 }
};
static int aflag, Aflag, bflag, dflag, Dflag, gflag, Hflag, Nflag,
lflag, Lflag, Rflag, wflag, pflag;
lflag, Lflag, Rflag, wflag, pflag, uflag;
static char *varname;
static u_long attrib = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
@ -175,6 +177,27 @@ asciidump(uint8_t *data, size_t datalen)
printf("\n");
}
static void
utf8dump(uint8_t *data, size_t datalen)
{
char *utf8 = NULL;
efi_char *ucs2;
/*
* NUL terminate the string. Not all strings need it, but some
* do and an extra NUL won't change what's printed.
*/
ucs2 = malloc(datalen + sizeof(efi_char));
memcpy(ucs2, data, datalen);
ucs2[datalen / sizeof(efi_char)] = 0;
ucs2_to_utf8(ucs2, &utf8);
if (!Nflag)
printf("\n");
printf("%s\n", utf8);
free(utf8);
free(ucs2);
}
static void
hexdump(uint8_t *data, size_t datalen)
{
@ -245,6 +268,8 @@ print_var(efi_guid_t *guid, char *name)
printf("%s-%s", gname, name);
if (Aflag)
asciidump(data, datalen);
else if (uflag)
utf8dump(data, datalen);
else if (bflag)
bindump(data, datalen);
else if (dflag)
@ -344,6 +369,9 @@ parse_args(int argc, char **argv)
case 't':
attrib = strtoul(optarg, NULL, 16);
break;
case 'u':
uflag++;
break;
case 'w':
wflag++;
break;