/*
 *
 *  D-Bus helper library
 *
 *  Copyright (C) 2004-2011  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <string.h>

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

#include "gdbus.h"

#define info(fmt...)
#define error(fmt...)
#define debug(fmt...)

#define DBUS_INTERFACE_OBJECT_MANAGER "org.freedesktop.DBus.ObjectManager"

#ifndef DBUS_ERROR_UNKNOWN_PROPERTY
#define DBUS_ERROR_UNKNOWN_PROPERTY "org.freedesktop.DBus.Error.UnknownProperty"
#endif

#ifndef DBUS_ERROR_PROPERTY_READ_ONLY
#define DBUS_ERROR_PROPERTY_READ_ONLY "org.freedesktop.DBus.Error.PropertyReadOnly"
#endif

struct generic_data {
	unsigned int refcount;
	DBusConnection *conn;
	char *path;
	GSList *interfaces;
	GSList *objects;
	GSList *added;
	GSList *removed;
	guint process_id;
	gboolean pending_prop;
	char *introspect;
	struct generic_data *parent;
};

struct interface_data {
	char *name;
	const GDBusMethodTable *methods;
	const GDBusSignalTable *signals;
	const GDBusPropertyTable *properties;
	GSList *pending_prop;
	void *user_data;
	GDBusDestroyFunction destroy;
};

struct security_data {
	GDBusPendingReply pending;
	DBusMessage *message;
	const GDBusMethodTable *method;
	void *iface_user_data;
};

struct property_data {
	DBusConnection *conn;
	GDBusPendingPropertySet id;
	DBusMessage *message;
};

static int global_flags = 0;
static struct generic_data *root;
static GSList *pending = NULL;

static gboolean process_changes(gpointer user_data);
static void process_properties_from_interface(struct generic_data *data,
						struct interface_data *iface);
static void process_property_changes(struct generic_data *data);

static void print_arguments(GString *gstr, const GDBusArgInfo *args,
						const char *direction)
{
	for (; args && args->name; args++) {
		g_string_append_printf(gstr,
					"<arg name=\"%s\" type=\"%s\"",
					args->name, args->signature);

		if (direction)
			g_string_append_printf(gstr,
					" direction=\"%s\"/>\n", direction);
		else
			g_string_append_printf(gstr, "/>\n");

	}
}

#define G_DBUS_ANNOTATE(name_, value_)				\
	"<annotation name=\"org.freedesktop.DBus." name_ "\" "	\
	"value=\"" value_ "\"/>"

#define G_DBUS_ANNOTATE_DEPRECATED \
	G_DBUS_ANNOTATE("Deprecated", "true")

#define G_DBUS_ANNOTATE_NOREPLY \
	G_DBUS_ANNOTATE("Method.NoReply", "true")

static gboolean check_experimental(int flags, int flag)
{
	if (!(flags & flag))
		return FALSE;

	return !(global_flags & G_DBUS_FLAG_ENABLE_EXPERIMENTAL);
}

static void generate_interface_xml(GString *gstr, struct interface_data *iface)
{
	const GDBusMethodTable *method;
	const GDBusSignalTable *signal;
	const GDBusPropertyTable *property;

	for (method = iface->methods; method && method->name; method++) {
		if (check_experimental(method->flags,
					G_DBUS_METHOD_FLAG_EXPERIMENTAL))
			continue;

		g_string_append_printf(gstr, "<method name=\"%s\">",
								method->name);
		print_arguments(gstr, method->in_args, "in");
		print_arguments(gstr, method->out_args, "out");

		if (method->flags & G_DBUS_METHOD_FLAG_DEPRECATED)
			g_string_append_printf(gstr,
						G_DBUS_ANNOTATE_DEPRECATED);

		if (method->flags & G_DBUS_METHOD_FLAG_NOREPLY)
			g_string_append_printf(gstr, G_DBUS_ANNOTATE_NOREPLY);

		g_string_append_printf(gstr, "</method>");
	}

	for (signal = iface->signals; signal && signal->name; signal++) {
		if (check_experimental(signal->flags,
					G_DBUS_SIGNAL_FLAG_EXPERIMENTAL))
			continue;

		g_string_append_printf(gstr, "<signal name=\"%s\">",
								signal->name);
		print_arguments(gstr, signal->args, NULL);

		if (signal->flags & G_DBUS_SIGNAL_FLAG_DEPRECATED)
			g_string_append_printf(gstr,
						G_DBUS_ANNOTATE_DEPRECATED);

		g_string_append_printf(gstr, "</signal>\n");
	}

	for (property = iface->properties; property && property->name;
								property++) {
		if (check_experimental(property->flags,
					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL))
			continue;

		g_string_append_printf(gstr, "<property name=\"%s\""
					" type=\"%s\" access=\"%s%s\">",
					property->name,	property->type,
					property->get ? "read" : "",
					property->set ? "write" : "");

		if (property->flags & G_DBUS_PROPERTY_FLAG_DEPRECATED)
			g_string_append_printf(gstr,
						G_DBUS_ANNOTATE_DEPRECATED);

		g_string_append_printf(gstr, "</property>");
	}
}

static void generate_introspection_xml(DBusConnection *conn,
				struct generic_data *data, const char *path)
{
	GSList *list;
	GString *gstr;
	char **children;
	int i;

	g_free(data->introspect);

	gstr = g_string_new(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE);

	g_string_append_printf(gstr, "<node>");

	for (list = data->interfaces; list; list = list->next) {
		struct interface_data *iface = list->data;

		g_string_append_printf(gstr, "<interface name=\"%s\">",
								iface->name);

		generate_interface_xml(gstr, iface);

		g_string_append_printf(gstr, "</interface>");
	}

	if (!dbus_connection_list_registered(conn, path, &children))
		goto done;

	for (i = 0; children[i]; i++)
		g_string_append_printf(gstr, "<node name=\"%s\"/>",
								children[i]);

	dbus_free_string_array(children);

done:
	g_string_append_printf(gstr, "</node>");

	data->introspect = g_string_free(gstr, FALSE);
}

static DBusMessage *introspect(DBusConnection *connection,
				DBusMessage *message, void *user_data)
{
	struct generic_data *data = user_data;
	DBusMessage *reply;

	if (data->introspect == NULL)
		generate_introspection_xml(connection, data,
						dbus_message_get_path(message));

	reply = dbus_message_new_method_return(message);
	if (reply == NULL)
		return NULL;

	dbus_message_append_args(reply, DBUS_TYPE_STRING, &data->introspect,
					DBUS_TYPE_INVALID);

	return reply;
}

static DBusHandlerResult process_message(DBusConnection *connection,
			DBusMessage *message, const GDBusMethodTable *method,
							void *iface_user_data)
{
	DBusMessage *reply;

	reply = method->function(connection, message, iface_user_data);

	if (method->flags & G_DBUS_METHOD_FLAG_NOREPLY) {
		if (reply != NULL)
			dbus_message_unref(reply);
		return DBUS_HANDLER_RESULT_HANDLED;
	}

	if (method->flags & G_DBUS_METHOD_FLAG_ASYNC) {
		if (reply == NULL)
			return DBUS_HANDLER_RESULT_HANDLED;
	}

	if (reply == NULL)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	g_dbus_send_message(connection, reply);

	return DBUS_HANDLER_RESULT_HANDLED;
}

static GDBusPendingReply next_pending = 1;
static GSList *pending_security = NULL;

static const GDBusSecurityTable *security_table = NULL;

void g_dbus_pending_success(DBusConnection *connection,
					GDBusPendingReply pending)
{
	GSList *list;

	for (list = pending_security; list; list = list->next) {
		struct security_data *secdata = list->data;

		if (secdata->pending != pending)
			continue;

		pending_security = g_slist_remove(pending_security, secdata);

		process_message(connection, secdata->message,
				secdata->method, secdata->iface_user_data);

		dbus_message_unref(secdata->message);
		g_free(secdata);
		return;
	}
}

void g_dbus_pending_error_valist(DBusConnection *connection,
				GDBusPendingReply pending, const char *name,
					const char *format, va_list args)
{
	GSList *list;

	for (list = pending_security; list; list = list->next) {
		struct security_data *secdata = list->data;

		if (secdata->pending != pending)
			continue;

		pending_security = g_slist_remove(pending_security, secdata);

		g_dbus_send_error_valist(connection, secdata->message,
							name, format, args);

		dbus_message_unref(secdata->message);
		g_free(secdata);
		return;
	}
}

void g_dbus_pending_error(DBusConnection *connection,
				GDBusPendingReply pending,
				const char *name, const char *format, ...)
{
	va_list args;

	va_start(args, format);

	g_dbus_pending_error_valist(connection, pending, name, format, args);

	va_end(args);
}

int polkit_check_authorization(DBusConnection *conn,
				const char *action, gboolean interaction,
				void (*function) (dbus_bool_t authorized,
							void *user_data),
						void *user_data, int timeout);

struct builtin_security_data {
	DBusConnection *conn;
	GDBusPendingReply pending;
};

static void builtin_security_result(dbus_bool_t authorized, void *user_data)
{
	struct builtin_security_data *data = user_data;

	if (authorized == TRUE)
		g_dbus_pending_success(data->conn, data->pending);
	else
		g_dbus_pending_error(data->conn, data->pending,
						DBUS_ERROR_AUTH_FAILED, NULL);

	g_free(data);
}

static void builtin_security_function(DBusConnection *conn,
						const char *action,
						gboolean interaction,
						GDBusPendingReply pending)
{
	struct builtin_security_data *data;

	data = g_new0(struct builtin_security_data, 1);
	data->conn = conn;
	data->pending = pending;

	if (polkit_check_authorization(conn, action, interaction,
				builtin_security_result, data, 30000) < 0)
		g_dbus_pending_error(conn, pending, NULL, NULL);
}

static gboolean check_privilege(DBusConnection *conn, DBusMessage *msg,
			const GDBusMethodTable *method, void *iface_user_data)
{
	const GDBusSecurityTable *security;

	for (security = security_table; security && security->privilege;
								security++) {
		struct security_data *secdata;
		gboolean interaction;

		if (security->privilege != method->privilege)
			continue;

		secdata = g_new(struct security_data, 1);
		secdata->pending = next_pending++;
		secdata->message = dbus_message_ref(msg);
		secdata->method = method;
		secdata->iface_user_data = iface_user_data;

		pending_security = g_slist_prepend(pending_security, secdata);

		if (security->flags & G_DBUS_SECURITY_FLAG_ALLOW_INTERACTION)
			interaction = TRUE;
		else
			interaction = FALSE;

		if (!(security->flags & G_DBUS_SECURITY_FLAG_BUILTIN) &&
							security->function)
			security->function(conn, security->action,
						interaction, secdata->pending);
		else
			builtin_security_function(conn, security->action,
						interaction, secdata->pending);

		return TRUE;
	}

	return FALSE;
}

static GDBusPendingPropertySet next_pending_property = 1;
static GSList *pending_property_set;

static struct property_data *remove_pending_property_data(
						GDBusPendingPropertySet id)
{
	struct property_data *propdata;
	GSList *l;

	for (l = pending_property_set; l != NULL; l = l->next) {
		propdata = l->data;
		if (propdata->id != id)
			continue;

		break;
	}

	if (l == NULL)
		return NULL;

	pending_property_set = g_slist_delete_link(pending_property_set, l);

	return propdata;
}

void g_dbus_pending_property_success(GDBusPendingPropertySet id)
{
	struct property_data *propdata;

	propdata = remove_pending_property_data(id);
	if (propdata == NULL)
		return;

	g_dbus_send_reply(propdata->conn, propdata->message,
							DBUS_TYPE_INVALID);
	dbus_message_unref(propdata->message);
	g_free(propdata);
}

void g_dbus_pending_property_error_valist(GDBusPendingReply id,
					const char *name, const char *format,
					va_list args)
{
	struct property_data *propdata;

	propdata = remove_pending_property_data(id);
	if (propdata == NULL)
		return;

	g_dbus_send_error_valist(propdata->conn, propdata->message, name,
								format, args);

	dbus_message_unref(propdata->message);
	g_free(propdata);
}

void g_dbus_pending_property_error(GDBusPendingReply id, const char *name,
						const char *format, ...)
{
	va_list args;

	va_start(args, format);

	g_dbus_pending_property_error_valist(id, name, format, args);

	va_end(args);
}

static void reset_parent(gpointer data, gpointer user_data)
{
	struct generic_data *child = data;
	struct generic_data *parent = user_data;

	child->parent = parent;
}

static void append_property(struct interface_data *iface,
			const GDBusPropertyTable *p, DBusMessageIter *dict)
{
	DBusMessageIter entry, value;

	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, NULL,
								&entry);
	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &p->name);
	dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT, p->type,
								&value);

	p->get(p, &value, iface->user_data);

	dbus_message_iter_close_container(&entry, &value);
	dbus_message_iter_close_container(dict, &entry);
}

static void append_properties(struct interface_data *data,
							DBusMessageIter *iter)
{
	DBusMessageIter dict;
	const GDBusPropertyTable *p;

	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
				DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
				DBUS_TYPE_STRING_AS_STRING
				DBUS_TYPE_VARIANT_AS_STRING
				DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);

	for (p = data->properties; p && p->name; p++) {
		if (check_experimental(p->flags,
					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL))
			continue;

		if (p->get == NULL)
			continue;

		if (p->exists != NULL && !p->exists(p, data->user_data))
			continue;

		append_property(data, p, &dict);
	}

	dbus_message_iter_close_container(iter, &dict);
}

static void append_interface(gpointer data, gpointer user_data)
{
	struct interface_data *iface = data;
	DBusMessageIter *array = user_data;
	DBusMessageIter entry;

	dbus_message_iter_open_container(array, DBUS_TYPE_DICT_ENTRY, NULL,
								&entry);
	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &iface->name);
	append_properties(data, &entry);
	dbus_message_iter_close_container(array, &entry);
}

static void emit_interfaces_added(struct generic_data *data)
{
	DBusMessage *signal;
	DBusMessageIter iter, array;

	if (root == NULL || data == root)
		return;

	signal = dbus_message_new_signal(root->path,
					DBUS_INTERFACE_OBJECT_MANAGER,
					"InterfacesAdded");
	if (signal == NULL)
		return;

	dbus_message_iter_init_append(signal, &iter);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
								&data->path);

	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
				DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
				DBUS_TYPE_STRING_AS_STRING
				DBUS_TYPE_ARRAY_AS_STRING
				DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
				DBUS_TYPE_STRING_AS_STRING
				DBUS_TYPE_VARIANT_AS_STRING
				DBUS_DICT_ENTRY_END_CHAR_AS_STRING
				DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array);

	g_slist_foreach(data->added, append_interface, &array);
	g_slist_free(data->added);
	data->added = NULL;

	dbus_message_iter_close_container(&iter, &array);

	/* Use dbus_connection_send to avoid recursive calls to g_dbus_flush */
	dbus_connection_send(data->conn, signal, NULL);
	dbus_message_unref(signal);
}

