persistent property store - first try

Kay Sievers kay.sievers at vrfy.org
Mon Jun 14 10:11:26 PDT 2004


On Sat, Jun 12, 2004 at 08:58:23PM +0200, David Zeuthen wrote:
> On Fri, 2004-06-11 at 17:21, Kay Sievers wrote:
> > > > On Fri, 2004-06-11 at 00:06 +0200, Kay Sievers wrote:
> > 
> > Here is a small update with a few more checks for NULL parameters
> > and a simpler device.c integration.
> > 
> > Hmm, should we convert:
> >   hal_device_property_set_persistence(d, "info.test", TRUE)
> > 
> > to a generic method, so we may use it for other possible attributes too?
> > Something like this:
> >   hal_device_property_set_attribute(d, "info.test", HAL_PROP_ATTR_CALLOUT, FALSE)
> >   hal_device_property_set_attribute(d, "info.test", HAL_PROP_ATTR_PERSISTENCE, TRUE)
> > 
> > Or if we have bits only:
> >   hal_device_property_set_attribute(d, "info.test", HAL_PROP_ATTR_CALLOUT |)
> >                                                     HAL_PROP_ATTR_PERSISTENCE)
> > 
> 
> I'd say go for the former, but that's more a personal preference. We
> probably want to look at what attributes we should have other than
> these. PER_USER and READONLY comes to mind. 
> 
> By default we should probably go with exactly CALLOUT, PERSISTENCE,
> READONLY. And we should probably hardcode things such that any property
> whose keyname starts with 'user.' is always PER_USER, !READONLY and
> !CALLOUT. Per-user probably requires a bit rework on hald_dbus.c.
> 
> One comment on this patch
> 
> > +#define HAL_PSTORE_SYSTEM_PATH      "/var/lib/hal"
> > +
> 
> This should probably be PACKAGE_LOCALSTATE_DIR so it works with
> installing in /usr/local.

Here are a few fixes:
  o use (LOCALSTATEDIR "/lib/hal")

  o switched hal_property_set_persistence () to:
    hal_property_set_attribute (HalProperty *prop, enum property_attribute attr, gboolean val)
    hal_property_get_attribute (HalProperty *prop, enum property_attribute attr)

    (readonly and callout attributes are not handled by now)

  o fixed wrong use of g__return_if_fail ()


Thanks,
Kay
-------------- next part --------------
--- hal/hal/hald/Makefile.am	2004-06-05 02:58:50.000000000 +0200
+++ hal.kay/hal/hald/Makefile.am	2004-06-14 18:26:45.396517080 +0200
@@ -5,6 +5,7 @@
 	-DPACKAGE_DATA_DIR=\""$(datadir)"\" \
 	-DPACKAGE_BIN_DIR=\""$(bindir)"\" \
 	-DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
+	-DPACKAGE_LOCALSTATEDIR=\""$(localstatedir)"\" \
 	-I$(top_srcdir) \
 	@PACKAGE_CFLAGS@
 
@@ -25,6 +26,7 @@
 	logger.h			logger.c			\
 	osspec.h							\
 	property.h			property.c                      \
+	pstore.h                        pstore.c                        \
 	hald_conf.h                     hald_conf.c
 
 hald_SOURCES +=	\
--- hal/hal/hald/hald.h	2004-04-03 09:46:33.000000000 +0200
+++ hal.kay/hal/hald/hald.h	2004-06-14 13:23:29.000000000 +0200
@@ -31,6 +31,7 @@
 #include <dbus/dbus.h>
 
 #include "device_store.h"
