2003-01-25 Anders Carlsson <andersca@codefactory.se>
[platform/upstream/dbus.git] / bus / dispatch.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dispatch.c  Message dispatcher
3  *
4  * Copyright (C) 2003  CodeFactory AB
5  *
6  * Licensed under the Academic Free License version 1.2
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 #include "dispatch.h"
25 #include "connection.h"
26 #include "driver.h"
27 #include <dbus/dbus-internals.h>
28 #include <string.h>
29
30 static int message_handler_slot;
31
32 static void
33 send_one_message (DBusConnection *connection, void *data)
34 {
35   _DBUS_HANDLE_OOM (dbus_connection_send_message (connection, data, NULL, NULL));
36 }
37
38 void
39 bus_dispatch_broadcast_message (DBusMessage *message)
40 {
41   _dbus_assert (dbus_message_get_sender (message) != NULL);
42   
43   bus_connection_foreach (send_one_message, message);
44   
45 }
46
47 static DBusHandlerResult
48 bus_dispatch_message_handler (DBusMessageHandler *handler,
49                               DBusConnection     *connection,
50                               DBusMessage        *message,
51                               void               *user_data)
52 {
53   const char *sender, *service;
54   
55   /* Assign a sender to the message */
56   sender = bus_connection_get_name (connection);
57   _DBUS_HANDLE_OOM (dbus_message_set_sender (message, sender));
58
59   service = dbus_message_get_service (message);
60   
61   /* See if the message is to the driver */
62   if (strcmp (service, DBUS_SERVICE_DBUS) == 0)
63     {
64       bus_driver_handle_message (connection, message);
65     }
66   else if (sender == NULL)
67     {
68       _dbus_verbose ("Received message from non-registered client. Disconnecting.\n");
69       dbus_connection_disconnect (connection);
70     }
71   else if (strcmp (service, DBUS_SERVICE_BROADCAST) == 0)
72     {
73       bus_dispatch_broadcast_message (message);
74     }
75   else  
76     {
77       /* Dispatch the message */
78     }
79
80   return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
81 }
82
83 dbus_bool_t
84 bus_dispatch_add_connection (DBusConnection *connection)
85 {
86   DBusMessageHandler *handler;
87   
88   message_handler_slot = dbus_connection_allocate_data_slot ();
89
90   if (message_handler_slot < 0)
91     return FALSE;
92
93   handler = dbus_message_handler_new (bus_dispatch_message_handler, NULL, NULL);  
94
95   if (!dbus_connection_add_filter (connection, handler))
96     {
97       dbus_message_handler_unref (handler);
98
99       return FALSE;
100     }
101
102   if (!dbus_connection_set_data (connection,
103                                  message_handler_slot,
104                                  handler,
105                                  (DBusFreeFunction)dbus_message_handler_unref))
106     {
107       dbus_connection_remove_filter (connection, handler);
108       dbus_message_handler_unref (handler);
109
110       return FALSE;
111     }
112
113   return TRUE;
114 }
115
116 void
117 bus_dispatch_remove_connection (DBusConnection *connection)
118 {
119   /* Here we tell the bus driver that we want to get off. */
120   bus_driver_remove_connection (connection);
121   
122   dbus_connection_set_data (connection,
123                             message_handler_slot,
124                             NULL, NULL);
125 }
126