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 <sys/types.h>
00029 #include <unistd.h>
00030
00042 typedef struct DBusServerUnix DBusServerUnix;
00043
00048 struct DBusServerUnix
00049 {
00050 DBusServer base;
00051 int fd;
00052 DBusWatch *watch;
00053 char *socket_name;
00054 };
00055
00056 static void
00057 unix_finalize (DBusServer *server)
00058 {
00059 DBusServerUnix *unix_server = (DBusServerUnix*) server;
00060
00061 if (unix_server->watch)
00062 _dbus_watch_unref (unix_server->watch);
00063
00064 dbus_free (unix_server->socket_name);
00065
00066 _dbus_server_finalize_base (server);
00067
00068 dbus_free (server);
00069 }
00070
00076
00077 static dbus_bool_t
00078 handle_new_client_fd (DBusServer *server,
00079 int client_fd)
00080 {
00081 DBusConnection *connection;
00082 DBusTransport *transport;
00083
00084 _dbus_verbose ("Creating new client connection with fd %d\n", client_fd);
00085
00086 if (!_dbus_set_fd_nonblocking (client_fd, NULL))
00087 return TRUE;
00088
00089 transport = _dbus_transport_new_for_fd (client_fd, TRUE, NULL);
00090 if (transport == NULL)
00091 {
00092 close (client_fd);
00093 return FALSE;
00094 }
00095
00096 if (!_dbus_transport_set_auth_mechanisms (transport,
00097 (const char **) server->auth_mechanisms))
00098 {
00099 _dbus_transport_unref (transport);
00100 return FALSE;
00101 }
00102
00103
00104
00105
00106
00107 connection = _dbus_connection_new_for_transport (transport);
00108 _dbus_transport_unref (transport);
00109
00110 if (connection == NULL)
00111 return FALSE;
00112
00113
00114
00115
00116 if (server->new_connection_function)
00117 {
00118 dbus_server_ref (server);
00119
00120 (* server->new_connection_function) (server, connection,
00121 server->new_connection_data);
00122 dbus_server_unref (server);
00123 }
00124
00125
00126 dbus_connection_unref (connection);
00127
00128 return TRUE;
00129 }
00130
00131 static dbus_bool_t
00132 unix_handle_watch (DBusWatch *watch,
00133 unsigned int flags,
00134 void *data)
00135 {
00136 DBusServer *server = data;
00137 DBusServerUnix *unix_server = data;
00138
00139 _dbus_assert (watch == unix_server->watch);
00140
00141 _dbus_verbose ("Handling client connection, flags 0x%x\n", flags);
00142
00143 if (flags & DBUS_WATCH_READABLE)
00144 {
00145 int client_fd;
00146 int listen_fd;
00147
00148 listen_fd = dbus_watch_get_fd (watch);
00149
00150 client_fd = _dbus_accept (listen_fd);
00151
00152 if (client_fd < 0)
00153 {
00154
00155
00156 if (errno == EAGAIN || errno == EWOULDBLOCK)
00157 _dbus_verbose ("No client available to accept after all\n");
00158 else
00159 _dbus_verbose ("Failed to accept a client connection: %s\n",
00160 _dbus_strerror (errno));
00161 }
00162 else
00163 {
00164 _dbus_fd_set_close_on_exec (client_fd);
00165
00166 if (!handle_new_client_fd (server, client_fd))
00167 _dbus_verbose ("Rejected client connection due to lack of memory\n");
00168 }
00169 }
00170
00171 if (flags & DBUS_WATCH_ERROR)
00172 _dbus_verbose ("Error on server listening socket\n");
00173
00174 if (flags & DBUS_WATCH_HANGUP)
00175 _dbus_verbose ("Hangup on server listening socket\n");
00176
00177 return TRUE;
00178 }
00179
00180 static void
00181 unix_disconnect (DBusServer *server)
00182 {
00183 DBusServerUnix *unix_server = (DBusServerUnix*) server;
00184
00185 if (unix_server->watch)
00186 {
00187 _dbus_server_remove_watch (server,
00188 unix_server->watch);
00189 _dbus_watch_unref (unix_server->watch);
00190 unix_server->watch = NULL;
00191 }
00192
00193 close (unix_server->fd);
00194 unix_server->fd = -1;
00195
00196 if (unix_server->socket_name != NULL)
00197 {
00198 DBusString tmp;
00199 _dbus_string_init_const (&tmp, unix_server->socket_name);
00200 _dbus_delete_file (&tmp, NULL);
00201 }
00202 }
00203
00204 static DBusServerVTable unix_vtable = {
00205 unix_finalize,
00206 unix_disconnect
00207 };
00208
00222 DBusServer*
00223 _dbus_server_new_for_fd (int fd,
00224 const DBusString *address)
00225 {
00226 DBusServerUnix *unix_server;
00227 DBusWatch *watch;
00228
00229 unix_server = dbus_new0 (DBusServerUnix, 1);
00230 if (unix_server == NULL)
00231 return NULL;
00232
00233 watch = _dbus_watch_new (fd,
00234 DBUS_WATCH_READABLE,
00235 TRUE,
00236 unix_handle_watch, unix_server,
00237 NULL);
00238 if (watch == NULL)
00239 {
00240 dbus_free (unix_server);
00241 return NULL;
00242 }
00243
00244 if (!_dbus_server_init_base (&unix_server->base,
00245 &unix_vtable, address))
00246 {
00247 _dbus_watch_unref (watch);
00248 dbus_free (unix_server);
00249 return NULL;
00250 }
00251
00252 if (!_dbus_server_add_watch (&unix_server->base,
00253 watch))
00254 {
00255 _dbus_server_finalize_base (&unix_server->base);
00256 _dbus_watch_unref (watch);
00257 dbus_free (unix_server);
00258 return NULL;
00259 }
00260
00261 unix_server->fd = fd;
00262 unix_server->watch = watch;
00263
00264 return (DBusServer*) unix_server;
00265 }
00266
00275 DBusServer*
00276 _dbus_server_new_for_domain_socket (const char *path,
00277 dbus_bool_t abstract,
00278 DBusError *error)
00279 {
00280 DBusServer *server;
00281 DBusServerUnix *unix_server;
00282 int listen_fd;
00283 DBusString address;
00284 char *path_copy;
00285
00286 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00287
00288 if (!_dbus_string_init (&address))
00289 {
00290 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00291 return NULL;
00292 }
00293
00294 if ((abstract &&
00295 !_dbus_string_append (&address, "unix:abstract=")) ||
00296 (!abstract &&
00297 !_dbus_string_append (&address, "unix:path=")) ||
00298 !_dbus_string_append (&address, path))
00299 {
00300 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00301 goto failed_0;
00302 }
00303
00304 path_copy = _dbus_strdup (path);
00305 if (path_copy == NULL)
00306 {
00307 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00308 goto failed_0;
00309 }
00310
00311 listen_fd = _dbus_listen_unix_socket (path, abstract, error);
00312 _dbus_fd_set_close_on_exec (listen_fd);
00313
00314 if (listen_fd < 0)
00315 {
00316 _DBUS_ASSERT_ERROR_IS_SET (error);
00317 goto failed_1;
00318 }
00319
00320 server = _dbus_server_new_for_fd (listen_fd, &address);
00321 if (server == NULL)
00322 {
00323 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00324 goto failed_2;
00325 }
00326
00327 unix_server = (DBusServerUnix*) server;
00328 unix_server->socket_name = path_copy;
00329
00330 _dbus_string_free (&address);
00331
00332 return server;
00333
00334 failed_2:
00335 _dbus_close (listen_fd, NULL);
00336 failed_1:
00337 dbus_free (path_copy);
00338 failed_0:
00339 _dbus_string_free (&address);
00340
00341 return NULL;
00342 }
00343
00353 DBusServer*
00354 _dbus_server_new_for_tcp_socket (const char *host,
00355 dbus_uint32_t port,
00356 DBusError *error)
00357 {
00358 DBusServer *server;
00359 int listen_fd;
00360 DBusString address;
00361
00362 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00363
00364 if (!_dbus_string_init (&address))
00365 {
00366 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00367 return NULL;
00368 }
00369
00370 if (!_dbus_string_append (&address, "tcp:host=") ||
00371 !_dbus_string_append (&address, host) ||
00372 !_dbus_string_append (&address, ",port=") ||
00373 !_dbus_string_append_int (&address, port))
00374 {
00375 _dbus_string_free (&address);
00376 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00377 return NULL;
00378 }
00379
00380 listen_fd = _dbus_listen_tcp_socket (host, port, error);
00381 _dbus_fd_set_close_on_exec (listen_fd);
00382
00383 if (listen_fd < 0)
00384 {
00385 _dbus_string_free (&address);
00386 return NULL;
00387 }
00388
00389 server = _dbus_server_new_for_fd (listen_fd, &address);
00390 if (server == NULL)
00391 {
00392 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00393 close (listen_fd);
00394 _dbus_string_free (&address);
00395 return NULL;
00396 }
00397
00398 _dbus_string_free (&address);
00399
00400 return server;
00401
00402
00403 }
00404