hal/hald Makefile.am, 1.40, 1.41 device.c, 1.11, 1.12 device.h, 1.9, 1.10 device_info.c, 1.18, 1.19 device_store.c, 1.21, 1.22 hald.c, 1.21, 1.22 hald.h, 1.6, 1.7 hald_dbus.c, 1.18, 1.19 hald_dbus.h, 1.4, 1.5 hald_test.c, NONE, 1.1 hald_test_libhal.c, NONE, 1.1 property.c, 1.8, 1.9 property.h, 1.5, 1.6 pstore.c, 1.3, NONE pstore.h, 1.1, NONE

David Zeuthen david at freedesktop.org
Mon Jan 31 12:06:41 PST 2005


Update of /cvs/hal/hal/hald
In directory gabe:/tmp/cvs-serv1622/hald

Modified Files:
	Makefile.am device.c device.h device_info.c device_store.c 
	hald.c hald.h hald_dbus.c hald_dbus.h property.c property.h 
Added Files:
	hald_test.c hald_test_libhal.c 
Removed Files:
	pstore.c pstore.h 
Log Message:
2005-01-31  David Zeuthen  <davidz at redhat.com>

	* configure.in: Prebump to 0.5.0 - but we're not doing a release yet!
	Add libtool versioning since libhal and libhal-storage are going
	to break API and ABI backwards compatibility.

	* hald/hald_test.c: Add the beginnings of a test suite

	* hald/hald_test_libhal.c: -do-

	* hald/Makefile.am: Add build rules for test suite

	* tools/linux/hal_hotplug_map.c: Update to use new libhal API.

	* tools/lshal.c: Update to use new libhal API.

	* tools/hal_set_property.c: Update to use new libhal API.

	* tools/hal_get_property.c: Update to use new libhal API.

	* tools/fstab-sync.c: Update to use new libhal API.

	* libhal-storage/libhal-storage.c: Update to use new libhal API.
	This library will also go through a renaming/cleanup before 0.5.0.

	* libhal-storage/Makefile.am: Use library versioning

	* libhal/libhal.[ch]: Prefix all function names and other identifiers
	with libhal instead of hal. Add code for string lists. Change the
	way libhal is initialized to be a multistep process. Use HAL_PROPERTY_
	TYPE_* instead of DBUS_TYPE_*. Make all functions using IPC take
	a DBusError argument for better error handling. Notable changes
	(libhal_device_get_all_properties): Teach this function about 
	string lists
	(libhal_psi_get_strlist): New function
	(hal_initialize): Removed
	(hal_shutdown): Removed
	(libhal_device_get_property_strlist): New function
	(libhal_device_property_strlist_append): New function
	(libhal_device_property_strlist_prepend): New function
	(libhal_device_property_strlist_remove_index): New function
	(libhal_device_property_strlist_remove): New function
	(libhal_ctx_new): New function
	(libhal_ctx_set_cache): New function
	(libhal_ctx_set_dbus_connection): New function
	(libhal_ctx_init): New function
	(libhal_ctx_shutdown): New function
	(libhal_ctx_free): New function
	(libhal_ctx_set_device_added): New function
	(libhal_ctx_set_device_removed): New function
	(libhal_ctx_set_device_new_capability): New function
	(libhal_ctx_set_device_lost_capability): New function
	(libhal_ctx_set_device_property_modified): New function
	(libhal_ctx_set_device_condition): New function

	* libhal/Makefile.am: Use library versioning

	* hald/linux2/probing/probe-input.c: Port to new libhal API

	* hald/property.h: Rename property types to HAL_PROPERTY_TYPE_*.
	Add prototypes for new string list properties.

	* hald/property.c: Rename property types to HAL_PROPERTY_TYPE_*.
	(hal_property_free): Teach this function about string lists.
	(hal_property_new_strlist): New function
	(hal_property_get_strlist): New function
	(hal_property_strlist_append): New function
	(hal_property_strlist_prepend): New function
	(hal_property_strlist_remove_elem): New function
	(hal_property_strlist_add): New function
	(hal_property_strlist_remove): New function

	* hald/hald_dbus.c: Rename property types to HAL_PROPERTY_TYPE_*.
	Add new ugly code to handle string lists with the current D-BUS.
	(device_string_list_append_prepend): New function
	(hald_dbus_filter_function): Rename from filter_function. Add
	handlers for new D-BUS methods. Export this function 

	* hald/hald.[ch]: Rip out persistent property code.

	* hald/device_info.c: Rename property types to HAL_PROPERTY_TYPE_*.

	* hald/device.c: Rename to property to HAL_PROPERTY_TYPE_*. Rip out
	persistent property code.
	(hal_device_property_get_as_string): Add code for strlist type
	(hal_device_property_get_strlist): New function
	(hal_device_property_strlist_append): New function
	(hal_device_property_strlist_prepend): New function
	(hal_device_property_strlist_remove_elem): New function
	(hal_device_property_strlist_add): New function
	(hal_device_property_strlist_remove): New function

	* hald/device.h: Add new strlist prototypes

	* pstore.[ch]: Remove for now as persistent properties needs to be
	reworked



Index: Makefile.am
===================================================================
RCS file: /cvs/hal/hal/hald/Makefile.am,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- Makefile.am	16 Dec 2004 04:55:28 -0000	1.40
+++ Makefile.am	31 Jan 2005 20:06:39 -0000	1.41
@@ -11,6 +11,26 @@
 	-I$(top_srcdir) \
 	@PACKAGE_CFLAGS@
 
+check_PROGRAMS = hald-test
+
+hald_test_SOURCES =                                                     \
+	hald_marshal.h			hald_marshal.c			\
+	callout.h			callout.c			\
+	device.h			device.c			\
+	device_info.h			device_info.c			\
+	device_store.h			device_store.c			\
+	logger.h			logger.c			\
+	property.h			property.c                      \
+	hald_conf.h                     hald_conf.c			\
+	hald_dbus.h			hald_dbus.c			\
+	hald_test.c							\
+	hald_test_libhal.c
+
+hald_test_LDADD = @PACKAGE_LIBS@ -lm @EXPAT_LIB@ $(top_builddir)/libhal/libhal.la
+
+TESTS = hald-test
+
+
 sbin_PROGRAMS = hald
 
 BUILT_SOURCES =		\
@@ -28,7 +48,6 @@
 	logger.h			logger.c			\
 	osspec.h							\
 	property.h			property.c                      \
-	pstore.h                        pstore.c                        \
 	hald_conf.h                     hald_conf.c
 
 hald_LDADD = @PACKAGE_LIBS@ -lm -lcap @EXPAT_LIB@ $(top_builddir)/hald/$(HALD_BACKEND)/libhald_$(HALD_BACKEND).la

Index: device.c
===================================================================
RCS file: /cvs/hal/hal/hald/device.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- device.c	12 Oct 2004 20:17:08 -0000	1.11
+++ device.c	31 Jan 2005 20:06:39 -0000	1.12
@@ -33,7 +33,6 @@
 
 #include "hald.h"
 #include "device.h"
-#include "pstore.h"
 #include "hald_marshal.h"
 #include "logger.h"
 #include "hald_conf.h"
@@ -205,36 +204,36 @@
 
 		/* only remove target if it exists with a different type */
 		target_type = hal_device_property_get_type (target, key);
