void
nm_dns_manager_set_hostname (NMDnsManager *mgr,
                             const char *hostname)
{
    NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (mgr);
    GError *error = NULL;
    const char *filtered = NULL;

    /* Certain hostnames we don't want to include in resolv.conf 'searches' */
    if (   hostname
            && strcmp (hostname, "localhost.localdomain")
            && strcmp (hostname, "localhost6.localdomain6")
            && !strstr (hostname, ".in-addr.arpa")
            && strchr (hostname, '.')) {
        filtered = hostname;
    }

    if (   (!priv->hostname && !filtered)
            || (priv->hostname && filtered && !strcmp (priv->hostname, filtered)))
        return;

    g_free (priv->hostname);
    priv->hostname = g_strdup (filtered);

    /* Passing the last interface here is completely bogus, but SUSE's netconfig
     * wants one.  But hostname changes are system-wide and *not* tied to a
     * specific interface, so netconfig can't really handle this.  Fake it.
     */
    if (!update_dns (mgr, priv->last_iface, FALSE, &error)) {
        nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s",
                     error ? error->code : -1,
                     error && error->message ? error->message : "(unknown)");
        g_clear_error (&error);
    }
}
gboolean
nm_dns_manager_add_ip6_config (NMDnsManager *mgr,
                               const char *iface,
                               NMIP6Config *config,
                               NMDnsIPConfigType cfg_type)
{
    NMDnsManagerPrivate *priv;
    GError *error = NULL;

    g_return_val_if_fail (mgr != NULL, FALSE);
    g_return_val_if_fail (iface != NULL, FALSE);
    g_return_val_if_fail (config != NULL, FALSE);

    priv = NM_DNS_MANAGER_GET_PRIVATE (mgr);

    switch (cfg_type) {
    case NM_DNS_IP_CONFIG_TYPE_VPN:
        /* FIXME: not quite yet... */
        g_return_val_if_fail (cfg_type != NM_DNS_IP_CONFIG_TYPE_VPN, FALSE);
        priv->ip6_vpn_config = config;
        break;
    case NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE:
        priv->ip6_device_config = config;
        break;
    default:
        break;
    }

    /* Don't allow the same zone added twice */
    if (!g_slist_find (priv->configs, config))
        priv->configs = g_slist_append (priv->configs, g_object_ref (config));

    if (!config_changed (mgr))
        return TRUE;

    if (!update_dns (mgr, iface, FALSE, &error)) {
        nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s",
                     error ? error->code : -1,
                     error && error->message ? error->message : "(unknown)");
        g_clear_error (&error);
    }

    return TRUE;
}
static void
plugin_failed (NMDnsPlugin *plugin, gpointer user_data)
{
    NMDnsManager *self = NM_DNS_MANAGER (user_data);
    NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
    GError *error = NULL;

    /* Errors with non-caching plugins aren't fatal */
    if (!nm_dns_plugin_is_caching (plugin))
        return;

    /* Disable caching until the next DNS update */
    if (!update_dns (self, priv->last_iface, TRUE, &error)) {
        nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s",
                     error ? error->code : -1,
                     error && error->message ? error->message : "(unknown)");
        g_clear_error (&error);
    }
}
static void service_property_set_cb(const char *path,
					const char *property, void *user_data)
{
	update_header();
	update_ipv4();
	update_ipv6();
	update_dns();
	update_timeservers();
	update_proxy();
	update_provider();
	update_ethernet();

	ipv4_changed = FALSE;
	ipv6_changed = FALSE;
	proxy_changed = FALSE;
	nameservers_changed = FALSE;
	domains_changed = FALSE;
	timeservers_changed = FALSE;

	connman_service_set_property_changed_callback(path,
					service_property_changed_cb, NULL);
}
gboolean
nm_dns_manager_remove_ip6_config (NMDnsManager *mgr,
                                  const char *iface,
                                  NMIP6Config *config)
{
    NMDnsManagerPrivate *priv;
    GError *error = NULL;

    g_return_val_if_fail (mgr != NULL, FALSE);
    g_return_val_if_fail (iface != NULL, FALSE);
    g_return_val_if_fail (config != NULL, FALSE);

    priv = NM_DNS_MANAGER_GET_PRIVATE (mgr);

    /* Can't remove it if it wasn't in the list to begin with */
    if (!g_slist_find (priv->configs, config))
        return FALSE;

    priv->configs = g_slist_remove (priv->configs, config);

    if (config == priv->ip6_vpn_config)
        priv->ip6_vpn_config = NULL;
    if (config == priv->ip6_device_config)
        priv->ip6_device_config = NULL;

    g_object_unref (config);

    if (!config_changed (mgr))
        return TRUE;

    if (!update_dns (mgr, iface, FALSE, &error)) {
        nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s",
                     error ? error->code : -1,
                     error && error->message ? error->message : "(unknown)");
        g_clear_error (&error);
    }

    return TRUE;
}
static void
dispose (GObject *object)
{
    NMDnsManager *self = NM_DNS_MANAGER (object);
    NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
    GError *error = NULL;

    if (priv->disposed == FALSE) {
        priv->disposed = TRUE;

        g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL);
        g_slist_free (priv->plugins);
        priv->plugins = NULL;

        /* If last_iface is NULL, this means we haven't done a DNS update before,
         * so no reason to try and take down entries from resolv.conf.
         */
        if (priv->last_iface != NULL) {
            /* If we're quitting leave a valid resolv.conf in place, not one
             * pointing to 127.0.0.1 if any plugins were active.  Thus update
             * DNS after disposing of all plugins.
             */
            if (!update_dns (self, priv->last_iface, TRUE, &error)) {
                nm_log_warn (LOGD_DNS, "could not commit DNS changes on shutdown: (%d) %s",
                             error ? error->code : -1,
                             error && error->message ? error->message : "(unknown)");
                g_clear_error (&error);
            }
        }

        g_slist_foreach (priv->configs, (GFunc) g_object_unref, NULL);
        g_slist_free (priv->configs);
        priv->configs = NULL;
    }

    G_OBJECT_CLASS (nm_dns_manager_parent_class)->dispose (object);
}