summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'dbus/dbus-transport.c')
-rw-r--r--dbus/dbus-transport.c221
1 files changed, 129 insertions, 92 deletions
diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c
index b271d944..59eb8e44 100644
--- a/dbus/dbus-transport.c
+++ b/dbus/dbus-transport.c
@@ -75,22 +75,19 @@ live_messages_size_notify (DBusCounter *counter,
}
/**
- * Initializes the base class members of DBusTransport. Chained up to
- * by subclasses in their constructor. The server GUID is the
- * globally unique ID for the server creating this connection
- * and will be #NULL for the client side of a connection. The GUID
- * is in hex format.
+ * Initializes the base class members of DBusTransport.
+ * Chained up to by subclasses in their constructor.
*
* @param transport the transport being created.
* @param vtable the subclass vtable.
- * @param server_guid non-#NULL if this transport is on the server side of a connection
+ * @param server #TRUE if this transport is on the server side of a connection
* @param address the address of the transport
* @returns #TRUE on success.
*/
dbus_bool_t
_dbus_transport_init_base (DBusTransport *transport,
const DBusTransportVTable *vtable,
- const DBusString *server_guid,
+ dbus_bool_t server,
const DBusString *address)
{
DBusMessageLoader *loader;
@@ -102,8 +99,8 @@ _dbus_transport_init_base (DBusTransport *transport,
if (loader == NULL)
return FALSE;
- if (server_guid)
- auth = _dbus_auth_server_new (server_guid);
+ if (server)
+ auth = _dbus_auth_server_new ();
else
auth = _dbus_auth_client_new ();
if (auth == NULL)
@@ -120,7 +117,7 @@ _dbus_transport_init_base (DBusTransport *transport,
return FALSE;
}
- if (server_guid)
+ if (server)
{
_dbus_assert (address == NULL);
address_copy = NULL;
@@ -145,9 +142,9 @@ _dbus_transport_init_base (DBusTransport *transport,
transport->live_messages_size = counter;
transport->authenticated = FALSE;
transport->disconnected = FALSE;
- transport->is_server = (server_guid != NULL);
- transport->send_credentials_pending = !transport->is_server;
- transport->receive_credentials_pending = transport->is_server;
+ transport->send_credentials_pending = !server;
+ transport->receive_credentials_pending = server;
+ transport->is_server = server;
transport->address = address_copy;
transport->unix_user_function = NULL;
@@ -198,22 +195,33 @@ _dbus_transport_finalize_base (DBusTransport *transport)
}
/**
- * Try to open a new transport for the given address entry. (This
- * opens a client-side-of-the-connection transport.)
+ * Opens a new transport for the given address. (This opens a
+ * client-side-of-the-connection transport.)
+ *
+ * @todo error messages on bad address could really be better.
+ * DBusResultCode is a bit limiting here.
*
- * @param entry the address entry
+ * @param address the address.
* @param error location to store reason for failure.
* @returns new transport of #NULL on failure.
*/
DBusTransport*
-_dbus_transport_open (DBusAddressEntry *entry,
- DBusError *error)
+_dbus_transport_open (const char *address,
+ DBusError *error)
{
DBusTransport *transport;
+ DBusAddressEntry **entries;
+ DBusError tmp_error;
+ DBusError first_error;
+ int len, i;
const char *address_problem_type;
const char *address_problem_field;
const char *address_problem_other;
- const char *method;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ if (!dbus_parse_address (address, &entries, &len, error))
+ return NULL;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -221,96 +229,125 @@ _dbus_transport_open (DBusAddressEntry *entry,
address_problem_type = NULL;
address_problem_field = NULL;
address_problem_other = NULL;
-
- method = dbus_address_entry_get_method (entry);
- _dbus_assert (method != NULL);
-
- if (strcmp (method, "unix") == 0)
+
+ dbus_error_init (&tmp_error);
+ dbus_error_init (&first_error);
+ for (i = 0; i < len; i++)
{
- const char *path = dbus_address_entry_get_value (entry, "path");
- const char *tmpdir = dbus_address_entry_get_value (entry, "tmpdir");
- const char *abstract = dbus_address_entry_get_value (entry, "abstract");
+ const char *method;
+
+ method = dbus_address_entry_get_method (entries[i]);
+
+ if (strcmp (method, "unix") == 0)
+ {
+ const char *path = dbus_address_entry_get_value (entries[i], "path");
+ const char *tmpdir = dbus_address_entry_get_value (entries[i], "tmpdir");
+ const char *abstract = dbus_address_entry_get_value (entries[i], "abstract");
- if (tmpdir != NULL)
- {
- address_problem_other = "cannot use the \"tmpdir\" option for an address to connect to, only in an address to listen on";
- goto bad_address;
- }
+ if (tmpdir != NULL)
+ {
+ address_problem_other = "cannot use the \"tmpdir\" option for an address to connect to, only in an address to listen on";
+ goto bad_address;
+ }
- if (path == NULL && abstract == NULL)
- {
- address_problem_type = "unix";
- address_problem_field = "path or abstract";
- goto bad_address;
- }
+ if (path == NULL && abstract == NULL)
+ {
+ address_problem_type = "unix";
+ address_problem_field = "path or abstract";
+ goto bad_address;
+ }
- if (path != NULL && abstract != NULL)
- {
- address_problem_other = "can't specify both \"path\" and \"abstract\" options in an address";
- goto bad_address;
- }
+ if (path != NULL && abstract != NULL)
+ {
+ address_problem_other = "can't specify both \"path\" and \"abstract\" options in an address";
+ goto bad_address;
+ }
- if (path)
- transport = _dbus_transport_new_for_domain_socket (path, FALSE,
- error);
- else
- transport = _dbus_transport_new_for_domain_socket (abstract, TRUE,
- error);
- }
- else if (strcmp (method, "tcp") == 0)
- {
- const char *host = dbus_address_entry_get_value (entry, "host");
- const char *port = dbus_address_entry_get_value (entry, "port");
- DBusString str;
- long lport;
- dbus_bool_t sresult;
+ if (path)
+ transport = _dbus_transport_new_for_domain_socket (path, FALSE,
+ &tmp_error);
+ else
+ transport = _dbus_transport_new_for_domain_socket (abstract, TRUE,
+ &tmp_error);
+ }
+ else if (strcmp (method, "tcp") == 0)
+ {
+ const char *host = dbus_address_entry_get_value (entries[i], "host");
+ const char *port = dbus_address_entry_get_value (entries[i], "port");
+ DBusString str;
+ long lport;
+ dbus_bool_t sresult;
- if (port == NULL)
- {
- address_problem_type = "tcp";
- address_problem_field = "port";
- goto bad_address;
- }
+ if (port == NULL)
+ {
+ address_problem_type = "tcp";
+ address_problem_field = "port";
+ goto bad_address;
+ }
- _dbus_string_init_const (&str, port);
- sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
- _dbus_string_free (&str);
+ _dbus_string_init_const (&str, port);
+ sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
+ _dbus_string_free (&str);
- if (sresult == FALSE || lport <= 0 || lport > 65535)
- {
- address_problem_other = "Port is not an integer between 0 and 65535";
- goto bad_address;
- }
+ if (sresult == FALSE || lport <= 0 || lport > 65535)
+ {
+ address_problem_other = "Port is not an integer between 0 and 65535";
+ goto bad_address;
+ }
- transport = _dbus_transport_new_for_tcp_socket (host, lport, error);
- }
+ transport = _dbus_transport_new_for_tcp_socket (host, lport, &tmp_error);
+ }
#ifdef DBUS_BUILD_TESTS
- else if (strcmp (method, "debug-pipe") == 0)
- {
- const char *name = dbus_address_entry_get_value (entry, "name");
+ else if (strcmp (method, "debug-pipe") == 0)
+ {
+ const char *name = dbus_address_entry_get_value (entries[i], "name");
- if (name == NULL)
+ if (name == NULL)
+ {
+ address_problem_type = "debug-pipe";
+ address_problem_field = "name";
+ goto bad_address;
+ }
+
+ transport = _dbus_transport_debug_pipe_new (name, &tmp_error);
+ }
+#endif
+ else
{
- address_problem_type = "debug-pipe";
- address_problem_field = "name";
+ address_problem_other = "Unknown address type (examples of valid types are \"unix\" and \"tcp\")";
goto bad_address;
}
-
- transport = _dbus_transport_debug_pipe_new (name, error);
+
+ if (transport)
+ break;
+
+ _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
+
+ if (i == 0)
+ dbus_move_error (&tmp_error, &first_error);
+ else
+ dbus_error_free (&tmp_error);
+ }
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
+
+ if (transport == NULL)
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (&first_error);
+ dbus_move_error (&first_error, error);
}
-#endif
else
{
- address_problem_other = "Unknown address type (examples of valid types are \"unix\" and \"tcp\")";
- goto bad_address;
+ dbus_error_free (&first_error);
}
-
- if (transport == NULL)
- _DBUS_ASSERT_ERROR_IS_SET (error);
+ dbus_address_entries_free (entries);
return transport;
-
+
bad_address:
+ dbus_address_entries_free (entries);
+
if (address_problem_type != NULL)
dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
"Address of type %s was missing argument %s",
@@ -916,10 +953,10 @@ _dbus_transport_get_unix_user (DBusTransport *transport,
{
DBusCredentials auth_identity;
- *uid = _DBUS_INT32_MAX; /* better than some root or system user in
- * case of bugs in the caller. Caller should
- * never use this value on purpose, however.
- */
+ *uid = _DBUS_INT_MAX; /* better than some root or system user in
+ * case of bugs in the caller. Caller should
+ * never use this value on purpose, however.
+ */
if (!transport->authenticated)
return FALSE;