Changeset View
Standalone View
usr.sbin/efibootmgr/efibootmgr.c
Show First 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | |||||
#include <geom/geom_ctl.h> | #include <geom/geom_ctl.h> | ||||
#include <geom/geom_int.h> | #include <geom/geom_int.h> | ||||
#include <efivar.h> | #include <efivar.h> | ||||
#include <efiutil.h> | #include <efiutil.h> | ||||
#include <efichar.h> | #include <efichar.h> | ||||
#include <efivar-dp.h> | #include <efivar-dp.h> | ||||
#ifndef LOAD_OPTION_ACTIVE | #ifndef LOAD_OPTION_ACTIVE | ||||
imp: Don't do this. Use getprogname() instead.
| |||||
#define LOAD_OPTION_ACTIVE 0x00000001 | #define LOAD_OPTION_ACTIVE 0x00000001 | ||||
#endif | #endif | ||||
#ifndef LOAD_OPTION_CATEGORY_BOOT | #ifndef LOAD_OPTION_CATEGORY_BOOT | ||||
#define LOAD_OPTION_CATEGORY_BOOT 0x00000000 | #define LOAD_OPTION_CATEGORY_BOOT 0x00000000 | ||||
#endif | #endif | ||||
#define BAD_LENGTH ((size_t)-1) | #define BAD_LENGTH ((size_t)-1) | ||||
▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
set_bootvar(const char *name, uint8_t *data, size_t size) | set_bootvar(const char *name, uint8_t *data, size_t size) | ||||
{ | { | ||||
return efi_set_variable(EFI_GLOBAL_GUID, name, data, size, | return efi_set_variable(EFI_GLOBAL_GUID, name, data, size, | ||||
COMMON_ATTRS); | COMMON_ATTRS); | ||||
} | } | ||||
typedef enum { | |||||
EBM_USAGE, | |||||
EBM_LIST, | |||||
EBM_CREATE, | |||||
EBM_DELETE, | |||||
EBM_ACTIVE, | |||||
EBM_BOOTNEXT_SET, | |||||
EBM_BOOTNEXT_DELETE, | |||||
EBM_ORDER, | |||||
EBM_TIMEOUT_SET, | |||||
EBM_TIMEOUT_DELETE | |||||
} ebm_usage_t; | |||||
static const char * const ebm_usage[] = { | |||||
[EBM_LIST] = "[-v]", | |||||
[EBM_CREATE] = "-c -l loader [-aD] [-b bootnum] [-k kernel] [-L label]", | |||||
[EBM_DELETE] = "-B -b bootnum", | |||||
[EBM_ACTIVE] = "{-a|-A} -b bootnum", | |||||
[EBM_BOOTNEXT_SET] = "-n -b bootnum", | |||||
[EBM_BOOTNEXT_DELETE] = "-N", | |||||
[EBM_ORDER] = "-o bootnum1,bootnum2,...", | |||||
[EBM_TIMEOUT_SET] = "-t seconds", | |||||
[EBM_TIMEOUT_DELETE] = "-T" | |||||
}; | |||||
#define USAGE \ | static void | ||||
" [-aAnB -b bootnum] [-N] [-t timeout] [-T] [-o bootorder] [-O] [--verbose] [--help]\n\ | usage(ebm_usage_t unum) | ||||
[-c -l loader [-k kernel] [-L label] [--dry-run] [-b bootnum]]" | { | ||||
Done Inline ActionsWe should always send usage message to stderr. imp: We should always send usage message to stderr.
What's the advantage of doing it differently… | |||||
Done Inline Actions*Some* utilities do (e.g. camcontrol help and zfs/zpool from contrib), but it doesn't really matter much, changed. yuripv: *Some* utilities do (e.g. `camcontrol help` and zfs/zpool from contrib), but it doesn't really… | |||||
#define CREATE_USAGE \ | fprintf(stderr, "Usage:\n"); | ||||
" efibootmgr -c -l loader [-k kernel] [-L label] [--dry-run] [-b bootnum] [-a]" | |||||
#define ORDER_USAGE \ | |||||
" efibootmgr -o bootvarnum1,bootvarnum2,..." | |||||
#define TIMEOUT_USAGE \ | |||||
" efibootmgr -t seconds" | |||||
#define DELETE_USAGE \ | |||||
" efibootmgr -B -b bootnum" | |||||
#define ACTIVE_USAGE \ | |||||
" efibootmgr [-a | -A] -b bootnum" | |||||
#define BOOTNEXT_USAGE \ | |||||
" efibootmgr [-n | -N] -b bootnum" | |||||
if (unum >= 1 && unum < nitems(ebm_usage)) | |||||
fprintf(stderr, "\t%s %s\n", getprogname(), ebm_usage[unum]); | |||||
Done Inline Actionsgetprogname() is the preferred interface imp: getprogname() is the preferred interface
| |||||
else { | |||||
ebm_usage_t i; | |||||
Done Inline ActionsWe should always exit with status 1 here. We can eliminate the help bool which would also simplify things. imp: We should always exit with status 1 here. We can eliminate the help bool which would also… | |||||
for (i = 1; i < nitems(ebm_usage); i++) | |||||
fprintf(stderr, "\t%s %s\n", getprogname(), | |||||
ebm_usage[i]); | |||||
} | |||||
exit(1); | |||||
} | |||||
static void | static void | ||||
parse_args(int argc, char *argv[]) | parse_args(int argc, char *argv[]) | ||||
{ | { | ||||
int ch; | int ch; | ||||
while ((ch = getopt_long(argc, argv, "AaBb:C:cDe:hk:L:l:NnOo:Tt:v", | while ((ch = getopt_long(argc, argv, "AaBb:C:cDe:hk:L:l:NnOo:Tt:v", | ||||
lopts, NULL)) != -1) { | lopts, NULL)) != -1) { | ||||
switch (ch) { | switch (ch) { | ||||
Show All 20 Lines | case 'D': /* should be remove dups XXX */ | ||||
opts.dry_run = true; | opts.dry_run = true; | ||||
break; | break; | ||||
case 'e': | case 'e': | ||||
free(opts.env); | free(opts.env); | ||||
opts.env = strdup(optarg); | opts.env = strdup(optarg); | ||||
break; | break; | ||||
case 'h': | case 'h': | ||||
default: | default: | ||||
errx(1, "%s", USAGE); | usage(EBM_USAGE); | ||||
break; | break; | ||||
case 'k': | case 'k': | ||||
free(opts.kernel); | free(opts.kernel); | ||||
opts.kernel = strdup(optarg); | opts.kernel = strdup(optarg); | ||||
break; | break; | ||||
case 'L': | case 'L': | ||||
free(opts.label); | free(opts.label); | ||||
opts.label = strdup(optarg); | opts.label = strdup(optarg); | ||||
Show All 22 Lines | while ((ch = getopt_long(argc, argv, "AaBb:C:cDe:hk:L:l:NnOo:Tt:v", | ||||
case 't': | case 't': | ||||
opts.set_timeout = true; | opts.set_timeout = true; | ||||
opts.timeout = strtoul(optarg, NULL, 10); | opts.timeout = strtoul(optarg, NULL, 10); | ||||
break; | break; | ||||
case 'v': | case 'v': | ||||
opts.verbose = true; | opts.verbose = true; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
Done Inline ActionsCompilers are getting pickier and pickier. This is no valid C++, for example, and the trend is to having enums move away from being just an int into something more. IF you going to go for an enum, go all in and define one here too. imp: Compilers are getting pickier and pickier. This is no valid C++, for example, and the trend is… | |||||
if (opts.create) { | if (opts.create) { | ||||
if (!opts.loader) | if (!opts.loader) | ||||
errx(1, "%s",CREATE_USAGE); | usage(EBM_CREATE); | ||||
return; | return; | ||||
} | } | ||||
if (opts.order && !(opts.order)) | if (opts.order && !(opts.order)) | ||||
errx(1, "%s", ORDER_USAGE); | usage(EBM_ORDER); | ||||
if ((opts.set_inactive || opts.set_active) && !opts.has_bootnum) | if ((opts.set_inactive || opts.set_active) && !opts.has_bootnum) | ||||
errx(1, "%s", ACTIVE_USAGE); | usage(EBM_ACTIVE); | ||||
if (opts.delete && !opts.has_bootnum) | if (opts.delete && !opts.has_bootnum) | ||||
errx(1, "%s", DELETE_USAGE); | usage(EBM_DELETE); | ||||
if (opts.set_bootnext && !opts.has_bootnum) | if (opts.set_bootnext && !opts.has_bootnum) | ||||
errx(1, "%s", BOOTNEXT_USAGE); | usage(EBM_BOOTNEXT_SET); | ||||
} | } | ||||
static void | static void | ||||
read_vars(void) | read_vars(void) | ||||
{ | { | ||||
efi_guid_t *guid; | efi_guid_t *guid; | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | set_boot_order(char *order) | ||||
new_data = malloc(size); | new_data = malloc(size); | ||||
i = 0; | i = 0; | ||||
cp = strdup(order); | cp = strdup(order); | ||||
while ((next = strsep(&cp, ",")) != NULL) { | while ((next = strsep(&cp, ",")) != NULL) { | ||||
new_data[i] = strtoul(next, NULL, 16); | new_data[i] = strtoul(next, NULL, 16); | ||||
if (new_data[i] == 0 && errno == EINVAL) { | if (new_data[i] == 0 && errno == EINVAL) { | ||||
warnx("can't parse %s as a numb", next); | warnx("can't parse %s as a numb", next); | ||||
errx(1, "%s", ORDER_USAGE); | usage(EBM_ORDER); | ||||
} | } | ||||
i++; | i++; | ||||
} | } | ||||
free(cp); | free(cp); | ||||
if (set_bootvar("BootOrder", (uint8_t*)new_data, size) < 0) | if (set_bootvar("BootOrder", (uint8_t*)new_data, size) < 0) | ||||
err(1, "Unabke to set BootOrder to %s", order); | err(1, "Unabke to set BootOrder to %s", order); | ||||
Done Inline ActionsThis is good, but should be a separate commit. imp: This is good, but should be a separate commit.
| |||||
free(new_data); | free(new_data); | ||||
} | } | ||||
static void | static void | ||||
handle_activity(int bootnum, bool active) | handle_activity(int bootnum, bool active) | ||||
{ | { | ||||
uint32_t attrs, load_attrs; | uint32_t attrs, load_attrs; | ||||
uint8_t *data; | uint8_t *data; | ||||
▲ Show 20 Lines • Show All 582 Lines • Show Last 20 Lines |
Don't do this. Use getprogname() instead.