Add -u (--to-unix) and -e (--to-efi) to convert unix or efi paths to

the other.

Sponsored by: Netflix
This commit is contained in:
imp 2017-12-02 07:29:24 +00:00
parent e75506d838
commit b105c4e459
3 changed files with 133 additions and 49 deletions

View File

@ -3,6 +3,6 @@
PROG= efidp
MAN= efidp.8
LIBADD= efivar
LIBADD= efivar geom
.include <bsd.prog.mk>

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd November 21, 2017
.Dd December 1, 2017
.Dt EFIDP 8
.Os
.Sh NAME
@ -46,15 +46,24 @@ Specification.
.Bl -tag -width 20m
.It Fl f Fl -format
Formats a binary UEFI Device Path into its canonical UTF-8 textual form.
A binary Device Path can be no longer than 8192 bytes.
The textual form must fit into 4096 bytes.
A binary Device Path can be no longer than 65536 bytes.
The textual form must fit into 65536 bytes.
Multiple binary device paths may be specified.
.It Fl p Fl -parse
Parses a UEFI Device Path UTF-8 specification and outputs the binary
Device Path form.
Only one device path is parsed, even if there are multiple present in
the input.
Leading white space is ignored.
The resulting binary Device Path can be no longer than 8192 bytes.
The resulting binary Device Path can be no longer than 65536 bytes.
Multiple lines may be specified.
Each one will be translated.
.It Fl e Fl --to-efi
Translate a Unix file path to an EFI Device Path.
The output is the textual representation of the EFI Device Path.
.It Fl u Fl --to-unix
Translate an EFI device path to a Unix file path.
The input is the textual representation of the EFI Device Path.
.El
.Sh SEE ALSO
Appendix A of the UEFI specification has the format for GUIDs.

View File

@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
#include <efivar.h>
#include <efivar-dp.h>
#include <err.h>
#include <errno.h>
#include <getopt.h>
#include <stddef.h>
#include <stdio.h>
@ -42,19 +43,21 @@ __FBSDID("$FreeBSD$");
/* options descriptor */
static struct option longopts[] = {
{ "to-unix", no_argument, NULL, 'u' },
{ "to-efi", no_argument, NULL, 'e' },
{ "format", no_argument, NULL, 'f' },
{ "parse", no_argument, NULL, 'p' },
{ NULL, 0, NULL, 0 }
};
static int flag_format, flag_parse;
static int flag_format, flag_parse, flag_unix, flag_efi;
static void
usage(void)
{
errx(1, "efidp [-fp]");
errx(1, "efidp [-efpu]");
}
static ssize_t
@ -86,15 +89,21 @@ parse_args(int argc, char **argv)
{
int ch;
while ((ch = getopt_long(argc, argv, "fp",
while ((ch = getopt_long(argc, argv, "efpu",
longopts, NULL)) != -1) {
switch (ch) {
case 'e':
flag_efi++;
break;
case 'f':
flag_format++;
break;
case 'p':
flag_parse++;
break;
case 'u':
flag_unix++;
break;
default:
usage();
}
@ -105,7 +114,7 @@ parse_args(int argc, char **argv)
if (argc >= 1)
usage();
if (flag_parse + flag_format != 1) {
if (flag_parse + flag_format + flag_efi + flag_unix != 1) {
warnx("Can only use one of -p (--parse), "
"and -f (--format)");
usage();
@ -125,49 +134,115 @@ trim(char *s)
return s;
}
static void
unix_to_efi(void)
{
char buffer[MAXSIZE];
char efi[MAXSIZE];
efidp dp;
char *walker;
int rv;
while (fgets(buffer, sizeof(buffer), stdin)) {
walker= trim(buffer);
rv = efivar_unix_path_to_device_path(walker, &dp);
if (rv != 0) {
errno = rv;
warn("Can't convert '%s' to efi", walker);
continue;
}
if (efidp_format_device_path(efi, sizeof(efi),
dp, efidp_size(dp)) < 0) {
warnx("Can't format dp for '%s'", walker);
continue;
}
printf("%s\n", efi);
}
}
static void
efi_to_unix(void)
{
char buffer[MAXSIZE];
char dpbuf[MAXSIZE];
efidp dp;
size_t dplen;
char *walker, *dev, *relpath, *abspath;
int rv;
dp = (efidp)dpbuf;
while (fgets(buffer, sizeof(buffer), stdin)) {
walker= trim(buffer);
dplen = efidp_parse_device_path(walker, dp, sizeof(dpbuf));
rv = efivar_device_path_to_unix_path(dp, &dev, &relpath, &abspath);
if (rv == 0)
printf("%s:%s %s\n", dev, relpath, abspath);
else {
errno = rv;
warn("Can't convert '%s' to unix", walker);
}
}
}
static void
format(void)
{
char buffer[MAXSIZE];
ssize_t fmtlen;
ssize_t len;
void *data;
size_t dplen;
const_efidp dp;
len = read_file(STDIN_FILENO, &data);
if (len == -1)
err(1, "read");
dp = (const_efidp)data;
while (len > 0) {
dplen = efidp_size(dp);
fmtlen = efidp_format_device_path(buffer, sizeof(buffer),
dp, dplen);
if (fmtlen > 0)
printf("%s\n", buffer);
len -= dplen;
dp = (const_efidp)((const char *)dp + dplen);
}
free(data);
}
static void
parse(void)
{
char buffer[MAXSIZE];
efidp dp;
ssize_t dplen;
char *walker;
dplen = MAXSIZE;
dp = malloc(dplen);
if (dp == NULL)
errx(1, "Can't allocate memory.");
while (fgets(buffer, sizeof(buffer), stdin)) {
walker= trim(buffer);
dplen = efidp_parse_device_path(walker, dp, dplen);
if (dplen == -1)
errx(1, "Can't parse %s", walker);
write(STDOUT_FILENO, dp, dplen);
}
free(dp);
}
int
main(int argc, char **argv)
{
char buffer[MAXSIZE];
parse_args(argc, argv);
if (flag_format) {
ssize_t fmtlen;
ssize_t len;
void *data;
size_t dplen;
const_efidp dp;
len = read_file(STDIN_FILENO, &data);
if (len == -1)
err(1, "read");
dp = (const_efidp)data;
while (len > 0) {
dplen = efidp_size(dp);
fmtlen = efidp_format_device_path(buffer, sizeof(buffer),
dp, dplen);
if (fmtlen > 0)
printf("%s\n", buffer);
len -= dplen;
dp = (const_efidp)((const char *)dp + dplen);
}
free(data);
} else if (flag_parse) {
efidp dp;
ssize_t dplen;
char *walker;
dplen = MAXSIZE;
dp = malloc(dplen);
if (dp == NULL)
errx(1, "Can't allocate memory.");
while (fgets(buffer, sizeof(buffer), stdin)) {
walker= trim(buffer);
dplen = efidp_parse_device_path(walker, dp, dplen);
if (dplen == -1)
errx(1, "Can't parse %s", walker);
write(STDOUT_FILENO, dp, dplen);
}
free(dp);
}
if (flag_unix)
efi_to_unix();
else if (flag_efi)
unix_to_efi();
else if (flag_format)
format();
else if (flag_parse)
parse();
}