static struct interface_data *find_interface(GSList *interfaces,
						const char *name)
{
	GSList *list;

	if (name == NULL)
		return NULL;

	for (list = interfaces; list; list = list->next) {
		struct interface_data *iface = list->data;
		if (!strcmp(name, iface->name))
			return iface;
	}

	return NULL;
}

static gboolean g_dbus_args_have_signature(const GDBusArgInfo *args,
							DBusMessage *message)
{
	const char *sig = dbus_message_get_signature(message);
	const char *p = NULL;

	for (; args && args->signature && *sig; args++) {
		p = args->signature;

		for (; *sig && *p; sig++, p++) {
			if (*p != *sig)
				return FALSE;
		}
	}

	if (*sig || (p && *p) || (args && args->signature))
		return FALSE;

	return TRUE;
}

static void add_pending(struct generic_data *data)
{
	if (data->process_id > 0)
		return;

	data->process_id = g_idle_add(process_changes, data);

	pending = g_slist_append(pending, data);
}

static gboolean remove_interface(struct generic_data *data, const char *name)
{
	struct interface_data *iface;

	iface = find_interface(data->interfaces, name);
	if (iface == NULL)
		return FALSE;

	process_properties_from_interface(data, iface);

	data->interfaces = g_slist_remove(data->interfaces, iface);

	if (iface->destroy) {
		iface->destroy(iface->user_data);
		iface->user_data = NULL;
	}

	/*
	 * Interface being removed was just added, on the same mainloop
	 * iteration? Don't send any signal
	 */
	if (g_slist_find(data->added, iface)) {
		data->added = g_slist_remove(data->added, iface);
		g_free(iface->name);
		g_free(iface);
		return TRUE;
	}

	if (data->parent == NULL) {
		g_free(iface->name);
		g_free(iface);
		return TRUE;
	}

	data->removed = g_slist_prepend(data->removed, iface->name);
	g_free(iface);

	add_pending(data);

	return TRUE;
}

