#include "dbus-connection-internal.h"
#include "dbus-watch.h"
#include "dbus-auth.h"
+#include "dbus-address.h"
#ifdef DBUS_BUILD_TESTS
#include "dbus-transport-debug.h"
#endif
* or encryption schemes.
*/
-/**
- * Refs a transport and associated connection for reentrancy.
- *
- * @todo this macro reflects a design mistake, which is that the
- * transport has a pointer to its connection. Ownership should move in
- * only one direction; the connection should push/pull from the
- * transport, rather than vice versa. Then the connection would take
- * care of referencing itself when needed.
- */
-#define DBUS_TRANSPORT_HOLD_REF(t) \
- _dbus_transport_ref (t); if ((t)->connection) dbus_connection_ref ((t)->connection)
-
-/**
- * Inverse of DBUS_TRANSPORT_HOLD_REF().
- */
-#define DBUS_TRANSPORT_RELEASE_REF(t) \
- if ((t)->connection) dbus_connection_unref ((t)->connection); _dbus_transport_unref (t)
-
static void
live_messages_size_notify (DBusCounter *counter,
void *user_data)
{
DBusTransport *transport = user_data;
- DBUS_TRANSPORT_HOLD_REF (transport);
+ _dbus_transport_ref (transport);
#if 0
_dbus_verbose ("Counter value is now %d\n",
if (* transport->vtable->live_messages_changed)
(* transport->vtable->live_messages_changed) (transport);
- DBUS_TRANSPORT_RELEASE_REF (transport);
+ _dbus_transport_unref (transport);
}
/**
* Opens a new transport for the given address. (This opens a
* client-side-of-the-connection transport.)
*
- * @todo right now the address is just a Unix domain socket path.
+ * @todo error messages on bad address could really be better.
+ * DBusResultCode is a bit limiting here.
*
* @param address the address.
* @param result location to store reason for failure.
DBusResultCode *result)
{
DBusTransport *transport;
+ DBusAddressEntry **entries;
+ int len, i;
- /* FIXME parse the address - whatever format
- * we decide addresses are in - and find the
- * appropriate transport.
- */
+ if (!dbus_parse_address (address, &entries, &len, result))
+ return NULL;
-#if 1
- /* Pretend it's just a unix domain socket name for now */
- transport = _dbus_transport_new_for_domain_socket (address,
- FALSE,
- result);
-#else
- transport = _dbus_transport_debug_client_new (address,
- result);
-#endif
+ transport = NULL;
+
+ for (i = 0; i < len; i++)
+ {
+ const char *method = dbus_address_entry_get_method (entries[i]);
+
+ if (strcmp (method, "unix") == 0)
+ {
+ const char *path = dbus_address_entry_get_value (entries[i], "path");
+
+ if (path == NULL)
+ goto bad_address;
+
+ transport = _dbus_transport_new_for_domain_socket (path, FALSE, result);
+ }
+#ifdef DBUS_BUILD_TESTS
+ else if (strcmp (method, "debug") == 0)
+ {
+ const char *name = dbus_address_entry_get_value (entries[i], "name");
+
+ if (name == NULL)
+ goto bad_address;
+
+ transport = _dbus_transport_debug_client_new (name, result);
+ }
+#endif
+ else
+ goto bad_address;
+
+ if (transport)
+ break;
+ }
+
+ dbus_address_entries_free (entries);
return transport;
+
+ bad_address:
+ dbus_address_entries_free (entries);
+ dbus_set_result (result, DBUS_RESULT_BAD_ADDRESS);
+
+ return NULL;
}
/**
if (transport->disconnected)
return;
- DBUS_TRANSPORT_HOLD_REF (transport);
+ _dbus_transport_ref (transport);
(* transport->vtable->disconnect) (transport);
transport->disconnected = TRUE;
_dbus_connection_notify_disconnected (transport->connection);
- DBUS_TRANSPORT_RELEASE_REF (transport);
+ _dbus_transport_unref (transport);
}
/**
_dbus_watch_sanitize_condition (watch, &condition);
- DBUS_TRANSPORT_HOLD_REF (transport);
+ _dbus_transport_ref (transport);
_dbus_watch_ref (watch);
(* transport->vtable->handle_watch) (transport, watch, condition);
_dbus_watch_unref (watch);
- DBUS_TRANSPORT_RELEASE_REF (transport);
+ _dbus_transport_unref (transport);
}
/**
transport->connection = connection;
- DBUS_TRANSPORT_HOLD_REF (transport);
+ _dbus_transport_ref (transport);
(* transport->vtable->connection_set) (transport);
- DBUS_TRANSPORT_RELEASE_REF (transport);
+ _dbus_transport_unref (transport);
}
/**
transport->messages_need_sending = queue_length > 0;
- DBUS_TRANSPORT_HOLD_REF (transport);
+ _dbus_transport_ref (transport);
(* transport->vtable->messages_pending) (transport,
queue_length);
- DBUS_TRANSPORT_RELEASE_REF (transport);
+ _dbus_transport_unref (transport);
}
/**
if (transport->disconnected)
return;
- DBUS_TRANSPORT_HOLD_REF (transport);
+ _dbus_transport_ref (transport);
(* transport->vtable->do_iteration) (transport, flags,
timeout_milliseconds);
- DBUS_TRANSPORT_RELEASE_REF (transport);
+ _dbus_transport_unref (transport);
}
/**