+#include "pstore.h"
 
 /**
  *  @addtogroup HalDaemon
@@ -40,6 +41,7 @@
 
 HalDeviceStore *hald_get_gdl (void);
 HalDeviceStore *hald_get_tdl (void);
+HalPStore *hald_get_pstore_sys (void);
 
 void property_atomic_update_begin ();
 void property_atomic_update_end ();
--- hal/hal/hald/hald.c	2004-06-05 02:58:50.000000000 +0200
+++ hal.kay/hal/hald/hald.c	2004-06-14 18:20:42.847632888 +0200
@@ -46,6 +46,7 @@
 #include "logger.h"
 #include "hald.h"
 #include "device_store.h"
+#include "pstore.h"
 #include "device_info.h"
 #include "osspec.h"
 #include "hald_dbus.h"
@@ -61,6 +62,8 @@
 
 static HalDeviceStore *temporary_device_list = NULL;
 
+static HalPStore *pstore_sys = NULL;
+
 static void
 gdl_store_changed (HalDeviceStore *store, HalDevice *device,
 		   gboolean is_added, gpointer user_data)
@@ -131,6 +134,16 @@
 	return temporary_device_list;
 }
 
+HalPStore *
+hald_get_pstore_sys (void)
+{
+	if (pstore_sys == NULL)
+		pstore_sys = hal_pstore_open (PACKAGE_LOCALSTATEDIR
+					      "/lib/hal");
+
+	return pstore_sys;
+}
+
 /**
  * @defgroup MainDaemon Basic functions
  * @ingroup HalDaemon
@@ -273,6 +286,9 @@
 
 	loop = g_main_loop_new (NULL, FALSE);
 
+	/* initialize persitent property store, read uuid from path */
+	hal_pstore_init (PACKAGE_LOCALSTATEDIR "/lib/hal/uuid");
+
 	/* initialize operating system specific parts */
 	osspec_init (dbus_connection);
 	/* and detect devices */
--- hal/hal/hald/device.h	2004-04-26 22:08:58.000000000 +0200
+++ hal.kay/hal/hald/device.h	2004-06-14 18:37:11.586321760 +0200
@@ -150,4 +150,9 @@
 
 void          hal_device_callouts_finished    (HalDevice    *device);
 
+gboolean      hal_device_property_set_attribute (HalDevice *device,
+						 const char *key,
+						 enum property_attribute attr,
+						 gboolean persistence);
+
 #endif /* DEVICE_H */
--- hal/hal/hald/device.c	2004-04-26 22:08:58.000000000 +0200
+++ hal.kay/hal/hald/device.c	2004-06-14 18:34:14.335268016 +0200
@@ -31,7 +31,9 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "hald.h"
 #include "device.h"
+#include "pstore.h"
 #include "hald_marshal.h"
 #include "logger.h"
 
@@ -603,15 +605,18 @@
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, FALSE);
 
-		return TRUE;
-	}
+		if (hal_property_get_attribute (prop, PERSISTENCE))
+			hal_pstore_save_property (hald_get_pstore_sys (), device, prop); 
 
-	prop = hal_property_new_string (key, value);
+	} else {
 
-	device->properties = g_slist_prepend (device->properties, prop);
+		prop = hal_property_new_string (key, value);
 
-	g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
-		       key, FALSE, TRUE);
+		device->properties = g_slist_prepend (device->properties, prop);
+
+		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+			       key, FALSE, TRUE);
+	}
 
 	return TRUE;
 }
@@ -638,15 +643,17 @@
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, FALSE);
 
-		return TRUE;
-	}
+		if (hal_property_get_attribute (prop, PERSISTENCE))
+			hal_pstore_save_property (hald_get_pstore_sys (), device, prop); 
 
-	prop = hal_property_new_int (key, value);
+	} else {
+		prop = hal_property_new_int (key, value);
 
-	device->properties = g_slist_prepend (device->properties, prop);
+		device->properties = g_slist_prepend (device->properties, prop);
 
-	g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
-		       key, FALSE, TRUE);
+		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+			       key, FALSE, TRUE);
+	}
 
 	return TRUE;
 }
@@ -673,15 +680,17 @@
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, FALSE);
 
-		return TRUE;
-	}
+		if (hal_property_get_attribute (prop, PERSISTENCE))
+			hal_pstore_save_property (hald_get_pstore_sys (), device, prop); 
 
-	prop = hal_property_new_bool (key, value);
+	} else {
+		prop = hal_property_new_bool (key, value);
 
-	device->properties = g_slist_prepend (device->properties, prop);
+		device->properties = g_slist_prepend (device->properties, prop);
 
-	g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
-		       key, FALSE, TRUE);
+		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+			       key, FALSE, TRUE);
+	}
 
 	return TRUE;
 }
@@ -708,15 +717,17 @@
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, FALSE);
 
-		return TRUE;
-	}
+		if (hal_property_get_attribute (prop, PERSISTENCE))
+			hal_pstore_save_property (hald_get_pstore_sys (), device, prop); 
 
