summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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