summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-connection.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2006-10-01 03:18:47 +0000
committerHavoc Pennington <hp@redhat.com>2006-10-01 03:18:47 +0000
commitd8155bf51bf6484a94e734601526bf211053a5e1 (patch)
tree0185753a00e18f73efe79533624b54714e03071d /dbus/dbus-connection.c
parentf6fa010403cb2badd88ce096ae91f664418508d1 (diff)
2006-09-30 Havoc Pennington <hp@redhat.com>
* configure.in (LT_CURRENT, LT_AGE): increment current and age to reflect addition of interfaces. * doc/dbus-specification.xml: describe a new org.freedesktop.DBus.Peer.GetMachineId method * dbus/dbus-string.c (_dbus_string_skip_white_reverse): new function (_dbus_string_skip_white, _dbus_string_skip_blank): use new DBUS_IS_ASCII_BLANK, DBUS_IS_ASCII_WHITE macros and fix assertion at end of skip_white (_dbus_string_chop_white): new function * bus/connection.c (bus_connections_setup_connection): call dbus_connection_set_route_peer_messages. * dbus/dbus-connection.c (_dbus_connection_peer_filter_unlocked_no_update): modify to support a GetMachineId method. Also, support a new flag to let the bus pass peer methods through to apps on the bus, which can be set with dbus_connection_set_route_peer_messages. Finally, handle and return an error for anything unknown on the Peer interface, which will allow us to extend the Peer interface in the future without fear that we're now intercepting something apps were wanting to see. * tools/dbus-uuidgen.c: a thin wrapper around the functions in dbus/dbus-uuidgen.c * dbus/dbus-uuidgen.c: implement the bulk of the dbus-uuidgen binary here, since most of the code is already in libdbus * dbus/dbus-sysdeps.c (_dbus_read_local_machine_uuid): read the uuid from the system config file * dbus/dbus-internals.c (_dbus_generate_uuid, _dbus_uuid_encode) (_dbus_read_uuid_file_without_creating) (_dbus_create_uuid_file_exclusively, _dbus_read_uuid_file): new uuid-related functions, partly factored out from dbus-server.c * dbus/dbus-sysdeps.c (_dbus_error_from_errno): convert EEXIST to DBUS_ERROR_FILE_EXISTS instead of EEXIST * dbus/dbus-protocol.h (DBUS_ERROR_FILE_EXISTS): add file exists error * tools/dbus-cleanup-sockets.1: explain what the point of this thing is a bit more * autogen.sh (run_configure): add --config-cache to default configure args * dbus/dbus-internals.h (_DBUS_ASSERT_ERROR_IS_SET): disable the error set/clear assertions when DBUS_DISABLE_CHECKS is defined * tools/dbus-launch.c (main): if xdisplay hasn't been opened, don't try to save address, fixes crash in make check
Diffstat (limited to 'dbus/dbus-connection.c')
-rw-r--r--dbus/dbus-connection.c169
1 files changed, 160 insertions, 9 deletions
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index d60816c3..254eb008 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-connection.c DBusConnection object
*
- * Copyright (C) 2002, 2003, 2004, 2005 Red Hat Inc.
+ * Copyright (C) 2002-2006 Red Hat Inc.
*
* Licensed under the Academic Free License version 2.1
*
@@ -246,6 +246,8 @@ struct DBusConnection
unsigned int io_path_acquired : 1; /**< Someone has transport io path (can use the transport to read/write messages) */
unsigned int exit_on_disconnect : 1; /**< If #TRUE, exit after handling disconnect signal */
+
+ unsigned int route_peer_messages : 1; /**< If #TRUE, if org.freedesktop.DBus.Peer messages have a bus name, don't handle them automatically */
#ifndef DBUS_DISABLE_CHECKS
unsigned int have_connection_lock : 1; /**< Used to check locking */
@@ -1175,6 +1177,8 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
connection->objects = objects;
connection->exit_on_disconnect = FALSE;
connection->shareable = FALSE;
+ connection->route_peer_messages = FALSE;
+
#ifndef DBUS_DISABLE_CHECKS
connection->generation = _dbus_current_generation;
#endif
@@ -3575,15 +3579,20 @@ dbus_connection_get_dispatch_status (DBusConnection *connection)
}
/**
-* Filter funtion for handling the Peer standard interface
-**/
+ * Filter funtion for handling the Peer standard interface.
+ */
static DBusHandlerResult
_dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
DBusMessage *message)
{
- if (dbus_message_is_method_call (message,
- DBUS_INTERFACE_PEER,
- "Ping"))
+ if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
+ {
+ /* This means we're letting the bus route this message */
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ else if (dbus_message_is_method_call (message,
+ DBUS_INTERFACE_PEER,
+ "Ping"))
{
DBusMessage *ret;
dbus_bool_t sent;
@@ -3601,9 +3610,68 @@ _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
return DBUS_HANDLER_RESULT_HANDLED;
}
-
-
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ else if (dbus_message_is_method_call (message,
+ DBUS_INTERFACE_PEER,
+ "GetMachineId"))
+ {
+ DBusMessage *ret;
+ dbus_bool_t sent;
+ DBusString uuid;
+
+ ret = dbus_message_new_method_return (message);
+ if (ret == NULL)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+ sent = FALSE;
+ _dbus_string_init (&uuid);
+ if (_dbus_get_local_machine_uuid_encoded (&uuid))
+ {
+ const char *v_STRING = _dbus_string_get_const_data (&uuid);
+ if (dbus_message_append_args (ret,
+ DBUS_TYPE_STRING, &v_STRING,
+ DBUS_TYPE_INVALID))
+ {
+ sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
+ }
+ }
+ _dbus_string_free (&uuid);
+
+ dbus_message_unref (ret);
+
+ if (!sent)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
+ {
+ /* We need to bounce anything else with this interface, otherwise apps
+ * could start extending the interface and when we added extensions
+ * here to DBusConnection we'd break those apps.
+ */
+
+ DBusMessage *ret;
+ dbus_bool_t sent;
+
+ ret = dbus_message_new_error (message,
+ DBUS_ERROR_UNKNOWN_METHOD,
+ "Unknown method invoked on org.freedesktop.DBus.Peer interface");
+ if (ret == NULL)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+ sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
+
+ dbus_message_unref (ret);
+
+ if (!sent)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ else
+ {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
}
/**
@@ -4409,6 +4477,35 @@ dbus_connection_set_unix_user_function (DBusConnection *connection,
}
/**
+ *
+ * Normally #DBusConnection automatically handles all messages to the
+ * org.freedesktop.DBus.Peer interface. However, the message bus wants
+ * to be able to route methods on that interface through the bus and
+ * to other applications. If routing peer messages is enabled, then
+ * messages with the org.freedesktop.DBus.Peer interface that also
+ * have a bus destination name set will not be automatically
+ * handled by the #DBusConnection and instead will be dispatched
+ * normally to the application.
+ *
+ *
+ * If a normal application sets this flag, it can break things badly.
+ * So don't set this unless you are the message bus.
+ *
+ * @param connection the connection
+ * @param value #TRUE to pass through org.freedesktop.DBus.Peer messages with a bus name set
+ */
+void
+dbus_connection_set_route_peer_messages (DBusConnection *connection,
+ dbus_bool_t value)
+{
+ _dbus_return_if_fail (connection != NULL);
+
+ CONNECTION_LOCK (connection);
+ connection->route_peer_messages = TRUE;
+ CONNECTION_UNLOCK (connection);
+}
+
+/**
* Adds a message filter. Filters are handlers that are run on all
* incoming messages, prior to the objects registered with
* dbus_connection_register_object_path(). Filters are run in the
@@ -4968,4 +5065,58 @@ dbus_connection_get_outgoing_size (DBusConnection *connection)
return res;
}
+/**
+ * Obtains the machine UUID of the machine this process is running on.
+ *
+ * The returned string must be freed with dbus_free().
+ *
+ * This UUID is guaranteed to remain the same until the next reboot
+ * (unless the sysadmin foolishly changes it and screws themselves).
+ * It will usually remain the same across reboots also, but hardware
+ * configuration changes or rebuilding the machine could break that.
+ *
+ * The idea is that two processes with the same machine ID should be
+ * able to use shared memory, UNIX domain sockets, process IDs, and other
+ * features of the OS that require both processes to be running
+ * on the same OS kernel instance.
+ *
+ * The machine ID can also be used to create unique per-machine
+ * instances. For example, you could use it in bus names or
+ * X selection names.
+ *
+ * The machine ID is preferred over the machine hostname, because
+ * the hostname is frequently set to "localhost.localdomain" and
+ * may also change at runtime.
+ *
+ * You can get the machine ID of a remote application by invoking the
+ * method GetMachineId from interface org.freedesktop.DBus.Peer.
+ *
+ * If the remote application has the same machine ID as the one
+ * returned by this function, then the remote application is on the
+ * same machine as your application.
+ *
+ * @returns a 32-byte-long hex-encoded UUID string, or #NULL if insufficient memory
+ */
+char*
+dbus_get_local_machine_id (void)
+{
+ DBusString uuid;
+ char *s;
+
+ s = NULL;
+ _dbus_string_init (&uuid);
+ if (!_dbus_get_local_machine_uuid_encoded (&uuid) ||
+ !_dbus_string_steal_data (&uuid, &s))
+ {
+ _dbus_string_free (&uuid);
+ return FALSE;
+ }
+ else
+ {
+ _dbus_string_free (&uuid);
+ return s;
+ }
+
+}
+
/** @} */