static struct generic_data *invalidate_parent_data(DBusConnection *conn,
						const char *child_path)
{
	struct generic_data *data = NULL, *child = NULL, *parent = NULL;
	char *parent_path, *slash;

	parent_path = g_strdup(child_path);
	slash = strrchr(parent_path, '/');
	if (slash == NULL)
		goto done;

	if (slash == parent_path && parent_path[1] != '\0')
		parent_path[1] = '\0';
	else
		*slash = '\0';

	if (!strlen(parent_path))
		goto done;

	if (dbus_connection_get_object_path_data(conn, parent_path,
							(void *) &data) == FALSE) {
		goto done;
	}

	parent = invalidate_parent_data(conn, parent_path);

	if (data == NULL) {
		data = parent;
		if (data == NULL)
			goto done;
	}

	g_free(data->introspect);
	data->introspect = NULL;

	if (!dbus_connection_get_object_path_data(conn, child_path,
							(void *) &child))
		goto done;

	if (child == NULL || g_slist_find(data->objects, child) != NULL)
		goto done;

	data->objects = g_slist_prepend(data->objects, child);
	child->parent = data;

done:
	g_free(parent_path);
	return data;
}

static inline const GDBusPropertyTable *find_property(const GDBusPropertyTable *properties,
							const char *name)
{
	const GDBusPropertyTable *p;

	for (p = properties; p && p->name; p++) {
		if (strcmp(name, p->name) != 0)
			continue;

		if (check_experimental(p->flags,
					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL))
			break;

		return p;
	}

	return NULL;
}

