Main Page | Modules | Data Structures | File List | Data Fields | Related Pages

dbus-server-unix.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */ 00002 /* dbus-server-unix.c Server implementation for Unix network protocols. 00003 * 00004 * Copyright (C) 2002, 2003, 2004 Red Hat Inc. 00005 * 00006 * Licensed under the Academic Free License version 2.1 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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_free (unix_server->socket_name); 00063 00064 _dbus_server_finalize_base (server); 00065 00066 dbus_free (server); 00067 } 00068 00074 /* Return value is just for memory, not other failures. */ 00075 static dbus_bool_t 00076 handle_new_client_fd (DBusServer *server, 00077 int client_fd) 00078 { 00079 DBusConnection *connection; 00080 DBusTransport *transport; 00081 00082 _dbus_verbose ("Creating new client connection with fd %d\n", client_fd); 00083 00084 if (!_dbus_set_fd_nonblocking (client_fd, NULL)) 00085 return TRUE; 00086 00087 transport = _dbus_transport_new_for_fd (client_fd, TRUE, NULL); 00088 if (transport == NULL) 00089 { 00090 close (client_fd); 00091 return FALSE; 00092 } 00093 00094 if (!_dbus_transport_set_auth_mechanisms (transport, 00095 (const char **) server->auth_mechanisms)) 00096 { 00097 _dbus_transport_unref (transport); 00098 return FALSE; 00099 } 00100 00101 /* note that client_fd is now owned by the transport, and will be 00102 * closed on transport disconnection/finalization 00103 */ 00104 00105 connection = _dbus_connection_new_for_transport (transport); 00106 _dbus_transport_unref (transport); 00107 00108 if (connection == NULL) 00109 return FALSE; 00110 00111 /* See if someone wants to handle this new connection, 00112 * self-referencing for paranoia 00113 */ 00114 if (server->new_connection_function) 00115 { 00116 dbus_server_ref (server); 00117 00118 (* server->new_connection_function) (server, connection, 00119 server->new_connection_data); 00120 dbus_server_unref (server); 00121 } 00122 00123 /* If no one grabbed a reference, the connection will die. */ 00124 dbus_connection_unref (connection); 00125 00126 return TRUE; 00127 } 00128 00129 static dbus_bool_t 00130 unix_handle_watch (DBusWatch *watch, 00131 unsigned int flags, 00132 void *data) 00133 { 00134 DBusServer *server = data; 00135 DBusServerUnix *unix_server = data; 00136 00137 _dbus_assert (watch == unix_server->watch); 00138 00139 _dbus_verbose ("Handling client connection, flags 0x%x\n", flags); 00140 00141 if (flags & DBUS_WATCH_READABLE) 00142 { 00143 int client_fd; 00144 int listen_fd; 00145 00146 listen_fd = dbus_watch_get_fd (watch); 00147 00148 client_fd = _dbus_accept (listen_fd); 00149 00150 if (client_fd < 0) 00151 { 00152 /* EINTR handled for us */ 00153 00154 if (errno == EAGAIN || errno == EWOULDBLOCK) 00155 _dbus_verbose ("No client available to accept after all\n"); 00156 else 00157 _dbus_verbose ("Failed to accept a client connection: %s\n", 00158 _dbus_strerror (errno)); 00159 } 00160 else 00161 { 00162 _dbus_fd_set_close_on_exec (client_fd); 00163 00164 if (!handle_new_client_fd (server, client_fd)) 00165 _dbus_verbose ("Rejected client connection due to lack of memory\n"); 00166 } 00167 } 00168 00169 if (flags & DBUS_WATCH_ERROR) 00170 _dbus_verbose ("Error on server listening socket\n"); 00171 00172 if (flags & DBUS_WATCH_HANGUP) 00173 _dbus_verbose ("Hangup on server listening socket\n"); 00174 00175 return TRUE; 00176 } 00177 00178 static void 00179 unix_disconnect (DBusServer *server) 00180 { 00181 DBusServerUnix *unix_server = (DBusServerUnix*) server; 00182 00183 if (unix_server->watch) 00184 { 00185 _dbus_server_remove_watch (server, 00186 unix_server->watch); 00187 _dbus_watch_unref (unix_server->watch); 00188 unix_server->watch = NULL; 00189 } 00190 00191 close (unix_server->fd); 00192 unix_server->fd = -1; 00193 00194 if (unix_server->socket_name != NULL) 00195 { 00196 DBusString tmp; 00197 _dbus_string_init_const (&tmp, unix_server->socket_name); 00198 _dbus_delete_file (&tmp, NULL); 00199 } 00200 } 00201 00202 static DBusServerVTable unix_vtable = { 00203 unix_finalize, 00204 unix_disconnect 00205 }; 00206 00220 DBusServer* 00221 _dbus_server_new_for_fd (int fd, 00222 const DBusString *address) 00223 { 00224 DBusServerUnix *unix_server; 00225 DBusWatch *watch; 00226 00227 unix_server = dbus_new0 (DBusServerUnix, 1); 00228 if (unix_server == NULL) 00229 return NULL; 00230 00231 watch = _dbus_watch_new (fd, 00232 DBUS_WATCH_READABLE, 00233 TRUE, 00234 unix_handle_watch, unix_server, 00235 NULL); 00236 if (watch == NULL) 00237 { 00238 dbus_free (unix_server); 00239 return NULL; 00240 } 00241 00242 if (!_dbus_server_init_base (&unix_server->base, 00243 &unix_vtable, address)) 00244 { 00245 _dbus_watch_unref (watch); 00246 dbus_free (unix_server); 00247 return NULL; 00248 } 00249 00250 if (!_dbus_server_add_watch (&unix_server->base, 00251 watch)) 00252 { 00253 _dbus_server_finalize_base (&unix_server->base); 00254 _dbus_watch_unref (watch); 00255 dbus_free (unix_server); 00256 return NULL; 00257 } 00258 00259 unix_server->fd = fd; 00260 unix_server->watch = watch; 00261 00262 return (DBusServer*) unix_server; 00263 } 00264 00273 DBusServer* 00274 _dbus_server_new_for_domain_socket (const char *path, 00275 dbus_bool_t abstract, 00276 DBusError *error) 00277 { 00278 DBusServer *server; 00279 DBusServerUnix *unix_server; 00280 int listen_fd; 00281 DBusString address; 00282 char *path_copy; 00283 00284 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00285 00286 if (!_dbus_string_init (&address)) 00287 { 00288 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00289 return NULL; 00290 } 00291 00292 if ((abstract && 00293 !_dbus_string_append (&address, "unix:abstract=")) || 00294 (!abstract && 00295 !_dbus_string_append (&address, "unix:path=")) || 00296 !_dbus_string_append (&address, path)) 00297 { 00298 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00299 goto failed_0; 00300 } 00301 00302 path_copy = _dbus_strdup (path); 00303 if (path_copy == NULL) 00304 { 00305 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00306 goto failed_0; 00307 } 00308 00309 listen_fd = _dbus_listen_unix_socket (path, abstract, error); 00310 _dbus_fd_set_close_on_exec (listen_fd); 00311 00312 if (listen_fd < 0) 00313 { 00314 _DBUS_ASSERT_ERROR_IS_SET (error); 00315 goto failed_1; 00316 } 00317 00318 server = _dbus_server_new_for_fd (listen_fd, &address); 00319 if (server == NULL) 00320 { 00321 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00322 goto failed_2; 00323 } 00324 00325 unix_server = (DBusServerUnix*) server; 00326 unix_server->socket_name = path_copy; 00327 00328 _dbus_string_free (&address); 00329 00330 return server; 00331 00332 failed_2: 00333 _dbus_close (listen_fd, NULL); 00334 failed_1: 00335 dbus_free (path_copy); 00336 failed_0: 00337 _dbus_string_free (&address); 00338 00339 return NULL; 00340 } 00341 00351 DBusServer* 00352 _dbus_server_new_for_tcp_socket (const char *host, 00353 dbus_uint32_t port, 00354 DBusError *error) 00355 { 00356 DBusServer *server; 00357 int listen_fd; 00358 DBusString address; 00359 00360 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00361 00362 if (!_dbus_string_init (&address)) 00363 { 00364 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00365 return NULL; 00366 } 00367 00368 if (host == NULL) 00369 host = "localhost"; 00370 00371 if (!_dbus_string_append (&address, "tcp:host=") || 00372 !_dbus_string_append (&address, host) || 00373 !_dbus_string_append (&address, ",port=") || 00374 !_dbus_string_append_int (&address, port)) 00375 { 00376 _dbus_string_free (&address); 00377 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00378 return NULL; 00379 } 00380 00381 listen_fd = _dbus_listen_tcp_socket (host, port, error); 00382 _dbus_fd_set_close_on_exec (listen_fd); 00383 00384 if (listen_fd < 0) 00385 { 00386 _dbus_string_free (&address); 00387 return NULL; 00388 } 00389 00390 server = _dbus_server_new_for_fd (listen_fd, &address); 00391 if (server == NULL) 00392 { 00393 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00394 close (listen_fd); 00395 _dbus_string_free (&address); 00396 return NULL; 00397 } 00398 00399 _dbus_string_free (&address); 00400 00401 return server; 00402 00403 00404 } 00405

Generated on Tue Oct 12 02:07:53 2004 for D-BUS by doxygen 1.3.7