summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xclaesse@gmail.com>2011-08-19 12:42:36 +0200
committerXavier Claessens <xclaesse@gmail.com>2011-08-19 12:42:36 +0200
commit8db9abc63ea8a6a6765c50aa499e802254620f51 (patch)
tree77953cd96c375e72c5fe1240971f03a9cf61c1ee
parentc64e8956fbcef37e579a4e64e4e889acc1d80983 (diff)
Use new factory APIs from telepathy-glib 0.15.5
-rw-r--r--configure.ac2
-rw-r--r--src/client-helpers.c21
-rw-r--r--src/client-helpers.h2
-rw-r--r--src/client.c439
-rw-r--r--src/service.c9
5 files changed, 142 insertions, 331 deletions
diff --git a/configure.ac b/configure.ac
index ec12de9..01e200c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -27,7 +27,7 @@ IT_PROG_INTLTOOL([0.35.0])
PKG_CHECK_MODULES(SSH_CONTACT,
[
- telepathy-glib >= 0.13.9
+ telepathy-glib >= 0.15.5
glib-2.0 >= 2.28
gio-2.0
])
diff --git a/src/client-helpers.c b/src/client-helpers.c
index a6b060e..6fa5df3 100644
--- a/src/client-helpers.c
+++ b/src/client-helpers.c
@@ -100,9 +100,6 @@ create_tube_offer_cb (GObject *object,
{
GSimpleAsyncResult *simple = user_data;
GError *error = NULL;
- CreateTubeData *data;
-
- data = g_simple_async_result_get_op_res_gpointer (simple);
if (!tp_stream_tube_channel_offer_finish (TP_STREAM_TUBE_CHANNEL (object),
res, &error))
@@ -154,7 +151,7 @@ create_channel_cb (GObject *acr,
}
void
-_client_create_tube_async (const gchar *account_path,
+_client_create_tube_async (TpAccount *account,
const gchar *contact_id,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -162,21 +159,7 @@ _client_create_tube_async (const gchar *account_path,
GSimpleAsyncResult *simple;
CreateTubeData *data;
GHashTable *request;
- TpDBusDaemon *dbus;
- TpAccount *account = NULL;
TpAccountChannelRequest *acr;
- GError *error = NULL;
-
- dbus = tp_dbus_daemon_dup (&error);
- if (dbus != NULL)
- account = tp_account_new (dbus, account_path, &error);
- if (account == NULL)
- {
- g_simple_async_report_gerror_in_idle (NULL, callback, user_data, error);
- g_clear_error (&error);
- tp_clear_object (&dbus);
- return;
- }
simple = g_simple_async_result_new (NULL, callback, user_data,
_client_create_tube_finish);
@@ -201,8 +184,6 @@ _client_create_tube_async (const gchar *account_path,
NULL, create_channel_cb, simple);
g_hash_table_unref (request);
- g_object_unref (dbus);
- g_object_unref (account);
g_object_unref (acr);
}
diff --git a/src/client-helpers.h b/src/client-helpers.h
index ecfc5cf..d69be0f 100644
--- a/src/client-helpers.h
+++ b/src/client-helpers.h
@@ -26,7 +26,7 @@
G_BEGIN_DECLS
-void _client_create_tube_async (const gchar *account_path,
+void _client_create_tube_async (TpAccount *account,
const gchar *contact_id, GAsyncReadyCallback callback, gpointer user_data);
GSocketConnection *_client_create_tube_finish (GAsyncResult *res,
diff --git a/src/client.c b/src/client.c
index 29e221a..6bca25f 100644
--- a/src/client.c
+++ b/src/client.c
@@ -39,16 +39,10 @@ typedef struct
gchar *login;
gchar **ssh_opts;
- GList *accounts;
- guint n_readying_connections;
- TpAccount *account;
-
TpChannel *channel;
GSocketConnection *tube_connection;
GSocketConnection *ssh_connection;
- gboolean account_set:1;
- gboolean contact_set:1;
gboolean success:1;
} ClientContext;
@@ -198,343 +192,167 @@ OUT:
}
static void
-start_tube (ClientContext *context)
+start_tube (ClientContext *context,
+ TpContact *contact)
{
- if (!context->account_set || !context->contact_set)
+ TpAccount *account;
+
+ account = tp_connection_get_account (tp_contact_get_connection (contact));
+
+ if (context->account_path == NULL || context->contact_id == NULL)
{
g_print ("\nTo avoid interactive mode, you can use that command:\n"
"%s --account %s --contact %s\n", context->argv0,
- context->account_path, context->contact_id);
+ tp_proxy_get_object_path (account),
+ tp_contact_get_identifier (contact));
}
- _client_create_tube_async (context->account_path,
- context->contact_id, create_tube_cb, context);
+ _client_create_tube_async (account, tp_contact_get_identifier (contact),
+ create_tube_cb, context);
}
static void
-got_contacts_cb (TpConnection *connection,
- guint n_contacts,
- TpContact * const *contacts,
- guint n_failed,
- const TpHandle *failed,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
+choose_contact (ClientContext *context,
+ GList *accounts)
{
- ClientContext *context = user_data;
- guint i;
- GList *candidates = NULL, *l;
- guint count = 0;
+ GPtrArray *candidates;
+ GList *l;
+ GString *text;
gchar buffer[10];
gchar *str;
- if (error != NULL)
- {
- throw_error (context, error);
- return;
- }
-
- /* Build a list of all contacts supporting StreamTube */
- for (i = 0; i < n_contacts; i++)
- if (_capabilities_has_stream_tube (tp_contact_get_capabilities (contacts[i])))
- candidates = g_list_prepend (candidates, contacts[i]);
-
- if (candidates == NULL)
- {
- throw_error_message (context, "No suitable contact");
- return;
- }
-
- /* Ask the user which candidate to use */
- for (l = candidates; l != NULL; l = l->next)
- {
- TpContact *contact = l->data;
-
- g_print ("%d) %s (%s)\n", ++count, tp_contact_get_alias (contact),
- tp_contact_get_identifier (contact));
- }
-
- g_print ("Which contact to use? ");
- str = fgets (buffer, sizeof (buffer), stdin);
- if (str != NULL)
+ text = g_string_new (NULL);
+ candidates = g_ptr_array_new_with_free_func (g_object_unref);
+ for (l = accounts; l != NULL; l = l->next)
{
- str[strlen (str) - 1] = '\0';
- l = g_list_nth (candidates, atoi (str) - 1);
- }
- if (l == NULL)
- {
- throw_error_message (context, "Invalid contact number");
- return;
- }
-
- context->contact_id = g_strdup (tp_contact_get_identifier (l->data));
- start_tube (context);
-
- g_list_free (candidates);
-}
-
-static void
-stored_channel_prepare_cb (GObject *object,
- GAsyncResult *res,
- gpointer user_data)
-{
- ClientContext *context = user_data;
- TpChannel *channel = TP_CHANNEL (object);
- TpConnection *connection;
- TpContactFeature features[] = { TP_CONTACT_FEATURE_ALIAS,
- TP_CONTACT_FEATURE_CAPABILITIES };
- const TpIntSet *set;
- GArray *handles;
- GError *error = NULL;
-
- if (!tp_proxy_prepare_finish (channel, res, &error))
- {
- throw_error (context, error);
- g_clear_error (&error);
- return;
- }
-
- connection = tp_channel_borrow_connection (channel);
- set = tp_channel_group_get_members (channel);
- handles = tp_intset_to_array (set);
-
- if (handles->len <= 0)
- {
- throw_error_message(context, "No contacts available");
- return;
- }
-
- tp_connection_get_contacts_by_handle (connection, handles->len,
- (TpHandle *) handles->data, G_N_ELEMENTS (features), features,
- got_contacts_cb, context, NULL, NULL);
-
- g_array_unref (handles);
-}
-
-static void
-ensure_stored_channel_cb (TpConnection *connection,
- gboolean yours,
- const gchar *channel_path,
- GHashTable *properties,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- ClientContext *context = user_data;
- TpChannel *channel;
- GQuark features[] = { TP_CHANNEL_FEATURE_GROUP, 0 };
- GError *err = NULL;
-
- if (error != NULL)
- {
- throw_error (context, error);
- return;
- }
+ TpAccount *account = l->data;
+ TpConnection *connection;
+ TpCapabilities *caps;
+ GPtrArray *contacts;
+ GString *subtext;
+ gboolean found = FALSE;
+ guint i;
- channel = tp_channel_new_from_properties (connection, channel_path,
- properties, &err);
- if (channel == NULL)
- {
- throw_error (context, err);
- g_clear_error (&err);
- return;
- }
+ connection = tp_account_get_connection (account);
+ if (connection == NULL)
+ continue;
- tp_proxy_prepare_async (TP_PROXY (channel), features,
- stored_channel_prepare_cb, context);
+ caps = tp_connection_get_capabilities (connection);
+ if (!_capabilities_has_stream_tube (caps))
+ continue;
- g_object_unref (channel);
-}
+ subtext = g_string_new (NULL);
+ contacts = tp_connection_dup_contact_list (connection);
+ for (i = 0; i < contacts->len; i++)
+ {
+ TpContact *contact = g_ptr_array_index (contacts, i);
-static void
-chooser_contact (ClientContext *context)
-{
- TpConnection *connection;
- GHashTable *request;
+ caps = tp_contact_get_capabilities (contact);
+ if (!_capabilities_has_stream_tube (caps))
+ continue;
- /* If a contact ID was passed in the options, use it */
- if (context->contact_set)
- {
- g_assert (context->contact_id != NULL);
- start_tube (context);
- return;
- }
+ if (context->contact_id != NULL &&
+ tp_strdiff (context->contact_id,
+ tp_contact_get_identifier (contact)))
+ continue;
- /* Otherwise, we'll get TpContact objects for all stored contacts on that
- * account. */
- request = tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
- TP_IFACE_CHANNEL_TYPE_CONTACT_LIST,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
- TP_HANDLE_TYPE_LIST,
- TP_PROP_CHANNEL_TARGET_ID, G_TYPE_STRING,
- "stored",
- NULL);
-
- connection = tp_account_get_connection (context->account);
- tp_cli_connection_interface_requests_call_ensure_channel (connection, -1,
- request, ensure_stored_channel_cb, context, NULL, NULL);
-
- g_hash_table_unref (request);
-}
+ found = TRUE;
+ g_ptr_array_add (candidates, g_object_ref (contact));
-static void
-chooser_account (ClientContext *context)
-{
- GList *l;
- guint count = 0;
- gchar buffer[10];
- gchar *str;
+ g_string_append_printf (subtext, " %d) %s (%s)\n", candidates->len,
+ tp_contact_get_alias (contact),
+ tp_contact_get_identifier (contact));
+ }
+ g_ptr_array_unref (contacts);
- if (context->accounts == NULL)
- {
- throw_error_message (context, "No suitable account");
- return;
+ if (found)
+ {
+ g_string_append_printf (text,
+ "Account %s (%s):\n%s",
+ tp_account_get_display_name (l->data),
+ tp_account_get_protocol (l->data),
+ subtext->str);
+ }
+ g_string_free (subtext, TRUE);
}
- if (context->account_set)
+ if (candidates->len == 0)
{
- g_assert (context->account != NULL);
- g_assert (context->account_path != NULL);
- chooser_contact (context);
- return;
+ throw_error_message (context, "No suitable contact");
+ goto OUT;
}
- for (l = context->accounts; l != NULL; l = l->next)
+ if (candidates->len == 1 && context->contact_id != NULL)
{
- g_print ("%d) %s (%s)\n", ++count,
- tp_account_get_display_name (l->data),
- tp_account_get_protocol (l->data));
+ start_tube (context, g_ptr_array_index (candidates, 0));
+ goto OUT;
}
- g_print ("Which account to use? ");
+ g_print ("%sWhich contact to use? ", text->str);
str = fgets (buffer, sizeof (buffer), stdin);
if (str != NULL)
{
- str[strlen (str) - 1] = '\0';
- l = g_list_nth (context->accounts, atoi (str) - 1);
- }
- if (l == NULL)
- {
- throw_error_message (context, "Invalid account number");
- return;
- }
-
- context->account = g_object_ref (l->data);
- context->account_path = g_strdup (tp_proxy_get_object_path (context->account));
-
- chooser_contact (context);
-}
+ guint i;
-static void
-connection_prepare_cb (GObject *object,
- GAsyncResult *res,
- gpointer user_data)
-{
- TpConnection *connection = TP_CONNECTION (object);
- ClientContext *context = user_data;
+ str[strlen (str) - 1] = '\0';
+ i = atoi (str) - 1;
- if (!tp_proxy_prepare_finish (TP_PROXY (connection), res, NULL) ||
- !_capabilities_has_stream_tube (tp_connection_get_capabilities (connection)))
- {
- GList *l;
-
- /* Remove the account that has that connection from the list */
- for (l = context->accounts; l != NULL; l = l->next)
- if (tp_account_get_connection (l->data) == connection)
- {
- g_object_unref (l->data);
- context->accounts = g_list_delete_link (context->accounts, l);
- break;
- }
+ if (i < candidates->len)
+ {
+ start_tube (context, g_ptr_array_index (candidates, i));
+ goto OUT;
+ }
}
- if (--context->n_readying_connections == 0)
- chooser_account (context);
+ throw_error_message (context, "Invalid contact number");
+
+OUT:
+ g_ptr_array_unref (candidates);
+ g_string_free (text, TRUE);
}
static void
-account_manager_prepare_cb (GObject *object,
+account_prepared_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
- TpAccountManager *manager = TP_ACCOUNT_MANAGER (object);
+ TpAccount *account = TP_ACCOUNT (object);
ClientContext *context = user_data;
- GList *l, *next;
+ GList *accounts;
GError *error = NULL;
- if (!tp_proxy_prepare_finish (TP_PROXY (manager), res, &error))
+ if (!tp_proxy_prepare_finish (TP_PROXY (account), res, &error))
{
throw_error (context, error);
g_clear_error (&error);
return;
}
- /* We want to list all accounts which has a connection that have StreamTube
- * support. So first we prepare all connections, and we keep in
- * context->accounts those that are suitable. */
-
- context->accounts = tp_account_manager_get_valid_accounts (manager);
- g_list_foreach (context->accounts, (GFunc) g_object_ref, NULL);
-
- for (l = context->accounts; l != NULL; l = next)
- {
- GQuark features[] = { TP_CONNECTION_FEATURE_CAPABILITIES, 0 };
- TpAccount *account = l->data;
- TpConnection *connection;
-
- next = l->next;
-
- connection = tp_account_get_connection (account);
- if (connection == NULL)
- {
- g_object_unref (account);
- context->accounts = g_list_delete_link (context->accounts, l);
- continue;
- }
-
- context->n_readying_connections++;
- tp_proxy_prepare_async (TP_PROXY (connection), features,
- connection_prepare_cb, context);
- }
-
- if (context->n_readying_connections == 0)
- chooser_account (context);
+ accounts = g_list_prepend (NULL, account);
+ choose_contact (context, accounts);
+ g_list_free (accounts);
}
static void
-account_prepare_cb (GObject *object,
+account_manager_prepared_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
- TpAccount *account = TP_ACCOUNT (object);
+ TpAccountManager *manager = TP_ACCOUNT_MANAGER (object);
ClientContext *context = user_data;
- GQuark features[] = { TP_CONNECTION_FEATURE_CAPABILITIES, 0 };
- TpConnection *connection;
+ GList *accounts;
GError *error = NULL;
- /* We are in the case where an account was specified in options, so we have
- * only one candidate, if that accounts has no connection or the connection
- * has no StreamTube support, we'll fail. */
-
- if (!tp_proxy_prepare_finish (TP_PROXY (account), res, &error))
+ if (!tp_proxy_prepare_finish (TP_PROXY (manager), res, &error))
{
throw_error (context, error);
+ g_clear_error (&error);
return;
}
- connection = tp_account_get_connection (account);
- if (connection == NULL)
- {
- throw_error_message (context, "Account not online");
- return;
- }
-
- /* Prepare account's connection with caps feature */
- context->accounts = g_list_prepend (NULL, g_object_ref (account));
- context->n_readying_connections = 1;
- tp_proxy_prepare_async (TP_PROXY (connection), features,
- connection_prepare_cb, context);
+ accounts = tp_account_manager_get_valid_accounts (manager);
+ choose_contact (context, accounts);
+ g_list_free (accounts);
}
static void
@@ -547,10 +365,6 @@ client_context_clear (ClientContext *context)
g_free (context->login);
g_strfreev (context->ssh_opts);
- g_list_foreach (context->accounts, (GFunc) g_object_unref, NULL);
- g_list_free (context->accounts);
- tp_clear_object (&context->account);
-
tp_clear_object (&context->channel);
tp_clear_object (&context->tube_connection);
tp_clear_object (&context->ssh_connection);
@@ -559,7 +373,8 @@ client_context_clear (ClientContext *context)
int
main (gint argc, gchar *argv[])
{
- TpDBusDaemon *dbus = NULL;
+ TpDBusDaemon *dbus;
+ TpSimpleClientFactory *factory;
GError *error = NULL;
ClientContext context = { 0, };
GOptionContext *optcontext;
@@ -595,49 +410,61 @@ main (gint argc, gchar *argv[])
}
g_option_context_free (optcontext);
+ context.argv0 = g_strdup (argv[0]);
g_set_application_name (PACKAGE_NAME);
+ tp_debug_set_flags (g_getenv ("SSH_CONTACT_DEBUG"));
dbus = tp_dbus_daemon_dup (&error);
if (dbus == NULL)
goto OUT;
- context.argv0 = g_strdup (argv[0]);
+ /* Create a factory and define the features we need */
+ factory = (TpSimpleClientFactory *) tp_automatic_client_factory_new (dbus);
+ tp_simple_client_factory_add_account_features_varargs (factory,
+ TP_ACCOUNT_FEATURE_CONNECTION,
+ 0);
+ tp_simple_client_factory_add_connection_features_varargs (factory,
+ TP_CONNECTION_FEATURE_CONTACT_LIST,
+ TP_CONNECTION_FEATURE_CAPABILITIES,
+ 0);
+ tp_simple_client_factory_add_contact_features_varargs (factory,
+ TP_CONTACT_FEATURE_ALIAS,
+ TP_CONTACT_FEATURE_CAPABILITIES,
+ TP_CONTACT_FEATURE_INVALID);
+ g_object_unref (dbus);
+
+ /* If user gave an account path, prepare only that account, otherwise prepare
+ * the whole account manager. */
if (context.account_path != NULL)
- context.account_set = TRUE;
- if (context.contact_id != NULL)
- context.contact_set = TRUE;
-
- /* If an account id was specified in options, then prepare it, otherwise
- * we get the account manager to get a list of all accounts */
- if (context.account_set)
{
- if (!g_str_has_prefix (context.account_path, TP_ACCOUNT_OBJECT_PATH_BASE))
- {
- gchar *account_id = context.account_path;
+ TpAccount *account;
+ GArray *features;
- context.account_path = g_strconcat (TP_ACCOUNT_OBJECT_PATH_BASE,
- account_id, NULL);
+ account = tp_simple_client_factory_ensure_account (factory,
+ context.account_path, NULL, &error);
+ if (account == NULL)
+ goto OUT;
- g_free (account_id);
- }
+ features = tp_simple_client_factory_dup_account_features (factory,
+ account);
- context.account = tp_account_new (dbus, context.account_path, &error);
- if (context.account == NULL)
- goto OUT;
+ tp_proxy_prepare_async (account, (GQuark *) features->data,
+ account_prepared_cb, &context);
- tp_proxy_prepare_async (TP_PROXY (context.account), NULL,
- account_prepare_cb, &context);
+ g_object_unref (account);
+ g_array_unref (features);
}
else
{
TpAccountManager *manager;
- manager = tp_account_manager_new (dbus);
- tp_proxy_prepare_async (TP_PROXY (manager), NULL,
- account_manager_prepare_cb, &context);
+ manager = tp_account_manager_new_with_factory (factory);
+ tp_proxy_prepare_async (manager, NULL,
+ account_manager_prepared_cb, &context);
g_object_unref (manager);
}
+ g_object_unref (factory);
context.loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (context.loop);
@@ -650,10 +477,8 @@ OUT:
g_debug ("Error: %s", error->message);
}
- tp_clear_object (&dbus);
g_clear_error (&error);
client_context_clear (&context);
return context.success ? EXIT_SUCCESS : EXIT_FAILURE;
}
-
diff --git a/src/service.c b/src/service.c
index f440f2f..5134497 100644
--- a/src/service.c
+++ b/src/service.c
@@ -149,18 +149,22 @@ int
main (gint argc, gchar *argv[])
{
TpDBusDaemon *dbus = NULL;
+ TpSimpleClientFactory *factory = NULL;
TpBaseClient *client = NULL;
gboolean success = TRUE;
GError *error = NULL;
g_type_init ();
+ tp_debug_set_flags (g_getenv ("SSH_CONTACT_DEBUG"));
+
dbus = tp_dbus_daemon_dup (&error);
if (dbus == NULL)
goto OUT;
- client = tp_simple_handler_new (dbus, FALSE, FALSE, "SSHContact",
- FALSE, got_channel_cb, NULL, NULL);
+ factory = (TpSimpleClientFactory *) tp_automatic_client_factory_new (dbus);
+ client = tp_simple_handler_new_with_factory (factory, FALSE, FALSE,
+ "SSHContact", FALSE, got_channel_cb, NULL, NULL);
tp_base_client_take_handler_filter (client, tp_asv_new (
TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
@@ -189,6 +193,7 @@ OUT:
tp_clear_pointer (&loop, g_main_loop_unref);
tp_clear_object (&dbus);
+ tp_clear_object (&factory);
tp_clear_object (&client);
g_clear_error (&error);