summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWei-Cheng Xiao <garryxiao@chromium.org>2018-10-12 15:41:00 +0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2019-05-20 18:36:09 +0000
commitbf7838699a1d833a183cf02c6584236248c63ead (patch)
treea41d386b6b71771e8a57e2aac4ae0baa5e4a19d2
parent4863d59a86a9cf5b7370c81bebef17caa359f623 (diff)
downloadchrome-ec-bf7838699a1d833a183cf02c6584236248c63ead.tar.gz
gsctool: add a cmd line option -M to gsctool to allow machine-friendly outputs.
Add the option's support to remote firmware version output (-f). This allows other programs (e.g., debugd) to parse gsctool outputs without worrying about any future updates on current human-readable outputs. BRANCH=none BUG=None TEST=manually run gsctool -f -M on a soraka device connected with a nautilus. Sample output: RO_FW_VER=0.0.10 RW_FW_VER=0.3.10 Signed-off-by: Wei-Cheng Xiao <garryxiao@chromium.org> Change-Id: Ic6514a191b379d05acf2656e5e395d82086d93cd Reviewed-on: https://chromium-review.googlesource.com/1278073 Reviewed-by: Andrey Pronin <apronin@chromium.org> Reviewed-by: Mike Frysinger <vapier@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1539436 Reviewed-by: Cheng-Han Yang <chenghan@chromium.org> Commit-Queue: Cheng-Han Yang <chenghan@chromium.org> Tested-by: Cheng-Han Yang <chenghan@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1616887
-rw-r--r--extra/usb_updater/gsctool.c82
1 files changed, 74 insertions, 8 deletions
diff --git a/extra/usb_updater/gsctool.c b/extra/usb_updater/gsctool.c
index 77958fe920..2ea8d1fc1d 100644
--- a/extra/usb_updater/gsctool.c
+++ b/extra/usb_updater/gsctool.c
@@ -12,6 +12,8 @@
#include <getopt.h>
#include <libusb.h>
#include <openssl/sha.h>
+#include <stdarg.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -196,7 +198,7 @@ struct upgrade_pkt {
static int verbose_mode;
static uint32_t protocol_version;
static char *progname;
-static char *short_opts = "abcd:F:fhIikO:oPprstUuVv";
+static char *short_opts = "abcd:F:fhIikMO:oPprstUuVv";
static const struct option long_opts[] = {
/* name hasarg *flag val */
{"any", 0, NULL, 'a'},
@@ -211,6 +213,7 @@ static const struct option long_opts[] = {
{"factory", 1, NULL, 'F'},
{"fwver", 0, NULL, 'f'},
{"help", 0, NULL, 'h'},
+ {"machine", 0, NULL, 'M'},
{"openbox_rma", 1, NULL, 'O'},
{"password", 0, NULL, 'P'},
{"post_reset", 0, NULL, 'p'},
@@ -523,6 +526,8 @@ static void usage(int errs)
" ID could be 32 bit hex or 4 "
"character string.\n"
" -k,--ccd_lock Lock CCD\n"
+ " -M,--machine Output in a machine-friendly way. "
+ "Effective only with -f.\n"
" -O,--openbox_rma <desc_file>\n"
" Verify other device's RO integrity\n"
" using information provided in "
@@ -1947,6 +1952,53 @@ static void report_version(void)
exit(0);
}
+/*
+ * Machine output is formatted as "key=value", one key-value pair per line, and
+ * parsed by other programs (e.g., debugd). The value part should be specified
+ * in the printf-like way. For example:
+ *
+ * print_machine_output("date", "%d/%d/%d", 2018, 1, 1),
+ *
+ * which outputs this line in console:
+ *
+ * date=2018/1/1
+ *
+ * The key part should not contain '=' or newline. The value part may contain
+ * special characters like spaces, quotes, brackets, but not newlines. The
+ * newline character means end of value.
+ *
+ * Any output format change in this function may require similar changes on the
+ * programs that are using this gsctool.
+ */
+__attribute__((__format__(__printf__, 2, 3)))
+static void print_machine_output(const char *key, const char *format, ...)
+{
+ va_list args;
+
+ if (strchr(key, '=') != NULL || strchr(key, '\n') != NULL) {
+ fprintf(stderr,
+ "Error: key %s contains '=' or a newline character.\n",
+ key);
+ return;
+ }
+
+ if (strchr(format, '\n') != NULL) {
+ fprintf(stderr,
+ "Error: value format %s contains a newline character. "
+ "\n",
+ format);
+ return;
+ }
+
+ va_start(args, format);
+
+ printf("%s=", key);
+ vprintf(format, args);
+ printf("\n");
+
+ va_end(args);
+}
+
int main(int argc, char *argv[])
{
struct transfer_descriptor td;
@@ -1970,6 +2022,8 @@ int main(int argc, char *argv[])
int ccd_lock = 0;
int ccd_info = 0;
int try_all_transfer = 0;
+ bool show_machine_output = false;
+
const char *exclusive_opt_error =
"Options -a, -s and -t are mutually exclusive\n";
const char *openbox_desc_file = NULL;
@@ -2039,6 +2093,9 @@ int main(int argc, char *argv[])
case 'k':
ccd_lock = 1;
break;
+ case 'M':
+ show_machine_output = true;
+ break;
case 'O':
openbox_desc_file = optarg;
break;
@@ -2218,13 +2275,22 @@ int main(int argc, char *argv[])
generate_reset_request(&td);
if (show_fw_ver) {
- printf("Current versions:\n");
- printf("RO %d.%d.%d\n", targ.shv[0].epoch,
- targ.shv[0].major,
- targ.shv[0].minor);
- printf("RW %d.%d.%d\n", targ.shv[1].epoch,
- targ.shv[1].major,
- targ.shv[1].minor);
+ if (show_machine_output) {
+ print_machine_output("RO_FW_VER", "%d.%d.%d",
+ targ.shv[0].epoch,
+ targ.shv[0].major,
+ targ.shv[0].minor);
+ print_machine_output("RW_FW_VER", "%d.%d.%d",
+ targ.shv[1].epoch,
+ targ.shv[1].major,
+ targ.shv[1].minor);
+ } else {
+ printf("Current versions:\n");
+ printf("RO %d.%d.%d\n", targ.shv[0].epoch,
+ targ.shv[0].major, targ.shv[0].minor);
+ printf("RW %d.%d.%d\n", targ.shv[1].epoch,
+ targ.shv[1].major, targ.shv[1].minor);
+ }
}
}