2005-01-30 Havoc Pennington <hp@redhat.com>

dbus-viewer introspected and displayed the bus driver

	* dbus/dbus-object-tree.c
	(object_tree_test_iteration): add tests for a handler registered on "/"

	* dbus/dbus-object-tree.c
	(_dbus_decompose_path): fix to handle path "/" properly
	(run_decompose_tests): add tests for path decomposition

	* glib/dbus-gutils.c (_dbus_gutils_split_path): fix to handle "/"
	properly

	* glib/dbus-gobject.c (handle_introspect): fix quotes

	* test/glib/run-test.sh: support launching the bus, then running
	dbus-viewer

	* test/glib/test-service-glib.c (main): put in a trivial gobject
	subclass and register it on the connection

	* bus/driver.c (bus_driver_handle_introspect): implement
	introspection of the bus driver service

	* dbus/dbus-protocol.h: add #defines for the XML namespace,
	identifiers, doctype decl

	* bus/driver.c (bus_driver_handle_get_service_owner): handle
	attempts to get owner of DBUS_SERVICE_ORG_FREEDESKTOP_DBUS by
	returning the service unchanged.
	(bus_driver_handle_message): remove old check for reply_serial in
	method calls, now the message type deals with that
	(bus_driver_handle_message): handle NULL interface

	* glib/dbus-gproxy.c (dbus_g_proxy_get_bus_name): new function

	* glib/dbus-gloader-expat.c (description_load_from_string): allow
	-1 for len

	* tools/dbus-viewer.c: add support for introspecting a service on
	a bus

	* glib/dbus-gproxy.c (dbus_g_pending_call_ref): add
	(dbus_g_pending_call_unref): add
This commit is contained in:
Havoc Pennington 2005-01-30 05:18:44 +00:00
parent 2922b0e88b
commit 41f52c96d6
15 changed files with 667 additions and 113 deletions

View file

@ -1,3 +1,49 @@
2005-01-30 Havoc Pennington <hp@redhat.com>
dbus-viewer introspected and displayed the bus driver
* dbus/dbus-object-tree.c
(object_tree_test_iteration): add tests for a handler registered on "/"
* dbus/dbus-object-tree.c
(_dbus_decompose_path): fix to handle path "/" properly
(run_decompose_tests): add tests for path decomposition
* glib/dbus-gutils.c (_dbus_gutils_split_path): fix to handle "/"
properly
* glib/dbus-gobject.c (handle_introspect): fix quotes
* test/glib/run-test.sh: support launching the bus, then running
dbus-viewer
* test/glib/test-service-glib.c (main): put in a trivial gobject
subclass and register it on the connection
* bus/driver.c (bus_driver_handle_introspect): implement
introspection of the bus driver service
* dbus/dbus-protocol.h: add #defines for the XML namespace,
identifiers, doctype decl
* bus/driver.c (bus_driver_handle_get_service_owner): handle
attempts to get owner of DBUS_SERVICE_ORG_FREEDESKTOP_DBUS by
returning the service unchanged.
(bus_driver_handle_message): remove old check for reply_serial in
method calls, now the message type deals with that
(bus_driver_handle_message): handle NULL interface
* glib/dbus-gproxy.c (dbus_g_proxy_get_bus_name): new function
* glib/dbus-gloader-expat.c (description_load_from_string): allow
-1 for len
* tools/dbus-viewer.c: add support for introspecting a service on
a bus
* glib/dbus-gproxy.c (dbus_g_pending_call_ref): add
(dbus_g_pending_call_unref): add
2005-01-29 Havoc Pennington <hp@redhat.com>
* tools/dbus-tree-view.c: add support for displaying properties.
@ -6,7 +52,7 @@
* glib/dbus-gobject.c (handle_introspect): return
org.freedesktop.Properties and org.freedesktop.Introspectable
interfaces when we are introspected.
interfaces when we are introspected.
* doc/dbus-specification.xml: allow empty interface name when
Get/Set a property

View file

