1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-transport-unix.c UNIX socket subclasses of DBusTransport
4 * Copyright (C) 2002, 2003, 2004 Red Hat Inc.
6 * Licensed under the Academic Free License version 2.1
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "dbus-internals.h"
26 #include "dbus-connection-internal.h"
27 #include "dbus-transport-unix.h"
28 #include "dbus-transport-socket.h"
29 #include "dbus-transport-protected.h"
30 #include "dbus-watch.h"
31 #include "dbus-sysdeps-unix.h"
34 * @defgroup DBusTransportUnix DBusTransport implementations for UNIX
35 * @ingroup DBusInternals
36 * @brief Implementation details of DBusTransport on UNIX
42 * Creates a new transport for the given Unix domain socket
43 * path. This creates a client-side of a transport.
45 * @todo once we add a way to escape paths in a dbus
46 * address, this function needs to do escaping.
48 * @param path the path to the domain socket.
49 * @param abstract #TRUE to use abstract socket namespace
50 * @param error address where an error can be returned.
51 * @returns a new transport, or #NULL on failure.
54 _dbus_transport_new_for_domain_socket (const char *path,
59 DBusTransport *transport;
62 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
64 if (!_dbus_string_init (&address))
66 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
73 !_dbus_string_append (&address, "unix:abstract=")) ||
75 !_dbus_string_append (&address, "unix:path=")) ||
76 !_dbus_string_append (&address, path))
78 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
82 fd = _dbus_connect_unix_socket (path, abstract, error);
85 _DBUS_ASSERT_ERROR_IS_SET (error);
89 _dbus_verbose ("Successfully connected to unix socket %s\n",
92 transport = _dbus_transport_new_for_socket (fd, NULL, &address);
93 if (transport == NULL)
95 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
99 _dbus_string_free (&address);
104 _dbus_close_socket (fd, NULL);
106 _dbus_string_free (&address);
111 * Opens platform specific transport types.
113 * @param entry the address entry to try opening
114 * @param transport_p return location for the opened transport
115 * @param error error to be set
116 * @returns result of the attempt
118 DBusTransportOpenResult
119 _dbus_transport_open_platform_specific (DBusAddressEntry *entry,
120 DBusTransport **transport_p,
125 method = dbus_address_entry_get_method (entry);
126 _dbus_assert (method != NULL);
128 if (strcmp (method, "unix") == 0)
130 const char *path = dbus_address_entry_get_value (entry, "path");
131 const char *tmpdir = dbus_address_entry_get_value (entry, "tmpdir");
132 const char *abstract = dbus_address_entry_get_value (entry, "abstract");
136 _dbus_set_bad_address (error, NULL, NULL,
137 "cannot use the \"tmpdir\" option for an address to connect to, only in an address to listen on");
138 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
141 if (path == NULL && abstract == NULL)
143 _dbus_set_bad_address (error, "unix",
146 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
149 if (path != NULL && abstract != NULL)
151 _dbus_set_bad_address (error, NULL, NULL,
152 "can't specify both \"path\" and \"abstract\" options in an address");
153 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
157 *transport_p = _dbus_transport_new_for_domain_socket (path, FALSE,
160 *transport_p = _dbus_transport_new_for_domain_socket (abstract, TRUE,
162 if (*transport_p == NULL)
164 _DBUS_ASSERT_ERROR_IS_SET (error);
165 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
169 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
170 return DBUS_TRANSPORT_OPEN_OK;
173 #ifdef DBUS_ENABLE_LAUNCHD
174 else if (strcmp (method, "launchd") == 0)
176 DBusError tmp_error = DBUS_ERROR_INIT;
177 const char *launchd_env_var = dbus_address_entry_get_value (entry, "env");
178 const char *launchd_socket;
179 DBusString socket_path;
180 dbus_bool_t valid_socket;
182 if (!_dbus_string_init (&socket_path))
184 _DBUS_SET_OOM (error);
188 if (launchd_env_var == NULL)
190 _dbus_set_bad_address (error, "launchd", "env", NULL);
191 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
194 valid_socket = _dbus_lookup_launchd_socket (&socket_path, launchd_env_var, error);
196 if (dbus_error_is_set(error))
198 _dbus_string_free(&socket_path);
199 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
204 dbus_set_error(&tmp_error, DBUS_ERROR_BAD_ADDRESS,
205 "launchd's env var %s does not exist", launchd_env_var);
206 dbus_error_free(error);
207 dbus_move_error(&tmp_error, error);
208 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
211 launchd_socket = _dbus_string_get_const_data(&socket_path);
212 *transport_p = _dbus_transport_new_for_domain_socket (launchd_socket, FALSE, error);
214 if (*transport_p == NULL)
216 _DBUS_ASSERT_ERROR_IS_SET (error);
217 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
221 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
222 return DBUS_TRANSPORT_OPEN_OK;
228 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
229 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;