static DBusMessage *properties_get(DBusConnection *connection,
					DBusMessage *message, void *user_data)
{
	struct generic_data *data = user_data;
	struct interface_data *iface;
	const GDBusPropertyTable *property;
	const char *interface, *name;
	DBusMessageIter iter, value;
	DBusMessage *reply;

	if (!dbus_message_get_args(message, NULL,
					DBUS_TYPE_STRING, &interface,
					DBUS_TYPE_STRING, &name,
					DBUS_TYPE_INVALID))
		return NULL;

	iface = find_interface(data->interfaces, interface);
	if (iface == NULL)
		return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
				"No such interface '%s'", interface);

	property = find_property(iface->properties, name);
	if (property == NULL)
		return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
				"No such property '%s'", name);

	if (property->exists != NULL &&
			!property->exists(property, iface->user_data))
		return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
					"No such property '%s'", name);

	if (property->get == NULL)
		return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
				"Property '%s' is not readable", name);

	reply = dbus_message_new_method_return(message);
	if (reply == NULL)
		return NULL;

	dbus_message_iter_init_append(reply, &iter);
	dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
						property->type, &value);

	if (!property->get(property, &value, iface->user_data)) {
		dbus_message_unref(reply);
		return NULL;
	}

	dbus_message_iter_close_container(&iter, &value);

	return reply;
}

static DBusMessage *properties_get_all(DBusConnection *connection,
					DBusMessage *message, void *user_data)
{
	struct generic_data *data = user_data;
	struct interface_data *iface;
	const char *interface;
	DBusMessageIter iter;
	DBusMessage *reply;

	if (!dbus_message_get_args(message, NULL,
					DBUS_TYPE_STRING, &interface,
					DBUS_TYPE_INVALID))
		return NULL;

	iface = find_interface(data->interfaces, interface);
	if (iface == NULL)
		return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
					"No such interface '%s'", interface);

	reply = dbus_message_new_method_return(message);
	if (reply == NULL)
		return NULL;

	dbus_message_iter_init_append(reply, &iter);

	append_properties(iface, &iter);

	return reply;
}

static DBusMessage *properties_set(DBusConnection *connection,
					DBusMessage *message, void *user_data)
{
	struct generic_data *data = user_data;
	DBusMessageIter iter, sub;
	struct interface_data *iface;
	const GDBusPropertyTable *property;
	const char *name, *interface;
	struct property_data *propdata;
	gboolean valid_signature;
	char *signature;

	if (!dbus_message_iter_init(message, &iter))
		return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
							"No arguments given");

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
		return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
					"Invalid argument type: '%c'",
					dbus_message_iter_get_arg_type(&iter));

	dbus_message_iter_get_basic(&iter, &interface);
	dbus_message_iter_next(&iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
		return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
					"Invalid argument type: '%c'",
					dbus_message_iter_get_arg_type(&iter));

	dbus_message_iter_get_basic(&iter, &name);
	dbus_message_iter_next(&iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
		return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
					"Invalid argument type: '%c'",
					dbus_message_iter_get_arg_type(&iter));

	dbus_message_iter_recurse(&iter, &sub);

	iface = find_interface(data->interfaces, interface);
	if (iface == NULL)
		return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
					"No such interface '%s'", interface);

	property = find_property(iface->properties, name);
	if (property == NULL)
		return g_dbus_create_error(message,
						DBUS_ERROR_UNKNOWN_PROPERTY,
						"No such property '%s'", name);

	if (property->set == NULL)
		return g_dbus_create_error(message,
					DBUS_ERROR_PROPERTY_READ_ONLY,
					"Property '%s' is not writable", name);

	if (property->exists != NULL &&
			!property->exists(property, iface->user_data))
		return g_dbus_create_error(message,
						DBUS_ERROR_UNKNOWN_PROPERTY,
						"No such property '%s'", name);

	signature = dbus_message_iter_get_signature(&sub);
	valid_signature = strcmp(signature, property->type) ? FALSE : TRUE;
	dbus_free(signature);
	if (!valid_signature)
		return g_dbus_create_error(message,
					DBUS_ERROR_INVALID_SIGNATURE,
					"Invalid signature for '%s'", name);

	propdata = g_new(struct property_data, 1);
	propdata->id = next_pending_property++;
	propdata->message = dbus_message_ref(message);
	propdata->conn = connection;
	pending_property_set = g_slist_prepend(pending_property_set, propdata);

	property->set(property, &sub, propdata->id, iface->user_data);

	return NULL;
}