-		if (target_type != DBUS_TYPE_NIL && target_type != type)
+		if (target_type != HAL_PROPERTY_TYPE_NIL && target_type != type)
 			hal_device_property_remove (target, key);
 
 		switch (type) {
 
-		case DBUS_TYPE_STRING:
+		case HAL_PROPERTY_TYPE_STRING:
 			hal_device_property_set_string (
 				target, target_key,
 				hal_property_get_string (p));
 			break;
 
-		case DBUS_TYPE_INT32:
+		case HAL_PROPERTY_TYPE_INT32:
 			hal_device_property_set_int (
 				target, target_key,
 				hal_property_get_int (p));
 			break;
 
-		case DBUS_TYPE_UINT64:
+		case HAL_PROPERTY_TYPE_UINT64:
 			hal_device_property_set_uint64 (
 				target, target_key,
 				hal_property_get_uint64 (p));
 			break;
 
-		case DBUS_TYPE_BOOLEAN:
+		case HAL_PROPERTY_TYPE_BOOLEAN:
 			hal_device_property_set_bool (
 				target, target_key,
 				hal_property_get_bool (p));
 			break;
 
-		case DBUS_TYPE_DOUBLE:
+		case HAL_PROPERTY_TYPE_DOUBLE:
 			hal_device_property_set_double (
 				target, target_key,
 				hal_property_get_double (p));
@@ -275,36 +274,36 @@
 
 		/* only remove target if it exists with a different type */
 		target_type = hal_device_property_get_type (target, key);
-		if (target_type != DBUS_TYPE_NIL && target_type != type)
+		if (target_type != HAL_PROPERTY_TYPE_NIL && target_type != type)
 			hal_device_property_remove (target, key);
 
 		switch (type) {
 
-		case DBUS_TYPE_STRING:
+		case HAL_PROPERTY_TYPE_STRING:
 			hal_device_property_set_string (
 				target, key,
 				hal_property_get_string (p));
 			break;
 
-		case DBUS_TYPE_INT32:
+		case HAL_PROPERTY_TYPE_INT32:
 			hal_device_property_set_int (
 				target, key,
 				hal_property_get_int (p));
 			break;
 
-		case DBUS_TYPE_UINT64:
+		case HAL_PROPERTY_TYPE_UINT64:
 			hal_device_property_set_uint64 (
 				target, key,
 				hal_property_get_uint64 (p));
 			break;
 
-		case DBUS_TYPE_BOOLEAN:
+		case HAL_PROPERTY_TYPE_BOOLEAN:
 			hal_device_property_set_bool (
 				target, key,
 				hal_property_get_bool (p));
 			break;
 
-		case DBUS_TYPE_DOUBLE:
+		case HAL_PROPERTY_TYPE_DOUBLE:
 			hal_device_property_set_double (
 				target, key,
 				hal_property_get_double (p));
@@ -358,32 +357,32 @@
 
 		switch (type) {
 
-		case DBUS_TYPE_STRING:
+		case HAL_PROPERTY_TYPE_STRING:
 			if (strcmp (hal_property_get_string (p),
 				    hal_device_property_get_string (device2,
 								    key)) != 0)
 				return FALSE;
 			break;
 
-		case DBUS_TYPE_INT32:
+		case HAL_PROPERTY_TYPE_INT32:
 			if (hal_property_get_int (p) !=
 			    hal_device_property_get_int (device2, key))
 				return FALSE;
 			break;
 
-		case DBUS_TYPE_UINT64:
+		case HAL_PROPERTY_TYPE_UINT64:
 			if (hal_property_get_uint64 (p) !=
 				hal_device_property_get_uint64 (device2, key))
 				return FALSE;
 			break;
 
-		case DBUS_TYPE_BOOLEAN:
+		case HAL_PROPERTY_TYPE_BOOLEAN:
 			if (hal_property_get_bool (p) !=
 			    hal_device_property_get_bool (device2, key))
 				return FALSE;
 			break;
 
-		case DBUS_TYPE_DOUBLE:
+		case HAL_PROPERTY_TYPE_DOUBLE:
 			if (hal_property_get_double (p) !=
 			    hal_device_property_get_double (device2, key))
 				return FALSE;
@@ -537,15 +536,15 @@
 {
 	HalProperty *prop;
 
-	g_return_val_if_fail (device != NULL, DBUS_TYPE_NIL);
-	g_return_val_if_fail (key != NULL, DBUS_TYPE_NIL);
+	g_return_val_if_fail (device != NULL, HAL_PROPERTY_TYPE_NIL);
+	g_return_val_if_fail (key != NULL, HAL_PROPERTY_TYPE_NIL);
 
 	prop = hal_device_property_find (device, key);
 
 	if (prop != NULL)
 		return hal_property_get_type (prop);
 	else
-		return DBUS_TYPE_NIL;
+		return HAL_PROPERTY_TYPE_NIL;
 }
 
 const char *
@@ -577,21 +576,49 @@
 
 	if (prop != NULL) {
 		switch (hal_property_get_type (prop)) {
-		case DBUS_TYPE_STRING:
+		case HAL_PROPERTY_TYPE_STRING:
 			strncpy (buf, hal_property_get_string (prop), bufsize);
 			break;
-		case DBUS_TYPE_INT32:
+		case HAL_PROPERTY_TYPE_INT32:
 			snprintf (buf, bufsize, "%d", hal_property_get_int (prop));
 			break;
-		case DBUS_TYPE_UINT64:
+		case HAL_PROPERTY_TYPE_UINT64:
 			snprintf (buf, bufsize, "%lld", hal_property_get_uint64 (prop));
 			break;
-		case DBUS_TYPE_DOUBLE:
+		case HAL_PROPERTY_TYPE_DOUBLE:
 			snprintf (buf, bufsize, "%f", hal_property_get_double (prop));
 			break;
-		case DBUS_TYPE_BOOLEAN:
+		case HAL_PROPERTY_TYPE_BOOLEAN:
 			strncpy (buf, hal_property_get_bool (prop) ? "true" : "false", bufsize);
 			break;
+
+		case HAL_PROPERTY_TYPE_STRLIST:
+			/* print out as "\tval1\tval2\val3\t" */
+		        {
+				GSList *iter;
+				guint i;
+
+				if (bufsize > 0)
+					buf[0] = '\t';
+				i = 1;
+				for (iter = hal_property_get_strlist (prop); 
+				     iter != NULL && i < bufsize; 
+				     iter = g_slist_next (iter)) {
+					guint len;
+					const char *str;
+					
+					str = (const char *) iter->data;
+					len = strlen (str);
+					strncpy (buf + i, str, bufsize - i);
+					i += len;
+
+					if (i < bufsize) {
+						buf[i] = '\t';
+						i++;
+					}
+				}
+			}
+			break;
 		}
 		return buf;
 	} else {
@@ -674,7 +701,7 @@
 	prop = hal_device_property_find (device, key);
 
 	if (prop != NULL) {
-		if (hal_property_get_type (prop) != DBUS_TYPE_STRING)
+		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRING)
 			return FALSE;
 
 		/* don't bother setting the same value */
@@ -687,12 +714,6 @@
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, FALSE);
 
-		if (hal_property_get_attribute (prop, PERSISTENCE) &&
-		    hald_get_conf ()->persistent_device_list) {
-			hal_pstore_save_property (hald_get_pstore_sys (), 
-						  device, prop); 
-		}
-
 	} else {
 
 		prop = hal_property_new_string (key, value);
@@ -716,7 +737,7 @@
 	prop = hal_device_property_find (device, key);
 
 	if (prop != NULL) {
-		if (hal_property_get_type (prop) != DBUS_TYPE_INT32)
+		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_INT32)
 			return FALSE;
 
 		/* don't bother setting the same value */
@@ -728,12 +749,6 @@
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, FALSE);
 
-		if (hal_property_get_attribute (prop, PERSISTENCE) &&
-		    hald_get_conf ()->persistent_device_list) {
-			hal_pstore_save_property (hald_get_pstore_sys (), 
-						  device, prop); 
-		}
-
 	} else {
 		prop = hal_property_new_int (key, value);
 
@@ -756,7 +771,7 @@
 	prop = hal_device_property_find (device, key);
 
 	if (prop != NULL) {
-		if (hal_property_get_type (prop) != DBUS_TYPE_UINT64)
+		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_UINT64)
 			return FALSE;
 
 		/* don't bother setting the same value */
@@ -768,12 +783,6 @@
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, FALSE);
 
-		if (hal_property_get_attribute (prop, PERSISTENCE) &&
-		    hald_get_conf ()->persistent_device_list) {
-			hal_pstore_save_property (hald_get_pstore_sys (), 
-						  device, prop); 
-		}
-
 	} else {
 		prop = hal_property_new_uint64 (key, value);
 
@@ -796,7 +805,7 @@
 	prop = hal_device_property_find (device, key);
 
 	if (prop != NULL) {
-		if (hal_property_get_type (prop) != DBUS_TYPE_BOOLEAN)
+		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_BOOLEAN)
 			return FALSE;
 
 		/* don't bother setting the same value */
@@ -808,12 +817,6 @@
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, FALSE);
 
-		if (hal_property_get_attribute (prop, PERSISTENCE) &&
-		    hald_get_conf ()->persistent_device_list) {
-			hal_pstore_save_property (hald_get_pstore_sys (), 
-						  device, prop);
-		} 
-
 	} else {
 		prop = hal_property_new_bool (key, value);
 
@@ -836,7 +839,7 @@
 	prop = hal_device_property_find (device, key);
 
 	if (prop != NULL) {
-		if (hal_property_get_type (prop) != DBUS_TYPE_DOUBLE)
+		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_DOUBLE)
 			return FALSE;
 
 		/* don't bother setting the same value */
@@ -848,12 +851,6 @@
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, FALSE);
 
