00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "dbus-internals.h"
00025 #include "dbus-server-unix.h"
00026 #include "dbus-transport-unix.h"
00027 #include "dbus-connection-internal.h"
00028 #include "dbus-string.h"
00029 #include <sys/types.h>
00030 #include <unistd.h>
00031
00043 typedef struct DBusServerUnix DBusServerUnix;
00044
00049 struct DBusServerUnix
00050 {
00051 DBusServer base;
00052 int fd;
00053 DBusWatch *watch;
00054 char *socket_name;
00055 };
00056
00057 static void
00058 unix_finalize (DBusServer *server)
00059 {
00060 DBusServerUnix *unix_server = (DBusServerUnix*) server;
00061
00062 _dbus_server_finalize_base (server);
00063
00064 dbus_free (unix_server->socket_name);
00065 dbus_free (server);
00066 }
00067
00073
00074 static dbus_bool_t
00075 handle_new_client_fd_and_unlock (DBusServer *server,
00076 int client_fd)
00077 {
00078 DBusConnection *connection;
00079 DBusTransport *transport;
00080 DBusNewConnectionFunction new_connection_function;
00081 void *new_connection_data;
00082
00083 _dbus_verbose ("Creating new client connection with fd %d\n", client_fd);
00084
00085 HAVE_LOCK_CHECK (server);
00086
00087 if (!_dbus_set_fd_nonblocking (client_fd, NULL))
00088 {
00089 SERVER_UNLOCK (server);
00090 return TRUE;
00091 }
00092
00093 transport = _dbus_transport_new_for_fd (client_fd, TRUE, NULL);
00094 if (transport == NULL)
00095 {
00096 close (client_fd);
00097 SERVER_UNLOCK (server);
00098 return FALSE;
00099 }
00100
00101 if (!_dbus_transport_set_auth_mechanisms (transport,
00102 (const char **) server->auth_mechanisms))
00103 {
00104 _dbus_transport_unref (transport);
00105 SERVER_UNLOCK (server);
00106 return FALSE;
00107 }
00108
00109
00110
00111
00112
00113 connection = _dbus_connection_new_for_transport (transport);
00114 _dbus_transport_unref (transport);
00115 transport = NULL;
00116
00117 if (connection == NULL)
00118 {
00119 SERVER_UNLOCK (server);
00120 return FALSE;
00121 }
00122
00123
00124
00125
00126 new_connection_function = server->new_connection_function;
00127 new_connection_data = server->new_connection_data;
00128
00129 _dbus_server_ref_unlocked (server);
00130 SERVER_UNLOCK (server);
00131
00132 if (new_connection_function)
00133 {
00134 (* new_connection_function) (server, connection,
00135 new_connection_data);
00136 dbus_server_unref (server);
00137 }
00138
00139
00140 dbus_connection_unref (connection);
00141
00142 return TRUE;
00143 }
00144
00145 static dbus_bool_t
00146 unix_handle_watch (DBusWatch *watch,
00147 unsigned int flags,
00148 void *data)
00149 {
00150 DBusServer *server = data;
00151 DBusServerUnix *unix_server = data;
00152
00153 SERVER_LOCK (server);
00154
00155 _dbus_assert (watch == unix_server->watch);
00156
00157 _dbus_verbose ("Handling client connection, flags 0x%x\n", flags);
00158
00159 if (flags & DBUS_WATCH_READABLE)
00160 {
00161 int client_fd;
00162 int listen_fd;
00163
00164 listen_fd = dbus_watch_get_fd (watch);
00165
00166 client_fd = _dbus_accept (listen_fd);
00167
00168 if (client_fd < 0)
00169 {
00170
00171
00172 if (errno == EAGAIN || errno == EWOULDBLOCK)
00173 _dbus_verbose ("No client available to accept after all\n");
00174 else
00175 _dbus_verbose ("Failed to accept a client connection: %s\n",
00176 _dbus_strerror (errno));
00177
00178 SERVER_UNLOCK (server);
00179 }
00180 else
00181 {
00182 _dbus_fd_set_close_on_exec (client_fd);
00183
00184 if (!handle_new_client_fd_and_unlock (server, client_fd))
00185 _dbus_verbose ("Rejected client connection due to lack of memory\n");
00186 }
00187 }
00188
00189 if (flags & DBUS_WATCH_ERROR)
00190 _dbus_verbose ("Error on server listening socket\n");
00191
00192 if (flags & DBUS_WATCH_HANGUP)
00193 _dbus_verbose ("Hangup on server listening socket\n");
00194
00195 return TRUE;
00196 }
00197
00198 static void
00199 unix_disconnect (DBusServer *server)
00200 {
00201 DBusServerUnix *unix_server = (DBusServerUnix*) server;
00202
00203 if (unix_server->watch)
00204 {
00205 _dbus_server_remove_watch (server,
00206 unix_server->watch);
00207 _dbus_watch_unref (unix_server->watch);
00208 unix_server->watch = NULL;
00209 }
00210
00211 close (unix_server->fd);
00212 unix_server->fd = -1;
00213
00214 if (unix_server->socket_name != NULL)
00215 {
00216 DBusString tmp;
00217 _dbus_string_init_const (&tmp, unix_server->socket_name);
00218 _dbus_delete_file (&tmp, NULL);
00219 }
00220 }
00221
00222 static DBusServerVTable unix_vtable = {
00223 unix_finalize,
00224 unix_disconnect
00225 };
00226
00240 DBusServer*
00241 _dbus_server_new_for_fd (int fd,
00242 const DBusString *address)
00243 {
00244 DBusServerUnix *unix_server;
00245 DBusWatch *watch;
00246
00247 unix_server = dbus_new0 (DBusServerUnix, 1);
00248 if (unix_server == NULL)
00249 return NULL;
00250
00251 watch = _dbus_watch_new (fd,
00252 DBUS_WATCH_READABLE,
00253 TRUE,
00254 unix_handle_watch, unix_server,
00255 NULL);
00256 if (watch == NULL)
00257 {
00258 dbus_free (unix_server);
00259 return NULL;
00260 }
00261
00262 if (!_dbus_server_init_base (&unix_server->base,
00263 &unix_vtable, address))
00264 {
00265 _dbus_watch_unref (watch);
00266 dbus_free (unix_server);
00267 return NULL;
00268 }
00269
00270 #ifndef DBUS_DISABLE_CHECKS
00271 unix_server->base.have_server_lock = TRUE;
00272 #endif
00273
00274 if (!_dbus_server_add_watch (&unix_server->base,
00275 watch))
00276 {
00277 _dbus_server_finalize_base (&unix_server->base);
00278 _dbus_watch_unref (watch);
00279 dbus_free (unix_server);
00280 return NULL;
00281 }
00282
00283 #ifndef DBUS_DISABLE_CHECKS
00284 unix_server->base.have_server_lock = FALSE;
00285 #endif
00286
00287 unix_server->fd = fd;
00288 unix_server->watch = watch;
00289
00290 return (DBusServer*) unix_server;
00291 }
00292
00301 DBusServer*
00302 _dbus_server_new_for_domain_socket (const char *path,
00303 dbus_bool_t abstract,
00304 DBusError *error)
00305 {
00306 DBusServer *server;
00307 DBusServerUnix *unix_server;
00308 int listen_fd;
00309 DBusString address;
00310 char *path_copy;
00311
00312 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00313
00314 if (!_dbus_string_init (&address))
00315 {
00316 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00317 return NULL;
00318 }
00319
00320 if ((abstract &&
00321 !_dbus_string_append (&address, "unix:abstract=")) ||
00322 (!abstract &&
00323 !_dbus_string_append (&address, "unix:path=")) ||
00324 !_dbus_string_append (&address, path))
00325 {
00326 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00327 goto failed_0;
00328 }
00329
00330 path_copy = _dbus_strdup (path);
00331 if (path_copy == NULL)
00332 {
00333 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00334 goto failed_0;
00335 }
00336
00337 listen_fd = _dbus_listen_unix_socket (path, abstract, error);
00338 _dbus_fd_set_close_on_exec (listen_fd);
00339
00340 if (listen_fd < 0)
00341 {
00342 _DBUS_ASSERT_ERROR_IS_SET (error);
00343 goto failed_1;
00344 }
00345
00346 server = _dbus_server_new_for_fd (listen_fd, &address);
00347 if (server == NULL)
00348 {
00349 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00350 goto failed_2;
00351 }
00352
00353 unix_server = (DBusServerUnix*) server;
00354 unix_server->socket_name = path_copy;
00355
00356 _dbus_string_free (&address);
00357
00358 return server;
00359
00360 failed_2:
00361 _dbus_close (listen_fd, NULL);
00362 failed_1:
00363 dbus_free (path_copy);
00364 failed_0:
00365 _dbus_string_free (&address);
00366
00367 return NULL;
00368 }
00369
00379 DBusServer*
00380 _dbus_server_new_for_tcp_socket (const char *host,
00381 dbus_uint32_t port,
00382 DBusError *error)
00383 {
00384 DBusServer *server;
00385 int listen_fd;
00386 DBusString address;
00387
00388 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00389
00390 if (!_dbus_string_init (&address))
00391 {
00392 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00393 return NULL;
00394 }
00395
00396 if (host == NULL)
00397 host = "localhost";
00398
00399 if (!_dbus_string_append (&address, "tcp:host=") ||
00400 !_dbus_string_append (&address, host) ||
00401 !_dbus_string_append (&address, ",port=") ||
00402 !_dbus_string_append_int (&address, port))
00403 {
00404 _dbus_string_free (&address);
00405 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00406 return NULL;
00407 }
00408
00409 listen_fd = _dbus_listen_tcp_socket (host, port, error);
00410 _dbus_fd_set_close_on_exec (listen_fd);
00411
00412 if (listen_fd < 0)
00413 {
00414 _dbus_string_free (&address);
00415 return NULL;
00416 }
00417
00418 server = _dbus_server_new_for_fd (listen_fd, &address);
00419 if (server == NULL)
00420 {
00421 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00422 close (listen_fd);
00423 _dbus_string_free (&address);
00424 return NULL;
00425 }
00426
00427 _dbus_string_free (&address);
00428
00429 return server;
00430
00431
00432 }
00433