Initial version of crossystem.
Works for getting switch positions, hwid, fwid.
BUG=chrome-os-partner:1940
TEST=ran manually on Mario and Alex
Review URL: http://codereview.chromium.org/6413002
Change-Id: I874df3b5adf872fec2d36e574cb4b8b4a72d331c
diff --git a/utility/crossystem_main.c b/utility/crossystem_main.c
new file mode 100644
index 0000000..d6e0b8b
--- /dev/null
+++ b/utility/crossystem_main.c
@@ -0,0 +1,178 @@
+/* Copyright (c) 2011 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.
+ *
+ * Chrome OS firmware/system interface utility
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "crossystem.h"
+
+typedef struct Param {
+ const char* name; /* Parameter name */
+ int is_string; /* 0 if integer, 1 if string */
+ int can_write; /* 0 if read-only, 1 if writable */
+ const char* desc; /* Human-readable description */
+} Param;
+
+/* List of parameters, terminated with a param with NULL name */
+const Param sys_param_list[] = {
+ /* Read-only integers */
+ {"devsw_cur", 0, 0, "Developer switch current position"},
+ {"devsw_boot", 0, 0, "Developer switch position at boot"},
+ {"recoverysw_cur", 0, 0, "Recovery switch current position"},
+ {"recoverysw_boot", 0, 0, "Recovery switch position at boot"},
+ {"recoverysw_ec_boot", 0, 0, "Recovery switch position at EC boot"},
+ {"wpsw_cur", 0, 0, "Firmware write protect switch current position"},
+ {"wpsw_boot", 0, 0, "Firmware write protect switch position at boot"},
+ /* Read-only strings */
+ {"hwid", 1, 0, "Hardware ID"},
+ {"fwid", 1, 0, "Active firmware ID"},
+ {"ro_fwid", 1, 0, "Read-only firmware ID"},
+ /* Terminate with null name */
+ {NULL, 0, 0, NULL}
+};
+
+
+/* Print help */
+void PrintHelp(const char *progname) {
+ const Param *p;
+
+ printf("\nUsage:\n"
+ " %s\n"
+ " Prints all parameters with descriptions and current values.\n"
+ " %s [param1 [param2 [...]]]\n"
+ " Prints the current value(s) of the parameter(s).\n"
+ " %s [param1=value1] [param2=value2 [...]]]\n"
+ " Sets the parameter(s) to the specified value(s).\n"
+ "\n"
+ "Valid parameters:\n", progname, progname, progname);
+ for (p = sys_param_list; p->name; p++)
+ printf(" %-22s %s\n", p->name, p->desc);
+}
+
+
+/* Find the parameter in the list.
+ *
+ * Returns the parameter, or NULL if no match. */
+const Param* FindParam(const char* name) {
+ const Param* p;
+ for (p = sys_param_list; p->name; p++) {
+ if (!strcasecmp(p->name, name))
+ return p;
+ }
+ return NULL;
+}
+
+
+/* Set the specified parameter.
+ *
+ * Returns 0 if success, non-zero if error. */
+int SetParam(const Param* p, const char* value) {
+ if (!p->can_write)
+ return 1; /* Parameter is read-only */
+
+ if (p->is_string) {
+ return (0 == VbSetSystemPropertyString(p->name, value) ? 0 : 1);
+ } else {
+ char* e;
+ int i = strtol(value, &e, 0);
+ if (!*value || (e && *e))
+ return 1;
+ return (0 == VbSetSystemPropertyInt(p->name, i) ? 0 : 1);
+ }
+}
+
+
+/* Print the specified parameter.
+ *
+ * Returns 0 if success, non-zero if error. */
+int PrintParam(const Param* p) {
+ if (p->is_string) {
+ char buf[256];
+ const char* v = VbGetSystemPropertyString(p->name, buf, sizeof(buf));
+ if (!v)
+ return 1;
+ printf("%s", v);
+ } else {
+ int v = VbGetSystemPropertyInt(p->name);
+ if (v == -1)
+ return 1;
+ printf("%d", v);
+ }
+ return 0;
+}
+
+
+/* Print all parameters with descriptions,
+ *
+ * Returns 0 if success, non-zero if error. */
+int PrintAllParams(void) {
+ const Param* p;
+ int retval = 0;
+ char buf[256];
+ const char* value;
+
+ for (p = sys_param_list; p->name; p++) {
+ if (p->is_string) {
+ value = VbGetSystemPropertyString(p->name, buf, sizeof(buf));
+ } else {
+ int v = VbGetSystemPropertyInt(p->name);
+ if (v == -1)
+ value = NULL;
+ else {
+ snprintf(buf, sizeof(buf), "%d", v);
+ value = buf;
+ }
+ }
+ printf("%-22s = %-20s # %s\n",
+ p->name, (value ? value : "(error)"), p->desc);
+ }
+ return retval;
+}
+
+
+int main(int argc, char* argv[]) {
+ int retval = 0;
+ int i;
+
+ char* progname = strrchr(argv[0], '/');
+ if (progname)
+ progname++;
+ else
+ progname = argv[0];
+
+ /* If no args specified, print all params */
+ if (argc == 1)
+ return PrintAllParams();
+
+ /* Print help if needed */
+ if (!strcasecmp(argv[1], "-h") || !strcmp(argv[1], "-?")) {
+ PrintHelp(progname);
+ return 0;
+ }
+
+ /* Otherwise, loop through params and get/set them */
+ for (i = 1; i < argc && retval == 0; i++) {
+ char* name = strtok(argv[i], "=");
+ char* value = strtok(NULL, "=");
+ const Param* p = FindParam(name);
+ if (!p) {
+ fprintf(stderr, "Invalid parameter name: %s\n", name);
+ PrintHelp(progname);
+ return 1;
+ }
+
+ if (i > 1)
+ printf(" "); /* Output params space-delimited */
+ if (value)
+ retval = SetParam(p, value);
+ else
+ retval = PrintParam(p);
+ }
+
+ return retval;
+}