hal/hald/linux2/probing probe-smbios.c,1.5,1.6
Richard Hughes
hughsient at freedesktop.org
Mon Oct 10 08:48:13 PDT 2005
Update of /cvs/hal/hal/hald/linux2/probing
In directory gabe:/tmp/cvs-serv2525
Modified Files:
probe-smbios.c
Log Message:
the smbios prober now works with a new version of dmidecode
Index: probe-smbios.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/probing/probe-smbios.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- probe-smbios.c 27 Sep 2005 09:42:13 -0000 1.5
+++ probe-smbios.c 10 Oct 2005 15:48:11 -0000 1.6
@@ -4,6 +4,7 @@
* probe-smbios.c : Probe system BIOS according to the SMBIOS/DMI standard
*
* Copyright (C) 2005 David Zeuthen, <david at fubar.dk>
+ * Copyright (C) 2005 Richard Hughes, <richard at hughsie.com>
*
* Licensed under the Academic Free License version 2.0
*
@@ -39,37 +40,62 @@
#include "libhal/libhal.h"
#include "shared.h"
-#define DMIPARSER_STATE_IGNORE 0
-#define DMIPARSER_STATE_BIOS 1
-#define DMIPARSER_STATE_SYSTEM 2
-#define DMIPARSER_STATE_CHASSIS 3
+#define DMIPARSER_STATE_IGNORE 0
+#define DMIPARSER_STATE_BIOS 1
+#define DMIPARSER_STATE_SYSTEM 2
+#define DMIPARSER_STATE_CHASSIS 3
#define strbegin(buf, str) (strncmp (buf, str, sizeof (str) - 1) == 0)
-#define setstr(buf, str, prop) \
- do { \
- if (strbegin (buf, str)) { \
- dbus_error_init (&error); \
- libhal_device_set_property_string (ctx, udi, prop, buf + sizeof(str), &error); \
- dbg ("Setting %s='%s'", prop, buf + sizeof(str)); \
- } \
- } while (FALSE);
+/* global */
+char *udi = NULL;
+LibHalContext *ctx = NULL;
+/** Finds the start of a null terminated string and sets HAL
+ * property if valid.
+ *
+ * @param buf The non tabbed prefixed, null terminated string
+ * @param str The strings to compare with e.g. "Vendor:"
+ * @param prop The HAL property to set
+ * @return TRUE is found, FALSE otherwise.
+ */
+static int
+setstr (char *buf, char *str, char *prop)
+{
+ DBusError error;
+ char *value;
+
+ if (strbegin (buf, str)) {
+ dbus_error_init (&error);
+ value = buf + strlen (str) + 1;
+ libhal_device_set_property_string (ctx, udi, prop, value, &error);
+ dbg ("Setting %s='%s'", prop, value);
+ return TRUE;
+ }
+ return FALSE;
+}
+/** Main entry point
+ *
+ * @param argc Number of arguments given to program
+ * @param argv Arguments given to program
+ * @return Return code
+ */
int
main (int argc, char *argv[])
{
int ret;
- char *udi;
- LibHalContext *ctx = NULL;
DBusError error;
char buf[512];
+ char *nbuf;
int dmipipe[2];
int nullfd;
FILE *f;
int dmiparser_state = DMIPARSER_STATE_IGNORE;
- /* on some system chassis pops up several times; so only take the first entry for each */
+ /* on some system chassis pops up several times,
+ * so only take the first entry for each
+ */
int dmiparser_done_bios = FALSE;
int dmiparser_done_system = FALSE;
int dmiparser_done_chassis = FALSE;
@@ -78,15 +104,19 @@
ret = 1;
udi = getenv ("UDI");
- if (udi == NULL)
+ if (udi == NULL) {
+ dbg ("UDI not set");
goto out;
+ }
if ((getenv ("HALD_VERBOSE")) != NULL)
is_verbose = TRUE;
dbus_error_init (&error);
- if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
+ if ((ctx = libhal_ctx_init_direct (&error)) == NULL) {
+ dbg ("ctx init failed");
goto out;
+ }
pipe (dmipipe);
f = fdopen (dmipipe[0], "r");
@@ -106,6 +136,7 @@
execl ("/usr/sbin/dmidecode", "/usr/sbin/dmidecode", NULL);
/* throw an error if we ever reach this point */
+ dbg ("Failed to execute dmidecode!");
exit (1);
break;
case -1:
@@ -123,61 +154,86 @@
{
unsigned int i;
unsigned int len;
+ unsigned int tabs = 0;
/* trim whitespace */
len = strlen (buf);
+
+ /* check that will fit in buffer */
if (len >= sizeof (buf))
continue;
- for (i = len - 1; isspace (buf[i]) && i >= 0; --i)
- buf[i] = '\0';
-
- if (!strbegin (buf, "\t\t"))
+ /* not big enough for data, and protects us from underflow */
+ if (len < 3) {
dmiparser_state = DMIPARSER_STATE_IGNORE;
+ continue;
+ }
- switch (dmiparser_state)
- {
- case DMIPARSER_STATE_IGNORE:
- if (strbegin (buf, "\tBIOS Information")) {
- if (!dmiparser_done_bios)
- dmiparser_state = DMIPARSER_STATE_BIOS;
- } else if (strbegin (buf, "\tSystem Information")) {
- if (!dmiparser_done_system)
- dmiparser_state = DMIPARSER_STATE_SYSTEM;
- } else if (strbegin (buf, "\tChassis Information")) {
- if (!dmiparser_done_chassis)
- dmiparser_state = DMIPARSER_STATE_CHASSIS;
- }
- break;
+ /* find out number of leading tabs */
+ if (buf[0] == '\t' && buf[1] == '\t')
+ tabs = 2; /* this is list data */
+ else if (buf[0] == '\t')
+ tabs = 1; /* this is data, 0 is section type */
+
+ if (tabs == 2)
+ /* we do not proccess data at depth 2 */
+ continue;
- case DMIPARSER_STATE_BIOS:
- setstr (buf, "\t\tVendor:", "smbios.bios.vendor");
- setstr (buf, "\t\tVersion:", "smbios.bios.version");
- setstr (buf, "\t\tRelease Date:", "smbios.bios.release_date");
- dmiparser_done_bios = TRUE;
- break;
+ /* set the section type */
+ if (tabs == 0) {
+ if (!dmiparser_done_bios && strbegin (buf, "BIOS Information"))
+ dmiparser_state = DMIPARSER_STATE_BIOS;
+ else if (!dmiparser_done_system && strbegin (buf, "System Information"))
+ dmiparser_state = DMIPARSER_STATE_SYSTEM;
+ else if (!dmiparser_done_chassis && strbegin (buf, "Chassis Information"))
+ dmiparser_state = DMIPARSER_STATE_CHASSIS;
+ else
+ /*
+ * We do not match the other sections,
+ * or sections we have processed before
+ */
+ dmiparser_state = DMIPARSER_STATE_IGNORE;
+ continue; /* next line */
+ }
- case DMIPARSER_STATE_SYSTEM:
- setstr (buf, "\t\tManufacturer:", "smbios.system.manufacturer");
- setstr (buf, "\t\tProduct Name:", "smbios.system.product");
- setstr (buf, "\t\tVersion:", "smbios.system.version");
- setstr (buf, "\t\tSerial Number:", "smbios.system.serial");
- setstr (buf, "\t\tUUID:", "smbios.system.uuid");
- dmiparser_done_system = TRUE;
- break;
+ /* we are not in a section we know, no point continueing */
+ if (dmiparser_state == DMIPARSER_STATE_IGNORE)
+ continue;
- case DMIPARSER_STATE_CHASSIS:
- setstr (buf, "\t\tManufacturer:", "smbios.chassis.manufacturer");
- setstr (buf, "\t\tType:", "smbios.chassis.type");
+ /* removes the leading tab */
+ nbuf = &buf[1];
+
+ /* removes the trailing spaces */
+ for (i = len - 2; isspace (nbuf[i]) && i >= 0; --i)
+ nbuf[i] = '\0';
+
+ if (dmiparser_state == DMIPARSER_STATE_BIOS) {
+ setstr (nbuf, "Vendor:", "smbios.bios.vendor");
+ setstr (nbuf, "Version:", "smbios.bios.version");
+ setstr (nbuf, "Release Date:", "smbios.bios.release_date");
+ dmiparser_done_bios = TRUE;
+ } else if (dmiparser_state == DMIPARSER_STATE_BIOS) {
+ setstr (nbuf, "Manufacturer:", "smbios.system.manufacturer");
+ setstr (nbuf, "Product Name:", "smbios.system.product");
+ setstr (nbuf, "Version:", "smbios.system.version");
+ setstr (nbuf, "Serial Number:", "smbios.system.serial");
+ setstr (nbuf, "UUID:", "smbios.system.uuid");
+ dmiparser_done_system = TRUE;
+ } else if (dmiparser_state == DMIPARSER_STATE_CHASSIS) {
+ setstr (nbuf, "Manufacturer:", "smbios.chassis.manufacturer");
+ setstr (nbuf, "Type:", "smbios.chassis.type");
dmiparser_done_chassis = TRUE;
- break;
}
}
-
+
+ /* as read to EOF, close */
fclose (f);
+ /* return success */
+ ret = 0;
out:
+ /* free ctx */
if (ctx != NULL) {
dbus_error_init (&error);
libhal_ctx_shutdown (ctx, &error);
More information about the hal-commit
mailing list