summaryrefslogtreecommitdiffstats
path: root/bus
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@codefactory.se>2003-01-25 20:53:53 +0000
committerAnders Carlsson <andersca@codefactory.se>2003-01-25 20:53:53 +0000
commit39dd1fcee640b4a5a9abb453a9ccd5b7e099ba1c (patch)
tree152435396d67fa175d8a27ccb827f1bdb54917ba /bus
parentfdddf7246da9ea6ce841146e2befe843aede0466 (diff)
2003-01-25 Anders Carlsson <andersca@codefactory.se>
* bus/Makefile.am: * bus/connection.c: (connection_disconnect_handler), (connection_watch_callback), (bus_connection_setup): * bus/dispatch.c: (send_one_message), (bus_dispatch_broadcast_message), (bus_dispatch_message_handler), (bus_dispatch_add_connection), (bus_dispatch_remove_connection): * bus/dispatch.h: * bus/driver.c: (bus_driver_send_service_deleted), (bus_driver_send_service_created), (bus_driver_handle_hello), (bus_driver_send_welcome_message), (bus_driver_handle_list_services), (bus_driver_remove_connection), (bus_driver_handle_message): * bus/driver.h: Refactor code, put the message dispatching in its own file. Use _DBUS_HANDLE_OOM. Also send ServiceDeleted messages when a client is disconnected.
Diffstat (limited to 'bus')
-rw-r--r--bus/Makefile.am2
-rw-r--r--bus/connection.c11
-rw-r--r--bus/dispatch.c126
-rw-r--r--bus/dispatch.h34
-rw-r--r--bus/driver.c251
-rw-r--r--bus/driver.h5
6 files changed, 261 insertions, 168 deletions
diff --git a/bus/Makefile.am b/bus/Makefile.am
index af25867b..488b0c75 100644
--- a/bus/Makefile.am
+++ b/bus/Makefile.am
@@ -9,6 +9,8 @@ bin_PROGRAMS=dbus-daemon-1
dbus_daemon_1_SOURCES= \
connection.c \
connection.h \
+ dispatch.c \
+ dispatch.h \
driver.c \
driver.h \
loop.c \
diff --git a/bus/connection.c b/bus/connection.c
index 0fcfdbe2..2b2a0432 100644
--- a/bus/connection.c
+++ b/bus/connection.c
@@ -21,7 +21,7 @@
*
*/
#include "connection.h"
-#include "driver.h"
+#include "dispatch.h"
#include "loop.h"
#include "services.h"
#include <dbus/dbus-list.h>
@@ -54,8 +54,7 @@ connection_disconnect_handler (DBusConnection *connection,
while ((service = _dbus_list_get_last (&d->services_owned)))
bus_service_remove_owner (service, connection);
- /* Tell bus driver that we want to get off */
- bus_driver_remove_connection (connection);
+ bus_dispatch_remove_connection (connection);
/* no more watching */
dbus_connection_set_watch_functions (connection,
@@ -78,9 +77,12 @@ connection_watch_callback (DBusWatch *watch,
{
DBusConnection *connection = data;
+ dbus_connection_ref (connection);
+
dbus_connection_handle_watch (connection, watch, condition);
while (dbus_connection_dispatch_message (connection));
+ dbus_connection_unref (connection);
}
static void
@@ -159,7 +161,8 @@ bus_connection_setup (DBusConnection *connection)
connection_disconnect_handler,
NULL, NULL);
- if (!bus_driver_add_connection (connection))
+ /* Setup the connection with the dispatcher */
+ if (!bus_dispatch_add_connection (connection))
return FALSE;
return TRUE;
diff --git a/bus/dispatch.c b/bus/dispatch.c
new file mode 100644
index 00000000..a74b3719
--- /dev/null
+++ b/bus/dispatch.c
@@ -0,0 +1,126 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dispatch.c Message dispatcher
+ *
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 1.2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "dispatch.h"
+#include "connection.h"
+#include "driver.h"
+#include <dbus/dbus-internals.h>
+#include <string.h>
+
+static int message_handler_slot;
+
+static void
+send_one_message (DBusConnection *connection, void *data)
+{
+ _DBUS_HANDLE_OOM (dbus_connection_send_message (connection, data, NULL, NULL));
+}
+
+void
+bus_dispatch_broadcast_message (DBusMessage *message)
+{
+ _dbus_assert (dbus_message_get_sender (message) != NULL);
+
+ bus_connection_foreach (send_one_message, message);
+
+}
+
+static DBusHandlerResult
+bus_dispatch_message_handler (DBusMessageHandler *handler,
+ DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ const char *sender, *service;
+
+ /* Assign a sender to the message */
+ sender = bus_connection_get_name (connection);
+ _DBUS_HANDLE_OOM (dbus_message_set_sender (message, sender));
+
+ service = dbus_message_get_service (message);
+
+ /* See if the message is to the driver */
+ if (strcmp (service, DBUS_SERVICE_DBUS) == 0)
+ {
+ bus_driver_handle_message (connection, message);
+ }
+ else if (sender == NULL)
+ {
+ _dbus_verbose ("Received message from non-registered client. Disconnecting.\n");
+ dbus_connection_disconnect (connection);
+ }
+ else if (strcmp (service, DBUS_SERVICE_BROADCAST) == 0)
+ {
+ bus_dispatch_broadcast_message (message);
+ }
+ else
+ {
+ /* Dispatch the message */
+ }
+
+ return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+}
+
+dbus_bool_t
+bus_dispatch_add_connection (DBusConnection *connection)
+{
+ DBusMessageHandler *handler;
+
+ message_handler_slot = dbus_connection_allocate_data_slot ();
+
+ if (message_handler_slot < 0)
+ return FALSE;
+
+ handler = dbus_message_handler_new (bus_dispatch_message_handler, NULL, NULL);
+
+ if (!dbus_connection_add_filter (connection, handler))
+ {
+ dbus_message_handler_unref (handler);
+
+ return FALSE;
+ }
+
+ if (!dbus_connection_set_data (connection,
+ message_handler_slot,
+ handler,
+ (DBusFreeFunction)dbus_message_handler_unref))
+ {
+ dbus_connection_remove_filter (connection, handler);
+ dbus_message_handler_unref (handler);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+bus_dispatch_remove_connection (DBusConnection *connection)
+{
+ /* Here we tell the bus driver that we want to get off. */
+ bus_driver_remove_connection (connection);
+
+ dbus_connection_set_data (connection,
+ message_handler_slot,
+ NULL, NULL);
+}
+
diff --git a/bus/dispatch.h b/bus/dispatch.h
new file mode 100644
index 00000000..2fe3479c
--- /dev/null
+++ b/bus/dispatch.h
@@ -0,0 +1,34 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dispatch.h Message dispatcher
+ *
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 1.2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef BUS_DISPATCH_H
+#define BUS_DISPATCH_H
+
+#include <dbus/dbus.h>
+
+dbus_bool_t bus_dispatch_add_connection (DBusConnection *connection);
+void bus_dispatch_remove_connection (DBusConnection *connection);
+void bus_dispatch_broadcast_message (DBusMessage *message);
+
+
+#endif /* BUS_DISPATCH_H */
diff --git a/bus/driver.c b/bus/driver.c
index eacca934..6e13e486 100644
--- a/bus/driver.c
+++ b/bus/driver.c
@@ -23,59 +23,49 @@
#include "connection.h"
#include "driver.h"
+#include "dispatch.h"
#include "services.h"
-#include <dbus/dbus-message-internal.h>
-#include <dbus/dbus-internals.h>
#include <dbus/dbus-string.h>
+#include <dbus/dbus-internals.h>
#include <string.h>
-#define BUS_DRIVER_SERVICE_NAME "org.freedesktop.DBus"
-#define BUS_DRIVER_HELLO_NAME "org.freedesktop.DBus.Hello"
-#define BUS_DRIVER_WELCOME_NAME "org.freedesktop.DBus.Welcome"
-#define BUS_DRIVER_LIST_SERVICES_NAME "org.freedesktop.DBus.ListServices"
-#define BUS_DRIVER_SERVICES_NAME "org.freedesktop.DBus.Services"
-
-#define BUS_DRIVER_SERVICE_CREATED_NAME "org.freedesktop.DBus.ServiceCreated"
-#define BUS_DRIVER_SERVICE_DELETED_NAME "org.freedesktop.DBus.ServiceDeleted"
-
-static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection,
- DBusMessage *hello_message);
+static void bus_driver_send_welcome_message (DBusConnection *connection,
+ DBusMessage *hello_message);
static void
-send_one_message (DBusConnection *connection, void *data)
+bus_driver_send_service_deleted (DBusConnection *connection, const char *name)
{
- dbus_connection_send_message (connection, data, NULL, NULL);
-}
+ DBusMessage *message;
-static void
-bus_driver_broadcast_message (DBusMessage *message)
-{
- bus_connection_foreach (send_one_message, message);
+ _dbus_verbose ("sending service deleted: %s\n", name);
+
+ _DBUS_HANDLE_OOM (message = dbus_message_new (DBUS_SERVICE_BROADCAST,
+ DBUS_MESSAGE_SERVICE_DELETED));
+
+ _DBUS_HANDLE_OOM (dbus_message_set_sender (message, DBUS_SERVICE_DBUS));
+
+ _DBUS_HANDLE_OOM (dbus_message_append_fields (message,
+ DBUS_TYPE_STRING, name,
+ 0));
+ bus_dispatch_broadcast_message (message);
+ dbus_message_unref (message);
}
-static dbus_bool_t
+static void
bus_driver_send_service_created (DBusConnection *connection, const char *name)
{
DBusMessage *message;
- message = dbus_message_new (NULL, BUS_DRIVER_SERVICE_CREATED_NAME);
-
- if (!message)
- return FALSE;
-
- if (!dbus_message_append_fields (message,
- DBUS_TYPE_STRING, name,
- 0))
- {
- dbus_message_unref (message);
- return FALSE;
- }
+ _DBUS_HANDLE_OOM (message = dbus_message_new (DBUS_SERVICE_BROADCAST,
+ DBUS_MESSAGE_SERVICE_CREATED));
- dbus_message_set_sender (message, BUS_DRIVER_SERVICE_NAME);
- bus_driver_broadcast_message (message);
+ _DBUS_HANDLE_OOM (dbus_message_set_sender (message, DBUS_SERVICE_DBUS));
+
+ _DBUS_HANDLE_OOM (dbus_message_append_fields (message,
+ DBUS_TYPE_STRING, name,
+ 0));
+ bus_dispatch_broadcast_message (message);
dbus_message_unref (message);
-
- return TRUE;
}
static dbus_bool_t
@@ -140,7 +130,7 @@ create_unique_client_name (const char *name,
return TRUE;
}
-static dbus_bool_t
+static void
bus_driver_handle_hello (DBusConnection *connection,
DBusMessage *message)
{
@@ -148,88 +138,56 @@ bus_driver_handle_hello (DBusConnection *connection,
char *name;
DBusString unique_name;
BusService *service;
- dbus_bool_t retval;
- result = dbus_message_get_fields (message,
- DBUS_TYPE_STRING, &name,
- 0);
+ _DBUS_HANDLE_OOM ((result = dbus_message_get_fields (message,
+ DBUS_TYPE_STRING, &name,
+ 0)) != DBUS_RESULT_NO_MEMORY);
- /* FIXME: Handle this in a better way */
if (result != DBUS_RESULT_SUCCESS)
- return FALSE;
+ dbus_connection_disconnect (connection);
- if (!_dbus_string_init (&unique_name, _DBUS_INT_MAX))
- return FALSE;
-
- if (!create_unique_client_name (name, &unique_name))
- {
- _dbus_string_free (&unique_name);
- return FALSE;
- }
+ _DBUS_HANDLE_OOM (_dbus_string_init (&unique_name, _DBUS_INT_MAX));
+ _DBUS_HANDLE_OOM (create_unique_client_name (name, &unique_name));
+
/* Create the service */
- service = bus_service_lookup (&unique_name, TRUE);
- if (!service)
- {
- _dbus_string_free (&unique_name);
- return FALSE;
- }
+ _DBUS_HANDLE_OOM (service = bus_service_lookup (&unique_name, TRUE));
- /* FIXME: Error checks from this point */
-
/* Add the connection as the owner */
- bus_service_add_owner (service, connection);
- bus_connection_set_name (connection, &unique_name);
+ _DBUS_HANDLE_OOM (bus_service_add_owner (service, connection));
+ _DBUS_HANDLE_OOM (bus_connection_set_name (connection, &unique_name));
- /* We need to assign the sender to the message here */
- dbus_message_set_sender (message,
- bus_connection_get_name (connection));
+ _DBUS_HANDLE_OOM (dbus_message_set_sender (message,
+ bus_connection_get_name (connection)));
_dbus_string_free (&unique_name);
- retval = bus_driver_send_welcome_message (connection, message);
+ _DBUS_HANDLE_OOM (bus_driver_send_welcome_message (connection, message));
- if (!retval)
- return FALSE;
-
- /* Broadcast a ServiceCreated message */
- retval = bus_driver_send_service_created (connection, bus_connection_get_name (connection));
-
- return retval;
+ /* Broadcast a service created message */
+ bus_driver_send_service_created (connection, bus_service_get_name (service));
}
-static dbus_bool_t
+static void
bus_driver_send_welcome_message (DBusConnection *connection,
DBusMessage *hello_message)
{
DBusMessage *welcome;
const char *name;
- dbus_bool_t retval;
-
name = bus_connection_get_name (connection);
_dbus_assert (name != NULL);
- welcome = dbus_message_new_reply (BUS_DRIVER_WELCOME_NAME,
- hello_message);
- if (welcome == NULL)
- return FALSE;
-
- /* FIXME: Return value */
- dbus_message_set_sender (welcome, BUS_DRIVER_SERVICE_NAME);
+ _DBUS_HANDLE_OOM (welcome = dbus_message_new_reply (DBUS_MESSAGE_WELCOME,
+ hello_message));
- if (!dbus_message_append_fields (welcome,
- DBUS_TYPE_STRING, name,
- NULL))
- {
- dbus_message_unref (welcome);
- return FALSE;
- }
-
- retval = dbus_connection_send_message (connection, welcome, NULL, NULL);
- dbus_message_unref (welcome);
-
- return retval;
+ _DBUS_HANDLE_OOM (dbus_message_set_sender (welcome, DBUS_SERVICE_DBUS));
+
+ _DBUS_HANDLE_OOM (dbus_message_append_fields (welcome,
+ DBUS_TYPE_STRING, name,
+ NULL));
+
+ _DBUS_HANDLE_OOM (dbus_connection_send_message (connection, welcome, NULL, NULL));
}
static void
@@ -240,26 +198,18 @@ bus_driver_handle_list_services (DBusConnection *connection,
int len, i;
char **services;
- reply = dbus_message_new_reply (BUS_DRIVER_SERVICES_NAME, message);
-
- if (reply == NULL)
- return;
+ _DBUS_HANDLE_OOM (reply = dbus_message_new_reply (DBUS_MESSAGE_SERVICES, message));
- services = bus_services_list (&len);
+ _DBUS_HANDLE_OOM (services = bus_services_list (&len));
- if (!services)
- goto error;
-
- if (!dbus_message_append_fields (reply,
- DBUS_TYPE_STRING_ARRAY, services, len,
- 0))
- goto error;
+ _DBUS_HANDLE_OOM (dbus_message_append_fields (reply,
+ DBUS_TYPE_STRING_ARRAY, services, len,
+ 0));
+
+ _DBUS_HANDLE_OOM (dbus_connection_send_message (connection, reply, NULL, NULL));
- if (!dbus_connection_send_message (connection, reply, NULL, NULL))
- goto error;
-
- error:
dbus_message_unref (reply);
+
if (services != NULL)
{
for (i = 0; i < len; i++)
@@ -268,57 +218,6 @@ bus_driver_handle_list_services (DBusConnection *connection,
}
}
-/* This is where all the magic occurs */
-static DBusHandlerResult
-bus_driver_message_handler (DBusMessageHandler *handler,
- DBusConnection *connection,
- DBusMessage *message,
- void *user_data)
-{
- const char *service, *name;
-
- service = dbus_message_get_service (message);
- name = dbus_message_get_name (message);
-
- dbus_message_set_sender (message,
- bus_connection_get_name (connection));
-
- if (strcmp (service, BUS_DRIVER_SERVICE_NAME) == 0)
- {
- if (strcmp (name, BUS_DRIVER_HELLO_NAME) == 0)
- bus_driver_handle_hello (connection, message);
- else if (strcmp (name, BUS_DRIVER_LIST_SERVICES_NAME) == 0)
- bus_driver_handle_list_services (connection, message);
- }
- else
- {
- /* FIXME: Dispatch the message :-) */
- }
-
- return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
-}
-
-dbus_bool_t
-bus_driver_add_connection (DBusConnection *connection)
-{
- DBusMessageHandler *handler;
-
- handler = dbus_message_handler_new (bus_driver_message_handler, NULL, NULL);
-
- if (!dbus_connection_add_filter (connection, handler))
- {
- dbus_message_handler_unref (handler);
-
- return FALSE;
- }
-
- /* FIXME we are leaking the DBusMessageHandler */
-
- _dbus_verbose ("D-Bus driver on board...\n");
-
- return TRUE;
-}
-
void
bus_driver_remove_connection (DBusConnection *connection)
{
@@ -335,6 +234,34 @@ bus_driver_remove_connection (DBusConnection *connection)
service = bus_service_lookup (&service_name, FALSE);
+ bus_driver_send_service_deleted (connection, name);
+
if (service)
bus_service_free (service);
}
+
+void
+bus_driver_handle_message (DBusConnection *connection,
+ DBusMessage *message)
+{
+ const char *name, *sender;
+
+ _dbus_verbose ("Driver got a message: %s\n",
+ dbus_message_get_name (message));
+
+ name = dbus_message_get_name (message);
+ sender = dbus_message_get_sender (message);
+
+ if (sender == NULL && (strcmp (name, DBUS_MESSAGE_HELLO) != 0))
+ {
+ _dbus_verbose ("Trying to send a message without being registered. Disconnecting.\n");
+ dbus_connection_disconnect (connection);
+ return;
+ }
+
+ /* Now check names. */
+ if (strcmp (name, DBUS_MESSAGE_HELLO) == 0)
+ bus_driver_handle_hello (connection, message);
+ else if (strcmp (name, DBUS_MESSAGE_LIST_SERVICES) == 0)
+ bus_driver_handle_list_services (connection, message);
+}
diff --git a/bus/driver.h b/bus/driver.h
index ea5638c3..897a2db2 100644
--- a/bus/driver.h
+++ b/bus/driver.h
@@ -26,7 +26,8 @@
#include <dbus/dbus.h>
-dbus_bool_t bus_driver_add_connection (DBusConnection *connection);
-void bus_driver_remove_connection (DBusConnection *connection);
+void bus_driver_handle_message (DBusConnection *connection,
+ DBusMessage *message);
+void bus_driver_remove_connection (DBusConnection *connection);
#endif /* BUS_DRIVER_H */