summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2018-08-23 23:02:41 -0400
committerMatthias Clasen <mclasen@redhat.com>2018-08-27 10:55:01 -0400
commita090d8605bc5e393c603f5ec0cfcf31259e82e3e (patch)
tree9df9fc0765ae09e8122a07eaeabcacf4fe297782
parent3a3a32a2bb55cd64510dcdbe3bf8e844a747b49a (diff)
downloadglib-a090d8605bc5e393c603f5ec0cfcf31259e82e3e.tar.gz
portal network monitor: Implement can_reach
Version 3 of the network monitor portal interface adds a CanReach method. Use it to implement can_reach. The docs state that can_reach will either return TRUE or set an error. So, set an error of G_IO_ERROR_HOST_UNREACHABLE when the portal returns FALSE for CanReach.
-rw-r--r--gio/gnetworkmonitorportal.c123
1 files changed, 121 insertions, 2 deletions
diff --git a/gio/gnetworkmonitorportal.c b/gio/gnetworkmonitorportal.c
index 33bdea87f..ebf210e5b 100644
--- a/gio/gnetworkmonitorportal.c
+++ b/gio/gnetworkmonitorportal.c
@@ -325,7 +325,7 @@ g_network_monitor_portal_initable_init (GInitable *initable,
g_variant_get (ret, "u", &version);
g_variant_unref (ret);
- if (version != 1 && version != 2)
+ if (version != 1 && version != 2 && version != 3)
{
g_object_unref (proxy);
g_set_error (error,
@@ -345,7 +345,7 @@ g_network_monitor_portal_initable_init (GInitable *initable,
if (!initable_parent_iface->init (initable, cancellable, error))
return FALSE;
- if (nm->priv->has_network && nm->priv->version == 2)
+ if (nm->priv->has_network && nm->priv->version > 1)
update_properties (proxy, nm);
return TRUE;
@@ -374,9 +374,128 @@ g_network_monitor_portal_class_init (GNetworkMonitorPortalClass *class)
g_object_class_override_property (gobject_class, PROP_CONNECTIVITY, "connectivity");
}
+static gboolean
+g_network_monitor_portal_can_reach (GNetworkMonitor *monitor,
+ GSocketConnectable *connectable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (monitor);
+ GVariant *ret;
+ GNetworkAddress *address;
+ gboolean reachable = FALSE;
+
+ if (!G_IS_NETWORK_ADDRESS (connectable))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Can't handle this kind of GSocketConnectable (%s)",
+ G_OBJECT_TYPE_NAME (connectable));
+ return FALSE;
+ }
+
+ address = G_NETWORK_ADDRESS (connectable);
+
+ ret = g_dbus_proxy_call_sync (nm->priv->proxy,
+ "CanReach",
+ g_variant_new ("(su)",
+ g_network_address_get_hostname (address),
+ g_network_address_get_port (address)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ error);
+
+ if (ret)
+ {
+ g_variant_get (ret, "(b)", &reachable);
+ g_variant_unref (ret);
+ }
+
+ return reachable;
+}
+
+static void
+can_reach_done (GObject *source,
+ GAsyncResult *result,
+ gpointer data)
+{
+ GTask *task = data;
+ GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (g_task_get_source_object (task));
+ GError *error = NULL;
+ GVariant *ret;
+ gboolean reachable;
+
+ ret = g_dbus_proxy_call_finish (nm->priv->proxy, result, &error);
+ if (ret == NULL)
+ {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ g_variant_get (ret, "(b)", &reachable);
+ g_variant_unref (ret);
+
+ if (reachable)
+ g_task_return_boolean (task, TRUE);
+ else
+ g_task_return_new_error (task,
+ G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE,
+ "Can't reach host");
+
+ g_object_unref (task);
+}
+
+static void
+g_network_monitor_portal_can_reach_async (GNetworkMonitor *monitor,
+ GSocketConnectable *connectable,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer data)
+{
+ GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (monitor);
+ GTask *task;
+ GNetworkAddress *address;
+
+ task = g_task_new (monitor, cancellable, callback, data);
+
+ if (!G_IS_NETWORK_ADDRESS (connectable))
+ {
+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Can't handle this kind of GSocketConnectable (%s)",
+ G_OBJECT_TYPE_NAME (connectable));
+ g_object_unref (task);
+ return;
+ }
+
+ address = G_NETWORK_ADDRESS (connectable);
+
+ g_dbus_proxy_call (nm->priv->proxy,
+ "CanReach",
+ g_variant_new ("(su)",
+ g_network_address_get_hostname (address),
+ g_network_address_get_port (address)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ can_reach_done,
+ task);
+}
+
+static gboolean
+g_network_monitor_portal_can_reach_finish (GNetworkMonitor *monitor,
+ GAsyncResult *result,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
static void
g_network_monitor_portal_iface_init (GNetworkMonitorInterface *monitor_iface)
{
+ monitor_iface->can_reach = g_network_monitor_portal_can_reach;
+ monitor_iface->can_reach_async = g_network_monitor_portal_can_reach_async;
+ monitor_iface->can_reach_finish = g_network_monitor_portal_can_reach_finish;
}
static void