futility: Let each command provide its own help
Instead of a separate help function for each command, let's just require each command to handle a --help option. This will make it easier to layer the commands (for example, "sign" could have several subcommand variants, each with its own help). BUG=none BRANCH=none TEST=make runtests I also compared the result of running "futility help CMD" before and after this change. The help still shows up correctly. Change-Id: I5c58176f32b41b0a2c2b8f0afb17dddd80fddc70 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/260495 Reviewed-by: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
parent
49a422fab9
commit
01466d36af
2
Makefile
2
Makefile
|
@ -1422,7 +1422,7 @@ TEST_DEPS += ${TEST_OBJS:%.o=%.o.d}
|
|||
SRCDIRPAT=$(subst /,\/,${SRCDIR}/)
|
||||
|
||||
# Note: vboot 2.0 is deprecated, so don't index those files
|
||||
${BUILD}/cscope.files: test_setup
|
||||
${BUILD}/cscope.files: all test_setup
|
||||
${Q}rm -f $@
|
||||
${Q}cat ${ALL_DEPS} | tr -d ':\\' | tr ' ' '\012' | \
|
||||
grep -v /lib20/ | \
|
||||
|
|
|
@ -31,6 +31,7 @@ enum {
|
|||
OPT_DESC,
|
||||
OPT_ID,
|
||||
OPT_HASH_ALG,
|
||||
OPT_HELP,
|
||||
};
|
||||
|
||||
#define DEFAULT_VERSION 1
|
||||
|
@ -48,6 +49,7 @@ static const struct option long_opts[] = {
|
|||
{"desc", 1, 0, OPT_DESC},
|
||||
{"id", 1, 0, OPT_ID},
|
||||
{"hash_alg", 1, 0, OPT_HASH_ALG},
|
||||
{"help", 0, 0, OPT_HELP},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -331,6 +333,9 @@ static int do_create(int argc, char *argv[])
|
|||
errorcnt++;
|
||||
}
|
||||
break;
|
||||
case OPT_HELP:
|
||||
print_help(argc, argv);
|
||||
return !!errorcnt;
|
||||
|
||||
case '?':
|
||||
if (optopt)
|
||||
|
@ -406,7 +411,5 @@ static int do_create(int argc, char *argv[])
|
|||
return r;
|
||||
}
|
||||
|
||||
DECLARE_FUTIL_COMMAND(create, do_create,
|
||||
VBOOT_VERSION_ALL,
|
||||
"Create a keypair from an RSA .pem file",
|
||||
print_help);
|
||||
DECLARE_FUTIL_COMMAND(create, do_create, VBOOT_VERSION_ALL,
|
||||
"Create a keypair from an RSA .pem file");
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
@ -411,6 +412,13 @@ static void print_help(int argc, char *argv[])
|
|||
printf(usage, argv[0]);
|
||||
}
|
||||
|
||||
enum {
|
||||
OPT_HELP = 1000,
|
||||
};
|
||||
static const struct option long_opts[] = {
|
||||
{"help", 0, 0, OPT_HELP},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
static int do_dump_fmap(int argc, char *argv[])
|
||||
{
|
||||
int c;
|
||||
|
@ -421,7 +429,7 @@ static int do_dump_fmap(int argc, char *argv[])
|
|||
int retval = 1;
|
||||
|
||||
opterr = 0; /* quiet, you */
|
||||
while ((c = getopt(argc, argv, ":xpFhH")) != -1) {
|
||||
while ((c = getopt_long(argc, argv, ":xpFhH", long_opts, 0)) != -1) {
|
||||
switch (c) {
|
||||
case 'x':
|
||||
opt_extract = 1;
|
||||
|
@ -439,6 +447,9 @@ static int do_dump_fmap(int argc, char *argv[])
|
|||
opt_format = FMT_HUMAN;
|
||||
opt_overlap++;
|
||||
break;
|
||||
case OPT_HELP:
|
||||
print_help(argc, argv);
|
||||
return 0;
|
||||
case '?':
|
||||
fprintf(stderr, "%s: unrecognized switch: -%c\n",
|
||||
argv[0], optopt);
|
||||
|
@ -510,7 +521,5 @@ static int do_dump_fmap(int argc, char *argv[])
|
|||
return retval;
|
||||
}
|
||||
|
||||
DECLARE_FUTIL_COMMAND(dump_fmap, do_dump_fmap,
|
||||
VBOOT_VERSION_ALL,
|
||||
"Display FMAP contents from a firmware image",
|
||||
print_help);
|
||||
DECLARE_FUTIL_COMMAND(dump_fmap, do_dump_fmap, VBOOT_VERSION_ALL,
|
||||
"Display FMAP contents from a firmware image");
|
||||
|
|
|
@ -15,10 +15,12 @@
|
|||
|
||||
enum {
|
||||
OPT_KLOADADDR = 1000,
|
||||
OPT_HELP,
|
||||
};
|
||||
|
||||
static const struct option long_opts[] = {
|
||||
{"kloadaddr", 1, NULL, OPT_KLOADADDR},
|
||||
{"help", 0, 0, OPT_HELP},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
|
@ -29,7 +31,7 @@ static void print_help(int argc, char *argv[])
|
|||
"KERNEL_PARTITION\n\n", argv[0]);
|
||||
}
|
||||
|
||||
static int do_dump_kernel_config(int argc, char *argv[])
|
||||
static int do_dump_kern_cfg(int argc, char *argv[])
|
||||
{
|
||||
char *infile = NULL;
|
||||
char *config = NULL;
|
||||
|
@ -58,6 +60,10 @@ static int do_dump_kernel_config(int argc, char *argv[])
|
|||
parse_error = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case OPT_HELP:
|
||||
print_help(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,7 +93,6 @@ static int do_dump_kernel_config(int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
DECLARE_FUTIL_COMMAND(dump_kernel_config, do_dump_kernel_config,
|
||||
VBOOT_VERSION_ALL,
|
||||
"Prints the kernel command line",
|
||||
print_help);
|
||||
DECLARE_FUTIL_COMMAND(dump_kernel_config, do_dump_kern_cfg, VBOOT_VERSION_ALL,
|
||||
"Prints the kernel command line");
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ enum {
|
|||
OPT_HWID = 1000,
|
||||
OPT_FLAGS,
|
||||
OPT_DIGEST,
|
||||
OPT_HELP,
|
||||
};
|
||||
|
||||
/* Command line options */
|
||||
|
@ -75,6 +76,7 @@ static struct option long_opts[] = {
|
|||
{"hwid", 0, NULL, OPT_HWID},
|
||||
{"flags", 0, NULL, OPT_FLAGS},
|
||||
{"digest", 0, NULL, OPT_DIGEST},
|
||||
{"help", 0, NULL, OPT_HELP},
|
||||
{NULL, 0, NULL, 0},
|
||||
};
|
||||
|
||||
|
@ -410,6 +412,10 @@ static int do_gbb_utility(int argc, char *argv[])
|
|||
case OPT_DIGEST:
|
||||
sel_digest = 1;
|
||||
break;
|
||||
case OPT_HELP:
|
||||
print_help(argc, argv);
|
||||
return !!errorcnt;
|
||||
|
||||
case '?':
|
||||
errorcnt++;
|
||||
if (optopt)
|
||||
|
@ -637,7 +643,5 @@ static int do_gbb_utility(int argc, char *argv[])
|
|||
return !!errorcnt;
|
||||
}
|
||||
|
||||
DECLARE_FUTIL_COMMAND(gbb_utility, do_gbb_utility,
|
||||
VBOOT_VERSION_ALL,
|
||||
"Manipulate the Google Binary Block (GBB)",
|
||||
print_help);
|
||||
DECLARE_FUTIL_COMMAND(gbb_utility, do_gbb_utility, VBOOT_VERSION_ALL,
|
||||
"Manipulate the Google Binary Block (GBB)");
|
||||
|
|
|
@ -44,8 +44,12 @@ static void print_help(int argc, char *argv[])
|
|||
printf(usage, argv[0], argv[0]);
|
||||
}
|
||||
|
||||
enum {
|
||||
OPT_HELP = 1000,
|
||||
};
|
||||
static const struct option long_opts[] = {
|
||||
/* name hasarg *flag val */
|
||||
{"help", 0, NULL, OPT_HELP},
|
||||
{NULL, 0, NULL, 0},
|
||||
};
|
||||
static char *short_opts = ":o:";
|
||||
|
@ -105,6 +109,9 @@ static int do_load_fmap(int argc, char *argv[])
|
|||
case 'o':
|
||||
outfile = optarg;
|
||||
break;
|
||||
case OPT_HELP:
|
||||
print_help(argc, argv);
|
||||
return !!errorcnt;
|
||||
case '?':
|
||||
if (optopt)
|
||||
fprintf(stderr, "Unrecognized option: -%c\n",
|
||||
|
@ -198,7 +205,6 @@ done_file:
|
|||
return !!errorcnt;
|
||||
}
|
||||
|
||||
DECLARE_FUTIL_COMMAND(load_fmap, do_load_fmap,
|
||||
VBOOT_VERSION_ALL,
|
||||
"Replace the contents of specified FMAP areas",
|
||||
print_help);
|
||||
DECLARE_FUTIL_COMMAND(load_fmap, do_load_fmap, VBOOT_VERSION_ALL,
|
||||
"Replace the contents of specified FMAP areas");
|
||||
|
||||
|
|
|
@ -96,7 +96,13 @@ static void print_digest(const uint8_t *buf, int len)
|
|||
printf("%02x", buf[i]);
|
||||
}
|
||||
|
||||
|
||||
enum {
|
||||
OPT_HELP = 1000,
|
||||
};
|
||||
static const struct option long_opts[] = {
|
||||
{"help", 0, 0, OPT_HELP},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
static int do_pcr(int argc, char *argv[])
|
||||
{
|
||||
uint8_t accum[SHA256_DIGEST_SIZE * 2];
|
||||
|
@ -109,7 +115,7 @@ static int do_pcr(int argc, char *argv[])
|
|||
int i;
|
||||
|
||||
opterr = 0; /* quiet, you */
|
||||
while ((i = getopt(argc, argv, ":i2")) != -1) {
|
||||
while ((i = getopt_long(argc, argv, ":i2", long_opts, NULL)) != -1) {
|
||||
switch (i) {
|
||||
case 'i':
|
||||
opt_init = 1;
|
||||
|
@ -118,6 +124,9 @@ static int do_pcr(int argc, char *argv[])
|
|||
digest_alg = SHA256_DIGEST_ALGORITHM;
|
||||
digest_size = SHA256_DIGEST_SIZE;
|
||||
break;
|
||||
case OPT_HELP:
|
||||
print_help(argc, argv);
|
||||
return !!errorcnt;
|
||||
case '?':
|
||||
if (optopt)
|
||||
fprintf(stderr, "Unrecognized option: -%c\n",
|
||||
|
@ -181,7 +190,5 @@ static int do_pcr(int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
DECLARE_FUTIL_COMMAND(pcr, do_pcr,
|
||||
VBOOT_VERSION_ALL,
|
||||
"Simulate a TPM PCR extension operation",
|
||||
print_help);
|
||||
DECLARE_FUTIL_COMMAND(pcr, do_pcr, VBOOT_VERSION_ALL,
|
||||
"Simulate a TPM PCR extension operation");
|
||||
|
|
|
@ -557,6 +557,7 @@ int futil_cb_show_begin(struct futil_traverse_state_s *state)
|
|||
|
||||
enum no_short_opts {
|
||||
OPT_PADDING = 1000,
|
||||
OPT_HELP,
|
||||
};
|
||||
|
||||
static const char usage[] = "\n"
|
||||
|
@ -597,6 +598,7 @@ static const struct option long_opts[] = {
|
|||
{"fv", 1, 0, 'f'},
|
||||
{"pad", 1, NULL, OPT_PADDING},
|
||||
{"verify", 0, &option.strict, 1},
|
||||
{"help", 0, NULL, OPT_HELP},
|
||||
{NULL, 0, NULL, 0},
|
||||
};
|
||||
static char *short_opts = ":f:k:t";
|
||||
|
@ -667,6 +669,9 @@ static int do_show(int argc, char *argv[])
|
|||
errorcnt++;
|
||||
}
|
||||
break;
|
||||
case OPT_HELP:
|
||||
print_help(argc, argv);
|
||||
return !!errorcnt;
|
||||
|
||||
case '?':
|
||||
if (optopt)
|
||||
|
@ -746,10 +751,8 @@ done:
|
|||
return !!errorcnt;
|
||||
}
|
||||
|
||||
DECLARE_FUTIL_COMMAND(show, do_show,
|
||||
VBOOT_VERSION_ALL,
|
||||
"Display the content of various binary components",
|
||||
print_help);
|
||||
DECLARE_FUTIL_COMMAND(show, do_show, VBOOT_VERSION_ALL,
|
||||
"Display the content of various binary components");
|
||||
|
||||
static int do_verify(int argc, char *argv[])
|
||||
{
|
||||
|
@ -759,5 +762,4 @@ static int do_verify(int argc, char *argv[])
|
|||
|
||||
DECLARE_FUTIL_COMMAND(verify, do_verify,
|
||||
VBOOT_VERSION_ALL,
|
||||
"Verify the signatures of various binary components",
|
||||
print_help);
|
||||
"Verify the signatures of various binary components");
|
||||
|
|
|
@ -666,6 +666,7 @@ enum no_short_opts {
|
|||
OPT_PEM_SIGNPRIV,
|
||||
OPT_PEM_ALGO,
|
||||
OPT_PEM_EXTERNAL,
|
||||
OPT_HELP,
|
||||
};
|
||||
|
||||
static const struct option long_opts[] = {
|
||||
|
@ -693,6 +694,7 @@ static const struct option long_opts[] = {
|
|||
{"pem_algo", 1, NULL, OPT_PEM_ALGO},
|
||||
{"pem_external", 1, NULL, OPT_PEM_EXTERNAL},
|
||||
{"vblockonly", 0, &option.vblockonly, 1},
|
||||
{"help", 0, NULL, OPT_HELP},
|
||||
{NULL, 0, NULL, 0},
|
||||
};
|
||||
static char *short_opts = ":s:b:k:S:B:v:f:d:l:";
|
||||
|
@ -856,6 +858,9 @@ static int do_sign(int argc, char *argv[])
|
|||
case OPT_PEM_EXTERNAL:
|
||||
option.pem_external = optarg;
|
||||
break;
|
||||
case OPT_HELP:
|
||||
print_help(argc, argv);
|
||||
return !!errorcnt;
|
||||
|
||||
case '?':
|
||||
if (optopt)
|
||||
|
@ -1077,7 +1082,6 @@ done:
|
|||
return !!errorcnt;
|
||||
}
|
||||
|
||||
DECLARE_FUTIL_COMMAND(sign, do_sign,
|
||||
VBOOT_VERSION_ALL,
|
||||
"Sign / resign various binary components",
|
||||
print_help);
|
||||
DECLARE_FUTIL_COMMAND(sign, do_sign, VBOOT_VERSION_ALL,
|
||||
"Sign / resign various binary components");
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ enum {
|
|||
OPT_FV,
|
||||
OPT_KERNELKEY,
|
||||
OPT_FLAGS,
|
||||
OPT_HELP,
|
||||
};
|
||||
|
||||
static const struct option long_opts[] = {
|
||||
|
@ -42,6 +43,7 @@ static const struct option long_opts[] = {
|
|||
{"fv", 1, 0, OPT_FV},
|
||||
{"kernelkey", 1, 0, OPT_KERNELKEY},
|
||||
{"flags", 1, 0, OPT_FLAGS},
|
||||
{"help", 0, 0, OPT_HELP},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -322,6 +324,9 @@ static int do_vbutil_firmware(int argc, char *argv[])
|
|||
printf("Unknown option\n");
|
||||
parse_error = 1;
|
||||
break;
|
||||
case OPT_HELP:
|
||||
print_help(argc, argv);
|
||||
return !!parse_error;
|
||||
|
||||
case OPT_MODE_VBLOCK:
|
||||
case OPT_MODE_VERIFY:
|
||||
|
@ -385,7 +390,5 @@ static int do_vbutil_firmware(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
DECLARE_FUTIL_COMMAND(vbutil_firmware, do_vbutil_firmware,
|
||||
VBOOT_VERSION_1_0,
|
||||
"Verified boot firmware utility",
|
||||
print_help);
|
||||
DECLARE_FUTIL_COMMAND(vbutil_firmware, do_vbutil_firmware, VBOOT_VERSION_1_0,
|
||||
"Verified boot firmware utility");
|
||||
|
|
|
@ -64,6 +64,7 @@ enum {
|
|||
OPT_MINVERSION,
|
||||
OPT_VMLINUZ_OUT,
|
||||
OPT_FLAGS,
|
||||
OPT_HELP,
|
||||
};
|
||||
|
||||
static const struct option long_opts[] = {
|
||||
|
@ -87,6 +88,7 @@ static const struct option long_opts[] = {
|
|||
{"verbose", 0, &opt_verbose, 1},
|
||||
{"vmlinuz-out", 1, 0, OPT_VMLINUZ_OUT},
|
||||
{"flags", 1, 0, OPT_FLAGS},
|
||||
{"help", 0, 0, OPT_HELP},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -270,6 +272,9 @@ static int do_vbutil_kernel(int argc, char *argv[])
|
|||
case 0:
|
||||
/* silently handled option */
|
||||
break;
|
||||
case OPT_HELP:
|
||||
print_help(argc, argv);
|
||||
return !!parse_error;
|
||||
|
||||
case OPT_MODE_PACK:
|
||||
case OPT_MODE_REPACK:
|
||||
|
@ -646,7 +651,5 @@ static int do_vbutil_kernel(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
DECLARE_FUTIL_COMMAND(vbutil_kernel, do_vbutil_kernel,
|
||||
VBOOT_VERSION_1_0,
|
||||
"Creates, signs, and verifies the kernel partition",
|
||||
print_help);
|
||||
DECLARE_FUTIL_COMMAND(vbutil_kernel, do_vbutil_kernel, VBOOT_VERSION_1_0,
|
||||
"Creates, signs, and verifies the kernel partition");
|
||||
|
|
|
@ -26,6 +26,7 @@ enum {
|
|||
OPT_MODE_PACK,
|
||||
OPT_MODE_UNPACK,
|
||||
OPT_COPYTO,
|
||||
OPT_HELP,
|
||||
};
|
||||
|
||||
static const struct option long_opts[] = {
|
||||
|
@ -35,6 +36,7 @@ static const struct option long_opts[] = {
|
|||
{"pack", 1, 0, OPT_MODE_PACK},
|
||||
{"unpack", 1, 0, OPT_MODE_UNPACK},
|
||||
{"copyto", 1, 0, OPT_COPYTO},
|
||||
{"help", 0, 0, OPT_HELP},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -180,6 +182,9 @@ static int do_vbutil_key(int argc, char *argv[])
|
|||
VbExError("Unknown option\n");
|
||||
parse_error = 1;
|
||||
break;
|
||||
case OPT_HELP:
|
||||
print_help(argc, argv);
|
||||
return !!parse_error;
|
||||
|
||||
case OPT_INKEY:
|
||||
infile = optarg;
|
||||
|
@ -234,7 +239,5 @@ static int do_vbutil_key(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
DECLARE_FUTIL_COMMAND(vbutil_key, do_vbutil_key,
|
||||
VBOOT_VERSION_1_0,
|
||||
"Wraps RSA keys with vboot headers",
|
||||
print_help);
|
||||
DECLARE_FUTIL_COMMAND(vbutil_key, do_vbutil_key, VBOOT_VERSION_1_0,
|
||||
"Wraps RSA keys with vboot headers");
|
||||
|
|
|
@ -28,6 +28,7 @@ enum {
|
|||
OPT_PEM_ALGORITHM,
|
||||
OPT_EXTERNAL_SIGNER,
|
||||
OPT_FLAGS,
|
||||
OPT_HELP,
|
||||
};
|
||||
|
||||
static const struct option long_opts[] = {
|
||||
|
@ -40,6 +41,7 @@ static const struct option long_opts[] = {
|
|||
{"pem_algorithm", 1, 0, OPT_PEM_ALGORITHM},
|
||||
{"externalsigner", 1, 0, OPT_EXTERNAL_SIGNER},
|
||||
{"flags", 1, 0, OPT_FLAGS},
|
||||
{"help", 0, 0, OPT_HELP},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -244,6 +246,9 @@ static int do_vbutil_keyblock(int argc, char *argv[])
|
|||
printf("Unknown option\n");
|
||||
parse_error = 1;
|
||||
break;
|
||||
case OPT_HELP:
|
||||
print_help(argc, argv);
|
||||
return !!parse_error;
|
||||
|
||||
case OPT_MODE_PACK:
|
||||
case OPT_MODE_UNPACK:
|
||||
|
@ -331,7 +336,5 @@ static int do_vbutil_keyblock(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
DECLARE_FUTIL_COMMAND(vbutil_keyblock, do_vbutil_keyblock,
|
||||
VBOOT_VERSION_1_0,
|
||||
"Creates, signs, and verifies a keyblock",
|
||||
print_help);
|
||||
DECLARE_FUTIL_COMMAND(vbutil_keyblock, do_vbutil_keyblock, VBOOT_VERSION_1_0,
|
||||
"Creates, signs, and verifies a keyblock");
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include "futility.h"
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Logging stuff */
|
||||
|
||||
|
@ -201,7 +200,8 @@ 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))
|
||||
if (((*cmd)->version & vboot_version) &&
|
||||
!strcmp((*cmd)->name, name))
|
||||
return *cmd;
|
||||
|
||||
return NULL;
|
||||
|
@ -217,18 +217,29 @@ static void list_commands(void)
|
|||
(*cmd)->name, (*cmd)->shorthelp);
|
||||
}
|
||||
|
||||
static int run_command(const struct futil_cmd_t *cmd, int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
Debug("%s(\"%s\") ...\n", __func__, cmd->name);
|
||||
for (i = 0; i < argc; i++)
|
||||
Debug(" argv[%d] = \"%s\"\n", i, argv[i]);
|
||||
|
||||
return cmd->handler(argc, argv);
|
||||
}
|
||||
|
||||
static int do_help(int argc, char *argv[])
|
||||
{
|
||||
const struct futil_cmd_t *cmd;
|
||||
const char *vstr;
|
||||
|
||||
if (argc >= 2) {
|
||||
/* Help about a known command? */
|
||||
if (argc > 1) {
|
||||
cmd = find_command(argv[1]);
|
||||
if (cmd) {
|
||||
printf("\n%s - %s\n", argv[1], cmd->shorthelp);
|
||||
if (cmd->longhelp)
|
||||
cmd->longhelp(argc - 1, argv + 1);
|
||||
return 0;
|
||||
/* Let the command provide its own help */
|
||||
argv[0] = argv[1];
|
||||
argv[1] = "--help";
|
||||
return run_command(cmd, argc, argv);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,31 +267,21 @@ static int do_help(int argc, char *argv[])
|
|||
}
|
||||
|
||||
DECLARE_FUTIL_COMMAND(help, do_help, VBOOT_VERSION_ALL,
|
||||
"Show a bit of help (you're looking at it)",
|
||||
NULL);
|
||||
"Show a bit of help (you're looking at it)");
|
||||
|
||||
static const char ver_help[] =
|
||||
"Show the futility source revision and build date";
|
||||
static int do_version(int argc, char *argv[])
|
||||
{
|
||||
printf("%s\n", futility_version);
|
||||
if (argc > 1)
|
||||
printf("%s - %s\n", argv[0], ver_help);
|
||||
else
|
||||
printf("%s\n", futility_version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DECLARE_FUTIL_COMMAND(version, do_version, VBOOT_VERSION_ALL,
|
||||
"Show the futility source revision and build date",
|
||||
NULL);
|
||||
|
||||
static int run_command(const struct futil_cmd_t *cmd, int argc, char *argv[])
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
|
||||
return cmd->handler(argc, argv);
|
||||
}
|
||||
ver_help);
|
||||
|
||||
static char *simple_basename(char *str)
|
||||
{
|
||||
|
@ -293,16 +294,19 @@ static char *simple_basename(char *str)
|
|||
}
|
||||
|
||||
/* Here we go */
|
||||
#define OPT_HELP 1000
|
||||
int main(int argc, char *argv[], char *envp[])
|
||||
{
|
||||
char *progname;
|
||||
const struct futil_cmd_t *cmd;
|
||||
int i, errorcnt = 0;
|
||||
int vb_ver = VBOOT_VERSION_ALL;
|
||||
int helpind = 0;
|
||||
struct option long_opts[] = {
|
||||
{"debug", 0, &debugging_enabled, 1},
|
||||
{"vb1" , 0, &vb_ver, VBOOT_VERSION_1_0},
|
||||
{"vb21", 0, &vb_ver, VBOOT_VERSION_2_1},
|
||||
{"help", 0, 0, OPT_HELP},
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
|
@ -313,14 +317,20 @@ int main(int argc, char *argv[], char *envp[])
|
|||
|
||||
/* See if the program name is a command we recognize */
|
||||
cmd = find_command(progname);
|
||||
if (cmd)
|
||||
if (cmd) {
|
||||
/* Yep, just do that */
|
||||
return run_command(cmd, argc, argv);
|
||||
}
|
||||
|
||||
/* Parse the global options, stopping at the first non-option. */
|
||||
opterr = 0; /* quiet, you. */
|
||||
while ((i = getopt_long(argc, argv, "+:", long_opts, NULL)) != -1) {
|
||||
switch (i) {
|
||||
case OPT_HELP:
|
||||
/* Remember where we found this option */
|
||||
/* Note: this might be GNU-specific */
|
||||
helpind = optind - 1;
|
||||
break;
|
||||
case '?':
|
||||
if (optopt)
|
||||
fprintf(stderr, "Unrecognized option: -%c\n",
|
||||
|
@ -343,26 +353,38 @@ int main(int argc, char *argv[], char *envp[])
|
|||
}
|
||||
vboot_version = vb_ver;
|
||||
|
||||
/* Reset the getopt state so commands can parse their own options. */
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
optind = 0;
|
||||
/*
|
||||
* Translate "--help" in the args to "help" as the first parameter,
|
||||
* by rearranging argv[].
|
||||
*/
|
||||
if (helpind) {
|
||||
int i;
|
||||
optind--;
|
||||
for (i = helpind; i < optind; i++)
|
||||
argv[i] = argv[i + 1];
|
||||
argv[i] = "help";
|
||||
}
|
||||
|
||||
/* We require a command name. */
|
||||
if (errorcnt || argc < 1) {
|
||||
do_help(0, 0);
|
||||
if (errorcnt || argc == optind) {
|
||||
do_help(1, argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* For reasons I've forgotten, treat /blah/blah/CMD the same as CMD */
|
||||
progname = simple_basename(argv[0]);
|
||||
argv[optind] = simple_basename(argv[optind]);
|
||||
|
||||
/* Do we recognize the command? */
|
||||
cmd = find_command(progname);
|
||||
if (cmd)
|
||||
cmd = find_command(argv[optind]);
|
||||
if (cmd) {
|
||||
/* Reset so commands can parse their own options */
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
optind = 0;
|
||||
return run_command(cmd, argc, argv);
|
||||
}
|
||||
|
||||
/* Nope. We've no clue what we're being asked to do. */
|
||||
do_help(0, 0);
|
||||
do_help(1, argv);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -44,21 +44,25 @@ enum vboot_version vboot_version;
|
|||
|
||||
/* Here's a structure to define the commands that futility implements. */
|
||||
struct futil_cmd_t {
|
||||
/* String used to invoke this command */
|
||||
const char *const name;
|
||||
/* Function to do the work. Returns 0 on success.
|
||||
* Called with argv[0] == "name".
|
||||
* It should handle its own "--help" option. */
|
||||
int (*const handler) (int argc, char **argv);
|
||||
/* Supported ABIs */
|
||||
enum vboot_version version;
|
||||
/* One-line summary of what it does */
|
||||
const char *const shorthelp;
|
||||
void (*longhelp) (int argc, char *argv[]); /* argv[0] is the command */
|
||||
};
|
||||
|
||||
/* Macro to define a command */
|
||||
#define DECLARE_FUTIL_COMMAND(NAME, HANDLER, VERSION, SHORTHELP, LONGHELP) \
|
||||
#define DECLARE_FUTIL_COMMAND(NAME, HANDLER, VERSION, SHORTHELP) \
|
||||
const struct futil_cmd_t __cmd_##NAME = { \
|
||||
.name = #NAME, \
|
||||
.handler = HANDLER, \
|
||||
.version = VERSION, \
|
||||
.shorthelp = SHORTHELP, \
|
||||
.longhelp = LONGHELP, \
|
||||
}
|
||||
|
||||
/* This is the list of pointers to all commands. */
|
||||
|
|
Loading…
Reference in New Issue