/* bus.c message bus context object
*
* Copyright (C) 2003, 2004 Red Hat, Inc.
+ * Copyright (C) 2013 Samsung Electronics
*
* Licensed under the Academic Free License version 2.1
*
#include <dbus/dbus-credentials.h>
#include <dbus/dbus-internals.h>
+#ifdef ENABLE_KDBUS_TRANSPORT
+#include "kdbus-d.h"
+#include <stdlib.h>
+#endif
+
#ifdef DBUS_CYGWIN
#include <signal.h>
#endif
unsigned int keep_umask : 1;
unsigned int allow_anonymous : 1;
unsigned int systemd_activation : 1;
+#ifdef ENABLE_KDBUS_TRANSPORT
+ DBusConnection *myKdbusConnection; //todo maybe can be rafctored and removed
+#endif
};
static dbus_int32_t server_data_slot = -1;
_dbus_loop_remove_watch (context->loop, watch);
}
+static void
+toggle_server_watch (DBusWatch *watch,
+ void *data)
+{
+ DBusServer *server = data;
+ BusContext *context;
+
+ context = server_get_context (server);
+
+ _dbus_loop_toggle_watch (context->loop, watch);
+}
+
static dbus_bool_t
add_server_timeout (DBusTimeout *timeout,
void *data)
if (!dbus_server_set_watch_functions (server,
add_server_watch,
remove_server_watch,
- NULL,
+ toggle_server_watch,
server,
NULL))
{
return TRUE;
}
+#ifdef ENABLE_KDBUS_TRANSPORT
+static int
+init_server_for_kdbus (BusContext *context,
+ const char *address,
+ DBusError *error)
+{
+ DBusBusType type;
+ DBusServer* server;
+ char* bus_address;
+
+ if (!strcmp (context->type, "system"))
+ type = DBUS_BUS_SYSTEM;
+ else if (!strcmp (context->type, "session"))
+ type = DBUS_BUS_SESSION;
+ else
+ type = DBUS_BUS_STARTER;
+
+ bus_address = make_kdbus_bus (type, address, error);
+ if (bus_address == NULL)
+ return -1;
+
+ server = empty_server_init (bus_address);
+ if (server == NULL)
+ {
+ free (bus_address);
+ return -1;
+ }
+ if (!_dbus_list_append (&context->servers, server))
+ {
+ free (bus_address);
+ return -2;
+ }
+
+ context->myKdbusConnection = daemon_as_client (type, bus_address, error);
+ if (context->myKdbusConnection == NULL)
+ return -1;
+
+ return 0;
+}
+#endif
+
/* This code only gets executed the first time the
* config files are parsed. It is not executed
* when config files are reloaded.
process_config_first_time_only (BusContext *context,
BusConfigParser *parser,
const DBusString *address,
- dbus_bool_t systemd_activation,
+ BusContextFlags flags,
DBusError *error)
{
DBusString log_prefix;
retval = FALSE;
auth_mechanisms = NULL;
+ pidfile = NULL;
- _dbus_init_system_log ();
+ _dbus_init_system_log (TRUE);
- context->systemd_activation = systemd_activation;
+ if (flags & BUS_CONTEXT_FLAG_SYSTEMD_ACTIVATION)
+ context->systemd_activation = TRUE;
+ else
+ context->systemd_activation = FALSE;
/* Check for an existing pid file. Of course this is a race;
* we'd have to use fcntl() locks on the pid file to
* avoid that. But we want to check for the pid file
* before overwriting any existing sockets, etc.
*/
- pidfile = bus_config_parser_get_pidfile (parser);
+
+ if (flags & BUS_CONTEXT_FLAG_WRITE_PID_FILE)
+ pidfile = bus_config_parser_get_pidfile (parser);
+
if (pidfile != NULL)
{
DBusString u;
if (auth_mechanisms[i] == NULL)
goto oom;
link = _dbus_list_get_next_link (auth_mechanisms_list, link);
+ i += 1;
}
}
else
if (address)
{
- DBusServer *server;
-
- server = dbus_server_listen (_dbus_string_get_const_data(address), error);
- if (server == NULL)
+#ifdef ENABLE_KDBUS_TRANSPORT
+ if(!strncmp(_dbus_string_get_const_data(address), "kdbus:", strlen("kdbus:")))
{
- _DBUS_ASSERT_ERROR_IS_SET (error);
- goto failed;
+ int ret;
+
+ ret = init_server_for_kdbus (context, _dbus_string_get_const_data (address), error);
+
+ if (ret == -1)
+ goto failed;
+ else if (ret == -2)
+ goto oom;
}
- else if (!setup_server (context, server, auth_mechanisms, error))
+ else
+#endif
{
- _DBUS_ASSERT_ERROR_IS_SET (error);
- goto failed;
- }
-
- if (!_dbus_list_append (&context->servers, server))
- goto oom;
+ DBusServer *server;
+
+ server = dbus_server_listen (_dbus_string_get_const_data(address), error);
+ if (server == NULL)
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ goto failed;
+ }
+ else if (!setup_server (context, server, auth_mechanisms, error))
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ goto failed;
+ }
+
+ if (!_dbus_list_append (&context->servers, server))
+ goto oom;
+ }
}
else
{
addresses = bus_config_parser_get_addresses (parser);
link = _dbus_list_get_first_link (addresses);
- while (link != NULL)
+#ifdef ENABLE_KDBUS_TRANSPORT
+ if (!strcmp (link->data, "kdbus:"))
{
- DBusServer *server;
+ int ret;
- server = dbus_server_listen (link->data, error);
- if (server == NULL)
- {
- _DBUS_ASSERT_ERROR_IS_SET (error);
- goto failed;
- }
- else if (!setup_server (context, server, auth_mechanisms, error))
- {
- _DBUS_ASSERT_ERROR_IS_SET (error);
- goto failed;
- }
+ ret = init_server_for_kdbus (context, link->data, error);
- if (!_dbus_list_append (&context->servers, server))
+ if (ret == -1)
+ goto failed;
+ else if (ret == -2)
goto oom;
-
- link = _dbus_list_get_next_link (addresses, link);
}
+ else
+#endif
+ {
+ while (link != NULL)
+ {
+ DBusServer *server;
+
+ server = dbus_server_listen (link->data, error);
+ if (server == NULL)
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ goto failed;
+ }
+ else if (!setup_server (context, server, auth_mechanisms, error))
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ goto failed;
+ }
+
+ if (!_dbus_list_append (&context->servers, server))
+ goto oom;
+
+ link = _dbus_list_get_next_link (addresses, link);
+ }
+ }
}
context->fork = bus_config_parser_get_fork (parser);
BusContext*
bus_context_new (const DBusString *config_file,
- ForceForkSetting force_fork,
+ BusContextFlags flags,
DBusPipe *print_addr_pipe,
DBusPipe *print_pid_pipe,
const DBusString *address,
- dbus_bool_t systemd_activation,
DBusError *error)
{
BusContext *context;
BusConfigParser *parser;
+ _dbus_assert ((flags & BUS_CONTEXT_FLAG_FORK_NEVER) == 0 ||
+ (flags & BUS_CONTEXT_FLAG_FORK_ALWAYS) == 0);
+
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
context = NULL;
}
context->refcount = 1;
+#ifdef ENABLE_KDBUS_TRANSPORT
+ context->myKdbusConnection = NULL;
+#endif
+
_dbus_generate_uuid (&context->uuid);
if (!_dbus_string_copy_data (config_file, &context->config_file))
goto failed;
}
- if (!process_config_first_time_only (context, parser, address, systemd_activation, error))
+ if (!process_config_first_time_only (context, parser, address, flags, error))
{
_DBUS_ASSERT_ERROR_IS_SET (error);
goto failed;
if (context->pidfile)
_dbus_string_init_const (&u, context->pidfile);
- if ((force_fork != FORK_NEVER && context->fork) || force_fork == FORK_ALWAYS)
+ if (((flags & BUS_CONTEXT_FLAG_FORK_NEVER) == 0 && context->fork) ||
+ (flags & BUS_CONTEXT_FLAG_FORK_ALWAYS))
{
_dbus_verbose ("Forking and becoming daemon\n");
dbus_server_free_data_slot (&server_data_slot);
+#ifdef ENABLE_KDBUS_TRANSPORT
+ if(context->myKdbusConnection)
+ {
+ DBusString unique_name;
+
+ if(!bus_connections_setup_connection(context->connections, context->myKdbusConnection))
+ {
+ _dbus_verbose ("Bus connections setup connection failed for myKdbusConnection!\n");
+ dbus_connection_close (context->myKdbusConnection);
+ dbus_connection_unref (context->myKdbusConnection);
+ goto failed;
+ }
+ dbus_connection_set_route_peer_messages (context->myKdbusConnection, FALSE);
+ _dbus_string_init_const (&unique_name, dbus_bus_get_unique_name(context->myKdbusConnection));
+ if(!bus_connection_complete (context->myKdbusConnection, &unique_name, error))
+ {
+ _dbus_verbose ("Bus connection complete failed for myKdbusConnection!\n");
+ goto failed;
+ }
+
+ if(!register_daemon_name(context->myKdbusConnection))
+ {
+ _dbus_verbose ("Registering org.freedesktop.DBus name for daemon failed!\n");
+ goto failed;
+ }
+ if(!register_kdbus_starters(context->myKdbusConnection))
+ {
+ _dbus_verbose ("Registering kdbus starters for dbus activatable names failed!\n");
+ goto failed;
+ }
+ }
+#endif
+
return context;
failed:
_DBUS_ASSERT_ERROR_IS_SET (error);
goto failed;
}
+
+#ifdef ENABLE_KDBUS_TRANSPORT
+ if(context->myKdbusConnection)
+ {
+ if(!update_kdbus_starters(context->myKdbusConnection))
+ {
+ _dbus_verbose ("Update kdbus starters for dbus activatable names failed.\n");
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ goto failed;
+ }
+ }
+#endif
+
ret = TRUE;
bus_context_log (context, DBUS_SYSTEM_LOG_INFO, "Reloaded configuration");
return context->limits.reply_timeout;
}
+#ifdef ENABLE_KDBUS_TRANSPORT
+dbus_bool_t bus_context_is_kdbus(BusContext* context)
+{
+ return context->myKdbusConnection != NULL;
+}
+#endif
+
void
bus_context_log (BusContext *context, DBusSystemLogSeverity severity, const char *msg, ...) _DBUS_GNUC_PRINTF (3, 4);