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 <config.h>
00025 #include "dbus-internals.h"
00026 #include "dbus-server-unix.h"
00027 #include "dbus-server-socket.h"
00028 #include "dbus-transport-unix.h"
00029 #include "dbus-connection-internal.h"
00030 #include "dbus-sysdeps-unix.h"
00031 #include "dbus-string.h"
00032
00052 DBusServerListenResult
00053 _dbus_server_listen_platform_specific (DBusAddressEntry *entry,
00054 DBusServer **server_p,
00055 DBusError *error)
00056 {
00057 const char *method;
00058
00059 *server_p = NULL;
00060
00061 method = dbus_address_entry_get_method (entry);
00062
00063 if (strcmp (method, "unix") == 0)
00064 {
00065 const char *path = dbus_address_entry_get_value (entry, "path");
00066 const char *tmpdir = dbus_address_entry_get_value (entry, "tmpdir");
00067 const char *abstract = dbus_address_entry_get_value (entry, "abstract");
00068
00069 if (path == NULL && tmpdir == NULL && abstract == NULL)
00070 {
00071 _dbus_set_bad_address(error, "unix",
00072 "path or tmpdir or abstract",
00073 NULL);
00074 return DBUS_SERVER_LISTEN_BAD_ADDRESS;
00075 }
00076
00077 if ((path && tmpdir) ||
00078 (path && abstract) ||
00079 (tmpdir && abstract))
00080 {
00081 _dbus_set_bad_address(error, NULL, NULL,
00082 "cannot specify two of \"path\" and \"tmpdir\" and \"abstract\" at the same time");
00083 return DBUS_SERVER_LISTEN_BAD_ADDRESS;
00084 }
00085
00086 if (tmpdir != NULL)
00087 {
00088 DBusString full_path;
00089 DBusString filename;
00090
00091 if (!_dbus_string_init (&full_path))
00092 {
00093 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00094 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00095 }
00096
00097 if (!_dbus_string_init (&filename))
00098 {
00099 _dbus_string_free (&full_path);
00100 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00101 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00102 }
00103
00104 if (!_dbus_string_append (&filename,
00105 "dbus-") ||
00106 !_dbus_generate_random_ascii (&filename, 10) ||
00107 !_dbus_string_append (&full_path, tmpdir) ||
00108 !_dbus_concat_dir_and_file (&full_path, &filename))
00109 {
00110 _dbus_string_free (&full_path);
00111 _dbus_string_free (&filename);
00112 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00113 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00114 }
00115
00116
00117
00118 *server_p =
00119 _dbus_server_new_for_domain_socket (_dbus_string_get_const_data (&full_path),
00120 #ifdef HAVE_ABSTRACT_SOCKETS
00121 TRUE,
00122 #else
00123 FALSE,
00124 #endif
00125 error);
00126
00127 _dbus_string_free (&full_path);
00128 _dbus_string_free (&filename);
00129 }
00130 else
00131 {
00132 if (path)
00133 *server_p = _dbus_server_new_for_domain_socket (path, FALSE, error);
00134 else
00135 *server_p = _dbus_server_new_for_domain_socket (abstract, TRUE, error);
00136 }
00137
00138 if (*server_p != NULL)
00139 {
00140 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00141 return DBUS_SERVER_LISTEN_OK;
00142 }
00143 else
00144 {
00145 _DBUS_ASSERT_ERROR_IS_SET(error);
00146 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00147 }
00148 }
00149 else if (strcmp (method, "systemd") == 0)
00150 {
00151 int n, *fds;
00152 DBusString address;
00153
00154 n = _dbus_listen_systemd_sockets (&fds, error);
00155 if (n < 0)
00156 {
00157 _DBUS_ASSERT_ERROR_IS_SET (error);
00158 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00159 }
00160
00161 _dbus_string_init_const (&address, "systemd:");
00162
00163 *server_p = _dbus_server_new_for_socket (fds, n, &address, NULL);
00164 if (*server_p == NULL)
00165 {
00166 int i;
00167
00168 for (i = 0; i < n; i++)
00169 {
00170 _dbus_close_socket (fds[i], NULL);
00171 }
00172 dbus_free (fds);
00173
00174 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00175 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00176 }
00177
00178 dbus_free (fds);
00179
00180 return DBUS_SERVER_LISTEN_OK;
00181 }
00182 else
00183 {
00184
00185
00186
00187 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00188 return DBUS_SERVER_LISTEN_NOT_HANDLED;
00189 }
00190 }
00191
00200 DBusServer*
00201 _dbus_server_new_for_domain_socket (const char *path,
00202 dbus_bool_t abstract,
00203 DBusError *error)
00204 {
00205 DBusServer *server;
00206 int listen_fd;
00207 DBusString address;
00208 char *path_copy;
00209 DBusString path_str;
00210
00211 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00212
00213 if (!_dbus_string_init (&address))
00214 {
00215 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00216 return NULL;
00217 }
00218
00219 _dbus_string_init_const (&path_str, path);
00220 if ((abstract &&
00221 !_dbus_string_append (&address, "unix:abstract=")) ||
00222 (!abstract &&
00223 !_dbus_string_append (&address, "unix:path=")) ||
00224 !_dbus_address_append_escaped (&address, &path_str))
00225 {
00226 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00227 goto failed_0;
00228 }
00229
00230 path_copy = _dbus_strdup (path);
00231 if (path_copy == NULL)
00232 {
00233 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00234 goto failed_0;
00235 }
00236
00237 listen_fd = _dbus_listen_unix_socket (path, abstract, error);
00238
00239 if (listen_fd < 0)
00240 {
00241 _DBUS_ASSERT_ERROR_IS_SET (error);
00242 goto failed_1;
00243 }
00244
00245 server = _dbus_server_new_for_socket (&listen_fd, 1, &address, 0);
00246 if (server == NULL)
00247 {
00248 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00249 goto failed_2;
00250 }
00251
00252 _dbus_server_socket_own_filename(server, path_copy);
00253
00254 _dbus_string_free (&address);
00255
00256 return server;
00257
00258 failed_2:
00259 _dbus_close_socket (listen_fd, NULL);
00260 failed_1:
00261 dbus_free (path_copy);
00262 failed_0:
00263 _dbus_string_free (&address);
00264
00265 return NULL;
00266 }
00267