D-Bus  1.4.10
dbus-transport-unix.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-transport-unix.c UNIX socket subclasses of DBusTransport
3  *
4  * Copyright (C) 2002, 2003, 2004 Red Hat Inc.
5  *
6  * Licensed under the Academic Free License version 2.1
7  *
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.
12  *
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.
17  *
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
21  *
22  */
23 
24 #include <config.h>
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"
32 
55  dbus_bool_t abstract,
56  DBusError *error)
57 {
58  int fd;
59  DBusTransport *transport;
60  DBusString address;
61 
62  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
63 
64  if (!_dbus_string_init (&address))
65  {
67  return NULL;
68  }
69 
70  fd = -1;
71 
72  if ((abstract &&
73  !_dbus_string_append (&address, "unix:abstract=")) ||
74  (!abstract &&
75  !_dbus_string_append (&address, "unix:path=")) ||
76  !_dbus_string_append (&address, path))
77  {
79  goto failed_0;
80  }
81 
82  fd = _dbus_connect_unix_socket (path, abstract, error);
83  if (fd < 0)
84  {
85  _DBUS_ASSERT_ERROR_IS_SET (error);
86  goto failed_0;
87  }
88 
89  _dbus_verbose ("Successfully connected to unix socket %s\n",
90  path);
91 
92  transport = _dbus_transport_new_for_socket (fd, NULL, &address);
93  if (transport == NULL)
94  {
96  goto failed_1;
97  }
98 
99  _dbus_string_free (&address);
100 
101  return transport;
102 
103  failed_1:
104  _dbus_close_socket (fd, NULL);
105  failed_0:
106  _dbus_string_free (&address);
107  return NULL;
108 }
109 
118 DBusTransportOpenResult
120  DBusTransport **transport_p,
121  DBusError *error)
122 {
123  const char *method;
124 
125  method = dbus_address_entry_get_method (entry);
126  _dbus_assert (method != NULL);
127 
128  if (strcmp (method, "unix") == 0)
129  {
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");
133 
134  if (tmpdir != NULL)
135  {
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;
139  }
140 
141  if (path == NULL && abstract == NULL)
142  {
143  _dbus_set_bad_address (error, "unix",
144  "path or abstract",
145  NULL);
146  return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
147  }
148 
149  if (path != NULL && abstract != NULL)
150  {
152  "can't specify both \"path\" and \"abstract\" options in an address");
153  return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
154  }
155 
156  if (path)
157  *transport_p = _dbus_transport_new_for_domain_socket (path, FALSE,
158  error);
159  else
160  *transport_p = _dbus_transport_new_for_domain_socket (abstract, TRUE,
161  error);
162  if (*transport_p == NULL)
163  {
164  _DBUS_ASSERT_ERROR_IS_SET (error);
165  return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
166  }
167  else
168  {
169  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
170  return DBUS_TRANSPORT_OPEN_OK;
171  }
172  }
173 #ifdef DBUS_ENABLE_LAUNCHD
174  else if (strcmp (method, "launchd") == 0)
175  {
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;
181 
182  if (!_dbus_string_init (&socket_path))
183  {
184  _DBUS_SET_OOM (error);
185  return FALSE;
186  }
187 
188  if (launchd_env_var == NULL)
189  {
190  _dbus_set_bad_address (error, "launchd", "env", NULL);
191  return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
192  }
193 
194  valid_socket = _dbus_lookup_launchd_socket (&socket_path, launchd_env_var, error);
195 
196  if (dbus_error_is_set(error))
197  {
198  _dbus_string_free(&socket_path);
199  return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
200  }
201 
202  if (!valid_socket)
203  {
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;
209  }
210 
211  launchd_socket = _dbus_string_get_const_data(&socket_path);
212  *transport_p = _dbus_transport_new_for_domain_socket (launchd_socket, FALSE, error);
213 
214  if (*transport_p == NULL)
215  {
216  _DBUS_ASSERT_ERROR_IS_SET (error);
217  return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
218  }
219  else
220  {
221  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
222  return DBUS_TRANSPORT_OPEN_OK;
223  }
224  }
225 #endif
226  else
227  {
228  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
229  return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
230  }
231 }
232