-		if (hal_property_get_attribute (prop, PERSISTENCE) &&
-		    hald_get_conf ()->persistent_device_list) {
-			hal_pstore_save_property (hald_get_pstore_sys (), 
-						  device, prop); 
-		}
-
 	} else {
 		prop = hal_property_new_double (key, value);
 
@@ -875,23 +872,23 @@
 
 	if (hal_device_has_property (from_device, from)) {
 		switch (hal_device_property_get_type (from_device, from)) {
-		case DBUS_TYPE_STRING:
+		case HAL_PROPERTY_TYPE_STRING:
 			rc = hal_device_property_set_string (
 				to_device, to, hal_device_property_get_string (from_device, from));
 			break;
-		case DBUS_TYPE_INT32:
+		case HAL_PROPERTY_TYPE_INT32:
 			rc = hal_device_property_set_int (
 				to_device, to, hal_device_property_get_int (from_device, from));
 			break;
-		case DBUS_TYPE_UINT64:
+		case HAL_PROPERTY_TYPE_UINT64:
 			rc = hal_device_property_set_uint64 (
 				to_device, to, hal_device_property_get_uint64 (from_device, from));
 			break;
-		case DBUS_TYPE_BOOLEAN:
+		case HAL_PROPERTY_TYPE_BOOLEAN:
 			rc = hal_device_property_set_bool (
 				to_device, to, hal_device_property_get_bool (from_device, from));
 			break;
-		case DBUS_TYPE_DOUBLE:
+		case HAL_PROPERTY_TYPE_DOUBLE:
 			rc = hal_device_property_set_double (
 				to_device, to, hal_device_property_get_double (from_device, from));
 			break;
@@ -911,12 +908,6 @@
 	if (prop == NULL)
 		return FALSE;
 
-	if (hal_property_get_attribute (prop, PERSISTENCE) &&
-	    hald_get_conf ()->persistent_device_list) {
-		hal_pstore_delete_property (hald_get_pstore_sys (), 
-					    device, prop); 
-	}
-
 	device->properties = g_slist_remove (device->properties, prop);
 
 	hal_property_free (prop);
@@ -940,20 +931,6 @@
 	if (prop == NULL)
 		return FALSE;
 
-	hal_property_set_attribute (prop, PERSISTENCE, val);
-
-	if (attr == PERSISTENCE &&
-	    hald_get_conf ()->persistent_device_list) {
-		/* 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;
 }
 
@@ -973,29 +950,29 @@
                 type = hal_property_get_type (p);
 
                 switch (type) {
-                case DBUS_TYPE_STRING:
+                case HAL_PROPERTY_TYPE_STRING:
                         fprintf (stderr, "  %s = '%s'  (string)\n", key,
                                 hal_property_get_string (p));
                         break;
  
-                case DBUS_TYPE_INT32:
+                case HAL_PROPERTY_TYPE_INT32:
                         fprintf (stderr, "  %s = %d  0x%x  (int)\n", key,
                                 hal_property_get_int (p),
                                 hal_property_get_int (p));
                         break;
  
-                case DBUS_TYPE_UINT64:
+                case HAL_PROPERTY_TYPE_UINT64:
                         fprintf (stderr, "  %s = %lld  0x%llx  (uint64)\n", key,
                                 hal_property_get_uint64 (p),
                                 hal_property_get_uint64 (p));
                         break;
  
-                case DBUS_TYPE_DOUBLE:
+                case HAL_PROPERTY_TYPE_DOUBLE:
                         fprintf (stderr, "  %s = %g  (double)\n", key,
                                 hal_property_get_double (p));
                         break;
  
-                case DBUS_TYPE_BOOLEAN:
+                case HAL_PROPERTY_TYPE_BOOLEAN:
                         fprintf (stderr, "  %s = %s  (bool)\n", key,
                                 (hal_property_get_bool (p) ? "true" :
                                  "false"));
@@ -1110,3 +1087,167 @@
 	g_signal_emit (device, signals[CANCELLED], 0);
 }
 
+
+
+
+GSList *
+hal_device_property_get_strlist (HalDevice    *device, 
+				 const char   *key)
+{
+	HalProperty *prop;
+
+	g_return_val_if_fail (device != NULL, NULL);
+	g_return_val_if_fail (key != NULL, NULL);
+
+	prop = hal_device_property_find (device, key);
+
+	if (prop != NULL)
+		return hal_property_get_strlist (prop);
+	else
+		return NULL;
+}
+
+gboolean
+hal_device_property_strlist_append (HalDevice    *device,
+				    const char   *key,
+				    const char *value)
+{
+	HalProperty *prop;
+
+	/* check if property already exists */
+	prop = hal_device_property_find (device, key);
+
+	if (prop != NULL) {
+		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
+			return FALSE;
+
+		hal_property_strlist_append (prop, value);
+
+		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+			       key, FALSE, FALSE);
+
+	} else {
+		prop = hal_property_new_strlist (key);
+		hal_property_strlist_append (prop, value);
+
+		device->properties = g_slist_prepend (device->properties, prop);
+
+		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+			       key, FALSE, TRUE);
+	}
+
+	return TRUE;
+}
+
+gboolean 
+hal_device_property_strlist_prepend (HalDevice    *device,
+				     const char   *key,
+				     const char *value)
+{
+	HalProperty *prop;
+
+	/* check if property already exists */
+	prop = hal_device_property_find (device, key);
+
+	if (prop != NULL) {
+		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
+			return FALSE;
+
+		hal_property_strlist_prepend (prop, value);
+
+		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+			       key, FALSE, FALSE);
+
+	} else {
+		prop = hal_property_new_strlist (key);
+		hal_property_strlist_prepend (prop, value);
+
+		device->properties = g_slist_prepend (device->properties, prop);
+
+		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+			       key, FALSE, TRUE);
+	}
+
+	return TRUE;
+}
+
+gboolean
+hal_device_property_strlist_remove_elem (HalDevice    *device,
+					 const char   *key,
+					 guint index)
+{
+	HalProperty *prop;
+
+	/* check if property already exists */
+	prop = hal_device_property_find (device, key);
+
+	if (prop == NULL)
+		return FALSE;
+
+	if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
+		return FALSE;
+	
+	if (hal_property_strlist_remove_elem (prop, index)) {
+		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+			       key, FALSE, FALSE);
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+gboolean
+hal_device_property_strlist_add (HalDevice *device,
+				 const char *key,
+				 const char *value)
+{
+	HalProperty *prop;
+
+	/* check if property already exists */
+	prop = hal_device_property_find (device, key);
+
+	if (prop != NULL) {
+		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
+			return FALSE;
+
+		if (hal_property_strlist_add (prop, value)) {
+			g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+				       key, FALSE, FALSE);
+		}
+
+	} else {
+		prop = hal_property_new_strlist (key);
+		hal_property_strlist_prepend (prop, value);
+
+		device->properties = g_slist_prepend (device->properties, prop);
+
+		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+			       key, FALSE, TRUE);
+	}
+
+	return TRUE;
+}
+
+gboolean
+hal_device_property_strlist_remove (HalDevice *device,
+				    const char *key,
+				    const char *value)
+{
+	HalProperty *prop;
+
+	/* check if property already exists */
+	prop = hal_device_property_find (device, key);
+
+	if (prop == NULL)
+		return FALSE;
+
+	if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
+		return FALSE;
+	
+	if (hal_property_strlist_remove (prop, value)) {
+		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+			       key, FALSE, FALSE);
+	}
+	
+	return TRUE;
+}

Index: device.h
===================================================================
RCS file: /cvs/hal/hal/hald/device.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- device.h	12 Oct 2004 20:17:08 -0000	1.9
+++ device.h	31 Jan 2005 20:06:39 -0000	1.10
@@ -121,6 +121,8 @@
 						 const char   *key,
 						 char *buf,
 						 size_t bufsize);
+
+
 const char   *hal_device_property_get_string (HalDevice    *device,
 					      const char   *key);
 dbus_int32_t  hal_device_property_get_int    (HalDevice    *device,
@@ -131,6 +133,10 @@
 					      const char   *key);
 double        hal_device_property_get_double (HalDevice    *device,
 					      const char   *key);
+GSList       *hal_device_property_get_strlist (HalDevice    *device,
+					       const char   *key);
+
+
 
 gboolean      hal_device_property_set_string (HalDevice    *device,
 					      const char   *key,
@@ -147,6 +153,22 @@
 gboolean      hal_device_property_set_double (HalDevice    *device,
 					      const char   *key,
 					      double        value);
+gboolean      hal_device_property_strlist_append (HalDevice    *device,
+						  const char   *key,
+						  const char *value);
+gboolean      hal_device_property_strlist_prepend (HalDevice    *device,
+						  const char   *key,
+						  const char *value);
+gboolean      hal_device_property_strlist_remove_elem (HalDevice    *device,
+						       const char   *key,
+						       guint index);
+gboolean      hal_device_property_strlist_add (HalDevice    *device,
+					       const char   *key,
+					       const char *value);
+gboolean      hal_device_property_strlist_remove (HalDevice    *device,
+						  const char   *key,
+						  const char *value);
+
 
 gboolean      hal_device_property_remove     (HalDevice    *device,
 					      const char   *key);

Index: device_info.c
===================================================================
RCS file: /cvs/hal/hal/hald/device_info.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- device_info.c	18 Jan 2005 19:48:12 -0000	1.18
+++ device_info.c	31 Jan 2005 20:06:39 -0000	1.19
@@ -158,7 +158,7 @@
  *  @param  prop_result_size    Size of property string
  *  @return                     TRUE if and only if the path resolved.
  */
-gboolean
+static gboolean
 resolve_udiprop_path (const char *path, const char *source_udi,
 		      char *udi_result, size_t udi_result_size, 
 		      char *prop_result, size_t prop_result_size)
@@ -270,29 +270,29 @@
 
 	proptype = hal_device_property_get_type (d, key);
 	switch (proptype) {
-	case DBUS_TYPE_STRING:
+	case HAL_PROPERTY_TYPE_STRING:
 		*result = (dbus_int64_t) strcmp (hal_device_property_get_string (d, key), right_side);
 		rc = TRUE;
 		break;
 
-	case DBUS_TYPE_INT32:
+	case HAL_PROPERTY_TYPE_INT32:
 		*result = ((dbus_int64_t) hal_device_property_get_int (d, key)) - strtoll (right_side, NULL, 0);
 		rc = TRUE;
 		break;
 
-	case DBUS_TYPE_UINT64:
+	case HAL_PROPERTY_TYPE_UINT64:
 		*result = ((dbus_int64_t) hal_device_property_get_uint64 (d, key)) - ((dbus_int64_t) strtoll (right_side, NULL, 0));
 		rc = TRUE;
 		break;
 
-	case DBUS_TYPE_DOUBLE:
+	case HAL_PROPERTY_TYPE_DOUBLE:
 		*result = (dbus_int64_t) ceil (hal_device_property_get_double (d, key) - atof (right_side));
 		rc = TRUE;
 		break;
 
 	default:
 		/* explicit fallthrough */
-	case DBUS_TYPE_BOOLEAN:
+	case HAL_PROPERTY_TYPE_BOOLEAN:
 		/* explicit blank since this doesn't make sense */
 		break;
 	}
@@ -355,7 +355,7 @@
 		/*HAL_INFO(("Checking that key='%s' is a string that "
 		  "equals '%s'", key, value)); */
 
-		if (hal_device_property_get_type (d, prop_to_check) != DBUS_TYPE_STRING)
+		if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_STRING)
 			return FALSE;
 
 		if (strcmp (hal_device_property_get_string (d, prop_to_check),
@@ -375,7 +375,7 @@
 		/*HAL_INFO (("Checking that key='%s' is a int that equals %d", 
 		  key, value));*/
 
-		if (hal_device_property_get_type (d, prop_to_check) != DBUS_TYPE_INT32)
+		if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_INT32)
 			return FALSE;
 
 		if (hal_device_property_get_int (d, prop_to_check) != value) {
@@ -394,7 +394,7 @@
 		/*HAL_INFO (("Checking that key='%s' is a int that equals %d", 
 		  key, value));*/
 
-		if (hal_device_property_get_type (d, prop_to_check) != DBUS_TYPE_UINT64)
+		if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_UINT64)
 			return FALSE;
 
 		if (hal_device_property_get_uint64 (d, prop_to_check) != value) {
@@ -418,7 +418,7 @@
 		  key, value ? "TRUE" : "FALSE"));*/
 
 		if (hal_device_property_get_type (d, prop_to_check) != 
-		    DBUS_TYPE_BOOLEAN)
+		    HAL_PROPERTY_TYPE_BOOLEAN)
 			return FALSE;
 
 		if (hal_device_property_get_bool (d, prop_to_check) != value)