@ -792,24 +792,34 @@ bus_driver_handle_get_service_owner (DBusConnection *connection,
_dbus_string_init_const (&str, text);
service = bus_registry_lookup (registry, &str);
if (service == NULL)
if (service == NULL &&
_dbus_string_equal_c_str (&str, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
{
/* ORG_FREEDESKTOP_DBUS owns itself */
base_name = DBUS_SERVICE_ORG_FREEDESKTOP_DBUS;
}
else if (service == NULL)
{
dbus_set_error (error,
DBUS_ERROR_NAME_HAS_NO_OWNER,
"Could not get owner of name '%s': no such name", text);
DBUS_ERROR_NAME_HAS_NO_OWNER,
"Could not get owner of name '%s': no such name", text);
goto failed;
}
else
{
base_name = bus_connection_get_name (bus_service_get_primary_owner (service));
if (base_name == NULL)
{
/* FIXME - how is this error possible? */
dbus_set_error (error,
DBUS_ERROR_FAILED,
"Could not determine unique name for '%s'", text);
goto failed;
}
_dbus_assert (*base_name == ':');
}
base_name = bus_connection_get_name (bus_service_get_primary_owner (service));
if (base_name == NULL)
{
/* FIXME - how is this error possible? */
dbus_set_error (error,
DBUS_ERROR_FAILED,
"Could not determine unique name for '%s'", text);
goto failed;
}
_dbus_assert (*base_name == ':');
_dbus_assert (base_name != NULL);
reply = dbus_message_new_method_return (message);
if (reply == NULL)
@ -1040,13 +1050,89 @@ struct
{ "ReloadConfig", bus_driver_handle_reload_config }
};
static dbus_bool_t
bus_driver_handle_introspect (DBusConnection *connection,
BusTransaction *transaction,
DBusMessage *message,
DBusError *error)
{
DBusString xml;
DBusMessage *reply;
const char *v_STRING;
_dbus_verbose ("Introspect() on bus driver\n");
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
reply = NULL;
if (! dbus_message_get_args (message, error,
DBUS_TYPE_INVALID))
{
_DBUS_ASSERT_ERROR_IS_SET (error);
return FALSE;
}
if (!_dbus_string_init (&xml))
{
BUS_SET_OOM (error);
return FALSE;
}
if (!_dbus_string_append (&xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
goto oom;
if (!_dbus_string_append (&xml, "<node>\n"))
goto oom;
if (!_dbus_string_append (&xml, " <interface name=\"org.freedesktop.Introspectable\">\n"))
goto oom;
if (!_dbus_string_append (&xml, " <method name=\"Introspect\">\n"))
goto oom;
if (!_dbus_string_append (&xml, " <arg name=\"data\" direction=\"out\" type=\"string\"/>\n"))
goto oom;
if (!_dbus_string_append (&xml, " </method>\n"))
goto oom;
if (!_dbus_string_append (&xml, " </interface>\n"))
goto oom;
if (!_dbus_string_append (&xml, "</node>\n"))
goto oom;
reply = dbus_message_new_method_return (message);
if (reply == NULL)
goto oom;
v_STRING = _dbus_string_get_const_data (&xml);
if (! dbus_message_append_args (reply,
DBUS_TYPE_STRING, &v_STRING,
DBUS_TYPE_INVALID))
goto oom;
if (! bus_transaction_send_from_driver (transaction, connection, reply))
goto oom;
dbus_message_unref (reply);
_dbus_string_free (&xml);
return TRUE;
oom:
BUS_SET_OOM (error);
if (reply)
dbus_message_unref (reply);
_dbus_string_free (&xml);
return FALSE;
}
dbus_bool_t
bus_driver_handle_message (DBusConnection *connection,
BusTransaction *transaction,
DBusMessage *message,
DBusError *error)
{
const char *name, *sender;
const char *name, *sender, *interface;
int i;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@ -1057,17 +1143,25 @@ bus_driver_handle_message (DBusConnection *connection,
return TRUE; /* we just ignore this */
}
_dbus_assert (dbus_message_get_interface (message) != NULL);
if (dbus_message_is_method_call (message,
DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE,
"Introspect"))
return bus_driver_handle_introspect (connection, transaction, message, error);
interface = dbus_message_get_interface (message);
if (interface == NULL)
interface = DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS;
_dbus_assert (dbus_message_get_member (message) != NULL);
name = dbus_message_get_member (message);
sender = dbus_message_get_sender (message);
if (strcmp (dbus_message_get_interface (message),
if (strcmp (interface,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS) != 0)
{
_dbus_verbose ("Driver got message to unknown interface \"%s\"\n",
dbus_message_get_interface (message));
interface);
goto unknown;
}
@ -1076,12 +1170,6 @@ bus_driver_handle_message (DBusConnection *connection,
/* security checks should have kept this from getting here */
_dbus_assert (sender != NULL || strcmp (name, "Hello") == 0);
if (dbus_message_get_reply_serial (message) != 0)
{
_dbus_verbose ("Client sent a reply to the bus driver, ignoring it\n");
return TRUE;
}
i = 0;
while (i < _DBUS_N_ELEMENTS (message_handlers))

View file

@ -145,7 +145,10 @@ void dbus_g_proxy_call_no_reply (DBusGProxy *proxy,
const char *method,
int first_arg_type,
...);
const char* dbus_g_proxy_get_bus_name (DBusGProxy *proxy);
DBusGPendingCall* dbus_g_pending_call_ref (DBusGPendingCall *call);
void dbus_g_pending_call_unref (DBusGPendingCall *call);
#undef DBUS_INSIDE_DBUS_GLIB_H

View file

@ -573,7 +573,7 @@ _dbus_validate_path (const DBusString *str,
_dbus_assert (start >= 0);
_dbus_assert (len >= 0);
_dbus_assert (start <= _dbus_string_get_length (str));
if (len > _dbus_string_get_length (str) - start)
return FALSE;

View file

@ -630,6 +630,9 @@ handle_default_introspect_unlocked (DBusObjectTree *tree,
if (!_dbus_object_tree_list_registered_unlocked (tree, path, &children))
goto out;
if (!_dbus_string_append (&xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
goto out;
if (!_dbus_string_append (&xml, "<node>\n"))
goto out;
@ -945,6 +948,7 @@ _dbus_object_tree_list_registered_and_unlock (DBusObjectTree *tree,
/**
* Decompose an object path. A path of just "/" is
* represented as an empty vector of strings.
* The path need not be nul terminated.
*
* @param data the path data
* @param len the length of the path string
@ -962,19 +966,22 @@ _dbus_decompose_path (const char* data,
int i, j, comp;
_dbus_assert (data != NULL);
#if VERBOSE_DECOMPOSE
_dbus_verbose ("Decomposing path \"%s\"\n",
data);
#endif
n_components = 0;
i = 0;
while (i < len)
if (len > 1) /* if path is not just "/" */
{
if (data[i] == '/')
n_components += 1;
++i;
i = 0;
while (i < len)
{
if (data[i] == '/')
n_components += 1;
++i;
}
}
retval = dbus_new0 (char*, n_components + 1);
@ -983,9 +990,14 @@ _dbus_decompose_path (const char* data,
return FALSE;
comp = 0;
i = 0;
while (i < len)
if (n_components == 0)
i = 1;
else
i = 0;
while (comp < n_components)
{
_dbus_assert (i < len);
if (data[i] == '/')
++i;
j = i;
@ -1037,22 +1049,31 @@ static char*
flatten_path (const char **path)
{
DBusString str;
int i;
char *s;
if (!_dbus_string_init (&str))
return NULL;
i = 0;
while (path[i])
if (path[0] == NULL)
{
if (!_dbus_string_append_byte (&str, '/'))
goto nomem;
if (!_dbus_string_append (&str, path[i]))
goto nomem;
++i;
}
else
{
int i;
i = 0;
while (path[i])
{
if (!_dbus_string_append_byte (&str, '/'))
goto nomem;
if (!_dbus_string_append (&str, path[i]))
goto nomem;
++i;
}
}
if (!_dbus_string_steal_data (&str, &s))
@ -1191,7 +1212,7 @@ do_register (DBusObjectTree *tree,
{
DBusObjectPathVTable vtable = { test_unregister_function,
test_message_function, NULL };
tree_test_data[i].message_handled = FALSE;
tree_test_data[i].handler_unregistered = FALSE;
tree_test_data[i].handler_fallback = fallback;
@ -1278,17 +1299,82 @@ do_test_dispatch (DBusObjectTree *tree,
}
static size_t
string_array_length (char **array)
string_array_length (const char **array)
{
size_t i;
for (i = 0; array[i]; i++) ;
return i;
}
typedef struct
{
const char *path;
const char *result[20];
} DecomposePathTest;
static DecomposePathTest decompose_tests[] = {
{ "/foo", { "foo", NULL } },
{ "/foo/bar", { "foo", "bar", NULL } },
{ "/", { NULL } },
{ "/a/b", { "a", "b", NULL } },
{ "/a/b/c", { "a", "b", "c", NULL } },
{ "/a/b/c/d", { "a", "b", "c", "d", NULL } },
{ "/foo/bar/q", { "foo", "bar", "q", NULL } },
{ "/foo/bar/this/is/longer", { "foo", "bar", "this", "is", "longer", NULL } }
};
static dbus_bool_t
run_decompose_tests (void)
{
int i;
i = 0;
while (i < _DBUS_N_ELEMENTS (decompose_tests))
{
char **result;
int result_len;
int expected_len;
if (!_dbus_decompose_path (decompose_tests[i].path,
strlen (decompose_tests[i].path),
&result, &result_len))
return FALSE;
expected_len = string_array_length (decompose_tests[i].result);
if (result_len != (int) string_array_length ((const char**)result) ||
expected_len != result_len ||
path_contains (decompose_tests[i].result,
(const char**) result) != STR_EQUAL)
{
int real_len = string_array_length ((const char**)result);
_dbus_warn ("Expected decompose of %s to have len %d, returned %d, appears to have %d\n",
decompose_tests[i].path, expected_len, result_len,
real_len);
_dbus_warn ("Decompose resulted in elements: { ");
i = 0;
while (i < real_len)
{
_dbus_warn ("\"%s\"%s", result[i],
(i + 1) == real_len ? "" : ", ");
++i;
}
_dbus_warn ("}\n");
_dbus_assert_not_reached ("path decompose failed\n");
}
dbus_free_string_array (result);
++i;
}
return TRUE;
}
static dbus_bool_t
object_tree_test_iteration (void *data)
{
const char *path0[] = { NULL };
const char *path1[] = { "foo", NULL };
const char *path2[] = { "foo", "bar", NULL };
const char *path3[] = { "foo", "bar", "baz", NULL };
@ -1298,19 +1384,46 @@ object_tree_test_iteration (void *data)
const char *path7[] = { "blah", "boof", "this", "is", "really", "long", NULL };
const char *path8[] = { "childless", NULL };
DBusObjectTree *tree;
TreeTestData tree_test_data[8];
TreeTestData tree_test_data[9];
int i;
dbus_bool_t exact_match;
if (!run_decompose_tests ())
return FALSE;
tree = NULL;
tree = _dbus_object_tree_new (NULL);
if (tree == NULL)
goto out;
if (!do_register (tree, path1, TRUE, 0, tree_test_data))
if (!do_register (tree, path0, TRUE, 0, tree_test_data))
goto out;
_dbus_assert (find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (!find_subtree (tree, path3, NULL));
_dbus_assert (!find_subtree (tree, path4, NULL));
_dbus_assert (!find_subtree (tree, path5, NULL));
_dbus_assert (!find_subtree (tree, path6, NULL));
_dbus_assert (!find_subtree (tree, path7, NULL));
_dbus_assert (!find_subtree (tree, path8, NULL));
_dbus_assert (find_handler (tree, path0, &exact_match) && exact_match);
_dbus_assert (find_handler (tree, path1, &exact_match) == tree->root && !exact_match);
_dbus_assert (find_handler (tree, path2, &exact_match) == tree->root && !exact_match);
_dbus_assert (find_handler (tree, path3, &exact_match) == tree->root && !exact_match);
_dbus_assert (find_handler (tree, path4, &exact_match) == tree->root && !exact_match);
_dbus_assert (find_handler (tree, path5, &exact_match) == tree->root && !exact_match);
_dbus_assert (find_handler (tree, path6, &exact_match) == tree->root && !exact_match);
_dbus_assert (find_handler (tree, path7, &exact_match) == tree->root && !exact_match);
_dbus_assert (find_handler (tree, path8, &exact_match) == tree->root && !exact_match);
if (!do_register (tree, path1, TRUE, 1, tree_test_data))
goto out;
_dbus_assert (find_subtree (tree, path0, NULL));
_dbus_assert (find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (!find_subtree (tree, path3, NULL));
@ -1320,6 +1433,7 @@ object_tree_test_iteration (void *data)
_dbus_assert (!find_subtree (tree, path7, NULL));
_dbus_assert (!find_subtree (tree, path8, NULL));
_dbus_assert (find_handler (tree, path0, &exact_match) && exact_match);
_dbus_assert (find_handler (tree, path1, &exact_match) && exact_match);
_dbus_assert (find_handler (tree, path2, &exact_match) && !exact_match);
_dbus_assert (find_handler (tree, path3, &exact_match) && !exact_match);
@ -1329,7 +1443,7 @@ object_tree_test_iteration (void *data)
_dbus_assert (find_handler (tree, path7, &exact_match) == tree->root && !exact_match);
_dbus_assert (find_handler (tree, path8, &exact_match) == tree->root && !exact_match);
if (!do_register (tree, path2, TRUE, 1, tree_test_data))
if (!do_register (tree, path2, TRUE, 2, tree_test_data))
goto out;
_dbus_assert (find_subtree (tree, path1, NULL));
@ -1341,9 +1455,10 @@ object_tree_test_iteration (void *data)
_dbus_assert (!find_subtree (tree, path7, NULL));
_dbus_assert (!find_subtree (tree, path8, NULL));
if (!do_register (tree, path3, TRUE, 2, tree_test_data))
if (!do_register (tree, path3, TRUE, 3, tree_test_data))
goto out;
_dbus_assert (find_subtree (tree, path0, NULL));
_dbus_assert (find_subtree (tree, path1, NULL));
_dbus_assert (find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@ -1353,9 +1468,10 @@ object_tree_test_iteration (void *data)
_dbus_assert (!find_subtree (tree, path7, NULL));
_dbus_assert (!find_subtree (tree, path8, NULL));
if (!do_register (tree, path4, TRUE, 3, tree_test_data))
if (!do_register (tree, path4, TRUE, 4, tree_test_data))
goto out;
_dbus_assert (find_subtree (tree, path0, NULL));
_dbus_assert (find_subtree (tree, path1, NULL));
_dbus_assert (find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@ -1365,9 +1481,10 @@ object_tree_test_iteration (void *data)
_dbus_assert (!find_subtree (tree, path7, NULL));
_dbus_assert (!find_subtree (tree, path8, NULL));
if (!do_register (tree, path5, TRUE, 4, tree_test_data))
if (!do_register (tree, path5, TRUE, 5, tree_test_data))
goto out;
_dbus_assert (find_subtree (tree, path0, NULL));
_dbus_assert (find_subtree (tree, path1, NULL));
_dbus_assert (find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@ -1376,7 +1493,8 @@ object_tree_test_iteration (void *data)
_dbus_assert (!find_subtree (tree, path6, NULL));
_dbus_assert (!find_subtree (tree, path7, NULL));
_dbus_assert (!find_subtree (tree, path8, NULL));
_dbus_assert (find_handler (tree, path0, &exact_match) == tree->root && exact_match);
_dbus_assert (find_handler (tree, path1, &exact_match) != tree->root && exact_match);
_dbus_assert (find_handler (tree, path2, &exact_match) != tree->root && exact_match);
_dbus_assert (find_handler (tree, path3, &exact_match) != tree->root && exact_match);
@ -1386,9 +1504,10 @@ object_tree_test_iteration (void *data)
_dbus_assert (find_handler (tree, path7, &exact_match) != tree->root && !exact_match);
_dbus_assert (find_handler (tree, path8, &exact_match) == tree->root && !exact_match);
if (!do_register (tree, path6, TRUE, 5, tree_test_data))
if (!do_register (tree, path6, TRUE, 6, tree_test_data))
goto out;
_dbus_assert (find_subtree (tree, path0, NULL));
_dbus_assert (find_subtree (tree, path1, NULL));
_dbus_assert (find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@ -1398,9 +1517,10 @@ object_tree_test_iteration (void *data)
_dbus_assert (!find_subtree (tree, path7, NULL));
_dbus_assert (!find_subtree (tree, path8, NULL));
if (!do_register (tree, path7, TRUE, 6, tree_test_data))
if (!do_register (tree, path7, TRUE, 7, tree_test_data))
goto out;
_dbus_assert (find_subtree (tree, path0, NULL));
_dbus_assert (find_subtree (tree, path1, NULL));
_dbus_assert (find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@ -1410,9 +1530,10 @@ object_tree_test_iteration (void *data)
_dbus_assert (find_subtree (tree, path7, NULL));
_dbus_assert (!find_subtree (tree, path8, NULL));
if (!do_register (tree, path8, TRUE, 7, tree_test_data))
if (!do_register (tree, path8, TRUE, 8, tree_test_data))
goto out;
_dbus_assert (find_subtree (tree, path0, NULL));
_dbus_assert (find_subtree (tree, path1, NULL));
_dbus_assert (find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@ -1421,7 +1542,8 @@ object_tree_test_iteration (void *data)
_dbus_assert (find_subtree (tree, path6, NULL));
_dbus_assert (find_subtree (tree, path7, NULL));
_dbus_assert (find_subtree (tree, path8, NULL));
_dbus_assert (find_handler (tree, path0, &exact_match) == tree->root && exact_match);
_dbus_assert (find_handler (tree, path1, &exact_match) != tree->root && exact_match);
_dbus_assert (find_handler (tree, path2, &exact_match) != tree->root && exact_match);
_dbus_assert (find_handler (tree, path3, &exact_match) != tree->root && exact_match);
@ -1441,7 +1563,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_list_registered_unlocked (tree, path1, &child_entries);
if (child_entries != NULL)
{
nb = string_array_length (child_entries);
nb = string_array_length ((const char**)child_entries);
_dbus_assert (nb == 1);
dbus_free_string_array (child_entries);
}
@ -1449,7 +1571,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_list_registered_unlocked (tree, path2, &child_entries);
if (child_entries != NULL)
{
nb = string_array_length (child_entries);
nb = string_array_length ((const char**)child_entries);
_dbus_assert (nb == 2);
dbus_free_string_array (child_entries);
}
@ -1457,7 +1579,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_list_registered_unlocked (tree, path8, &child_entries);
if (child_entries != NULL)
{
nb = string_array_length (child_entries);
nb = string_array_length ((const char**)child_entries);
_dbus_assert (nb == 0);
dbus_free_string_array (child_entries);
}
@ -1465,7 +1587,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_list_registered_unlocked (tree, root, &child_entries);
if (child_entries != NULL)
{
nb = string_array_length (child_entries);
nb = string_array_length ((const char**)child_entries);
_dbus_assert (nb == 3);
dbus_free_string_array (child_entries);
}
@ -1487,25 +1609,40 @@ object_tree_test_iteration (void *data)
if (tree == NULL)
goto out;
if (!do_register (tree, path1, TRUE, 0, tree_test_data))
if (!do_register (tree, path0, TRUE, 0, tree_test_data))
goto out;
if (!do_register (tree, path2, TRUE, 1, tree_test_data))
if (!do_register (tree, path1, TRUE, 1, tree_test_data))
goto out;
if (!do_register (tree, path3, TRUE, 2, tree_test_data))
if (!do_register (tree, path2, TRUE, 2, tree_test_data))
goto out;
if (!do_register (tree, path4, TRUE, 3, tree_test_data))
if (!do_register (tree, path3, TRUE, 3, tree_test_data))
goto out;
if (!do_register (tree, path5, TRUE, 4, tree_test_data))
if (!do_register (tree, path4, TRUE, 4, tree_test_data))
goto out;
if (!do_register (tree, path6, TRUE, 5, tree_test_data))
if (!do_register (tree, path5, TRUE, 5, tree_test_data))
goto out;
if (!do_register (tree, path7, TRUE, 6, tree_test_data))
if (!do_register (tree, path6, TRUE, 6, tree_test_data))
goto out;
if (!do_register (tree, path8, TRUE, 7, tree_test_data))
if (!do_register (tree, path7, TRUE, 7, tree_test_data))
goto out;
if (!do_register (tree, path8, TRUE, 8, tree_test_data))
goto out;
_dbus_object_tree_unregister_and_unlock (tree, path0);
_dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (find_subtree (tree, path1, NULL));
_dbus_assert (find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
_dbus_assert (find_subtree (tree, path4, NULL));
_dbus_assert (find_subtree (tree, path5, NULL));
_dbus_assert (find_subtree (tree, path6, NULL));
_dbus_assert (find_subtree (tree, path7, NULL));
_dbus_assert (find_subtree (tree, path8, NULL));
_dbus_object_tree_unregister_and_unlock (tree, path1);
_dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@ -1517,6 +1654,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_unregister_and_unlock (tree, path2);
_dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@ -1528,6 +1666,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_unregister_and_unlock (tree, path3);
_dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (!find_subtree (tree, path3, NULL));
@ -1539,6 +1678,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_unregister_and_unlock (tree, path4);
_dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (!find_subtree (tree, path3, NULL));
@ -1550,6 +1690,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_unregister_and_unlock (tree, path5);
_dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (!find_subtree (tree, path3, NULL));
@ -1561,6 +1702,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_unregister_and_unlock (tree, path6);
_dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (!find_subtree (tree, path3, NULL));
@ -1572,6 +1714,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_unregister_and_unlock (tree, path7);
_dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (!find_subtree (tree, path3, NULL));
@ -1583,6 +1726,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_unregister_and_unlock (tree, path8);
_dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (!find_subtree (tree, path3, NULL));
@ -1601,43 +1745,47 @@ object_tree_test_iteration (void *data)
}
/* Register it all again, and test dispatch */
if (!do_register (tree, path1, FALSE, 0, tree_test_data))
if (!do_register (tree, path0, TRUE, 0, tree_test_data))
goto out;
if (!do_register (tree, path2, TRUE, 1, tree_test_data))
if (!do_register (tree, path1, FALSE, 1, tree_test_data))
goto out;
if (!do_register (tree, path3, TRUE, 2, tree_test_data))
if (!do_register (tree, path2, TRUE, 2, tree_test_data))
goto out;
if (!do_register (tree, path4, TRUE, 3, tree_test_data))
if (!do_register (tree, path3, TRUE, 3, tree_test_data))
goto out;
if (!do_register (tree, path5, TRUE, 4, tree_test_data))
if (!do_register (tree, path4, TRUE, 4, tree_test_data))
goto out;
if (!do_register (tree, path6, FALSE, 5, tree_test_data))
if (!do_register (tree, path5, TRUE, 5, tree_test_data))
goto out;
if (!do_register (tree, path7, TRUE, 6, tree_test_data))
if (!do_register (tree, path6, FALSE, 6, tree_test_data))
goto out;
if (!do_register (tree, path8, TRUE, 7, tree_test_data))
if (!do_register (tree, path7, TRUE, 7, tree_test_data))
goto out;
if (!do_register (tree, path8, TRUE, 8, tree_test_data))
goto out;
#if 0
spew_tree (tree);
#endif
if (!do_test_dispatch (tree, path1, 0, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
if (!do_test_dispatch (tree, path0, 0, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
if (!do_test_dispatch (tree, path2, 1, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
if (!do_test_dispatch (tree, path1, 1, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
if (!do_test_dispatch (tree, path3, 2, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
if (!do_test_dispatch (tree, path2, 2, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
if (!do_test_dispatch (tree, path4, 3, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
if (!do_test_dispatch (tree, path3, 3, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
if (!do_test_dispatch (tree, path5, 4, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
if (!do_test_dispatch (tree, path4, 4, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
if (!do_test_dispatch (tree, path6, 5, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
if (!do_test_dispatch (tree, path5, 5, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
if (!do_test_dispatch (tree, path7, 6, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
if (!do_test_dispatch (tree, path6, 6, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
if (!do_test_dispatch (tree, path8, 7, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
if (!do_test_dispatch (tree, path7, 7, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
if (!do_test_dispatch (tree, path8, 8, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
out:

View file

@ -272,6 +272,12 @@ extern "C" {
#define DBUS_ERROR_SPAWN_FAILED "org.freedesktop.DBus.Error.Spawn.Failed"
#define DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN "org.freedesktop.DBus.Error.UnixProcessIdUnknown"
#define DBUS_INTROSPECT_1_0_XML_NAMESPACE "http://www.freedesktop.org/standards/dbus"
#define DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
#define DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"
#define DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<!DOCTYPE node PUBLIC \""DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER"\"\n\""DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER"\">\n"
#ifdef __cplusplus
}
#endif

View file

@ -303,6 +303,20 @@ node_info_add_node (NodeInfo *info,
info->nodes = g_slist_append (info->nodes, node);
}
void
node_info_replace_node (NodeInfo *info,
NodeInfo *old_child,
NodeInfo *new_child)
{
GSList *link;
node_info_ref (new_child); /* before unref old_child in case they are the same */
link = g_slist_find (info->nodes, old_child);
g_assert (link != NULL);
node_info_unref (old_child);
link->data = new_child;
}
InterfaceInfo*
interface_info_new (const char *name)
{

View file

@ -83,6 +83,9 @@ void node_info_add_interface (NodeInfo *info,
InterfaceInfo *interface);
void node_info_add_node (NodeInfo *info,
NodeInfo *child);
void node_info_replace_node (NodeInfo *info,
NodeInfo *old_child,
NodeInfo *new_child);
InterfaceInfo* interface_info_new (const char *name);
InterfaceInfo* interface_info_ref (InterfaceInfo *info);
void interface_info_unref (InterfaceInfo *info);

View file

@ -23,6 +23,7 @@
#include "dbus-gparser.h"
#include <expat.h>
#include <string.h>
static void*
expat_g_malloc (size_t sz)
@ -192,6 +193,9 @@ description_load_from_string (const char *str,
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
if (len < 0)
len = strlen (str);
expat = NULL;
context.parser = NULL;
context.error = error;

View file

@ -289,26 +289,28 @@ handle_introspect (DBusConnection *connection,
xml = g_string_new (NULL);
g_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE);
g_string_append (xml, "<node>\n");
/* We are introspectable, though I guess that was pretty obvious */
g_string_append (xml, " <interface name=\"org.freedesktop.Introspectable\">\n");
g_string_append (xml, " <method name=\"Introspect\">\n");
g_string_append (xml, " <arg name=\"data\" direction=\"out\" type=\"string\"\"/>\n");
g_string_append (xml, " <arg name=\"data\" direction=\"out\" type=\"string\"/>\n");
g_string_append (xml, " </method>\n");
g_string_append (xml, " </interface>\n");
/* We support get/set properties */
g_string_append (xml, " <interface name=\"org.freedesktop.Properties\">\n");
g_string_append (xml, " <method name=\"Get\">\n");
g_string_append (xml, " <arg name=\"interface\" direction=\"in\" type=\"string\"\"/>\n");
g_string_append (xml, " <arg name=\"propname\" direction=\"in\" type=\"string\"\"/>\n");
g_string_append (xml, " <arg name=\"value\" direction=\"out\" type=\"variant\"\"/>\n");
g_string_append (xml, " <arg name=\"interface\" direction=\"in\" type=\"string\"/>\n");
g_string_append (xml, " <arg name=\"propname\" direction=\"in\" type=\"string\"/>\n");
g_string_append (xml, " <arg name=\"value\" direction=\"out\" type=\"variant\"/>\n");
g_string_append (xml, " </method>\n");
g_string_append (xml, " <method name=\"Set\">\n");
g_string_append (xml, " <arg name=\"interface\" direction=\"in\" type=\"string\"\"/>\n");
g_string_append (xml, " <arg name=\"propname\" direction=\"in\" type=\"string\"\"/>\n");
g_string_append (xml, " <arg name=\"value\" direction=\"in\" type=\"variant\"\"/>\n");
g_string_append (xml, " <arg name=\"interface\" direction=\"in\" type=\"string\"/>\n");
g_string_append (xml, " <arg name=\"propname\" direction=\"in\" type=\"string\"/>\n");
g_string_append (xml, " <arg name=\"value\" direction=\"in\" type=\"variant\"/>\n");
g_string_append (xml, " </method>\n");
g_string_append (xml, " </interface>\n");

View file

@ -1032,11 +1032,30 @@ dbus_g_proxy_new_for_peer (DBusGConnection *connection,
g_return_val_if_fail (interface_name != NULL, NULL);
proxy = dbus_g_proxy_new (connection, NULL,
path_name, interface_name);
path_name, interface_name);
return proxy;
}
/**
* Gets the bus name a proxy is bound to (may be #NULL in some cases).
* If you created the proxy with dbus_g_proxy_new_for_name(), then
* the name you passed to that will be returned.
* If you created it with dbus_g_proxy_new_for_name_owner(), then the
* unique connection name will be returned. If you created it
* with dbus_g_proxy_new_for_peer() then #NULL will be returned.
*
* @param proxy the proxy
* @returns the bus name the proxy sends messages to
*/
const char*
dbus_g_proxy_get_bus_name (DBusGProxy *proxy)
{
g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), NULL);
return proxy->name;
}
/**
* Invokes a method on a remote interface. This function does not
* block; instead it returns an opaque #DBusPendingCall object that
@ -1113,23 +1132,28 @@ dbus_g_proxy_begin_call (DBusGProxy *proxy,
*
* Otherwise, the "out" parameters and return value of the
* method are stored in the provided varargs list.
* The list should be terminated with DBUS_TYPE_INVALID.
* The list should be terminated with #DBUS_TYPE_INVALID.
*
* This function doesn't affect the reference count of the
* #DBusPendingCall, the caller of dbus_g_proxy_begin_call() still owns
* a reference.
*
* @todo this should be changed to make a g_malloc() copy of the
* data returned probably; right now the data vanishes
* when you free the PendingCall which is sort of strange.
*
* @param proxy a proxy for a remote interface
* @param pending the pending call from dbus_g_proxy_begin_call()
* @param error return location for an error
* @param first_arg_type type of first "out" argument
* @returns #FALSE if an error is set */
* @returns #FALSE if an error is set
*/
gboolean
dbus_g_proxy_end_call (DBusGProxy *proxy,
DBusGPendingCall *pending,
GError **error,
int first_arg_type,
...)
DBusGPendingCall *pending,
GError **error,
int first_arg_type,
...)
{
DBusMessage *message;
va_list args;
@ -1222,6 +1246,30 @@ dbus_g_proxy_call_no_reply (DBusGProxy *proxy,
g_error ("Out of memory");
}
/**
* Increments refcount on a pending call.
*
* @param call the call
* @returns the same call
*/
DBusGPendingCall*
dbus_g_pending_call_ref (DBusGPendingCall *call)
{
dbus_pending_call_ref (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (call));
return call;
}
/**
* Decrements refcount on a pending call.
*
* @param call the call
*/
void
dbus_g_pending_call_unref (DBusGPendingCall *call)
{
dbus_pending_call_unref (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (call));
}
/**
* Sends a message to the interface we're proxying for. Does not
* block or wait for a reply. The message is only actually written out

View file

@ -39,19 +39,25 @@ _dbus_gutils_split_path (const char *path)
len = strlen (path);
n_components = 0;
i = 0;
while (i < len)
if (path[1] != '\0') /* if not "/" */
{
if (path[i] == '/')
n_components += 1;
++i;
i = 0;
while (i < len)
{
if (path[i] == '/')
n_components += 1;
++i;
}
}
split = g_new0 (char*, n_components + 1);
comp = 0;
i = 0;
while (i < len)
if (n_components == 0)
i = 1;
else
i = 0;
while (comp < n_components)
{
if (path[i] == '/')
++i;

View file

@ -57,12 +57,21 @@ echo "Started test bus pid $DBUS_SESSION_BUS_PID at $DBUS_SESSION_BUS_ADDRESS"
export DBUS_TEST_GLIB_RUN_TEST_SCRIPT=1
if test x$MODE = xprofile ; then
echo "profiling type $PROFILE_TYPE"
sleep 2 ## this lets the bus get started so its startup time doesn't affect the profile too much
if test x$PROFILE_TYPE = x ; then
PROFILE_TYPE=all
fi
libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/glib/test-profile $PROFILE_TYPE || die "test-profile failed"
elif test x$MODE = xviewer ; then
echo "Launching dbus-viewer"
ARGS=
if test x$DEBUG = x ; then
ARGS="--services org.freedesktop.DBus"
fi
libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/tools/dbus-viewer $ARGS || die "could not run dbus-viewer"
else
echo "running test-dbus-glib"
libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/glib/test-dbus-glib || die "test-dbus-glib failed"
fi

View file

@ -4,6 +4,43 @@
#include <stdlib.h>
#include <string.h>
typedef struct MyObject MyObject;
typedef struct MyObjectClass MyObjectClass;
GType my_object_get_type (void);
struct MyObject
{
GObject parent;
};
struct MyObjectClass
{
GObjectClass parent;
};
#define MY_TYPE_OBJECT (my_object_get_type ())
#define MY_OBJECT_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MY_TYPE_OBJECT, MyObject))
#define MY_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MY_TYPE_OBJECT, MyObjectClass))
#define MY_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MY_TYPE_OBJECT))
#define MY_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MY_TYPE_OBJECT))
#define MY_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MY_TYPE_OBJECT, MyObjectClass))
G_DEFINE_TYPE(MyObject, my_object, G_TYPE_OBJECT)
static void
my_object_init (MyObject *obj)
{
}
static void
my_object_class_init (MyObjectClass *obj_class)
{
}
static GMainLoop *loop;
int
@ -11,6 +48,7 @@ main (int argc, char **argv)
{
DBusGConnection *connection;
GError *error;
GObject *obj;
g_type_init ();
@ -27,7 +65,15 @@ main (int argc, char **argv)
exit (1);
}
obj = g_object_new (MY_TYPE_OBJECT, NULL);
dbus_g_connection_register_g_object (connection,
"/org/freedesktop/my_test_object",
obj);
g_print ("GLib test service entering main loop\n");
g_main_loop_run (loop);
g_print ("Successfully completed %s\n", argv[0]);

View file

@ -29,6 +29,7 @@
#include "dbus-tree-view.h"
#include <glib/dbus-gparser.h>
#include <glib/dbus-gutils.h>
#include <dbus/dbus-glib.h>
#include <libintl.h>
#define _(x) dgettext (GETTEXT_PACKAGE, x)
@ -188,6 +189,133 @@ show_error_dialog (GtkWindow *transient_parent,
}
}
static gboolean
load_child_nodes (const char *service_name,
NodeInfo *parent,
GError **error)
{
DBusGConnection *connection;
GSList *tmp;
connection = dbus_g_bus_get (DBUS_BUS_SESSION, error);
if (connection == NULL)
return FALSE;
tmp = node_info_get_nodes (parent);
while (tmp != NULL)
{
DBusGProxy *proxy;
DBusGPendingCall *call;
const char *data;
NodeInfo *child;
NodeInfo *complete_child;
complete_child = NULL;
child = tmp->data;
g_assert (*service_name == ':'); /* so we don't need new_for_name_owner */
proxy = dbus_g_proxy_new_for_name (connection,
service_name,
"/",
DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE);
g_assert (proxy != NULL);
call = dbus_g_proxy_begin_call (proxy, "Introspect",
DBUS_TYPE_INVALID);
data = NULL;
if (!dbus_g_proxy_end_call (proxy, call, error, DBUS_TYPE_STRING, &data,
DBUS_TYPE_INVALID))
goto done;
complete_child = description_load_from_string (data, -1, error);
if (complete_child == NULL)
goto done;
done:
dbus_g_pending_call_unref (call);
g_object_unref (proxy);
if (complete_child == NULL)
return FALSE;
/* change complete_child's name to relative */
base_info_set_name ((BaseInfo*)complete_child,
base_info_get_name ((BaseInfo*)child));
/* Stitch in complete_child rather than child */
node_info_replace_node (parent, child, complete_child);
node_info_unref (complete_child); /* ref still held by parent */
/* Now recurse */
if (!load_child_nodes (service_name, complete_child, error))
return FALSE;
tmp = tmp->next;
}
return TRUE;
}
static NodeInfo*
load_from_service (const char *service_name,
GError **error)
{
DBusGConnection *connection;
DBusGProxy *root_proxy;
DBusGPendingCall *call;
const char *data;
NodeInfo *node;
node = NULL;
call = NULL;
connection = dbus_g_bus_get (DBUS_BUS_SESSION, error);
if (connection == NULL)
return NULL;
root_proxy = dbus_g_proxy_new_for_name_owner (connection,
service_name,
"/",
DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE,
error);
if (root_proxy == NULL)
return NULL;
call = dbus_g_proxy_begin_call (root_proxy, "Introspect",
DBUS_TYPE_INVALID);
data = NULL;
if (!dbus_g_proxy_end_call (root_proxy, call, error, DBUS_TYPE_STRING, &data,
DBUS_TYPE_INVALID))
goto out;
node = description_load_from_string (data, -1, error);
/* g_print ("%s\n", data); */
if (node == NULL)
goto out;
base_info_set_name ((BaseInfo*)node, "/");
if (!load_child_nodes (dbus_g_proxy_get_bus_name (root_proxy),
node, error))
{
node_info_unref (node);
node = NULL;
goto out;
}
out:
if (call)
dbus_g_pending_call_unref (call);
g_object_unref (root_proxy);
return node;
}
static void
usage (int ecode)
{
@ -214,6 +342,7 @@ main (int argc, char **argv)
GSList *files;
gboolean end_of_args;
GSList *tmp;
gboolean services;
bindtextdomain (GETTEXT_PACKAGE, DBUS_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
@ -221,6 +350,7 @@ main (int argc, char **argv)
gtk_init (&argc, &argv);
services = FALSE;
end_of_args = FALSE;
files = NULL;
prev_arg = NULL;
@ -237,6 +367,8 @@ main (int argc, char **argv)
usage (0);
else if (strcmp (arg, "--version") == 0)
version ();
else if (strcmp (arg, "--services") == 0)
services = TRUE;
else if (arg[0] == '-' &&
arg[1] == '-' &&
arg[2] == '\0')
@ -270,8 +402,12 @@ main (int argc, char **argv)
filename = tmp->data;
error = NULL;
node = description_load_from_file (filename,
&error);
if (services)
node = load_from_service (filename, &error);
else
node = description_load_from_file (filename,
&error);
if (node == NULL)
{
g_assert (error != NULL);
@ -313,8 +449,3 @@ main (int argc, char **argv)
return 0;
}