D-Bus 1.2.24
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 * 00022 */ 00023 00024 #include "dbus-internals.h" 00025 #include "dbus-server-unix.h" 00026 #include "dbus-server-socket.h" 00027 #include "dbus-transport-unix.h" 00028 #include "dbus-connection-internal.h" 00029 #include "dbus-sysdeps-unix.h" 00030 #include "dbus-string.h" 00031 00051 DBusServerListenResult 00052 _dbus_server_listen_platform_specific (DBusAddressEntry *entry, 00053 DBusServer **server_p, 00054 DBusError *error) 00055 { 00056 const char *method; 00057 00058 *server_p = NULL; 00059 00060 method = dbus_address_entry_get_method (entry); 00061 00062 if (strcmp (method, "unix") == 0) 00063 { 00064 const char *path = dbus_address_entry_get_value (entry, "path"); 00065 const char *tmpdir = dbus_address_entry_get_value (entry, "tmpdir"); 00066 const char *abstract = dbus_address_entry_get_value (entry, "abstract"); 00067 00068 if (path == NULL && tmpdir == NULL && abstract == NULL) 00069 { 00070 _dbus_set_bad_address(error, "unix", 00071 "path or tmpdir or abstract", 00072 NULL); 00073 return DBUS_SERVER_LISTEN_BAD_ADDRESS; 00074 } 00075 00076 if ((path && tmpdir) || 00077 (path && abstract) || 00078 (tmpdir && abstract)) 00079 { 00080 _dbus_set_bad_address(error, NULL, NULL, 00081 "cannot specify two of \"path\" and \"tmpdir\" and \"abstract\" at the same time"); 00082 return DBUS_SERVER_LISTEN_BAD_ADDRESS; 00083 } 00084 00085 if (tmpdir != NULL) 00086 { 00087 DBusString full_path; 00088 DBusString filename; 00089 00090 if (!_dbus_string_init (&full_path)) 00091 { 00092 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00093 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT; 00094 } 00095 00096 if (!_dbus_string_init (&filename)) 00097 { 00098 _dbus_string_free (&full_path); 00099 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00100 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT; 00101 } 00102 00103 if (!_dbus_string_append (&filename, 00104 "dbus-") || 00105 !_dbus_generate_random_ascii (&filename, 10) || 00106 !_dbus_string_append (&full_path, tmpdir) || 00107 !_dbus_concat_dir_and_file (&full_path, &filename)) 00108 { 00109 _dbus_string_free (&full_path); 00110 _dbus_string_free (&filename); 00111 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00112 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT; 00113 } 00114 00115 /* Always use abstract namespace if possible with tmpdir */ 00116 00117 *server_p = 00118 _dbus_server_new_for_domain_socket (_dbus_string_get_const_data (&full_path), 00119 #ifdef HAVE_ABSTRACT_SOCKETS 00120 TRUE, 00121 #else 00122 FALSE, 00123 #endif 00124 error); 00125 00126 _dbus_string_free (&full_path); 00127 _dbus_string_free (&filename); 00128 } 00129 else 00130 { 00131 if (path) 00132 *server_p = _dbus_server_new_for_domain_socket (path, FALSE, error); 00133 else 00134 *server_p = _dbus_server_new_for_domain_socket (abstract, TRUE, error); 00135 } 00136 00137 if (*server_p != NULL) 00138 { 00139 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 00140 return DBUS_SERVER_LISTEN_OK; 00141 } 00142 else 00143 { 00144 _DBUS_ASSERT_ERROR_IS_SET(error); 00145 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT; 00146 } 00147 } 00148 else 00149 { 00150 /* If we don't handle the method, we return NULL with the 00151 * error unset 00152 */ 00153 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 00154 return DBUS_SERVER_LISTEN_NOT_HANDLED; 00155 } 00156 } 00157 00166 DBusServer* 00167 _dbus_server_new_for_domain_socket (const char *path, 00168 dbus_bool_t abstract, 00169 DBusError *error) 00170 { 00171 DBusServer *server; 00172 int listen_fd; 00173 DBusString address; 00174 char *path_copy; 00175 DBusString path_str; 00176 00177 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00178 00179 if (!_dbus_string_init (&address)) 00180 { 00181 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00182 return NULL; 00183 } 00184 00185 _dbus_string_init_const (&path_str, path); 00186 if ((abstract && 00187 !_dbus_string_append (&address, "unix:abstract=")) || 00188 (!abstract && 00189 !_dbus_string_append (&address, "unix:path=")) || 00190 !_dbus_address_append_escaped (&address, &path_str)) 00191 { 00192 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00193 goto failed_0; 00194 } 00195 00196 path_copy = _dbus_strdup (path); 00197 if (path_copy == NULL) 00198 { 00199 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00200 goto failed_0; 00201 } 00202 00203 listen_fd = _dbus_listen_unix_socket (path, abstract, error); 00204 _dbus_fd_set_close_on_exec (listen_fd); 00205 00206 if (listen_fd < 0) 00207 { 00208 _DBUS_ASSERT_ERROR_IS_SET (error); 00209 goto failed_1; 00210 } 00211 00212 server = _dbus_server_new_for_socket (&listen_fd, 1, &address); 00213 if (server == NULL) 00214 { 00215 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00216 goto failed_2; 00217 } 00218 00219 _dbus_server_socket_own_filename(server, path_copy); 00220 00221 _dbus_string_free (&address); 00222 00223 return server; 00224 00225 failed_2: 00226 _dbus_close_socket (listen_fd, NULL); 00227 failed_1: 00228 dbus_free (path_copy); 00229 failed_0: 00230 _dbus_string_free (&address); 00231 00232 return NULL; 00233 } 00234