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-unix.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
00138 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00139
00140
if (!pipe_hash_ref ())
00141
return NULL;
00142
00143
if (
_dbus_hash_table_lookup_string (server_pipe_hash, server_name) !=
NULL)
00144 {
00145
dbus_set_error (error, DBUS_ERROR_ADDRESS_IN_USE, NULL);
00146 pipe_hash_unref ();
00147
return NULL;
00148 }
00149
00150 debug_server =
dbus_new0 (DBusServerDebugPipe, 1);
00151
if (debug_server ==
NULL)
00152
goto nomem_0;
00153
00154
if (!
_dbus_string_init (&address))
00155
goto nomem_1;
00156
00157
if (!
_dbus_string_append (&address,
"debug-pipe:name=") ||
00158 !
_dbus_string_append (&address, server_name))
00159
goto nomem_2;
00160
00161 debug_server->name =
_dbus_strdup (server_name);
00162
if (debug_server->name ==
NULL)
00163
goto nomem_2;
00164
00165
if (!
_dbus_server_init_base (&debug_server->base,
00166 &debug_vtable, &address))
00167
goto nomem_3;
00168
00169
if (!
_dbus_hash_table_insert_string (server_pipe_hash,
00170 debug_server->name,
00171 debug_server))
00172
goto nomem_4;
00173
00174
_dbus_string_free (&address);
00175
00176
00177
00178
return (
DBusServer *)debug_server;
00179
00180 nomem_4:
00181
_dbus_server_finalize_base (&debug_server->base);
00182 nomem_3:
00183
dbus_free (debug_server->name);
00184 nomem_2:
00185
_dbus_string_free (&address);
00186 nomem_1:
00187
dbus_free (debug_server);
00188 nomem_0:
00189 pipe_hash_unref ();
00190
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00191
return NULL;
00192 }
00193
00203
DBusTransport*
00204 _dbus_transport_debug_pipe_new (
const char *server_name,
00205
DBusError *error)
00206 {
00207
DBusTransport *client_transport;
00208
DBusTransport *server_transport;
00209
DBusConnection *connection;
00210
int client_fd, server_fd;
00211
DBusServer *server;
00212
DBusString address;
00213
00214 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00215
00216
if (server_pipe_hash ==
NULL)
00217 {
00218
dbus_set_error (error, DBUS_ERROR_NO_SERVER, NULL);
00219
return NULL;
00220 }
00221
00222 server =
_dbus_hash_table_lookup_string (server_pipe_hash,
00223 server_name);
00224
if (server ==
NULL ||
00225 ((DBusServerDebugPipe*)server)->disconnected)
00226 {
00227
dbus_set_error (error, DBUS_ERROR_NO_SERVER, NULL);
00228
return NULL;
00229 }
00230
00231
if (!
_dbus_string_init (&address))
00232 {
00233
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00234
return NULL;
00235 }
00236
00237
if (!
_dbus_string_append (&address,
"debug-pipe:name=") ||
00238 !
_dbus_string_append (&address, server_name))
00239 {
00240
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00241
_dbus_string_free (&address);
00242
return NULL;
00243 }
00244
00245
if (!
_dbus_full_duplex_pipe (&client_fd, &server_fd, FALSE,
00246 NULL))
00247 {
00248 _dbus_verbose (
"failed to create full duplex pipe\n");
00249
dbus_set_error (error, DBUS_ERROR_FAILED,
"Could not create full-duplex pipe");
00250
_dbus_string_free (&address);
00251
return NULL;
00252 }
00253
00254
_dbus_fd_set_close_on_exec (client_fd);
00255
_dbus_fd_set_close_on_exec (server_fd);
00256
00257 client_transport =
_dbus_transport_new_for_fd (client_fd,
00258 FALSE, &address);
00259
if (client_transport ==
NULL)
00260 {
00261
_dbus_close (client_fd, NULL);
00262
_dbus_close (server_fd, NULL);
00263
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00264
_dbus_string_free (&address);
00265
return NULL;
00266 }
00267
00268
_dbus_string_free (&address);
00269
00270 client_fd = -1;
00271
00272 server_transport =
_dbus_transport_new_for_fd (server_fd,
00273 TRUE, NULL);
00274
if (server_transport ==
NULL)
00275 {
00276
_dbus_transport_unref (client_transport);
00277
_dbus_close (server_fd, NULL);
00278
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00279
return NULL;
00280 }
00281
00282 server_fd = -1;
00283
00284
if (!
_dbus_transport_set_auth_mechanisms (server_transport,
00285 (
const char**) server->
auth_mechanisms))
00286 {
00287
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00288
_dbus_transport_unref (server_transport);
00289
_dbus_transport_unref (client_transport);
00290
return FALSE;
00291 }
00292
00293 connection =
_dbus_connection_new_for_transport (server_transport);
00294
_dbus_transport_unref (server_transport);
00295 server_transport =
NULL;
00296
00297
if (connection ==
NULL)
00298 {
00299
_dbus_transport_unref (client_transport);
00300
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00301
return NULL;
00302 }
00303
00304
00305
00306
00307
if (server->
new_connection_function)
00308 {
00309
dbus_server_ref (server);
00310 (* server->
new_connection_function) (server, connection,
00311 server->
new_connection_data);
00312
dbus_server_unref (server);
00313 }
00314
00315
00316
00317
00318
dbus_connection_unref (connection);
00319
00320
return client_transport;
00321 }
00322
00323
00326
#endif
00327