/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2007  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 <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <signal.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <glib.h>

#include <dbus/dbus.h>

#include "dbus.h"
#include "dbus-helper.h"
#include "hcid.h"
#include "notify.h"
#include "dbus-common.h"
#include "dbus-error.h"
#include "dbus-manager.h"
#include "dbus-service.h"
#include "dbus-hci.h"

#define SERVICE_INTERFACE "org.bluez.Service"

#define STARTUP_TIMEOUT (10 * 1000) /* 10 seconds */
#define SHUTDOWN_TIMEOUT (2 * 1000) /* 2 seconds */

#define SERVICE_SUFFIX ".service"
#define SERVICE_GROUP "Bluetooth Service"

#define NAME_MATCH "interface=" DBUS_INTERFACE_DBUS ",member=NameOwnerChanged"

static GSList *services = NULL;
static GSList *removed = NULL;

static void service_free(struct service *service)
{
	if (!service)
		return;

	if (service->action)
		dbus_message_unref(service->action);

	g_free(service->bus_name);
	g_free(service->filename);
	g_free(service->object_path);
	g_free(service->name);
	g_free(service->descr);
	g_free(service->ident);

	g_free(service);
}

static void service_exit(const char *name, struct service *service)
{
	DBusConnection *conn = get_dbus_connection();
	
	debug("Service owner exited: %s", name);

	dbus_connection_emit_signal(conn, service->object_path,
					SERVICE_INTERFACE, "Stopped",
					DBUS_TYPE_INVALID);

	if (service->action) {
		DBusMessage *reply;
	      	reply = dbus_message_new_method_return(service->action);
		send_message_and_unref(conn, reply);
		dbus_message_unref(service->action);
		service->action = NULL;
	}

	g_free(service->bus_name);
	service->bus_name = NULL;
}