static const GDBusMethodTable properties_methods[] = {
	{ GDBUS_METHOD("Get",
			GDBUS_ARGS({ "interface", "s" }, { "name", "s" }),
			GDBUS_ARGS({ "value", "v" }),
			properties_get) },
	{ GDBUS_ASYNC_METHOD("Set",
			GDBUS_ARGS({ "interface", "s" }, { "name", "s" },
							{ "value", "v" }),
			NULL,
			properties_set) },
	{ GDBUS_METHOD("GetAll",
			GDBUS_ARGS({ "interface", "s" }),
			GDBUS_ARGS({ "properties", "a{sv}" }),
			properties_get_all) },
	{ }
};

static const GDBusSignalTable properties_signals[] = {
	{ GDBUS_SIGNAL("PropertiesChanged",
			GDBUS_ARGS({ "interface", "s" },
					{ "changed_properties", "a{sv}" },
					{ "invalidated_properties", "as"})) },
	{ }
};

static void append_name(gpointer data, gpointer user_data)
{
	char *name = data;
	DBusMessageIter *iter = user_data;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &name);
}

static void emit_interfaces_removed(struct generic_data *data)
{
	DBusMessage *signal;
	DBusMessageIter iter, array;

	if (root == NULL || data == root)
		return;

	signal = dbus_message_new_signal(root->path,
					DBUS_INTERFACE_OBJECT_MANAGER,
					"InterfacesRemoved");
	if (signal == NULL)
		return;

	dbus_message_iter_init_append(signal, &iter);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
								&data->path);
	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
					DBUS_TYPE_STRING_AS_STRING, &array);

	g_slist_foreach(data->removed, append_name, &array);
	g_slist_free_full(data->removed, g_free);
	data->removed = NULL;

	dbus_message_iter_close_container(&iter, &array);

	/* Use dbus_connection_send to avoid recursive calls to g_dbus_flush */
	dbus_connection_send(data->conn, signal, NULL);
	dbus_message_unref(signal);
}

static void remove_pending(struct generic_data *data)
{
	if (data->process_id > 0) {
		g_source_remove(data->process_id);
		data->process_id = 0;
	}

	pending = g_slist_remove(pending, data);
}

static gboolean process_changes(gpointer user_data)
{
	struct generic_data *data = user_data;

	remove_pending(data);

	if (data->added != NULL)
		emit_interfaces_added(data);

	/* Flush pending properties */
	if (data->pending_prop == TRUE)
		process_property_changes(data);

	if (data->removed != NULL)
		emit_interfaces_removed(data);

	data->process_id = 0;

	return FALSE;
}

static void generic_unregister(DBusConnection *connection, void *user_data)
{
	struct generic_data *data = user_data;
	struct generic_data *parent = data->parent;

	if (parent != NULL)
		parent->objects = g_slist_remove(parent->objects, data);

	if (data->process_id > 0) {
		g_source_remove(data->process_id);
		data->process_id = 0;
		process_changes(data);
	}

	g_slist_foreach(data->objects, reset_parent, data->parent);
	g_slist_free(data->objects);

	dbus_connection_unref(data->conn);
	g_free(data->introspect);
	g_free(data->path);
	g_free(data);
}

static DBusHandlerResult generic_message(DBusConnection *connection,
					DBusMessage *message, void *user_data)
{
	struct generic_data *data = user_data;
	struct interface_data *iface;
	const GDBusMethodTable *method;
	const char *interface;

	interface = dbus_message_get_interface(message);

	iface = find_interface(data->interfaces, interface);
	if (iface == NULL)
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

	for (method = iface->methods; method &&
			method->name && method->function; method++) {

		if (dbus_message_is_method_call(message, iface->name,
							method->name) == FALSE)
			continue;

		if (check_experimental(method->flags,
					G_DBUS_METHOD_FLAG_EXPERIMENTAL))
			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

		if (g_dbus_args_have_signature(method->in_args,
							message) == FALSE)
			continue;

		if (check_privilege(connection, message, method,
						iface->user_data) == TRUE)
			return DBUS_HANDLER_RESULT_HANDLED;

		return process_message(connection, message, method,
							iface->user_data);
	}

	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

static DBusObjectPathVTable generic_table = {
	.unregister_function	= generic_unregister,
	.message_function	= generic_message,
};

static const GDBusMethodTable introspect_methods[] = {
	{ GDBUS_METHOD("Introspect", NULL,
			GDBUS_ARGS({ "xml", "s" }), introspect) },
	{ }
};

static void append_interfaces(struct generic_data *data, DBusMessageIter *iter)
{
	DBusMessageIter array;

	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
				DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
				DBUS_TYPE_STRING_AS_STRING
				DBUS_TYPE_ARRAY_AS_STRING
				DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
				DBUS_TYPE_STRING_AS_STRING
				DBUS_TYPE_VARIANT_AS_STRING
				DBUS_DICT_ENTRY_END_CHAR_AS_STRING
				DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array);

	g_slist_foreach(data->interfaces, append_interface, &array);

	dbus_message_iter_close_container(iter, &array);
}

static void append_object(gpointer data, gpointer user_data)
{
	struct generic_data *child = data;
	DBusMessageIter *array = user_data;
	DBusMessageIter entry;

	dbus_message_iter_open_container(array, DBUS_TYPE_DICT_ENTRY, NULL,
								&entry);
	dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
								&child->path);
	append_interfaces(child, &entry);
	dbus_message_iter_close_container(array, &entry);

	g_slist_foreach(child->objects, append_object, user_data);
}

