2003-01-25 Anders Carlsson <andersca@codefactory.se>
authorAnders Carlsson <andersca@codefactory.se>
Sat, 25 Jan 2003 20:53:53 +0000 (20:53 +0000)
committerAnders Carlsson <andersca@codefactory.se>
Sat, 25 Jan 2003 20:53:53 +0000 (20:53 +0000)
* 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.

ChangeLog
bus/Makefile.am
bus/connection.c
bus/dispatch.c [new file with mode: 0644]
bus/dispatch.h [new file with mode: 0644]
bus/driver.c
bus/driver.h

index 7626157..1d9da0e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 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.
+       
+2003-01-25  Anders Carlsson  <andersca@codefactory.se>
+
        * dbus/dbus-internals.h:
        Add _DBUS_HANDLE_OOM macro, it doesn't do anything currently.
        
index af25867..488b0c7 100644 (file)
@@ -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                                  \
index 0fcfdbe..2b2a043 100644 (file)
@@ -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 (file)
index 0000000..a74b371
--- /dev/null
@@ -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 (file)
index 0000000..2fe3479
--- /dev/null
@@ -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 */
index eacca93..6e13e48 100644 (file)
 
 #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);
+}
index ea5638c..897a2db 100644 (file)
@@ -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 */