+ /* get the service directories */
+ dirs = bus_config_parser_get_service_dirs (parser);
+
+ /* and the service helper */
+ servicehelper = bus_config_parser_get_servicehelper (parser);
+
+ s = _dbus_strdup(servicehelper);
+ if (s == NULL && servicehelper != NULL)
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+ else
+ {
+ dbus_free(context->servicehelper);
+ context->servicehelper = s;
+ }
+
+ /* Create activation subsystem */
+ if (context->activation)
+ {
+ if (!bus_activation_reload (context->activation, &full_address, dirs, error))
+ goto failed;
+ }
+ else
+ {
+ context->activation = bus_activation_new (context, &full_address, dirs, error);
+ }
+
+ if (context->activation == NULL)
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ goto failed;
+ }
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ retval = TRUE;
+
+ failed:
+ _dbus_string_free (&full_address);
+
+ if (addr)
+ dbus_free (addr);
+
+ return retval;
+}
+
+static dbus_bool_t
+list_concat_new (DBusList **a,
+ DBusList **b,
+ DBusList **result)
+{
+ DBusList *link;
+
+ *result = NULL;
+
+ for (link = _dbus_list_get_first_link (a); link; link = _dbus_list_get_next_link (a, link))
+ {
+ if (!_dbus_list_append (result, link->data))
+ goto oom;
+ }
+ for (link = _dbus_list_get_first_link (b); link; link = _dbus_list_get_next_link (b, link))
+ {
+ if (!_dbus_list_append (result, link->data))
+ goto oom;
+ }
+
+ return TRUE;
+oom:
+ _dbus_list_clear (result);
+ return FALSE;
+}
+
+static dbus_bool_t
+process_config_postinit (BusContext *context,
+ BusConfigParser *parser,
+ DBusError *error)
+{
+ DBusHashTable *service_context_table;
+ DBusList *watched_dirs = NULL;
+
+ service_context_table = bus_config_parser_steal_service_context_table (parser);
+ if (!bus_registry_set_service_context_table (context->registry,
+ service_context_table))
+ {
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ _dbus_hash_table_unref (service_context_table);
+
+ /* We need to monitor both the configuration directories and directories
+ * containing .service files.
+ */
+ if (!list_concat_new (bus_config_parser_get_conf_dirs (parser),
+ bus_config_parser_get_service_dirs (parser),
+ &watched_dirs))
+ {
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ bus_set_watched_dirs (context, &watched_dirs);
+
+ _dbus_list_clear (&watched_dirs);
+
+ return TRUE;
+}
+
+BusContext*
+bus_context_new (const DBusString *config_file,
+ ForceForkSetting force_fork,
+ DBusPipe *print_addr_pipe,
+ DBusPipe *print_pid_pipe,
+ const DBusString *address,
+ dbus_bool_t systemd_activation,
+ DBusError *error)
+{
+ DBusString log_prefix;
+ BusContext *context;
+ BusConfigParser *parser;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ context = NULL;
+ parser = NULL;
+
+ if (!dbus_server_allocate_data_slot (&server_data_slot))
+ {
+ BUS_SET_OOM (error);
+ return NULL;
+ }
+
+ context = dbus_new0 (BusContext, 1);
+ if (context == NULL)
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+ context->refcount = 1;
+
+ _dbus_generate_uuid (&context->uuid);
+
+ if (!_dbus_string_copy_data (config_file, &context->config_file))
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+
+ context->loop = _dbus_loop_new ();
+ if (context->loop == NULL)
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+
+ context->registry = bus_registry_new (context);
+ if (context->registry == NULL)
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+
+ parser = bus_config_load (config_file, TRUE, NULL, error);
+ if (parser == NULL)
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ goto failed;
+ }
+
+ if (!process_config_first_time_only (context, parser, address, systemd_activation, error))
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ goto failed;
+ }
+ if (!process_config_every_time (context, parser, FALSE, error))
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ goto failed;
+ }
+
+ /* we need another ref of the server data slot for the context
+ * to own
+ */
+ if (!dbus_server_allocate_data_slot (&server_data_slot))
+ _dbus_assert_not_reached ("second ref of server data slot failed");
+
+ /* Note that we don't know whether the print_addr_pipe is