From 779796f57e1e0236ea502248ede2cbea986fca21 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Tue, 23 Sep 2014 11:47:40 -0700 Subject: futility: Improve help messages This provides help messages for the futility commands similar to the way git does. These show the available commands: futility futility help futility --help While these show help for a specific command: futility help COMMAND futility --help COMMAND futility COMMAND --help BUG=none BRANCH=ToT TEST=manual make runtests And manually look at help messages for each command. Change-Id: I1126471e242784c6ca7a2f11694fa7c505d833e8 Signed-off-by: Bill Richardson Reviewed-on: https://chromium-review.googlesource.com/219528 Reviewed-by: Randall Spangler --- Makefile | 2 +- futility/cmd_dev_sign_file.c | 76 +++++++------- futility/cmd_dump_fmap.c | 88 ++++++++-------- futility/cmd_dump_kernel_config.c | 18 ++-- futility/cmd_gbb_utility.c | 47 +++++---- futility/cmd_load_fmap.c | 11 +- futility/cmd_show.c | 71 ++++++++----- futility/cmd_sign.c | 31 ++++-- futility/cmd_vb2_verify_fw.c | 27 +++-- futility/cmd_vbutil_firmware.c | 65 ++++++------ futility/cmd_vbutil_kernel.c | 89 ++++++++-------- futility/cmd_vbutil_key.c | 76 +++++++------- futility/cmd_vbutil_keyblock.c | 29 +++--- futility/cmd_verify_kernel.c | 24 ++--- futility/dump_kernel_config_lib.c | 4 +- futility/futility.c | 212 ++++++++++++++++++++++---------------- futility/futility.h | 26 ++--- futility/kernel_blob.h | 3 +- futility/misc.c | 3 +- futility/traversal.h | 2 +- 20 files changed, 480 insertions(+), 424 deletions(-) diff --git a/Makefile b/Makefile index d091e183..b65c692e 100644 --- a/Makefile +++ b/Makefile @@ -1046,7 +1046,7 @@ ${FUTIL_CMD_LIST} ${FUTIL_STATIC_CMD_LIST}: @$(PRINTF) " GEN $(subst ${BUILD}/,,$@)\n" ${Q}rm -f $@ $@_t $@_commands ${Q}mkdir -p ${BUILD}/gen - ${Q}grep -hoRE '^DECLARE_FUTIL_COMMAND\([^,]+' $^ -R \ + ${Q}grep -hoRE '^DECLARE_FUTIL_COMMAND\([^,]+' $^ \ | sed 's/DECLARE_FUTIL_COMMAND(\(.*\)/_CMD(\1)/' \ | sort >>$@_commands ${Q}echo '#define _CMD(NAME) extern const struct' \ diff --git a/futility/cmd_dev_sign_file.c b/futility/cmd_dev_sign_file.c index 134339eb..bcfb3d62 100644 --- a/futility/cmd_dev_sign_file.c +++ b/futility/cmd_dev_sign_file.c @@ -24,7 +24,7 @@ #include "vboot_common.h" /* Global opt */ -static int opt_debug = 0; +static int opt_debug; /* Command line options */ enum { @@ -46,34 +46,30 @@ static const struct option long_opts[] = { }; /* Print help and return error */ -static int PrintHelp(const char *progname) +static void PrintHelp(const char *progname) { - fprintf(stderr, - "This is used to sign and verify developer-mode files\n"); - fprintf(stderr, - "\n" - "Usage: %s --sign [PARAMETERS]\n" - "\n" - " Required parameters:\n" - " --keyblock Key block in .keyblock format\n" - " --signprivate " - " Private key to sign file data, in .vbprivk format\n" - " --vblock " - " Output signature in .vblock format\n" - "\n", progname); - fprintf(stderr, - "OR\n\n" - "Usage: %s --verify [PARAMETERS]\n" - "\n" - " Required parameters:\n" - " --vblock " - " Signature file in .vblock format\n" - "\n" - " Optional parameters:\n" - " --keyblock " - " Extract .keyblock to file if verification succeeds\n" - "\n", progname); - return 1; + printf("\n" + "Usage: " MYNAME " %s --sign [PARAMETERS]\n" + "\n" + " Required parameters:\n" + " --keyblock Key block in .keyblock format\n" + " --signprivate " + " Private key to sign file data,\n" + " in .vbprivk format\n" + " --vblock " + " Output signature in .vblock format\n" + "\n", progname); + printf("OR\n\n" + "Usage: " MYNAME " %s --verify [PARAMETERS]\n" + "\n" + " Required parameters:\n" + " --vblock " + " Signature file in .vblock format\n" + "\n" + " Optional parameters:\n" + " --keyblock " + " Extract .keyblock to file\n" + "\n", progname); } static void Debug(const char *format, ...) @@ -296,12 +292,6 @@ static int do_dev_sign_file(int argc, char *argv[]) int parse_error = 0; int option_index; - char *progname = strrchr(argv[0], '/'); - if (progname) - progname++; - else - progname = argv[0]; - while ((option_index = getopt_long(argc, argv, ":", long_opts, NULL)) != -1 && !parse_error) { @@ -342,14 +332,17 @@ static int do_dev_sign_file(int argc, char *argv[]) } } - if (parse_error) - return PrintHelp(progname); + if (parse_error) { + PrintHelp(argv[0]); + return 1; + } switch (mode) { case OPT_MODE_SIGN: if (!keyblock_file || !signprivate_file || !vblock_file) { fprintf(stderr, "Some required options are missing\n"); - return PrintHelp(progname); + PrintHelp(argv[0]); + return 1; } return Sign(filename, keyblock_file, signprivate_file, vblock_file); @@ -357,13 +350,15 @@ static int do_dev_sign_file(int argc, char *argv[]) case OPT_MODE_VERIFY: if (!vblock_file) { fprintf(stderr, "Some required options are missing\n"); - return PrintHelp(progname); + PrintHelp(argv[0]); + return 1; } return Verify(filename, vblock_file, keyblock_file); default: fprintf(stderr, "You must specify either --sign or --verify\n"); - return PrintHelp(progname); + PrintHelp(argv[0]); + return 1; } /* NOTREACHED */ @@ -371,4 +366,5 @@ static int do_dev_sign_file(int argc, char *argv[]) } DECLARE_FUTIL_COMMAND(dev_sign_file, do_dev_sign_file, - "Sign or verify dev-mode files (DEPRECATED)"); + "Sign or verify dev-mode files (DEPRECATED)", + PrintHelp); diff --git a/futility/cmd_dump_fmap.c b/futility/cmd_dump_fmap.c index d1c962cc..482cf23d 100644 --- a/futility/cmd_dump_fmap.c +++ b/futility/cmd_dump_fmap.c @@ -21,13 +21,13 @@ enum { FMT_NORMAL, FMT_PRETTY, FMT_FLASHROM, FMT_HUMAN }; /* global variables */ -static int opt_extract = 0; +static int opt_extract; static int opt_format = FMT_NORMAL; -static int opt_overlap = 0; +static int opt_overlap; static char *progname; static void *base_of_rom; static size_t size_of_rom; -static int opt_gaps = 0; +static int opt_gaps; /* Return 0 if successful */ static int dump_fmap(const FmapHeader *fmh, int argc, char *argv[]) @@ -61,9 +61,8 @@ static int dump_fmap(const FmapHeader *fmh, int argc, char *argv[]) found = 1; break; } - if (!found) { + if (!found) continue; - } } switch (opt_format) { @@ -123,12 +122,12 @@ static int dump_fmap(const FmapHeader *fmh, int argc, char *argv[]) /****************************************************************************/ /* Stuff for human-readable form */ -typedef struct dup_s { +struct dup_s { char *name; struct dup_s *next; -} dupe_t; +}; -typedef struct node_s { +struct node_s { char *name; uint32_t start; uint32_t size; @@ -136,15 +135,15 @@ typedef struct node_s { struct node_s *parent; int num_children; struct node_s **child; - dupe_t *alias; -} node_t; + struct dup_s *alias; +}; -static node_t *all_nodes; +static struct node_s *all_nodes; -static void sort_nodes(int num, node_t * ary[]) +static void sort_nodes(int num, struct node_s *ary[]) { int i, j; - node_t *tmp; + struct node_s *tmp; /* bubble-sort is quick enough with only a few entries */ for (i = 0; i < num; i++) { @@ -179,10 +178,10 @@ static void empty(int indent, uint32_t start, uint32_t end, char *name) gapcount++; } -static void show(node_t * p, int indent, int show_first) +static void show(struct node_s *p, int indent, int show_first) { int i; - dupe_t *alias; + struct dup_s *alias; if (show_first) { line(indent, p->name, p->start, p->end, p->size, 0); for (alias = p->alias; alias; alias = alias->next) @@ -205,8 +204,8 @@ static void show(node_t * p, int indent, int show_first) static int overlaps(int i, int j) { - node_t *a = all_nodes + i; - node_t *b = all_nodes + j; + struct node_s *a = all_nodes + i; + struct node_s *b = all_nodes + j; return ((a->start < b->start) && (b->start < a->end) && (b->start < a->end) && (a->end < b->end)); @@ -214,16 +213,16 @@ static int overlaps(int i, int j) static int encloses(int i, int j) { - node_t *a = all_nodes + i; - node_t *b = all_nodes + j; + struct node_s *a = all_nodes + i; + struct node_s *b = all_nodes + j; return ((a->start <= b->start) && (a->end >= b->end)); } static int duplicates(int i, int j) { - node_t *a = all_nodes + i; - node_t *b = all_nodes + j; + struct node_s *a = all_nodes + i; + struct node_s *b = all_nodes + j; return ((a->start == b->start) && (a->end == b->end)); } @@ -231,9 +230,9 @@ static int duplicates(int i, int j) static void add_dupe(int i, int j, int numnodes) { int k; - dupe_t *alias; + struct dup_s *alias; - alias = (dupe_t *) malloc(sizeof(dupe_t)); + alias = (struct dup_s *) malloc(sizeof(struct dup_s)); alias->name = all_nodes[j].name; alias->next = all_nodes[i].alias; all_nodes[i].alias = alias; @@ -241,12 +240,13 @@ static void add_dupe(int i, int j, int numnodes) all_nodes[k] = all_nodes[k + 1]; } -static void add_child(node_t * p, int n) +static void add_child(struct node_s *p, int n) { int i; if (p->num_children && !p->child) { p->child = - (struct node_s **)calloc(p->num_children, sizeof(node_t *)); + (struct node_s **)calloc(p->num_children, + sizeof(struct node_s *)); if (!p->child) { perror("calloc failed"); exit(1); @@ -276,7 +276,8 @@ static int human_fmap(const FmapHeader *fmh) numnodes = fmh->fmap_nareas; /* plus one for the all-enclosing "root" */ - all_nodes = (node_t *) calloc(numnodes + 1, sizeof(node_t)); + all_nodes = (struct node_s *) calloc(numnodes + 1, + sizeof(struct node_s)); if (!all_nodes) { perror("calloc failed"); exit(1); @@ -285,7 +286,8 @@ static int human_fmap(const FmapHeader *fmh) char buf[FMAP_NAMELEN + 1]; strncpy(buf, ah[i].area_name, FMAP_NAMELEN); buf[FMAP_NAMELEN] = '\0'; - if (!(all_nodes[i].name = strdup(buf))) { + all_nodes[i].name = strdup(buf); + if (!all_nodes[i].name) { perror("strdup failed"); exit(1); } @@ -364,17 +366,24 @@ static int human_fmap(const FmapHeader *fmh) /****************************************************************************/ static const char usage[] = - "\nUsage: %s [-x] [-p|-f|-h] FLASHIMAGE [NAME...]\n\n" - "Display (and extract with -x) the FMAP components from a BIOS image.\n" - "The -p option makes the output easier to parse by scripts.\n" - "The -f option emits the FMAP in the format used by flashrom.\n" + "\nUsage: " MYNAME " %s [OPTIONS] FLASHIMAGE [NAME...]\n\n" + "Display (and extract) the FMAP components from a BIOS image.\n" "\n" - "Specify one or more NAMEs to only print sections that exactly match.\n" + "Options:\n" + " -p Use a format easy to parse by scripts\n" + " -f Use the format expected by flashrom\n" + " -h Use a human-readable format\n" + " -H With -h, display any gaps\n" + " -x Extract the named sections from the file\n" "\n" - "The -h option shows the whole FMAP in human-readable form.\n" - " Use -H to also display any gaps.\n" + "Specify one or more NAMEs to dump only those sections.\n" "\n"; +static void print_help(const char *name) +{ + printf(usage, name); +} + static int do_dump_fmap(int argc, char *argv[]) { int c; @@ -384,11 +393,7 @@ static int do_dump_fmap(int argc, char *argv[]) const FmapHeader *fmap; int retval = 1; - progname = strrchr(argv[0], '/'); - if (progname) - progname++; - else - progname = argv[0]; + progname = argv[0]; opterr = 0; /* quiet, you */ while ((c = getopt(argc, argv, ":xpfhH")) != -1) { @@ -426,7 +431,7 @@ static int do_dump_fmap(int argc, char *argv[]) } if (errorcnt || optind >= argc) { - fprintf(stderr, usage, progname); + print_help(progname); return 1; } @@ -481,4 +486,5 @@ static int do_dump_fmap(int argc, char *argv[]) } DECLARE_FUTIL_COMMAND(dump_fmap, do_dump_fmap, - "Display FMAP contents from a firmware image"); + "Display FMAP contents from a firmware image", + print_help); diff --git a/futility/cmd_dump_kernel_config.c b/futility/cmd_dump_kernel_config.c index 1bf411b2..520d2802 100644 --- a/futility/cmd_dump_kernel_config.c +++ b/futility/cmd_dump_kernel_config.c @@ -23,13 +23,10 @@ static const struct option long_opts[] = { }; /* Print help and return error */ -static int PrintHelp(void) +static void PrintHelp(const char *progname) { - puts("dump_kernel_config - Prints the kernel command line\n" - "\n" - "Usage: dump_kernel_config [--kloadaddr
] " - "\n" "\n" ""); - return 1; + printf("\nUsage: " MYNAME " %s [--kloadaddr ADDRESS] " + "KERNEL_PARTITION\n\n", progname); } static int do_dump_kernel_config(int argc, char *argv[]) @@ -70,8 +67,10 @@ static int do_dump_kernel_config(int argc, char *argv[]) } else infile = argv[optind]; - if (parse_error) - return PrintHelp(); + if (parse_error) { + PrintHelp(argv[0]); + return 1; + } if (!infile || !*infile) { fprintf(stderr, "Must specify filename\n"); @@ -89,4 +88,5 @@ static int do_dump_kernel_config(int argc, char *argv[]) } DECLARE_FUTIL_COMMAND(dump_kernel_config, do_dump_kernel_config, - "Prints the kernel command line"); + "Prints the kernel command line", + PrintHelp); diff --git a/futility/cmd_gbb_utility.c b/futility/cmd_gbb_utility.c index 8d742cb9..e8910e67 100644 --- a/futility/cmd_gbb_utility.c +++ b/futility/cmd_gbb_utility.c @@ -18,10 +18,11 @@ #include "futility.h" #include "gbb_header.h" -static void help_and_quit(const char *prog) +static void print_help(const char *prog) { - fprintf(stderr, "\n" - "Usage: %s [-g|-s|-c] [OPTIONS] bios_file [output_file]\n" + printf("\n" + "Usage: " MYNAME " %s [-g|-s|-c] [OPTIONS] " + "bios_file [output_file]\n" "\n" "GET MODE:\n" "-g, --get (default)\tGet (read) from bios_file, " @@ -52,7 +53,6 @@ static void help_and_quit(const char *prog) " bios.bin newbios.bin\n" " %s -c 0x100,0x1000,0x03DE80,0x1000 gbb.blob\n\n", prog, prog, prog, prog); - exit(1); } /* Command line options */ @@ -75,7 +75,7 @@ static char *short_opts = ":gsc:o:k:b:R:r:h:i:L:f:"; static int errorcnt; #define GBB_SEARCH_STRIDE 4 -GoogleBinaryBlockHeader *FindGbbHeader(uint8_t * ptr, size_t size) +static GoogleBinaryBlockHeader *FindGbbHeader(uint8_t *ptr, size_t size) { size_t i; GoogleBinaryBlockHeader *tmp, *gbb_header = NULL; @@ -105,7 +105,7 @@ GoogleBinaryBlockHeader *FindGbbHeader(uint8_t * ptr, size_t size) } } -static uint8_t *create_gbb(const char *desc, off_t * sizeptr) +static uint8_t *create_gbb(const char *desc, off_t *sizeptr) { char *str, *sizes, *param, *e = NULL; size_t size = GBB_HEADER_SIZE; @@ -177,7 +177,7 @@ static uint8_t *create_gbb(const char *desc, off_t * sizeptr) return buf; } -uint8_t *read_entire_file(const char *filename, off_t * sizeptr) +static uint8_t *read_entire_file(const char *filename, off_t *sizeptr) { FILE *fp = NULL; uint8_t *buf = NULL; @@ -232,7 +232,7 @@ fail: } static int write_to_file(const char *msg, const char *filename, - uint8_t * start, size_t size) + uint8_t *start, size_t size) { FILE *fp; int r = 0; @@ -268,7 +268,7 @@ static int write_to_file(const char *msg, const char *filename, } static int read_from_file(const char *msg, const char *filename, - uint8_t * start, uint32_t size) + uint8_t *start, uint32_t size) { FILE *fp; struct stat sb; @@ -419,15 +419,18 @@ static int do_gbb_utility(int argc, char *argv[]) } /* Problems? */ - if (errorcnt) - help_and_quit(argv[0]); + if (errorcnt) { + print_help(argv[0]); + return 1; + } /* Now try to do something */ switch (mode) { case DO_GET: if (argc - optind < 1) { fprintf(stderr, "\nERROR: missing input filename\n"); - help_and_quit(argv[0]); + print_help(argv[0]); + return 1; } else { infile = argv[optind++]; } @@ -475,7 +478,8 @@ static int do_gbb_utility(int argc, char *argv[]) case DO_SET: if (argc - optind < 1) { fprintf(stderr, "\nERROR: missing input filename\n"); - help_and_quit(argv[0]); + print_help(argv[0]); + return 1; } infile = argv[optind++]; if (!outfile) @@ -483,11 +487,13 @@ static int do_gbb_utility(int argc, char *argv[]) if (sel_hwid && !opt_hwid) { fprintf(stderr, "\nERROR: missing new HWID value\n"); - help_and_quit(argv[0]); + print_help(argv[0]); + return 1; } if (sel_flags && (!opt_flags || !*opt_flags)) { fprintf(stderr, "\nERROR: missing new flags value\n"); - help_and_quit(argv[0]); + print_help(argv[0]); + return 1; } /* With no args, we'll either copy it unchanged or do nothing */ @@ -576,7 +582,8 @@ static int do_gbb_utility(int argc, char *argv[]) if (argc - optind < 1) { fprintf(stderr, "\nERROR: missing output filename\n"); - help_and_quit(argv[0]); + print_help(argv[0]); + return 1; } outfile = argv[optind++]; } @@ -586,7 +593,8 @@ static int do_gbb_utility(int argc, char *argv[]) fprintf(stderr, "\nERROR: unable to parse creation spec (%s)\n", opt_create); - help_and_quit(argv[0]); + print_help(argv[0]); + return 1; } if (!errorcnt) write_to_file("successfully created new GBB to:", @@ -598,8 +606,9 @@ static int do_gbb_utility(int argc, char *argv[]) free(inbuf); if (outbuf) free(outbuf); - return ! !errorcnt; + return !!errorcnt; } DECLARE_FUTIL_COMMAND(gbb_utility, do_gbb_utility, - "Utility to manage Google Binary Block (GBB)"); + "Manipulate the Google Binary Block (GBB)", + print_help); diff --git a/futility/cmd_load_fmap.c b/futility/cmd_load_fmap.c index 3b10aa9f..f7b978aa 100644 --- a/futility/cmd_load_fmap.c +++ b/futility/cmd_load_fmap.c @@ -41,8 +41,7 @@ static const char usage[] = "\n" static void help_and_quit(const char *prog) { - fprintf(stderr, usage, prog, prog); - exit(1); + printf(usage, prog, prog); } static const struct option long_opts[] = { @@ -124,14 +123,17 @@ static int do_load_fmap(int argc, char *argv[]) } } - if (errorcnt) + if (errorcnt) { help_and_quit(argv[0]); + return 1; + } if (argc - optind < 2) { fprintf(stderr, "You must specify an input file" " and at least one AREA:file argument\n"); help_and_quit(argv[0]); + return 1; } infile = argv[optind++]; @@ -199,4 +201,5 @@ done_file: } DECLARE_FUTIL_COMMAND(load_fmap, do_load_fmap, - "Replace the contents of specified FMAP areas"); + "Replace the contents of specified FMAP areas", + help_and_quit); diff --git a/futility/cmd_show.c b/futility/cmd_show.c index 41377bc9..c6be07a3 100644 --- a/futility/cmd_show.c +++ b/futility/cmd_show.c @@ -39,7 +39,7 @@ static struct local_data_s { static void show_key(VbPublicKey *pubkey, const char *sp) { - printf("%sAlgorithm: %" PRIu64 " %s\n", sp,pubkey->algorithm, + printf("%sAlgorithm: %" PRIu64 " %s\n", sp, pubkey->algorithm, (pubkey->algorithm < kNumAlgorithms ? algo_strings[pubkey->algorithm] : "(invalid)")); printf("%sKey Version: %" PRIu64 "\n", sp, pubkey->key_version); @@ -51,11 +51,14 @@ static void show_key(VbPublicKey *pubkey, const char *sp) static void show_keyblock(VbKeyBlockHeader *key_block, const char *name, int sign_key, int good_sig) { - printf("Key block: %s\n", name); - printf(" Size: %" PRIu64 "\n", + if (name) + printf("Key block: %s\n", name); + else + printf("Key block:\n"); + printf(" Signature: %s\n", + sign_key ? (good_sig ? "valid" : "invalid") : "ignored"); + printf(" Size: 0x%" PRIx64 "\n", key_block->key_block_size); - printf(" Signature %s\n", - sign_key ? (good_sig ? "valid" : "invalid" ) : "ignored"); printf(" Flags: %" PRIu64 " ", key_block->key_block_flags); if (key_block->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_0) @@ -282,7 +285,7 @@ int futil_cb_show_fw_preamble(struct futil_traverse_state_s *state) RSAPublicKey *rsa = PublicKeyToRSA(&key_block->data_key); if (!rsa) { - VbExError("Error parsing data key in %s\n", state->name); + fprintf(stderr, "Error parsing data key in %s\n", state->name); return 1; } uint32_t more = key_block->key_block_size; @@ -296,7 +299,7 @@ int futil_cb_show_fw_preamble(struct futil_traverse_state_s *state) } uint32_t flags = VbGetFirmwarePreambleFlags(preamble); - printf("Preamble:\n"); + printf("Firmware Preamble:\n"); printf(" Size: %" PRIu64 "\n", preamble->preamble_size); printf(" Header version: %" PRIu32 ".%" PRIu32 "\n", @@ -319,14 +322,13 @@ int futil_cb_show_fw_preamble(struct futil_traverse_state_s *state) if (flags & VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL) { - printf ("Preamble requests USE_RO_NORMAL;" - " skipping body verification.\n"); + printf("Preamble requests USE_RO_NORMAL;" + " skipping body verification.\n"); goto done; } /* We'll need to get the firmware body from somewhere... */ - if (fw_body_area && (fw_body_area->_flags & AREA_IS_VALID)) - { + if (fw_body_area && (fw_body_area->_flags & AREA_IS_VALID)) { fv_data = fw_body_area->buf; fv_size = fw_body_area->len; } @@ -339,7 +341,7 @@ int futil_cb_show_fw_preamble(struct futil_traverse_state_s *state) if (VBOOT_SUCCESS != VerifyData(fv_data, fv_size, &preamble->body_signature, rsa)) { - VbExError("Error verifying firmware body.\n"); + fprintf(stderr, "Error verifying firmware body.\n"); return 1; } @@ -378,18 +380,26 @@ int futil_cb_show_begin(struct futil_traverse_state_s *state) return 0; } -static void help_and_quit(const char *prog) +static const char usage[] = "\n" + "Usage: " MYNAME " %s [OPTIONS] FILE\n" + "\n" + "Where FILE could be a\n" + "\n" + " public key (.vbpubk)\n" + " keyblock (.keyblock)\n" + " firmware preamble signature (VBLOCK_A/B)\n" + " firmware image (bios.bin)\n" + " kernel partition (/dev/sda2, /dev/mmcblk0p2)\n" + "\n" + "Options:\n" + " -k|--publickey FILE Use this public key for validation\n" + " -f|--fv FILE|OFFSET Verify this payload (FW_MAIN_A/B, or\n" + " kernel vblock padding size)\n" + "\n"; + +static void print_help(const char *prog) { - fprintf(stderr, "\n" - "Usage: " MYNAME " %s [OPTIONS] FILE\n" - "\n" - "Display the contents of the given FILE\n" - "\n" - "Options:\n" - " -k|--publickey FILE Use this public key for validation\n" - " -f|--fv FILE Use this firmware blob where needed\n" - "\n", prog); - exit(1); + printf(usage, prog); } static const struct option long_opts[] = { @@ -437,17 +447,22 @@ static int do_show(int argc, char *argv[]) fprintf(stderr, "Missing argument to -%c\n", optopt); errorcnt++; break; + case 0: /* handled option */ + break; default: DIE; } } - if (errorcnt) - help_and_quit(argv[0]); + if (errorcnt) { + print_help(argv[0]); + return 1; + } if (argc - optind < 1) { fprintf(stderr, "ERROR: missing input filename\n"); - help_and_quit(argv[0]); + print_help(argv[0]); + return 1; } for (i = optind; i < argc; i++) { @@ -481,4 +496,6 @@ static int do_show(int argc, char *argv[]) return !!errorcnt; } -DECLARE_FUTIL_COMMAND(show, do_show, "Display what we know about a file"); +DECLARE_FUTIL_COMMAND(show, do_show, + "Display the content of various binary components", + print_help); diff --git a/futility/cmd_sign.c b/futility/cmd_sign.c index 8c59fb21..49ea5f00 100644 --- a/futility/cmd_sign.c +++ b/futility/cmd_sign.c @@ -73,7 +73,11 @@ int futil_cb_sign_fw_main(struct futil_traverse_state_s *state) return 0; } - +/* + * This handles VBLOCK_A and VBLOCK_B while processing a BIOS image. + * We don't do any signing here. We just check to see if the VBLOCK + * area contains a firmware preamble. + */ int futil_cb_sign_fw_preamble(struct futil_traverse_state_s *state) { VbKeyBlockHeader *key_block = (VbKeyBlockHeader *)state->my_area->buf; @@ -91,7 +95,7 @@ int futil_cb_sign_fw_preamble(struct futil_traverse_state_s *state) if (VBOOT_SUCCESS != KeyBlockVerify(key_block, len, NULL, 1)) { fprintf(stderr, "Warning: %s keyblock is invalid. " "Signing the entire FW FMAP region...\n", - state->name); + state->name); goto whatever; } @@ -125,7 +129,7 @@ int futil_cb_sign_fw_preamble(struct futil_traverse_state_s *state) if (fw_size > fw_body_area->len) { fprintf(stderr, "%s says the firmware is larger than we have\n", - state->name); + state->name); return 1; } @@ -297,10 +301,9 @@ static const char usage[] = "\n" " -l|--loemid STRING Local OEM vblock suffix\n" "\n"; -static void help_and_quit(const char *prog) +static void print_help(const char *prog) { - fprintf(stderr, usage, prog, option.version); - exit(1); + printf(usage, prog, option.version); } static const struct option long_opts[] = { @@ -425,8 +428,10 @@ static int do_sign(int argc, char *argv[]) errorcnt++; } - if (errorcnt) - help_and_quit(argv[0]); + if (errorcnt) { + print_help(argv[0]); + return 1; + } switch (argc - optind) { case 2: @@ -442,11 +447,13 @@ static int do_sign(int argc, char *argv[]) break; case 0: fprintf(stderr, "ERROR: missing input filename\n"); - help_and_quit(argv[0]); + print_help(argv[0]); + return 1; break; default: fprintf(stderr, "ERROR: too many arguments left over\n"); - help_and_quit(argv[0]); + print_help(argv[0]); + return 1; } @@ -479,4 +486,6 @@ static int do_sign(int argc, char *argv[]) return !!errorcnt; } -DECLARE_FUTIL_COMMAND(sign, do_sign, "[Re]Sign a BIOS image"); +DECLARE_FUTIL_COMMAND(sign, do_sign, + "[Re]Sign a BIOS image", + print_help); diff --git a/futility/cmd_vb2_verify_fw.c b/futility/cmd_vb2_verify_fw.c index 7343d7a4..989fc782 100644 --- a/futility/cmd_vb2_verify_fw.c +++ b/futility/cmd_vb2_verify_fw.c @@ -13,8 +13,6 @@ #include "2api.h" #include "futility.h" -const char *progname = "vb2_verify_fw"; - const char *gbb_fname; const char *vblock_fname; const char *body_fname; @@ -34,7 +32,7 @@ int vb2ex_read_resource(struct vb2_context *ctx, int got_size; /* Get the filename for the resource */ - switch(index) { + switch (index) { case VB2_RES_GBB: fname = gbb_fname; break; @@ -72,7 +70,7 @@ int vb2ex_tpm_clear_owner(struct vb2_context *ctx) /** * Save non-volatile and/or secure data if needed. */ -void save_if_needed(struct vb2_context *ctx) +static void save_if_needed(struct vb2_context *ctx) { if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) { @@ -89,7 +87,7 @@ void save_if_needed(struct vb2_context *ctx) /** * Verify firmware body */ -int hash_body(struct vb2_context *ctx) +static int hash_body(struct vb2_context *ctx) { uint32_t expect_size; uint8_t block[8192]; @@ -134,21 +132,19 @@ int hash_body(struct vb2_context *ctx) return VB2_SUCCESS; } -int do_vb2_verify_fw(int argc, char *argv[]) +static void print_help(const char *progname) +{ + printf("Usage: %s \n", progname); +} + +static int do_vb2_verify_fw(int argc, char *argv[]) { struct vb2_context ctx; uint8_t workbuf[16384]; int rv; - progname = strrchr(argv[0], '/'); - if (progname) - progname++; - else - progname = argv[0]; - if (argc < 4) { - fprintf(stderr, - "usage: %s \n", progname); + print_help(argv[0]); return 1; } @@ -216,4 +212,5 @@ int do_vb2_verify_fw(int argc, char *argv[]) } DECLARE_FUTIL_COMMAND(vb2_verify_fw, do_vb2_verify_fw, - "Verifies firmware using vboot2 library"); + "Verifies firmware using vboot2 library", + print_help); diff --git a/futility/cmd_vbutil_firmware.c b/futility/cmd_vbutil_firmware.c index 95cae28d..dcb325e1 100644 --- a/futility/cmd_vbutil_firmware.c +++ b/futility/cmd_vbutil_firmware.c @@ -46,33 +46,32 @@ static const struct option long_opts[] = { }; /* Print help and return error */ -static int PrintHelp(void) +static void print_help(const char *prog) { - - puts("vbutil_firmware - Verified boot key block utility\n" - "\n" - "Usage: vbutil_firmware <--vblock|--verify> [OPTIONS]\n" - "\n" - "For '--vblock ', required OPTIONS are:\n" - " --keyblock Key block in .keyblock format\n" - " --signprivate " - " Signing private key in .vbprivk format\n" - " --version Firmware version\n" - " --fv Firmware volume to sign\n" - " --kernelkey Kernel subkey in .vbpubk format\n" - "optional OPTIONS are:\n" - " --flags Preamble flags (defaults to 0)\n" - "\n" - "For '--verify ', required OPTIONS are:\n" - " --signpubkey " - " Signing public key in .vbpubk format\n" - " --fv Firmware volume to verify\n" - "\n" - "For '--verify ', optional OPTIONS are:\n" - " --kernelkey " - " Write the kernel subkey to this file\n" - ""); - return 1; + printf("\nUsage: " MYNAME " %s <--vblock|--verify> [OPTIONS]\n" + "\n" + "For '--vblock ', required OPTIONS are:\n" + "\n" + " --keyblock Key block in .keyblock format\n" + " --signprivate " + " Signing private key in .vbprivk format\n" + " --version Firmware version\n" + " --fv Firmware volume to sign\n" + " --kernelkey Kernel subkey in .vbpubk format\n" + "\n" + "optional OPTIONS are:\n" + " --flags Preamble flags (defaults to 0)\n" + "\n" + "For '--verify ', required OPTIONS are:\n" + "\n" + " --signpubkey " + " Signing public key in .vbpubk format\n" + " --fv Firmware volume to verify\n" + "\n" + "For '--verify ', optional OPTIONS are:\n" + " --kernelkey " + " Write the kernel subkey to this file\n\n", + prog); } /* Create a firmware .vblock */ @@ -368,8 +367,10 @@ static int do_vbutil_firmware(int argc, char *argv[]) } } - if (parse_error) - return PrintHelp(); + if (parse_error) { + print_help(argv[0]); + return 1; + } switch (mode) { case OPT_MODE_VBLOCK: @@ -378,10 +379,12 @@ static int do_vbutil_firmware(int argc, char *argv[]) case OPT_MODE_VERIFY: return Verify(filename, signpubkey, fv_file, kernelkey_file); default: - printf("Must specify a mode.\n"); - return PrintHelp(); + fprintf(stderr, "Must specify a mode.\n"); + print_help(argv[0]); + return 1; } } DECLARE_FUTIL_COMMAND(vbutil_firmware, do_vbutil_firmware, - "Verified boot firmware utility"); + "Verified boot firmware utility", + print_help); diff --git a/futility/cmd_vbutil_kernel.c b/futility/cmd_vbutil_kernel.c index ebb4510e..740c3af4 100644 --- a/futility/cmd_vbutil_kernel.c +++ b/futility/cmd_vbutil_kernel.c @@ -28,9 +28,9 @@ #include "vboot_common.h" /* Global opts */ -static int opt_debug = 0; -static int opt_verbose = 0; -static int opt_vblockonly = 0; +static int opt_debug; +static int opt_verbose; +static int opt_vblockonly; static uint64_t opt_pad = 65536; /* Command line options */ @@ -85,9 +85,8 @@ static const struct option long_opts[] = { static const char usage[] = - "This program creates, signs, and verifies the kernel blob\n" "\n" - "Usage: %s --pack [PARAMETERS]\n" + "Usage: " MYNAME " %s --pack [PARAMETERS]\n" "\n" " Required parameters:\n" " --keyblock Key block in .keyblock format\n" @@ -104,7 +103,7 @@ static const char usage[] = " --pad Verification padding size in bytes\n" " --vblockonly Emit just the verification blob\n" "\nOR\n\n" - "Usage: %s --repack [PARAMETERS]\n" + "Usage: " MYNAME " %s --repack [PARAMETERS]\n" "\n" " Required parameters:\n" " --signprivate Private key to sign kernel data,\n" @@ -120,7 +119,7 @@ static const char usage[] = " --pad Verification blob size in bytes\n" " --vblockonly Emit just the verification blob\n" "\nOR\n\n" - "Usage: %s --verify [PARAMETERS]\n" + "Usage: " MYNAME " %s --verify [PARAMETERS]\n" "\n" " Optional:\n" " --signpubkey " @@ -136,10 +135,9 @@ static const char usage[] = /* Print help and return error */ -static int PrintHelp(char *progname) +static void print_help(const char *progname) { - fprintf(stderr, usage, progname, progname, progname); - return 1; + printf(usage, progname, progname, progname); } static void Debug(const char *format, ...) @@ -165,7 +163,7 @@ static void Fatal(const char *format, ...) } /* Return an explanation when fread() fails. */ -static const char *error_fread(FILE * fp) +static const char *error_fread(FILE *fp) { const char *retval = "beats me why"; if (feof(fp)) @@ -238,7 +236,7 @@ static VbKernelPreambleHeader *g_preamble; * Return the buffer contaning the line on success (and set the line length * using the passed in parameter), or NULL in case something goes wrong. */ -static uint8_t *ReadConfigFile(const char *config_file, uint64_t * config_size) +static uint8_t *sReadConfigFile(const char *config_file, uint64_t *config_size) { uint8_t *config_buf; int ii; @@ -252,16 +250,15 @@ static uint8_t *ReadConfigFile(const char *config_file, uint64_t * config_size) } /* Replace newlines with spaces */ - for (ii = 0; ii < *config_size; ii++) { - if ('\n' == config_buf[ii]) { + for (ii = 0; ii < *config_size; ii++) + if ('\n' == config_buf[ii]) config_buf[ii] = ' '; - } - } + return config_buf; } /* Offset of kernel command line string from start of packed kernel blob */ -static uint64_t CmdLineOffset(VbKernelPreambleHeader * preamble) +static uint64_t CmdLineOffset(VbKernelPreambleHeader *preamble) { return preamble->bootloader_address - preamble->body_load_address - CROS_CONFIG_SIZE - CROS_PARAMS_SIZE; @@ -355,7 +352,7 @@ static int ImportVmlinuzFile(const char *vmlinuz_file, arch_t arch, /* This returns just the kernel blob, with the verification blob separated * and copied to new memory in g_keyblock and g_preamble. */ static uint8_t *ReadOldBlobFromFileOrDie(const char *filename, - uint64_t * size_ptr) + uint64_t *size_ptr) { FILE *fp = NULL; struct stat statbuf; @@ -371,9 +368,8 @@ static uint8_t *ReadOldBlobFromFileOrDie(const char *filename, Fatal("Unable to stat %s: %s\n", filename, strerror(errno)); if (S_ISBLK(statbuf.st_mode)) { - int fd; - - if ((fd = open(filename, O_RDONLY)) >= 0) { + int fd = open(filename, O_RDONLY); + if (fd >= 0) { ioctl(fd, BLKGETSIZE64, &file_size); close(fd); } @@ -460,7 +456,7 @@ static uint8_t *ReadOldBlobFromFileOrDie(const char *filename, /* Split a kernel blob into separate g_kernel, g_param, g_config, and * g_bootloader parts. */ -static void UnpackKernelBlob(uint8_t * kernel_blob_data, +static void UnpackKernelBlob(uint8_t *kernel_blob_data, uint64_t kernel_blob_size) { @@ -498,8 +494,8 @@ static void UnpackKernelBlob(uint8_t * kernel_blob_data, /****************************************************************************/ -static uint8_t *CreateKernelBlob(uint64_t kernel_body_load_address, - arch_t arch, uint64_t * size_ptr) +static uint8_t *CreateKernBlob(uint64_t kernel_body_load_address, + arch_t arch, uint64_t *size_ptr) { uint8_t *kern_blob; uint64_t kern_blob_size; @@ -525,9 +521,8 @@ static uint8_t *CreateKernelBlob(uint64_t kernel_body_load_address, now += CROS_CONFIG_SIZE; Debug("params goes at kern_blob+0x%" PRIx64 "\n", now); - if (g_param_size) { + if (g_param_size) Memcpy(kern_blob + now, g_param_data, g_param_size); - } now += CROS_PARAMS_SIZE; Debug("bootloader goes at kern_blob+0x%" PRIx64 "\n", now); @@ -547,10 +542,11 @@ static uint8_t *CreateKernelBlob(uint64_t kernel_body_load_address, } static int Pack(const char *outfile, - uint8_t * kernel_blob, + uint8_t *kernel_blob, uint64_t kernel_size, int version, - uint64_t kernel_body_load_address, VbPrivateKey * signpriv_key) + uint64_t kernel_body_load_address, + VbPrivateKey *signpriv_key) { VbSignature *body_sig; FILE *f; @@ -611,10 +607,11 @@ static int Pack(const char *outfile, return 0; } -static int Verify(uint8_t * kernel_blob, +static int Verify(uint8_t *kernel_blob, uint64_t kernel_size, - VbPublicKey * signpub_key, - const char *keyblock_outfile, uint64_t min_version) + VbPublicKey *signpub_key, + const char *keyblock_outfile, + uint64_t min_version) { VbPublicKey *data_key; RSAPublicKey *rsa; @@ -737,12 +734,6 @@ static int do_vbutil_kernel(int argc, char *argv[]) uint8_t *kernel_blob = NULL; uint64_t kernel_size = 0; - char *progname = strrchr(argv[0], '/'); - if (progname) - progname++; - else - progname = argv[0]; - while (((i = getopt_long(argc, argv, ":", long_opts, NULL)) != -1) && !parse_error) { switch (i) { @@ -855,8 +846,10 @@ static int do_vbutil_kernel(int argc, char *argv[]) } } - if (parse_error) - return PrintHelp(progname); + if (parse_error) { + print_help(argv[0]); + return 1; + } switch (mode) { case OPT_MODE_PACK: @@ -882,7 +875,7 @@ static int do_vbutil_kernel(int argc, char *argv[]) if (config_file) { Debug("Reading %s\n", config_file); g_config_data = - ReadConfigFile(config_file, &g_config_size); + sReadConfigFile(config_file, &g_config_size); if (!g_config_data) Fatal("Error reading config file.\n"); } @@ -904,8 +897,8 @@ static int do_vbutil_kernel(int argc, char *argv[]) /* Do it */ - kernel_blob = CreateKernelBlob(kernel_body_load_address, arch, - &kernel_size); + kernel_blob = CreateKernBlob(kernel_body_load_address, arch, + &kernel_size); return Pack(filename, kernel_blob, kernel_size, version, kernel_body_load_address, signpriv_key); @@ -949,7 +942,7 @@ static int do_vbutil_kernel(int argc, char *argv[]) free(g_config_data); Debug("Reading %s\n", config_file); g_config_data = - ReadConfigFile(config_file, &g_config_size); + sReadConfigFile(config_file, &g_config_size); if (!g_config_data) Fatal("Error reading config file.\n"); } @@ -965,8 +958,8 @@ static int do_vbutil_kernel(int argc, char *argv[]) /* Put it back together */ - kernel_blob = CreateKernelBlob(kernel_body_load_address, arch, - &kernel_size); + kernel_blob = CreateKernBlob(kernel_body_load_address, arch, + &kernel_size); return Pack(filename, kernel_blob, kernel_size, version, kernel_body_load_address, signpriv_key); @@ -991,8 +984,10 @@ static int do_vbutil_kernel(int argc, char *argv[]) fprintf(stderr, "You must specify a mode: --pack, --repack or --verify\n"); - return PrintHelp(progname); + print_help(argv[0]); + return 1; } DECLARE_FUTIL_COMMAND(vbutil_kernel, do_vbutil_kernel, - "Verified boot kernel utility"); + "Creates, signs, and verifies the kernel blob", + print_help); diff --git a/futility/cmd_vbutil_key.c b/futility/cmd_vbutil_key.c index c8c1c61b..ea8dea0b 100644 --- a/futility/cmd_vbutil_key.c +++ b/futility/cmd_vbutil_key.c @@ -38,40 +38,32 @@ static const struct option long_opts[] = { {NULL, 0, 0, 0} }; -/* Print help and return error */ -static int PrintHelp(char *progname) +static void print_help(const char *progname) { int i; - fprintf(stderr, - "This program wraps RSA keys with verified boot headers\n"); - fprintf(stderr, - "\n" - "Usage: %s --pack [PARAMETERS]\n" - "\n" - " Required parameters:\n" - " --key RSA key file (.keyb or .pem)\n" - " --version Key version number " - "(required for .keyb,\n" - " ignored for .pem)\n" - " --algorithm " - "Signing algorithm to use with key:\n", progname); + printf("\n" + "Usage: " MYNAME " %s --pack [PARAMETERS]\n" + "\n" + " Required parameters:\n" + " --key RSA key file (.keyb or .pem)\n" + " --version Key version number " + "(required for .keyb,\n" + " ignored for .pem)\n" + " --algorithm " + "Signing algorithm to use with key:\n", progname); for (i = 0; i < kNumAlgorithms; i++) { - fprintf(stderr, - " %d = (%s)\n", - i, algo_strings[i]); + printf(" %d = (%s)\n", + i, algo_strings[i]); } - fprintf(stderr, - "\nOR\n\n" - "Usage: %s --unpack \n" - "\n" - " Optional parameters:\n" - " --copyto " - "Write a copy of the key to this file.\n" "\n", progname); - - return 1; + printf("\nOR\n\n" + "Usage: " MYNAME " %s --unpack \n" + "\n" + " Optional parameters:\n" + " --copyto " + "Write a copy of the key to this file.\n\n", progname); } /* Pack a .keyb file into a .vbpubk, or a .pem into a .vbprivk */ @@ -86,7 +78,8 @@ static int Pack(const char *infile, const char *outfile, uint64_t algorithm, return 1; } - if ((pubkey = PublicKeyReadKeyb(infile, algorithm, version))) { + pubkey = PublicKeyReadKeyb(infile, algorithm, version); + if (pubkey) { if (0 != PublicKeyWrite(outfile, pubkey)) { fprintf(stderr, "vbutil_key: Error writing key.\n"); return 1; @@ -95,7 +88,8 @@ static int Pack(const char *infile, const char *outfile, uint64_t algorithm, return 0; } - if ((privkey = PrivateKeyReadPem(infile, algorithm))) { + privkey = PrivateKeyReadPem(infile, algorithm); + if (privkey) { if (0 != PrivateKeyWrite(outfile, privkey)) { fprintf(stderr, "vbutil_key: Error writing key.\n"); return 1; @@ -119,7 +113,8 @@ static int Unpack(const char *infile, const char *outfile) return 1; } - if ((pubkey = PublicKeyRead(infile))) { + pubkey = PublicKeyRead(infile); + if (pubkey) { printf("Public Key file: %s\n", infile); printf("Algorithm: %" PRIu64 " %s\n", pubkey->algorithm, (pubkey->algorithm < kNumAlgorithms ? @@ -140,7 +135,8 @@ static int Unpack(const char *infile, const char *outfile) return 0; } - if ((privkey = PrivateKeyRead(infile))) { + privkey = PrivateKeyRead(infile); + if (privkey) { printf("Private Key file: %s\n", infile); printf("Algorithm: %" PRIu64 " %s\n", privkey->algorithm, @@ -177,12 +173,6 @@ static int do_vbutil_key(int argc, char *argv[]) char *e; int i; - char *progname = strrchr(argv[0], '/'); - if (progname) - progname++; - else - progname = argv[0]; - while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) { switch (i) { case '?': @@ -227,8 +217,10 @@ static int do_vbutil_key(int argc, char *argv[]) } } - if (parse_error) - return PrintHelp(progname); + if (parse_error) { + print_help(argv[0]); + return 1; + } switch (mode) { case OPT_MODE_PACK: @@ -237,9 +229,11 @@ static int do_vbutil_key(int argc, char *argv[]) return Unpack(infile, outfile); default: printf("Must specify a mode.\n"); - return PrintHelp(progname); + print_help(argv[0]); + return 1; } } DECLARE_FUTIL_COMMAND(vbutil_key, do_vbutil_key, - "Wraps RSA keys with vboot headers"); + "Wraps RSA keys with vboot headers", + print_help); diff --git a/futility/cmd_vbutil_keyblock.c b/futility/cmd_vbutil_keyblock.c index 58d89c1a..c73fd9ae 100644 --- a/futility/cmd_vbutil_keyblock.c +++ b/futility/cmd_vbutil_keyblock.c @@ -44,9 +44,8 @@ static const struct option long_opts[] = { }; static const char usage[] = - "Verified boot key block utility\n" "\n" - "Usage: %s <--pack|--unpack> [OPTIONS]\n" + "Usage: " MYNAME " %s <--pack|--unpack> [OPTIONS]\n" "\n" "For '--pack ', required OPTIONS are:\n" " --datapubkey Data public key in .vbpubk format\n" @@ -70,13 +69,11 @@ static const char usage[] = " Signing public key in .vbpubk format. This is required to\n" " verify a signed keyblock.\n" " --datapubkey " - " Write the data public key to this file.\n"; + " Write the data public key to this file.\n\n"; -/* Print help and return error */ -static int PrintHelp(char *progname) +static void print_help(const char *progname) { - fprintf(stderr, usage, progname); - return 1; + printf(usage, progname); } /* Pack a .keyblock */ @@ -240,12 +237,6 @@ static int do_vbutil_keyblock(int argc, char *argv[]) char *e; int i; - char *progname = strrchr(argv[0], '/'); - if (progname) - progname++; - else - progname = argv[0]; - while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) { switch (i) { case '?': @@ -321,8 +312,10 @@ static int do_vbutil_keyblock(int argc, char *argv[]) parse_error = 1; } - if (parse_error) - return PrintHelp(progname); + if (parse_error) { + print_help(argv[0]); + return 1; + } switch (mode) { case OPT_MODE_PACK: @@ -333,9 +326,11 @@ static int do_vbutil_keyblock(int argc, char *argv[]) return Unpack(filename, datapubkey, signpubkey); default: printf("Must specify a mode.\n"); - return PrintHelp(progname); + print_help(argv[0]); + return 1; } } DECLARE_FUTIL_COMMAND(vbutil_keyblock, do_vbutil_keyblock, - "Verified boot key block utility"); + "Creates, signs, and verifies a keyblock", + print_help); diff --git a/futility/cmd_verify_kernel.c b/futility/cmd_verify_kernel.c index 8c413427..28d24536 100644 --- a/futility/cmd_verify_kernel.c +++ b/futility/cmd_verify_kernel.c @@ -26,7 +26,7 @@ static LoadKernelParams params; static VbCommonParams cparams; VbError_t VbExDiskRead(VbExDiskHandle_t handle, uint64_t lba_start, - uint64_t lba_count, void *buffer) + uint64_t lba_count, void *buffer) { if (handle != (VbExDiskHandle_t)1) return VBERROR_UNKNOWN; @@ -40,7 +40,7 @@ VbError_t VbExDiskRead(VbExDiskHandle_t handle, uint64_t lba_start, } VbError_t VbExDiskWrite(VbExDiskHandle_t handle, uint64_t lba_start, - uint64_t lba_count, const void *buffer) + uint64_t lba_count, const void *buffer) { if (handle != (VbExDiskHandle_t)1) return VBERROR_UNKNOWN; @@ -53,21 +53,20 @@ VbError_t VbExDiskWrite(VbExDiskHandle_t handle, uint64_t lba_start, return VBERROR_SUCCESS; } -int do_verify_kernel(int argc, char *argv[]) +static void print_help(const char *progname) +{ + printf("\nUsage: " MYNAME " %s \n\n", + progname); +} + +static int do_verify_kernel(int argc, char *argv[]) { VbPublicKey *kernkey; uint64_t disk_bytes = 0; int rv; - const char *progname = strrchr(argv[0], '/'); - if (progname) - progname++; - else - progname = argv[0]; - if (argc < 3) { - fprintf(stderr, - "usage: %s \n", progname); + print_help(argv[0]); return 1; } @@ -138,4 +137,5 @@ int do_verify_kernel(int argc, char *argv[]) } DECLARE_FUTIL_COMMAND(verify_kernel, do_verify_kernel, - "Verifies a kernel / disk image"); + "Verifies a kernel / disk image", + print_help); diff --git a/futility/dump_kernel_config_lib.c b/futility/dump_kernel_config_lib.c index d3e88a96..93a51581 100644 --- a/futility/dump_kernel_config_lib.c +++ b/futility/dump_kernel_config_lib.c @@ -14,7 +14,7 @@ #include "vboot_api.h" #include "vboot_host.h" -static uint8_t *GetKernelConfig(uint8_t * blob, size_t blob_size, +static uint8_t *GetKernelConfig(uint8_t *blob, size_t blob_size, uint64_t kernel_body_load_address) { @@ -58,7 +58,7 @@ static uint8_t *GetKernelConfig(uint8_t * blob, size_t blob_size, return blob + offset; } -static void *MMapFile(const char *filename, size_t * size) +static void *MMapFile(const char *filename, size_t *size) { FILE *f; uint8_t *buf; diff --git a/futility/futility.c b/futility/futility.c index 1a132202..bc98a75f 100644 --- a/futility/futility.c +++ b/futility/futility.c @@ -16,85 +16,17 @@ #include "futility.h" -#define MYNAME_S MYNAME "_s" + +/******************************************************************************/ +/* Logging stuff */ /* File to use for logging, if present */ #define LOGFILE "/tmp/futility.log" /* Normally logging will only happen if the logfile already exists. Uncomment * this to force log file creation (and thus logging) always. */ -/* #define FORCE_LOGGING_ON */ - -/******************************************************************************/ - -static const char *const usage = "\n\ -Usage: " MYNAME " PROGRAM|COMMAND [args...]\n\ -\n\ -This is the unified firmware utility, which will eventually replace\n\ -most of the distinct verified boot tools formerly produced by the\n\ -vboot_reference package.\n\ -\n\ -When symlinked under the name of one of those previous tools, should\n\ -fully implement the original behavior. It can also be invoked directly\n\ -as " MYNAME ", followed by the original name as the first argument.\n\ -\n\ -In either case it will append some usage information to " LOGFILE "\n\ -(iff that file exists), to help improve coverage and correctness.\n\ -\n"; - -static int do_help(int argc, char *argv[]) -{ - const struct futil_cmd_t *const *cmd; - int i; - - fputs(usage, stdout); - - printf("The following commands are built-in:\n\n"); - - for (cmd = futil_cmds; *cmd; cmd++) - printf(" %-20s %s\n", (*cmd)->name, (*cmd)->shorthelp); - printf("\n"); - - if (argc) { - printf("FYI, you added these args that I'm ignoring:\n"); - for (i = 0; i < argc; i++) - printf("argv[%d] = %s\n", i, argv[i]); - } - - return 0; -} - -DECLARE_FUTIL_COMMAND(help, do_help, - "Show a bit of help (you're looking at it)"); - -/* - * These are built-in functions that we'd like to abandon completely someday. - * TODO: If no one complains, get rid of them. - */ -static const char *const dep_cmds[] = { - "dev_sign_file", -}; - -static const char *const dep_usage = "\n\ -The program \"%s\" is deprecated and may go away soon.\n\ -\n\ -If you feel this is in error, please open a bug at\n\ -\n\ - http://dev.chromium.org/for-testers/bug-reporting-guidelines\n\ -\n\ -In the meantime, you may continue to use the program by invoking it as\n\ -\n\ - " MYNAME " %s [...]\n\ -\n"; - -static void deprecated(const char *depname) -{ - fprintf(stderr, dep_usage, depname, depname); - exit(1); -} -/******************************************************************************/ -/* Logging stuff */ +/* #define FORCE_LOGGING_ON */ static int log_fd = -1; @@ -241,9 +173,100 @@ static void log_args(int argc, char *argv[]) log_close(); } +/******************************************************************************/ + +static const char *const usage = "\n" +"Usage: " MYNAME " COMMAND [args...]\n" +"\n" +"This is the unified firmware utility, which will eventually replace\n" +"most of the distinct verified boot tools formerly produced by the\n" +"vboot_reference package.\n" +"\n" +"When symlinked under the name of one of those previous tools, it should\n" +"fully implement the original behavior. It can also be invoked directly\n" +"as " MYNAME ", followed by the original name as the first argument.\n" +"\n"; + +static void print_help(const char *cmd) +{ + puts(usage); +} + +static const struct futil_cmd_t *find_command(const char *name) +{ + const struct futil_cmd_t *const *cmd; + + for (cmd = futil_cmds; *cmd; cmd++) + if (0 == strcmp((*cmd)->name, name)) + return *cmd; + + return NULL; +} + +static void list_commands(void) +{ + const struct futil_cmd_t *const *cmd; + + for (cmd = futil_cmds; *cmd; cmd++) + printf(" %-20s %s\n", (*cmd)->name, (*cmd)->shorthelp); +} + +static int do_help(int argc, char *argv[]) +{ + const struct futil_cmd_t *cmd; + + if (argc >= 2) { + cmd = find_command(argv[1]); + if (cmd) { + printf("\n%s - %s\n", argv[1], cmd->shorthelp); + cmd->longhelp(argv[1]); + return 0; + } + } + + fputs(usage, stdout); + + printf("The following commands are built-in:\n\n"); + list_commands(); + printf("\nUse \"" MYNAME " help COMMAND\" for more information.\n\n"); + + return 0; +} + +DECLARE_FUTIL_COMMAND(help, do_help, + "Show a bit of help (you're looking at it)", + print_help); + +/* + * These are built-in functions that we'd like to abandon completely someday. + * TODO: If no one complains, get rid of them. + */ +static const char *const dep_cmds[] = { + "dev_sign_file", +}; + +static const char *const dep_usage = "\n" +"The program \"%s\" is deprecated and may go away soon.\n" +"\n" +"If you feel this is in error, please open a bug at\n" +"\n" +" http://dev.chromium.org/for-testers/bug-reporting-guidelines\n" +"\n" +"In the meantime, you may continue to use the program by invoking it as\n" +"\n" MYNAME " %s [...]\n" +"\n"; + +static void deprecated(const char *depname) +{ + fprintf(stderr, dep_usage, depname, depname); + exit(1); +} + /******************************************************************************/ /* Here we go */ +#define MYNAME_S MYNAME "_s" + int main(int argc, char *argv[], char *envp[]) { char *fullname, *progname; @@ -251,7 +274,7 @@ int main(int argc, char *argv[], char *envp[]) char buf[80]; pid_t myproc; ssize_t r; - const struct futil_cmd_t *const *cmd; + const struct futil_cmd_t *cmd; int i; int via_symlink = 0; @@ -267,6 +290,7 @@ int main(int argc, char *argv[], char *envp[]) /* Invoked directly by name */ if (0 == strcmp(progname, MYNAME) || 0 == strcmp(progname, MYNAME_S)) { + if (argc < 2) { /* must have an argument */ do_help(0, 0); exit(1); @@ -282,6 +306,10 @@ int main(int argc, char *argv[], char *envp[]) progname++; else progname = argv[0]; + /* Oh, and treat "--foo" the same as "foo" */ + while (*progname == '-') + progname++; + } else { /* Invoked by symlink */ via_symlink = 1; /* Block any deprecated functions. */ @@ -291,18 +319,26 @@ int main(int argc, char *argv[], char *envp[]) } /* See if it's asking for something we know how to do ourselves */ - for (cmd = futil_cmds; *cmd; cmd++) - if (0 == strcmp((*cmd)->name, progname)) - return (*cmd)->handler(argc, argv); + cmd = find_command(progname); + if (cmd) { + /* Handle the "CMD --help" case ourselves */ + if (2 == argc && 0 == strcmp(argv[1], "--help")) { + char *fake_argv[] = {"help", + (char *)cmd->name, + NULL}; + return do_help(2, fake_argv); + } else { + return cmd->handler(argc, argv); + } + } - /* Nope */ + /* Never heard of it */ if (!via_symlink) { do_help(0, 0); exit(1); } /* Complain about bogus symlink */ - myproc = getpid(); snprintf(buf, sizeof(buf), "/proc/%d/exe", myproc); r = readlink(buf, truename, PATH_MAX - 1); @@ -313,15 +349,15 @@ int main(int argc, char *argv[], char *envp[]) } truename[r] = '\0'; - fprintf(stderr, "\n\ -The program\n\n %s\n\nis a symlink to\n\n %s\n\ -\n\ -However, " MYNAME " doesn't know how to implement that function.\n\ -\n\ -This is probably an error in your installation. If the problem persists\n\ -after a fresh checkout/build/install, please open a bug at\n\ -\n\ - http://dev.chromium.org/for-testers/bug-reporting-guidelines\n\ -\n", fullname, truename); + fprintf(stderr, "\n" +"The program\n\n %s\n\nis a symlink to\n\n %s\n" +"\n" +"However, " MYNAME " doesn't know how to implement that function.\n" +"\n" +"This is probably an error in your installation. If the problem persists\n" +"after a fresh checkout/build/install, please open a bug at\n" +"\n" +" http://dev.chromium.org/for-testers/bug-reporting-guidelines\n" +"\n", fullname, truename); return 1; } diff --git a/futility/futility.h b/futility/futility.h index 03b4cb57..18261710 100644 --- a/futility/futility.h +++ b/futility/futility.h @@ -18,21 +18,17 @@ struct futil_cmd_t { const char *const name; int (*const handler) (int argc, char **argv); const char *const shorthelp; + void (*longhelp) (const char *cmd); }; -/* - * Macro to define a command. - * - * This defines the struct, then puts a pointer to it in a separate section. - * We'll have a linker script to gather the pointers up later, so we can refer - * to them without explictly declaring every function in a header somewhere. - */ -#define DECLARE_FUTIL_COMMAND(NAME, HANDLER, SHORTHELP) \ - const struct futil_cmd_t __cmd_##NAME = { \ - .name = #NAME, \ - .handler = HANDLER, \ - .shorthelp = SHORTHELP \ - }; +/* Macro to define a command */ +#define DECLARE_FUTIL_COMMAND(NAME, HANDLER, SHORTHELP, LONGHELP) \ + const struct futil_cmd_t __cmd_##NAME = { \ + .name = #NAME, \ + .handler = HANDLER, \ + .shorthelp = SHORTHELP, \ + .longhelp = LONGHELP, \ + } /* This is the list of pointers to all commands. */ extern const struct futil_cmd_t *const futil_cmds[]; @@ -45,8 +41,8 @@ extern const struct futil_cmd_t *const futil_cmds[]; /* Test an important condition at compile time, not run time */ #ifndef BUILD_ASSERT #define _BA1_(cond, line) \ - extern int __build_assertion_ ## line[1 - 2*!(cond)] \ - __attribute__ ((unused)) + extern int __build_assertion_ ## line[1 - 2*!(cond)] \ + __attribute__ ((unused)) #define _BA0_(c, x) _BA1_(c, x) #define BUILD_ASSERT(cond) _BA0_(cond, __LINE__) #endif diff --git a/futility/kernel_blob.h b/futility/kernel_blob.h index 6ecc02d7..ab1c82fd 100644 --- a/futility/kernel_blob.h +++ b/futility/kernel_blob.h @@ -56,7 +56,8 @@ struct linux_kernel_params { uint8_t relocatable_kernel; /* 234 */ uint8_t min_alignment; /* 235 */ uint8_t pad6[0x2d0 - 0x236]; - struct linux_kernel_e820entry e820_entries[E820_ENTRY_MAX]; /* 2d0-cd0 */ + struct linux_kernel_e820entry + e820_entries[E820_ENTRY_MAX]; /* 2d0-cd0 */ } __attribute__ ((packed)); #endif /* VBOOT_REFERENCE_KERNEL_BLOB_H_ */ diff --git a/futility/misc.c b/futility/misc.c index 22e45165..41458ed7 100644 --- a/futility/misc.c +++ b/futility/misc.c @@ -140,8 +140,7 @@ void copy_file_or_die(const char *infile, const char *outfile) exit(1); } - if (WIFSIGNALED(status)) - { + if (WIFSIGNALED(status)) { status = WTERMSIG(status); fprintf(stderr, "/bin/cp was killed with signal %d\n", status); exit(1); diff --git a/futility/traversal.h b/futility/traversal.h index 48bc3b6a..307f8197 100644 --- a/futility/traversal.h +++ b/futility/traversal.h @@ -59,7 +59,7 @@ struct cb_area_s { /* What do we know at this point in time? */ struct futil_traverse_state_s { - /* These two should be initialized by the caller */ + /* These two should be initialized by the caller as needed */ const char *in_filename; enum futil_op_type op; /* Current activity during traversal */ -- cgit v1.2.1