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-server-launchd.h"
00029 #include "dbus-transport-unix.h"
00030 #include "dbus-connection-internal.h"
00031 #include "dbus-sysdeps-unix.h"
00032 #include "dbus-string.h"
00033
00053 DBusServerListenResult
00054 _dbus_server_listen_platform_specific (DBusAddressEntry *entry,
00055 DBusServer **server_p,
00056 DBusError *error)
00057 {
00058 const char *method;
00059
00060 *server_p = NULL;
00061
00062 method = dbus_address_entry_get_method (entry);
00063
00064 if (strcmp (method, "unix") == 0)
00065 {
00066 const char *path = dbus_address_entry_get_value (entry, "path");
00067 const char *tmpdir = dbus_address_entry_get_value (entry, "tmpdir");
00068 const char *abstract = dbus_address_entry_get_value (entry, "abstract");
00069 const char *runtime = dbus_address_entry_get_value (entry, "runtime");
00070 int mutually_exclusive_modes = 0;
00071
00072 mutually_exclusive_modes = (path != NULL) + (tmpdir != NULL) +
00073 (abstract != NULL) + (runtime != NULL);
00074
00075 if (mutually_exclusive_modes < 1)
00076 {
00077 _dbus_set_bad_address(error, "unix",
00078 "path or tmpdir or abstract or runtime",
00079 NULL);
00080 return DBUS_SERVER_LISTEN_BAD_ADDRESS;
00081 }
00082
00083 if (mutually_exclusive_modes > 1)
00084 {
00085 _dbus_set_bad_address(error, NULL, NULL,
00086 "cannot specify two of \"path\", \"tmpdir\", \"abstract\" and \"runtime\" at the same time");
00087 return DBUS_SERVER_LISTEN_BAD_ADDRESS;
00088 }
00089
00090 if (runtime != NULL)
00091 {
00092 DBusString full_path;
00093 DBusString filename;
00094 const char *runtimedir;
00095
00096 if (strcmp (runtime, "yes") != 0)
00097 {
00098 _dbus_set_bad_address(error, NULL, NULL,
00099 "if given, the only value allowed for \"runtime\" is \"yes\"");
00100 return DBUS_SERVER_LISTEN_BAD_ADDRESS;
00101 }
00102
00103 runtimedir = _dbus_getenv ("XDG_RUNTIME_DIR");
00104
00105 if (runtimedir == NULL)
00106 {
00107 dbus_set_error (error,
00108 DBUS_ERROR_NOT_SUPPORTED, "\"XDG_RUNTIME_DIR\" is not set");
00109 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00110 }
00111
00112 _dbus_string_init_const (&filename, "bus");
00113
00114 if (!_dbus_string_init (&full_path))
00115 {
00116 _DBUS_SET_OOM (error);
00117 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00118 }
00119
00120 if (!_dbus_string_append (&full_path, runtimedir) ||
00121 !_dbus_concat_dir_and_file (&full_path, &filename))
00122 {
00123 _dbus_string_free (&full_path);
00124 _DBUS_SET_OOM (error);
00125 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00126 }
00127
00128
00129
00130
00131 *server_p = _dbus_server_new_for_domain_socket (
00132 _dbus_string_get_const_data (&full_path),
00133 FALSE, error);
00134
00135 _dbus_string_free (&full_path);
00136 }
00137 else if (tmpdir != NULL)
00138 {
00139 DBusString full_path;
00140 DBusString filename;
00141
00142 if (!_dbus_string_init (&full_path))
00143 {
00144 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00145 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00146 }
00147
00148 if (!_dbus_string_init (&filename))
00149 {
00150 _dbus_string_free (&full_path);
00151 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00152 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00153 }
00154
00155 if (!_dbus_string_append (&filename, "dbus-"))
00156 {
00157 _dbus_string_free (&full_path);
00158 _dbus_string_free (&filename);
00159 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00160 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00161 }
00162
00163 if (!_dbus_generate_random_ascii (&filename, 10, error))
00164 {
00165 _dbus_string_free (&full_path);
00166 _dbus_string_free (&filename);
00167 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00168 }
00169
00170 if (!_dbus_string_append (&full_path, tmpdir) ||
00171 !_dbus_concat_dir_and_file (&full_path, &filename))
00172 {
00173 _dbus_string_free (&full_path);
00174 _dbus_string_free (&filename);
00175 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00176 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00177 }
00178
00179
00180
00181 *server_p =
00182 _dbus_server_new_for_domain_socket (_dbus_string_get_const_data (&full_path),
00183 #ifdef HAVE_ABSTRACT_SOCKETS
00184 TRUE,
00185 #else
00186 FALSE,
00187 #endif
00188 error);
00189
00190 _dbus_string_free (&full_path);
00191 _dbus_string_free (&filename);
00192 }
00193 else
00194 {
00195 if (path)
00196 *server_p = _dbus_server_new_for_domain_socket (path, FALSE, error);
00197 else
00198 *server_p = _dbus_server_new_for_domain_socket (abstract, TRUE, error);
00199 }
00200
00201 if (*server_p != NULL)
00202 {
00203 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00204 return DBUS_SERVER_LISTEN_OK;
00205 }
00206 else
00207 {
00208 _DBUS_ASSERT_ERROR_IS_SET(error);
00209 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00210 }
00211 }
00212 else if (strcmp (method, "systemd") == 0)
00213 {
00214 int i, n;
00215 DBusSocket *fds;
00216 DBusString address;
00217
00218 n = _dbus_listen_systemd_sockets (&fds, error);
00219 if (n < 0)
00220 {
00221 _DBUS_ASSERT_ERROR_IS_SET (error);
00222 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00223 }
00224
00225 if (!_dbus_string_init (&address))
00226 goto systemd_oom;
00227
00228 for (i = 0; i < n; i++)
00229 {
00230 if (i > 0)
00231 {
00232 if (!_dbus_string_append (&address, ";"))
00233 goto systemd_oom;
00234 }
00235 if (!_dbus_append_address_from_socket (fds[i], &address, error))
00236 goto systemd_err;
00237 }
00238
00239 *server_p = _dbus_server_new_for_socket (fds, n, &address, NULL, error);
00240 if (*server_p == NULL)
00241 goto systemd_err;
00242
00243 dbus_free (fds);
00244
00245 return DBUS_SERVER_LISTEN_OK;
00246
00247 systemd_oom:
00248 _DBUS_SET_OOM (error);
00249 systemd_err:
00250 for (i = 0; i < n; i++)
00251 {
00252 _dbus_close_socket (fds[i], NULL);
00253 }
00254 dbus_free (fds);
00255 _dbus_string_free (&address);
00256
00257 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00258 }
00259 #ifdef DBUS_ENABLE_LAUNCHD
00260 else if (strcmp (method, "launchd") == 0)
00261 {
00262 const char *launchd_env_var = dbus_address_entry_get_value (entry, "env");
00263 if (launchd_env_var == NULL)
00264 {
00265 _dbus_set_bad_address (error, "launchd", "env", NULL);
00266 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00267 }
00268 *server_p = _dbus_server_new_for_launchd (launchd_env_var, error);
00269
00270 if (*server_p != NULL)
00271 {
00272 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00273 return DBUS_SERVER_LISTEN_OK;
00274 }
00275 else
00276 {
00277 _DBUS_ASSERT_ERROR_IS_SET(error);
00278 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00279 }
00280 }
00281 #endif
00282 else
00283 {
00284
00285
00286
00287 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00288 return DBUS_SERVER_LISTEN_NOT_HANDLED;
00289 }
00290 }
00291
00300 DBusServer*
00301 _dbus_server_new_for_domain_socket (const char *path,
00302 dbus_bool_t abstract,
00303 DBusError *error)
00304 {
00305 DBusServer *server;
00306 DBusSocket listen_fd;
00307 DBusString address;
00308 char *path_copy;
00309 DBusString path_str;
00310
00311 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00312
00313 if (!_dbus_string_init (&address))
00314 {
00315 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00316 return NULL;
00317 }
00318
00319 _dbus_string_init_const (&path_str, path);
00320 if ((abstract &&
00321 !_dbus_string_append (&address, "unix:abstract=")) ||
00322 (!abstract &&
00323 !_dbus_string_append (&address, "unix:path=")) ||
00324 !_dbus_address_append_escaped (&address, &path_str))
00325 {
00326 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00327 goto failed_0;
00328 }
00329
00330 if (abstract)
00331 {
00332 path_copy = NULL;
00333 }
00334 else
00335 {
00336 path_copy = _dbus_strdup (path);
00337 if (path_copy == NULL)
00338 {
00339 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00340 goto failed_0;
00341 }
00342 }
00343
00344 listen_fd.fd = _dbus_listen_unix_socket (path, abstract, error);
00345
00346 if (listen_fd.fd < 0)
00347 {
00348 _DBUS_ASSERT_ERROR_IS_SET (error);
00349 goto failed_1;
00350 }
00351
00352 server = _dbus_server_new_for_socket (&listen_fd, 1, &address, 0, error);
00353 if (server == NULL)
00354 {
00355 goto failed_2;
00356 }
00357
00358 if (path_copy != NULL)
00359 _dbus_server_socket_own_filename(server, path_copy);
00360
00361 _dbus_string_free (&address);
00362
00363 return server;
00364
00365 failed_2:
00366 _dbus_close_socket (listen_fd, NULL);
00367 failed_1:
00368 dbus_free (path_copy);
00369 failed_0:
00370 _dbus_string_free (&address);
00371
00372 return NULL;
00373 }
00374