diff options
-rw-r--r-- | hcid/dbus-manager.c | 12 | ||||
-rw-r--r-- | hcid/dbus-security.c | 4 | ||||
-rw-r--r-- | hcid/dbus-service.c | 96 | ||||
-rw-r--r-- | hcid/dbus-service.h | 5 |
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 */ |