2003-01-28 Anders Carlsson <set EMAIL_ADDRESS environment variable>
[platform/upstream/dbus.git] / dbus / dbus-server-debug.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-server-debug.h In-proc debug server implementation 
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 "dbus-internals.h"
25 #include "dbus-server-debug.h"
26 #include "dbus-transport-debug.h"
27 #include "dbus-connection-internal.h"
28 #include "dbus-hash.h"
29
30 #ifdef DBUS_BUILD_TESTS
31
32 #define DEFAULT_INTERVAL 10
33
34 typedef struct DBusServerDebug DBusServerDebug;
35
36 /**
37  * Implementation details of DBusServerDebug. All members
38  * are private.
39  */
40 struct DBusServerDebug
41 {
42   DBusServer base;  /**< Parent class members. */
43
44   char *name; /**< Server name. */
45 };
46
47 static DBusHashTable *server_hash;
48
49 static void
50 debug_finalize (DBusServer *server)
51 {
52 }
53
54 static void
55 debug_handle_watch (DBusServer  *server,
56                     DBusWatch   *watch,
57                     unsigned int flags)
58 {
59 }
60
61 static void
62 debug_disconnect (DBusServer *server)
63 {
64 }
65
66 static DBusServerVTable debug_vtable = {
67   debug_finalize,
68   debug_handle_watch,
69   debug_disconnect
70 };
71
72 DBusServer*
73 _dbus_server_debug_lookup (const char *server_name)
74 {
75   if (!server_hash)
76     return NULL;
77
78   return _dbus_hash_table_lookup_string (server_hash, server_name);
79 }
80
81 DBusServer*
82 _dbus_server_debug_new (const char     *server_name,
83                         DBusResultCode *result)
84 {
85   DBusServerDebug *debug_server;
86
87   if (!server_hash)
88     {
89       server_hash = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, NULL);
90
91       if (!server_hash)
92         {
93           dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
94           return NULL;
95         }
96     }
97
98   if (_dbus_hash_table_lookup_string (server_hash, server_name) != NULL)
99     {
100       dbus_set_result (result, DBUS_RESULT_ADDRESS_IN_USE);
101       return NULL;
102     }
103   
104   debug_server = dbus_new0 (DBusServerDebug, 1);
105
106   if (debug_server == NULL)
107     return NULL;
108
109   debug_server->name = _dbus_strdup (server_name);
110   if (debug_server->name == NULL)
111     {
112       dbus_free (debug_server->name);
113       dbus_free (debug_server);
114
115       dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
116     }
117   
118   if (!_dbus_server_init_base (&debug_server->base,
119                                &debug_vtable))
120     {
121       dbus_free (debug_server->name);      
122       dbus_free (debug_server);
123
124       dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
125
126       return NULL;
127     }
128
129   if (!_dbus_hash_table_insert_string (server_hash,
130                                        debug_server->name,
131                                        debug_server))
132     {
133       _dbus_server_finalize_base (&debug_server->base);
134       dbus_free (debug_server->name);      
135       dbus_free (debug_server);
136
137       dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
138
139       return NULL;
140     }
141   
142   dbus_set_result (result, DBUS_RESULT_SUCCESS);
143   
144   return (DBusServer *)debug_server;
145 }
146
147 typedef struct
148 {
149   DBusServer *server;
150   DBusTransport *transport;
151   
152 } ServerAndTransport;
153
154 static void
155 handle_new_client (void *data)
156 {
157   ServerAndTransport *st = data;
158   DBusTransport *transport;
159   DBusConnection *connection;
160   
161   transport = _dbus_transport_debug_server_new (st->transport);
162   if (transport == NULL)
163     {
164       return;
165     }
166
167   connection = _dbus_connection_new_for_transport (transport);
168   _dbus_transport_unref (transport);
169
170   if (connection == NULL)
171     return;
172
173   /* See if someone wants to handle this new connection,
174    * self-referencing for paranoia
175    */
176   if (st->server->new_connection_function)
177     {
178       dbus_server_ref (st->server);
179       
180       (* st->server->new_connection_function) (st->server, connection,
181                                                st->server->new_connection_data);
182       dbus_server_unref (st->server);
183     }
184   
185   /* If no one grabbed a reference, the connection will die. */
186   dbus_connection_unref (connection);
187 }
188
189 dbus_bool_t
190 _dbus_server_debug_accept_transport (DBusServer     *server,
191                                      DBusTransport  *transport)
192 {
193   DBusTimeout *timeout;
194   ServerAndTransport *st;
195
196   st = dbus_new (ServerAndTransport, 1);
197   if (st == NULL)
198     return FALSE;
199
200   st->transport = transport;
201   st->server = server;
202   
203   timeout = _dbus_timeout_new (DEFAULT_INTERVAL, handle_new_client, st, dbus_free);
204
205   if (timeout == NULL)
206     {
207       dbus_free (st);
208       return FALSE;
209     }
210
211   if (!_dbus_server_add_timeout (server, timeout))
212     {
213       _dbus_timeout_unref (timeout);
214       
215       return FALSE;
216     }
217
218   return TRUE;
219 }
220
221 #endif /* DBUS_BUILD_TESTS */
222