diff options
author | Anders Carlsson <andersca@codefactory.se> | 2003-01-25 20:53:53 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@codefactory.se> | 2003-01-25 20:53:53 +0000 |
commit | 39dd1fcee640b4a5a9abb453a9ccd5b7e099ba1c (patch) | |
tree | 152435396d67fa175d8a27ccb827f1bdb54917ba /bus | |
parent | fdddf7246da9ea6ce841146e2befe843aede0466 (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.am | 2 | ||||
-rw-r--r-- | bus/connection.c | 11 | ||||
-rw-r--r-- | bus/dispatch.c | 126 | ||||
-rw-r--r-- | bus/dispatch.h | 34 | ||||
-rw-r--r-- | bus/driver.c | 251 | ||||
-rw-r--r-- | bus/driver.h | 5 |
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 */ |