diff options
Diffstat (limited to 'futility/futility.c')
-rw-r--r-- | futility/futility.c | 212 |
1 files changed, 124 insertions, 88 deletions
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; @@ -242,8 +174,99 @@ static void log_args(int argc, char *argv[]) } /******************************************************************************/ + +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; } |