From a2890dd1641e3e497cafb18360252e437acd356a Mon Sep 17 00:00:00 2001
From: Danny Kukawka <danny.kukawka@web.de>
Date: Tue, 16 Mar 2010 10:59:37 +0100
Subject: add new prober to get the results of lsb_release

Added new prober to get the results of lsb_release. Parse
the output and add these new keys:
- system.lsb.version
- system.lsb.distributor_id
- system.lsb.description
- system.lsb.release
- system.lsb.codename
---
 hald/linux/osspec.c                    |  26 ++--
 hald/linux/probing/.gitignore          |  12 +-
 hald/linux/probing/Makefile.am         |   4 +
 hald/linux/probing/probe-lsb-release.c | 224 +++++++++++++++++++++++++++++++++
 4 files changed, 247 insertions(+), 19 deletions(-)
 create mode 100644 hald/linux/probing/probe-lsb-release.c

diff --git a/hald/linux/osspec.c b/hald/linux/osspec.c
index e3399020..a8233fda 100644
--- a/hald/linux/osspec.c
+++ b/hald/linux/osspec.c
@@ -798,6 +798,22 @@ computer_probing_pm_is_supported_helper_done (HalDevice *d, guint32 exit_type,
 	decode_dmi (d);
 }
 
+static void
+computer_probing_lsb_release_helper_done (HalDevice *d, guint32 exit_type,
+                                          gint return_code, gchar **error,
+                                          gpointer data1, gpointer data2)
+{
+        /* Try and set the suspend/hibernate keys using pm-is-supported
+         */
+        if (g_file_test ("/usr/bin/pm-is-supported", G_FILE_TEST_IS_EXECUTABLE)) {
+                hald_runner_run (d, "hal-system-power-pm-is-supported", NULL, HAL_HELPER_TIMEOUT,
+                                 computer_probing_pm_is_supported_helper_done, NULL, NULL);
+        } else {
+                decode_dmi (d);
+        }
+}
+
+
 static void
 get_primary_videocard (HalDevice *d)
 {
@@ -884,14 +900,8 @@ osspec_probe (void)
         /* set the vendor/product of primary video card */
         get_primary_videocard (root);
 
-        /* Try and set the suspend/hibernate keys using pm-is-supported
-         */
-        if (g_file_test ("/usr/bin/pm-is-supported", G_FILE_TEST_IS_EXECUTABLE)) {
-                hald_runner_run (root, "hal-system-power-pm-is-supported", NULL, HAL_HELPER_TIMEOUT,
-                                 computer_probing_pm_is_supported_helper_done, NULL, NULL);
-        } else {
-                decode_dmi (root);
-        }
+        hald_runner_run (root, "hald-probe-lsb-release", NULL, HAL_HELPER_TIMEOUT,
+                         computer_probing_lsb_release_helper_done, NULL, NULL);
 }
 
 DBusHandlerResult
diff --git a/hald/linux/probing/.gitignore b/hald/linux/probing/.gitignore
index d537ee32..1edb4164 100644
--- a/hald/linux/probing/.gitignore
+++ b/hald/linux/probing/.gitignore
@@ -4,16 +4,6 @@ Makefile
 Makefile.in
 *.lo
 *.la
-hald-probe-hiddev
-hald-probe-input
-hald-probe-net-bluetooth
-hald-probe-pc-floppy
-hald-probe-printer
-hald-probe-smbios
-hald-probe-storage
-hald-probe-volume
-hald-probe-serial
-hald-probe-ieee1394-unit
-hald-probe-video4linux
+hald-probe-*
 *.o
 *~
diff --git a/hald/linux/probing/Makefile.am b/hald/linux/probing/Makefile.am
index ec7f94da..3b37ca45 100644
--- a/hald/linux/probing/Makefile.am
+++ b/hald/linux/probing/Makefile.am
@@ -20,6 +20,7 @@ libexec_PROGRAMS = 			\
 	hald-probe-serial 		\
 	hald-probe-ieee1394-unit 	\
 	hald-probe-net-bluetooth 	\
+	hald-probe-lsb-release		\
 	hald-probe-video4linux
 endif
 
@@ -53,6 +54,9 @@ hald_probe_ieee1394_unit_LDADD = $(top_builddir)/libhal/libhal.la @DBUS_LIBS@
 hald_probe_net_bluetooth_SOURCES = probe-net-bluetooth.c ../../logger.c
 hald_probe_net_bluetooth_LDADD = $(top_builddir)/libhal/libhal.la @DBUS_LIBS@
 
+hald_probe_lsb_release_SOURCES = probe-lsb-release.c ../../logger.c
+hald_probe_lsb_release_LDADD = $(top_builddir)/libhal/libhal.la
+
 hald_probe_video4linux_SOURCES = probe-video4linux.c ../../logger.c
 hald_probe_video4linux_LDADD = $(top_builddir)/libhal/libhal.la @DBUS_LIBS@
 
