summaryrefslogtreecommitdiffstats
path: root/tools/msiinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/msiinfo.c')
-rw-r--r--tools/msiinfo.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/tools/msiinfo.c b/tools/msiinfo.c
new file mode 100644
index 0000000..ada9293
--- /dev/null
+++ b/tools/msiinfo.c
@@ -0,0 +1,161 @@
+/*
+ * msiinfo - MSI inspection tool
+ *
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * Author: Paolo Bonzini <pbonzini@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "libmsi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static const char *program_name;
+
+struct Command {
+ const char *cmd;
+ const char *desc;
+ const char *usage;
+ const char *opts;
+ const char *help;
+ int (*func)(struct Command *cmd, int argc, char **argv);
+};
+
+static struct Command cmds[];
+
+static char *get_basename(char *path)
+{
+ char *p;
+ if (!path || !*path) {
+ return ".";
+ }
+ p = path + strlen(path);
+ while (p > path && *p != '/' && *p != '\\') {
+ p--;
+ }
+ if (p > path) {
+ p++;
+ }
+ return p;
+}
+
+static void usage(FILE *out)
+{
+ int i;
+
+ fprintf(out, "Usage: %s SUBCOMMAND COMMAND-OPTIONS...\n\n", program_name);
+ fprintf(out, "Options:\n");
+ fprintf(out, " -h, --help Show program usage\n");
+ fprintf(out, " -v, --version Display program version\n\n");
+ fprintf(out, "Available subcommands:\n");
+ for (i = 0; cmds[i].cmd; i++) {
+ if (cmds[i].desc) {
+ fprintf(out, " %-18s%s\n", cmds[i].cmd, cmds[i].desc);
+ }
+ }
+ exit (out == stderr);
+}
+
+static void cmd_usage(FILE *out, struct Command *cmd)
+{
+ fprintf(out, "%s %s %s\n\n%s.\n", program_name, cmd->cmd, cmd->opts,
+ cmd->desc);
+
+ if (cmd->help) {
+ fprintf(out, "\n%s\n", cmd->help);
+ }
+ exit (out == stderr);
+}
+
+static struct Command *find_cmd(const char *s)
+{
+ int i;
+
+ for (i = 0; cmds[i].cmd; i++) {
+ if (!strcmp(s, cmds[i].cmd)) {
+ return &cmds[i];
+ }
+ }
+
+ fprintf(stderr, "%s: Unrecognized command '%s'\n", program_name, s);
+ return NULL;
+}
+
+static int cmd_version(struct Command *cmd, int argc, char **argv)
+{
+ printf("%s (%s) version %s\n", program_name, PACKAGE, VERSION);
+ return 0;
+}
+
+static int cmd_help(struct Command *cmd, int argc, char **argv)
+{
+ if (argc > 1) {
+ cmd = find_cmd(argv[1]);
+ if (cmd && cmd->desc) {
+ cmd_usage(stdout, cmd);
+ }
+ }
+
+ usage(stdout);
+}
+
+static struct Command cmds[] = {
+ {
+ .cmd = "help",
+ .opts = "[SUBCOMMAND]",
+ .desc = "Show program or subcommand usage",
+ .func = cmd_help,
+ },
+ {
+ .cmd = "-h",
+ .func = cmd_help,
+ },
+ {
+ .cmd = "--help",
+ .func = cmd_help,
+ },
+ {
+ .cmd = "-v",
+ .func = cmd_version
+ },
+ {
+ .cmd = "--version",
+ .func = cmd_version
+ },
+ { NULL },
+};
+
+int main(int argc, char **argv)
+{
+ struct Command *cmd = NULL;
+
+ program_name = get_basename(argv[0]);
+
+ if (argc == 1) {
+ usage(stderr);
+ }
+
+ cmd = find_cmd(argv[1]);
+ if (!cmd) {
+ fprintf(stderr, "%s: Unrecognized command\n", program_name);
+ usage(stderr);
+ }
+
+ return cmd->func(cmd, argc - 1, argv + 1);
+}