+
+dbus_bool_t update_kdbus_starters(DBusConnection* connection)
+{
+ dbus_bool_t retval = FALSE;
+ DBusList **services_old;
+ DBusList *link;
+ BusService *service = NULL;
+ BusTransaction *transaction;
+ int fd;
+
+ transaction = bus_transaction_new (bus_connection_get_context(connection));
+ if (transaction == NULL)
+ return FALSE;
+
+ if(!_dbus_transport_get_socket_fd(dbus_connection_get_transport(connection), &fd))
+ goto out;
+
+ services_old = bus_connection_get_services_owned(connection);
+ link = _dbus_list_get_first_link(services_old);
+ link = _dbus_list_get_next_link (services_old, link); //skip org.freedesktop.DBus which is not starter
+
+ while (link != NULL)
+ {
+ int ret;
+
+ service = (BusService*) link->data;
+ if(service == NULL)
+ goto out;
+
+ ret = release_kdbus_name(fd, bus_service_get_name(service), 0);
+
+ if (ret == DBUS_RELEASE_NAME_REPLY_RELEASED)
+ {
+ if(!bus_service_remove_owner(service, connection, transaction, NULL))
+ _dbus_verbose ("Unable to remove\n");
+ }
+ else if(ret < 0)
+ goto out;
+
+ link = _dbus_list_get_next_link (services_old, link);
+ }
+
+ if(!register_kdbus_starters(connection))
+ {
+ _dbus_verbose ("Registering kdbus starters for dbus activatable names failed!\n");
+ goto out;
+ }
+ retval = TRUE;
+
+out:
+ bus_transaction_free(transaction);
+ return retval;
+}
+
+/*
+static dbus_bool_t remove_conn_if_name_match (DBusConnection *connection, void *data)
+{
+ if(!strcmp(bus_connection_get_name(connection), (char*)data))
+ {
+ bus_connection_disconnected(connection);
+ return FALSE; //this is to break foreach function
+ }
+ return TRUE;
+}*/
+
+void handleNameOwnerChanged(DBusMessage *msg, BusTransaction *transaction, DBusConnection *connection)
+{
+ const char *name, *old, *new;
+
+ if(!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old, DBUS_TYPE_STRING, &new, DBUS_TYPE_INVALID))
+ {
+ _dbus_verbose ("Couldn't get args of NameOwnerChanged signal: .\n");//, error.message);
+ return;
+ }
+
+ _dbus_verbose ("Got NameOwnerChanged signal:\nName: %s\nOld: %s\nNew: %s\n", name, old, new);
+
+ if(!strncmp(name, ":1.", 3))/*if it starts from :1. it is unique name - this might be IdRemoved info*/
+ {
+ if(!strcmp(name, old)) //yes it is - someone has disconnected
+ {
+ DBusConnection* conn;
+
+ conn = bus_connections_find_conn_by_name(bus_connection_get_connections(connection), name);
+ if(conn)
+ bus_connection_disconnected(conn);
+ }
+ }
+ else //it is well-known name
+ {
+ if((*old != 0) && (strcmp(old, ":1.1")))
+ {
+ DBusMessage *message;
+
+ if(bus_connections_find_conn_by_name(bus_connection_get_connections(connection), old) == NULL)
+ goto next;
+
+ _dbus_verbose ("Owner '%s' lost name '%s'. Sending NameLost.\n", old, name);
+
+ message = dbus_message_new_signal (DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameLost");
+ if (message == NULL)
+ goto next;
+
+ if (!dbus_message_set_destination (message, old) || !dbus_message_append_args (message,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_INVALID))
+ {
+ dbus_message_unref (message);
+ goto next;
+ }
+
+ bus_transaction_send_from_driver (transaction, connection, message);
+ dbus_message_unref (message);
+ }
+ next:
+ if((*new != 0) && (strcmp(new, ":1.1")))
+ {
+ DBusMessage *message;
+
+ _dbus_verbose ("Owner '%s' acquired name '%s'. Sending NameAcquired.\n", new, name);
+
+ message = dbus_message_new_signal (DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameAcquired");
+ if (message == NULL)
+ return;
+
+ if (!dbus_message_set_destination (message, new) || !dbus_message_append_args (message,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_INVALID))
+ {
+ dbus_message_unref (message);
+ return;
+ }
+
+ bus_transaction_send_from_driver (transaction, connection, message);
+ dbus_message_unref (message);
+ }
+ }
+}