diff --git a/hald/linux/probing/probe-lsb-release.c b/hald/linux/probing/probe-lsb-release.c
new file mode 100644
index 00000000..8a83add4
--- /dev/null
+++ b/hald/linux/probing/probe-lsb-release.c
@@ -0,0 +1,224 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * probe-lsb-release.c : Probe LSB information
+ *
+ * Copyright (C) 2010 Danny Kukawka, <danny.kukawka@web.de>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "libhal/libhal.h"
+#include "../../logger.h"
+
+#define strbegin(buf, str) (strncmp (buf, str, strlen (str)) == 0)
+
+/* global */
+static char *udi = NULL;
+static LibHalContext *ctx = NULL;
+
+/** 
+ *  setstr:
+ *  @buf:		The non tabbed prefixed, null terminated string
+ *  @str:		The strings to compare with e.g. "Vendor:"
+ *  @prop:		The HAL property to set
+ *
+ *  Returns:		TRUE is found, FALSE otherwise.
+ *
+ *  Finds the start of a null terminated string and sets HAL
+ *  property if valid.
+ */
+static int
+setstr (char *buf, char *str, char *prop)
+{
+	DBusError error;
+	char *value;
+
+	dbus_error_init (&error);
+
+	if (buf[strlen(buf)-1] == '\n')
+		buf[strlen(buf)-1] = '\0';	
+
+	value = buf + strlen (str) + 1;
+	if (strcmp (value, "n/a") == 0)
+		goto out;
+
+	if (!libhal_device_set_property_string (ctx, udi, prop, value, &error))
+		dbus_error_init (&error);
+
+	HAL_DEBUG (("Setting %s='%s'", prop, value));
+	return TRUE;
+
+out:
+	return FALSE;
+}
+
+
+/** 
+ *  main:
+ *  @argc:	Number of arguments given to program
+ *  @argv:	Arguments given to program
+ *
+ *  Returns: 	Return code
+ * 
+ *  Main entry point
+ */
+int 
+main (int argc, char *argv[])
+{
+	int ret;
+	DBusError error;
+	char buf[512];
+	int lsbpipe[2];
+	int nullfd;
+	FILE *f;
+
+	uint i;
+	struct stat s;
+	const char *path = NULL;
+	const char *possible_paths[] = {
+		"/usr/bin/lsb_release",
+		"/bin/lsb_release",
+		"/sbin/lsb_release",
+		"/usr/local/bin/lsb_release",
+        };
+
+	/* assume failure */
+	ret = 1;
+
+	setup_logger ();
+
+	dbus_error_init (&error);
+
+	udi = getenv ("UDI");
+	if (udi == NULL) {
+		HAL_ERROR (("UDI not set"));
+		goto out;
+	}
+
+	if ((ctx = libhal_ctx_init_direct (&error)) == NULL) {
+		HAL_ERROR (("ctx init failed"));
+		goto out;
+	}
+
+
+	/* find the path to lsb_release */
+        for (i = 0; i < sizeof (possible_paths) / sizeof (char *); i++) {
+                if (stat (possible_paths[i], &s) == 0 && S_ISREG (s.st_mode)) {
+                        path = possible_paths[i];
+                        break;
+                }
+        }
+
+        if (path == NULL) {
+                HAL_ERROR(("Could not find lsb_release, exit!"));
+		exit(1);
+	}
+
+	if(pipe (lsbpipe) == -1) {
+		HAL_ERROR(("Could not create pipe (error: '%s'), exit!", strerror(errno)));
+		exit(1);
+	}	
+
+	if ((f = fdopen (lsbpipe[0], "r")) == NULL) {
+		HAL_ERROR(("Could not open file (error: '%s'), exit!", strerror(errno)));
+		exit(1);
+	}
+
+	if ((nullfd = open ("/dev/null", O_RDONLY)) == -1){
+		HAL_ERROR(("Could not open /dev/null (error: '%s'), exit!", strerror(errno)));
+		exit(1);
+	}
+	
+	/* fork the child process */
+	switch (fork ()) {
+	case 0:
+		/* child */
+		
+		dup2 (nullfd, STDIN_FILENO);
+		dup2 (lsbpipe[1], STDOUT_FILENO);
+		close (lsbpipe[0]);
+		close (lsbpipe[1]);
+		
+		/* execute the child */
+		execl (path, path, "-a", NULL);
+		
+		/* throw an error if we ever reach this point */
+		HAL_ERROR (("Failed to execute lsb_release!"));
+		exit (1);
+		break;
+	case -1:
+		HAL_ERROR (("Cannot fork!"));
+		goto out;
+	}
+	
+	/* parent continues from here */
+	
+	/* close unused descriptor */
+	close (lsbpipe[1]);
+	
+	/* read the output of the child */
+	while(fgets (buf, sizeof(buf), f) != NULL)
+	{
+		HAL_DEBUG (("probe-lsb-release, got line: '%s'", buf));
+
+		if (strbegin (buf, "LSB Version:")) {
+			setstr (buf, "LSB Version:", "system.lsb.version");
+		} else if (strbegin (buf, "Distributor ID:")) {
+			setstr (buf, "Distributor ID:", "system.lsb.distributor_id");
+		} else if (strbegin (buf, "Description:")) {
+			setstr (buf, "Description:", "system.lsb.description");
+		} else if (strbegin (buf, "Release:")) {
+			setstr (buf, "Release:", "system.lsb.release");
+		} else if (strbegin (buf, "Codename:")) {
+			setstr (buf, "Codename:", "system.lsb.codename");
+		}
+
+		/* return success only if there was something usefull to parse */
+		ret = 0;
+	}
+
+	/* as read to EOF, close */
+	fclose (f);
+
+out:
+	LIBHAL_FREE_DBUS_ERROR (&error);
+
+	/* free ctx */
+	if (ctx != NULL) {
+		libhal_ctx_shutdown (ctx, &error);
+		LIBHAL_FREE_DBUS_ERROR (&error);
+		libhal_ctx_free (ctx);
+	}
+
+	return ret;
+}
-- 
cgit v1.2.3