summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZeeshan Ali (Khattak) <zeeshanak@gnome.org>2011-08-29 15:33:19 +0300
committerZeeshan Ali (Khattak) <zeeshanak@gnome.org>2011-09-01 22:29:33 +0300
commitc968179a0dae56d6bc151b01639a0df25d8c7c9c (patch)
tree2153af1df1376e739276befdfc42ea3c582e6541
parent208fc70f7d35638eee7557ebaec7dded84ded3cf (diff)
Add utility app that detects OS given a media
Given a path to a ISO9660 image/device, detects if media is bootable and the relavent OS if media is an installer for it.
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac1
-rw-r--r--libosinfo.spec.in1
-rw-r--r--tools/Makefile.am14
-rw-r--r--tools/osinfo-detect.c157
5 files changed, 174 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index 92220ea..8ee8bb0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,5 @@
-SUBDIRS = osinfo test data docs examples scripts
+SUBDIRS = osinfo test data tools docs examples scripts
EXTRA_DIST = \
COPYING.LIB \
diff --git a/configure.ac b/configure.ac
index bf5681b..324c0a1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -118,6 +118,7 @@ AC_CONFIG_FILES([
data/devices/Makefile
data/hypervisors/Makefile
data/oses/Makefile
+ tools/Makefile
scripts/Makefile
test/Makefile
docs/Makefile
diff --git a/libosinfo.spec.in b/libosinfo.spec.in
index 5d215ce..17ec5d7 100644
--- a/libosinfo.spec.in
+++ b/libosinfo.spec.in
@@ -85,6 +85,7 @@ rm -fr %{buildroot}
%doc AUTHORS ChangeLog COPYING.LIB NEWS README
%{_bindir}/osinfo-pciids-convert
%{_bindir}/osinfo-usbids-convert
+%{_bindir}/osinfo-detect
%dir %{_datadir}/libosinfo/
%dir %{_datadir}/libosinfo/data/
%{_datadir}/libosinfo/data/usb.ids
diff --git a/tools/Makefile.am b/tools/Makefile.am
new file mode 100644
index 0000000..f87ccd4
--- /dev/null
+++ b/tools/Makefile.am
@@ -0,0 +1,14 @@
+AM_CFLAGS = $(GOBJECT_CFLAGS) \
+ $(GIO_CFLAGS) \
+ $(LIBXML_CFLAGS) \
+ -I$(top_srcdir)
+
+bin_PROGRAMS = osinfo-detect
+
+osinfo_detect_SOURCES = osinfo-detect.c
+
+osinfo_detect_LDADD = $(GOBJECT_LIBS) \
+ $(GIO_LIBS) \
+ $(LIBXML_LIBS) \
+ $(top_builddir)/osinfo/libosinfo-1.0.la
+
diff --git a/tools/osinfo-detect.c b/tools/osinfo-detect.c
new file mode 100644
index 0000000..6afa30a
--- /dev/null
+++ b/tools/osinfo-detect.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc
+ *
+ * osinfo-detect: Given a path to a ISO9660 image/device, detects if media is
+ * bootable and the relavent OS if media is an installer for it.
+ *
+ * This program 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 program 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ * Zeeshan Ali <zeenix@redhat.com>
+ */
+
+#include <osinfo/osinfo.h>
+
+#define FORMAT_STR_PLAIN "plain"
+#define FORMAT_STR_ENV "env"
+
+typedef enum {
+ OUTPUT_FORMAT_PLAIN,
+ OUTPUT_FORMAT_ENV
+} OutputFormat;
+
+static OutputFormat format = OUTPUT_FORMAT_PLAIN;
+
+static gboolean parse_format_str(const gchar *option_name,
+ const gchar *value,
+ gpointer data,
+ GError **error)
+{
+ if (strcmp(value, FORMAT_STR_ENV) == 0)
+ format = OUTPUT_FORMAT_ENV;
+ else if (strcmp(value, FORMAT_STR_PLAIN) == 0)
+ format = OUTPUT_FORMAT_PLAIN;
+ else {
+ g_set_error(error,
+ G_OPTION_ERROR,
+ G_OPTION_ERROR_FAILED,
+ "Invalid value '%s'", value);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static GOptionEntry entries[] =
+{
+ { "format", 'f', 0,
+ G_OPTION_ARG_CALLBACK, parse_format_str,
+ "Output format. Default: plain",
+ "plain|env." },
+ { NULL }
+};
+
+static void print_bootable(gboolean bootable)
+{
+ if (bootable)
+ if (format == OUTPUT_FORMAT_ENV)
+ g_print("OSINFO_BOOTABLE=1\n");
+ else
+ g_print("Media is bootable.\n");
+ else
+ if (format == OUTPUT_FORMAT_ENV)
+ g_print("OSINFO_BOOTABLE=0\n");
+ else
+ g_print("Media is not bootable.\n");
+}
+
+static void print_os(OsinfoOs *os)
+{
+ if (os == NULL)
+ return;
+
+ if (format == OUTPUT_FORMAT_ENV)
+ g_print("OSINFO_INSTALLER=%s\n",
+ osinfo_entity_get_id(OSINFO_ENTITY(os)));
+ else
+ g_print("Media is an installer for OS '%s'\n",
+ osinfo_product_get_name(OSINFO_PRODUCT(os)));
+}
+
+gint main(gint argc, gchar **argv)
+{
+ GOptionContext *context;
+ GError *error = NULL;
+ OsinfoMedia *media = NULL;
+ OsinfoLoader *loader = NULL;
+ OsinfoDb *db = NULL;
+ OsinfoOs *os = NULL;
+ gint ret = 0;
+
+ context = g_option_context_new("- Detect if media is bootable " \
+ "and the relavent OS and distribution.");
+ /* FIXME: We don't have a gettext package to pass to this function. */
+ g_option_context_add_main_entries(context, entries, NULL);
+ if (!g_option_context_parse(context, &argc, &argv, &error)) {
+ g_printerr("Error while parsing options: %s\n", error->message);
+ g_printerr("%s\n", g_option_context_get_help(context, FALSE, NULL));
+
+ ret = -1;
+ goto EXIT;
+ }
+
+ if (argc < 2) {
+ g_printerr("%s\n", g_option_context_get_help(context, FALSE, NULL));
+
+ ret = -2;
+ goto EXIT;
+ }
+
+ g_type_init();
+
+ media = osinfo_media_create_from_location(argv[1], NULL, &error);
+ if (error != NULL) {
+ if (error->code != OSINFO_MEDIA_ERROR_NOT_BOOTABLE) {
+ g_printerr("Error parsing media: %s\n", error->message);
+
+ ret = -3;
+ goto EXIT;
+ } else
+ print_bootable(FALSE);
+ } else
+ print_bootable(TRUE);
+
+ loader = osinfo_loader_new();
+ osinfo_loader_process_default_path(loader, &error);
+ if (error != NULL) {
+ g_printerr("Error loading OS data: %s\n", error->message);
+
+ ret = -4;
+ goto EXIT;
+ }
+
+ db = osinfo_loader_get_db(loader);
+ os = osinfo_db_guess_os_from_media(db, media);
+
+ print_os(os);
+
+EXIT:
+ g_clear_error(&error);
+ g_clear_object(&loader);
+ g_option_context_free(context);
+
+ return ret;
+}