-	prop = hal_property_new_double (key, value);
+	} else {
+		prop = hal_property_new_double (key, value);
 
-	device->properties = g_slist_prepend (device->properties, prop);
+		device->properties = g_slist_prepend (device->properties, prop);
 
-	g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
-		       key, FALSE, TRUE);
+		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+			       key, FALSE, TRUE);
+	}
 
 	return TRUE;
 }
@@ -731,6 +742,9 @@
 	if (prop == NULL)
 		return FALSE;
 
+	if (hal_property_get_attribute (prop, PERSISTENCE))
+		hal_pstore_delete_property (hald_get_pstore_sys (), device, prop); 
+
 	device->properties = g_slist_remove (device->properties, prop);
 
 	hal_property_free (prop);
@@ -741,6 +755,32 @@
 	return TRUE;
 }
 
+gboolean
+hal_device_property_set_attribute (HalDevice *device,
+				   const char *key,
+				   enum property_attribute attr,
+				   gboolean val)
+{
+	HalProperty *prop;
+
+	prop = hal_device_property_find (device, key);
+
+	if (prop == NULL)
+		return FALSE;
+
+	hal_property_set_attribute (prop, PERSISTENCE, val);
+
+	if (attr == PERSISTENCE) {
+		/* Save property to disk, or delete it */
+		if (val)
+			hal_pstore_save_property (hald_get_pstore_sys (), device, prop);
+		else
+			hal_pstore_delete_property (hald_get_pstore_sys (), device, prop);
+	}
+
+	return TRUE;
+}
+
 void
 hal_device_print (HalDevice *device)
 {
--- hal/hal/hald/property.h	2004-04-20 22:54:15.000000000 +0200
+++ hal.kay/hal/hald/property.h	2004-06-14 18:40:29.859179704 +0200
@@ -31,6 +31,12 @@
 
 typedef struct _HalProperty HalProperty;
 
+enum property_attribute {
+	READONLY,
+	PERSISTENCE,
+	CALLOUT
+};
+
 void          hal_property_free          (HalProperty  *prop);
 
 HalProperty *hal_property_new_string     (const char   *key,
@@ -59,5 +65,10 @@
 					  dbus_bool_t   value);
 void          hal_property_set_double    (HalProperty  *prop,
 					  double        value);
+void          hal_property_set_attribute (HalProperty *prop,
+					  enum property_attribute attr,
+					  gboolean val);
+gboolean      hal_property_get_attribute (HalProperty *prop,
+					  enum property_attribute attr);
 
 #endif /* PROPERTY_H */
--- hal/hal/hald/property.c	2004-04-20 22:54:15.000000000 +0200
+++ hal.kay/hal/hald/property.c	2004-06-14 18:22:05.770026768 +0200
@@ -42,13 +42,16 @@
 		dbus_bool_t bool_value;
 		double double_value;
 	};
+	gboolean readonly;
+	gboolean persistence;
+	gboolean callout;
 };
 
 void
 hal_property_free (HalProperty *prop)
 {
 	g_free (prop->key);
-	
+
 	if (prop->type == DBUS_TYPE_STRING)
 		g_free (prop->str_value);
 
@@ -226,3 +229,41 @@
 	prop->type = DBUS_TYPE_DOUBLE;
 	prop->double_value = value;
 }
+
+void
+hal_property_set_attribute (HalProperty *prop,
+			    enum property_attribute attr,
+			    gboolean val)
+{
+	g_return_if_fail (prop != NULL);
+
+	switch (attr) {
+	case READONLY:
+		prop->readonly = val;
+		break;
+	case PERSISTENCE:
+		prop->persistence = val;
+		break;
+	case CALLOUT:
+		prop->callout = val;
+		break;
+	}
+}
+
+gboolean
+hal_property_get_attribute (HalProperty *prop,
+			    enum property_attribute attr)
+{
+	g_return_val_if_fail (prop != NULL, -1);
+
+	switch (attr) {
+	case READONLY:
+		return prop->readonly;
+	case PERSISTENCE:
+		return prop->persistence;
+	case CALLOUT:
+		return prop->callout;
+	default:
+		return -1;
+	}
+}
--- hal/hal/hald/hald_dbus.c	2004-05-04 18:05:35.000000000 +0200
+++ hal.kay/hal/hald/hald_dbus.c	2004-06-14 18:35:53.068258320 +0200
@@ -872,6 +872,7 @@
 
 	type = dbus_message_iter_get_arg_type (&iter);
 	rc = FALSE;
