summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hcid/dbus-manager.c12
-rw-r--r--hcid/dbus-security.c4
-rw-r--r--hcid/dbus-service.c96
-rw-r--r--hcid/dbus-service.h5
4 files changed, 64 insertions, 53 deletions
diff --git a/hcid/dbus-manager.c b/hcid/dbus-manager.c
index 9418f9ab..524b7d14 100644
--- a/hcid/dbus-manager.c
+++ b/hcid/dbus-manager.c
@@ -272,7 +272,7 @@ static DBusHandlerResult add_service_record(DBusConnection *conn,
return error_invalid_arguments(conn, msg);
}
- if (!service || strcmp(dbus_message_get_sender(msg), service->id))
+ if (!service || strcmp(dbus_message_get_sender(msg), service->bus_name))
return error_not_authorized(conn, msg);
dbus_message_iter_next(&iter);
@@ -296,7 +296,7 @@ static DBusHandlerResult add_service_record(DBusConnection *conn,
/* Assign a new handle */
rec->ext_handle = next_handle++;
- if (service->id) {
+ if (service->bus_name) {
uint32_t handle = 0;
if (register_sdp_record(rec->buf->data, rec->buf->data_size, &handle) < 0) {
@@ -350,7 +350,7 @@ static DBusHandlerResult add_service_record_xml(DBusConnection *conn,
return error_invalid_arguments(conn, msg);
}
- if (!service || strcmp(dbus_message_get_sender(msg), service->id))
+ if (!service || strcmp(dbus_message_get_sender(msg), service->bus_name))
return error_not_authorized(conn, msg);
reply = dbus_message_new_method_return(msg);
@@ -397,7 +397,7 @@ static DBusHandlerResult add_service_record_xml(DBusConnection *conn,
/* Assign a new handle */
rec->ext_handle = next_handle++;
- if (service->id) {
+ if (service->bus_name) {
uint32_t handle = 0;
if (register_sdp_record(rec->buf->data, rec->buf->data_size, &handle) < 0) {
@@ -450,7 +450,7 @@ static DBusHandlerResult remove_service_record(DBusConnection *conn,
return error_invalid_arguments(conn, msg);
}
- if (!service || strcmp(dbus_message_get_sender(msg), service->id))
+ if (!service || strcmp(dbus_message_get_sender(msg), service->bus_name))
return error_not_authorized(conn, msg);
@@ -466,7 +466,7 @@ static DBusHandlerResult remove_service_record(DBusConnection *conn,
service->records = g_slist_remove(service->records, rec);
/* If the service is running: remove it from the from sdpd */
- if (service->id && rec->handle != 0xffffffff) {
+ if (service->bus_name && rec->handle != 0xffffffff) {
if (unregister_sdp_record(rec->handle) < 0) {
error("Service record unregistration failed: %s (%d)",
strerror(errno), errno);
diff --git a/hcid/dbus-security.c b/hcid/dbus-security.c
index 26372f7f..5e0fd6c9 100644
--- a/hcid/dbus-security.c
+++ b/hcid/dbus-security.c
@@ -792,7 +792,7 @@ static DBusHandlerResult authorize_service(DBusConnection *conn,
if (!service)
return error_service_does_not_exist(conn, msg);
- if (strcmp(dbus_message_get_sender(msg), service->id))
+ if (strcmp(dbus_message_get_sender(msg), service->bus_name))
return error_rejected(conn, msg);
/* Check it is a trusted device */
@@ -870,7 +870,7 @@ static DBusHandlerResult cancel_authorization_process(DBusConnection *conn,
if (!service)
return error_service_does_not_exist(conn, msg);
- if (strcmp(dbus_message_get_sender(msg), service->id))
+ if (strcmp(dbus_message_get_sender(msg), service->bus_name))
return error_not_authorized(conn, msg);
if (!default_auth_agent)
diff --git a/hcid/dbus-service.c b/hcid/dbus-service.c
index a6658dd7..7bc984a2 100644
--- a/hcid/dbus-service.c
+++ b/hcid/dbus-service.c
@@ -30,6 +30,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
+#include <signal.h>
#include <sys/types.h>
#include <dbus/dbus.h>
@@ -112,46 +113,13 @@ void service_call_free(void *data)
free(call);
}
-#if 0
-static int service_cmp(const struct service *a, const struct service *b)
-{
- int ret;
-
- if (b->id) {
- if (!a->id)
- return -1;
- ret = strcmp(a->id, b->id);
- if (ret)
- return ret;
- }
-
- if (b->name) {
- if (!a->name)
- return -1;
- ret = strcmp(a->name, b->name);
- if (ret)
- return ret;
- }
-
- if (b->description) {
- if (!a->description)
- return -1;
- ret = strcmp(a->description, b->description);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-#endif
-
static void service_free(struct service *service)
{
if (!service)
return;
- if (service->id)
- free(service->id);
+ if (service->bus_name)
+ free(service->bus_name);
if (service->exec)
free(service->exec);
@@ -235,7 +203,7 @@ static void service_exit(const char *name, void *data)
if (!dbus_connection_get_object_path_data(conn, path, (void *) &service))
continue;
- if (!service || strcmp(name, service->id))
+ if (!service || strcmp(name, service->bus_name))
continue;
if (service->records)
@@ -290,7 +258,7 @@ static DBusHandlerResult get_connection_name(DBusConnection *conn,
return DBUS_HANDLER_RESULT_NEED_MEMORY;
dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &service->id,
+ DBUS_TYPE_STRING, &service->bus_name,
DBUS_TYPE_INVALID);
return send_message_and_unref(conn, reply);
@@ -339,13 +307,48 @@ static DBusHandlerResult get_description(DBusConnection *conn,
return send_message_and_unref(conn, reply);
}
+static void service_setup(gpointer data)
+{
+ /* struct service *service = data; */
+}
+
+static void service_died(GPid pid, gint status, gpointer data)
+{
+ struct service *service = data;
+
+ debug("%s (%s) exited with status %d", service->exec, service->name,
+ status);
+
+ g_spawn_close_pid(pid);
+
+ service->pid = 0;
+}
+
static DBusHandlerResult start(DBusConnection *conn,
DBusMessage *msg, void *data)
{
+ DBusMessage *reply;
struct service *service = data;
+ char *argv[2];
if (service->pid)
- return error_failed(conn, msg, EPERM);
+ return error_failed(conn, msg, EALREADY);
+
+ argv[0] = service->exec;
+ argv[1] = NULL;
+
+ if (!g_spawn_async(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
+ service_setup, service, &service->pid, NULL)) {
+ error("Unable to execute %s", service->exec);
+ return error_failed(conn, msg, ENOEXEC);
+ }
+
+ service->watch_id = g_child_watch_add(service->pid, service_died,
+ service);
+
+ reply = dbus_message_new_method_return(msg);
+ if (reply)
+ send_message_and_unref(conn, reply);
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -353,11 +356,18 @@ static DBusHandlerResult start(DBusConnection *conn,
static DBusHandlerResult stop(DBusConnection *conn,
DBusMessage *msg, void *data)
{
+ DBusMessage *reply;
struct service *service = data;
- if (!service->id)
+ if (!service->bus_name)
return error_failed(conn, msg, EPERM);
+ kill(service->pid, SIGTERM);
+
+ reply = dbus_message_new_method_return(msg);
+ if (reply)
+ send_message_and_unref(conn, reply);
+
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -372,7 +382,7 @@ static DBusHandlerResult is_running(DBusConnection *conn,
if (!reply)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
- running = service->id ? TRUE : FALSE;
+ running = service->bus_name ? TRUE : FALSE;
dbus_message_append_args(reply,
DBUS_TYPE_BOOLEAN, &running,
@@ -522,7 +532,7 @@ static DBusHandlerResult msg_func_services(DBusConnection *conn,
if(!forward)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
- dbus_message_set_destination(forward, service->id);
+ dbus_message_set_destination(forward, service->bus_name);
dbus_message_set_path(forward, dbus_message_get_path(msg));
call_data = service_call_new(conn, msg, service);
@@ -559,7 +569,7 @@ int register_service(char *path, struct service *service)
path[strlen(path) - strlen(SERVICE_SUFFIX)] = '\0';
slash = strrchr(path, '/');
- snprintf(obj_path, sizeof(obj_path) - 1, "/org/bluez/service-%s", &slash[1]);
+ snprintf(obj_path, sizeof(obj_path) - 1, "/org/bluez/service_%s", &slash[1]);
debug("Registering service object: %s (%s)", service->name, obj_path);
@@ -582,7 +592,7 @@ int unregister_service(const char *sender, const char *path)
if (dbus_connection_get_object_path_data(conn, path, (void *) &service)) {
/* No data assigned to this path or it is not the owner */
- if (!service || strcmp(sender, service->id))
+ if (!service || strcmp(sender, service->bus_name))
return -EPERM;
if (service->records)
diff --git a/hcid/dbus-service.h b/hcid/dbus-service.h
index add33887..d3c2f441 100644
--- a/hcid/dbus-service.h
+++ b/hcid/dbus-service.h
@@ -28,8 +28,9 @@
struct service {
/* These two are set when the service is running */
- pid_t pid;
- char *id; /* Connection id */
+ pid_t pid; /* Process id */
+ char *bus_name; /* D-Bus unique name */
+ guint watch_id; /* Id for the child watch */
/* Information parsed from the service file */
char *exec; /* Location of executable */