/*
 *
 *  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 "server.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 *addr, *argv[2], *envp[2], command[PATH_MAX], address[256];

	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;

	addr = get_local_server_address();

	snprintf(address, sizeof(address) - 1, "BLUETOOTHD_ADDRESS=%s", addr);
	envp[0] = address;
	envp[1] = NULL;

	dbus_free(addr);

	if (!g_spawn_async(SERVICEDIR, argv, envp, 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;

	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_for_connection(DBusConnection *connection,
						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(connection, 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;
}

static int unregister_service(struct service *service)
{
	return unregister_service_for_connection(get_dbus_connection(), service);
}

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(DBusConnection *conn, const char *bus_name, const char *ident,
				const char *name, const char *description)
{
	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(get_dbus_connection(), service->object_path,
					SERVICE_INTERFACE, "Started",
					DBUS_TYPE_INVALID);

	return 0;
}

int service_unregister(DBusConnection *conn, struct service *service)
{
	return unregister_service_for_connection(conn, service);
}