@@ -450,7 +450,7 @@
 		if (strcmp (attr[3], "false") == 0)
 			should_be_empty = FALSE;
 
-		if (hal_device_property_get_type (d, prop_to_check) != DBUS_TYPE_STRING)
+		if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_STRING)
 			return FALSE;
 
 		if (hal_device_has_property (d, prop_to_check))
@@ -477,7 +477,7 @@
 		if (strcmp (attr[3], "false") == 0)
 			should_be_ascii = FALSE;
 
-		if (hal_device_property_get_type (d, prop_to_check) != DBUS_TYPE_STRING)
+		if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_STRING)
 			return FALSE;
 
 		is_ascii = TRUE;
@@ -509,7 +509,7 @@
 
 		/*HAL_INFO (("d->udi='%s', prop_to_check='%s'", d->udi, prop_to_check));*/
 
-		if (hal_device_property_get_type (d, prop_to_check) != DBUS_TYPE_STRING)
+		if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_STRING)
 			return FALSE;
 
 		if (hal_device_has_property (d, prop_to_check)) {
@@ -538,7 +538,7 @@
 
 		needle = attr[3];
 
-		if (hal_device_property_get_type (d, prop_to_check) != DBUS_TYPE_STRING)
+		if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_STRING)
 			return FALSE;
 
 		if (hal_device_has_property (d, prop_to_check)) {
@@ -557,7 +557,7 @@
 
 		needle = attr[3];
 
-		if (hal_device_property_get_type (d, prop_to_check) != DBUS_TYPE_STRING)
+		if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_STRING)
 			return FALSE;
 
 		if (hal_device_has_property (d, prop_to_check)) {
@@ -933,7 +933,7 @@
 			break;
 		}
 	} else if (pc->curelem == CURELEM_APPEND && pc->match_ok && 
-		   hal_device_property_get_type (pc->device, pc->merge_key) == DBUS_TYPE_STRING) {
+		   hal_device_property_get_type (pc->device, pc->merge_key) == HAL_PROPERTY_TYPE_STRING) {
 		char buf[256];
 		char buf2[256];
 

Index: device_store.c
===================================================================
RCS file: /cvs/hal/hal/hald/device_store.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- device_store.c	16 Sep 2004 22:04:15 -0000	1.21
+++ device_store.c	31 Jan 2005 20:06:39 -0000	1.22
@@ -284,7 +284,7 @@
 			continue;
 
 		type = hal_device_property_get_type (d, key);
-		if (type != DBUS_TYPE_STRING)
+		if (type != HAL_PROPERTY_TYPE_STRING)
 			continue;
 
 		if (strcmp (hal_device_property_get_string (d, key),
@@ -313,7 +313,7 @@
 			continue;
 
 		type = hal_device_property_get_type (d, key);
-		if (type != DBUS_TYPE_INT32)
+		if (type != HAL_PROPERTY_TYPE_INT32)
 			continue;
 
 		if (hal_device_property_get_int (d, key) == value)
@@ -343,7 +343,7 @@
 			continue;
 
 		type = hal_device_property_get_type (d, key);
-		if (type != DBUS_TYPE_STRING)
+		if (type != HAL_PROPERTY_TYPE_STRING)
 			continue;
 
 		if (strcmp (hal_device_property_get_string (d, key),

Index: hald.c
===================================================================
RCS file: /cvs/hal/hal/hald/hald.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- hald.c	18 Oct 2004 22:52:05 -0000	1.21
+++ hald.c	31 Jan 2005 20:06:39 -0000	1.22
@@ -50,7 +50,6 @@
 #include "logger.h"
 #include "hald.h"
 #include "device_store.h"
-#include "pstore.h"
 #include "device_info.h"
 #include "osspec.h"
 #include "hald_dbus.h"
@@ -70,8 +69,6 @@
 
 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)
@@ -142,16 +139,6 @@
 	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
@@ -497,10 +484,6 @@
 
 	loop = g_main_loop_new (NULL, FALSE);
 
-	/* initialize persitent property store, read uuid from path */
-	if (hald_get_conf ()->persistent_device_list)
-		hal_pstore_init (PACKAGE_LOCALSTATEDIR "/lib/hal/uuid");
-
 	/* initialize operating system specific parts */
 	osspec_init ();
 

Index: hald.h
===================================================================
RCS file: /cvs/hal/hal/hald/hald.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- hald.h	22 Aug 2004 19:27:22 -0000	1.6
+++ hald.h	31 Jan 2005 20:06:39 -0000	1.7
@@ -31,7 +31,6 @@
 #include <dbus/dbus.h>
 
 #include "device_store.h"
-#include "pstore.h"
 
 /**
  *  @addtogroup HalDaemon
@@ -41,7 +40,6 @@
 
 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 ();

Index: hald_dbus.c
===================================================================
RCS file: /cvs/hal/hal/hald/hald_dbus.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- hald_dbus.c	18 Jan 2005 19:48:12 -0000	1.18
+++ hald_dbus.c	31 Jan 2005 20:06:39 -0000	1.19
@@ -655,32 +655,51 @@
 	key = hal_property_get_key (p);
 	type = hal_property_get_type (p);
 
-	dbus_message_iter_append_dict_key (iter, key);
-
 	switch (type) {
-	case DBUS_TYPE_STRING:
-		dbus_message_iter_append_string (iter,
-						 hal_property_get_string (p));
+	case HAL_PROPERTY_TYPE_STRING:
+		dbus_message_iter_append_dict_key (iter, key);
+		dbus_message_iter_append_string (iter, hal_property_get_string (p));
 		break;
-	case DBUS_TYPE_INT32:
-		dbus_message_iter_append_int32 (iter,
-						hal_property_get_int (p));
+	case HAL_PROPERTY_TYPE_INT32:
+		dbus_message_iter_append_dict_key (iter, key);
+		dbus_message_iter_append_int32 (iter, hal_property_get_int (p));
 		break;
-	case DBUS_TYPE_UINT64:
-		dbus_message_iter_append_uint64 (iter,
-						hal_property_get_uint64 (p));
+	case HAL_PROPERTY_TYPE_UINT64:
+		dbus_message_iter_append_dict_key (iter, key);
+		dbus_message_iter_append_uint64 (iter, hal_property_get_uint64 (p));
 		break;
-	case DBUS_TYPE_DOUBLE:
-		dbus_message_iter_append_double (iter,
-						 hal_property_get_double (p));
+	case HAL_PROPERTY_TYPE_DOUBLE:
+		dbus_message_iter_append_dict_key (iter, key);
+		dbus_message_iter_append_double (iter, hal_property_get_double (p));
 		break;
-	case DBUS_TYPE_BOOLEAN:
-		dbus_message_iter_append_boolean (iter,
-						  hal_property_get_bool (p));
+	case HAL_PROPERTY_TYPE_BOOLEAN:
+		dbus_message_iter_append_dict_key (iter, key);
+		dbus_message_iter_append_boolean (iter, hal_property_get_bool (p));
+		break;
+	case HAL_PROPERTY_TYPE_STRLIST:
+	{
+		char buf[256];
+
+		/* yikes, this is *really* ugly - we kind of have to do it, as D-BUS as of 0.23 doesn't
+		 * support anything but primitive types as dict values. D-BUS CVS as of Jan 27, 2005
+		 * should work (since it got recursive data types); TODO FIXME HACK XXX
+		 *
+		 * So, instead, send it over the wire as '\tval1\tval2\tval3\t' and put some brains
+		 * in the other end (libhal) to clean it up... 
+		 *
+		 * Of course, this will sort of break stuff not using libhal.
+		 *
+		 * I did say *really* ugly... sue me..
+		 */
+		
+		dbus_message_iter_append_dict_key (iter, key);
+		dbus_message_iter_append_string (iter, 
+						 hal_device_property_get_as_string (device, key, buf, sizeof (buf)));
+	}
 		break;
 		
 	default:
-		HAL_WARNING (("Unknown property type %d", type));
+		HAL_WARNING (("Unknown property type 0x%04x", type));
 		break;
 	}
 
@@ -808,25 +827,30 @@
 
 	type = hal_property_get_type (p);
 	switch (type) {
-	case DBUS_TYPE_STRING:
-		dbus_message_iter_append_string (&iter,
-						 hal_property_get_string (p));
+	case HAL_PROPERTY_TYPE_STRING:
+		dbus_message_iter_append_string (&iter, hal_property_get_string (p));
 		break;
-	case DBUS_TYPE_INT32:
-		dbus_message_iter_append_int32 (&iter,
-						hal_property_get_int (p));
+	case HAL_PROPERTY_TYPE_INT32:
+		dbus_message_iter_append_int32 (&iter, hal_property_get_int (p));
 		break;
-	case DBUS_TYPE_UINT64:
-		dbus_message_iter_append_uint64 (&iter,
-						hal_property_get_uint64 (p));
+	case HAL_PROPERTY_TYPE_UINT64:
+		dbus_message_iter_append_uint64 (&iter, hal_property_get_uint64 (p));
 		break;
-	case DBUS_TYPE_DOUBLE:
-		dbus_message_iter_append_double (&iter,
-						 hal_property_get_double (p));
+	case HAL_PROPERTY_TYPE_DOUBLE:
+		dbus_message_iter_append_double (&iter, hal_property_get_double (p));
 		break;
-	case DBUS_TYPE_BOOLEAN:
-		dbus_message_iter_append_boolean (&iter,
-						  hal_property_get_bool (p));
+	case HAL_PROPERTY_TYPE_BOOLEAN:
+		dbus_message_iter_append_boolean (&iter, hal_property_get_bool (p));
+		break;
+	case HAL_PROPERTY_TYPE_STRLIST:
+	{
+		GSList *l;
+		DBusMessageIter iter_array;
+		dbus_message_iter_append_array (&iter, &iter_array, DBUS_TYPE_STRING);
+		for (l = hal_property_get_strlist (p); l != NULL; l = g_slist_next (l)) {
+			dbus_message_iter_append_string (&iter_array, l->data);
+		}
+	}
 		break;
 
 	default:
@@ -1039,11 +1063,6 @@
 		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_HANDLED;
@@ -1156,6 +1175,61 @@
 }
 
 
+/* TODO: docs */
+static DBusHandlerResult
+device_string_list_append_prepend (DBusConnection * connection, DBusMessage * message, dbus_bool_t do_prepend)
+{
+	const char *udi;
+	const char *key;
+	const char *value;
+	HalDevice *d;
+	DBusMessage *reply;
+	DBusError error;
+	gboolean ret;
+
+	HAL_TRACE (("entering"));
+
+	udi = dbus_message_get_path (message);
+
+	d = hal_device_store_find (hald_get_gdl (), udi);
+	if (d == NULL)
+		d = hal_device_store_find (hald_get_tdl (), udi);
+
+	if (d == NULL) {
+		raise_no_such_device (connection, message, udi);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	dbus_error_init (&error);
+	if (!dbus_message_get_args (message, &error,
+				    DBUS_TYPE_STRING, &key,
+				    DBUS_TYPE_STRING, &value,
+				    DBUS_TYPE_INVALID)) {
+		raise_syntax (connection, message, do_prepend ? "StringListPrepend" : "StringListAppend");
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	if (do_prepend)
+		ret = hal_device_property_strlist_prepend (d, key, value);
+	else
+		ret = hal_device_property_strlist_append (d, key, value);
+	if (!ret) {
+		raise_property_type_error (connection, message, udi, key);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	reply = dbus_message_new_method_return (message);
+	if (reply == NULL)
+		DIE (("No memory"));
+
+	if (!dbus_connection_send (connection, reply, NULL))
+		DIE (("No memory"));
+
+	dbus_message_unref (reply);
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
 
 /** Remove a property on a device.
  *
@@ -1788,16 +1862,16 @@
  *  @param  user_data           User data
  *  @return                     What to do with the message
  */
-static DBusHandlerResult
-filter_function (DBusConnection * connection,
-		 DBusMessage * message, void *user_data)
+DBusHandlerResult
+hald_dbus_filter_function (DBusConnection * connection,
+			   DBusMessage * message, void *user_data)
 {
-/*
-    HAL_INFO (("obj_path=%s interface=%s method=%s", 
-	       dbus_message_get_path(message), 
-	       dbus_message_get_interface(message),
-	       dbus_message_get_member(message)));
-*/
+
+	HAL_INFO (("obj_path=%s interface=%s method=%s", 
+		   dbus_message_get_path(message), 
+		   dbus_message_get_interface(message),
+		   dbus_message_get_member(message)));
+
 
 	if (dbus_message_is_signal (message,
 				    DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
@@ -1857,6 +1931,10 @@
 		return device_get_property (connection, message);
 	} else if (dbus_message_is_method_call (message,
 						"org.freedesktop.Hal.Device",
+						"GetPropertyStringList")) {
+		return device_get_property (connection, message);
+	} else if (dbus_message_is_method_call (message,
+						"org.freedesktop.Hal.Device",
 						"GetPropertyInteger")) {
 		return device_get_property (connection, message);
 	} else if (dbus_message_is_method_call (message,
@@ -1915,6 +1993,14 @@
 						"org.freedesktop.Hal.Device",
 						"Unlock")) {
 		return device_unlock (connection, message);
+	} else if (dbus_message_is_method_call (message,
+						"org.freedesktop.Hal.Device",
+						"StringListAppend")) {
+		return device_string_list_append_prepend (connection, message, FALSE);
+	} else if (dbus_message_is_method_call (message,
+						"org.freedesktop.Hal.Device",
+						"StringListPrepend")) {
+		return device_string_list_append_prepend (connection, message, TRUE);
 	} else
 		osspec_filter_function (connection, message, user_data);
 
@@ -1946,7 +2032,7 @@
 		return FALSE;
 	}
 
-	dbus_connection_add_filter (dbus_connection, filter_function, NULL,
+	dbus_connection_add_filter (dbus_connection, hald_dbus_filter_function, NULL,
 				    NULL);
 
 	dbus_bus_add_match (dbus_connection,

Index: hald_dbus.h
===================================================================
RCS file: /cvs/hal/hal/hald/hald_dbus.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- hald_dbus.h	17 Sep 2004 17:05:48 -0000	1.4
+++ hald_dbus.h	31 Jan 2005 20:06:39 -0000	1.5
@@ -89,4 +89,7 @@
 
 gboolean hald_dbus_init (void);
 
+DBusHandlerResult hald_dbus_filter_function (DBusConnection * connection, DBusMessage * message, void *user_data);
+
+
 #endif /* HAL_DBUS_H */

--- NEW FILE: hald_test.c ---
/***************************************************************************
 * CVSID: $Id: hald_test.c,v 1.1 2005/01/31 20:06:39 david Exp $
 *
 * hald_test.c : Unit tests for hald
 *
 * Copyright (C) 2005 David Zeuthen, <david at fubar.dk>
 *
 * 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 <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/prctl.h>
#include <sys/capability.h>
#include <grp.h>
#include <syslog.h>

#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>

#include "logger.h"
#include "hald.h"
#include "device_store.h"
#include "device_info.h"

static HalDeviceStore *global_device_list = NULL;

static HalDeviceStore *temporary_device_list = NULL;

/** This is set to #TRUE if we are probing and #FALSE otherwise */
dbus_bool_t hald_is_initialising;

/** This is set to #TRUE if we are shutting down and #FALSE otherwise */
dbus_bool_t hald_is_shutting_down;

/** If #TRUE, we will spew out debug */
dbus_bool_t hald_is_verbose = FALSE;

HalDeviceStore *
hald_get_gdl (void)
{
	if (global_device_list == NULL) {
		global_device_list = hal_device_store_new ();
#if 0		
		g_signal_connect (global_device_list,
				  "store_changed",
				  G_CALLBACK (gdl_store_changed), NULL);
		g_signal_connect (global_device_list,
				  "device_property_changed",
				  G_CALLBACK (gdl_property_changed), NULL);
		g_signal_connect (global_device_list,
				  "device_capability_added",
				  G_CALLBACK (gdl_capability_added), NULL);
#endif
	}

	return global_device_list;
}

HalDeviceStore *
hald_get_tdl (void)
{
	if (temporary_device_list == NULL) {
		temporary_device_list = hal_device_store_new ();
		
	}

	return temporary_device_list;
}

/*--------------------------------------------------------------------------------------------------------------*/

static gboolean
check_properties (void)
{
	HalDevice *d;
	GSList *s;

	printf ("Checking HalDevice properties\n");

	d = hal_device_new ();
	if (d == NULL) {
		printf ("Cannot allocate HalDevice object\n");
		goto out;
	}

	printf ("int: ");
	hal_device_property_set_int (d, "test.int", 42);
	if (hal_device_property_get_int (d, "test.int") != 42) {
		printf ("FAILED\n");
		goto out;
	}
	printf ("PASSED\n");

	printf ("uint64: ");
	hal_device_property_set_uint64 (d, "test.uint64", ((((dbus_uint64_t)1)<<35) + 5));
	if (hal_device_property_get_uint64 (d, "test.uint64") != ((((dbus_uint64_t)1)<<35) + 5)) {
		printf ("FAILED\n");
		goto out;
	}
	printf ("PASSED\n");

	{
		double val = 0.53434343;
		double val2;

		printf ("double: ");
		hal_device_property_set_double (d, "test.double", val);
		val2 = hal_device_property_get_double (d, "test.double");
		if (memcmp (&val, &val2, sizeof (double)) != 0) {
			printf ("FAILED\n");
			goto out;
		}
		printf ("PASSED\n");
	}

	printf ("string (ASCII): ");
	hal_device_property_set_string (d, "test.string", "fooooobar22");
	if (strcmp (hal_device_property_get_string (d, "test.string"), "fooooobar22") != 0) {
		printf ("FAILED\n");
		goto out;
	}
	printf ("PASSED\n");

	printf ("string (UTF-8): ");
	hal_device_property_set_string (d, "test.string2", "fooøةמ");
	if (strcmp (hal_device_property_get_string (d, "test.string2"), "fooøةמ") != 0) {
		printf ("FAILED\n");
		goto out;
	}
	printf ("PASSED\n");

	printf ("bool: ");
	hal_device_property_set_bool (d, "test.bool", TRUE);
	if (hal_device_property_get_bool (d, "test.bool") != TRUE) {
		printf ("FAILED\n");
		goto out;
	}
	printf ("PASSED\n");

	printf ("strlist: ");
	if (!hal_device_property_strlist_append (d, "test.strlist", "foostrlist0")) {
		printf ("FAILED00\n");
		goto out;
	}
	if ((s = hal_device_property_get_strlist (d, "test.strlist")) == NULL) {
		printf ("FAILED01\n");
		goto out;
	}
	if (g_slist_length (s) != 1) {
		printf ("FAILED02\n");
		goto out;
	}
	if (strcmp (s->data, "foostrlist0") != 0) {
		printf ("FAILED03\n");
		goto out;
	}
	
	if (!hal_device_property_strlist_append (d, "test.strlist", "foostrlist1")) {
		printf ("FAILED10\n");
		goto out;
	}
	if ((s = hal_device_property_get_strlist (d, "test.strlist")) == NULL) {
		printf ("FAILED11\n");
		goto out;
	}
	if (g_slist_length (s) != 2) {
		printf ("FAILED12\n");
		goto out;
	}
	if (s == NULL || strcmp (s->data, "foostrlist0") != 0) {
		printf ("FAILED13\n");
		goto out;
	}
	s = s->next;
	if (s == NULL || strcmp (s->data, "foostrlist1") != 0) {
		printf ("FAILED14\n");
		goto out;
	}
	
	if (!hal_device_property_strlist_prepend (d, "test.strlist", "foostrlist2")) {
		printf ("FAILED20\n");
		goto out;
	}
	if ((s = hal_device_property_get_strlist (d, "test.strlist")) == NULL) {
		printf ("FAILED21\n");
		goto out;
	}
	if (g_slist_length (s) != 3) {
		printf ("FAILED22\n");
		goto out;
	}
	if (s == NULL || strcmp (s->data, "foostrlist2") != 0) {
		printf ("FAILED23\n");
		goto out;
	}
	s = s->next;
	if (s == NULL || strcmp (s->data, "foostrlist0") != 0) {
		printf ("FAILED24\n");
		goto out;
	}
	s = s->next;
	if (s == NULL || strcmp (s->data, "foostrlist1") != 0) {
		printf ("FAILED25\n");
		goto out;
	}


	if (!hal_device_property_strlist_remove_elem (d, "test.strlist", 1)) {
		printf ("FAILED30\n");
		goto out;
	}
	if ((s = hal_device_property_get_strlist (d, "test.strlist")) == NULL) {
		printf ("FAILED31\n");
		goto out;
	}
	if (g_slist_length (s) != 2) {
		printf ("FAILED32\n");
		goto out;
	}
	if (s == NULL || strcmp (s->data, "foostrlist2") != 0) {
		printf ("FAILED33\n");
		goto out;
	}
	s = s->next;
	if (s == NULL || strcmp (s->data, "foostrlist1") != 0) {
		printf ("FAILED34\n");
		goto out;
	}

	/* this add will succeed but it shouldn't change the list */
	if (!hal_device_property_strlist_add (d, "test.strlist", "foostrlist2")) {
		printf ("FAILED40\n");
		goto out;
	}
	if ((s = hal_device_property_get_strlist (d, "test.strlist")) == NULL) {
		printf ("FAILED31\n");
		goto out;
	}
	if (g_slist_length (s) != 2) {
		printf ("FAILED42\n");
		goto out;
	}
	if (s == NULL || strcmp (s->data, "foostrlist2") != 0) {
		printf ("FAILED43\n");
		goto out;
	}
	s = s->next;
	if (s == NULL || strcmp (s->data, "foostrlist1") != 0) {
		printf ("FAILED44\n");
		goto out;
	}

	/* this add will succeed and it should change the list */
	if (!hal_device_property_strlist_add (d, "test.strlist", "foostrlist3")) {
		printf ("FAILED50\n");
		goto out;
	}
	if ((s = hal_device_property_get_strlist (d, "test.strlist")) == NULL) {
		printf ("FAILED51\n");
		goto out;
	}
	if (g_slist_length (s) != 3) {
		printf ("FAILED52\n");
		goto out;
	}
	if (s == NULL || strcmp (s->data, "foostrlist2") != 0) {
		printf ("FAILED53\n");
		goto out;
	}
	s = s->next;
	if (s == NULL || strcmp (s->data, "foostrlist1") != 0) {
		printf ("FAILED54\n");
		goto out;
	}
	s = s->next;
	if (s == NULL || strcmp (s->data, "foostrlist3") != 0) {
		printf ("FAILED55\n");
		goto out;
	}



	/* this remove will succeed and it should change the list */
	if (!hal_device_property_strlist_remove (d, "test.strlist", "foostrlist1")) {
		printf ("FAILED60\n");
		goto out;
	}
	if ((s = hal_device_property_get_strlist (d, "test.strlist")) == NULL) {
		printf ("FAILED61\n");
		goto out;
	}
	if (g_slist_length (s) != 2) {
		printf ("FAILED62\n");
		goto out;
	}
	if (s == NULL || strcmp (s->data, "foostrlist2") != 0) {
		printf ("FAILED63\n");
		goto out;
	}
	s = s->next;
	if (s == NULL || strcmp (s->data, "foostrlist3") != 0) {
		printf ("FAILED65\n");
		goto out;
	}

	/* this remove will succeed but it shouldn't change the list */
	if (!hal_device_property_strlist_remove (d, "test.strlist", "foostrlist1")) {
		printf ("FAILED70\n");
		goto out;
	}
	if ((s = hal_device_property_get_strlist (d, "test.strlist")) == NULL) {
		printf ("FAILED71\n");
		goto out;
	}
	if (g_slist_length (s) != 2) {
		printf ("FAILED72\n");
		goto out;
	}
	if (s == NULL || strcmp (s->data, "foostrlist2") != 0) {
		printf ("FAILED73\n");
		goto out;
	}
	s = s->next;
	if (s == NULL || strcmp (s->data, "foostrlist3") != 0) {
		printf ("FAILED75\n");
		goto out;
	}
	printf ("PASSED\n");

	printf ("property existence: ");
	if (!hal_device_has_property (d, "test.int") ||
	    !hal_device_has_property (d, "test.uint64") ||
	    !hal_device_has_property (d, "test.double") ||
	    !hal_device_has_property (d, "test.bool") ||
	    !hal_device_has_property (d, "test.string") ||
	    !hal_device_has_property (d, "test.string2") ||
	    !hal_device_has_property (d, "test.strlist")) {
		printf ("FAILED0\n");
		goto out;
	}
	if (hal_device_has_property (d, "moe") ||
	    hal_device_has_property (d, "joe") ||
	    hal_device_has_property (d, "woo")) {
		printf ("FAILED1\n");
		goto out;
	}
	printf ("PASSED\n");

	hal_device_set_udi (d, "/org/freedesktop/Hal/devices/testobj1");
	hal_device_property_set_string (d, "info.udi", "/org/freedesktop/Hal/devices/testobj1");

	/* add this to the global device store */
	hal_device_store_add (hald_get_gdl (), d);

	return TRUE;
out:
	return FALSE;
}

static gboolean check_libhal (const char *server_addr);



static DBusHandlerResult
server_filter_function (DBusConnection * connection,
			DBusMessage * message, void *user_data)
{
    printf ("server_filter_function: obj_path=%s interface=%s method=%s destination=%s", 
	    dbus_message_get_path (message), 
	    dbus_message_get_interface (message),
	    dbus_message_get_member (message),
	    dbus_message_get_destination (message));
}

static DBusHandlerResult 
server_message_handler (DBusConnection *connection, 
			DBusMessage *message, 
			void *user_data)
{
	printf ("destination=%s obj_path=%s interface=%s method=%s\n", 
		dbus_message_get_destination (message), 
		dbus_message_get_path (message), 
		dbus_message_get_interface (message),
		dbus_message_get_member (message));

	/* cheat, and handle AddMatch since libhal will try that */
	if (dbus_message_is_method_call (message, "org.freedesktop.DBus", "AddMatch")) {
		DBusMessage *reply;
		
		reply = dbus_message_new_error (message, "org.freedesktop.Hal.Error",
						"Not handled in HAL testing mode");
		if (reply == NULL)
			DIE (("No memory"));
		if (!dbus_connection_send (connection, reply, NULL))
			DIE (("No memory"));
		dbus_message_unref (reply);
		return DBUS_HANDLER_RESULT_HANDLED;
	}

	return hald_dbus_filter_function (connection, message, user_data);
}

DBusHandlerResult 
osspec_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data)
{
	return DBUS_HANDLER_RESULT_HANDLED;
}

static void
server_unregister_handler (DBusConnection *connection, void *user_data)
{
	printf ("unregistered\n");
}

static void
server_handle_connection (DBusServer *server,
			  DBusConnection *new_connection,
			  void *data)
{
	DBusObjectPathVTable vtable = { &server_unregister_handler, 
					&server_message_handler, 
					NULL, NULL, NULL, NULL};

	printf ("%d: Got a connection\n", getpid ());
	printf ("dbus_connection_get_is_connected = %d\n", dbus_connection_get_is_connected (new_connection));

	/*dbus_connection_add_filter (new_connection, server_filter_function, NULL, NULL);*/

	dbus_connection_register_fallback (new_connection, 
					   "/org/freedesktop",
					   &vtable,
					   NULL);
	dbus_connection_ref (new_connection);
	dbus_connection_setup_with_g_main (new_connection, NULL);
}


int
main (int argc, char *argv[])
{
	int num_tests_failed;
	DBusServer *server;
	DBusError error;
	GMainLoop *loop;

	num_tests_failed = 0;

	g_type_init ();

	loop = g_main_loop_new (NULL, FALSE);

	printf ("=============================\n");

	/* setup a server listening on a socket so we can do point to point connections 
	 * for testing libhal
	 */
	dbus_error_init (&error);
	if ((server = dbus_server_listen ("unix:tmpdir=hald-test", &error)) == NULL) { 
		printf ("Cannot create D-BUS server\n");
		num_tests_failed++;
		goto out;
	}
	printf ("server is listening at %s\n", dbus_server_get_address (server));
	dbus_server_setup_with_g_main (server, NULL);

	dbus_server_set_new_connection_function (server, server_handle_connection, NULL, NULL);

	if (!check_properties ())
		num_tests_failed++;
/*
	if (!check_libhal (dbus_server_get_address (server)))
		num_tests_failed++;
*/
	printf ("=============================\n");

	printf ("Total number of tests failed: %d\n", num_tests_failed);

/*
	g_main_loop_run (loop);
*/

out:
	return num_tests_failed;
}

--- NEW FILE: hald_test_libhal.c ---
/***************************************************************************
 * CVSID: $Id: hald_test_libhal.c,v 1.1 2005/01/31 20:06:39 david Exp $
 *
 * hald_test_libhal.c : Unit tests for libhal
 *
 * Copyright (C) 2005 David Zeuthen, <david at fubar.dk>
 *
 * 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 <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/prctl.h>
#include <sys/capability.h>
#include <grp.h>
#include <syslog.h>

#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>

#include "libhal/libhal.h"


/* TODO: All this needs work */

gboolean
check_libhal (const char *server_addr)
{
	pid_t child_pid;

	child_pid = fork ();
	if (child_pid == -1) {
		printf ("Cannot fork\n");
		exit (1);
	} else if (child_pid == 0) {
		DBusError error;
		DBusConnection *conn;
		LibHalContext *ctx;

		printf ("server address='%s'\n", server_addr);

		dbus_error_init (&error);
		if ((conn = dbus_connection_open (server_addr, &error)) == NULL) {
			printf ("Error connecting to server: %s\n", error.message);
			/* TODO: handle */
		}

		dbus_connection_setup_with_g_main (conn, NULL);

		if ((ctx = libhal_ctx_new ()) == NULL) {
			printf ("Error getting libhal context\n");
			/* TODO: handle */
		}

		libhal_ctx_set_dbus_connection (ctx, conn);
		libhal_ctx_init (ctx, &error);
		printf ("got %s\n", libhal_device_get_property_string (ctx, "/org/freedesktop/Hal/devices/testobj1", "test.string", &error));
		libhal_device_print (ctx, "/org/freedesktop/Hal/devices/testobj1", &error);

	} else {
		printf ("child pid=%d\n", child_pid);
	}
	return TRUE;
}

Index: property.c
===================================================================
RCS file: /cvs/hal/hal/hald/property.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- property.c	2 Sep 2004 21:45:49 -0000	1.8
+++ property.c	31 Jan 2005 20:06:39 -0000	1.9
@@ -28,6 +28,7 @@
 #  include <config.h>
 #endif
 
+#include <string.h>
 #include <glib.h>
 
 #include "logger.h"
@@ -43,6 +44,7 @@
  		dbus_uint64_t uint64_value;
 		dbus_bool_t bool_value;
 		double double_value;
+		GSList *strlist_value;
 	};
 	gboolean readonly;
 	gboolean persistence;
@@ -52,10 +54,18 @@
 void
 hal_property_free (HalProperty *prop)
 {
+
 	g_free (prop->key);
 
-	if (prop->type == DBUS_TYPE_STRING)
+	if (prop->type == HAL_PROPERTY_TYPE_STRING) {
 		g_free (prop->str_value);
+	} else if (prop->type == HAL_PROPERTY_TYPE_STRLIST) {
+		GSList *i;
+		for (i = prop->strlist_value; i != NULL; i = g_slist_next (i)) {
+			g_free (i->data);
+		}
+		g_slist_free (prop->strlist_value);
+	}
 
 	g_free (prop);
 }
@@ -69,7 +79,7 @@
 
 	prop = g_new0 (HalProperty, 1);
 
-	prop->type = DBUS_TYPE_STRING;
+	prop->type = HAL_PROPERTY_TYPE_STRING;
 	prop->key = g_strdup (key);
 	prop->str_value = g_strdup (value);
 
@@ -94,7 +104,7 @@
 
 	prop = g_new0 (HalProperty, 1);
 
-	prop->type = DBUS_TYPE_INT32;
+	prop->type = HAL_PROPERTY_TYPE_INT32;
 	prop->key = g_strdup (key);
 	prop->int_value = value;
 
@@ -108,7 +118,7 @@
 
 	prop = g_new0 (HalProperty, 1);
 
-	prop->type = DBUS_TYPE_UINT64;
+	prop->type = HAL_PROPERTY_TYPE_UINT64;
 	prop->key = g_strdup (key);
 	prop->uint64_value = value;
 
@@ -122,7 +132,7 @@
 
 	prop = g_new0 (HalProperty, 1);
 
-	prop->type = DBUS_TYPE_BOOLEAN;
+	prop->type = HAL_PROPERTY_TYPE_BOOLEAN;
 	prop->key = g_strdup (key);
 	prop->bool_value = value;
 
@@ -136,7 +146,7 @@
 
 	prop = g_new0 (HalProperty, 1);
 
-	prop->type = DBUS_TYPE_DOUBLE;
+	prop->type = HAL_PROPERTY_TYPE_DOUBLE;
 	prop->key = g_strdup (key);
 	prop->double_value = value;
 
@@ -154,7 +164,7 @@
 int
 hal_property_get_type (HalProperty *prop)
 {
-	g_return_val_if_fail (prop != NULL, DBUS_TYPE_INVALID);
+	g_return_val_if_fail (prop != NULL, HAL_PROPERTY_TYPE_NIL);
 
 	return prop->type;
 }
@@ -163,7 +173,7 @@
 hal_property_get_string (HalProperty *prop)
 {
 	g_return_val_if_fail (prop != NULL, NULL);
-	g_return_val_if_fail (prop->type == DBUS_TYPE_STRING, NULL);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRING, NULL);
 
 	return prop->str_value;
 }
@@ -172,7 +182,7 @@
 hal_property_get_int (HalProperty *prop)
 {
 	g_return_val_if_fail (prop != NULL, -1);
-	g_return_val_if_fail (prop->type == DBUS_TYPE_INT32, -1);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_INT32, -1);
 
 	return prop->int_value;
 }
@@ -181,7 +191,7 @@
 hal_property_get_uint64 (HalProperty *prop)
 {
 	g_return_val_if_fail (prop != NULL, -1);
-	g_return_val_if_fail (prop->type == DBUS_TYPE_UINT64, -1);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_UINT64, -1);
 
 	return prop->uint64_value;
 }
@@ -190,7 +200,7 @@
 hal_property_get_bool (HalProperty *prop)
 {
 	g_return_val_if_fail (prop != NULL, FALSE);
-	g_return_val_if_fail (prop->type == DBUS_TYPE_BOOLEAN, FALSE);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_BOOLEAN, FALSE);
 
 	return prop->bool_value;
 }
@@ -201,16 +211,16 @@
 	g_return_val_if_fail (prop != NULL, NULL);
 
 	switch (prop->type) {
-	case DBUS_TYPE_STRING:
+	case HAL_PROPERTY_TYPE_STRING:
 		return g_strdup (prop->str_value);
-	case DBUS_TYPE_INT32:
+	case HAL_PROPERTY_TYPE_INT32:
 		return g_strdup_printf ("%d", prop->int_value);
-	case DBUS_TYPE_UINT64:
+	case HAL_PROPERTY_TYPE_UINT64:
 		return g_strdup_printf ("%lld", prop->uint64_value);
-	case DBUS_TYPE_BOOLEAN:
+	case HAL_PROPERTY_TYPE_BOOLEAN:
 		/* FIXME: Maybe use 1 and 0 here instead? */
 		return g_strdup (prop->bool_value ? "true" : "false");
-	case DBUS_TYPE_DOUBLE:
+	case HAL_PROPERTY_TYPE_DOUBLE:
 		return g_strdup_printf ("%f", prop->double_value);
 	default:
 		return NULL;
@@ -221,7 +231,7 @@
 hal_property_get_double (HalProperty *prop)
 {
 	g_return_val_if_fail (prop != NULL, -1.0);
-	g_return_val_if_fail (prop->type == DBUS_TYPE_DOUBLE, -1.0);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_DOUBLE, -1.0);
 
 	return prop->double_value;
 }
@@ -233,10 +243,10 @@
 	gboolean validated = TRUE;
 
 	g_return_if_fail (prop != NULL);
-	g_return_if_fail (prop->type == DBUS_TYPE_STRING ||
-			  prop->type == DBUS_TYPE_NIL);
+	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_STRING ||
+			  prop->type == HAL_PROPERTY_TYPE_NIL);
 
-	prop->type = DBUS_TYPE_STRING;
+	prop->type = HAL_PROPERTY_TYPE_STRING;
 	prop->str_value = g_strdup (value);
 
 	while (!g_utf8_validate (prop->str_value, -1,
@@ -255,10 +265,10 @@
 hal_property_set_int (HalProperty *prop, dbus_int32_t value)
 {
 	g_return_if_fail (prop != NULL);
-	g_return_if_fail (prop->type == DBUS_TYPE_INT32 ||
-			  prop->type == DBUS_TYPE_NIL);
+	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_INT32 ||
+			  prop->type == HAL_PROPERTY_TYPE_NIL);
 
-	prop->type = DBUS_TYPE_INT32;
+	prop->type = HAL_PROPERTY_TYPE_INT32;
 	prop->int_value = value;
 }
 
@@ -266,10 +276,10 @@
 hal_property_set_uint64 (HalProperty *prop, dbus_uint64_t value)
 {
 	g_return_if_fail (prop != NULL);
-	g_return_if_fail (prop->type == DBUS_TYPE_UINT64 ||
-			  prop->type == DBUS_TYPE_NIL);
+	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_UINT64 ||
+			  prop->type == HAL_PROPERTY_TYPE_NIL);
 
-	prop->type = DBUS_TYPE_UINT64;
+	prop->type = HAL_PROPERTY_TYPE_UINT64;
 	prop->uint64_value = value;
 }
 
@@ -277,10 +287,10 @@
 hal_property_set_bool (HalProperty *prop, dbus_bool_t value)
 {
 	g_return_if_fail (prop != NULL);
-	g_return_if_fail (prop->type == DBUS_TYPE_BOOLEAN ||
-			  prop->type == DBUS_TYPE_NIL);
+	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_BOOLEAN ||
+			  prop->type == HAL_PROPERTY_TYPE_NIL);
 
-	prop->type = DBUS_TYPE_BOOLEAN;
+	prop->type = HAL_PROPERTY_TYPE_BOOLEAN;
 	prop->bool_value = value;
 }
 
@@ -288,10 +298,10 @@
 hal_property_set_double (HalProperty *prop, double value)
 {
 	g_return_if_fail (prop != NULL);
-	g_return_if_fail (prop->type == DBUS_TYPE_DOUBLE ||
-			  prop->type == DBUS_TYPE_NIL);
+	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_DOUBLE ||
+			  prop->type == HAL_PROPERTY_TYPE_NIL);
 
-	prop->type = DBUS_TYPE_DOUBLE;
+	prop->type = HAL_PROPERTY_TYPE_DOUBLE;
 	prop->double_value = value;
 }
 
