+ if (bus_context_get_systemd_activation (activation->context))
+ {
+ if (strcmp (service_name, "org.freedesktop.systemd1") == 0)
+ /* systemd itself is missing apparently. That can happen
+ only during early startup. Let's just wait until systemd
+ connects to us and do nothing. */
+ return TRUE;
+
+ if (entry->systemd_service)
+ {
+ BusTransaction *activation_transaction;
+ DBusString service_string;
+ BusService *service;
+ BusRegistry *registry;
+
+ /* OK, we have a systemd service configured for this entry,
+ hence let's enqueue an activation request message. This
+ is implemented as a directed signal, not a method call,
+ for three reasons: 1) we don't expect a response on
+ success, where we just expect a name appearing on the
+ bus; 2) at this time the systemd service might not yet
+ have connected, so we wouldn't know the message serial at
+ this point to set up a pending call; 3) it is ugly if the
+ bus suddenly becomes the caller of a remote method. */
+
+ message = dbus_message_new_signal (DBUS_PATH_DBUS,
+ "org.freedesktop.systemd1.Activator",
+ "ActivationRequest");
+ if (!message)
+ {
+ _dbus_verbose ("No memory to create activation message\n");
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS) ||
+ !dbus_message_set_destination (message, "org.freedesktop.systemd1") ||
+ !dbus_message_append_args (message,
+ DBUS_TYPE_STRING, &entry->systemd_service,
+ DBUS_TYPE_INVALID))
+ {
+ _dbus_verbose ("No memory to set args of activation message\n");
+ dbus_message_unref (message);
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ /* Create our transaction */
+ activation_transaction = bus_transaction_new (activation->context);
+ if (activation_transaction == NULL)
+ {
+ _dbus_verbose ("No memory to create activation transaction\n");
+ dbus_message_unref (message);
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ /* Check whether systemd is already connected */
+ registry = bus_connection_get_registry (connection);
+ _dbus_string_init_const (&service_string, "org.freedesktop.systemd1");
+ service = bus_registry_lookup (registry, &service_string);
+
+ if (service != NULL)
+ {
+ bus_context_log (activation->context,
+ DBUS_SYSTEM_LOG_INFO, "Activating via systemd: service name='%s' unit='%s'",
+ service_name,
+ entry->systemd_service);
+ /* Wonderful, systemd is connected, let's just send the msg */
+ retval = bus_dispatch_matches (activation_transaction, NULL, bus_service_get_primary_owners_connection (service),
+ message, error);
+ }
+ else
+ {
+ bus_context_log (activation->context,
+ DBUS_SYSTEM_LOG_INFO, "Activating systemd to hand-off: service name='%s' unit='%s'",
+ service_name,
+ entry->systemd_service);
+ /* systemd is not around, let's "activate" it. */
+ retval = bus_activation_activate_service (activation, NULL, activation_transaction, TRUE,
+ message, "org.freedesktop.systemd1", error);
+ }
+
+ dbus_message_unref (message);
+
+ if (!retval)
+ {
+ bus_context_log (activation->context,
+ DBUS_SYSTEM_LOG_INFO, "Failed to activate via systemd: service name='%s' unit='%s'",
+ service_name,
+ entry->systemd_service);
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ _dbus_verbose ("failed to send activation message: %s\n", error->name);
+ bus_transaction_cancel_and_free (activation_transaction);
+ return FALSE;
+ }
+
+ bus_transaction_execute_and_free (activation_transaction);
+ return TRUE;
+ }
+
+ /* OK, we have no configured systemd service, hence let's
+ proceed with traditional activation. */
+ }
+