From feb2518166b1cd181e607c611cbb610f0c7300da Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Thu, 7 Mar 2013 12:54:29 -0800 Subject: Wrap all vboot utilities with futility. This moves all the old userspace utilities generated by vboot_reference into a subdirectory not in $PATH, and replaces them with symlinks to a single executable named 'futility'. At the moment that utility just execs the original utilities (optionally logging that fact first). Ultimately, the old utilities will be subsumed into a single binary instead of multiple separate executables. There is a matching CL needed to make the recovery image creation work. BUG=chromium-os:37062 BRANCH=none CQ-DEPEND=CL:44864 TEST=auto To test, build everything, test everything. It should work as before in all cases. I have built normal images, test images, factory installers, recovery images; they all seem to work. I've run trybots on daisy-paladin link-paladin lumpy-paladin and alex-paladin. Change-Id: Ie93db676f2ed2a64e4b13b3b5dc6b65a77db0f8c Signed-off-by: Bill Richardson Reviewed-on: https://gerrit.chromium.org/gerrit/44871 Reviewed-by: Randall Spangler Reviewed-by: Hung-Te Lin --- Makefile | 66 +++++--- futility/IGNOREME.c | 12 -- futility/cmd_foo.c | 22 +++ futility/futility.c | 285 +++++++++++++++++++++++++++++++++++ futility/futility.h | 57 +++++++ futility/futility.lds | 9 +- futility/tests/common.sh | 47 ++++++ futility/tests/run_futility_tests.sh | 78 ++++++++++ utility/dumpRSAPublicKey.c | 8 +- utility/gbb_utility.cc | 7 +- utility/tpmc.c | 11 +- 11 files changed, 565 insertions(+), 37 deletions(-) delete mode 100644 futility/IGNOREME.c create mode 100644 futility/cmd_foo.c create mode 100644 futility/futility.c create mode 100644 futility/futility.h create mode 100755 futility/tests/common.sh create mode 100755 futility/tests/run_futility_tests.sh diff --git a/Makefile b/Makefile index a7101cc4..cd391143 100644 --- a/Makefile +++ b/Makefile @@ -37,22 +37,29 @@ # We should only run pwd once, not every time we refer to ${BUILD}. SRCDIR := $(shell pwd) -BUILD ?= $(SRCDIR)/build +BUILD = $(SRCDIR)/build export BUILD # Stuff for 'make install' -INSTALL ?= install -DESTDIR ?= /usr/local/bin - +INSTALL = install +DESTDIR = /usr/local/bin +OLDDIR = old_bins + +# Where exactly do the pieces go? +# FT_DIR = futility target directory - where it will be on the target +# F_DIR = futility install directory - where it gets put right now +# UB_DIR = userspace binary directory for futility's exec() targets +# VB_DIR = target vboot directory - for dev-mode-only helpers, keys, etc. ifeq (${MINIMAL},) # Host install just puts everything in one place -UB_DIR=${DESTDIR} -SB_DIR=${DESTDIR} -VB_DIR=${DESTDIR} +FT_DIR=${DESTDIR} +F_DIR=${DESTDIR} +UB_DIR=${DESTDIR}/${OLDDIR} else # Target install puts things into DESTDIR subdirectories -UB_DIR=${DESTDIR}/usr/bin -SB_DIR=${DESTDIR}/sbin +FT_DIR=/usr/bin +F_DIR=${DESTDIR}${FT_DIR} +UB_DIR=${F_DIR}/${OLDDIR} VB_DIR=${DESTDIR}/usr/share/vboot/bin endif @@ -127,6 +134,10 @@ CC ?= gcc CFLAGS += -DCHROMEOS_ENVIRONMENT -Wall -Werror # HEY: always want last two? endif +ifneq (${OLDDIR},) +CFLAGS += -DOLDDIR=${OLDDIR} +endif + ifneq (${DEBUG},) CFLAGS += -DVBOOT_DEBUG endif @@ -135,6 +146,10 @@ ifeq (${DISABLE_NDEBUG},) CFLAGS += -DNDEBUG endif +ifneq (${FORCE_LOGGING_ON},) +CFLAGS += -DFORCE_LOGGING_ON=${FORCE_LOGGING_ON} +endif + # Create / use dependency files CFLAGS += -MMD -MF $@.d @@ -429,8 +444,13 @@ SIGNING_COMMON = scripts/image_signing/common_minimal.sh # The unified firmware utility will eventually replace all the others FUTIL_BIN = ${BUILD}/futility/futility +# These are the others it will replace. +FUTIL_OLD = $(notdir ${CGPT} ${UTIL_BINS} ${UTIL_SCRIPTS} \ + ${SIGNING_SCRIPTS} ${SIGNING_SCRIPTS_DEV}) + FUTIL_SRCS = \ - futility/IGNOREME.c + futility/futility.c \ + futility/cmd_foo.c FUTIL_LDS = futility/futility.lds @@ -696,13 +716,15 @@ utils_install: ${UTIL_BINS} ${UTIL_SCRIPTS} # And some signing stuff for the target .PHONY: signing_install signing_install: ${SIGNING_SCRIPTS} ${SIGNING_SCRIPTS_DEV} ${SIGNING_COMMON} -ifneq (${MINIMAL},) @printf " INSTALL SIGNING\n" ${Q}mkdir -p ${UB_DIR} ${Q}${INSTALL} -t ${UB_DIR} ${SIGNING_SCRIPTS} + ${Q}${INSTALL} -t ${UB_DIR} ${SIGNING_SCRIPTS_DEV} + ${Q}${INSTALL} -t ${UB_DIR} -m 'u=rw,go=r,a-s' ${SIGNING_COMMON} +ifneq (${VB_DIR},) ${Q}mkdir -p ${VB_DIR} - ${Q}${INSTALL} -t ${VB_DIR} ${SIGNING_SCRIPTS_DEV} - ${Q}${INSTALL} -t ${VB_DIR} -m 'u=rw,go=r,a-s' ${SIGNING_COMMON} + ${Q}for prog in $(notdir ${SIGNING_SCRIPTS_DEV}); do \ + ln -sf "${FT_DIR}/futility" "${VB_DIR}/$$prog"; done endif # ---------------------------------------------------------------------------- @@ -718,9 +740,10 @@ ${FUTIL_BIN}: ${FUTIL_LDS} ${FUTIL_OBJS} .PHONY: futil_install futil_install: ${FUTIL_BIN} @printf " INSTALL futility\n" - ${Q}mkdir -p ${UB_DIR} - ${Q}${INSTALL} -t ${UB_DIR} $^ - + ${Q}mkdir -p ${F_DIR} + ${Q}${INSTALL} -t ${F_DIR} ${FUTIL_BIN} + ${Q}for prog in ${FUTIL_OLD}; do \ + ln -sf futility "${F_DIR}/$$prog"; done # ---------------------------------------------------------------------------- # Utility to generate TLCL structure definition header file. @@ -791,6 +814,10 @@ ${BUILD}/firmware/linktest/main: LIBS = ${FWLIB} # GBB utility needs C++ linker. TODO: It shouldn't. ${BUILD}/utility/gbb_utility: LD = ${CXX} +# Because we play some clever linker script games to add new commands without +# changing any header files, futility must be linked with ld.bfd, not gold. +${FUTIL_BIN}: LDFLAGS += -fuse-ld=bfd + # Some utilities need external crypto functions ${BUILD}/utility/dumpRSAPublicKey: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/utility/pad_digest_utility: LDLIBS += ${CRYPTO_LIBS} @@ -855,7 +882,7 @@ test_targets:: runcgpttests runmisctests ifeq (${MINIMAL},) # Bitmap utility isn't compiled for minimal variant -test_targets:: runbmptests +test_targets:: runbmptests runfutiltests # Scripts don't work under qemu testing # TODO: convert scripts to makefile so they can be called directly test_targets:: runtestscripts @@ -938,9 +965,9 @@ runmisctests: test_setup ${RUNTEST} ${BUILD_RUN}/tests/vboot_nvstorage_test .PHONY: runfutiltests -runfutiltests: DESTDIR := ${TEST_INSTALL_DIR} +runfutiltests: override DESTDIR = ${TEST_INSTALL_DIR} runfutiltests: test_setup install - @echo "$@ passed" + futility/tests/run_futility_tests.sh ${DESTDIR} # Run long tests, including all permutations of encryption keys (instead of # just the ones we use) and tests of currently-unused code. @@ -987,4 +1014,3 @@ coverage: else coverage: coverage_init runtests coverage_html endif - diff --git a/futility/IGNOREME.c b/futility/IGNOREME.c deleted file mode 100644 index c90c87e5..00000000 --- a/futility/IGNOREME.c +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (c) 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#include - -int main(int argc, char *argv[]) -{ - printf("Pay no attention to that man behind the curtain.\n"); - return 1; -} diff --git a/futility/cmd_foo.c b/futility/cmd_foo.c new file mode 100644 index 00000000..e02a9ffb --- /dev/null +++ b/futility/cmd_foo.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include + +#include "futility.h" + +static int do_something(int argc, char *argv[]) +{ + int i; + printf("this is %s\n", __func__); + for (i = 0; i < argc; i++) + printf("argv[%d] = %s\n", i, argv[i]); + return 0; +} + +DECLARE_FUTIL_COMMAND(foo, do_something, "invoke a foo"); +DECLARE_FUTIL_COMMAND(bar, do_something, "go to bar"); +DECLARE_FUTIL_COMMAND(hey, do_something, "shout"); diff --git a/futility/futility.c b/futility/futility.c new file mode 100644 index 00000000..c30e3e8e --- /dev/null +++ b/futility/futility.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "futility.h" + +#define MYNAME "futility" +#ifdef OLDDIR +#define XSTR(A) STR(A) +#define STR(A) #A +#define SUBDIR XSTR(OLDDIR) +#else +#define SUBDIR "old_bins" +#endif + +/* 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\ +all the distinct userspace tools formerly produced by the\n\ +vboot_reference package.\n\ +\n\ +When symlinked under the name of one of those previous tools, it can\n\ +do one of two things: either it will fully implement the original\n\ +behavior, or (until that functionality is complete) it will just exec\n\ +the original binary.\n\ +\n\ +In either case it can append some usage information to " LOGFILE "\n\ +to help improve coverage and correctness.\n\ +\n\ +If you invoke it directly instead of via a symlink, it requires one\n\ +argument, which is the name of the old binary to exec. That binary\n\ +must be located in a directory named \"" SUBDIR "\" underneath\n\ +the " MYNAME " executable.\n\ +\n"; + +static int help(int argc, char *argv[]) +{ + futil_cmd_t *cmd; + int i; + + fputs(usage, stdout); + + printf("The following commands are built-in:\n"); + + for (cmd = futil_cmds_start(); cmd < futil_cmds_end(); cmd++) + printf(" %-20s %s\n", + cmd->name, cmd->shorthelp); + + printf("\n"); + + 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, help, "Show a bit of help"); + + +/******************************************************************************/ +/* Logging stuff */ + +static int log_fd = -1; + +/* Write the string and a newline. Silently give up on errors */ +static void log_str(char *str) +{ + int len, done, n; + + if (log_fd < 0) + return; + + if (!str) + str = "(NULL)"; + + len = strlen(str); + if (len == 0) { + str = "(EMPTY)"; + len = strlen(str); + } + + for (done = 0; done < len; done += n) { + n = write(log_fd, str + done, len - done); + if (n < 0) + return; + } + + write(log_fd, "\n", 1); +} + +static void log_close(void) +{ + struct flock lock; + + if (log_fd >= 0) { + memset(&lock, 0, sizeof(lock)); + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + if (fcntl(log_fd, F_SETLKW, &lock)) + perror("Unable to unlock log file"); + + close(log_fd); + log_fd = -1; + } +} + +static void log_open(void) +{ + struct flock lock; + int ret; + +#ifdef FORCE_LOGGING_ON + log_fd = open(LOGFILE, O_WRONLY|O_APPEND|O_CREAT, 0666); +#else + log_fd = open(LOGFILE, O_WRONLY|O_APPEND); +#endif + if (log_fd < 0) { + + if (errno != EACCES) + return; + + /* Permission problems should improve shortly ... */ + sleep(1); + log_fd = open(LOGFILE, O_WRONLY|O_APPEND|O_CREAT, 0666); + if (log_fd < 0) /* Nope, they didn't */ + return; + } + + /* Let anyone have a turn */ + fchmod(log_fd, 0666); + + /* But only one at a time */ + memset(&lock, 0, sizeof(lock)); + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_END; + + ret = fcntl(log_fd, F_SETLKW, &lock); /* this blocks */ + if (ret < 0) + log_close(); +} + +#define CALLER_PREFIX "CALLER:" +static void log_args(int argc, char *argv[]) +{ + int i; + ssize_t r; + pid_t parent; + char buf[80]; + char str_caller[PATH_MAX + sizeof(CALLER_PREFIX)] = CALLER_PREFIX; + char *truename = str_caller + sizeof(CALLER_PREFIX) - 1; + /* Note: truename starts on the \0 from CALLER_PREFIX, so we can write + * PATH_MAX chars into truename and still append a \0 at the end. */ + + log_open(); + + /* delimiter */ + log_str("##### HEY #####"); + + /* Can we tell who called us? */ + parent = getppid(); + snprintf(buf, sizeof(buf), "/proc/%d/exe", parent); + r = readlink(buf, truename, PATH_MAX); + if (r >= 0) { + truename[r] = '\0'; + log_str(str_caller); + } + + /* Now log the stuff about ourselves */ + for (i = 0; i < argc; i++) + log_str(argv[i]); + + log_close(); +} + + +/******************************************************************************/ +/* Here we go */ + +int main(int argc, char *argv[], char *envp[]) +{ + char *progname; + char truename[PATH_MAX]; + char oldname[PATH_MAX]; + char buf[80]; + pid_t myproc; + ssize_t r; + char *s; + futil_cmd_t *cmd; + + log_args(argc, argv); + + /* How were we invoked? */ + progname = strrchr(argv[0], '/'); + if (progname) + progname++; + else + progname = argv[0]; + + /* Invoked directly by name */ + if (0 == strcmp(progname, MYNAME)) { + if (argc < 2) { /* must have an argument */ + fputs(usage, stderr); + exit(1); + } + + /* We can just pass the rest along, then */ + argc--; + argv++; + + /* So now what name do we want to invoke? */ + progname = strrchr(argv[0], '/'); + if (progname) + progname++; + else + progname = argv[0]; + } + + /* See if it's asking for something we know how to do ourselves */ + for (cmd = futil_cmds_start(); cmd < futil_cmds_end(); cmd++) + if (0 == strcmp(cmd->name, progname)) + return cmd->handler(argc, argv); + + /* Nope, it must be wrapped */ + + /* The old binaries live under the true executable. Find out where that is. */ + 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); + } else if (r == PATH_MAX - 1) { + /* Yes, it might _just_ fit, but we'll count that as wrong anyway. We can't + * determine the right size using the example in the readlink manpage, + * because the /proc symlink returns an st_size of 0. */ + fprintf(stderr, "%s is too long: %s => %s\n", MYNAME, argv[0], buf); + exit(1); + } + + truename[r] = '\0'; + s = strrchr(truename, '/'); /* Find the true directory */ + if (s) { + *s = '\0'; + } else { /* I don't think this can happen */ + fprintf(stderr, "%s says %s doesn't make sense\n", MYNAME, truename); + exit(1); + } + /* If the old binary path doesn't fit, just give up. */ + r = snprintf(oldname, PATH_MAX, "%s/%s/%s", truename, SUBDIR, progname); + if (r >= PATH_MAX) { + fprintf(stderr, "%s/%s/%s is too long\n", truename, SUBDIR, progname); + exit(1); + } + + fflush(0); + execve(oldname, argv, envp); + + fprintf(stderr, "%s failed to exec %s: %s\n", MYNAME, + oldname, strerror(errno)); + return 1; +} diff --git a/futility/futility.h b/futility/futility.h new file mode 100644 index 00000000..ed268905 --- /dev/null +++ b/futility/futility.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include + +#ifndef VBOOT_REFERENCE_FUTILITY_H_ +#define VBOOT_REFERENCE_FUTILITY_H_ + +/* + Here's a structure to define the commands that futility implements. + */ +typedef struct { + const char const * name; + int (*handler)(int argc, char **argv); + const char const * shorthelp; +} __attribute__ ((aligned (16))) futil_cmd_t ; /* align for x86_64 ABI */ + +/* + * Create an instance in a separate section. We'll have a linker script to + * gather them all up later, so we can refer to them without explictly + * declaring every function in a header somewhere + */ +#define DECLARE_FUTIL_COMMAND(name, handler, shorthelp) \ + static const char __futil_cmd_name_##name[] = #name; \ + const futil_cmd_t __futil_cmd_##name \ + __attribute__((section(".futil_cmds." #name))) \ + = { __futil_cmd_name_##name, handler, shorthelp } + +/* + * Functions to find the command table. We have to play some games here, + * because the x86_64 ABI says this: + * + * An array uses the same alignment as its elements, except that a local or + * global array variable that requires at least 16 bytes, or a C99 local or + * global variable-length array variable, always has alignment of at least + * 16 bytes. + * + * The linker script doesn't know what alignment to use for __futil_cmds_start, + * because that's determined at compile-time and unavailable to the script + * unless we define one global futil_cmd_t in advance. + */ +static inline futil_cmd_t *futil_cmds_start(void) +{ + extern uintptr_t __futil_cmds_start[]; /* from linker script */ + uintptr_t mask = sizeof(futil_cmd_t) - 1; + uintptr_t addr = (uintptr_t)(__futil_cmds_start); + return (futil_cmd_t *)((addr + mask) & ~mask); +} +static inline futil_cmd_t *futil_cmds_end(void) +{ + extern uintptr_t __futil_cmds_end[]; /* from linker script */ + return (futil_cmd_t *)(&__futil_cmds_end[0]); +} + +#endif /* VBOOT_REFERENCE_FUTILITY_H_ */ diff --git a/futility/futility.lds b/futility/futility.lds index e428ddca..e03ab5c4 100644 --- a/futility/futility.lds +++ b/futility/futility.lds @@ -4,4 +4,11 @@ * found in the LICENSE file. */ -/* Nothing to see here. Move along... */ +SECTIONS +{ + .rodata : { + __futil_cmds_start = .; + *(SORT(.futil_cmds.*)); + __futil_cmds_end = .; + } +} diff --git a/futility/tests/common.sh b/futility/tests/common.sh new file mode 100755 index 00000000..ed187d7b --- /dev/null +++ b/futility/tests/common.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Color output encodings. +COL_RED='\E[31;1m' +COL_GREEN='\E[32;1m' +COL_YELLOW='\E[33;1m' +COL_BLUE='\E[34;1m' +COL_STOP='\E[0;m' + +# args: [message] +green() { + echo -e "${COL_GREEN}$*${COL_STOP}" +} + +# args: [message] +yellow() { + echo -e "${COL_YELLOW}WARNING: $*${COL_STOP}" +} + +# args: [message] +red() { + echo -e "${COL_RED}$*${COL_STOP}" +} + +# args: [nested level] [message] +error() { + local lev=${1:-} + case "${1:-}" in + [0-9]*) + lev=$1 + shift + ;; + *) lev=0 + ;; + esac + local x=$(caller $lev) + local cline="${x%% *}" + local cfile="${x#* }" + cfile="${cfile##*/}" + local args="$*" + local spacer="${args:+: }" + red "at ${cfile}, line ${cline}${spacer}${args}" 1>&2 + exit 1 +} diff --git a/futility/tests/run_futility_tests.sh b/futility/tests/run_futility_tests.sh new file mode 100755 index 00000000..ff2de4be --- /dev/null +++ b/futility/tests/run_futility_tests.sh @@ -0,0 +1,78 @@ +#!/bin/bash +# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Load common constants and variables. +. "$(dirname "$0")/common.sh" + +# Where are the programs I'm testing against? +[ -z "${1:-}" ] && error "Directory argument is required" +BINDIR="$1" +shift + +FUTILITY="$BINDIR/futility" +OLDDIR="$BINDIR/old_bins" + +BUILD=$(dirname "${BINDIR}") + +# Here are the old programs to be wrapped +# FIXME(chromium-os:37062): There are others besides these. +# FIXME: dev_debug_vboot isn't tested right now. +PROGS=${*:-cgpt crossystem dev_sign_file dumpRSAPublicKey + dump_fmap dump_kernel_config enable_dev_usb_boot gbb_utility + tpm_init_temp_fix tpmc vbutil_firmware vbutil_kernel vbutil_key + vbutil_keyblock vbutil_what_keys} + +# Get ready +pass=0 +progs=0 +pwd +OUTDIR="${BUILD}/tests/futility_test_dir" +[ -d "$OUTDIR" ] || mkdir -p "$OUTDIR" + +# For now just compare results of invoking each program with no args. +# FIXME(chromium-os:37062): Create true rigorous tests for every program. +for i in $PROGS; do + : $(( progs++ )) + + # Try the real thing first + echo -n "$i ... " + rc=$("${OLDDIR}/$i" \ + 1>"${OUTDIR}/$i.stdout.orig" 2>"${OUTDIR}/$i.stderr.orig" \ + || echo "$?") + echo "${rc:-0}" > "${OUTDIR}/$i.return.orig" + + # Then try the symlink + rc=$("$BINDIR/$i" 1>"${OUTDIR}/$i.stdout.link" \ + 2>"${OUTDIR}/$i.stderr.link" || echo "$?") + echo "${rc:-0}" > "${OUTDIR}/$i.return.link" + + # And finally try the explicit wrapper + rc=$("$FUTILITY" "$i" 1>"${OUTDIR}/$i.stdout.futil" \ + 2>"${OUTDIR}/$i.stderr.futil" || echo "$?") + echo "${rc:-0}" > "${OUTDIR}/$i.return.futil" + + # Different? + if cmp -s "${OUTDIR}/$i.return.orig" "${OUTDIR}/$i.return.link" && + cmp -s "${OUTDIR}/$i.stdout.orig" "${OUTDIR}/$i.stdout.link" && + cmp -s "${OUTDIR}/$i.stderr.orig" "${OUTDIR}/$i.stderr.link" && + cmp -s "${OUTDIR}/$i.return.orig" "${OUTDIR}/$i.return.futil" && + cmp -s "${OUTDIR}/$i.stdout.orig" "${OUTDIR}/$i.stdout.futil" && + cmp -s "${OUTDIR}/$i.stderr.orig" "${OUTDIR}/$i.stderr.futil" ; then + green "passed" + : $(( pass++ )) + rm -f ${OUTDIR}/$i.{stdout,stderr,return}.{orig,link,futil} + else + red "failed" + fi +done + +# done +if [ "$pass" -eq "$progs" ]; then + green "Success: $pass / $progs passed" + exit 0 +fi + +red "FAIL: $pass / $progs passed" +exit 1 diff --git a/utility/dumpRSAPublicKey.c b/utility/dumpRSAPublicKey.c index da8597af..113e9a0b 100644 --- a/utility/dumpRSAPublicKey.c +++ b/utility/dumpRSAPublicKey.c @@ -141,9 +141,15 @@ int main(int argc, char* argv[]) { X509* cert = NULL; RSA* pubkey = NULL; EVP_PKEY* key; + char *progname; if (argc != 3 || (strcmp(argv[1], "-cert") && strcmp(argv[1], "-pub"))) { - fprintf(stderr, "Usage: %s <-cert | -pub> \n", argv[0]); + progname = strrchr(argv[0], '/'); + if (progname) + progname++; + else + progname = argv[0]; + fprintf(stderr, "Usage: %s <-cert | -pub> \n", progname); return -1; } diff --git a/utility/gbb_utility.cc b/utility/gbb_utility.cc index 52135d01..e68bd9b1 100644 --- a/utility/gbb_utility.cc +++ b/utility/gbb_utility.cc @@ -486,6 +486,11 @@ using vboot_reference::GoogleBinaryBlockUtil; // utility function: provide usage of this utility and exit. static void usagehelp_exit(const char *prog_name) { + const char *basename = strrchr(prog_name, '/'); + if (basename) + basename++; + else + basename = prog_name; fprintf(stderr, "Utility to manage Google Binary Block (GBB)\n" "Usage: %s [-g|-s|-c] [OPTIONS] bios_file [output_file]\n" @@ -516,7 +521,7 @@ static void usagehelp_exit(const char *prog_name) { " %s -g bios.bin\n" " %s --set --hwid='New Model' -k key.bin bios.bin newbios.bin\n" " %s -c 0x100,0x1000,0x03DE80,0x1000 gbb.blob\n", - prog_name, prog_name, prog_name, prog_name); + basename, basename, basename, basename); exit(1); } diff --git a/utility/tpmc.c b/utility/tpmc.c index 898e2552..9302dd1e 100644 --- a/utility/tpmc.c +++ b/utility/tpmc.c @@ -412,9 +412,16 @@ command_record command_table[] = { static int n_commands = sizeof(command_table) / sizeof(command_table[0]); int main(int argc, char* argv[]) { + char *progname; + progname = strrchr(argv[0], '/'); + if (progname) + progname++; + else + progname = argv[0]; + if (argc < 2) { fprintf(stderr, "usage: %s [args]\n or: %s help\n", - argv[0], argv[0]); + progname, progname); return OTHER_ERROR; } else { command_record* c; @@ -439,7 +446,7 @@ int main(int argc, char* argv[]) { } /* No command matched. */ - fprintf(stderr, "%s: unknown command: %s\n", argv[0], cmd); + fprintf(stderr, "%s: unknown command: %s\n", progname, cmd); return OTHER_ERROR; } } -- cgit v1.2.1