@@ -332,3 +342,104 @@
 		return -1;
 	}
 }
+
+HalProperty *
+hal_property_new_strlist (const char *key)
+{
+	HalProperty *prop;
+
+	prop = g_new0 (HalProperty, 1);
+
+	prop->type = HAL_PROPERTY_TYPE_STRLIST;
+	prop->key = g_strdup (key);
+	prop->strlist_value = NULL;
+
+	return prop;
+}
+
+GSList *
+hal_property_get_strlist (HalProperty *prop)
+{
+	g_return_val_if_fail (prop != NULL, NULL);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, NULL);
+
+	return prop->strlist_value;
+}
+
+gboolean
+hal_property_strlist_append (HalProperty *prop, const char *value)
+{
+	g_return_val_if_fail (prop != NULL, FALSE);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+	prop->strlist_value = g_slist_append (prop->strlist_value, g_strdup (value));
+
+	return TRUE;
+}
+
+gboolean
+hal_property_strlist_prepend (HalProperty *prop, const char *value)
+{
+	g_return_val_if_fail (prop != NULL, FALSE);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+	prop->strlist_value = g_slist_prepend (prop->strlist_value, g_strdup (value));
+
+	return TRUE;
+}
+
+gboolean
+hal_property_strlist_remove_elem (HalProperty *prop, guint index)
+{
+	GSList *elem;
+
+	g_return_val_if_fail (prop != NULL, FALSE);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+	if (prop->strlist_value == NULL)
+		return FALSE;
+
+	elem = g_slist_nth (prop->strlist_value, index);
+	if (elem == NULL)
+		return FALSE;
+
+	g_free (elem->data);
+	prop->strlist_value = g_slist_delete_link (prop->strlist_value, elem);
+	return TRUE;
+}
+
+
+gboolean 
+hal_property_strlist_add (HalProperty  *prop, const char *value)
+{
+	GSList *elem;
+
+	g_return_val_if_fail (prop != NULL, FALSE);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+	for (elem = prop->strlist_value; elem != NULL; elem = g_slist_next (elem)) {
+		if (strcmp (elem->data, value) == 0) {
+			return FALSE;
+		}
+	}
+
+	return hal_property_strlist_append (prop, value);
+}
+
+gboolean 
+hal_property_strlist_remove (HalProperty *prop, const char *value)
+{
+	guint i;
+	GSList *elem;
+
+	g_return_val_if_fail (prop != NULL, FALSE);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+	for (elem = prop->strlist_value, i = 0; elem != NULL; elem = g_slist_next (elem), i++) {
+		if (strcmp (elem->data, value) == 0) {
+			return hal_property_strlist_remove_elem (prop, i);
+		}
+	}
+
+	return FALSE;
+}