static DBusMessage *get_objects(DBusConnection *connection,
				DBusMessage *message, void *user_data)
{
	struct generic_data *data = user_data;
	DBusMessage *reply;
	DBusMessageIter iter;
	DBusMessageIter array;

	reply = dbus_message_new_method_return(message);
	if (reply == NULL)
		return NULL;

	dbus_message_iter_init_append(reply, &iter);

	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
					DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
					DBUS_TYPE_OBJECT_PATH_AS_STRING
					DBUS_TYPE_ARRAY_AS_STRING
					DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
					DBUS_TYPE_STRING_AS_STRING
					DBUS_TYPE_ARRAY_AS_STRING
					DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
					DBUS_TYPE_STRING_AS_STRING
					DBUS_TYPE_VARIANT_AS_STRING
					DBUS_DICT_ENTRY_END_CHAR_AS_STRING
					DBUS_DICT_ENTRY_END_CHAR_AS_STRING
					DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
					&array);

	g_slist_foreach(data->objects, append_object, &array);

	dbus_message_iter_close_container(&iter, &array);

	return reply;
}

static const GDBusMethodTable manager_methods[] = {
	{ GDBUS_METHOD("GetManagedObjects", NULL,
		GDBUS_ARGS({ "objects", "a{oa{sa{sv}}}" }), get_objects) },
	{ }
};

static const GDBusSignalTable manager_signals[] = {
	{ GDBUS_SIGNAL("InterfacesAdded",
		GDBUS_ARGS({ "object", "o" },
				{ "interfaces", "a{sa{sv}}" })) },
	{ GDBUS_SIGNAL("InterfacesRemoved",
		GDBUS_ARGS({ "object", "o" }, { "interfaces", "as" })) },
	{ }
};

static gboolean add_interface(struct generic_data *data,
				const char *name,
				const GDBusMethodTable *methods,
				const GDBusSignalTable *signals,
				const GDBusPropertyTable *properties,
				void *user_data,
				GDBusDestroyFunction destroy)
{
	struct interface_data *iface;
	const GDBusMethodTable *method;
	const GDBusSignalTable *signal;
	const GDBusPropertyTable *property;

	for (method = methods; method && method->name; method++) {
		if (!check_experimental(method->flags,
					G_DBUS_METHOD_FLAG_EXPERIMENTAL))
			goto done;
	}

	for (signal = signals; signal && signal->name; signal++) {
		if (!check_experimental(signal->flags,
					G_DBUS_SIGNAL_FLAG_EXPERIMENTAL))
			goto done;
	}

	for (property = properties; property && property->name; property++) {
		if (!check_experimental(property->flags,
					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL))
			goto done;
	}

	/* Nothing to register */
	return FALSE;

done:
	iface = g_new0(struct interface_data, 1);
	iface->name = g_strdup(name);
	iface->methods = methods;
	iface->signals = signals;
	iface->properties = properties;
	iface->user_data = user_data;
	iface->destroy = destroy;

	data->interfaces = g_slist_append(data->interfaces, iface);
	if (data->parent == NULL)
		return TRUE;

	data->added = g_slist_append(data->added, iface);

	add_pending(data);

	return TRUE;
}

