summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2014-10-14 20:58:41 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-10-15 20:49:19 +0000
commit3638625d351ec0a0ba32d7cf8172dda179235db9 (patch)
treee433ed363ec7c88efe33564e4964c1af9cf39ce2
parent4184e626336fa8d794a21208387226f154d77d0f (diff)
downloadvboot-3638625d351ec0a0ba32d7cf8172dda179235db9.tar.gz
futility: Be more accepting of how it's invoked
Now that futility is pretty much working as intended, we don't have to be quite so picky in the way it's being invoked. Up until now, it's only worked when invoked as "futility" or as one of the built-in commands, such as "dump_fmap". This change removes those restrictions. You can invoke futility under any name you wish. If it recognizes the name as a built-in command, great. Otherwise it will require a valid command as the first arg, just like it always has. BUG=none BRANCH=ToT, Samus TEST=make runtests In addtion to the new test included with this CL, I manually ran lddtree --copy-to-tree=blah --generate-wrappers /usr/bin/futility ./blah/usr/bin/futility dump_fmap -h tests/futility/data/bios_peppy_mp.bin Before this CL, the wrapper didn't work because the binary was being invoked as futility.elf, which was rejected. After this CL, the wrapper works fine. Change-Id: Iafdaff6e07ed294a7d29e4cff599ace0a3089229 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/223386 Reviewed-by: Hung-Te Lin <hungte@chromium.org>
-rw-r--r--futility/futility.c130
-rwxr-xr-xtests/futility/test_main.sh48
2 files changed, 92 insertions, 86 deletions
diff --git a/futility/futility.c b/futility/futility.c
index bc98a75f..19ee65b7 100644
--- a/futility/futility.c
+++ b/futility/futility.c
@@ -256,108 +256,80 @@ static const char *const dep_usage = "\n"
"\n" MYNAME " %s [...]\n"
"\n";
-static void deprecated(const char *depname)
+static int deprecated(const char *depname)
{
fprintf(stderr, dep_usage, depname, depname);
- exit(1);
+ return 1;
}
-/******************************************************************************/
-/* Here we go */
+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);
+ }
-#define MYNAME_S MYNAME "_s"
+ return cmd->handler(argc, argv);
+}
+static char *simple_basename(char *str)
+{
+ char *s = strrchr(str, '/');
+ if (s)
+ s++;
+ else
+ s = str;
+ return s;
+}
+
+/* Here we go */
int main(int argc, char *argv[], char *envp[])
{
- char *fullname, *progname;
- char truename[PATH_MAX];
- char buf[80];
- pid_t myproc;
- ssize_t r;
+ char *progname;
const struct futil_cmd_t *cmd;
int i;
- int via_symlink = 0;
log_args(argc, argv);
/* How were we invoked? */
- fullname = strdup(argv[0]);
- progname = strrchr(argv[0], '/');
- if (progname)
- progname++;
- else
- progname = argv[0];
+ progname = simple_basename(argv[0]);
- /* 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);
- }
-
- /* We can just pass the rest along, then */
- argc--;
- argv++;
-
- /* So now what function do we want to invoke? */
- progname = strrchr(argv[0], '/');
- if (progname)
- 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. */
+ /* See if the program name is a command we recognize */
+ cmd = find_command(progname);
+ if (cmd) {
+ /* Block any deprecated functions invoked directly. */
for (i = 0; i < ARRAY_SIZE(dep_cmds); i++)
if (0 == strcmp(dep_cmds[i], progname))
- deprecated(progname);
- }
+ return deprecated(progname);
- /* See if it's asking for something we know how to do ourselves */
- 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);
- }
+ return run_command(cmd, argc, argv);
}
- /* Never heard of it */
- if (!via_symlink) {
+ /* The program name means nothing, so we require an argument. */
+ if (argc < 2) {
do_help(0, 0);
- exit(1);
+ return 1;
}
- /* Complain about bogus symlink */
- myproc = getpid();
- snprintf(buf, sizeof(buf), "/proc/%d/exe", myproc);
- r = readlink(buf, truename, PATH_MAX - 1);
- if (r < 0) {
- fprintf(stderr, "%s is lost: %s => %s: %s\n", MYNAME, argv[0],
- buf, strerror(errno));
- exit(1);
- }
- truename[r] = '\0';
+ /* The first arg should be a command we recognize */
+ argc--;
+ argv++;
- 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);
+ /* For reasons I've forgotten, treat /blah/blah/CMD the same as CMD */
+ progname = simple_basename(argv[0]);
+ /* Oh, and treat "--foo" the same as "foo" */
+ while (*progname == '-')
+ progname++;
+
+ /* Do we recognize the command? */
+ cmd = find_command(progname);
+ if (cmd)
+ return run_command(cmd, argc, argv);
+
+ /* Nope. We've no clue what we're being asked to do. */
+ do_help(0, 0);
return 1;
}
diff --git a/tests/futility/test_main.sh b/tests/futility/test_main.sh
index 17a54675..83fc53db 100755
--- a/tests/futility/test_main.sh
+++ b/tests/futility/test_main.sh
@@ -10,18 +10,18 @@ TMP="$me.tmp"
cd "$OUTDIR"
# No args returns nonzero exit code
-"$FUTILITY" && false
+${FUTILITY} && false
# It's weird but okay if the command is a full path.
-"$FUTILITY" /fake/path/to/help > "$TMP"
+${FUTILITY} /fake/path/to/help > "$TMP"
grep Usage "$TMP"
# Make sure logging does something.
LOG="/tmp/futility.log"
[ -f ${LOG} ] && mv ${LOG} ${LOG}.backup
touch ${LOG}
-"$FUTILITY" help
-grep "$FUTILITY" ${LOG}
+${FUTILITY} help
+grep ${FUTILITY} ${LOG}
rm -f ${LOG}
[ -f ${LOG}.backup ] && mv ${LOG}.backup ${LOG}
@@ -29,16 +29,50 @@ rm -f ${LOG}
DEPRECATED="dev_sign_file"
for i in $DEPRECATED; do
- ln -sf "$FUTILITY" $i
+ ln -sf ${FUTILITY} $i
if ./$i 2>${TMP}.outmsg ; then false; fi
grep deprecated ${TMP}.outmsg
# They may still fail when invoked through futility
# but with a different error message.
- "$FUTILITY" $i 1>${TMP}.outmsg2 2>&1 || true
+ ${FUTILITY} $i 1>${TMP}.outmsg2 2>&1 || true
if grep deprecated ${TMP}.outmsg2; then false; fi
rm -f $i
done
+# Use some known digests to verify that things work...
+DEVKEYS=${SRCDIR}/tests/devkeys
+SHA=e78ce746a037837155388a1096212ded04fb86eb
+
+# all progs in the pipelines should work
+set -o pipefail
+
+# If it's invoked as the name of a command we know, it should do that command
+ln -sf ${FUTILITY} vbutil_key
+./vbutil_key --unpack ${DEVKEYS}/installer_kernel_data_key.vbpubk | grep ${SHA}
+ln -sf ${FUTILITY} vbutil_keyblock
+./vbutil_keyblock --unpack ${DEVKEYS}/installer_kernel.keyblock | grep ${SHA}
+cp ${FUTILITY} show
+./show ${SCRIPTDIR}/data/rec_kernel_part.bin | grep ${SHA}
+
+# If it's invoked by any other name, expect the command to be the first arg.
+ln -sf ${FUTILITY} muggle
+./muggle vbutil_key --unpack ${DEVKEYS}/installer_kernel_data_key.vbpubk \
+ | grep ${SHA}
+ln -sf ${FUTILITY} buggle
+./buggle vbutil_keyblock --unpack ${DEVKEYS}/installer_kernel.keyblock \
+ | grep ${SHA}
+cp ${FUTILITY} boo
+./boo show ${SCRIPTDIR}/data/rec_kernel_part.bin | grep ${SHA}
+
+
+# we expect the first command fail, but the output to match anyway
+set +o pipefail
+
+# If it can't figure out the command at all, it should complain.
+${FUTILITY} muggle | grep Usage:
+./buggle futility | grep Usage:
+./boo | grep Usage:
+
# cleanup
-rm -f ${TMP}*
+rm -f ${TMP}* vbutil_key vbutil_keyblock show muggle buggle boo
exit 0