Index: property.h
===================================================================
RCS file: /cvs/hal/hal/hald/property.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- property.h	1 Sep 2004 17:38:58 -0000	1.5
+++ property.h	31 Jan 2005 20:06:39 -0000	1.6
@@ -31,49 +31,72 @@
 
 typedef struct _HalProperty HalProperty;
 
+#define HAL_PROPERTY_TYPE_NIL         DBUS_TYPE_NIL
+#define HAL_PROPERTY_TYPE_INT32       DBUS_TYPE_INT32
+#define HAL_PROPERTY_TYPE_UINT64      DBUS_TYPE_UINT64
+#define HAL_PROPERTY_TYPE_DOUBLE      DBUS_TYPE_DOUBLE
+#define HAL_PROPERTY_TYPE_BOOLEAN     DBUS_TYPE_BOOLEAN
+#define HAL_PROPERTY_TYPE_STRING      DBUS_TYPE_STRING
+#define HAL_PROPERTY_TYPE_STRLIST     ((int) (DBUS_TYPE_STRING<<8)+('l'))
+
 enum PropertyAttribute {
 	READONLY,
 	PERSISTENCE,
 	CALLOUT
 };
 
-void          hal_property_free          (HalProperty  *prop);
+void          hal_property_free               (HalProperty  *prop);
 