static DBusHandlerResult get_info(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct service *service = data;
	DBusMessage *reply;
	DBusMessageIter iter;
	DBusMessageIter dict;
	dbus_bool_t running;

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	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_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);

	dbus_message_iter_append_dict_entry(&dict, "identifier",
			DBUS_TYPE_STRING, &service->ident);

	dbus_message_iter_append_dict_entry(&dict, "name",
			DBUS_TYPE_STRING, &service->name);

	dbus_message_iter_append_dict_entry(&dict, "description",
			DBUS_TYPE_STRING, &service->descr);

	running = (service->external || service->bus_name) ? TRUE : FALSE;

	dbus_message_iter_append_dict_entry(&dict, "running",
			DBUS_TYPE_BOOLEAN, &running);

	dbus_message_iter_close_container(&iter, &dict);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult get_identifier(DBusConnection *conn,
					DBusMessage *msg, void *data)
{

	struct service *service = data;
	DBusMessage *reply;
	const char *identifier = "";

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	if (service->ident)
		identifier = service->ident;
	
	dbus_message_append_args(reply,
			DBUS_TYPE_STRING, &identifier,
			DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult get_name(DBusConnection *conn,
					DBusMessage *msg, void *data)
{

	struct service *service = data;
	DBusMessage *reply;
	const char *name = "";

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	if (service->name)
		name = service->name;
	
	dbus_message_append_args(reply,
			DBUS_TYPE_STRING, &name,
			DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult get_description(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct service *service = data;
	DBusMessage *reply;
	const char *description = "";

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	if (service->descr)
		description = service->descr;
	
	dbus_message_append_args(reply,
			DBUS_TYPE_STRING, &description,
			DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult get_bus_name(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct service *service = data;
	DBusMessage *reply;

	if (!service->bus_name)
		return error_not_available(conn, msg);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	dbus_message_append_args(reply,
			DBUS_TYPE_STRING, &service->bus_name,
			DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static void service_setup(gpointer data)
{
	/* struct service *service = data; */
}

static DBusHandlerResult service_filter(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	DBusError err;
	struct service *service = data;
	const char *name, *old, *new;
	unsigned long pid;

	if (!dbus_message_is_signal(msg, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

	if (!dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old,
				DBUS_TYPE_STRING, &new, DBUS_TYPE_INVALID)) {
		error("Invalid arguments for NameOwnerChanged signal");
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
	}

	if (*new == '\0' || *old != '\0' || *new != ':')
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

	if (!dbus_bus_get_unix_process_id(conn, new, &pid)) {
		error("Could not get PID of %s", new);
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
	}

	if ((GPid) pid != service->pid)
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

	debug("Child PID %d got the unique bus name %s", service->pid, new);

	service->bus_name = g_strdup(new);

	dbus_error_init(&err);
	dbus_bus_remove_match(conn, NAME_MATCH, &err);
	if (dbus_error_is_set(&err)) {
		error("Remove match \"%s\" failed: %s" NAME_MATCH, err.message);
		dbus_error_free(&err);
	}
	dbus_connection_remove_filter(conn, service_filter, service);

	if (service->action) {
		msg = dbus_message_new_method_return(service->action);
		if (msg) {
			if (dbus_message_is_method_call(service->action, MANAGER_INTERFACE,
							"ActivateService"))
				dbus_message_append_args(msg, DBUS_TYPE_STRING, &new,
							DBUS_TYPE_INVALID);
			send_message_and_unref(conn, msg);
		}

		dbus_message_unref(service->action);
		service->action = NULL;
	}

	if (service->startup_timer) {
		g_source_remove(service->startup_timer);
		service->startup_timer = 0;
	} else
		debug("service_filter: timeout was already removed!");

	name_listener_add(conn, new, (name_cb_t) service_exit, service);

	dbus_connection_emit_signal(conn, service->object_path,
					SERVICE_INTERFACE, "Started",
					DBUS_TYPE_INVALID);

	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

static void abort_startup(struct service *service, DBusConnection *conn, int ecode)
{
	DBusError err;

	if (conn) {
		dbus_error_init(&err);
		dbus_bus_remove_match(conn, NAME_MATCH, &err);
		if (dbus_error_is_set(&err)) {
			error("Remove match \"%s\" failed: %s" NAME_MATCH, err.message);
		dbus_error_free(&err);
		}

		dbus_connection_remove_filter(conn, service_filter, service);
	}

	g_source_remove(service->startup_timer);
	service->startup_timer = 0;

	if (service->action) {
		if (conn)
			error_failed(conn, service->action, ecode);
		dbus_message_unref(service->action);
		service->action = NULL;
	}

	if (service->pid > 0 && kill(service->pid, SIGKILL) < 0)
		error("kill(%d, SIGKILL): %s (%d)", service->pid,
				strerror(errno), errno);
}

static void service_died(GPid pid, gint status, gpointer data)
{
	struct service *service = data;

	if (WIFEXITED(status))
		debug("%s (%s) exited with status %d", service->name,
				service->ident, WEXITSTATUS(status));
	else
		debug("%s (%s) was killed by signal %d", service->name,
				service->ident, WTERMSIG(status));

	g_spawn_close_pid(pid);
	service->pid = 0;

	if (service->startup_timer)
		abort_startup(service, get_dbus_connection(), ECANCELED);

	if (service->shutdown_timer) {
		g_source_remove(service->shutdown_timer);
		service->shutdown_timer = 0;
	}

	if (g_slist_find(removed, service)) {
		removed = g_slist_remove(removed, service);
		service_free(service);
	}
}

static gboolean service_shutdown_timeout(gpointer data)
{
	struct service *service = data;

	if (service->pid > 0) {
		debug("SIGKILL for \"%s\" (PID %d) since it didn't exit yet",
			service->name, service->pid);

		if (kill(service->pid, SIGKILL) < 0)
			error("kill(%d, SIGKILL): %s (%d)", service->pid,
						strerror(errno), errno);
	}

	service->shutdown_timer = 0;

	return FALSE;
}

static void stop_service(struct service *service, gboolean remove)
{
	if (service->pid > 0 && kill(service->pid, SIGTERM) < 0)
		error("kill(%d, SIGTERM): %s (%d)", service->pid,
				strerror(errno), errno);

	service->shutdown_timer = g_timeout_add(SHUTDOWN_TIMEOUT,
						service_shutdown_timeout,
						service);

	if (remove) {
		services = g_slist_remove(services, service);
		removed = g_slist_append(removed, service);
	}
}

static gboolean service_startup_timeout(gpointer data)
{
	struct service *service = data;

	debug("Killing \"%s\" (PID %d) because it did not connect to D-Bus in time",
			service->name, service->pid);

	abort_startup(service, get_dbus_connection(), ETIME);

	return FALSE;
}

int service_start(struct service *service, DBusConnection *conn)
{
	DBusError derr;
	char *argv[2], command[PATH_MAX];

	if (!dbus_connection_add_filter(conn, service_filter, service, NULL)) {
		error("Unable to add signal filter");
		return -1;
	}

	dbus_error_init(&derr);
	dbus_bus_add_match(conn, NAME_MATCH, &derr);
	if (dbus_error_is_set(&derr)) {
		error("Add match \"%s\" failed: %s", derr.message);
		dbus_error_free(&derr);
		dbus_connection_remove_filter(conn, service_filter, service);
		return -1;
	}

	snprintf(command, sizeof(command) - 1, "%s/bluetoothd-service-%s",
			SERVICEDIR, service->ident);
	argv[0] = command;
	argv[1] = NULL;

	if (!g_spawn_async(SERVICEDIR, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
				service_setup, service, &service->pid, NULL)) {
		error("Unable to execute %s", argv[0]);
		dbus_connection_remove_filter(conn, service_filter, service);
		dbus_bus_remove_match(conn, NAME_MATCH, NULL);
		return -1;
	}

	g_child_watch_add(service->pid, service_died, service);

	debug("%s executed with PID %d", argv[0], service->pid);

	service->startup_timer = g_timeout_add(STARTUP_TIMEOUT,
						service_startup_timeout,
						service);

	return 0;
}

static DBusHandlerResult start(DBusConnection *conn,
				DBusMessage *msg, void *data)
{
	struct service *service = data;

	if (service->external || service->pid)
		return error_failed(conn, msg, EALREADY);

	if (service_start(service, conn) < 0)
		return error_failed(conn, msg, ENOEXEC);

	service->action = dbus_message_ref(msg);

	return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult stop(DBusConnection *conn,
				DBusMessage *msg, void *data)
{
	struct service *service  = data;

	if (service->external || !service->bus_name)
		return error_failed(conn, msg, EPERM);

	stop_service(service, FALSE);

	service->action = dbus_message_ref(msg);

	return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult is_running(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct service *service = data;
	DBusMessage *reply;
	dbus_bool_t running;

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	running = (service->external || service->bus_name) ? TRUE : FALSE;

	dbus_message_append_args(reply,
			DBUS_TYPE_BOOLEAN, &running,
			DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult is_external(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct service *service = data;
	DBusMessage *reply;

	if (!hcid_dbus_use_experimental())
		return error_unknown_method(conn, msg);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	dbus_message_append_args(reply,
			DBUS_TYPE_BOOLEAN, &service->external,
			DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult list_users(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

static DBusHandlerResult remove_user(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

static DBusHandlerResult set_trusted(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct service *service = data;
	DBusMessage *reply;
	const char *address;

	if (!dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &address,
			DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	if (check_address(address) < 0)
		return error_invalid_arguments(conn, msg);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	write_trust(BDADDR_ANY, address, service->ident, TRUE);

	dbus_connection_emit_signal(conn, service->object_path,
					SERVICE_INTERFACE, "TrustAdded",
					DBUS_TYPE_STRING, &address,
					DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult is_trusted(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct service *service = data;
	DBusMessage *reply;
	const char *address;
	dbus_bool_t trusted;

	if (!dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &address,
			DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	if (check_address(address) < 0)
		return error_invalid_arguments(conn, msg);

	trusted = read_trust(BDADDR_ANY, address, service->ident);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	dbus_message_append_args(reply,
				DBUS_TYPE_BOOLEAN, &trusted,
				DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult remove_trust(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct service *service = data;
	DBusMessage *reply;
	const char *address;

	if (!dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &address,
			DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	if (check_address(address) < 0)
		return error_invalid_arguments(conn, msg);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	write_trust(BDADDR_ANY, address, service->ident, FALSE);

	dbus_connection_emit_signal(conn, service->object_path,
					SERVICE_INTERFACE, "TrustRemoved",
					DBUS_TYPE_STRING, &address,
					DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusMethodVTable service_methods[] = {
	{ "GetInfo",		get_info,		"",	"{sv}"	},
	{ "GetIdentifier",	get_identifier,		"",	"s"	},
	{ "GetName",		get_name,		"",	"s"	},
	{ "GetDescription",	get_description,	"",	"s"	},
	{ "GetBusName",		get_bus_name,		"",	"s"	},
	{ "Start",		start,			"",	""	},
	{ "Stop",		stop,			"",	""	},
	{ "IsRunning",		is_running,		"",	"b"	},
	{ "IsExternal",		is_external,		"",	"b"	},
	{ "ListUsers",		list_users,		"",	"as"	},
	{ "RemoveUser",		remove_user,		"s",	""	},
	{ "SetTrusted",		set_trusted,		"s",	""	},
	{ "IsTrusted",		is_trusted,		"s",	"b"	},
	{ "RemoveTrust",	remove_trust,		"s",	""	},
	{ NULL, NULL, NULL, NULL }
};

static DBusSignalVTable service_signals[] = {
	{ "Started",		""	},
	{ "Stopped",		""	},	
	{ "TrustAdded",		"s"	},
	{ "TrustRemoved",	"s"	},
	{ NULL, NULL }
};

static dbus_bool_t service_init(DBusConnection *conn, const char *path)
{
	return dbus_connection_register_interface(conn, path, SERVICE_INTERFACE,
							service_methods,
							service_signals, NULL);
}

static int service_cmp_path(struct service *service, const char *path)
{
	return strcmp(service->object_path, path);
}

static int service_cmp_ident(struct service *service, const char *ident)
{
	return strcmp(service->ident, ident);
}

static int register_service(struct service *service)
{
	char obj_path[PATH_MAX], *suffix;
	DBusConnection *conn = get_dbus_connection();
	int i;

	if (g_slist_find_custom(services, service->ident,
				(GCompareFunc) service_cmp_ident)
			|| !strcmp(service->ident, GLOBAL_TRUST))
		return -EADDRINUSE;

	if (service->external) {
		snprintf(obj_path, sizeof(obj_path) - 1,
				"/org/bluez/external_%s", service->ident);
	} else {
		snprintf(obj_path, sizeof(obj_path) - 1,
				"/org/bluez/service_%s", service->filename);

		/* Don't include the .service part in the path */
		suffix = strstr(obj_path, SERVICE_SUFFIX);
		*suffix = '\0';
	}

	/* Make the path valid for D-Bus */
	for (i = strlen("/org/bluez/"); obj_path[i]; i++) {
		if (!isalnum(obj_path[i]))
			obj_path[i] = '_';
	}

	if (g_slist_find_custom(services, obj_path,
				(GCompareFunc) service_cmp_path))
		return -EADDRINUSE;

	debug("Registering service object: ident=%s, name=%s (%s)",
			service->ident, service->name, obj_path);


	if (!dbus_connection_create_object_path(conn, obj_path,
						service, NULL)) {
		error("D-Bus failed to register %s object", obj_path);
		return -1;
	}

	if (!service_init(conn, obj_path)) {
		error("Service init failed");
		return -1;
	}

	service->object_path = g_strdup(obj_path);

	services = g_slist_append(services, service);

	dbus_connection_emit_signal(conn, BASE_PATH, MANAGER_INTERFACE,
					"ServiceAdded",
					DBUS_TYPE_STRING, &service->object_path,
					DBUS_TYPE_INVALID);

	return 0;
}

static int unregister_service(struct service *service)
{
	DBusConnection *conn = get_dbus_connection();

	debug("Unregistering service object: %s", service->object_path);

	if (!conn)
		goto cleanup;

	if (service->bus_name)
		name_listener_remove(conn, service->bus_name,
					(name_cb_t) service_exit, service);

	dbus_connection_emit_signal(conn, service->object_path,
					SERVICE_INTERFACE,
					"Stopped", DBUS_TYPE_INVALID);

	if (!dbus_connection_destroy_object_path(conn, service->object_path)) {
		error("D-Bus failed to unregister %s object", service->object_path);
		return -1;
	}

	dbus_connection_emit_signal(conn, BASE_PATH, MANAGER_INTERFACE,
					"ServiceRemoved",
					DBUS_TYPE_STRING, &service->object_path,
					DBUS_TYPE_INVALID);

cleanup:
	if (service->pid) {
		if (service->startup_timer) {
			abort_startup(service, conn, ECANCELED);
			services = g_slist_remove(services, service);
			removed = g_slist_append(removed, service);
		} else if (!service->shutdown_timer)
			stop_service(service, TRUE);
	} else {
		services = g_slist_remove(services, service);
		service_free(service);
	}
	
	return 0;
}

void release_services(DBusConnection *conn)
{
	debug("release_services");

	g_slist_foreach(services, (GFunc) unregister_service, NULL);
	g_slist_free(services);
	services = NULL;
}

struct service *search_service(DBusConnection *conn, const char *pattern)
{
	GSList *l;

	for (l = services; l != NULL; l = l->next) {
		struct service *service = l->data;

		if (service->ident && !strcmp(service->ident, pattern))
			return service;

		if (service->bus_name && !strcmp(service->bus_name, pattern))
			return service;
	}

	return NULL;
}

void append_available_services(DBusMessageIter *array_iter)
{
	GSList *l;

	for (l = services; l != NULL; l = l->next) {
		struct service *service = l->data;

		dbus_message_iter_append_basic(array_iter,
					DBUS_TYPE_STRING, &service->object_path);
	}
}

static struct service *create_service(const char *file)
{
	GKeyFile *keyfile;
	GError *err = NULL;
	struct service *service;
	gboolean autostart;
	const char *slash;

	service = g_try_new0(struct service, 1);
	if (!service) {
		error("OOM while allocating new service");
		return NULL;
	}

	service->external = FALSE;

	keyfile = g_key_file_new();

	if (!g_key_file_load_from_file(keyfile, file, 0, &err)) {
		error("Parsing %s failed: %s", file, err->message);
		g_error_free(err);
		goto failed;
	}

	service->ident = g_key_file_get_string(keyfile, SERVICE_GROUP,
						"Identifier", &err);
	if (err) {
		debug("%s: %s", file, err->message);
		g_error_free(err);
		goto failed;
	}

	service->name = g_key_file_get_string(keyfile, SERVICE_GROUP,
						"Name", &err);
	if (!service->name) {
		error("%s: %s", file, err->message);
		g_error_free(err);
		goto failed;
	}

	slash = strrchr(file, '/');
	if (!slash) {
		error("No slash in service file path!?");
		goto failed;
	}

	service->filename = g_strdup(slash + 1);

	service->descr = g_key_file_get_string(keyfile, SERVICE_GROUP,
						"Description", &err);
	if (err) {
		debug("%s: %s", file, err->message);
		g_error_free(err);
		err = NULL;
	}

	autostart = g_key_file_get_boolean(keyfile, SERVICE_GROUP,
						"Autostart", &err);
	if (err) {
		debug("%s: %s", file, err->message);
		g_error_free(err);
		err = NULL;
	} else
		service->autostart = autostart;

	g_key_file_free(keyfile);

	return service;

failed:
	g_key_file_free(keyfile);
	service_free(service);
	return NULL;
}

static gint service_filename_cmp(struct service *service, const char *filename)
{
	return strcmp(service->filename, filename);
}

static void service_notify(int action, const char *name, void *user_data)
{
	GSList *l;
	struct service *service;
	size_t len;
	char fullpath[PATH_MAX];

	debug("Received notify event %d for %s", action, name);

	len = strlen(name);
	if (len < (strlen(SERVICE_SUFFIX) + 1))
		return;

	if (strcmp(name + (len - strlen(SERVICE_SUFFIX)), SERVICE_SUFFIX))
		return;

	switch (action) {
	case NOTIFY_CREATE:
		debug("%s was created", name);
		snprintf(fullpath, sizeof(fullpath) - 1, "%s/%s", CONFIGDIR, name);
		service = create_service(fullpath);
		if (!service) {
			error("Unable to read %s", fullpath);
			break;
		}

		if (register_service(service) < 0) {
			error("Unable to register service");
			service_free(service);
			break;
		}

		if (service->autostart)
			service_start(service, get_dbus_connection());

		break;
	case NOTIFY_DELETE:
		debug("%s was deleted", name);
		l = g_slist_find_custom(services, name,
					(GCompareFunc) service_filename_cmp);
		if (l)
			unregister_service(l->data);
		break;
	case NOTIFY_MODIFY:
		debug("%s was modified", name);
		break;
	default:
		debug("Unknown notify action %d", action);
		break;
	}
}

int init_services(const char *path)
{
	DIR *d;
	struct dirent *e;

	d = opendir(path);
	if (!d) {
		error("Unable to open service dir %s: %s", path, strerror(errno));
		return -1;
	}

	while ((e = readdir(d)) != NULL) {
		char full_path[PATH_MAX];
		struct service *service;
		size_t len = strlen(e->d_name);

		if (len < (strlen(SERVICE_SUFFIX) + 1))
			continue;

		/* Skip if the file doesn't end in .service */
		if (strcmp(&e->d_name[len - strlen(SERVICE_SUFFIX)], SERVICE_SUFFIX))
			continue;

		snprintf(full_path, sizeof(full_path) - 1, "%s/%s", path, e->d_name);

		service = create_service(full_path);
		if (!service) {
			error("Unable to read %s", full_path);
			continue;
		}

		if (register_service(service) < 0) {
			error("Unable to register service");
			service_free(service);
			continue;
		}

		if (service->autostart)
			service_start(service, get_dbus_connection());
	}

	closedir(d);

	notify_add(path, service_notify, NULL);

	return 0;
}

static struct service *create_external_service(const char *ident,
				const char *name, const char *description)
{
	struct service *service;

	service = g_try_new0(struct service, 1);
	if (!service) {
		error("OOM while allocating new external service");
		return NULL;
	}

	service->filename = NULL;
	service->name = g_strdup(name);
	service->descr = g_strdup(description);
	service->ident = g_strdup(ident);

	service->external = TRUE;

	return service;
}

static void external_service_exit(const char *name, struct service *service)
{
	DBusConnection *conn = get_dbus_connection();

	service_exit(name, service);

	if (!conn)
		return;

	if (!dbus_connection_destroy_object_path(conn, service->object_path))
		return;

	dbus_connection_emit_signal(conn, BASE_PATH, MANAGER_INTERFACE,
					"ServiceRemoved",
					DBUS_TYPE_STRING, &service->object_path,
					DBUS_TYPE_INVALID);

	services = g_slist_remove(services, service);
	service_free(service);
}

int service_register(const char *bus_name, const char *ident,
				const char *name, const char *description)
{
	DBusConnection *conn = get_dbus_connection();
	struct service *service;

	if (!conn)
		return -1;

	service = create_external_service(ident, name, description);
	if (!service)
		return -1;

	service->bus_name = g_strdup(bus_name);

	if (register_service(service) < 0) {
		service_free(service);
		return -1;
	}

	name_listener_add(conn, bus_name, (name_cb_t) external_service_exit,
				service);

	dbus_connection_emit_signal(conn, service->object_path,
					SERVICE_INTERFACE, "Started",
					DBUS_TYPE_INVALID);

	return 0;
}

int service_unregister(struct service *service)
{
	return unregister_service(service);
}
