mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-07 08:40:59 +00:00
e1c7a2b5d0
We commonly don't use the glib typedefs for char/short/int/long, but their C types directly. $ git grep '\<g\(char\|short\|int\|long\|float\|double\)\>' | wc -l 587 $ git grep '\<\(char\|short\|int\|long\|float\|double\)\>' | wc -l 21114 One could argue that using the glib typedefs is preferable in public API (of our glib based libnm library) or where it clearly is related to glib, like during g_object_set (obj, PROPERTY, (gint) value, NULL); However, that argument does not seem strong, because in practice we don't follow that argument today, and seldomly use the glib typedefs. Also, the style guide for this would be hard to formalize, because "using them where clearly related to a glib" is a very loose suggestion. Also note that glib typedefs will always just be typedefs of the underlying C types. There is no danger of glib changing the meaning of these typedefs (because that would be a major API break of glib). A simple style guide is instead: don't use these typedefs. No manual actions, I only ran the bash script: FILES=($(git ls-files '*.[hc]')) sed -i \ -e 's/\<g\(char\|short\|int\|long\|float\|double\)\>\( [^ ]\)/\1\2/g' \ -e 's/\<g\(char\|short\|int\|long\|float\|double\)\> /\1 /g' \ -e 's/\<g\(char\|short\|int\|long\|float\|double\)\>/\1/g' \ "${FILES[@]}"
451 lines
12 KiB
C
451 lines
12 KiB
C
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301 USA.
|
|
*
|
|
* Copyright 2016 Red Hat, Inc.
|
|
*/
|
|
|
|
#include "nm-default.h"
|
|
|
|
#include "nm-dns-manager.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include "nm-dbus-interface.h"
|
|
#include "nm-connection.h"
|
|
|
|
#include "nm-client.h"
|
|
#include "nm-object-private.h"
|
|
#include "nm-dbus-helpers.h"
|
|
#include "nm-core-internal.h"
|
|
|
|
#include "introspection/org.freedesktop.NetworkManager.DnsManager.h"
|
|
|
|
G_DEFINE_TYPE (NMDnsManager, nm_dns_manager, NM_TYPE_OBJECT)
|
|
|
|
#define NM_DNS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DNS_MANAGER, NMDnsManagerPrivate))
|
|
|
|
typedef struct {
|
|
NMDBusDnsManager *proxy;
|
|
char *mode;
|
|
char *rc_manager;
|
|
GPtrArray *configuration;
|
|
} NMDnsManagerPrivate;
|
|
|
|
enum {
|
|
PROP_0,
|
|
PROP_MODE,
|
|
PROP_RC_MANAGER,
|
|
PROP_CONFIGURATION,
|
|
|
|
LAST_PROP
|
|
};
|
|
|
|
/*****************************************************************************
|
|
* NMDnsEntry
|
|
*****************************************************************************/
|
|
|
|
G_DEFINE_BOXED_TYPE (NMDnsEntry, nm_dns_entry, nm_dns_entry_dup, nm_dns_entry_unref)
|
|
|
|
struct NMDnsEntry {
|
|
guint refcount;
|
|
|
|
char *interface;
|
|
char **nameservers;
|
|
char **domains;
|
|
int priority;
|
|
gboolean vpn;
|
|
};
|
|
|
|
/**
|
|
* nm_dns_entry_new:
|
|
*
|
|
* Creates a new #NMDnsEntry object.
|
|
*
|
|
* Returns: (transfer full): the new #NMDnsEntry object, or %NULL on error
|
|
**/
|
|
NMDnsEntry *
|
|
nm_dns_entry_new (const char *interface,
|
|
const char * const *nameservers,
|
|
const char * const *domains,
|
|
int priority,
|
|
gboolean vpn)
|
|
{
|
|
NMDnsEntry *entry;
|
|
guint i, len;
|
|
|
|
entry = g_slice_new0 (NMDnsEntry);
|
|
entry->refcount = 1;
|
|
|
|
entry->interface = g_strdup (interface);
|
|
|
|
if (nameservers) {
|
|
len = g_strv_length ((char **) nameservers);
|
|
entry->nameservers = g_new (char *, len + 1);
|
|
for (i = 0; i < len + 1; i++)
|
|
entry->nameservers[i] = g_strdup (nameservers[i]);
|
|
}
|
|
|
|
if (domains) {
|
|
len = g_strv_length ((char **) domains);
|
|
entry->domains = g_new (char *, len + 1);
|
|
for (i = 0; i < len + 1; i++)
|
|
entry->domains[i] = g_strdup (domains[i]);
|
|
}
|
|
|
|
entry->priority = priority;
|
|
entry->vpn = vpn;
|
|
|
|
return entry;
|
|
}
|
|
|
|
/**
|
|
* nm_dns_entry_dup:
|
|
* @entry: the #NMDnsEntry
|
|
*
|
|
* Creates a copy of @entry
|
|
*
|
|
* Returns: (transfer full): a copy of @entry
|
|
**/
|
|
NMDnsEntry *
|
|
nm_dns_entry_dup (NMDnsEntry *entry)
|
|
{
|
|
NMDnsEntry *copy;
|
|
|
|
g_return_val_if_fail (entry != NULL, NULL);
|
|
g_return_val_if_fail (entry->refcount > 0, NULL);
|
|
|
|
copy = nm_dns_entry_new (entry->interface,
|
|
(const char * const *) entry->nameservers,
|
|
(const char * const *) entry->domains,
|
|
entry->priority,
|
|
entry->vpn);
|
|
|
|
return copy;
|
|
}
|
|
|
|
/**
|
|
* nm_dns_entry_unref:
|
|
* @entry: the #NMDnsEntry
|
|
*
|
|
* Decreases the reference count of the object. If the reference count
|
|
* reaches zero, the object will be destroyed.
|
|
*
|
|
* Since: 1.6
|
|
**/
|
|
void
|
|
nm_dns_entry_unref (NMDnsEntry *entry)
|
|
{
|
|
g_return_if_fail (entry != NULL);
|
|
g_return_if_fail (entry->refcount > 0);
|
|
|
|
entry->refcount--;
|
|
if (entry->refcount == 0) {
|
|
g_free (entry->interface);
|
|
g_strfreev (entry->nameservers);
|
|
g_strfreev (entry->domains);
|
|
g_slice_free (NMDnsEntry, entry);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* nm_dns_entry_get_interface:
|
|
* @entry: the #NMDnsEntry
|
|
*
|
|
* Gets the interface on which name servers are contacted.
|
|
*
|
|
* Returns: (transfer none): the interface name
|
|
*
|
|
* Since: 1.6
|
|
**/
|
|
const char *
|
|
nm_dns_entry_get_interface (NMDnsEntry *entry)
|
|
{
|
|
g_return_val_if_fail (entry, 0);
|
|
g_return_val_if_fail (entry->refcount > 0, 0);
|
|
|
|
return entry->interface;
|
|
}
|
|
|
|
/**
|
|
* nm_dns_entry_get_nameservers:
|
|
* @entry: the #NMDnsEntry
|
|
*
|
|
* Gets the list of name servers for this entry.
|
|
*
|
|
* Returns: (transfer none): the list of name servers
|
|
*
|
|
* Since: 1.6
|
|
**/
|
|
const char * const *
|
|
nm_dns_entry_get_nameservers (NMDnsEntry *entry)
|
|
{
|
|
g_return_val_if_fail (entry, 0);
|
|
g_return_val_if_fail (entry->refcount > 0, 0);
|
|
|
|
return (const char * const *) entry->nameservers;
|
|
}
|
|
|
|
/**
|
|
* nm_dns_entry_get_domains:
|
|
* @entry: the #NMDnsEntry
|
|
*
|
|
* Gets the list of DNS domains.
|
|
*
|
|
* Returns: (transfer none): the list of DNS domains
|
|
*
|
|
* Since: 1.6
|
|
**/
|
|
const char * const *
|
|
nm_dns_entry_get_domains (NMDnsEntry *entry)
|
|
{
|
|
g_return_val_if_fail (entry, 0);
|
|
g_return_val_if_fail (entry->refcount > 0, 0);
|
|
|
|
return (const char * const *)entry->domains;
|
|
}
|
|
|
|
/**
|
|
* nm_dns_entry_get_vpn:
|
|
* @entry: the #NMDnsEntry
|
|
*
|
|
* Gets whether the entry refers to VPN name servers.
|
|
*
|
|
* Returns: %TRUE if the entry refers to VPN name servers
|
|
*
|
|
* Since: 1.6
|
|
**/
|
|
gboolean
|
|
nm_dns_entry_get_vpn (NMDnsEntry *entry)
|
|
{
|
|
g_return_val_if_fail (entry, 0);
|
|
g_return_val_if_fail (entry->refcount > 0, 0);
|
|
|
|
return entry->vpn;
|
|
}
|
|
|
|
/**
|
|
* nm_dns_entry_get_priority:
|
|
* @entry: the #NMDnsEntry
|
|
*
|
|
* Gets the priority of the entry
|
|
*
|
|
* Returns: the priority of the entry
|
|
*
|
|
* Since: 1.6
|
|
**/
|
|
int
|
|
nm_dns_entry_get_priority (NMDnsEntry *entry)
|
|
{
|
|
g_return_val_if_fail (entry, 0);
|
|
g_return_val_if_fail (entry->refcount > 0, 0);
|
|
|
|
return entry->priority;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
static gboolean
|
|
demarshal_dns_configuration (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
|
|
{
|
|
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (object);
|
|
GVariant *entry_var;
|
|
GVariantIter iter, *iterp;
|
|
NMDnsEntry *entry;
|
|
GPtrArray *array;
|
|
|
|
g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aa{sv}")), FALSE);
|
|
|
|
g_variant_iter_init (&iter, value);
|
|
g_ptr_array_unref (priv->configuration);
|
|
priv->configuration = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_dns_entry_unref);
|
|
|
|
while (g_variant_iter_next (&iter, "@a{sv}", &entry_var)) {
|
|
char **nameservers = NULL, **domains = NULL;
|
|
gboolean vpn = FALSE;
|
|
char *interface = NULL, *str;
|
|
int priority;
|
|
|
|
if ( !g_variant_lookup (entry_var, "nameservers", "as", &iterp)
|
|
|| !g_variant_lookup (entry_var, "priority", "i", &priority)) {
|
|
g_warning ("Ignoring invalid DNS configuration");
|
|
g_variant_unref (entry_var);
|
|
continue;
|
|
}
|
|
|
|
array = g_ptr_array_new ();
|
|
while (g_variant_iter_next (iterp, "&s", &str))
|
|
g_ptr_array_add (array, str);
|
|
g_ptr_array_add (array, NULL);
|
|
nameservers = (char **) g_ptr_array_free (array, FALSE);
|
|
g_variant_iter_free (iterp);
|
|
|
|
if (g_variant_lookup (entry_var, "domains", "as", &iterp)) {
|
|
array = g_ptr_array_new ();
|
|
while (g_variant_iter_next (iterp, "&s", &str))
|
|
g_ptr_array_add (array, str);
|
|
g_ptr_array_add (array, NULL);
|
|
domains = (char **) g_ptr_array_free (array, FALSE);
|
|
g_variant_iter_free (iterp);
|
|
}
|
|
|
|
g_variant_lookup (entry_var, "interface", "&s", &interface);
|
|
g_variant_lookup (entry_var, "priority", "i", &priority);
|
|
g_variant_lookup (entry_var, "vpn", "b", &vpn);
|
|
|
|
entry = nm_dns_entry_new (interface,
|
|
(const char * const *) nameservers,
|
|
(const char * const *) domains,
|
|
priority,
|
|
vpn);
|
|
g_free (domains);
|
|
g_free (nameservers);
|
|
g_variant_unref (entry_var);
|
|
if (!entry) {
|
|
g_warning ("Ignoring invalid DNS entry");
|
|
continue;
|
|
}
|
|
|
|
g_ptr_array_add (priv->configuration, entry);
|
|
}
|
|
|
|
_nm_object_queue_notify (object, NM_DNS_MANAGER_CONFIGURATION);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
const char *
|
|
nm_dns_manager_get_mode (NMDnsManager *manager)
|
|
{
|
|
return NM_DNS_MANAGER_GET_PRIVATE (manager)->mode;
|
|
}
|
|
|
|
const char *
|
|
nm_dns_manager_get_rc_manager (NMDnsManager *manager)
|
|
{
|
|
return NM_DNS_MANAGER_GET_PRIVATE (manager)->rc_manager;
|
|
}
|
|
|
|
const GPtrArray *
|
|
nm_dns_manager_get_configuration (NMDnsManager *manager)
|
|
{
|
|
return NM_DNS_MANAGER_GET_PRIVATE (manager)->configuration;
|
|
}
|
|
/*****************************************************************************/
|
|
|
|
static void
|
|
nm_dns_manager_init (NMDnsManager *self)
|
|
{
|
|
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
|
|
|
|
priv->configuration = g_ptr_array_new ();
|
|
}
|
|
|
|
static void
|
|
init_dbus (NMObject *object)
|
|
{
|
|
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (object);
|
|
const NMPropertiesInfo property_info[] = {
|
|
{ NM_DNS_MANAGER_MODE, &priv->mode },
|
|
{ NM_DNS_MANAGER_RC_MANAGER, &priv->rc_manager },
|
|
{ NM_DNS_MANAGER_CONFIGURATION, &priv->configuration, demarshal_dns_configuration },
|
|
{ NULL },
|
|
};
|
|
|
|
NM_OBJECT_CLASS (nm_dns_manager_parent_class)->init_dbus (object);
|
|
|
|
priv->proxy = NMDBUS_DNS_MANAGER (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_DNS_MANAGER));
|
|
_nm_object_register_properties (object,
|
|
NM_DBUS_INTERFACE_DNS_MANAGER,
|
|
property_info);
|
|
}
|
|
|
|
static void
|
|
dispose (GObject *object)
|
|
{
|
|
NMDnsManager *self = NM_DNS_MANAGER (object);
|
|
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
|
|
|
|
g_clear_pointer (&priv->mode, g_free);
|
|
g_clear_pointer (&priv->rc_manager, g_free);
|
|
g_clear_pointer (&priv->configuration, g_ptr_array_unref);
|
|
|
|
G_OBJECT_CLASS (nm_dns_manager_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
get_property (GObject *object, guint prop_id,
|
|
GValue *value, GParamSpec *pspec)
|
|
{
|
|
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (object);
|
|
|
|
switch (prop_id) {
|
|
case PROP_MODE:
|
|
g_value_set_string (value, priv->mode);
|
|
break;
|
|
case PROP_RC_MANAGER:
|
|
g_value_set_string (value, priv->rc_manager);
|
|
break;
|
|
case PROP_CONFIGURATION:
|
|
g_value_take_boxed (value, _nm_utils_copy_array (priv->configuration,
|
|
(NMUtilsCopyFunc) nm_dns_entry_dup,
|
|
(GDestroyNotify) nm_dns_entry_unref));
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
nm_dns_manager_class_init (NMDnsManagerClass *class)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
|
NMObjectClass *nm_object_class = NM_OBJECT_CLASS (class);
|
|
|
|
g_type_class_add_private (class, sizeof (NMDnsManagerPrivate));
|
|
|
|
/* Virtual methods */
|
|
object_class->get_property = get_property;
|
|
object_class->dispose = dispose;
|
|
|
|
nm_object_class->init_dbus = init_dbus;
|
|
|
|
/* Properties */
|
|
|
|
g_object_class_install_property
|
|
(object_class, PROP_MODE,
|
|
g_param_spec_string (NM_DNS_MANAGER_MODE, "", "",
|
|
NULL,
|
|
G_PARAM_READABLE |
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
g_object_class_install_property
|
|
(object_class, PROP_RC_MANAGER,
|
|
g_param_spec_string (NM_DNS_MANAGER_RC_MANAGER, "", "",
|
|
NULL,
|
|
G_PARAM_READABLE |
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
g_object_class_install_property
|
|
(object_class, PROP_CONFIGURATION,
|
|
g_param_spec_boxed (NM_DNS_MANAGER_CONFIGURATION, "", "",
|
|
G_TYPE_PTR_ARRAY,
|
|
G_PARAM_READABLE |
|
|
G_PARAM_STATIC_STRINGS));
|
|
}
|