-HalProperty *hal_property_new_string     (const char   *key,
-					  const char   *value);
-HalProperty *hal_property_new_int        (const char   *key,
-					  dbus_int32_t  value);
-HalProperty *hal_property_new_uint64     (const char   *key,
-					  dbus_uint64_t value);
-HalProperty *hal_property_new_bool       (const char   *key,
-					  dbus_bool_t   value);
-HalProperty *hal_property_new_double     (const char   *key,
-					  double        value);
+HalProperty *hal_property_new_string          (const char   *key,
+					       const char   *value);
+HalProperty *hal_property_new_int             (const char   *key,
+					       dbus_int32_t  value);
+HalProperty *hal_property_new_uint64          (const char   *key,
+					       dbus_uint64_t value);
+HalProperty *hal_property_new_bool            (const char   *key,
+					       dbus_bool_t   value);
+HalProperty *hal_property_new_double          (const char   *key,
+					       double        value);
+HalProperty *hal_property_new_strlist         (const char   *key);
 
-const char   *hal_property_get_key       (HalProperty  *prop);
-int           hal_property_get_type      (HalProperty  *prop);
-char         *hal_property_to_string     (HalProperty  *prop);
+const char   *hal_property_get_key            (HalProperty  *prop);
+int           hal_property_get_type           (HalProperty  *prop);
+char         *hal_property_to_string          (HalProperty  *prop);
 