+
 	switch (type) {
 	case DBUS_TYPE_STRING:
 		rc = hal_device_property_set_string (device, key,
@@ -899,6 +900,11 @@
 		break;
 	}
 
+	/* FIXME: temporary pstore test only */
+	hal_device_property_set_attribute (device, key, PERSISTENCE, TRUE);
+	HAL_WARNING (("FIXME: persistence set for all D-BUS props; "
+		      "udi=%s, key=%s", udi, key));
+
 	if (!rc) {
 		raise_property_type_error (connection, message, udi, key);
 		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
--- hal/hal/hald/linux/common.c	2004-04-26 22:42:13.000000000 +0200
+++ hal.kay/hal/hald/linux/common.c	2004-06-14 13:23:29.000000000 +0200
@@ -44,6 +44,7 @@
 
 #include "../logger.h"
 #include "../device_store.h"
+#include "../pstore.h"
 #include "../device_info.h"
 #include "../hald.h"
 #include "common.h"
@@ -512,6 +513,8 @@
 			HAL_INFO (("Found a .fdi file for %s", d->udi));
 		}
 
+		/* add possible saved properties for this udi from disk*/
+		hal_pstore_load_device (hald_get_pstore_sys (), d);
 	}
 
 	return computed_udi;
--- /dev/null	2004-02-23 22:02:56.000000000 +0100
+++ hal.kay/hal/hald/pstore.h	2004-06-14 17:54:46.872177112 +0200
@@ -0,0 +1,56 @@
+/***************************************************************************
+ * CVSID: $Id: $
+ *
+ * pstore.h : persistent property store on disk
+ *
+ * Copyright (C) 2004 Kay Sievers, <kay.sievers at vrfy.org>
+ *
+ * Licensed under the Academic Free License version 2.0
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ **************************************************************************/
+
+#ifndef PSTORE_H
+#define PSTORE_H
+
+#include "device.h"
+#include "property.h"
+
+typedef struct _HalPStore	HalPStore;
+
+void		hal_pstore_init			(const char *path);
+
+HalPStore	*hal_pstore_open		(const char *path);
+
+void		hal_pstore_close		(HalPStore *pstore);
+
+void		hal_pstore_save_property	(HalPStore *pstore,
+						 HalDevice *device,
+						 HalProperty *prop);
+
+void		hal_pstore_load_property	(HalPStore *pstore,
+						 HalDevice *device,
+						 const char *key);
+
+void		hal_pstore_delete_property	(HalPStore *pstore,
+						 HalDevice *device,
+						 HalProperty *prop);
+
+void		hal_pstore_load_device		(HalPStore *pstore,
+						 HalDevice *device);
+
+
+#endif /* PSTORE_H */
--- /dev/null	2004-02-23 22:02:56.000000000 +0100
+++ hal.kay/hal/hald/pstore.c	2004-06-14 13:23:29.000000000 +0200
@@ -0,0 +1,380 @@
+/***************************************************************************
+ * CVSID: $Id: $
+ *
+ * pstore.c : persistent property store on disk
+ *
+ * Copyright (C) 2004 Kay Sievers, <kay.sievers at vrfy.org>
+ *
+ * Licensed under the Academic Free License version 2.0
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <glib.h>
+
+#include "logger.h"
+#include "pstore.h"
+
+#define PSTR		"String:"
+#define PINT32		"Int32:"
+#define PBOOL		"Bool:"
+#define PDOUBLE		"Double:"
+#define UDI_STRIP	"/org/freedesktop/Hal"
+
+static char *pstore_uuid = NULL;
+
+struct _HalPStore {
+	char *path;
+	const char *uuid;
+};
+
+/** Create relative or absolute path.
+ *
+ */
+static int
+create_path(const char *path)
+{
+	char *p;
+	char *pos;
+	struct stat stats;
+
+	if (stat (path, &stats) == 0)
+		return 0;
+
+	p = g_strdup (path);
+	pos = strrchr (p, '/');
+	if (pos != NULL && pos != p) {
+		pos[0] = '\0';
+		create_path (p);
+	}
+	g_free (p);
+
+	return mkdir(path, 0755);
+}
+
+/** Return absolute filename with simplified udi string.
+ *
+ */
+static char
+*build_path (HalPStore *pstore,
+	     const char *udi, const char *file)
+{
+	char *path;
+	const char *udi_s;
+
+	udi_s = udi;
+	/* strip namespace part of udi string */
+	if (udi != NULL &&
+	    g_ascii_strncasecmp(udi, UDI_STRIP, sizeof(UDI_STRIP)-1) == 0)
+			udi_s = &udi[sizeof(UDI_STRIP)-1];
+
+	path = g_build_filename (G_DIR_SEPARATOR_S,
+				 pstore->path, pstore->uuid,
+				 udi_s, file, NULL);
+
+	return path;
+}
+
+/** Init pstore system by reading or generating our uuid.
+ *
+ */
+void
+hal_pstore_init (const char *uuid_file)
+{
+	char *uuid;
+	char hostname[HOST_NAME_MAX];
+	char *p;
+	GIOChannel *io;
+	GError *error = NULL;
+	int written;
+
+	g_file_get_contents (uuid_file, &uuid, NULL, NULL);
+
+	if (uuid == NULL) {
+		/* create new uuid and save it to disk */
+		gethostname (hostname, HOST_NAME_MAX);
+		uuid = g_strdup_printf ("%s-%lx", hostname, time(NULL));
+
+		p = g_path_get_dirname (uuid_file);
+		create_path(p);
+		g_free(p);
+
+		io = g_io_channel_new_file (uuid_file, "w", &error);
+		if (error != NULL) {
+			HAL_WARNING (("error creating file %s", error->message));
+			g_error_free (error);
+			return;
+		}
+		g_io_channel_write_chars (io, uuid, -1, &written, &error);
+		g_io_channel_shutdown (io, TRUE, NULL);
+		if (error != NULL) {
+			HAL_WARNING (("error writing to file %s", error->message));
+			g_error_free (error);
+			return;
+		}
+	}
+
+	HAL_DEBUG (("uuid is %s", uuid));
+	pstore_uuid = uuid;
+}
+
+
+/** Open pstore on the given location.
+ *
+ */
+HalPStore
+*hal_pstore_open (const char *path)
+{
+	HalPStore *pstore;
+	char *p;
+
+	g_return_val_if_fail (pstore_uuid != NULL, NULL);
+	g_return_val_if_fail (path != NULL, NULL);
+
+	pstore = g_new0 (HalPStore, 1);
+
+	pstore->path = g_strdup (path);
+
+	pstore->uuid = pstore_uuid;
+
+	p = g_build_path (G_DIR_SEPARATOR_S,
+			  pstore->path, pstore->uuid, NULL);
+	create_path(p);
+	g_free(p);
+
+	HAL_DEBUG (("opened pstore at %s/%s/", pstore->path, pstore->uuid));
+
+	return pstore;
+}
+
+/** Turn around the OPEN sign, in the store's entrance :)
+ *
+ */
+void
+hal_pstore_close (HalPStore *pstore)
+{
+	g_return_if_fail (pstore != NULL);
+
+	g_free (pstore->path);
+	g_free (pstore);
+}
+
+/** Save a property value to the disk.
+ *
+ */
+void
+hal_pstore_save_property (HalPStore *pstore,
+			  HalDevice *device, HalProperty *prop)
+{
+	char *path;
+	char *file;
+	GIOChannel *io;
+	GError *error = NULL;
+	char *id;
+	char *value;
+	char *buf;
+	int written;
+
+	g_return_if_fail (pstore != NULL);
+	g_return_if_fail (device != NULL);
+	g_return_if_fail (prop != NULL);
+
+	switch (hal_property_get_type (prop)) {
+	case DBUS_TYPE_STRING:
+		id = PSTR;
+		break;
+	case DBUS_TYPE_INT32:
+		id = PINT32;
+		break;
+	case DBUS_TYPE_BOOLEAN:
+		id = PBOOL;
+		break;
+	case DBUS_TYPE_DOUBLE:
+		id = PDOUBLE;
+		break;
+	default:
+		HAL_WARNING (("unknown property type %s",
+			   hal_property_get_key (prop)));
+		return;
+	}
+
+	path = build_path (pstore, hal_device_get_udi (device), NULL);
+	create_path(path);
+	g_free(path);
+
+	file = build_path (pstore,
+			   hal_device_get_udi (device),
+			   hal_property_get_key (prop));
+
+	io = g_io_channel_new_file (file, "w", &error);
+	if (error != NULL) {
+		HAL_WARNING (("error creating file %s (%s)", file, error->message));
+		g_error_free (error);
+		g_free (file);
+		return;
+	}
+
+	value = hal_property_to_string (prop);
+
+	buf = g_strconcat (id, value, NULL);
+	g_free (value);
+
+	HAL_DEBUG (("write %s to disk", hal_property_get_key (prop)));
+
+	g_io_channel_write_chars (io, buf, -1, &written, &error);
+	if (error != NULL) {
+		HAL_WARNING (("error writing to file %s (%s)", file, error->message));
+		g_error_free (error);
+	}
+
+	g_io_channel_shutdown (io, TRUE, NULL);
+	g_free (buf);
+	g_free (file);
+}
+
+/** Load a stored property value from the disk.
+ *
+ */
+void
+hal_pstore_load_property (HalPStore *pstore,
+			   HalDevice *device, const char *key)
+{
+	char *file;
+	char *buf;
+	char *str;
+	int i;
+	double d;
+
+	g_return_if_fail (pstore != NULL);
+	g_return_if_fail (device != NULL);
+	g_return_if_fail (key != NULL);
+
+	file = build_path (pstore, hal_device_get_udi (device), key);
+
+	g_file_get_contents (file, &buf, NULL, NULL);
+	g_free (file);
+	if (buf == NULL) {
+		HAL_DEBUG (("error reading file %s", file));
+		return;
+	}
+
+	if (g_ascii_strncasecmp (buf, PSTR, sizeof (PSTR)-1) == 0) {
+		str =  &buf[sizeof (PSTR)-1];
+		hal_device_property_set_string (device, key, str);
+		HAL_INFO (("STRING %s read for %s", str, key));
+		goto exit;
+	}
+
+	if (g_ascii_strncasecmp (buf, PINT32, sizeof (PINT32)-1) == 0) {
+		str =  &buf[sizeof (PINT32)-1];
+		i = strtol (str, NULL, 10);
+		hal_device_property_set_int (device, key, i);
+		goto exit;
+	}
+
+	if (g_ascii_strncasecmp (buf, PBOOL, sizeof (PBOOL)-1) == 0) {
+		str =  &buf[sizeof (PBOOL)-1];
+		if (g_ascii_strcasecmp (str, "true") == 0)
+			i = TRUE;
+		else
+			i = FALSE;
+		hal_device_property_set_bool (device, key, i);
+		goto exit;
+	}
+
+	if (g_ascii_strncasecmp (buf, PDOUBLE, sizeof (PDOUBLE)-1) == 0) {
+		str =  &buf[sizeof (PDOUBLE)-1];
+		d = atof (str);
+		hal_device_property_set_double (device, key, d);
+		goto exit;
+	}
+
+	HAL_WARNING (("error determining pstore property type %s", key));
+
+exit:
+	g_free (buf);
+}
+
+/** Delete a stored property from the disk.
+ *
+ */
+void
+hal_pstore_delete_property (HalPStore *pstore,
+			    HalDevice *device, HalProperty *prop)
+{
+	char *file;
+
+	g_return_if_fail (pstore != NULL);
+	g_return_if_fail (device != NULL);
+	g_return_if_fail (prop != NULL);
+
+	file = build_path (pstore,
+			   hal_device_get_udi (device),
+			   hal_property_get_key (prop));
+
+	HAL_DEBUG (("unlinking %s", file));
+
+	unlink(file);
+	g_free(file);
+}
+
+/** Load all stored properties of a device from the disk.
+ *
+ */
+void
+hal_pstore_load_device (HalPStore *pstore,
+			HalDevice *device)
+{
+	GDir *dir;
+	GError *error  = NULL;
+	const char *dirname;
+	char *path;
+
+	g_return_if_fail (pstore != NULL);
+	g_return_if_fail (device != NULL);
+
+	path = build_path (pstore,
+			   hal_device_get_udi (device),
+			   NULL);
+
+	HAL_DEBUG (("reading directory %s", path));
+
+	dir = g_dir_open (path, 0, &error);
+	if (error)
+		goto exit;
+
+	while (1) {
+		dirname = g_dir_read_name (dir);
+		if (dirname == NULL)
+			break;
+
+		hal_pstore_load_property (pstore, device, dirname);
+	}
+
+	g_dir_close (dir);
+
+exit:
+	g_free (path);
+}
-------------- next part --------------
_______________________________________________
hal mailing list
hal at freedesktop.org
http://freedesktop.org/mailman/listinfo/hal


More information about the Hal mailing list