static struct generic_data *object_path_ref(DBusConnection *connection,
							const char *path)
{
	struct generic_data *data;

	if (dbus_connection_get_object_path_data(connection, path,
						(void *) &data) == TRUE) {
		if (data != NULL) {
			data->refcount++;
			return data;
		}
	}

	data = g_new0(struct generic_data, 1);
	data->conn = dbus_connection_ref(connection);
	data->path = g_strdup(path);
	data->refcount = 1;

	data->introspect = g_strdup(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<node></node>");

	if (!dbus_connection_register_object_path(connection, path,
						&generic_table, data)) {
		dbus_connection_unref(data->conn);
		g_free(data->path);
		g_free(data->introspect);
		g_free(data);
		return NULL;
	}

	invalidate_parent_data(connection, path);

	add_interface(data, DBUS_INTERFACE_INTROSPECTABLE, introspect_methods,
						NULL, NULL, data, NULL);

	return data;
}

static void object_path_unref(DBusConnection *connection, const char *path)
{
	struct generic_data *data = NULL;

	if (dbus_connection_get_object_path_data(connection, path,
						(void *) &data) == FALSE)
		return;

	if (data == NULL)
		return;

	data->refcount--;

	if (data->refcount > 0)
		return;

	remove_interface(data, DBUS_INTERFACE_INTROSPECTABLE);
	remove_interface(data, DBUS_INTERFACE_PROPERTIES);

	invalidate_parent_data(data->conn, data->path);

	dbus_connection_unregister_object_path(data->conn, data->path);
}

static gboolean check_signal(DBusConnection *conn, const char *path,
				const char *interface, const char *name,
				const GDBusArgInfo **args)
{
	struct generic_data *data = NULL;
	struct interface_data *iface;
	const GDBusSignalTable *signal;

	*args = NULL;
	if (!dbus_connection_get_object_path_data(conn, path,
					(void *) &data) || data == NULL) {
		error("dbus_connection_emit_signal: path %s isn't registered",
				path);
		return FALSE;
	}

	iface = find_interface(data->interfaces, interface);
	if (iface == NULL) {
		error("dbus_connection_emit_signal: %s does not implement %s",
				path, interface);
		return FALSE;
	}

	for (signal = iface->signals; signal && signal->name; signal++) {
		if (strcmp(signal->name, name) != 0)
			continue;

		if (signal->flags & G_DBUS_SIGNAL_FLAG_EXPERIMENTAL) {
			const char *env = g_getenv("GDBUS_EXPERIMENTAL");
			if (g_strcmp0(env, "1") != 0)
				break;
		}

		*args = signal->args;
		return TRUE;
	}

	error("No signal named %s on interface %s", name, interface);
	return FALSE;
}

gboolean g_dbus_register_interface(DBusConnection *connection,
					const char *path, const char *name,
					const GDBusMethodTable *methods,
					const GDBusSignalTable *signals,
					const GDBusPropertyTable *properties,
					void *user_data,
					GDBusDestroyFunction destroy)
{
	struct generic_data *data;

	data = object_path_ref(connection, path);
	if (data == NULL)
		return FALSE;

	if (find_interface(data->interfaces, name)) {
		object_path_unref(connection, path);
		return FALSE;
	}

	if (!add_interface(data, name, methods, signals, properties, user_data,
								destroy)) {
		object_path_unref(connection, path);
		return FALSE;
	}

	if (properties != NULL && !find_interface(data->interfaces,
						DBUS_INTERFACE_PROPERTIES))
		add_interface(data, DBUS_INTERFACE_PROPERTIES,
				properties_methods, properties_signals, NULL,
				data, NULL);

	g_free(data->introspect);
	data->introspect = NULL;

	return TRUE;
}

gboolean g_dbus_unregister_interface(DBusConnection *connection,
					const char *path, const char *name)
{
	struct generic_data *data = NULL;

	if (path == NULL)
		return FALSE;

	if (dbus_connection_get_object_path_data(connection, path,
						(void *) &data) == FALSE)
		return FALSE;

	if (data == NULL)
		return FALSE;

	if (remove_interface(data, name) == FALSE)
		return FALSE;

	g_free(data->introspect);
	data->introspect = NULL;

	object_path_unref(connection, data->path);

	return TRUE;
}

gboolean g_dbus_register_security(const GDBusSecurityTable *security)
{
	if (security_table != NULL)
		return FALSE;

	security_table = security;

	return TRUE;
}

gboolean g_dbus_unregister_security(const GDBusSecurityTable *security)
{
	security_table = NULL;

	return TRUE;
}

DBusMessage *g_dbus_create_error_valist(DBusMessage *message, const char *name,
					const char *format, va_list args)
{
	char str[1024];

	if (format)
		vsnprintf(str, sizeof(str), format, args);
	else
		str[0] = '\0';

	return dbus_message_new_error(message, name, str);
}

DBusMessage *g_dbus_create_error(DBusMessage *message, const char *name,
						const char *format, ...)
{
	va_list args;
	DBusMessage *reply;

	va_start(args, format);

	reply = g_dbus_create_error_valist(message, name, format, args);

	va_end(args);

	return reply;
}

DBusMessage *g_dbus_create_reply_valist(DBusMessage *message,
						int type, va_list args)
{
	DBusMessage *reply;

	reply = dbus_message_new_method_return(message);
	if (reply == NULL)
		return NULL;

	if (dbus_message_append_args_valist(reply, type, args) == FALSE) {
		dbus_message_unref(reply);
		return NULL;
	}

	return reply;
}

DBusMessage *g_dbus_create_reply(DBusMessage *message, int type, ...)
{
	va_list args;
	DBusMessage *reply;

	va_start(args, type);

	reply = g_dbus_create_reply_valist(message, type, args);

	va_end(args);

	return reply;
}

static void g_dbus_flush(DBusConnection *connection)
{
	GSList *l;

	for (l = pending; l;) {
		struct generic_data *data = l->data;

		l = l->next;
		if (data->conn != connection)
			continue;

		process_changes(data);
	}
}

gboolean g_dbus_send_message(DBusConnection *connection, DBusMessage *message)
{
	dbus_bool_t result = FALSE;

	if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
		dbus_message_set_no_reply(message, TRUE);
	else if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL) {
		const char *path = dbus_message_get_path(message);
		const char *interface = dbus_message_get_interface(message);
		const char *name = dbus_message_get_member(message);
		const GDBusArgInfo *args;

		if (!check_signal(connection, path, interface, name, &args))
			goto out;
	}

	/* Flush pending signal to guarantee message order */
	g_dbus_flush(connection);

	result = dbus_connection_send(connection, message, NULL);

out:
	dbus_message_unref(message);

	return result;
}

gboolean g_dbus_send_message_with_reply(DBusConnection *connection,
					DBusMessage *message,
					DBusPendingCall **call, int timeout)
{
	dbus_bool_t ret;

	/* Flush pending signal to guarantee message order */
	g_dbus_flush(connection);

	ret = dbus_connection_send_with_reply(connection, message, call,
								timeout);

	if (ret == TRUE && call != NULL && *call == NULL) {
		error("Unable to send message (passing fd blocked?)");
		return FALSE;
	}

	return ret;
}

gboolean g_dbus_send_error_valist(DBusConnection *connection,
					DBusMessage *message, const char *name,
					const char *format, va_list args)
{
	DBusMessage *error;

	error = g_dbus_create_error_valist(message, name, format, args);
	if (error == NULL)
		return FALSE;

	return g_dbus_send_message(connection, error);
}

gboolean g_dbus_send_error(DBusConnection *connection, DBusMessage *message,
				const char *name, const char *format, ...)
{
	va_list args;
	gboolean result;

	va_start(args, format);

	result = g_dbus_send_error_valist(connection, message, name,
							format, args);

	va_end(args);

	return result;
}

gboolean g_dbus_send_reply_valist(DBusConnection *connection,
				DBusMessage *message, int type, va_list args)
{
	DBusMessage *reply;

	reply = dbus_message_new_method_return(message);
	if (reply == NULL)
		return FALSE;

	if (dbus_message_append_args_valist(reply, type, args) == FALSE) {
		dbus_message_unref(reply);
		return FALSE;
	}

	return g_dbus_send_message(connection, reply);
}

gboolean g_dbus_send_reply(DBusConnection *connection,
				DBusMessage *message, int type, ...)
{
	va_list args;
	gboolean result;

	va_start(args, type);

	result = g_dbus_send_reply_valist(connection, message, type, args);

	va_end(args);

	return result;
}

