From b194ae79cd9237e395fce17b01f0e399b4fbdf74 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 12 Nov 2015 10:56:22 -0500 Subject: [PATCH] Add eficonman beginnings Signed-off-by: Peter Jones --- src/.gitignore | 2 + src/Makefile | 7 ++- src/eficonman.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 src/eficonman.c diff --git a/src/.gitignore b/src/.gitignore index efc8f8a..db68884 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1 +1,3 @@ efibootmgr +eficonman +efibootnext diff --git a/src/Makefile b/src/Makefile index 37fbfa4..61495c5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -7,18 +7,22 @@ include $(TOPDIR)/Make.defaults SUBDIR_CFLAGS = -I$(SRCDIR)/include -BINTARGETS=efibootmgr +BINTARGETS=efibootmgr eficonman TARGETS=$(BINTARGETS) all : deps $(TARGETS) EFIBOOTMGR_SOURCES = efibootmgr.c efi.c unparse_path.c +EFICONMAN_SOURCES = eficonman.c ALL_SOURCES=$(EFIBOOTMGR_SOURCES) -include $(call deps-of,$(ALL_SOURCES)) efibootmgr : $(call objects-of,$(EFIBOOTMGR_SOURCES)) efibootmgr : PKGS=efivar efiboot +eficonman : $(call objects-of,$(EFICONMAN_SOURCES)) +eficonman : PKGS=efivar efiboot popt + deps : $(ALL_SOURCES) $(MAKE) -f $(TOPDIR)/Make.deps deps SOURCES="$(ALL_SOURCES)" SUBDIR_CFLAGS="$(SUBDIR_CFLAGS)" @@ -29,6 +33,7 @@ clean : install : $(INSTALL) -d -m 755 $(DESTDIR)/$(sbindir)/ $(INSTALL) -m 755 efibootmgr $(DESTDIR)/$(sbindir)/efibootmgr + $(INSTALL) -m 755 eficonman $(DESTDIR)/$(sbindir)/eficonman $(INSTALL) -d -m 755 $(DESTDIR)/$(mandir)/man8/ $(INSTALL) -m 644 efibootmgr.8 $(DESTDIR)/$(mandir)/man8/efibootmgr.8 diff --git a/src/eficonman.c b/src/eficonman.c new file mode 100644 index 0000000..3cd264b --- /dev/null +++ b/src/eficonman.c @@ -0,0 +1,161 @@ +/* + * eficonman.c - console manager for UEFI + * + * Copyright 2015 Red Hat, Inc. + * + * See "COPYING" for license terms. + * + * Author: Peter Jones + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define _(String) gettext (String) +#define Q_(String) dgettext (NULL, String) +#define C_(Context,String) dgettext (Context,String) + +/* ConIn-8be4df61-93ca-11d2-aa0d-00e098032b8c + * ConInDev-8be4df61-93ca-11d2-aa0d-00e098032b8c + * ConOut-8be4df61-93ca-11d2-aa0d-00e098032b8c + * ConOutDev-8be4df61-93ca-11d2-aa0d-00e098032b8c + * ErrOut-8be4df61-93ca-11d2-aa0d-00e098032b8c + * ErrOutDev-8be4df61-93ca-11d2-aa0d-00e098032b8c + * Key0000-8be4df61-93ca-11d2-aa0d-00e098032b8c + * Key0001-8be4df61-93ca-11d2-aa0d-00e098032b8c + * Lang-8be4df61-93ca-11d2-aa0d-00e098032b8c + * LangCodes-8be4df61-93ca-11d2-aa0d-00e098032b8c + */ + +#define ACTION_INACTION 0x00 +#define ACTION_INFO 0x01 + +static int +do_list(void) +{ + struct { + char *varname; + char *label; + } vars[] = { + {"ConInDev", "Available console input devices"}, + {"ConOutDev", "Available console ouput devices"}, + {"ErrOutDev", "Available error output devices"}, + {"ConIn", "Configured console input devices"}, + {"ConOut", "Configured console ouptut devices"}, + {"ErrOut", "Configured error output devices"}, + {NULL, NULL} + }; + for (int i = 0; vars[i].varname != NULL; i++) { + uint8_t *data; + size_t data_size; + uint32_t attrs; + int rc; + const_efidp whole_dp, dp; + + rc = efi_get_variable(efi_guid_global, vars[i].varname, + &data, &data_size, &attrs); + if (rc < 0) { + printf("%s: none\n", vars[i].label); + continue; + } + whole_dp = (const_efidp)data; + printf("%s:\n", vars[i].label); + if (!efidp_is_valid(whole_dp, data_size)) { + printf("\tdata is invalid\n"); + continue; + } + dp = whole_dp; + while (dp) { + ssize_t sz, ssz; + char *s = NULL; + + if (efidp_is_multiinstance(dp)) { + sz = efidp_instance_size(dp); + if (sz < 0) + err(1, "efidp_instance_size()"); + } else { + sz = efidp_size(dp); + if (sz < 0) + err(1, "efidp_size()"); + } + + ssz = efidp_format_device_path(NULL, 0, dp, sz); + if (ssz < 0) + err(1, "efidp_format_device_path()"); + + s = alloca(ssz + 1); + ssz = efidp_format_device_path(s, ssz, dp, sz); + if (ssz < 0) + err(1, "efidp_format_device_path()"); + s[ssz] = '\0'; + printf("\t%s\n", s); + + if (!efidp_is_multiinstance(dp)) + break; + + rc = efidp_get_next_end(dp, &dp); + if (rc < 0) + break; + + rc = efidp_next_instance(dp, &dp); + if (rc < 0) + break; + } + } + return 0; +} + +int +main(int argc, char *argv[]) +{ + int action = 0; + int quiet = 0; + + setlocale(LC_ALL, ""); + bindtextdomain("eficonman", LOCALEDIR); + textdomain("eficonman"); + + struct poptOption options[] = { + {NULL, '\0', POPT_ARG_INTL_DOMAIN, "eficonman" }, + {"info", 'i', POPT_ARG_VAL|POPT_ARGFLAG_OR, &action, + ACTION_INFO, _("Display console information"), + NULL }, + {"quiet", 'q', POPT_ARG_VAL, &quiet, 1, _("Work quietly"), + NULL}, + POPT_AUTOALIAS + POPT_AUTOHELP + POPT_TABLEEND + }; + + poptContext optcon; + optcon = poptGetContext("eficonman", argc, (const char **)argv, options, 0); + + int rc; + rc = poptReadDefaultConfig(optcon, 0); + if (rc < 0 && !(rc == POPT_ERROR_ERRNO && errno == ENOENT)) + errx(1, _("poptReadDefaultConfig failed: %s: %s"), + poptBadOption(optcon, 0), poptStrerror(rc)); + + while ((rc = poptGetNextOpt(optcon)) > 0) + ; + + switch (action) { + case ACTION_INFO: + do_list(); + break; + case ACTION_INACTION: + default: + poptPrintUsage(optcon, stderr, 0); + exit(1); + } + return 0; +} -- 2.11.0