diff options
| author | Michael Biebl <biebl@debian.org> | 2017-01-17 20:25:09 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2017-01-17 20:25:09 +0100 |
| commit | 58f8be580039b0575b197b9573a1c92745d96d30 (patch) | |
| tree | 2c226233f623a0dcb529be0eb8cdf97e4a2ae0c0 /libnm/nm-client.c | |
| parent | 45cb5bb3c0e6edb887cf69b417fcaf7053814a9b (diff) | |
New upstream version 1.5.90 upstream/1.5.90
Diffstat (limited to 'libnm/nm-client.c')
| -rw-r--r-- | libnm/nm-client.c | 947 |
1 files changed, 887 insertions, 60 deletions
diff --git a/libnm/nm-client.c b/libnm/nm-client.c index 64c0d9de..63eaa84c 100644 --- a/libnm/nm-client.c +++ b/libnm/nm-client.c @@ -26,16 +26,55 @@ #include "nm-utils.h" #include "nm-client.h" #include "nm-manager.h" +#include "nm-dns-manager.h" #include "nm-remote-settings.h" #include "nm-device-ethernet.h" #include "nm-device-wifi.h" -#include "nm-device-private.h" #include "nm-core-internal.h" #include "nm-active-connection.h" #include "nm-vpn-connection.h" #include "nm-remote-connection.h" -#include "nm-object-cache.h" #include "nm-dbus-helpers.h" +#include "nm-wimax-nsp.h" +#include "nm-object-private.h" + +#include "introspection/org.freedesktop.NetworkManager.h" +#include "introspection/org.freedesktop.NetworkManager.Device.Wireless.h" +#include "introspection/org.freedesktop.NetworkManager.Device.h" +#include "introspection/org.freedesktop.NetworkManager.DnsManager.h" +#include "introspection/org.freedesktop.NetworkManager.Settings.h" +#include "introspection/org.freedesktop.NetworkManager.Settings.Connection.h" +#include "introspection/org.freedesktop.NetworkManager.VPN.Connection.h" + +#include "nm-access-point.h" +#include "nm-active-connection.h" +#include "nm-device-adsl.h" +#include "nm-device-bond.h" +#include "nm-device-bridge.h" +#include "nm-device-bt.h" +#include "nm-device-ethernet.h" +#include "nm-device-generic.h" +#include "nm-device-infiniband.h" +#include "nm-device-ip-tunnel.h" +#include "nm-device-macsec.h" +#include "nm-device-macvlan.h" +#include "nm-device-modem.h" +#include "nm-device-olpc-mesh.h" +#include "nm-device-team.h" +#include "nm-device-tun.h" +#include "nm-device-vlan.h" +#include "nm-device-vxlan.h" +#include "nm-device-wifi.h" +#include "nm-device-wimax.h" +#include "nm-dhcp4-config.h" +#include "nm-dhcp6-config.h" +#include "nm-dhcp-config.h" +#include "nm-ip4-config.h" +#include "nm-ip6-config.h" +#include "nm-manager.h" +#include "nm-remote-connection.h" +#include "nm-remote-settings.h" +#include "nm-vpn-connection.h" void _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, gboolean enabled); @@ -52,6 +91,9 @@ G_DEFINE_TYPE_WITH_CODE (NMClient, nm_client, G_TYPE_OBJECT, typedef struct { NMManager *manager; NMRemoteSettings *settings; + NMDnsManager *dns_manager; + GDBusObjectManager *object_manager; + GCancellable *new_object_manager_cancellable; } NMClientPrivate; enum { @@ -77,6 +119,9 @@ enum { PROP_HOSTNAME, PROP_CAN_MODIFY, PROP_METERED, + PROP_DNS_MODE, + PROP_DNS_RC_MANAGER, + PROP_DNS_CONFIGURATION, LAST_PROP }; @@ -97,7 +142,9 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -/**********************************************************************/ +static const GPtrArray empty = { 0, }; + +/*****************************************************************************/ /** * nm_client_error_quark: @@ -116,7 +163,7 @@ nm_client_error_quark (void) return quark; } -/**********************************************************************/ +/*****************************************************************************/ static void nm_client_init (NMClient *client) @@ -150,6 +197,9 @@ nm_client_get_version (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + if (!nm_client_get_nm_running (client)) + return NULL; + return nm_manager_get_version (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -166,6 +216,9 @@ nm_client_get_state (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), NM_STATE_UNKNOWN); + if (!nm_client_get_nm_running (client)) + return NM_STATE_UNKNOWN; + return nm_manager_get_state (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -181,7 +234,10 @@ nm_client_get_state (NMClient *client) gboolean nm_client_get_startup (NMClient *client) { - g_return_val_if_fail (NM_IS_CLIENT (client), NM_STATE_UNKNOWN); + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + if (!nm_client_get_nm_running (client)) + return FALSE; return nm_manager_get_startup (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -199,7 +255,7 @@ nm_client_get_nm_running (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); - return nm_manager_get_nm_running (NM_CLIENT_GET_PRIVATE (client)->manager); + return NM_CLIENT_GET_PRIVATE (client)->manager != NULL; } /** @@ -215,6 +271,9 @@ nm_client_networking_get_enabled (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + if (!nm_client_get_nm_running (client)) + return FALSE; + return nm_manager_networking_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -255,6 +314,9 @@ nm_client_wireless_get_enabled (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + if (!nm_client_get_nm_running (client)) + return FALSE; + return nm_manager_wireless_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -270,7 +332,7 @@ nm_client_wireless_set_enabled (NMClient *client, gboolean enabled) { g_return_if_fail (NM_IS_CLIENT (client)); - if (!_nm_client_check_nm_running (client, NULL)) + if (!nm_client_get_nm_running (client)) return; nm_manager_wireless_set_enabled (NM_CLIENT_GET_PRIVATE (client)->manager, enabled); @@ -289,6 +351,9 @@ nm_client_wireless_hardware_get_enabled (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + if (!nm_client_get_nm_running (client)) + return FALSE; + return nm_manager_wireless_hardware_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -305,6 +370,9 @@ nm_client_wwan_get_enabled (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + if (!nm_client_get_nm_running (client)) + return FALSE; + return nm_manager_wwan_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -339,6 +407,9 @@ nm_client_wwan_hardware_get_enabled (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + if (!nm_client_get_nm_running (client)) + return FALSE; + return nm_manager_wwan_hardware_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -355,6 +426,9 @@ nm_client_wimax_get_enabled (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + if (!nm_client_get_nm_running (client)) + return FALSE; + return nm_manager_wimax_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -370,7 +444,7 @@ nm_client_wimax_set_enabled (NMClient *client, gboolean enabled) { g_return_if_fail (NM_IS_CLIENT (client)); - if (!_nm_client_check_nm_running (client, NULL)) + if (!nm_client_get_nm_running (client)) return; nm_manager_wimax_set_enabled (NM_CLIENT_GET_PRIVATE (client)->manager, enabled); @@ -389,6 +463,9 @@ nm_client_wimax_hardware_get_enabled (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + if (!nm_client_get_nm_running (client)) + return FALSE; + return nm_manager_wimax_hardware_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -459,6 +536,9 @@ nm_client_get_permission_result (NMClient *client, NMClientPermission permission { g_return_val_if_fail (NM_IS_CLIENT (client), NM_CLIENT_PERMISSION_RESULT_UNKNOWN); + if (!nm_client_get_nm_running (client)) + return NM_CLIENT_PERMISSION_RESULT_UNKNOWN; + return nm_manager_get_permission_result (NM_CLIENT_GET_PRIVATE (client)->manager, permission); } @@ -478,6 +558,9 @@ nm_client_get_connectivity (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), NM_CONNECTIVITY_UNKNOWN); + if (!nm_client_get_nm_running (client)) + return NM_CONNECTIVITY_UNKNOWN; + return nm_manager_get_connectivity (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -614,6 +697,9 @@ nm_client_save_hostname (NMClient *client, { g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + if (!_nm_client_check_nm_running (client, error)) + return FALSE; + return nm_remote_settings_save_hostname (NM_CLIENT_GET_PRIVATE (client)->settings, hostname, cancellable, error); } @@ -698,9 +784,9 @@ nm_client_save_hostname_finish (NMClient *client, return g_simple_async_result_get_op_res_gboolean (simple); } -/****************************************************************/ +/*****************************************************************************/ /* Devices */ -/****************************************************************/ +/*****************************************************************************/ /** * nm_client_get_devices: @@ -720,6 +806,9 @@ nm_client_get_devices (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + if (!nm_client_get_nm_running (client)) + return ∅ + return nm_manager_get_devices (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -748,6 +837,9 @@ nm_client_get_all_devices (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + if (!nm_client_get_nm_running (client)) + return ∅ + return nm_manager_get_all_devices (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -766,6 +858,9 @@ nm_client_get_device_by_path (NMClient *client, const char *object_path) g_return_val_if_fail (NM_IS_CLIENT (client), NULL); g_return_val_if_fail (object_path, NULL); + if (!nm_client_get_nm_running (client)) + return NULL; + return nm_manager_get_device_by_path (NM_CLIENT_GET_PRIVATE (client)->manager, object_path); } @@ -784,12 +879,15 @@ nm_client_get_device_by_iface (NMClient *client, const char *iface) g_return_val_if_fail (NM_IS_CLIENT (client), NULL); g_return_val_if_fail (iface, NULL); + if (!nm_client_get_nm_running (client)) + return NULL; + return nm_manager_get_device_by_iface (NM_CLIENT_GET_PRIVATE (client)->manager, iface); } -/****************************************************************/ +/*****************************************************************************/ /* Active Connections */ -/****************************************************************/ +/*****************************************************************************/ /** * nm_client_get_active_connections: @@ -806,6 +904,9 @@ nm_client_get_active_connections (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + if (!nm_client_get_nm_running (client)) + return ∅ + return nm_manager_get_active_connections (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -833,6 +934,9 @@ nm_client_get_primary_connection (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + if (!nm_client_get_nm_running (client)) + return NULL; + return nm_manager_get_primary_connection (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -852,6 +956,9 @@ nm_client_get_activating_connection (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + if (!nm_client_get_nm_running (client)) + return NULL; + return nm_manager_get_activating_connection (NM_CLIENT_GET_PRIVATE (client)->manager); } @@ -1093,7 +1200,7 @@ nm_client_deactivate_connection (NMClient *client, g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (active), FALSE); - if (!_nm_client_check_nm_running (client, NULL)) + if (!nm_client_get_nm_running (client)) return TRUE; return nm_manager_deactivate_connection (NM_CLIENT_GET_PRIVATE (client)->manager, @@ -1180,9 +1287,9 @@ nm_client_deactivate_connection_finish (NMClient *client, return g_simple_async_result_get_op_res_gboolean (simple); } -/****************************************************************/ +/*****************************************************************************/ /* Connections */ -/****************************************************************/ +/*****************************************************************************/ /** * nm_client_get_connections: @@ -1200,6 +1307,9 @@ nm_client_get_connections (NMClient *client) { g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + if (!nm_client_get_nm_running (client)) + return ∅ + return nm_remote_settings_get_connections (NM_CLIENT_GET_PRIVATE (client)->settings); } @@ -1222,6 +1332,9 @@ nm_client_get_connection_by_id (NMClient *client, const char *id) g_return_val_if_fail (NM_IS_CLIENT (client), NULL); g_return_val_if_fail (id != NULL, NULL); + if (!nm_client_get_nm_running (client)) + NULL; + return nm_remote_settings_get_connection_by_id (NM_CLIENT_GET_PRIVATE (client)->settings, id); } @@ -1244,6 +1357,9 @@ nm_client_get_connection_by_path (NMClient *client, const char *path) g_return_val_if_fail (NM_IS_CLIENT (client), NULL); g_return_val_if_fail (path != NULL, NULL); + if (!nm_client_get_nm_running (client)) + NULL; + return nm_remote_settings_get_connection_by_path (NM_CLIENT_GET_PRIVATE (client)->settings, path); } @@ -1266,6 +1382,9 @@ nm_client_get_connection_by_uuid (NMClient *client, const char *uuid) g_return_val_if_fail (NM_IS_CLIENT (client), NULL); g_return_val_if_fail (uuid != NULL, NULL); + if (!nm_client_get_nm_running (client)) + NULL; + return nm_remote_settings_get_connection_by_uuid (NM_CLIENT_GET_PRIVATE (client)->settings, uuid); } @@ -1602,7 +1721,86 @@ nm_client_reload_connections_finish (NMClient *client, return g_simple_async_result_get_op_res_gboolean (simple); } -/****************************************************************/ +/*****************************************************************************/ + +/** + * nm_client_get_dns_mode: + * @client: the #NMClient + * + * Gets the current DNS processing mode. + * + * Return value: the DNS processing mode, or %NULL in case the + * value is not available. + * + * Since: 1.6 + **/ +const char * +nm_client_get_dns_mode (NMClient *client) +{ + NMClientPrivate *priv; + + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + priv = NM_CLIENT_GET_PRIVATE (client); + + if (priv->dns_manager) + return nm_dns_manager_get_mode (priv->dns_manager); + else + return NULL; +} + +/** + * nm_client_get_dns_rc_manager: + * @client: the #NMClient + * + * Gets the current DNS resolv.conf manager. + * + * Return value: the resolv.conf manager or %NULL in case the + * value is not available. + * + * Since: 1.6 + **/ +const char * +nm_client_get_dns_rc_manager (NMClient *client) +{ + NMClientPrivate *priv; + + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + priv = NM_CLIENT_GET_PRIVATE (client); + + if (priv->dns_manager) + return nm_dns_manager_get_rc_manager (priv->dns_manager); + else + return NULL; +} + +/** + * nm_client_get_dns_configuration: + * @client: a #NMClient + * + * Gets the current DNS configuration + * + * Returns: (transfer none) (element-type NMDnsEntry): a #GPtrArray + * containing #NMDnsEntry elements or %NULL in case the value is not + * available. The returned array is owned by the #NMClient object + * and should not be modified. + * + * Since: 1.6 + **/ +const GPtrArray * +nm_client_get_dns_configuration (NMClient *client) +{ + NMClientPrivate *priv; + + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + priv = NM_CLIENT_GET_PRIVATE (client); + + if (priv->dns_manager) + return nm_dns_manager_get_configuration (priv->dns_manager); + else + return NULL; +} + +/*****************************************************************************/ /** * nm_client_new: @@ -1770,14 +1968,222 @@ manager_active_connection_removed (NMManager *manager, } static void -constructed (GObject *object) +dns_notify (GObject *object, + GParamSpec *pspec, + gpointer client) +{ + char pname[128]; + + if (NM_IN_STRSET (pspec->name, + NM_DNS_MANAGER_MODE, + NM_DNS_MANAGER_RC_MANAGER, + NM_DNS_MANAGER_CONFIGURATION)) { + nm_sprintf_buf (pname, "dns-%s", pspec->name); + g_object_notify (client, pname); + } +} + +/****************************************************************/ +/* Object Initialization */ +/****************************************************************/ + +static GType +proxy_type (GDBusObjectManagerClient *manager, + const gchar *object_path, + const gchar *interface_name, + gpointer user_data) +{ + /* ObjectManager asks us for an object proxy. Unfortunatelly, we can't + * decide that by interface name and GDBusObjectManager doesn't allow + * us to look at the known interface list. Thus we need to create a + * generic GDBusObject and only couple a NMObject subclass later. */ + if (!interface_name) + return G_TYPE_DBUS_OBJECT_PROXY; + + /* An interface proxy */ + if (strcmp (interface_name, NM_DBUS_INTERFACE) == 0) + return NMDBUS_TYPE_MANAGER_PROXY; + else if (strcmp (interface_name, NM_DBUS_INTERFACE_DEVICE_WIRELESS) == 0) + return NMDBUS_TYPE_DEVICE_WIFI_PROXY; + else if (strcmp (interface_name, NM_DBUS_INTERFACE_DEVICE) == 0) + return NMDBUS_TYPE_DEVICE_PROXY; + else if (strcmp (interface_name, NM_DBUS_INTERFACE_SETTINGS_CONNECTION) == 0) + return NMDBUS_TYPE_SETTINGS_CONNECTION_PROXY; + else if (strcmp (interface_name, NM_DBUS_INTERFACE_SETTINGS) == 0) + return NMDBUS_TYPE_SETTINGS_PROXY; + else if (strcmp (interface_name, NM_DBUS_INTERFACE_DNS_MANAGER) == 0) + return NMDBUS_TYPE_DNS_MANAGER_PROXY; + else if (strcmp (interface_name, NM_DBUS_INTERFACE_VPN_CONNECTION) == 0) + return NMDBUS_TYPE_VPN_CONNECTION_PROXY; + + /* Use a generic D-Bus Proxy whenever we can. The typed GDBusProxy + * subclasses actually use quite some memory, so they're better avoided. */ + return G_TYPE_DBUS_PROXY; +} + +static NMObject * +obj_nm_for_gdbus_object (GDBusObject *object, GDBusObjectManager *object_manager) +{ + GList *interfaces; + GList *l; + GType type = G_TYPE_INVALID; + NMObject *obj_nm; + + g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (object), NULL); + + interfaces = g_dbus_object_get_interfaces (object); + for (l = interfaces; l; l = l->next) { + GDBusProxy *proxy = G_DBUS_PROXY (l->data); + const char *ifname = g_dbus_proxy_get_interface_name (proxy); + + /* This is a performance/scalability hack. It makes sense to call it + * from here, since this is in the common object creation path. */ + _nm_dbus_proxy_replace_match (proxy); + + if (strcmp (ifname, NM_DBUS_INTERFACE) == 0) + type = NM_TYPE_MANAGER; + else if (strcmp (ifname, NM_DBUS_INTERFACE_ACCESS_POINT) == 0) + type = NM_TYPE_ACCESS_POINT; + else if (strcmp (ifname, NM_DBUS_INTERFACE_ACTIVE_CONNECTION) == 0 && type != NM_TYPE_VPN_CONNECTION) + type = NM_TYPE_ACTIVE_CONNECTION; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_ADSL) == 0) + type = NM_TYPE_DEVICE_ADSL; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_BOND) == 0) + type = NM_TYPE_DEVICE_BOND; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_BRIDGE) == 0) + type = NM_TYPE_DEVICE_BRIDGE; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_BLUETOOTH) == 0) + type = NM_TYPE_DEVICE_BT; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_WIRED) == 0) + type = NM_TYPE_DEVICE_ETHERNET; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_GENERIC) == 0) + type = NM_TYPE_DEVICE_GENERIC; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_INFINIBAND) == 0) + type = NM_TYPE_DEVICE_INFINIBAND; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL) == 0) + type = NM_TYPE_DEVICE_IP_TUNNEL; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_MACSEC) == 0) + type = NM_TYPE_DEVICE_MACSEC; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_MACVLAN) == 0) + type = NM_TYPE_DEVICE_MACVLAN; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_MODEM) == 0) + type = NM_TYPE_DEVICE_MODEM; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_OLPC_MESH) == 0) + type = NM_TYPE_DEVICE_OLPC_MESH; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_TEAM) == 0) + type = NM_TYPE_DEVICE_TEAM; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_TUN) == 0) + type = NM_TYPE_DEVICE_TUN; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_VLAN) == 0) + type = NM_TYPE_DEVICE_VLAN; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_VXLAN) == 0) + type = NM_TYPE_DEVICE_VXLAN; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_WIRELESS) == 0) + type = NM_TYPE_DEVICE_WIFI; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_WIMAX) == 0) + type = NM_TYPE_DEVICE_WIMAX; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DHCP4_CONFIG) == 0) + type = NM_TYPE_DHCP4_CONFIG; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DHCP6_CONFIG) == 0) + type = NM_TYPE_DHCP6_CONFIG; + else if (strcmp (ifname, NM_DBUS_INTERFACE_IP4_CONFIG) == 0) + type = NM_TYPE_IP4_CONFIG; + else if (strcmp (ifname, NM_DBUS_INTERFACE_IP6_CONFIG) == 0) + type = NM_TYPE_IP6_CONFIG; + else if (strcmp (ifname, NM_DBUS_INTERFACE_SETTINGS_CONNECTION) == 0) + type = NM_TYPE_REMOTE_CONNECTION; + else if (strcmp (ifname, NM_DBUS_INTERFACE_SETTINGS) == 0) + type = NM_TYPE_REMOTE_SETTINGS; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DNS_MANAGER) == 0) + type = NM_TYPE_DNS_MANAGER; + else if (strcmp (ifname, NM_DBUS_INTERFACE_VPN_CONNECTION) == 0) + type = NM_TYPE_VPN_CONNECTION; + else if (strcmp (ifname, NM_DBUS_INTERFACE_WIMAX_NSP) == 0) + type = NM_TYPE_WIMAX_NSP; + + if (type != G_TYPE_INVALID) + break; + } + + g_list_free_full (interfaces, g_object_unref); + if (type == G_TYPE_INVALID) + return NULL; + + obj_nm = g_object_new (type, + NM_OBJECT_DBUS_OBJECT, object, + NM_OBJECT_DBUS_OBJECT_MANAGER, object_manager, + NULL); + g_object_set_qdata_full (G_OBJECT (object), _nm_object_obj_nm_quark (), + obj_nm, g_object_unref); + return obj_nm; +} + +static void +obj_nm_inited (GObject *object, GAsyncResult *result, gpointer user_data) +{ + if (!g_async_initable_init_finish (G_ASYNC_INITABLE (object), result, NULL)) { + /* This is a can-not-happen situation, the NMObject subclasses are not + * supposed to fail initialization. */ + g_warn_if_reached (); + } +} + + +static void +object_added (GDBusObjectManager *object_manager, GDBusObject *object, gpointer user_data) +{ + NMObject *obj_nm; + + obj_nm = obj_nm_for_gdbus_object (object, object_manager); + if (obj_nm) { + g_async_initable_init_async (G_ASYNC_INITABLE (obj_nm), + G_PRIORITY_DEFAULT, NULL, + obj_nm_inited, NULL); + } +} + +static void +object_removed (GDBusObjectManager *object_manager, GDBusObject *object, gpointer user_data) +{ + g_object_set_qdata (G_OBJECT (object), _nm_object_obj_nm_quark (), NULL); +} + +static gboolean +objects_created (NMClient *client, GDBusObjectManager *object_manager, GError **error) { - NMClient *client = NM_CLIENT (object); NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); + gs_unref_object GDBusObject *manager = NULL; + gs_unref_object GDBusObject *settings = NULL; + gs_unref_object GDBusObject *dns_manager = NULL; + NMObject *obj_nm; + GList *objects, *iter; + + /* First just ensure all the NMObjects for known GDBusObjects exist. */ + objects = g_dbus_object_manager_get_objects (object_manager); + for (iter = objects; iter; iter = iter->next) + obj_nm_for_gdbus_object (iter->data, object_manager); + g_list_free_full (objects, g_object_unref); + + manager = g_dbus_object_manager_get_object (object_manager, NM_DBUS_PATH); + if (!manager) { + g_set_error_literal (error, + NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "Manager object not found"); + return FALSE; + } + + obj_nm = g_object_get_qdata (G_OBJECT (manager), _nm_object_obj_nm_quark ()); + if (!obj_nm) { + g_set_error_literal (error, + NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "Manager object lacks the proper interface"); + return FALSE; + } + + priv->manager = NM_MANAGER (g_object_ref (obj_nm)); - priv->manager = g_object_new (NM_TYPE_MANAGER, - NM_OBJECT_PATH, NM_DBUS_PATH, - NULL); g_signal_connect (priv->manager, "notify", G_CALLBACK (subobject_notify), client); g_signal_connect (priv->manager, "device-added", @@ -1795,9 +2201,26 @@ constructed (GObject *object) g_signal_connect (priv->manager, "active-connection-removed", G_CALLBACK (manager_active_connection_removed), client); - priv->settings = g_object_new (NM_TYPE_REMOTE_SETTINGS, - NM_OBJECT_PATH, NM_DBUS_PATH_SETTINGS, - NULL); + settings = g_dbus_object_manager_get_object (object_manager, NM_DBUS_PATH_SETTINGS); + if (!settings) { + g_set_error_literal (error, + NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "Settings object not found"); + return FALSE; + } + + obj_nm = g_object_get_qdata (G_OBJECT (settings), _nm_object_obj_nm_quark ()); + if (!obj_nm) { + g_set_error_literal (error, + NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "Settings object lacks the proper interface"); + return FALSE; + } + + priv->settings = NM_REMOTE_SETTINGS (g_object_ref (obj_nm)); + g_signal_connect (priv->settings, "notify", G_CALLBACK (subobject_notify), client); g_signal_connect (priv->settings, "connection-added", @@ -1805,29 +2228,91 @@ constructed (GObject *object) g_signal_connect (priv->settings, "connection-removed", G_CALLBACK (settings_connection_removed), client); - G_OBJECT_CLASS (nm_client_parent_class)->constructed (object); + dns_manager = g_dbus_object_manager_get_object (object_manager, NM_DBUS_PATH_DNS_MANAGER); + if (dns_manager) { + obj_nm = g_object_get_qdata (G_OBJECT (dns_manager), _nm_object_obj_nm_quark ()); + if (!obj_nm) { + g_set_error_literal (error, + NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "DNS manager object lacks the proper interface"); + return FALSE; + } + priv->dns_manager = NM_DNS_MANAGER (g_object_ref (obj_nm)); + + g_signal_connect (priv->dns_manager, "notify", + G_CALLBACK (dns_notify), client); + } + + + /* The handlers don't really use the client instance. However + * it makes it convenient to unhook them by data. */ + g_signal_connect (object_manager, "object-added", + G_CALLBACK (object_added), client); + g_signal_connect (object_manager, "object-removed", + G_CALLBACK (object_removed), client); + + return TRUE; } +/* Synchronous initialization. */ + +static void name_owner_changed (GObject *object, GParamSpec *pspec, gpointer user_data); + static gboolean init_sync (GInitable *initable, GCancellable *cancellable, GError **error) { NMClient *client = NM_CLIENT (initable); NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); + GList *objects, *iter; + gchar *name_owner; - if (!g_initable_init (G_INITABLE (priv->manager), cancellable, error)) - return FALSE; - if (!g_initable_init (G_INITABLE (priv->settings), cancellable, error)) + priv->object_manager = g_dbus_object_manager_client_new_for_bus_sync (_nm_dbus_bus_type (), + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START, + "org.freedesktop.NetworkManager", + "/org/freedesktop", + proxy_type, NULL, NULL, + cancellable, error); + + if (!priv->object_manager) return FALSE; + name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager)); + if (name_owner) { + g_free (name_owner); + if (!objects_created (client, priv->object_manager, error)) + return FALSE; + + objects = g_dbus_object_manager_get_objects (priv->object_manager); + for (iter = objects; iter; iter = iter->next) { + NMObject *obj_nm; + + obj_nm = g_object_get_qdata (iter->data, _nm_object_obj_nm_quark ()); + if (!obj_nm) + continue; + + if (!g_initable_init (G_INITABLE (obj_nm), cancellable, NULL)) { + /* This is a can-not-happen situation, the NMObject subclasses are not + * supposed to fail initialization. */ + g_warn_if_reached (); + } + } + g_list_free_full (objects, g_object_unref); + } + + g_signal_connect (priv->object_manager, "notify::name-owner", + G_CALLBACK (name_owner_changed), client); + return TRUE; } +/* Asynchronous initialization. */ + typedef struct { NMClient *client; GCancellable *cancellable; GSimpleAsyncResult *result; - gboolean manager_inited; - gboolean settings_inited; + int pending_init; } NMClientInitData; static void @@ -1840,7 +2325,7 @@ init_async_complete (NMClientInitData *init_data) } static void -init_async_inited_manager (GObject *object, GAsyncResult *result, gpointer user_data) +async_inited_obj_nm (GObject *object, GAsyncResult *result, gpointer user_data) { NMClientInitData *init_data = user_data; GError *error = NULL; @@ -1848,46 +2333,185 @@ init_async_inited_manager (GObject *object, GAsyncResult *result, gpointer user_ if (!g_async_initable_init_finish (G_ASYNC_INITABLE (object), result, &error)) g_simple_async_result_take_error (init_data->result, error); - init_data->manager_inited = TRUE; - if (init_data->settings_inited) - init_async_complete (init_data); + if (init_data) { + init_data->pending_init--; + if (init_data->pending_init == 0) + init_async_complete (init_data); + } +} + +static void +init_async (GAsyncInitable *initable, int io_priority, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data); + +static void +unhook_om (NMClient *self) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self); + GList *objects, *iter; + + if (priv->manager) { + const GPtrArray *active_connections; + const GPtrArray *devices; + int i; + + active_connections = nm_manager_get_active_connections (priv->manager); + for (i = 0; i < active_connections->len; i++) + g_signal_emit (self, signals[ACTIVE_CONNECTION_REMOVED], 0, active_connections->pdata[i]); + + devices = nm_manager_get_all_devices (priv->manager); + for (i = 0; i < devices->len; i++) + g_signal_emit (self, signals[DEVICE_REMOVED], 0, devices->pdata[i]); + + g_signal_handlers_disconnect_by_data (priv->manager, self); + g_clear_object (&priv->manager); + g_object_notify (G_OBJECT (self), NM_CLIENT_ACTIVE_CONNECTIONS); + g_object_notify (G_OBJECT (self), NM_CLIENT_NM_RUNNING); + } + if (priv->settings) { + const GPtrArray *connections; + guint i; + + connections = nm_remote_settings_get_connections (priv->settings); + for (i = 0; i < connections->len; i++) + g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connections->pdata[i]); + + g_signal_handlers_disconnect_by_data (priv->settings, self); + g_clear_object (&priv->settings); + g_object_notify (G_OBJECT (self), NM_CLIENT_CONNECTIONS); + g_object_notify (G_OBJECT (self), NM_CLIENT_HOSTNAME); + g_object_notify (G_OBJECT (self), NM_CLIENT_CAN_MODIFY); + } + if (priv->dns_manager) { + g_signal_handlers_disconnect_by_data (priv->dns_manager, self); + g_clear_object (&priv->dns_manager); + } + + objects = g_dbus_object_manager_get_objects (priv->object_manager); + for (iter = objects; iter; iter = iter->next) + g_object_set_qdata (iter->data, _nm_object_obj_nm_quark (), NULL); + g_list_free_full (objects, g_object_unref); } static void -init_async_inited_settings (GObject *object, GAsyncResult *result, gpointer user_data) +new_object_manager (GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (source_object); + + g_object_notify (G_OBJECT (user_data), NM_CLIENT_NM_RUNNING); + g_clear_object (&priv->new_object_manager_cancellable); +} + +static void +got_object_manager (GObject *object, GAsyncResult *result, gpointer user_data) { NMClientInitData *init_data = user_data; + NMClient *client; + NMClientPrivate *priv; + GList *objects, *iter; + gchar *name_owner; GError *error = NULL; + GDBusObjectManager *object_manager; + + object_manager = g_dbus_object_manager_client_new_for_bus_finish (result, &error); + if (object_manager == NULL) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_simple_async_result_take_error (init_data->result, error); + init_async_complete (init_data); + } + return; + } - if (!g_async_initable_init_finish (G_ASYNC_INITABLE (object), result, &error)) - g_simple_async_result_take_error (init_data->result, error); - - init_data->settings_inited = TRUE; - if (init_data->manager_inited) + client = init_data->client; + priv = NM_CLIENT_GET_PRIVATE (client); + priv->object_manager = object_manager; + + name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager)); + if (name_owner) { + g_free (name_owner); + if (!objects_created (client, priv->object_manager, &error)) { + g_simple_async_result_take_error (init_data->result, error); + init_async_complete (init_data); + return; + } + + objects = g_dbus_object_manager_get_objects (priv->object_manager); + for (iter = objects; iter; iter = iter->next) { + NMObject *obj_nm; + + obj_nm = g_object_get_qdata (iter->data, _nm_object_obj_nm_quark ()); + if (!obj_nm) + continue; + + init_data->pending_init++; + g_async_initable_init_async (G_ASYNC_INITABLE (obj_nm), + G_PRIORITY_DEFAULT, init_data->cancellable, + async_inited_obj_nm, init_data); + } + g_list_free_full (objects, g_object_unref); + + } else init_async_complete (init_data); + + g_signal_connect (priv->object_manager, "notify::name-owner", + G_CALLBACK (name_owner_changed), client); } static void -init_async (GAsyncInitable *initable, int io_priority, - GCancellable *cancellable, GAsyncReadyCallback callback, - gpointer user_data) +prepare_object_manager (NMClient *client, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (initable); NMClientInitData *init_data; init_data = g_slice_new0 (NMClientInitData); - init_data->client = NM_CLIENT (initable); + init_data->client = client; init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL; - init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback, + init_data->result = g_simple_async_result_new (G_OBJECT (client), callback, user_data, init_async); g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE); - g_async_initable_init_async (G_ASYNC_INITABLE (priv->manager), - G_PRIORITY_DEFAULT, init_data->cancellable, - init_async_inited_manager, init_data); - g_async_initable_init_async (G_ASYNC_INITABLE (priv->settings), - G_PRIORITY_DEFAULT, init_data->cancellable, - init_async_inited_settings, init_data); + g_dbus_object_manager_client_new_for_bus (_nm_dbus_bus_type (), + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START, + "org.freedesktop.NetworkManager", + "/org/freedesktop", + proxy_type, NULL, NULL, + init_data->cancellable, + got_object_manager, + init_data); +} + +static void +name_owner_changed (GObject *object, GParamSpec *pspec, gpointer user_data) +{ + NMClient *self = user_data; + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self); + GDBusObjectManager *object_manager = G_DBUS_OBJECT_MANAGER (object); + gchar *name_owner; + + name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (object)); + if (name_owner) { + g_free (name_owner); + g_object_unref (object_manager); + if (priv->new_object_manager_cancellable) + g_cancellable_cancel (priv->new_object_manager_cancellable); + priv->new_object_manager_cancellable = g_cancellable_new (); + prepare_object_manager (self, priv->new_object_manager_cancellable, + new_object_manager, user_data); + } else { + g_signal_handlers_disconnect_by_func (object_manager, object_added, self); + unhook_om (self); + } +} + +static void +init_async (GAsyncInitable *initable, int io_priority, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) +{ + prepare_object_manager (NM_CLIENT (initable), cancellable, callback, user_data); } static gboolean @@ -1906,15 +2530,39 @@ dispose (GObject *object) { NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object); + if (priv->new_object_manager_cancellable) { + g_cancellable_cancel (priv->new_object_manager_cancellable); + g_clear_object (&priv->new_object_manager_cancellable); + } + if (priv->manager) { g_signal_handlers_disconnect_by_data (priv->manager, object); g_clear_object (&priv->manager); } + if (priv->settings) { g_signal_handlers_disconnect_by_data (priv->settings, object); g_clear_object (&priv->settings); } + if (priv->dns_manager) { + g_signal_handlers_disconnect_by_data (priv->dns_manager, object); + g_clear_object (&priv->dns_manager); + } + + if (priv->object_manager) { + GList *objects, *iter; + + /* Unhook the NM objects. */ + objects = g_dbus_object_manager_get_objects (priv->object_manager); + for (iter = objects; iter; iter = iter->next) + g_object_set_qdata (G_OBJECT (iter->data), _nm_object_obj_nm_quark (), NULL); + g_list_free_full (objects, g_object_unref); + + g_signal_handlers_disconnect_by_data (priv->object_manager, object); + g_clear_object (&priv->object_manager); + } + G_OBJECT_CLASS (nm_client_parent_class)->dispose (object); } @@ -1922,13 +2570,15 @@ static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object); + switch (prop_id) { case PROP_NETWORKING_ENABLED: case PROP_WIRELESS_ENABLED: case PROP_WWAN_ENABLED: case PROP_WIMAX_ENABLED: - g_object_set_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->manager), - pspec->name, value); + if (priv->manager) + g_object_set_property (G_OBJECT (priv->manager), pspec->name, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1940,33 +2590,116 @@ static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { + NMClient *self = NM_CLIENT (object); + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object); + switch (prop_id) { + case PROP_NM_RUNNING: + g_value_set_boolean (value, nm_client_get_nm_running (self)); + break; + + /* Manager properties. */ case PROP_VERSION: + g_value_set_string (value, nm_client_get_version (self)); + break; case PROP_STATE: + g_value_set_enum (value, nm_client_get_state (self)); + break; case PROP_STARTUP: - case PROP_NM_RUNNING: + g_value_set_boolean (value, nm_client_get_startup (self)); + break; case PROP_NETWORKING_ENABLED: + g_value_set_boolean (value, nm_client_networking_get_enabled (self)); + break; case PROP_WIRELESS_ENABLED: + g_value_set_boolean (value, nm_client_wireless_get_enabled (self)); + break; case PROP_WIRELESS_HARDWARE_ENABLED: + if (priv->manager) + g_object_get_property (G_OBJECT (priv->settings), pspec->name, value); + else + g_value_set_boolean (value, FALSE); + break; case PROP_WWAN_ENABLED: + g_value_set_boolean (value, nm_client_wwan_get_enabled (self)); + break; case PROP_WWAN_HARDWARE_ENABLED: + if (priv->manager) + g_object_get_property (G_OBJECT (priv->settings), pspec->name, value); + else + g_value_set_boolean (value, FALSE); + break; case PROP_WIMAX_ENABLED: + g_value_set_boolean (value, nm_client_wimax_get_enabled (self)); + break; case PROP_WIMAX_HARDWARE_ENABLED: + if (priv->manager) + g_object_get_property (G_OBJECT (priv->settings), pspec->name, value); + else + g_value_set_boolean (value, FALSE); + break; case PROP_ACTIVE_CONNECTIONS: + g_value_take_boxed (value, _nm_utils_copy_object_array (nm_client_get_active_connections (self))); + break; case PROP_CONNECTIVITY: + g_value_set_enum (value, nm_client_get_connectivity (self)); + break; case PROP_PRIMARY_CONNECTION: + g_value_set_object (value, nm_client_get_primary_connection (self)); + break; case PROP_ACTIVATING_CONNECTION: + g_value_set_object (value, nm_client_get_activating_connection (self)); + break; case PROP_DEVICES: + g_value_take_boxed (value, _nm_utils_copy_object_array (nm_client_get_devices (self))); + break; case PROP_METERED: + if (priv->manager) + g_object_get_property (G_OBJECT (priv->settings), pspec->name, value); + else + g_value_set_uint (value, NM_METERED_UNKNOWN); + break; case PROP_ALL_DEVICES: - g_object_get_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->manager), - pspec->name, value); + g_value_take_boxed (value, _nm_utils_copy_object_array (nm_client_get_all_devices (self))); break; + + /* Settings properties. */ case PROP_CONNECTIONS: + if (priv->settings) + g_object_get_property (G_OBJECT (priv->settings), pspec->name, value); + else + g_value_take_boxed (value, _nm_utils_copy_object_array (&empty)); + break; case PROP_HOSTNAME: + if (priv->settings) + g_object_get_property (G_OBJECT (priv->settings), pspec->name, value); + else + g_value_set_string (value, NULL); + break; case PROP_CAN_MODIFY: - g_object_get_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->settings), - pspec->name, value); + if (priv->settings) + g_object_get_property (G_OBJECT (priv->settings), pspec->name, value); + else + g_value_set_boolean (value, FALSE); + break; + + /* DNS properties */ + case PROP_DNS_MODE: + case PROP_DNS_RC_MANAGER: + g_return_if_fail (pspec->name && strlen (pspec->name) > NM_STRLEN ("dns-")); + if (priv->dns_manager) + g_object_get_property (G_OBJECT (priv->dns_manager), + &pspec->name[NM_STRLEN ("dns-")], value); + else + g_value_set_string (value, NULL); + break; + case PROP_DNS_CONFIGURATION: + if (priv->dns_manager) { + g_object_get_property (G_OBJECT (priv->dns_manager), + NM_DNS_MANAGER_CONFIGURATION, + value); + } else + g_value_take_boxed (value, NULL); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1982,7 +2715,6 @@ nm_client_class_init (NMClientClass *client_class) g_type_class_add_private (client_class, sizeof (NMClientPrivate)); /* virtual methods */ - object_class->constructed = constructed; object_class->set_property = set_property; object_class->get_property = get_property; object_class->dispose = dispose; @@ -2260,6 +2992,54 @@ nm_client_class_init (NMClientClass *client_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + /** + * NMClient:dns-mode: + * + * The current DNS processing mode. + * + * Since: 1.6 + **/ + g_object_class_install_property + (object_class, PROP_DNS_MODE, + g_param_spec_string (NM_CLIENT_DNS_MODE, "", "", + "", + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:dns-rc-manager: + * + * The current resolv.conf management mode. + * + * Since: 1.6 + **/ + g_object_class_install_property + (object_class, PROP_DNS_RC_MANAGER, + g_param_spec_string (NM_CLIENT_DNS_RC_MANAGER, "", "", + "", + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:dns-configuration: + * + * The current DNS configuration represented as an array of + * dictionaries. Each dictionary has the "nameservers", + * "priority" keys and, optionally, "interface" and "vpn". + * "nameservers" is the list of DNS servers, "priority" their + * relative priority, "interface" the interface on which these + * servers are contacted, "vpn" a boolean telling whether the + * configuration was obtained from a VPN connection. + * + * Since: 1.6 + **/ + g_object_class_install_property + (object_class, PROP_DNS_CONFIGURATION, + g_param_spec_boxed (NM_CLIENT_DNS_CONFIGURATION, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /* signals */ /** @@ -2419,3 +3199,50 @@ nm_client_async_initable_iface_init (GAsyncInitableIface *iface) iface->init_async = init_async; iface->init_finish = init_finish; } + +/***************************************************************************** + * Backported symbols. Usually, new API is only added in new major versions + * of NetworkManager (that is, on "master" branch). Sometimes however, we might + * have to backport some API to an older stable branch. In that case, we backport + * the symbols with a different version corresponding to the minor API. + * + * To allow upgrading from such a extended minor-release, "master" contains these + * backported symbols too. + * + * For example, 1.2.0 added nm_setting_connection_autoconnect_slaves_get_type. + * This was backported for 1.0.4 as nm_setting_connection_autoconnect_slaves_get_type@libnm_1_0_4 + * To allow an application that was linked against 1.0.4 to seamlessly upgrade to + * a newer major version, the same symbols is also exposed on "master". Note, that + * a user can only seamlessly upgrade to a newer major version, that is released + * *after* 1.0.4 is out. In this example, 1.2.0 was released after 1.4.0, and thus + * a 1.0.4 user can upgrade to 1.2.0 ABI. + *****************************************************************************/ + +NM_BACKPORT_SYMBOL (libnm_1_0_4, NMSettingConnectionAutoconnectSlaves, nm_setting_connection_get_autoconnect_slaves, (NMSettingConnection *setting), (setting)); + +NM_BACKPORT_SYMBOL (libnm_1_0_4, GType, nm_setting_connection_autoconnect_slaves_get_type, (void), ()); + +NM_BACKPORT_SYMBOL (libnm_1_0_6, NMMetered, nm_setting_connection_get_metered, (NMSettingConnection *setting), (setting)); + +NM_BACKPORT_SYMBOL (libnm_1_0_6, GType, nm_metered_get_type, (void), ()); + +NM_BACKPORT_SYMBOL (libnm_1_0_6, NMSettingWiredWakeOnLan, nm_setting_wired_get_wake_on_lan, + (NMSettingWired *setting), (setting)); + +NM_BACKPORT_SYMBOL (libnm_1_0_6, const char *, nm_setting_wired_get_wake_on_lan_password, + (NMSettingWired *setting), (setting)); + +NM_BACKPORT_SYMBOL (libnm_1_0_6, GType, nm_setting_wired_wake_on_lan_get_type, (void), ()); + +NM_BACKPORT_SYMBOL (libnm_1_0_6, const guint *, nm_utils_wifi_2ghz_freqs, (void), ()); + +NM_BACKPORT_SYMBOL (libnm_1_0_6, const guint *, nm_utils_wifi_5ghz_freqs, (void), ()); + +NM_BACKPORT_SYMBOL (libnm_1_0_6, char *, nm_utils_enum_to_str, + (GType type, int value), (type, value)); + +NM_BACKPORT_SYMBOL (libnm_1_0_6, gboolean, nm_utils_enum_from_str, + (GType type, const char *str, int *out_value, char **err_token), + (type, str, out_value, err_token)); + +NM_BACKPORT_SYMBOL (libnm_1_2_4, gint, nm_setting_ip_config_get_dns_priority, (NMSettingIPConfig *setting), (setting)); |