gboolean g_dbus_emit_signal(DBusConnection *connection,
				const char *path, const char *interface,
				const char *name, int type, ...)
{
	va_list args;
	gboolean result;

	va_start(args, type);

	result = g_dbus_emit_signal_valist(connection, path, interface,
							name, type, args);

	va_end(args);

	return result;
}

gboolean g_dbus_emit_signal_valist(DBusConnection *connection,
				const char *path, const char *interface,
				const char *name, int type, va_list args)
{
	DBusMessage *signal;
	dbus_bool_t ret;
	const GDBusArgInfo *args_info;

	if (!check_signal(connection, path, interface, name, &args_info))
		return FALSE;

	signal = dbus_message_new_signal(path, interface, name);
	if (signal == NULL) {
		error("Unable to allocate new %s.%s signal", interface,  name);
		return FALSE;
	}

	ret = dbus_message_append_args_valist(signal, type, args);
	if (!ret)
		goto fail;

	if (g_dbus_args_have_signature(args_info, signal) == FALSE) {
		error("%s.%s: got unexpected signature '%s'", interface, name,
					dbus_message_get_signature(signal));
		ret = FALSE;
		goto fail;
	}

	return g_dbus_send_message(connection, signal);

fail:
	dbus_message_unref(signal);

	return ret;
}

static void process_properties_from_interface(struct generic_data *data,
						struct interface_data *iface)
{
	GSList *l;
	DBusMessage *signal;
	DBusMessageIter iter, dict, array;
	GSList *invalidated;

	data->pending_prop = FALSE;

	if (iface->pending_prop == NULL)
		return;

	signal = dbus_message_new_signal(data->path,
			DBUS_INTERFACE_PROPERTIES, "PropertiesChanged");
	if (signal == NULL) {
		error("Unable to allocate new " DBUS_INTERFACE_PROPERTIES
						".PropertiesChanged signal");
		return;
	}

	iface->pending_prop = g_slist_reverse(iface->pending_prop);

	dbus_message_iter_init_append(signal, &iter);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,	&iface->name);
	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);

	invalidated = NULL;

	for (l = iface->pending_prop; l != NULL; l = l->next) {
		GDBusPropertyTable *p = l->data;

		if (p->get == NULL)
			continue;

		if (p->exists != NULL && !p->exists(p, iface->user_data)) {
			invalidated = g_slist_prepend(invalidated, p);
			continue;
		}

		append_property(iface, p, &dict);
	}

	dbus_message_iter_close_container(&iter, &dict);

	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
				DBUS_TYPE_STRING_AS_STRING, &array);
	for (l = invalidated; l != NULL; l = g_slist_next(l)) {
		GDBusPropertyTable *p = l->data;

		dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING,
								&p->name);
	}
	g_slist_free(invalidated);
	dbus_message_iter_close_container(&iter, &array);

	g_slist_free(iface->pending_prop);
	iface->pending_prop = NULL;

	/* Use dbus_connection_send to avoid recursive calls to g_dbus_flush */
	dbus_connection_send(data->conn, signal, NULL);
	dbus_message_unref(signal);
}

static void process_property_changes(struct generic_data *data)
{
	GSList *l;

	for (l = data->interfaces; l != NULL; l = l->next) {
		struct interface_data *iface = l->data;

		process_properties_from_interface(data, iface);
	}
}

void g_dbus_emit_property_changed(DBusConnection *connection,
				const char *path, const char *interface,
				const char *name)
{
	const GDBusPropertyTable *property;
	struct generic_data *data;
	struct interface_data *iface;

	if (path == NULL)
		return;

	if (!dbus_connection_get_object_path_data(connection, path,
					(void **) &data) || data == NULL)
		return;

	iface = find_interface(data->interfaces, interface);
	if (iface == NULL)
		return;

	/*
	 * If ObjectManager is attached, don't emit property changed if
	 * interface is not yet published
	 */
	if (root && g_slist_find(data->added, iface))
		return;

	property = find_property(iface->properties, name);
	if (property == NULL) {
		error("Could not find property %s in %p", name,
							iface->properties);
		return;
	}

	if (g_slist_find(iface->pending_prop, (void *) property) != NULL)
		return;

	data->pending_prop = TRUE;
	iface->pending_prop = g_slist_prepend(iface->pending_prop,
						(void *) property);

	add_pending(data);
}

gboolean g_dbus_get_properties(DBusConnection *connection, const char *path,
				const char *interface, DBusMessageIter *iter)
{
	struct generic_data *data;
	struct interface_data *iface;

	if (path == NULL)
		return FALSE;

	if (!dbus_connection_get_object_path_data(connection, path,
					(void **) &data) || data == NULL)
		return FALSE;

	iface = find_interface(data->interfaces, interface);
	if (iface == NULL)
		return FALSE;

	append_properties(iface, iter);

	return TRUE;
}

gboolean g_dbus_attach_object_manager(DBusConnection *connection)
{
	struct generic_data *data;

	data = object_path_ref(connection, "/");
	if (data == NULL)
		return FALSE;

	add_interface(data, DBUS_INTERFACE_OBJECT_MANAGER,
					manager_methods, manager_signals,
					NULL, data, NULL);
	root = data;

	return TRUE;
}

gboolean g_dbus_detach_object_manager(DBusConnection *connection)
{
	if (!g_dbus_unregister_interface(connection, "/",
					DBUS_INTERFACE_OBJECT_MANAGER))
		return FALSE;

	root = NULL;

	return TRUE;
}

void g_dbus_set_flags(int flags)
{
	global_flags = flags;
}

int g_dbus_get_flags(void)
{
	return global_flags;
}
