├── NOTICE ├── MODULE_LICENSE_GPL2 ├── Make.version ├── src ├── .gitignore ├── Android.mk ├── efibootdump.8.in ├── include │ ├── parse_loader_data.h │ ├── efi.h │ ├── efibootmgr.h │ └── list.h ├── Makefile ├── parse_loader_data.c ├── fix_coverity.h ├── error.h ├── eficonman.c ├── efibootnext.c ├── efibootdump.c ├── efibootmgr.8.in ├── efi.c └── efibootmgr.c ├── .gitignore ├── Make.deps ├── Make.fanalyzer ├── .github └── workflows │ └── ci.yml ├── INSTALL ├── TODO ├── Make.scan-build ├── AUTHORS ├── Make.coverity ├── Make.rules ├── Makefile ├── Make.defaults ├── efibootmgr.spec.in ├── README ├── README.md ├── CODE_OF_CONDUCT.md └── COPYING /NOTICE: -------------------------------------------------------------------------------- 1 | COPYING -------------------------------------------------------------------------------- /MODULE_LICENSE_GPL2: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Make.version: -------------------------------------------------------------------------------- 1 | VERSION=17 2 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | *.8 2 | efibootmgr 3 | eficonman 4 | efibootnext 5 | efibootdump 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .*.sw? 2 | *.E 3 | *.o 4 | *.patch 5 | *.S 6 | efibootmgr-*.tar.* 7 | core.* 8 | efibootmgr*.zip 9 | efibootmgr.spec 10 | .*.d 11 | cov-int 12 | scan-results/ 13 | -------------------------------------------------------------------------------- /Make.deps: -------------------------------------------------------------------------------- 1 | SRCDIR = $(realpath .) 2 | TOPDIR = $(realpath ..) 3 | 4 | include $(TOPDIR)/Make.version 5 | include $(TOPDIR)/Make.rules 6 | include $(TOPDIR)/Make.defaults 7 | 8 | .%.d : %.c 9 | $(CC) $(cflags) $(CPPFLAGS) -MM -MG -MF $@ $^ 10 | 11 | .%.d : %.S 12 | $(CC) $(cflags) $(CPPFLAGS) -MM -MG -MF $@ $^ 13 | 14 | SOURCES ?= 15 | deps : $(call deps-of,$(filter-out %.h,$(SOURCES))) 16 | -------------------------------------------------------------------------------- /Make.fanalyzer: -------------------------------------------------------------------------------- 1 | GCC_BINARY ?= $(shell x=$$(which --skip-alias --skip-functions gcc 2>/dev/null) ; [ -n "$$x" ] && echo "$$x") 2 | 3 | fanalyzer-test : ; $(if $(findstring /,$(GCC_BINARY)),,$(error gcc not found)) 4 | 5 | fanalyzer : | fanalyzer-test 6 | fanalyzer : clean 7 | $(MAKE) CC=gcc CCACHE_DISABLE=1 CFLAGS="-O2 -g -fanalyzer -Werror=analyzer-null-dereference" 8 | 9 | .PHONY : fanalyzer 10 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pull-request", 3 | "on": { 4 | "push": { "branches": "master" }, 5 | "pull_request": { "branches": "master" }, 6 | }, 7 | "jobs": { 8 | "linux": { 9 | "runs-on": "ubuntu-latest", 10 | "container": "vathpela/efi-ci:f35-x64", 11 | "steps": [ 12 | { "uses": "actions/checkout@v2" }, 13 | { "run": "EFIDIR=test make" }, 14 | ], 15 | }, 16 | }, 17 | } 18 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Running 'make' builds the file src/efibootmgr. 2 | efibootmgr should be placed into /usr/sbin/. 3 | 4 | efibootmgr currently requires efivar version 0.19, as well as the pkg-config 5 | utility, to be built. If you receive a message like the following: 6 | 7 | src/include/efi.h:32:20: fatal error: efivar.h: No such file or directory 8 | 9 | then you have not installed these dependencies, which can be found at: 10 | 11 | efivar: https://github.com/rhboot/efivar 12 | pkg-config: https://pkgconfig.freedesktop.org 13 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | - support for setting hotkeys 2 | - support for driver variables, not just boot variables. 3 | - support for arbitrary device paths with -c (including guid parsing) 4 | - maintain a list of known GUIDs and print {vendor} instead of the full GUID 5 | - accept these for arbitrary paths as well. 6 | - these are done in libefivar, but efibootmgr still needs some work on it 7 | - MS-DOS style extended partitions 8 | - lots more network stuff 9 | - IPv6 with various discovery methods 10 | - IPv4 w/o dhcp 11 | - make sure FCoE works 12 | - iscsi 13 | - make sure nvme works 14 | -------------------------------------------------------------------------------- /Make.scan-build: -------------------------------------------------------------------------------- 1 | SCAN_BUILD ?= $(shell x=$$(which --skip-alias --skip-functions scan-build 2>/dev/null) ; [ -n "$$x" ] && echo 1) 2 | ifeq ($(SCAN_BUILD),) 3 | SCAN_BUILD_ERROR = $(error scan-build not found) 4 | endif 5 | 6 | scan-test : ; $(SCAN_BUILD_ERROR) 7 | 8 | scan-clean : clean 9 | @if [[ -d scan-results ]]; then rm -rf scan-results && echo "removed 'scan-results'"; fi 10 | 11 | scan-build : | scan-test 12 | scan-build : clean 13 | scan-build -o scan-results make $(DASHJ) CC=clang all 14 | 15 | scan-build-all : | scan-test 16 | scan-build-all : clean 17 | scan-build -o scan-results make $(DASHJ) CC=clang all 18 | 19 | .PHONY : scan-build scan-clean 20 | 21 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Matt Domsch 2 | - All .c and .h files 3 | 4 | Andreas Schwab 5 | - Patches to several .c and .h files 6 | 7 | Richard Hirst 8 | - Patch to efichar.c 9 | 10 | dann frazier 11 | - docbook of manpage 12 | - Patches to efibootmgr.c 13 | - network boot entry creation in efi.c 14 | 15 | Joshua Giles 16 | - walk the PCI path inserting parent bridge device path components for 17 | network boot and EDD30 entries. 18 | 19 | Alex Williamson 20 | - Patch to efi.c and efibootmgr.c for handling BootXXXX values 21 | using uppercase hex rather than lowercase, per EFI 1.10 spec. 22 | 23 | Rogerio Timmers 24 | - add option -@ for passing extra variable options in from a file, 25 | necessary for setting up some boot entries for Microsoft Windows. 26 | -------------------------------------------------------------------------------- /src/Android.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 The Android-x86 Open Source Project 3 | # 4 | # Licensed under the GNU General Public License Version 2 or later. 5 | # You may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.gnu.org/licenses/gpl.html 9 | # 10 | 11 | LOCAL_PATH := $(call my-dir) 12 | 13 | include $(CLEAR_VARS) 14 | 15 | include $(LOCAL_PATH)/../Make.version 16 | 17 | LOCAL_MODULE := efibootmgr 18 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/include 19 | LOCAL_STATIC_LIBRARIES := libefivar 20 | LOCAL_MODULE_PATH := $(TARGET_INSTALLER_OUT)/sbin 21 | 22 | LOCAL_CFLAGS := \ 23 | -Werror -Wall -Wextra -Wsign-compare -Wstrict-aliasing \ 24 | -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE \ 25 | -DEFIBOOTMGR_VERSION="\"$(VERSION)\"" \ 26 | -DDEFAULT_LOADER=\"\\\\elilo.efi\" 27 | 28 | LOCAL_SRC_FILES := \ 29 | efi.c \ 30 | efibootmgr.c \ 31 | parse_loader_data.c 32 | 33 | include $(BUILD_EXECUTABLE) 34 | -------------------------------------------------------------------------------- /src/efibootdump.8.in: -------------------------------------------------------------------------------- 1 | .TH "EFIBOOTDUMP" "8" "24 February 2016" "" "" 2 | 3 | .SH NAME 4 | efibootdump \- dump a boot entries from a variable or a file 5 | .SH SYNOPSIS 6 | 7 | \fBefibootdump\fR [\fB-?\fR|\fB--help\fR] [\fB--usage\fR] 8 | .br 9 | [\fB-f\fR \fI\fR [... \fB-f\fR \fI\fR]] 10 | .br 11 | [[\fB-g\fR \fI{guid}\fR] \fI\fR [... [\fI\fR]]] 12 | .SH "DESCRIPTION" 13 | .PP 14 | \fBefibootdump\fR is a userspace application used to display individual UEFI boot options, from a file or a UEFI variable. This allows e.g. saved files from efivarfs to be displayed, as well as variables on the running machine. 15 | 16 | .SH "OPTIONS" 17 | The following is a list of options accepted by efibootmgr: 18 | .TP 19 | \fB-g | --guid\fR \fI{guid}\fR 20 | Any variables specified by name have the specified GUID. 21 | .TP 22 | \fB-f | --file\fR \fI\fR 23 | Read a single boot variable from the specified file. 24 | .TP 25 | \fI\fR 26 | Display the specified variable on the local machine. If no GUID is specified, EFI Global Variable is the default. 27 | .SH "BUGS" 28 | .PP 29 | Please direct any bugs, features, patches, etc. to the Red Hat bootloader team at https://github.com/rhboot/efibootmgr \&. 30 | .SH "SEE ALSO" 31 | .PP 32 | efibootmgr(8) 33 | -------------------------------------------------------------------------------- /src/include/parse_loader_data.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2001 Dell Computer Corporation 3 | Copyright 2014-2019 Peter Jones 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | 20 | #ifndef _PARSE_LOADER_DATA_H 21 | #define _PARSE_LOADER_DATA_H 22 | 23 | #include 24 | #include "efi.h" 25 | 26 | ssize_t parse_efi_guid(char *buffer, size_t buffer_size, 27 | uint8_t *p, uint64_t length); 28 | ssize_t parse_raw_text(char *buffer, size_t buffer_size, 29 | uint8_t *p, uint64_t length); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /Make.coverity: -------------------------------------------------------------------------------- 1 | COV_EMAIL=$(call get-config,coverity.email) 2 | COV_TOKEN=$(call get-config,coverity.token) 3 | COV_URL=$(call get-config,coverity.url) 4 | COV_FILE=$(NAME)-coverity-$(VERSION)-$(COMMIT_ID).tar.bz2 5 | 6 | cov-int : clean 7 | cov-build --dir cov-int make all 8 | 9 | cov-clean : 10 | @rm -vf $(NAME)-coverity-*.tar.* 11 | @if [[ -d cov-int ]]; then rm -rf cov-int && echo "removed 'cov-int'"; fi 12 | 13 | cov-file : | $(COV_FILE) 14 | 15 | $(COV_FILE) : cov-int 16 | tar caf $@ cov-int 17 | 18 | cov-upload : 19 | @if [[ -n "$(COV_URL)" ]] && \ 20 | [[ -n "$(COV_TOKEN)" ]] && \ 21 | [[ -n "$(COV_EMAIL)" ]] ; \ 22 | then \ 23 | echo curl --form token=$(COV_TOKEN) --form email="$(COV_EMAIL)" --form file=@"$(COV_FILE)" --form version=$(VERSION).1 --form description="$(COMMIT_ID)" "$(COV_URL)" ; \ 24 | curl --form token=$(COV_TOKEN) --form email="$(COV_EMAIL)" --form file=@"$(COV_FILE)" --form version=$(VERSION).1 --form description="$(COMMIT_ID)" "$(COV_URL)" ; \ 25 | else \ 26 | echo Coverity output is in $(COV_FILE) ; \ 27 | fi 28 | 29 | coverity : | cov-test 30 | coverity : cov-file cov-upload 31 | 32 | clean : | cov-clean 33 | 34 | COV_BUILD ?= $(shell x=$$(which --skip-alias --skip-functions cov-build 2>/dev/null) ; [ -n "$$x" ] && echo 1) 35 | ifeq ($(COV_BUILD),) 36 | COV_BUILD_ERROR = $(error cov-build not found) 37 | endif 38 | 39 | cov-test : ; $(COV_BUILD_ERROR) 40 | 41 | .PHONY : coverity cov-upload cov-clean cov-file cov-test 42 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | SRCDIR = $(realpath .) 2 | TOPDIR = $(realpath ..) 3 | 4 | include $(TOPDIR)/Make.version 5 | include $(TOPDIR)/Make.rules 6 | include $(TOPDIR)/Make.defaults 7 | 8 | SUBDIR_CFLAGS = -I$(SRCDIR)/include 9 | 10 | BINTARGETS=efibootmgr efibootdump 11 | TARGETS=$(BINTARGETS) efibootmgr.8 efibootdump.8 12 | 13 | all : deps $(TARGETS) 14 | 15 | EFIBOOTMGR_SOURCES = efibootmgr.c efi.c parse_loader_data.c 16 | EFICONMAN_SOURCES = eficonman.c 17 | EFIBOOTDUMP_SOURCES = efibootdump.c parse_loader_data.c 18 | EFIBOOTNEXT_SOURCES = efibootnext.c 19 | ALL_SOURCES=$(EFIBOOTMGR_SOURCES) 20 | -include $(call deps-of,$(ALL_SOURCES)) 21 | 22 | efibootmgr : $(call objects-of,$(EFIBOOTMGR_SOURCES)) 23 | efibootmgr : PKGS=efivar efiboot 24 | 25 | eficonman : $(call objects-of,$(EFICONMAN_SOURCES)) 26 | eficonman : PKGS=efivar efiboot popt 27 | 28 | efibootdump : $(call objects-of,$(EFIBOOTDUMP_SOURCES)) 29 | efibootdump : PKGS=efivar efiboot popt 30 | 31 | efibootnext : $(call objects-of,$(EFIBOOTNEXT_SOURCES)) 32 | efibootnext : PKGS=efivar efiboot popt 33 | 34 | deps : PKGS=efivar efiboot popt 35 | deps : $(ALL_SOURCES) 36 | $(MAKE) -f $(TOPDIR)/Make.deps \ 37 | SOURCES="$(ALL_SOURCES)" \ 38 | SUBDIR_CFLAGS="$(SUBDIR_CFLAGS)" \ 39 | PKGS="$(PKGS)" \ 40 | deps 41 | 42 | clean : 43 | @rm -rfv *.o *.a *.so $(TARGETS) 44 | @rm -rfv .*.d 45 | 46 | install : $(TARGETS) 47 | $(INSTALL) -d -m 755 $(DESTDIR)/$(sbindir)/ 48 | $(INSTALL) -m 755 efibootmgr $(DESTDIR)/$(sbindir)/efibootmgr 49 | $(INSTALL) -m 755 efibootdump $(DESTDIR)/$(sbindir)/efibootdump 50 | $(INSTALL) -d -m 755 $(DESTDIR)/$(mandir)/man8/ 51 | $(INSTALL) -m 644 efibootmgr.8 $(DESTDIR)/$(mandir)/man8/efibootmgr.8 52 | $(INSTALL) -m 644 efibootdump.8 $(DESTDIR)/$(mandir)/man8/efibootdump.8 53 | 54 | .PHONY : all deps clean install 55 | -------------------------------------------------------------------------------- /Make.rules: -------------------------------------------------------------------------------- 1 | default : all 2 | 3 | .PHONY: default all deps clean install 4 | 5 | include $(TOPDIR)/Make.version 6 | 7 | all : deps 8 | 9 | deps : 10 | 11 | clean : 12 | 13 | install : 14 | 15 | %.a : %.so 16 | $(AR) -cvqs $@ $^ 17 | 18 | % : %.c 19 | 20 | % : | %.c 21 | $(CCLD) $(ccldflags) $(CPPFLAGS) -o $@ $^ $(LDLIBS) 22 | 23 | %-static : %.c 24 | $(CCLD) $(ccldflags) $(CPPFLAGS) -o $@ $^ $(LDLIBS) 25 | 26 | %.so : 27 | $(CCLD) $(ccldflags) $(CPPFLAGS) $(SOFLAGS) \ 28 | -Wl,-soname,$@.$(VERSION) \ 29 | -o $@ $^ $(LDLIBS) 30 | 31 | %.o : %.c 32 | $(CC) $(cflags) $(CPPFLAGS) -c -o $@ $(filter %.c %.o %.S,$^) 33 | 34 | %.S: %.c 35 | $(CC) $(cflags) $(CPPFLAGS) -S $< -o $@ 36 | 37 | %.E: %.c 38 | $(CC) $(cflags) $(CPPFLAGS) -E $< -o $@ 39 | 40 | %.c : %.h 41 | 42 | .%.d : 43 | 44 | define substitute-version = 45 | sed \ 46 | -e "s,@@VERSION@@,$(VERSION),g" \ 47 | -e "s,@@LIBDIR@@,$(libdir),g" \ 48 | -e "s,@@LIBEXECDIR@@,$(libexecdir),g" \ 49 | -e "s,@@EFIDIR@@,$(EFIDIR),g" \ 50 | -e "s,@@EFI_LOADER@@,$(EFI_LOADER),g" \ 51 | -e 's,@@DEFAULT_LOADER@@,\\\\EFI\\\\$(EFIDIR)\\\\$(EFI_LOADER),g' \ 52 | $(1) > $(2) 53 | endef 54 | 55 | %.8 : %.8.in 56 | @$(call substitute-version,$<,$@) 57 | 58 | %.pc : %.pc.in 59 | @$(call substitute-version,$<,$@) 60 | 61 | %.spec : %.spec.in 62 | @$(call substitute-version,$<,$@) 63 | 64 | pkg-config-cflags = \ 65 | $(shell if [ -n "$(PKGS)" ]; then $(PKG_CONFIG) --cflags $(PKGS); fi) 66 | pkg-config-ldflags = \ 67 | $(shell if [ -n "$(PKGS)" ]; then $(PKG_CONFIG) --libs-only-L --libs-only-other $(PKGS) ; fi) 68 | pkg-config-ldlibs = \ 69 | $(shell if [ -n "$(PKGS)" ]; then $(PKG_CONFIG) --libs-only-l $(PKGS) ; fi) 70 | 71 | objects-of = \ 72 | $(patsubst %.c,%.o,$(1)) 73 | 74 | define deps-of = 75 | $(foreach src,$(filter %.c,$(1)),$(patsubst %.c,.%.d,$(src))) \ 76 | $(foreach src,$(filter %.S,$(1)),$(patsubst %.S,.%.d,$(src))) 77 | endef 78 | 79 | define get-config = 80 | $(shell git config --local --get "efibootmgr.$(1)") 81 | endef 82 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TOPDIR = $(shell echo $$PWD) 2 | 3 | include $(TOPDIR)/Make.version 4 | include $(TOPDIR)/Make.rules 5 | include $(TOPDIR)/Make.defaults 6 | include $(TOPDIR)/Make.coverity 7 | include $(TOPDIR)/Make.fanalyzer 8 | include $(TOPDIR)/Make.scan-build 9 | 10 | SUBDIRS := src 11 | 12 | all install deps : | check_efidir_error Make.version 13 | @set -e ; for x in $(SUBDIRS) ; do \ 14 | $(MAKE) -C $$x $@ ; \ 15 | done 16 | 17 | clean : | check_efidir_error Make.version 18 | @set -e ; for x in $(SUBDIRS) ; do \ 19 | $(MAKE) -C $$x $@ ; \ 20 | done 21 | 22 | all : efibootmgr.spec 23 | 24 | efibootmgr efibootmgr-static : 25 | $(MAKE) -C src $@ 26 | 27 | $(SUBDIRS) : 28 | $(MAKE) -C $@ 29 | 30 | .PHONY: $(SUBDIRS) 31 | 32 | efibootmgr.spec : | Makefile Make.version 33 | 34 | distclean : 35 | $(MAKE) clean 36 | @rm -vf efibootmgr.spec 37 | 38 | GITTAG = $(shell bash -c "echo $$(($(VERSION) + 1))") 39 | 40 | test-archive: efibootmgr.spec 41 | @rm -rf /tmp/efibootmgr-$(GITTAG) /tmp/efibootmgr-$(GITTAG)-tmp 42 | @mkdir -p /tmp/efibootmgr-$(GITTAG)-tmp 43 | @git archive --format=tar $(shell git branch | awk '/^*/ { print $$2 }') | ( cd /tmp/efibootmgr-$(GITTAG)-tmp/ ; tar x ) 44 | @git diff | ( cd /tmp/efibootmgr-$(GITTAG)-tmp/ ; patch -s -p1 -b -z .gitdiff ) 45 | @mv /tmp/efibootmgr-$(GITTAG)-tmp/ /tmp/efibootmgr-$(GITTAG)/ 46 | @cp efibootmgr.spec /tmp/efibootmgr-$(GITTAG)/ 47 | @dir=$$PWD; cd /tmp; tar -c --bzip2 -f $$dir/efibootmgr-$(GITTAG).tar.bz2 efibootmgr-$(GITTAG) 48 | @rm -rf /tmp/efibootmgr-$(GITTAG) 49 | @echo "The archive is in efibootmgr-$(GITTAG).tar.bz2" 50 | 51 | bumpver : 52 | @echo VERSION=$(GITTAG) > Make.version 53 | @git add Make.version 54 | git commit -m "Bump version to $(GITTAG)" -s 55 | 56 | tag: 57 | git tag -s $(GITTAG) refs/heads/master 58 | 59 | archive: bumpver tag efibootmgr.spec 60 | @rm -rf /tmp/efibootmgr-$(GITTAG) /tmp/efibootmgr-$(GITTAG)-tmp 61 | @mkdir -p /tmp/efibootmgr-$(GITTAG)-tmp 62 | @git archive --format=tar $(GITTAG) | ( cd /tmp/efibootmgr-$(GITTAG)-tmp/ ; tar x ) 63 | @mv /tmp/efibootmgr-$(GITTAG)-tmp/ /tmp/efibootmgr-$(GITTAG)/ 64 | @cp efibootmgr.spec /tmp/efibootmgr-$(GITTAG)/ 65 | @dir=$$PWD; cd /tmp; tar -c --bzip2 -f $$dir/efibootmgr-$(GITTAG).tar.bz2 efibootmgr-$(GITTAG) 66 | @rm -rf /tmp/efibootmgr-$(GITTAG) 67 | @echo "The archive is in efibootmgr-$(GITTAG).tar.bz2" 68 | 69 | -------------------------------------------------------------------------------- /src/parse_loader_data.c: -------------------------------------------------------------------------------- 1 | /* 2 | unparse_path.[ch] 3 | 4 | Copyright (C) 2001 Dell Computer Corporation 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | /* For PRIx64 */ 22 | #define __STDC_FORMAT_MACROS 23 | 24 | #include "fix_coverity.h" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include "efi.h" 36 | #include "parse_loader_data.h" 37 | 38 | /* Avoid unaligned access warnings */ 39 | #define get(buf, obj) *(typeof(obj) *)memcpy(buf, &obj, sizeof(obj)) 40 | 41 | extern int verbose; 42 | 43 | ssize_t 44 | parse_efi_guid(char *buffer, size_t buffer_size, uint8_t *p, uint64_t length) 45 | { 46 | ssize_t needed = 0; 47 | 48 | if (length == sizeof(efi_guid_t)) { 49 | needed = efi_guid_to_id_guid((efi_guid_t *)p, NULL); 50 | if (buffer && needed > 0 && buffer_size >= (size_t)needed) 51 | needed = efi_guid_to_id_guid((efi_guid_t *)p, &buffer); 52 | } 53 | 54 | return needed; 55 | } 56 | 57 | ssize_t 58 | parse_raw_text(char *buf, size_t buf_size, uint8_t *p, uint64_t length) 59 | { 60 | uint64_t i; 61 | unsigned char c; 62 | bool print_hex = false; 63 | 64 | ssize_t needed; 65 | size_t buf_offset = 0; 66 | 67 | for (i=0; i < length; i++) { 68 | c = p[i]; 69 | if (c < 32 || c > 127) 70 | print_hex = true; 71 | } 72 | for (i=0; i < length; i++) { 73 | c = p[i]; 74 | needed = snprintf(buf + buf_offset, 75 | buf_size == 0 ? 0 : buf_size - buf_offset, 76 | print_hex ? "%02hhx" : "%c", c); 77 | if (needed < 0) 78 | return -1; 79 | buf_offset += needed; 80 | } 81 | return buf_offset; 82 | } 83 | -------------------------------------------------------------------------------- /Make.defaults: -------------------------------------------------------------------------------- 1 | NAME = efibootmgr 2 | prefix ?= /usr 3 | libdir ?= $(prefix)/lib64 4 | datadir ?= $(prefix)/share 5 | mandir ?= $(datadir)/man 6 | includedir ?= $(prefix)/include 7 | bindir ?= $(prefix)/bin 8 | sbindir ?= $(prefix)/sbin 9 | localedir ?= $(datadir)/locale/ 10 | PCDIR ?= $(libdir)/pkgconfig 11 | DESTDIR ?= 12 | ifneq ($(origin EXTRALIBDIRS),undefined) 13 | override EXTRALIBDIR := $(foreach dir,$(EXTRALIBDIRS),-L$(dir)) 14 | endif 15 | ifneq ($(origin EXTRAINCDIRS),undefined) 16 | override EXTRAINCDIR := $(foreach dir,$(EXTRAINCDIRS),-I$(dir)) 17 | endif 18 | 19 | EFIDIR ?= $(shell x=$$(which --skip-alias --skip-functions git 2>/dev/null) ; [ -n "$$x" ] && git config --get efibootmgr.efidir) 20 | ifeq ($(EFIDIR),) 21 | EFIDIR_ERROR = $(error EFIDIR or .gitconfig efibootmgr.efidir must be set to this distro's reserved EFI System Partition subdirectory name) 22 | endif 23 | EFI_LOADER := grub.efi 24 | 25 | INSTALL ?= install 26 | CROSS_COMPILE ?= 27 | PKG_CONFIG = $(CROSS_COMPILE)pkg-config 28 | CC := $(if $(filter default,$(origin CC)),$(CROSS_COMPILE)gcc,$(CC)) 29 | CCLD := $(if $(filter undefined,$(origin CCLD)),$(CC),$(CCLD)) 30 | CFLAGS ?= -O2 -g -flto 31 | AR := $(CROSS_COMPILE)gcc-ar 32 | NM := $(CROSS_COMPILE)gcc-nm 33 | RANLIB := $(CROSS_COMPILE)gcc-ranlib 34 | 35 | PKGS = 36 | 37 | SUBDIR_CFLAGS ?= 38 | clang_cflags = 39 | gcc_cflags = 40 | cflags = $(EXTRALIBDIR) $(EXTRAINCDIR) $(CFLAGS) $(SUBDIR_CFLAGS) \ 41 | -Werror -Wall -Wextra -Wsign-compare -Wstrict-aliasing \ 42 | -std=gnu11 -fPIC \ 43 | -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -DLOCALEDIR=\"$(localedir)\" \ 44 | -DEFIBOOTMGR_VERSION="\"$(VERSION)\"" \ 45 | -DDEFAULT_LOADER=\"\\\\EFI\\\\$(EFIDIR)\\\\$(EFI_LOADER)\" \ 46 | $(if $(findstring clang,$(CC)),$(clang_cflags),) \ 47 | $(if $(findstring gcc,$(CC)),$(gcc_cflags),) \ 48 | $(call pkg-config-cflags) 49 | clang_ccldflags = 50 | gcc_ccldflags = -fno-merge-constants \ 51 | -Wl,--fatal-warnings,--no-allow-shlib-undefined \ 52 | -Wl,-O2 -Wl,--no-undefined-version 53 | ccldflags = $(cflags) $(CCLDFLAGS) $(LDFLAGS) \ 54 | $(if $(findstring clang,$(CCLD)),$(clang_ccldflags),) \ 55 | $(if $(findstring gcc,$(CCLD)),$(gcc_ccldflags),) \ 56 | $(call pkg-config-ldflags) 57 | CPPFLAGS?= 58 | SOFLAGS=-shared 59 | LDLIBS=$(foreach lib,$(LIBS),-l$(lib)) $(call pkg-config-ldlibs) 60 | 61 | .PHONY: check_efidir_error 62 | check_efidir_error : ; $(EFIDIR_ERROR) $(info Building with EFIDIR as $(EFIDIR)) 63 | 64 | COMMIT_ID=$(shell git log -1 --pretty=%H 2>/dev/null || echo master) 65 | -------------------------------------------------------------------------------- /src/include/efi.h: -------------------------------------------------------------------------------- 1 | /* 2 | efi.[ch] - Extensible Firmware Interface definitions 3 | 4 | Copyright (C) 2001, 2003 Dell Computer Corporation 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #ifndef EFI_H 22 | #define EFI_H 23 | 24 | /* 25 | * Extensible Firmware Interface 26 | * Based on 'Extensible Firmware Interface Specification' 27 | * version 1.02, 12 December, 2000 28 | */ 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | /******************************************************* 35 | * Boot Option Attributes 36 | *******************************************************/ 37 | #define LOAD_OPTION_ACTIVE 0x00000001 38 | #define LOAD_OPTION_FORCE_RECONNECT 0x00000002 39 | #define LOAD_OPTION_HIDDEN 0x00000008 40 | 41 | #define LOAD_OPTION_CATEGORY_MASK 0x00001f00 42 | #define LOAD_OPTION_CATEGORY_BOOT 0x00000000 43 | #define LOAD_OPTION_CATEGORY_APP 0x00000100 44 | 45 | /******************************************************* 46 | * GUIDs 47 | *******************************************************/ 48 | #define BLKX_UNKNOWN_GUID \ 49 | EFI_GUID( 0x47c7b225, 0xc42a, 0x11d2, 0x8e57, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b) 50 | #define ADDRESS_RANGE_MIRROR_VARIABLE_GUID \ 51 | EFI_GUID( 0x7b9be2e0, 0xe28a, 0x4197, 0xad3e, 0x32, 0xf0, 0x62, 0xf9, 0x46, 0x2c) 52 | 53 | /* Exported functions */ 54 | 55 | extern int read_boot_var_names(char ***namelist); 56 | extern int read_var_names(const char *prefix, char ***namelist); 57 | extern ssize_t make_linux_load_option(uint8_t **data, size_t *data_size, 58 | uint8_t *optional_data, size_t optional_data_size); 59 | extern ssize_t get_extra_args(uint8_t *data, ssize_t data_size); 60 | 61 | typedef struct { 62 | uint8_t mirror_version; 63 | uint8_t mirror_memory_below_4gb; 64 | uint16_t mirror_amount_above_4gb; 65 | uint8_t mirror_status; 66 | } __attribute__((packed)) ADDRESS_RANGE_MIRROR_VARIABLE_DATA; 67 | 68 | #define MIRROR_VERSION 1 69 | 70 | #define ADDRESS_RANGE_MIRROR_VARIABLE_CURRENT "MirrorCurrent" 71 | #define ADDRESS_RANGE_MIRROR_VARIABLE_REQUEST "MirrorRequest" 72 | 73 | #endif /* EFI_H */ 74 | -------------------------------------------------------------------------------- /src/include/efibootmgr.h: -------------------------------------------------------------------------------- 1 | /* 2 | efibootmgr.h - Manipulates EFI variables as exported in /proc/efi/vars 3 | 4 | Copyright (C) 2001 Dell Computer Corporation 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #ifndef _EFIBOOTMGR_H 22 | #define _EFIBOOTMGR_H 23 | 24 | #define EFIBOOTMGR_IPV4 0 25 | #define EFIBOOTMGR_IPV6 1 26 | 27 | #define EFIBOOTMGR_IPV4_ORIGIN_DHCP 0 28 | #define EFIBOOTMGR_IPV4_ORIGIN_STATIC 1 29 | #define EFIBOOTMGR_IPV6_ORIGIN_STATIC 0 30 | #define EFIBOOTMGR_IPV6_ORIGIN_STATELESS 1 31 | #define EFIBOOTMGR_IPV6_ORIGIN_STATEFUL 2 32 | 33 | #define EFIBOOTMGR_PATH_ABBREV_UNSPECIFIED 0 34 | #define EFIBOOTMGR_PATH_ABBREV_EDD10 1 35 | #define EFIBOOTMGR_PATH_ABBREV_HD 2 36 | #define EFIBOOTMGR_PATH_ABBREV_NONE 3 37 | #define EFIBOOTMGR_PATH_ABBREV_FILE 4 38 | 39 | typedef enum { 40 | boot, 41 | driver, 42 | sysprep, 43 | } ebm_mode; 44 | 45 | typedef struct { 46 | int argc; 47 | char **argv; 48 | int optind; 49 | char *disk; 50 | 51 | int ip_version; 52 | char *iface; 53 | char *macaddr; 54 | char *local_ip_addr; 55 | char *remote_ip_addr; 56 | char *gateway_ip_addr; 57 | char *ip_netmask; 58 | uint16_t ip_local_port; 59 | uint16_t ip_remote_port; 60 | uint16_t ip_protocol; 61 | uint8_t ip_addr_origin; 62 | 63 | char *loader; 64 | unsigned char *label; 65 | char *order; 66 | int keep_old_entries; 67 | char *testfile; 68 | char *extra_opts_file; 69 | uint32_t part; 70 | int abbreviate_path; 71 | uint32_t edd10_devicenum; 72 | int num; 73 | int bootnext; 74 | int verbose; 75 | int active; 76 | int reconnect; 77 | int below4g; 78 | int above4g; 79 | int deduplicate; 80 | unsigned int delete:1; 81 | unsigned int delete_order:1; 82 | unsigned int delete_bootnext:1; 83 | unsigned int quiet:1; 84 | unsigned int showversion:1; 85 | unsigned int create:1; 86 | unsigned int unicode:1; 87 | unsigned int write_signature:1; 88 | unsigned int forcegpt:1; 89 | unsigned int set_timeout:1; 90 | unsigned int delete_timeout:1; 91 | unsigned int set_mirror_lo:1; 92 | unsigned int set_mirror_hi:1; 93 | unsigned int no_order:1; 94 | unsigned int driver:1; 95 | unsigned int sysprep:1; 96 | unsigned int explicit_label:1; 97 | short int timeout; 98 | } efibootmgr_opt_t; 99 | 100 | extern efibootmgr_opt_t opts; 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /src/fix_coverity.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fix_coverity.h 3 | * Copyright 2017 Peter Jones 4 | * 5 | * Distributed under terms of the GPLv3 license. 6 | */ 7 | 8 | #ifndef FIX_COVERITY_H 9 | #define FIX_COVERITY_H 10 | 11 | #ifndef _GNU_SOURCE 12 | #define _GNU_SOURCE 13 | #endif 14 | 15 | #ifndef __COVERITY_GCC_VERSION_AT_LEAST 16 | #define __COVERITY_GCC_VERSION_AT_LEAST(x, y) 0 17 | #define FAKE__COVERITY_GCC_VERSION_AT_LEAST__ 18 | #endif /* __COVERITY_GCC_VERSION_AT_LEAST */ 19 | 20 | /* With gcc 7 on x86_64 (at least), coverity pretends to be GCC but 21 | * accidentally doesn't create all of the types GCC would. 22 | * 23 | * In glibc's headers, bits/floatn.h has: 24 | * 25 | * #if (defined __x86_64__ \ 26 | * ? __GNUC_PREREQ (4, 3) \ 27 | * : (defined __GNU__ ? __GNUC_PREREQ (4, 5) : __GNUC_PREREQ (4, 4))) 28 | * # define __HAVE_FLOAT128 1 29 | * #else 30 | * # define __HAVE_FLOAT128 0 31 | * #endif 32 | * 33 | * and stdlib.h has: 34 | * 35 | * #if __HAVE_FLOAT128 && __GLIBC_USE (IEC_60559_TYPES_EXT) 36 | * slash* Likewise for the '_Float128' format *slash 37 | * extern _Float128 strtof128 (const char *__restrict __nptr, 38 | * char **__restrict __endptr) 39 | * __THROW __nonnull ((1)); 40 | * #endif 41 | * 42 | * Which then causes cov-emit to lose its shit: 43 | * 44 | * "/usr/include/stdlib.h", line 133: error #20: identifier "_Float128" is 45 | * undefined 46 | * extern _Float128 strtof128 (const char *__restrict __nptr, 47 | * ^ 48 | * "/usr/include/stdlib.h", line 190: error #20: identifier "_Float128" is 49 | * undefined 50 | * _Float128 __f) 51 | * ^ 52 | * "/usr/include/stdlib.h", line 236: error #20: identifier "_Float128" is 53 | * undefined 54 | * extern _Float128 strtof128_l (const char *__restrict __nptr, 55 | * ^ 56 | * 57 | * And then you'll notice something like this later on: 58 | * [WARNING] Emitted 0 C/C++ compilation units (0%) successfully 59 | * 60 | * 0 C/C++ compilation units (0%) are ready for analysis 61 | * For more details, please look at: 62 | * /home/pjones/devel/github.com/dbxtool/master/cov-int/build-log.txt 63 | * 64 | * You would think that if you're writing something that pretends to be 65 | * gcc, and you've got a "build a configuration by running shit through gcc 66 | * and looking at the output" stage (which they do), you would run "gcc -da 67 | * -fdump-tree-all -c -o foo.o foo.c" on an empty file and snarf up all the 68 | * types defined in the foo.c.001t.tu output. Apparently, they do not. 69 | * 70 | * Anyway, even just defining the type doesn't always work in the face of 71 | * how _Complex is defined, so we cheat a bit here. Be prepared to vomit. 72 | */ 73 | #ifdef __x86_64__ 74 | #if __COVERITY_GCC_VERSION_AT_LEAST(7, 0) 75 | #if 0 76 | typedef float _Float128 __attribute__((__mode__(__TF__))); 77 | typedef __complex__ float __cfloat128 __attribute__ ((__mode__ (__TC__))); 78 | typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__TC__))); 79 | #else 80 | #include 81 | #define __cplusplus 201103L 82 | #include 83 | #undef __cplusplus 84 | #endif 85 | #endif 86 | #endif 87 | 88 | #ifdef FAKE__COVERITY_GCC_VERSION_AT_LEAST__ 89 | #undef FAKE__COVERITY_GCC_VERSION_AT_LEAST 90 | #undef __COVERITY_GCC_VERSION_AT_LEAST 91 | #endif 92 | 93 | #endif /* !FIX_COVERITY_H */ 94 | // vim:fenc=utf-8:tw=75 95 | -------------------------------------------------------------------------------- /efibootmgr.spec.in: -------------------------------------------------------------------------------- 1 | Summary: EFI Boot Manager 2 | Name: efibootmgr 3 | Version: @@VERSION@@ 4 | Release: 1%{?dist} 5 | Group: System Environment/Base 6 | License: GPLv2+ 7 | URL: https://github.com/rhboot/%{name}/ 8 | BuildRequires: git, popt-devel 9 | BuildRequires: efivar-libs >= 30-1, efivar-devel >= 30-1 10 | BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXXXX) 11 | # EFI/UEFI don't exist on PPC 12 | ExclusiveArch: %{ix86} x86_64 aarch64 arm 13 | 14 | # for RHEL / Fedora when efibootmgr was part of the elilo package 15 | Conflicts: elilo <= 3.6-6 16 | Obsoletes: elilo <= 3.6-6 17 | 18 | Source0: https://github.com/rhboot/%{name}/releases/download/%{name}-%{version}/%{name}-%{version}.tar.bz2 19 | 20 | %description 21 | %{name} displays and allows the user to edit the UEFI Boot Manager 22 | variables. Additional information about UEFI can be found at 23 | http://www.uefi.org 24 | 25 | %prep 26 | %setup -q 27 | git init 28 | git config user.email "example@example.com" 29 | git config user.name "RHEL Ninjas" 30 | git add . 31 | git commit -a -q -m "%{version} baseline." 32 | git am %{patches} - 14-1 56 | - Update to efibootmgr 14 57 | - Remove "(hex)" from description of --delete-bootnum 58 | - Fix a typo in the popt options 59 | - Add README.md 60 | - make efibootdump install by default 61 | - Man page fixes 62 | - Better compiler detection 63 | - Don't use --default-symver in efibootmgr 64 | - Make -flto part of the overrideable CFLAGS 65 | 66 | * Wed Aug 17 2016 Peter Jones - 13-1 67 | - Update to efibootmgr 13 68 | - Add support for --sysprep and --driver to support UEFI System Prep 69 | Applications and UEFI Drivers. 70 | - use efivar's error reporting facility, and show error traces when 71 | "-v -v" is used. 72 | - Still yet better error codes returned on failures. 73 | - Add -m and -M to support Memory Address Range Mirroring. 74 | - Add efibootdump, to examine Boot* variables found in tarballs in bug 75 | reports and similar. 76 | - miscellaneous bugfixes. 77 | 78 | * Thu May 28 2015 Peter Jones - 0.12-1 79 | - Update to 0.12 80 | - use libefiboot and libefivar to make device paths and load options 81 | - don't depend on -lz or -lpci any more 82 | 83 | * Tue Oct 21 2014 Peter Jones - 0.11.0-1 84 | - Fix "-n" and friends not being assigned/checked right sometimes from 0.10.0-1 85 | - Generate more archives to avoid people using github's, because they're just 86 | bad. 87 | 88 | * Mon Oct 20 2014 Peter Jones - 0.10.0-1 89 | - Make -o parameter validation work better and be more informative 90 | - Better exit values 91 | - Fix a segfault with appending ascii arguments. 92 | 93 | * Tue Sep 09 2014 Peter Jones - 0.8.0-1 94 | - Release 0.8.0 95 | 96 | * Mon Jan 13 2014 Peter Jones - 0.6.1-1 97 | - Release 0.6.1 98 | 99 | * Mon Jan 13 2014 Jared Dominguez 100 | - new home https://github.com/vathpela/efibootmgr 101 | 102 | * Thu Jan 3 2008 Matt Domsch 0.5.4-1 103 | - split efibootmgr into its own RPM for Fedora/RHEL. 104 | 105 | * Tue Aug 24 2004 Matt Domsch 106 | - new home linux.dell.com 107 | 108 | * Fri May 18 2001 Matt Domsch 109 | - See doc/ChangeLog 110 | -------------------------------------------------------------------------------- /src/error.h: -------------------------------------------------------------------------------- 1 | /* 2 | error.h - some error functions to work with efivars error logger. 3 | 4 | Copyright 2016 Red Hat, Inc. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | #ifndef EFIBOOTMGR_ERROR_H__ 21 | #define EFIBOOTMGR_ERROR_H__ 1 22 | 23 | extern int verbose; 24 | 25 | static inline void 26 | __attribute__((__unused__)) 27 | error_reporter(void) 28 | { 29 | int rc = 1; 30 | int saved_errno = errno; 31 | 32 | for (int i = 0; rc > 0; i++) { 33 | char *filename = NULL; 34 | char *function = NULL; 35 | int line = 0; 36 | char *message = NULL; 37 | int error = 0; 38 | 39 | rc = efi_error_get(i, &filename, &function, &line, &message, 40 | &error); 41 | if (rc < 0) { 42 | fprintf(stderr, "error fetching trace value"); 43 | exit(1); 44 | } 45 | if (rc == 0) 46 | break; 47 | fprintf(stderr, " %s:%d %s(): %s: %s\n", 48 | filename, line, function, message, strerror(error)); 49 | } 50 | errno = saved_errno; 51 | } 52 | 53 | static inline void 54 | __attribute__((__unused__)) 55 | conditional_error_reporter(int show, int clear) 56 | { 57 | int saved_errno = errno; 58 | fflush(NULL); 59 | 60 | if (show) { 61 | fprintf(stderr, "error trace:\n"); 62 | error_reporter(); 63 | } 64 | if (clear) { 65 | errno = 0; 66 | efi_error_clear(); 67 | } 68 | errno = saved_errno; 69 | } 70 | 71 | static inline void 72 | __attribute__((__unused__)) 73 | cond_error(int test, int eval, const char *fmt, ...) 74 | { 75 | int saved_errno = errno; 76 | if (!test) 77 | return; 78 | fflush(NULL); 79 | 80 | va_list ap; 81 | va_start(ap, fmt); 82 | vfprintf(stderr, fmt, ap); 83 | errno = saved_errno; 84 | fprintf(stderr, ": %m\n"); 85 | conditional_error_reporter(verbose >= 1, 0); 86 | va_end(ap); 87 | exit(eval); 88 | } 89 | 90 | static inline void 91 | __attribute__((__unused__)) 92 | error(int eval, const char *fmt, ...) 93 | { 94 | int saved_errno = errno; 95 | fflush(NULL); 96 | 97 | va_list ap; 98 | va_start(ap, fmt); 99 | vfprintf(stderr, fmt, ap); 100 | errno = saved_errno; 101 | fprintf(stderr, ": %m\n"); 102 | conditional_error_reporter(verbose >= 1, 0); 103 | va_end(ap); 104 | exit(eval); 105 | } 106 | 107 | static inline void 108 | __attribute__((__unused__)) 109 | errorx(int eval, const char *fmt, ...) 110 | { 111 | fflush(NULL); 112 | 113 | va_list ap; 114 | va_start(ap, fmt); 115 | vfprintf(stderr, fmt, ap); 116 | fprintf(stderr, "\n"); 117 | conditional_error_reporter(verbose >= 1, 1); 118 | va_end(ap); 119 | exit(eval); 120 | } 121 | 122 | static inline void 123 | __attribute__((__unused__)) 124 | cond_warning(int test, const char *fmt, ...) 125 | { 126 | int saved_errno = errno; 127 | if (!test) 128 | return; 129 | 130 | va_list ap; 131 | va_start(ap, fmt); 132 | vprintf(fmt, ap); 133 | errno = saved_errno; 134 | printf(": %m\n"); 135 | conditional_error_reporter(verbose >= 1, 1); 136 | va_end(ap); 137 | } 138 | 139 | static inline void 140 | __attribute__((__unused__)) 141 | warning(const char *fmt, ...) 142 | { 143 | int saved_errno = errno; 144 | va_list ap; 145 | 146 | va_start(ap, fmt); 147 | vprintf(fmt, ap); 148 | errno = saved_errno; 149 | printf(": %m\n"); 150 | conditional_error_reporter(verbose >= 1, 1); 151 | va_end(ap); 152 | } 153 | 154 | static inline void 155 | __attribute__((__unused__)) 156 | warningx(const char *fmt, ...) 157 | { 158 | va_list ap; 159 | 160 | va_start(ap, fmt); 161 | vprintf(fmt, ap); 162 | printf("\n"); 163 | conditional_error_reporter(verbose >= 1, 1); 164 | va_end(ap); 165 | } 166 | #endif /* EFIBOOTMGR_ERROR_H__ */ 167 | -------------------------------------------------------------------------------- /src/eficonman.c: -------------------------------------------------------------------------------- 1 | /* 2 | * eficonman.c - console manager for UEFI 3 | * 4 | * Copyright 2015 Red Hat, Inc. 5 | * 6 | * See "COPYING" for license terms. 7 | * 8 | * Author: Peter Jones 9 | */ 10 | 11 | #include "fix_coverity.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #define _(String) gettext (String) 25 | #define Q_(String) dgettext (NULL, String) 26 | #define C_(Context,String) dgettext (Context,String) 27 | 28 | /* ConIn-8be4df61-93ca-11d2-aa0d-00e098032b8c 29 | * ConInDev-8be4df61-93ca-11d2-aa0d-00e098032b8c 30 | * ConOut-8be4df61-93ca-11d2-aa0d-00e098032b8c 31 | * ConOutDev-8be4df61-93ca-11d2-aa0d-00e098032b8c 32 | * ErrOut-8be4df61-93ca-11d2-aa0d-00e098032b8c 33 | * ErrOutDev-8be4df61-93ca-11d2-aa0d-00e098032b8c 34 | * Key0000-8be4df61-93ca-11d2-aa0d-00e098032b8c 35 | * Key0001-8be4df61-93ca-11d2-aa0d-00e098032b8c 36 | * Lang-8be4df61-93ca-11d2-aa0d-00e098032b8c 37 | * LangCodes-8be4df61-93ca-11d2-aa0d-00e098032b8c 38 | */ 39 | 40 | #define ACTION_INACTION 0x00 41 | #define ACTION_INFO 0x01 42 | 43 | static int 44 | do_list(void) 45 | { 46 | struct { 47 | char *varname; 48 | char *label; 49 | } vars[] = { 50 | {"ConInDev", "Available console input devices"}, 51 | {"ConOutDev", "Available console ouput devices"}, 52 | {"ErrOutDev", "Available error output devices"}, 53 | {"ConIn", "Configured console input devices"}, 54 | {"ConOut", "Configured console ouptut devices"}, 55 | {"ErrOut", "Configured error output devices"}, 56 | {NULL, NULL} 57 | }; 58 | for (int i = 0; vars[i].varname != NULL; i++) { 59 | uint8_t *data; 60 | size_t data_size; 61 | uint32_t attrs; 62 | int rc; 63 | const_efidp whole_dp, dp; 64 | 65 | rc = efi_get_variable(efi_guid_global, vars[i].varname, 66 | &data, &data_size, &attrs); 67 | if (rc < 0) { 68 | printf("%s: none\n", vars[i].label); 69 | continue; 70 | } 71 | whole_dp = (const_efidp)data; 72 | printf("%s:\n", vars[i].label); 73 | if (!efidp_is_valid(whole_dp, data_size)) { 74 | printf("\tdata is invalid\n"); 75 | continue; 76 | } 77 | dp = whole_dp; 78 | while (dp) { 79 | ssize_t sz, ssz; 80 | unsigned char *s = NULL; 81 | 82 | if (efidp_is_multiinstance(dp)) { 83 | sz = efidp_instance_size(dp); 84 | if (sz < 0) 85 | err(1, "efidp_instance_size()"); 86 | } else { 87 | sz = efidp_size(dp); 88 | if (sz < 0) 89 | err(1, "efidp_size()"); 90 | } 91 | 92 | ssz = efidp_format_device_path(NULL, 0, dp, sz); 93 | if (ssz < 0) 94 | err(1, "efidp_format_device_path()"); 95 | 96 | s = alloca(ssz + 1); 97 | ssz = efidp_format_device_path(s, ssz, dp, sz); 98 | if (ssz < 0) 99 | err(1, "efidp_format_device_path()"); 100 | s[ssz] = '\0'; 101 | printf("\t%s\n", s); 102 | 103 | if (!efidp_is_multiinstance(dp)) 104 | break; 105 | 106 | rc = efidp_get_next_end(dp, &dp); 107 | if (rc < 0) 108 | break; 109 | 110 | rc = efidp_next_instance(dp, &dp); 111 | if (rc < 0) 112 | break; 113 | } 114 | } 115 | return 0; 116 | } 117 | 118 | int 119 | main(int argc, char *argv[]) 120 | { 121 | int action = 0; 122 | int quiet = 0; 123 | 124 | setlocale(LC_ALL, ""); 125 | bindtextdomain("eficonman", LOCALEDIR); 126 | textdomain("eficonman"); 127 | 128 | struct poptOption options[] = { 129 | {.argInfo = POPT_ARG_INTL_DOMAIN, 130 | .arg = "eficonman" }, 131 | {.longName = "info", 132 | .shortName = 'i', 133 | .argInfo = POPT_ARG_VAL|POPT_ARGFLAG_OR, 134 | .arg = &action, 135 | .val = ACTION_INFO, 136 | .descrip = _("Display console information"), }, 137 | {.longName = "quiet", 138 | .shortName = 'q', 139 | .argInfo = POPT_ARG_VAL, 140 | .arg = &quiet, 141 | .val = 1, 142 | .descrip = _("Work quietly"), }, 143 | POPT_AUTOALIAS 144 | POPT_AUTOHELP 145 | POPT_TABLEEND 146 | }; 147 | 148 | poptContext optcon; 149 | optcon = poptGetContext("eficonman", argc, (const char **)argv, options, 0); 150 | 151 | int rc; 152 | rc = poptReadDefaultConfig(optcon, 0); 153 | if (rc < 0 && !(rc == POPT_ERROR_ERRNO && errno == ENOENT)) 154 | errx(1, _("poptReadDefaultConfig failed: %s: %s"), 155 | poptBadOption(optcon, 0), poptStrerror(rc)); 156 | 157 | while ((rc = poptGetNextOpt(optcon)) > 0) 158 | ; 159 | 160 | switch (action) { 161 | case ACTION_INFO: 162 | do_list(); 163 | break; 164 | case ACTION_INACTION: 165 | default: 166 | poptPrintUsage(optcon, stderr, 0); 167 | exit(1); 168 | } 169 | return 0; 170 | } 171 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is efibootmgr, a Linux user-space application to modify the Intel 2 | Extensible Firmware Interface (EFI) Boot Manager. This application 3 | can create and destroy boot entries, change the boot order, change 4 | the next running boot option, and more. 5 | 6 | Details on the EFI Boot Manager are available from the EFI 7 | Specification, v1.02 or above, available from: http://www.uefi.org 8 | 9 | Note: efibootmgr requires either the efivarfs or the 10 | legacy efivars kernel module to be loaded prior to use. 11 | 12 | usage: efibootmgr [options] 13 | -a | --active sets bootnum active 14 | -A | --inactive sets bootnum inactive 15 | -b | --bootnum XXXX modify BootXXXX (hex) 16 | -B | --delete-bootnum delete bootnum 17 | -c | --create create new variable bootnum and add to bootorder 18 | -d | --disk disk (defaults to /dev/sda) containing loader 19 | -e | --edd [1|3|-1] force EDD 1.0 or 3.0 creation variables, or guess 20 | -E | --device num EDD 1.0 device number (defaults to 0x80) 21 | -g | --gpt force disk w/ invalid PMBR to be treated as GPT 22 | -i | --iface name create a netboot entry for the named interface 23 | -l | --loader name (defaults to \elilo.efi) 24 | -L | --label label Boot manager display label (defaults to "Linux") 25 | -n | --bootnext XXXX set BootNext to XXXX (hex) 26 | -N | --delete-bootnext delete BootNext 27 | -o | --bootorder XXXX,YYYY,ZZZZ,... explicitly set BootOrder (hex) 28 | -O | --delete-bootorder delete BootOrder 29 | -p | --part part (defaults to 1) containing loader 30 | -q | --quiet be quiet 31 | -t | --timeout seconds Boot manager timeout 32 | -T | --delete-timeout delete Timeout value 33 | -u | --unicode | --UCS-2 pass extra args as UCS-2 (default is ASCII) 34 | -v | --verbose print additional information 35 | -V | --version return version and exit 36 | -w | --write-signature write unique sig to MBR if needed 37 | -@ | --append-binary-args append extra variable args from 38 | file (use - to read from stdin). 39 | 40 | 41 | Typical usage: 42 | 43 | Root can use it to display the current Boot Manager settings. 44 | 45 | [root@localhost ~]# efibootmgr 46 | BootCurrent: 0004 47 | BootNext: 0003 48 | BootOrder: 0004,0000,0001,0002,0003 49 | Timeout: 30 seconds 50 | Boot0000* Diskette Drive(device:0) 51 | Boot0001* CD-ROM Drive(device:FF) 52 | Boot0002* Hard Drive(Device:80)/HD(Part1,Sig00112233) 53 | Boot0003* PXE Boot: MAC(00D0B7C15D91) 54 | Boot0004* Linux 55 | 56 | This shows: 57 | BootCurrent - the boot entry used to start the currently running 58 | system. 59 | 60 | BootOrder - the boot order as would appear in the boot manager. The 61 | boot manager tries to boot the first active entry on this list. If 62 | unsuccessful, it tries the next entry, and so on. 63 | 64 | BootNext - the boot entry which is scheduled to be run on next boot. 65 | This superceeds BootOrder for one boot only, and is deleted by the 66 | boot manager after first use. This allows you to change the next boot 67 | behavior without changing BootOrder. 68 | 69 | Timeout - the time in seconds between when the boot manager appears 70 | on the screen until when it automatically chooses the startup value 71 | from BootNext or BootOrder. 72 | 73 | Five boot entries (0000 - 0004), the active/inactive flag (* means 74 | active), and the name displayed on the screen. 75 | 76 | Alternative use cases could be as follows: 77 | 78 | 1) An OS installer would call 'efibootmgr -c'. This assumes that 79 | /dev/sda1 is your EFI System Partition, and is mounted at /boot/efi. 80 | This creates a new boot option, called "Linux", and puts it at the top 81 | of the boot order list. Options may be passed to modify the 82 | default behavior. The default OS Loader is elilo.efi. 83 | 84 | 2) A system administrator wants to change the boot order. She would 85 | call 'efibootmgr -o 3,4' to specify PXE boot first, then Linux 86 | boot. 87 | 88 | 3) A system administrator wants to change the boot order for the next 89 | boot only. She would call 'efibootmgr -n 4' to specify that the 90 | Linux entry be taken on next boot. 91 | 92 | 4) A system administrator wants to delete the Linux boot option from 93 | the menu. 'efibootmgr -b 4 -B' deletes entry 4 and removes it 94 | from BootOrder. 95 | 96 | 5) A system administrator wants to create a boot option to network 97 | boot (PXE). You create the boot entry with: 98 | 'efibootmgr -c -i eth0 -L netboot' 99 | 100 | Please direct any bugs, features, patches, etc. to Peter Jones: 101 | 102 | https://github.com/rhboot/efibootmgr 103 | -------------------------------------------------------------------------------- /src/include/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copied from the Linux 2.4.4 kernel, in linux/include/linux/list.h 3 | */ 4 | 5 | #ifndef _LINUX_LIST_H 6 | #define _LINUX_LIST_H 7 | 8 | 9 | /* 10 | * Simple doubly linked list implementation. 11 | * 12 | * Some of the internal functions ("__xxx") are useful when 13 | * manipulating whole lists rather than single entries, as 14 | * sometimes we already know the next/prev entries and we can 15 | * generate better code by using them directly rather than 16 | * using the generic single-entry routines. 17 | */ 18 | 19 | struct list_head { 20 | struct list_head *next, *prev; 21 | }; 22 | 23 | typedef struct list_head list_t; 24 | 25 | #define LIST_HEAD_INIT(name) { &(name), &(name) } 26 | 27 | #define LIST_HEAD(name) \ 28 | struct list_head name = LIST_HEAD_INIT(name) 29 | 30 | #define INIT_LIST_HEAD(ptr) do { \ 31 | (ptr)->next = (ptr); (ptr)->prev = (ptr); \ 32 | } while (0) 33 | 34 | /* 35 | * Insert a new entry between two known consecutive entries. 36 | * 37 | * This is only for internal list manipulation where we know 38 | * the prev/next entries already! 39 | */ 40 | static __inline__ void __list_add(struct list_head * new, 41 | struct list_head * prev, 42 | struct list_head * next) 43 | { 44 | next->prev = new; 45 | new->next = next; 46 | new->prev = prev; 47 | prev->next = new; 48 | } 49 | 50 | /** 51 | * list_add - add a new entry 52 | * @new: new entry to be added 53 | * @head: list head to add it after 54 | * 55 | * Insert a new entry after the specified head. 56 | * This is good for implementing stacks. 57 | */ 58 | static __inline__ void list_add(struct list_head *new, struct list_head *head) 59 | { 60 | __list_add(new, head, head->next); 61 | } 62 | 63 | /** 64 | * list_add_tail - add a new entry 65 | * @new: new entry to be added 66 | * @head: list head to add it before 67 | * 68 | * Insert a new entry before the specified head. 69 | * This is useful for implementing queues. 70 | */ 71 | static __inline__ void list_add_tail(struct list_head *new, struct list_head *head) 72 | { 73 | __list_add(new, head->prev, head); 74 | } 75 | 76 | /* 77 | * Delete a list entry by making the prev/next entries 78 | * point to each other. 79 | * 80 | * This is only for internal list manipulation where we know 81 | * the prev/next entries already! 82 | */ 83 | static __inline__ void __list_del(struct list_head * prev, 84 | struct list_head * next) 85 | { 86 | next->prev = prev; 87 | prev->next = next; 88 | } 89 | 90 | /** 91 | * list_del - deletes entry from list. 92 | * @entry: the element to delete from the list. 93 | * Note: list_empty on entry does not return true after this, the entry is in an undefined state. 94 | */ 95 | static __inline__ void list_del(struct list_head *entry) 96 | { 97 | __list_del(entry->prev, entry->next); 98 | } 99 | 100 | /** 101 | * list_del_init - deletes entry from list and reinitialize it. 102 | * @entry: the element to delete from the list. 103 | */ 104 | static __inline__ void list_del_init(struct list_head *entry) 105 | { 106 | __list_del(entry->prev, entry->next); 107 | INIT_LIST_HEAD(entry); 108 | } 109 | 110 | /** 111 | * list_empty - tests whether a list is empty 112 | * @head: the list to test. 113 | */ 114 | static __inline__ int list_empty(struct list_head *head) 115 | { 116 | return head->next == head; 117 | } 118 | 119 | /** 120 | * list_splice - join two lists 121 | * @list: the new list to add. 122 | * @head: the place to add it in the first list. 123 | */ 124 | static __inline__ void list_splice(struct list_head *list, struct list_head *head) 125 | { 126 | struct list_head *first = list->next; 127 | 128 | if (first != list) { 129 | struct list_head *last = list->prev; 130 | struct list_head *at = head->next; 131 | 132 | first->prev = head; 133 | head->next = first; 134 | 135 | last->next = at; 136 | at->prev = last; 137 | } 138 | } 139 | 140 | /** 141 | * list_entry - get the struct for this entry 142 | * @ptr: the &struct list_head pointer. 143 | * @type: the type of the struct this is embedded in. 144 | * @member: the name of the list_struct within the struct. 145 | */ 146 | #define list_entry(ptr, type, member) \ 147 | ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) 148 | 149 | /** 150 | * list_for_each - iterate over a list 151 | * @pos: the &struct list_head to use as a loop counter. 152 | * @head: the head for your list. 153 | */ 154 | #define list_for_each(pos, head) \ 155 | for (pos = (head)->next; pos != (head); pos = pos->next) 156 | 157 | /** 158 | * list_for_each_safe - iterate over a list safe against removal of list entry 159 | * @pos: the &struct list_head to use as a loop counter. 160 | * @n: another &struct list_head to use as temporary storage 161 | * @head: the head for your list. 162 | */ 163 | #define list_for_each_safe(pos, n, head) \ 164 | for (pos = (head)->next, n = pos->next; pos != (head); \ 165 | pos = n, n = pos->next) 166 | 167 | 168 | 169 | #endif 170 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is **efibootmgr**, a Linux user-space application to modify the Intel 2 | Extensible Firmware Interface (EFI) Boot Manager. This application 3 | can create and destroy boot entries, change the boot order, change 4 | the next running boot option, and more. 5 | 6 | Details on the EFI Boot Manager are available from the EFI 7 | Specification, v1.02 or above, available from: http://www.uefi.org 8 | 9 | Note: efibootmgr requires either the efivarfs or the 10 | legacy efivars kernel module to be loaded prior to use. 11 | 12 | ``` 13 | usage: efibootmgr [options] 14 | -a | --active sets bootnum active 15 | -A | --inactive sets bootnum inactive 16 | -b | --bootnum XXXX modify BootXXXX (hex) 17 | -B | --delete-bootnum delete bootnum 18 | -c | --create create new variable bootnum and add to bootorder 19 | -d | --disk disk (defaults to /dev/sda) containing loader 20 | -e | --edd [1|3|-1] force EDD 1.0 or 3.0 creation variables, or guess 21 | -E | --device num EDD 1.0 device number (defaults to 0x80) 22 | -f | --reconnect Re-connect devices after driver is loaded 23 | -F | --no-reconnect Do not re-connect devices after driver is loaded 24 | -g | --gpt force disk w/ invalid PMBR to be treated as GPT 25 | -i | --iface name create a netboot entry for the named interface 26 | -l | --loader name (defaults to \elilo.efi) 27 | -L | --label label Boot manager display label (defaults to "Linux") 28 | -n | --bootnext XXXX set BootNext to XXXX (hex) 29 | -N | --delete-bootnext delete BootNext 30 | -o | --bootorder XXXX,YYYY,ZZZZ,... explicitly set BootOrder (hex) 31 | -O | --delete-bootorder delete BootOrder 32 | -p | --part part (defaults to 1) containing loader 33 | -q | --quiet be quiet 34 | -t | --timeout seconds Boot manager timeout 35 | -T | --delete-timeout delete Timeout value 36 | -u | --unicode | --UCS-2 pass extra args as UCS-2 (default is ASCII) 37 | -v | --verbose print additional information 38 | -V | --version return version and exit 39 | -w | --write-signature write unique sig to MBR if needed 40 | -@ | --append-binary-args append extra variable args from 41 | file (use - to read from stdin). 42 | ``` 43 | 44 | Typical usage: 45 | 46 | Root can use it to display the current Boot Manager settings. 47 | ``` 48 | [root@localhost ~]# efibootmgr 49 | BootCurrent: 0004 50 | BootNext: 0003 51 | BootOrder: 0004,0000,0001,0002,0003 52 | Timeout: 30 seconds 53 | Boot0000* Diskette Drive(device:0) 54 | Boot0001* CD-ROM Drive(device:FF) 55 | Boot0002* Hard Drive(Device:80)/HD(Part1,Sig00112233) 56 | Boot0003* PXE Boot: MAC(00D0B7C15D91) 57 | Boot0004* Linux 58 | ``` 59 | This shows: 60 | **BootCurrent** - the boot entry used to start the currently running 61 | system. 62 | 63 | **BootOrder** - the boot order as would appear in the boot manager. The 64 | boot manager tries to boot the first active entry on this list. If 65 | unsuccessful, it tries the next entry, and so on. 66 | 67 | **BootNext** - the boot entry which is scheduled to be run on next boot. 68 | This superceeds BootOrder for one boot only, and is deleted by the 69 | boot manager after first use. This allows you to change the next boot 70 | behavior without changing BootOrder. 71 | 72 | **Timeout** - the time in seconds between when the boot manager appears 73 | on the screen until when it automatically chooses the startup value 74 | from BootNext or BootOrder. 75 | 76 | Five boot entries (0000 - 0004), the active/inactive flag (* means 77 | active), and the name displayed on the screen. 78 | 79 | Alternative use cases could be as follows: 80 | 81 | 1) An OS installer would call `efibootmgr -c`. This assumes that 82 | /dev/sda1 is your EFI System Partition, and is mounted at /boot/efi. 83 | This creates a new boot option, called "Linux", and puts it at the top 84 | of the boot order list. Options may be passed to modify the 85 | default behavior. The default OS Loader is elilo.efi. 86 | 87 | 2) A system administrator wants to change the boot order. She would 88 | call `efibootmgr -o 3,4` to specify PXE boot first, then Linux 89 | boot. 90 | 91 | 3) A system administrator wants to change the boot order for the next 92 | boot only. She would call `efibootmgr -n 4` to specify that the 93 | Linux entry be taken on next boot. 94 | 95 | 4) A system administrator wants to delete the Linux boot option from 96 | the menu. `efibootmgr -b 4 -B` deletes entry 4 and removes it 97 | from BootOrder. 98 | 99 | 5) A system administrator wants to create a boot option to network 100 | boot (PXE). You create the boot entry with: 101 | `efibootmgr -c -i eth0 -L netboot` 102 | 103 | Please direct any bugs, features, patches, etc. to the Red Hat bootloader team at https://github.com/rhboot/efibootmgr . 104 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | We as members, contributors, and leaders pledge to make participation in our 7 | community a harassment-free experience for everyone, regardless of age, body 8 | size, visible or invisible disability, ethnicity, sex characteristics, gender 9 | identity and expression, level of experience, education, socio-economic status, 10 | nationality, personal appearance, race, caste, color, religion, or sexual identity 11 | and orientation. 12 | 13 | We pledge to act and interact in ways that contribute to an open, welcoming, 14 | diverse, inclusive, and healthy community. 15 | 16 | ## Our Standards 17 | 18 | Examples of behavior that contributes to a positive environment for our 19 | community include: 20 | 21 | * Demonstrating empathy and kindness toward other people 22 | * Being respectful of differing opinions, viewpoints, and experiences 23 | * Giving and gracefully accepting constructive feedback 24 | * Accepting responsibility and apologizing to those affected by our mistakes, 25 | and learning from the experience 26 | * Focusing on what is best not just for us as individuals, but for the 27 | overall community 28 | 29 | Examples of unacceptable behavior include: 30 | 31 | * The use of sexualized language or imagery, and sexual attention or 32 | advances of any kind 33 | * Trolling, insulting or derogatory comments, and personal or political attacks 34 | * Public or private harassment 35 | * Publishing others' private information, such as a physical or email 36 | address, without their explicit permission 37 | * Other conduct which could reasonably be considered inappropriate in a 38 | professional setting 39 | 40 | ## Enforcement Responsibilities 41 | 42 | Community leaders are responsible for clarifying and enforcing our standards of 43 | acceptable behavior and will take appropriate and fair corrective action in 44 | response to any behavior that they deem inappropriate, threatening, offensive, 45 | or harmful. 46 | 47 | Community leaders have the right and responsibility to remove, edit, or reject 48 | comments, commits, code, wiki edits, issues, and other contributions that are 49 | not aligned to this Code of Conduct, and will communicate reasons for moderation 50 | decisions when appropriate. 51 | 52 | ## Scope 53 | 54 | This Code of Conduct applies within all community spaces, and also applies when 55 | an individual is officially representing the community in public spaces. 56 | Examples of representing our community include using an official e-mail address, 57 | posting via an official social media account, or acting as an appointed 58 | representative at an online or offline event. 59 | 60 | ## Enforcement 61 | 62 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 63 | reported to the community leaders responsible for enforcement at 64 | rharwood AT redhat DOT com. 65 | All complaints will be reviewed and investigated promptly and fairly. 66 | 67 | All community leaders are obligated to respect the privacy and security of the 68 | reporter of any incident. 69 | 70 | ## Enforcement Guidelines 71 | 72 | Community leaders will follow these Community Impact Guidelines in determining 73 | the consequences for any action they deem in violation of this Code of Conduct: 74 | 75 | ### 1. Correction 76 | 77 | **Community Impact**: Use of inappropriate language or other behavior deemed 78 | unprofessional or unwelcome in the community. 79 | 80 | **Consequence**: A private, written warning from community leaders, providing 81 | clarity around the nature of the violation and an explanation of why the 82 | behavior was inappropriate. A public apology may be requested. 83 | 84 | ### 2. Warning 85 | 86 | **Community Impact**: A violation through a single incident or series 87 | of actions. 88 | 89 | **Consequence**: A warning with consequences for continued behavior. No 90 | interaction with the people involved, including unsolicited interaction with 91 | those enforcing the Code of Conduct, for a specified period of time. This 92 | includes avoiding interactions in community spaces as well as external channels 93 | like social media. Violating these terms may lead to a temporary or 94 | permanent ban. 95 | 96 | ### 3. Temporary Ban 97 | 98 | **Community Impact**: A serious violation of community standards, including 99 | sustained inappropriate behavior. 100 | 101 | **Consequence**: A temporary ban from any sort of interaction or public 102 | communication with the community for a specified period of time. No public or 103 | private interaction with the people involved, including unsolicited interaction 104 | with those enforcing the Code of Conduct, is allowed during this period. 105 | Violating these terms may lead to a permanent ban. 106 | 107 | ### 4. Permanent Ban 108 | 109 | **Community Impact**: Demonstrating a pattern of violation of community 110 | standards, including sustained inappropriate behavior, harassment of an 111 | individual, or aggression toward or disparagement of classes of individuals. 112 | 113 | **Consequence**: A permanent ban from any sort of public interaction within 114 | the community. 115 | 116 | ## Attribution 117 | 118 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 119 | version 2.1, available at 120 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 121 | 122 | Community Impact Guidelines were inspired by 123 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 124 | 125 | For answers to common questions about this code of conduct, see the FAQ at 126 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available 127 | at [https://www.contributor-covenant.org/translations][translations]. 128 | 129 | [homepage]: https://www.contributor-covenant.org 130 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 131 | [Mozilla CoC]: https://github.com/mozilla/diversity 132 | [FAQ]: https://www.contributor-covenant.org/faq 133 | [translations]: https://www.contributor-covenant.org/translations 134 | 135 | -------------------------------------------------------------------------------- /src/efibootnext.c: -------------------------------------------------------------------------------- 1 | /* 2 | * efibootnext - Attempt to set a BootNext variable from existing boot 3 | * options. 4 | * 5 | * Copyright 2015 Red Hat, Inc. 6 | * Author: Peter Jones 7 | * 8 | * This program is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License as published by the Free 10 | * Software Foundation; either version 2 of the License, or (at your option) 11 | * any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 | * for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License along 19 | * with this library; if not, see . 20 | * 21 | */ 22 | 23 | #include "fix_coverity.h" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | typedef enum { 32 | notnot, // just a regular match sense 33 | ignore, // ignore this match - only consider its children 34 | not, // ! 35 | and, // -a 36 | or, // -o 37 | } match_sense; 38 | 39 | struct matcher { 40 | int sense; 41 | struct matcher *matchers; 42 | 43 | char *bootnum; 44 | char *disk; 45 | char *edd; 46 | char *edd_devnum; 47 | char *loader; 48 | char *label; 49 | int gpt; 50 | int in_boot_order; 51 | }; 52 | 53 | int 54 | main(int argc, char *argv[]) 55 | { 56 | int err_if_not_found = 1; 57 | int err_if_set_fails = 1; 58 | 59 | int which = 0; 60 | char *sorter = NULL; 61 | 62 | struct matcher *matchers; 63 | struct matcher *matcher; 64 | 65 | poptContext optCon; 66 | 67 | matcher = matchers = calloc(1, sizeof(struct matcher)); 68 | struct poptOption matchopts[] = { 69 | /* options to specify match criteria */ 70 | {"bootnum", 'n', POPT_ARG_STRING, matcher->bootnum, NULL, 71 | "boot entry number (hex)", "<####>" }, 72 | {"disk", 'd', POPT_ARG_STRING, matcher->disk, NULL, 73 | "disk containing loader", "" }, 74 | /* keep edd and device together despite alphabetism */ 75 | {"edd", 'e', POPT_ARG_STRING, matcher->edd, NULL, 76 | "EDD version", "[1|3|[any]]" }, 77 | {"device", 'E', POPT_ARG_STRING, matcher->edd_devnum, NULL, 78 | "EDD 1.0 device number (hex)", "[##|[80]]", }, 79 | /* keep gpt and mbr together despite alphabetism */ 80 | {"gpt", 'g', POPT_ARG_VAL, &matcher->gpt, 1, 81 | "only match GPT partitioned disks", }, 82 | {"mbr", 'm', POPT_ARG_VAL, &matcher->gpt, 2, 83 | "only match MBR partitioned disks", }, 84 | {"loader", 'l', POPT_ARG_STRING, matcher->loader, NULL, 85 | "loader path", "", }, 86 | {"label", 'L', POPT_ARG_STRING, matcher->label, NULL, 87 | "boot entry label", "