00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "dbus-internals.h"
00026 #include "dbus-server-debug-pipe.h"
00027 #include "dbus-transport-socket.h"
00028 #include "dbus-connection-internal.h"
00029 #include "dbus-hash.h"
00030 #include "dbus-string.h"
00031 #include "dbus-protocol.h"
00032
00033 #ifdef DBUS_BUILD_TESTS
00034
00049 typedef struct DBusServerDebugPipe DBusServerDebugPipe;
00050
00055 struct DBusServerDebugPipe
00056 {
00057 DBusServer base;
00059 char *name;
00061 dbus_bool_t disconnected;
00062 };
00063
00064
00065 static DBusHashTable *server_pipe_hash;
00066 static int server_pipe_hash_refcount = 0;
00067
00068 static dbus_bool_t
00069 pipe_hash_ref (void)
00070 {
00071 if (!server_pipe_hash)
00072 {
00073 _dbus_assert (server_pipe_hash_refcount == 0);
00074
00075 server_pipe_hash = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, NULL);
00076
00077 if (!server_pipe_hash)
00078 return FALSE;
00079 }
00080
00081 server_pipe_hash_refcount = 1;
00082
00083 return TRUE;
00084 }
00085
00086 static void
00087 pipe_hash_unref (void)
00088 {
00089 _dbus_assert (server_pipe_hash != NULL);
00090 _dbus_assert (server_pipe_hash_refcount > 0);
00091
00092 server_pipe_hash_refcount -= 1;
00093 if (server_pipe_hash_refcount == 0)
00094 {
00095 _dbus_hash_table_unref (server_pipe_hash);
00096 server_pipe_hash = NULL;
00097 }
00098 }
00099
00100 static void
00101 debug_finalize (DBusServer *server)
00102 {
00103 DBusServerDebugPipe *debug_server = (DBusServerDebugPipe*) server;
00104
00105 pipe_hash_unref ();
00106
00107 _dbus_server_finalize_base (server);
00108
00109 dbus_free (debug_server->name);
00110 dbus_free (server);
00111 }
00112
00113 static void
00114 debug_disconnect (DBusServer *server)
00115 {
00116 ((DBusServerDebugPipe*)server)->disconnected = TRUE;
00117 }
00118
00119 static DBusServerVTable debug_vtable = {
00120 debug_finalize,
00121 debug_disconnect
00122 };
00123
00131 DBusServer*
00132 _dbus_server_debug_pipe_new (const char *server_name,
00133 DBusError *error)
00134 {
00135 DBusServerDebugPipe *debug_server;
00136 DBusString address;
00137 DBusString name_str;
00138
00139 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00140
00141 if (!pipe_hash_ref ())
00142 return NULL;
00143
00144 if (_dbus_hash_table_lookup_string (server_pipe_hash, server_name) != NULL)
00145 {
00146 dbus_set_error (error, DBUS_ERROR_ADDRESS_IN_USE, NULL);
00147 pipe_hash_unref ();
00148 return NULL;
00149 }
00150
00151 debug_server = dbus_new0 (DBusServerDebugPipe, 1);
00152 if (debug_server == NULL)
00153 goto nomem_0;
00154
00155 if (!_dbus_string_init (&address))
00156 goto nomem_1;
00157
00158 _dbus_string_init_const (&name_str, server_name);
00159 if (!_dbus_string_append (&address, "debug-pipe:name=") ||
00160 !_dbus_address_append_escaped (&address, &name_str))
00161 goto nomem_2;
00162
00163 debug_server->name = _dbus_strdup (server_name);
00164 if (debug_server->name == NULL)
00165 goto nomem_2;
00166
00167 if (!_dbus_server_init_base (&debug_server->base,
00168 &debug_vtable, &address))
00169 goto nomem_3;
00170
00171 if (!_dbus_hash_table_insert_string (server_pipe_hash,
00172 debug_server->name,
00173 debug_server))
00174 goto nomem_4;
00175
00176 _dbus_string_free (&address);
00177
00178
00179
00180 return (DBusServer *)debug_server;
00181
00182 nomem_4:
00183 _dbus_server_finalize_base (&debug_server->base);
00184 nomem_3:
00185 dbus_free (debug_server->name);
00186 nomem_2:
00187 _dbus_string_free (&address);
00188 nomem_1:
00189 dbus_free (debug_server);
00190 nomem_0:
00191 pipe_hash_unref ();
00192 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00193 return NULL;
00194 }
00195
00205 DBusTransport*
00206 _dbus_transport_debug_pipe_new (const char *server_name,
00207 DBusError *error)
00208 {
00209 DBusTransport *client_transport;
00210 DBusTransport *server_transport;
00211 DBusConnection *connection;
00212 int client_fd, server_fd;
00213 DBusServer *server;
00214 DBusString address;
00215
00216 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00217
00218 if (server_pipe_hash == NULL)
00219 {
00220 dbus_set_error (error, DBUS_ERROR_NO_SERVER, NULL);
00221 return NULL;
00222 }
00223
00224 server = _dbus_hash_table_lookup_string (server_pipe_hash,
00225 server_name);
00226 if (server == NULL ||
00227 ((DBusServerDebugPipe*)server)->disconnected)
00228 {
00229 dbus_set_error (error, DBUS_ERROR_NO_SERVER, NULL);
00230 return NULL;
00231 }
00232
00233 if (!_dbus_string_init (&address))
00234 {
00235 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00236 return NULL;
00237 }
00238
00239 if (!_dbus_string_append (&address, "debug-pipe:name=") ||
00240 !_dbus_string_append (&address, server_name))
00241 {
00242 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00243 _dbus_string_free (&address);
00244 return NULL;
00245 }
00246
00247 if (!_dbus_full_duplex_pipe (&client_fd, &server_fd, FALSE,
00248 NULL))
00249 {
00250 _dbus_verbose ("failed to create full duplex pipe\n");
00251 dbus_set_error (error, DBUS_ERROR_FAILED, "Could not create full-duplex pipe");
00252 _dbus_string_free (&address);
00253 return NULL;
00254 }
00255
00256 _dbus_fd_set_close_on_exec (client_fd);
00257 _dbus_fd_set_close_on_exec (server_fd);
00258
00259 client_transport = _dbus_transport_new_for_socket (client_fd,
00260 NULL, &address);
00261 if (client_transport == NULL)
00262 {
00263 _dbus_close_socket (client_fd, NULL);
00264 _dbus_close_socket (server_fd, NULL);
00265 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00266 _dbus_string_free (&address);
00267 return NULL;
00268 }
00269
00270 _dbus_string_free (&address);
00271
00272 client_fd = -1;
00273
00274 server_transport = _dbus_transport_new_for_socket (server_fd,
00275 &server->guid_hex, NULL);
00276 if (server_transport == NULL)
00277 {
00278 _dbus_transport_unref (client_transport);
00279 _dbus_close_socket (server_fd, NULL);
00280 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00281 return NULL;
00282 }
00283
00284 server_fd = -1;
00285
00286 if (!_dbus_transport_set_auth_mechanisms (server_transport,
00287 (const char**) server->auth_mechanisms))
00288 {
00289 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00290 _dbus_transport_unref (server_transport);
00291 _dbus_transport_unref (client_transport);
00292 return NULL;
00293 }
00294
00295 connection = _dbus_connection_new_for_transport (server_transport);
00296 _dbus_transport_unref (server_transport);
00297 server_transport = NULL;
00298
00299 if (connection == NULL)
00300 {
00301 _dbus_transport_unref (client_transport);
00302 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00303 return NULL;
00304 }
00305
00306
00307
00308
00309 if (server->new_connection_function)
00310 {
00311 dbus_server_ref (server);
00312 (* server->new_connection_function) (server, connection,
00313 server->new_connection_data);
00314 dbus_server_unref (server);
00315 }
00316
00317
00318
00319
00320 _dbus_connection_close_if_only_one_ref (connection);
00321 dbus_connection_unref (connection);
00322
00323 return client_transport;
00324 }
00325
00337 DBusServerListenResult
00338 _dbus_server_listen_debug_pipe (DBusAddressEntry *entry,
00339 DBusServer **server_p,
00340 DBusError *error)
00341 {
00342 const char *method;
00343
00344 *server_p = NULL;
00345
00346 method = dbus_address_entry_get_method (entry);
00347
00348 if (strcmp (method, "debug-pipe") == 0)
00349 {
00350 const char *name = dbus_address_entry_get_value (entry, "name");
00351
00352 if (name == NULL)
00353 {
00354 _dbus_set_bad_address(error, "debug-pipe", "name",
00355 NULL);
00356 return DBUS_SERVER_LISTEN_BAD_ADDRESS;
00357 }
00358
00359 *server_p = _dbus_server_debug_pipe_new (name, error);
00360
00361 if (*server_p)
00362 {
00363 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00364 return DBUS_SERVER_LISTEN_OK;
00365 }
00366 else
00367 {
00368 _DBUS_ASSERT_ERROR_IS_SET(error);
00369 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00370 }
00371 }
00372 else
00373 {
00374 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00375 return DBUS_SERVER_LISTEN_NOT_HANDLED;
00376 }
00377 }
00378
00387 DBusTransportOpenResult
00388 _dbus_transport_open_debug_pipe (DBusAddressEntry *entry,
00389 DBusTransport **transport_p,
00390 DBusError *error)
00391 {
00392 const char *method;
00393
00394 method = dbus_address_entry_get_method (entry);
00395 _dbus_assert (method != NULL);
00396
00397 if (strcmp (method, "debug-pipe") == 0)
00398 {
00399 const char *name = dbus_address_entry_get_value (entry, "name");
00400
00401 if (name == NULL)
00402 {
00403 _dbus_set_bad_address (error, "debug-pipe", "name",
00404 NULL);
00405 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
00406 }
00407
00408 *transport_p = _dbus_transport_debug_pipe_new (name, error);
00409
00410 if (*transport_p == NULL)
00411 {
00412 _DBUS_ASSERT_ERROR_IS_SET (error);
00413 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
00414 }
00415 else
00416 {
00417 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00418 return DBUS_TRANSPORT_OPEN_OK;
00419 }
00420 }
00421 else
00422 {
00423 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00424 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
00425 }
00426 }
00427
00428
00431 #endif
00432