Whitespace fixes
[platform/upstream/glib.git] / gio / gnetworkmonitor.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright 2011 Red Hat, Inc
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22 #include "glib.h"
23 #include "glibintl.h"
24
25 #include "gnetworkmonitor.h"
26 #include "ginetaddress.h"
27 #include "ginetsocketaddress.h"
28 #include "ginitable.h"
29 #include "gioenumtypes.h"
30 #include "giomodule-priv.h"
31 #include "gsimpleasyncresult.h"
32
33 /**
34  * SECTION:gnetworkmonitor
35  * @title: GNetworkMonitor
36  * @short_description: Network status monitor
37  * @include: gio/gio.h
38  */
39
40 /**
41  * GNetworkMonitor:
42  *
43  * #GNetworkMonitor monitors the status of network connections and
44  * indicates when a possibly-user-visible change has occurred.
45  *
46  * Since: 2.32
47  */
48
49 G_DEFINE_INTERFACE_WITH_CODE (GNetworkMonitor, g_network_monitor, G_TYPE_OBJECT,
50                               g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_INITABLE);)
51
52
53 enum {
54   NETWORK_CHANGED,
55   LAST_SIGNAL
56 };
57
58 static guint signals[LAST_SIGNAL] = { 0 };
59
60 /**
61  * g_network_monitor_get_default:
62  *
63  * Gets the default #GNetworkMonitor for the system.
64  *
65  * Returns: (transfer none): a #GNetworkMonitor
66  *
67  * Since: 2.32
68  */
69 GNetworkMonitor *
70 g_network_monitor_get_default (void)
71 {
72   return _g_io_module_get_default (G_NETWORK_MONITOR_EXTENSION_POINT_NAME,
73                                    "GIO_USE_NETWORK_MONITOR",
74                                    NULL);
75 }
76
77 /**
78  * g_network_monitor_get_network_available:
79  * @monitor: the #GNetworkMonitor
80  *
81  * Checks if the network is available. "Available" here means that the
82  * system has a default route available for at least one of IPv4 or
83  * IPv6. It does not necessarily imply that the public Internet is
84  * reachable. See #GNetworkMonitor:network-available for more details.
85  *
86  * Return value: whether the network is available
87  *
88  * Since: 2.32
89  */
90 gboolean
91 g_network_monitor_get_network_available (GNetworkMonitor *monitor)
92 {
93   gboolean available = FALSE;
94
95   g_object_get (G_OBJECT (monitor), "network-available", &available, NULL);
96   return available;
97 }
98
99 /**
100  * g_network_monitor_can_reach:
101  * @monitor: a #GNetworkMonitor
102  * @connectable: a #GSocketConnectable
103  * @cancellable: a #GCancellable, or %NULL
104  * @error: return location for a #GError, or %NULL
105  *
106  * Attempts to determine whether or not the host pointed to by
107  * @connectable can be reached, without actually trying to connect to
108  * it.
109  *
110  * This may return %TRUE even when #GNetworkMonitor:network-available
111  * is %FALSE, if, for example, @monitor can determine that
112  * @connectable refers to a host on a local network.
113  *
114  * If @monitor believes that an attempt to connect to @connectable
115  * will succeed, it will return %TRUE. Otherwise, it will return
116  * %FALSE and set @error to an appropriate error (such as
117  * %G_IO_ERROR_HOST_UNREACHABLE).
118  *
119  * Note that although this does not attempt to connect to
120  * @connectable, it may still block for a brief period of time (eg,
121  * trying to do multicast DNS on the local network), so if you do not
122  * want to block, you should use g_network_monitor_can_reach_async().
123  *
124  * Return value: %TRUE if @connectable is reachable, %FALSE if not.
125  *
126  * Since: 2.32
127  */
128 gboolean
129 g_network_monitor_can_reach (GNetworkMonitor     *monitor,
130                              GSocketConnectable  *connectable,
131                              GCancellable        *cancellable,
132                              GError             **error)
133 {
134   GNetworkMonitorInterface *iface;
135
136   iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
137   return iface->can_reach (monitor, connectable, cancellable, error);
138 }
139
140 static void
141 g_network_monitor_real_can_reach_async (GNetworkMonitor     *monitor,
142                                         GSocketConnectable  *connectable,
143                                         GCancellable        *cancellable,
144                                         GAsyncReadyCallback  callback,
145                                         gpointer             user_data)
146 {
147   GSimpleAsyncResult *simple;
148   GError *error = NULL;
149
150   simple = g_simple_async_result_new (G_OBJECT (monitor),
151                                       callback, user_data,
152                                       g_network_monitor_real_can_reach_async);
153   if (g_network_monitor_can_reach (monitor, connectable, cancellable, &error))
154     g_simple_async_result_set_op_res_gboolean (simple, TRUE);
155   else
156     g_simple_async_result_take_error (simple, error);
157   g_simple_async_result_complete_in_idle (simple);
158   g_object_unref (simple);
159 }
160
161 void
162 g_network_monitor_can_reach_async (GNetworkMonitor     *monitor,
163                                    GSocketConnectable  *connectable,
164                                    GCancellable        *cancellable,
165                                    GAsyncReadyCallback  callback,
166                                    gpointer             user_data)
167 {
168   GNetworkMonitorInterface *iface;
169
170   iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
171   iface->can_reach_async (monitor, connectable, cancellable, callback, user_data);
172 }
173
174 static gboolean
175 g_network_monitor_real_can_reach_finish (GNetworkMonitor  *monitor,
176                                          GAsyncResult     *result,
177                                          GError          **error)
178 {
179   GSimpleAsyncResult *simple;
180
181   g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (monitor), g_network_monitor_real_can_reach_async), FALSE);
182
183   simple = G_SIMPLE_ASYNC_RESULT (result);
184   if (g_simple_async_result_propagate_error (simple, error))
185     return FALSE;
186   else
187     return g_simple_async_result_get_op_res_gboolean (simple);
188 }
189
190 gboolean
191 g_network_monitor_can_reach_finish (GNetworkMonitor     *monitor,
192                                     GAsyncResult        *result,
193                                     GError             **error)
194 {
195   GNetworkMonitorInterface *iface;
196
197   iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
198   return iface->can_reach_finish (monitor, result, error);
199 }
200
201 static void
202 g_network_monitor_default_init (GNetworkMonitorInterface *iface)
203 {
204   iface->can_reach_async  = g_network_monitor_real_can_reach_async;
205   iface->can_reach_finish = g_network_monitor_real_can_reach_finish;
206
207   /**
208    * GNetworkMonitor::network-changed:
209    * @monitor: a #GNetworkMonitor
210    * @available: the current value of #GNetworkMonitor:network-available
211    *
212    * Emitted when the network configuration changes. If @available is
213    * %TRUE, then some hosts may be reachable that were not reachable
214    * before, while others that were reachable before may no longer be
215    * reachable. If @available is %FALSE, then no remote hosts are
216    * reachable.
217    *
218    * Since: 2.32
219    */
220   signals[NETWORK_CHANGED] =
221     g_signal_new (I_("network-changed"),
222                   G_TYPE_NETWORK_MONITOR,
223                   G_SIGNAL_RUN_LAST,
224                   G_STRUCT_OFFSET (GNetworkMonitorInterface, network_changed),
225                   NULL, NULL,
226                   g_cclosure_marshal_VOID__BOOLEAN,
227                   G_TYPE_NONE, 1,
228                   G_TYPE_BOOLEAN);
229
230   /**
231    * GNetworkMonitor:network-available:
232    *
233    * Whether the network is considered available. That is, whether the
234    * system has a default route for at least one of IPv4 or IPv6.
235    *
236    * Real-world networks are of course much more complicated than
237    * this; the machine may be connected to a wifi hotspot that
238    * requires payment before allowing traffic through, or may be
239    * connected to a functioning router that has lost its own upstream
240    * connectivity. Some hosts might only be accessible when a VPN is
241    * active. Other hosts might only be accessible when the VPN is
242    * <emphasis>not</emphasis> active. Thus, it is best to use
243    * g_network_monitor_can_reach() or
244    * g_network_monitor_can_reach_async() to test for reachability on a
245    * host-by-host basis. (On the other hand, when the property is
246    * %FALSE, the application can reasonably expect that no remote
247    * hosts at all are reachable, and should indicate this to the user
248    * in its UI.)
249    *
250    * See also #GNetworkMonitor::network-changed.
251    *
252    * Since: 2.32
253    */
254   g_object_interface_install_property (iface,
255                                        g_param_spec_boolean ("network-available",
256                                                              P_("Network available"),
257                                                              P_("Whether the network is available"),
258                                                              FALSE,
259                                                              G_PARAM_READABLE |
260                                                              G_PARAM_STATIC_STRINGS));
261 }