-const char   *hal_property_get_string    (HalProperty  *prop);
-dbus_int32_t  hal_property_get_int       (HalProperty  *prop);
-dbus_uint64_t hal_property_get_uint64    (HalProperty  *prop);
-dbus_bool_t   hal_property_get_bool      (HalProperty  *prop);
-double        hal_property_get_double    (HalProperty  *prop);
+const char   *hal_property_get_string         (HalProperty  *prop);
+dbus_int32_t  hal_property_get_int            (HalProperty  *prop);
+dbus_uint64_t hal_property_get_uint64         (HalProperty  *prop);
+dbus_bool_t   hal_property_get_bool           (HalProperty  *prop);
+double        hal_property_get_double         (HalProperty  *prop);
+GSList       *hal_property_get_strlist        (HalProperty  *prop);
 
-void          hal_property_set_string    (HalProperty  *prop,
-					  const char   *value);
-void          hal_property_set_int       (HalProperty  *prop,
-					  dbus_int32_t  value);
-void          hal_property_set_uint64    (HalProperty  *prop,
- 					  dbus_uint64_t value);
-void          hal_property_set_bool      (HalProperty  *prop,
-					  dbus_bool_t   value);
-void          hal_property_set_double    (HalProperty  *prop,
-					  double        value);
-void          hal_property_set_attribute (HalProperty *prop,
-					  enum PropertyAttribute attr,
-					  gboolean val);
-gboolean      hal_property_get_attribute (HalProperty *prop,
-					  enum PropertyAttribute attr);
+void          hal_property_set_string         (HalProperty  *prop,
+					       const char   *value);
+void          hal_property_set_int            (HalProperty  *prop,
+					       dbus_int32_t  value);
+void          hal_property_set_uint64         (HalProperty  *prop,
+					       dbus_uint64_t value);
+void          hal_property_set_bool           (HalProperty  *prop,
+					       dbus_bool_t   value);
+void          hal_property_set_double         (HalProperty  *prop,
+					       double        value);
+gboolean      hal_property_strlist_append     (HalProperty  *prop,
+					       const char   *value);
+gboolean      hal_property_strlist_prepend    (HalProperty  *prop,
+					       const char   *value);
+gboolean      hal_property_strlist_remove_elem (HalProperty  *prop,
+					        guint index);
+
+gboolean      hal_property_strlist_add        (HalProperty  *prop,
+					       const char *value);
+gboolean      hal_property_strlist_remove     (HalProperty  *prop,
+					       const char *value);
+
+
+void          hal_property_set_attribute      (HalProperty *prop,
+					       enum PropertyAttribute attr,
+					       gboolean val);
+gboolean      hal_property_get_attribute      (HalProperty *prop,
+					       enum PropertyAttribute attr);
 
 #endif /* PROPERTY_H */

--- pstore.c DELETED ---

--- pstore.h DELETED ---




More information about the hal-commit mailing list