config,connectivity: merge branch 'th/rh1066697_reload_config'
Refactor NMConfig to support reloading. Implement reloading of NMConnectivity parameters https://bugzilla.redhat.com/show_bug.cgi?id=1066697
This commit is contained in:
@@ -287,6 +287,8 @@ nm_sources = \
|
||||
nm-active-connection.h \
|
||||
nm-config.c \
|
||||
nm-config.h \
|
||||
nm-config-data.c \
|
||||
nm-config-data.h \
|
||||
nm-connection-provider.c \
|
||||
nm-connection-provider.h \
|
||||
nm-connectivity.c \
|
||||
|
@@ -1463,7 +1463,7 @@ new_default_connection (NMDevice *self)
|
||||
const char *hw_address;
|
||||
char *defname, *uuid;
|
||||
|
||||
if (!nm_config_get_ethernet_can_auto_default (nm_config_get (), self))
|
||||
if (nm_config_get_no_auto_default_for_device (nm_config_get (), self))
|
||||
return NULL;
|
||||
|
||||
hw_address = nm_device_get_hw_address (self);
|
||||
|
@@ -40,9 +40,7 @@
|
||||
static gboolean
|
||||
sighup_handler (gpointer user_data)
|
||||
{
|
||||
/* Reread config stuff like system config files, VPN service files, etc */
|
||||
nm_log_info (LOGD_CORE, "caught SIGHUP, not supported yet.");
|
||||
|
||||
nm_main_config_reload ();
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
@@ -177,7 +175,8 @@ nm_main_utils_early_setup (const char *progname,
|
||||
char **argv[],
|
||||
int *argc,
|
||||
GOptionEntry *options,
|
||||
GOptionEntry *more_options,
|
||||
void (*option_context_hook) (gpointer user_data, GOptionContext *opt_ctx),
|
||||
gpointer option_context_hook_data,
|
||||
const char *summary)
|
||||
{
|
||||
GOptionContext *opt_ctx = NULL;
|
||||
@@ -220,9 +219,9 @@ nm_main_utils_early_setup (const char *progname,
|
||||
g_option_context_set_ignore_unknown_options (opt_ctx, FALSE);
|
||||
g_option_context_set_help_enabled (opt_ctx, TRUE);
|
||||
g_option_context_add_main_entries (opt_ctx, options, NULL);
|
||||
if (more_options)
|
||||
g_option_context_add_main_entries (opt_ctx, more_options, NULL);
|
||||
g_option_context_set_summary (opt_ctx, summary);
|
||||
if (option_context_hook)
|
||||
option_context_hook (option_context_hook_data, opt_ctx);
|
||||
|
||||
success = g_option_context_parse (opt_ctx, argc, argv, &error);
|
||||
if (!success) {
|
||||
|
@@ -33,7 +33,13 @@ gboolean nm_main_utils_early_setup (const char *progname,
|
||||
char **argv[],
|
||||
int *argc,
|
||||
GOptionEntry *options,
|
||||
GOptionEntry *more_options,
|
||||
void (*option_context_hook) (gpointer user_data, GOptionContext *opt_ctx),
|
||||
gpointer option_context_hook_data,
|
||||
const char *summary);
|
||||
|
||||
/* The following functions are not implemented inside nm-main-utils.c, instead
|
||||
* main.c and nm-iface-helper.c */
|
||||
|
||||
void nm_main_config_reload (void);
|
||||
|
||||
#endif /* __MAIN_UTILS_H__ */
|
||||
|
24
src/main.c
24
src/main.c
@@ -175,6 +175,19 @@ _init_nm_debug (const char *debug)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nm_main_config_reload ()
|
||||
{
|
||||
nm_log_info (LOGD_CORE, "reload configuration...");
|
||||
/* The signal handler thread is only installed after
|
||||
* creating NMConfig instance, and on shut down we
|
||||
* no longer run the mainloop (to reach this point).
|
||||
*
|
||||
* Hence, a NMConfig singleton instance must always be
|
||||
* available. */
|
||||
nm_config_reload (nm_config_get ());
|
||||
}
|
||||
|
||||
static void
|
||||
manager_configure_quit (NMManager *manager, gpointer user_data)
|
||||
{
|
||||
@@ -204,6 +217,7 @@ main (int argc, char *argv[])
|
||||
GError *error = NULL;
|
||||
gboolean wrote_pidfile = FALSE;
|
||||
char *bad_domains = NULL;
|
||||
NMConfigCmdLineOptions *config_cli;
|
||||
|
||||
GOptionEntry options[] = {
|
||||
{ "version", 'V', 0, G_OPTION_ARG_NONE, &show_version, N_("Print NetworkManager version and exit"), NULL },
|
||||
@@ -224,11 +238,13 @@ main (int argc, char *argv[])
|
||||
|
||||
main_loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
config_cli = nm_config_cmd_line_options_new ();
|
||||
if (!nm_main_utils_early_setup ("NetworkManager",
|
||||
&argv,
|
||||
&argc,
|
||||
options,
|
||||
nm_config_get_options (),
|
||||
(void (*)(gpointer, GOptionContext *)) nm_config_cmd_line_options_add_to_entries,
|
||||
config_cli,
|
||||
_("NetworkManager monitors all network connections and automatically\nchooses the best connection to use. It also allows the user to\nspecify wireless access points which wireless cards in the computer\nshould associate with.")))
|
||||
exit (1);
|
||||
|
||||
@@ -290,7 +306,9 @@ main (int argc, char *argv[])
|
||||
exit (1);
|
||||
|
||||
/* Read the config file and CLI overrides */
|
||||
config = nm_config_new (&error);
|
||||
config = nm_config_setup (config_cli, &error);
|
||||
nm_config_cmd_line_options_free (config_cli);
|
||||
config_cli = NULL;
|
||||
if (config == NULL) {
|
||||
fprintf (stderr, _("Failed to read configuration: (%d) %s\n"),
|
||||
error ? error->code : -1,
|
||||
@@ -369,7 +387,7 @@ main (int argc, char *argv[])
|
||||
nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting...");
|
||||
success = FALSE;
|
||||
|
||||
nm_log_info (LOGD_CORE, "Read config: %s", nm_config_get_description (config));
|
||||
nm_log_info (LOGD_CORE, "Read config: %s", nm_config_data_get_config_description (nm_config_get_data (config)));
|
||||
nm_log_info (LOGD_CORE, "WEXT support is %s",
|
||||
#if HAVE_WEXT
|
||||
"enabled"
|
||||
|
408
src/nm-config-data.c
Normal file
408
src/nm-config-data.c
Normal file
@@ -0,0 +1,408 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
* Copyright (C) 2013 Thomas Bechtold <thomasbechtold@jpberlin.de>
|
||||
*/
|
||||
|
||||
#include "nm-config-data.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "nm-config.h"
|
||||
#include "gsystem-local-alloc.h"
|
||||
|
||||
typedef struct {
|
||||
char *config_main_file;
|
||||
char *config_description;
|
||||
|
||||
GKeyFile *keyfile;
|
||||
|
||||
struct {
|
||||
char *uri;
|
||||
char *response;
|
||||
guint interval;
|
||||
} connectivity;
|
||||
|
||||
struct {
|
||||
char **arr;
|
||||
GSList *specs;
|
||||
} no_auto_default;
|
||||
} NMConfigDataPrivate;
|
||||
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_CONFIG_MAIN_FILE,
|
||||
PROP_CONFIG_DESCRIPTION,
|
||||
PROP_KEYFILE,
|
||||
PROP_CONNECTIVITY_URI,
|
||||
PROP_CONNECTIVITY_INTERVAL,
|
||||
PROP_CONNECTIVITY_RESPONSE,
|
||||
PROP_NO_AUTO_DEFAULT,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NMConfigData, nm_config_data, G_TYPE_OBJECT)
|
||||
|
||||
#define NM_CONFIG_DATA_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CONFIG_DATA, NMConfigDataPrivate))
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
const char *
|
||||
nm_config_data_get_config_main_file (const NMConfigData *self)
|
||||
{
|
||||
g_return_val_if_fail (self, NULL);
|
||||
|
||||
return NM_CONFIG_DATA_GET_PRIVATE (self)->config_main_file;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_config_data_get_config_description (const NMConfigData *self)
|
||||
{
|
||||
g_return_val_if_fail (self, NULL);
|
||||
|
||||
return NM_CONFIG_DATA_GET_PRIVATE (self)->config_description;
|
||||
}
|
||||
|
||||
char *
|
||||
nm_config_data_get_value (const NMConfigData *self, const char *group, const char *key, GError **error)
|
||||
{
|
||||
g_return_val_if_fail (self, NULL);
|
||||
|
||||
return g_key_file_get_string (NM_CONFIG_DATA_GET_PRIVATE (self)->keyfile, group, key, error);
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_config_data_get_connectivity_uri (const NMConfigData *self)
|
||||
{
|
||||
g_return_val_if_fail (self, NULL);
|
||||
|
||||
return NM_CONFIG_DATA_GET_PRIVATE (self)->connectivity.uri;
|
||||
}
|
||||
|
||||
const guint
|
||||
nm_config_data_get_connectivity_interval (const NMConfigData *self)
|
||||
{
|
||||
g_return_val_if_fail (self, 0);
|
||||
|
||||
return MAX (NM_CONFIG_DATA_GET_PRIVATE (self)->connectivity.interval, 0);
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_config_data_get_connectivity_response (const NMConfigData *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
|
||||
return NM_CONFIG_DATA_GET_PRIVATE (self)->connectivity.response;
|
||||
}
|
||||
|
||||
const char *const*
|
||||
nm_config_data_get_no_auto_default (const NMConfigData *self)
|
||||
{
|
||||
g_return_val_if_fail (self, FALSE);
|
||||
|
||||
return (const char *const*) NM_CONFIG_DATA_GET_PRIVATE (self)->no_auto_default.arr;
|
||||
}
|
||||
|
||||
const GSList *
|
||||
nm_config_data_get_no_auto_default_list (const NMConfigData *self)
|
||||
{
|
||||
g_return_val_if_fail (self, NULL);
|
||||
|
||||
return NM_CONFIG_DATA_GET_PRIVATE (self)->no_auto_default.specs;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
static gboolean
|
||||
_keyfile_a_contains_all_in_b (GKeyFile *kf_a, GKeyFile *kf_b)
|
||||
{
|
||||
gs_strfreev char **groups = NULL;
|
||||
guint i, j;
|
||||
|
||||
if (kf_a == kf_b)
|
||||
return TRUE;
|
||||
|
||||
groups = g_key_file_get_groups (kf_a, NULL);
|
||||
for (i = 0; groups && groups[i]; i++) {
|
||||
gs_strfreev char **keys = NULL;
|
||||
|
||||
keys = g_key_file_get_keys (kf_a, groups[i], NULL, NULL);
|
||||
if (keys) {
|
||||
for (j = 0; keys[j]; j++) {
|
||||
gs_free char *key_a = g_key_file_get_value (kf_a, groups[i], keys[j], NULL);
|
||||
gs_free char *key_b = g_key_file_get_value (kf_b, groups[i], keys[j], NULL);
|
||||
|
||||
if (g_strcmp0 (key_a, key_b) != 0)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NMConfigChangeFlags
|
||||
nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data)
|
||||
{
|
||||
NMConfigChangeFlags changes = NM_CONFIG_CHANGE_NONE;
|
||||
NMConfigDataPrivate *priv_old, *priv_new;
|
||||
GSList *spec_old, *spec_new;
|
||||
|
||||
g_return_val_if_fail (NM_IS_CONFIG_DATA (old_data), NM_CONFIG_CHANGE_NONE);
|
||||
g_return_val_if_fail (NM_IS_CONFIG_DATA (new_data), NM_CONFIG_CHANGE_NONE);
|
||||
|
||||
priv_old = NM_CONFIG_DATA_GET_PRIVATE (old_data);
|
||||
priv_new = NM_CONFIG_DATA_GET_PRIVATE (new_data);
|
||||
|
||||
if ( !_keyfile_a_contains_all_in_b (priv_old->keyfile, priv_new->keyfile)
|
||||
|| !_keyfile_a_contains_all_in_b (priv_new->keyfile, priv_old->keyfile))
|
||||
changes |= NM_CONFIG_CHANGE_VALUES;
|
||||
|
||||
if ( g_strcmp0 (nm_config_data_get_config_main_file (old_data), nm_config_data_get_config_main_file (new_data)) != 0
|
||||
|| g_strcmp0 (nm_config_data_get_config_description (old_data), nm_config_data_get_config_description (new_data)) != 0)
|
||||
changes |= NM_CONFIG_CHANGE_CONFIG_FILES;
|
||||
|
||||
if ( nm_config_data_get_connectivity_interval (old_data) != nm_config_data_get_connectivity_interval (new_data)
|
||||
|| g_strcmp0 (nm_config_data_get_connectivity_uri (old_data), nm_config_data_get_connectivity_uri (new_data))
|
||||
|| g_strcmp0 (nm_config_data_get_connectivity_response (old_data), nm_config_data_get_connectivity_response (new_data)))
|
||||
changes |= NM_CONFIG_CHANGE_CONNECTIVITY;
|
||||
|
||||
spec_old = priv_old->no_auto_default.specs;
|
||||
spec_new = priv_new->no_auto_default.specs;
|
||||
while (spec_old && spec_new && strcmp (spec_old->data, spec_new->data) == 0) {
|
||||
spec_old = spec_old->next;
|
||||
spec_new = spec_new->next;
|
||||
}
|
||||
if (spec_old || spec_new)
|
||||
changes |= NM_CONFIG_CHANGE_NO_AUTO_DEFAULT;
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
NMConfigData *self = NM_CONFIG_DATA (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CONFIG_MAIN_FILE:
|
||||
g_value_set_string (value, nm_config_data_get_config_main_file (self));
|
||||
break;
|
||||
case PROP_CONFIG_DESCRIPTION:
|
||||
g_value_set_string (value, nm_config_data_get_config_description (self));
|
||||
break;
|
||||
case PROP_NO_AUTO_DEFAULT:
|
||||
g_value_take_boxed (value, g_strdupv ((char **) nm_config_data_get_no_auto_default (self)));
|
||||
break;
|
||||
case PROP_CONNECTIVITY_URI:
|
||||
g_value_set_string (value, nm_config_data_get_connectivity_uri (self));
|
||||
break;
|
||||
case PROP_CONNECTIVITY_INTERVAL:
|
||||
g_value_set_uint (value, nm_config_data_get_connectivity_interval (self));
|
||||
break;
|
||||
case PROP_CONNECTIVITY_RESPONSE:
|
||||
g_value_set_string (value, nm_config_data_get_connectivity_response (self));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
NMConfigData *self = NM_CONFIG_DATA (object);
|
||||
NMConfigDataPrivate *priv = NM_CONFIG_DATA_GET_PRIVATE (self);
|
||||
guint i;
|
||||
|
||||
/* This type is immutable. All properties are construct only. */
|
||||
switch (prop_id) {
|
||||
case PROP_CONFIG_MAIN_FILE:
|
||||
priv->config_main_file = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_CONFIG_DESCRIPTION:
|
||||
priv->config_description = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_KEYFILE:
|
||||
priv->keyfile = g_value_dup_boxed (value);
|
||||
if (!priv->keyfile)
|
||||
priv->keyfile = nm_config_create_keyfile ();
|
||||
break;
|
||||
case PROP_NO_AUTO_DEFAULT:
|
||||
priv->no_auto_default.arr = g_strdupv (g_value_get_boxed (value));
|
||||
if (!priv->no_auto_default.arr)
|
||||
priv->no_auto_default.arr = g_new0 (char *, 1);
|
||||
for (i = 0; priv->no_auto_default.arr[i]; i++)
|
||||
priv->no_auto_default.specs = g_slist_prepend (priv->no_auto_default.specs, priv->no_auto_default.arr[i]);
|
||||
priv->no_auto_default.specs = g_slist_reverse (priv->no_auto_default.specs);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *gobject)
|
||||
{
|
||||
NMConfigDataPrivate *priv = NM_CONFIG_DATA_GET_PRIVATE (gobject);
|
||||
|
||||
g_free (priv->config_main_file);
|
||||
g_free (priv->config_description);
|
||||
|
||||
g_free (priv->connectivity.uri);
|
||||
g_free (priv->connectivity.response);
|
||||
|
||||
g_slist_free (priv->no_auto_default.specs);
|
||||
g_strfreev (priv->no_auto_default.arr);
|
||||
|
||||
G_OBJECT_CLASS (nm_config_data_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_config_data_init (NMConfigData *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
constructed (GObject *object)
|
||||
{
|
||||
NMConfigData *self = NM_CONFIG_DATA (object);
|
||||
NMConfigDataPrivate *priv = NM_CONFIG_DATA_GET_PRIVATE (self);
|
||||
int interval;
|
||||
|
||||
priv->connectivity.uri = g_key_file_get_value (priv->keyfile, "connectivity", "uri", NULL);
|
||||
priv->connectivity.response = g_key_file_get_value (priv->keyfile, "connectivity", "response", NULL);
|
||||
|
||||
interval = g_key_file_get_integer (priv->keyfile, "connectivity", "interval", NULL);
|
||||
priv->connectivity.interval = MAX (0, interval);
|
||||
|
||||
G_OBJECT_CLASS (nm_config_data_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
NMConfigData *
|
||||
nm_config_data_new (const char *config_main_file,
|
||||
const char *config_description,
|
||||
const char *const*no_auto_default,
|
||||
GKeyFile *keyfile)
|
||||
{
|
||||
return g_object_new (NM_TYPE_CONFIG_DATA,
|
||||
NM_CONFIG_DATA_CONFIG_MAIN_FILE, config_main_file,
|
||||
NM_CONFIG_DATA_CONFIG_DESCRIPTION, config_description,
|
||||
NM_CONFIG_DATA_KEYFILE, keyfile,
|
||||
NM_CONFIG_DATA_NO_AUTO_DEFAULT, no_auto_default,
|
||||
NULL);
|
||||
}
|
||||
|
||||
NMConfigData *
|
||||
nm_config_data_new_update_no_auto_default (const NMConfigData *base,
|
||||
const char *const*no_auto_default)
|
||||
{
|
||||
NMConfigDataPrivate *priv = NM_CONFIG_DATA_GET_PRIVATE (base);
|
||||
|
||||
return g_object_new (NM_TYPE_CONFIG_DATA,
|
||||
NM_CONFIG_DATA_CONFIG_MAIN_FILE, priv->config_main_file,
|
||||
NM_CONFIG_DATA_CONFIG_DESCRIPTION, priv->config_description,
|
||||
NM_CONFIG_DATA_KEYFILE, priv->keyfile, /* the keyfile is unchanged. It's safe to share it. */
|
||||
NM_CONFIG_DATA_NO_AUTO_DEFAULT, no_auto_default,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_config_data_class_init (NMConfigDataClass *config_class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (config_class);
|
||||
|
||||
g_type_class_add_private (config_class, sizeof (NMConfigDataPrivate));
|
||||
|
||||
object_class->constructed = constructed;
|
||||
object_class->dispose = dispose;
|
||||
object_class->finalize = finalize;
|
||||
object_class->get_property = get_property;
|
||||
object_class->set_property = set_property;
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_CONFIG_MAIN_FILE,
|
||||
g_param_spec_string (NM_CONFIG_DATA_CONFIG_MAIN_FILE, "", "",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_CONFIG_DESCRIPTION,
|
||||
g_param_spec_string (NM_CONFIG_DATA_CONFIG_DESCRIPTION, "", "",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_KEYFILE,
|
||||
g_param_spec_boxed (NM_CONFIG_DATA_KEYFILE, "", "",
|
||||
G_TYPE_KEY_FILE,
|
||||
G_PARAM_WRITABLE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_CONNECTIVITY_URI,
|
||||
g_param_spec_string (NM_CONFIG_DATA_CONNECTIVITY_URI, "", "",
|
||||
NULL,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_CONNECTIVITY_INTERVAL,
|
||||
g_param_spec_uint (NM_CONFIG_DATA_CONNECTIVITY_INTERVAL, "", "",
|
||||
0, G_MAXUINT, 0,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_CONNECTIVITY_RESPONSE,
|
||||
g_param_spec_string (NM_CONFIG_DATA_CONNECTIVITY_RESPONSE, "", "",
|
||||
NULL,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_NO_AUTO_DEFAULT,
|
||||
g_param_spec_boxed (NM_CONFIG_DATA_NO_AUTO_DEFAULT, "", "",
|
||||
G_TYPE_STRV,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
}
|
||||
|
91
src/nm-config-data.h
Normal file
91
src/nm-config-data.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2014 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_CONFIG_DATA_H
|
||||
#define NM_CONFIG_DATA_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "nm-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NM_TYPE_CONFIG_DATA (nm_config_data_get_type ())
|
||||
#define NM_CONFIG_DATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONFIG_DATA, NMConfigData))
|
||||
#define NM_CONFIG_DATA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CONFIG_DATA, NMConfigDataClass))
|
||||
#define NM_IS_CONFIG_DATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CONFIG_DATA))
|
||||
#define NM_IS_CONFIG_DATA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_CONFIG_DATA))
|
||||
#define NM_CONFIG_DATA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CONFIG_DATA, NMConfigDataClass))
|
||||
|
||||
|
||||
#define NM_CONFIG_DATA_CONFIG_MAIN_FILE "config-main-file"
|
||||
#define NM_CONFIG_DATA_CONFIG_DESCRIPTION "config-description"
|
||||
#define NM_CONFIG_DATA_KEYFILE "keyfile"
|
||||
#define NM_CONFIG_DATA_CONNECTIVITY_URI "connectivity-uri"
|
||||
#define NM_CONFIG_DATA_CONNECTIVITY_INTERVAL "connectivity-interval"
|
||||
#define NM_CONFIG_DATA_CONNECTIVITY_RESPONSE "connectivity-response"
|
||||
#define NM_CONFIG_DATA_NO_AUTO_DEFAULT "no-auto-default"
|
||||
|
||||
typedef enum { /*< flags >*/
|
||||
NM_CONFIG_CHANGE_NONE = 0,
|
||||
NM_CONFIG_CHANGE_CONFIG_FILES = (1L << 0),
|
||||
NM_CONFIG_CHANGE_VALUES = (1L << 1),
|
||||
NM_CONFIG_CHANGE_CONNECTIVITY = (1L << 2),
|
||||
NM_CONFIG_CHANGE_NO_AUTO_DEFAULT = (1L << 3),
|
||||
|
||||
_NM_CONFIG_CHANGE_LAST,
|
||||
NM_CONFIG_CHANGE_ALL = ((_NM_CONFIG_CHANGE_LAST - 1) << 1) - 1,
|
||||
} NMConfigChangeFlags;
|
||||
|
||||
struct _NMConfigData {
|
||||
GObject parent;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent;
|
||||
} NMConfigDataClass;
|
||||
|
||||
GType nm_config_data_get_type (void);
|
||||
|
||||
NMConfigData *nm_config_data_new (const char *config_main_file,
|
||||
const char *config_description,
|
||||
const char *const*no_auto_default,
|
||||
GKeyFile *keyfile);
|
||||
NMConfigData *nm_config_data_new_update_no_auto_default (const NMConfigData *base, const char *const*no_auto_default);
|
||||
|
||||
NMConfigChangeFlags nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data);
|
||||
|
||||
const char *nm_config_data_get_config_main_file (const NMConfigData *config_data);
|
||||
const char *nm_config_data_get_config_description (const NMConfigData *config_data);
|
||||
|
||||
char *nm_config_data_get_value (const NMConfigData *config_data, const char *group, const char *key, GError **error);
|
||||
|
||||
const char *nm_config_data_get_connectivity_uri (const NMConfigData *config_data);
|
||||
const guint nm_config_data_get_connectivity_interval (const NMConfigData *config_data);
|
||||
const char *nm_config_data_get_connectivity_response (const NMConfigData *config_data);
|
||||
|
||||
const char *const*nm_config_data_get_no_auto_default (const NMConfigData *config_data);
|
||||
const GSList * nm_config_data_get_no_auto_default_list (const NMConfigData *config_data);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* NM_CONFIG_DATA_H */
|
||||
|
717
src/nm-config.c
717
src/nm-config.c
@@ -29,6 +29,9 @@
|
||||
#include "nm-utils.h"
|
||||
#include "nm-glib-compat.h"
|
||||
#include "nm-device.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "gsystem-local-alloc.h"
|
||||
#include "nm-enum-types.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <glib/gi18n.h>
|
||||
@@ -38,12 +41,28 @@
|
||||
#define NM_OLD_SYSTEM_CONF_FILE NMCONFDIR "/nm-system-settings.conf"
|
||||
#define NM_NO_AUTO_DEFAULT_STATE_FILE NMSTATEDIR "/no-auto-default.state"
|
||||
|
||||
typedef struct {
|
||||
char *nm_conf_path;
|
||||
struct NMConfigCmdLineOptions {
|
||||
char *config_main_file;
|
||||
char *config_dir;
|
||||
char *no_auto_default_file;
|
||||
char *plugins;
|
||||
char *connectivity_uri;
|
||||
|
||||
/* We store interval as signed internally to track whether it's
|
||||
* set or not via GOptionEntry
|
||||
*/
|
||||
int connectivity_interval;
|
||||
char *connectivity_response;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
NMConfigCmdLineOptions cli;
|
||||
|
||||
NMConfigData *config_data;
|
||||
NMConfigData *config_data_orig;
|
||||
|
||||
char *config_dir;
|
||||
char *config_description;
|
||||
char *no_auto_default_file;
|
||||
GKeyFile *keyfile;
|
||||
|
||||
char **plugins;
|
||||
gboolean monitor_connection_files;
|
||||
@@ -56,24 +75,40 @@ typedef struct {
|
||||
|
||||
char *debug;
|
||||
|
||||
char *connectivity_uri;
|
||||
gint connectivity_interval;
|
||||
char *connectivity_response;
|
||||
|
||||
char **no_auto_default;
|
||||
char **ignore_carrier;
|
||||
|
||||
gboolean configure_and_quit;
|
||||
} NMConfigPrivate;
|
||||
|
||||
static NMConfig *singleton = NULL;
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_CMD_LINE_OPTIONS,
|
||||
LAST_PROP,
|
||||
};
|
||||
|
||||
enum {
|
||||
SIGNAL_CONFIG_CHANGED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void nm_config_initable_iface_init (GInitableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (NMConfig, nm_config, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_config_initable_iface_init);
|
||||
)
|
||||
|
||||
G_DEFINE_TYPE (NMConfig, nm_config, G_TYPE_OBJECT)
|
||||
|
||||
#define NM_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CONFIG, NMConfigPrivate))
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
static void _set_config_data (NMConfig *self, NMConfigData *new_data);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
static gboolean
|
||||
_get_bool_value (GKeyFile *keyfile,
|
||||
const char *section,
|
||||
@@ -109,20 +144,23 @@ _get_bool_value (GKeyFile *keyfile,
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
const char *
|
||||
nm_config_get_path (NMConfig *config)
|
||||
NMConfigData *
|
||||
nm_config_get_data (NMConfig *config)
|
||||
{
|
||||
g_return_val_if_fail (config != NULL, NULL);
|
||||
|
||||
return NM_CONFIG_GET_PRIVATE (config)->nm_conf_path;
|
||||
return NM_CONFIG_GET_PRIVATE (config)->config_data;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_config_get_description (NMConfig *config)
|
||||
/* The NMConfigData instance is reloadable and will be swapped on reload.
|
||||
* nm_config_get_data_orig() returns the original configuration, when the NMConfig
|
||||
* instance was created. */
|
||||
NMConfigData *
|
||||
nm_config_get_data_orig (NMConfig *config)
|
||||
{
|
||||
g_return_val_if_fail (config != NULL, NULL);
|
||||
|
||||
return NM_CONFIG_GET_PRIVATE (config)->config_description;
|
||||
return NM_CONFIG_GET_PRIVATE (config)->config_data_orig;
|
||||
}
|
||||
|
||||
const char **
|
||||
@@ -189,47 +227,12 @@ nm_config_get_debug (NMConfig *config)
|
||||
return NM_CONFIG_GET_PRIVATE (config)->debug;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_config_get_connectivity_uri (NMConfig *config)
|
||||
{
|
||||
g_return_val_if_fail (config != NULL, NULL);
|
||||
|
||||
return NM_CONFIG_GET_PRIVATE (config)->connectivity_uri;
|
||||
}
|
||||
|
||||
guint
|
||||
nm_config_get_connectivity_interval (NMConfig *config)
|
||||
{
|
||||
g_return_val_if_fail (config != NULL, 0);
|
||||
|
||||
/* We store interval as signed internally to track whether it's
|
||||
* set or not, but report as unsigned to callers.
|
||||
*/
|
||||
return MAX (NM_CONFIG_GET_PRIVATE (config)->connectivity_interval, 0);
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_config_get_connectivity_response (NMConfig *config)
|
||||
{
|
||||
g_return_val_if_fail (config != NULL, NULL);
|
||||
|
||||
return NM_CONFIG_GET_PRIVATE (config)->connectivity_response;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_config_get_configure_and_quit (NMConfig *config)
|
||||
{
|
||||
return NM_CONFIG_GET_PRIVATE (config)->configure_and_quit;
|
||||
}
|
||||
|
||||
char *
|
||||
nm_config_get_value (NMConfig *config, const char *group, const char *key, GError **error)
|
||||
{
|
||||
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config);
|
||||
|
||||
return g_key_file_get_string (priv->keyfile, group, key, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_config_get_ignore_carrier (NMConfig *config, NMDevice *device)
|
||||
{
|
||||
@@ -252,72 +255,71 @@ nm_config_get_ignore_carrier (NMConfig *config, NMDevice *device)
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
merge_no_auto_default_state (NMConfig *config)
|
||||
static char **
|
||||
no_auto_default_merge_from_file (const char *no_auto_default_file, const char *const* no_auto_default)
|
||||
{
|
||||
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config);
|
||||
GPtrArray *updated;
|
||||
char **list;
|
||||
int i, j;
|
||||
char *data;
|
||||
|
||||
/* If the config already matches everything, we don't need to do anything else. */
|
||||
if (priv->no_auto_default && !g_strcmp0 (priv->no_auto_default[0], "*"))
|
||||
return;
|
||||
|
||||
updated = g_ptr_array_new ();
|
||||
if (priv->no_auto_default) {
|
||||
for (i = 0; priv->no_auto_default[i]; i++)
|
||||
g_ptr_array_add (updated, priv->no_auto_default[i]);
|
||||
g_free (priv->no_auto_default);
|
||||
if (no_auto_default) {
|
||||
for (i = 0; no_auto_default[i]; i++)
|
||||
g_ptr_array_add (updated, g_strdup (no_auto_default[i]));
|
||||
}
|
||||
|
||||
if (g_file_get_contents (priv->no_auto_default_file, &data, NULL, NULL)) {
|
||||
if ( no_auto_default_file
|
||||
&& g_file_get_contents (no_auto_default_file, &data, NULL, NULL)) {
|
||||
list = g_strsplit (data, "\n", -1);
|
||||
for (i = 0; list[i]; i++) {
|
||||
if (!*list[i])
|
||||
continue;
|
||||
for (j = 0; j < updated->len; j++) {
|
||||
if (!strcmp (list[i], updated->pdata[j]))
|
||||
break;
|
||||
g_free (list[i]);
|
||||
else {
|
||||
for (j = 0; j < updated->len; j++) {
|
||||
if (!strcmp (list[i], updated->pdata[j]))
|
||||
break;
|
||||
}
|
||||
if (j == updated->len)
|
||||
g_ptr_array_add (updated, list[i]);
|
||||
else
|
||||
g_free (list[i]);
|
||||
}
|
||||
if (j == updated->len)
|
||||
g_ptr_array_add (updated, list[i]);
|
||||
}
|
||||
g_free (list);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
g_ptr_array_add (updated, NULL);
|
||||
priv->no_auto_default = (char **) g_ptr_array_free (updated, FALSE);
|
||||
return (char **) g_ptr_array_free (updated, FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_config_get_ethernet_can_auto_default (NMConfig *config, NMDevice *device)
|
||||
nm_config_get_no_auto_default_for_device (NMConfig *self, NMDevice *device)
|
||||
{
|
||||
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config);
|
||||
GSList *specs = NULL;
|
||||
int i;
|
||||
gboolean match;
|
||||
NMConfigData *config_data;
|
||||
|
||||
for (i = 0; priv->no_auto_default[i]; i++)
|
||||
specs = g_slist_prepend (specs, priv->no_auto_default[i]);
|
||||
g_return_val_if_fail (NM_IS_CONFIG (self), FALSE);
|
||||
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
|
||||
|
||||
match = nm_device_spec_match_list (device, specs);
|
||||
|
||||
g_slist_free (specs);
|
||||
return !match;
|
||||
config_data = NM_CONFIG_GET_PRIVATE (self)->config_data;
|
||||
return nm_device_spec_match_list (device, nm_config_data_get_no_auto_default_list (config_data));
|
||||
}
|
||||
|
||||
void
|
||||
nm_config_set_ethernet_no_auto_default (NMConfig *config, NMDevice *device)
|
||||
nm_config_set_no_auto_default_for_device (NMConfig *self, NMDevice *device)
|
||||
{
|
||||
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config);
|
||||
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (self);
|
||||
char *current;
|
||||
GString *updated;
|
||||
GError *error = NULL;
|
||||
char **no_auto_default;
|
||||
NMConfigData *new_data = NULL;
|
||||
|
||||
if (!nm_config_get_ethernet_can_auto_default (config, device))
|
||||
g_return_if_fail (NM_IS_CONFIG (self));
|
||||
g_return_if_fail (NM_IS_DEVICE (device));
|
||||
|
||||
if (nm_config_get_no_auto_default_for_device (self, device))
|
||||
return;
|
||||
|
||||
updated = g_string_new (NULL);
|
||||
@@ -339,48 +341,111 @@ nm_config_set_ethernet_no_auto_default (NMConfig *config, NMDevice *device)
|
||||
|
||||
g_string_free (updated, TRUE);
|
||||
|
||||
merge_no_auto_default_state (config);
|
||||
no_auto_default = no_auto_default_merge_from_file (priv->no_auto_default_file, nm_config_data_get_no_auto_default (priv->config_data));
|
||||
new_data = nm_config_data_new_update_no_auto_default (priv->config_data, (const char *const*) no_auto_default);
|
||||
g_strfreev (no_auto_default);
|
||||
|
||||
_set_config_data (self, new_data);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
static char *cli_config_path;
|
||||
static char *cli_config_dir;
|
||||
static char *cli_no_auto_default_file;
|
||||
static char *cli_plugins;
|
||||
static char *cli_connectivity_uri;
|
||||
static int cli_connectivity_interval = -1;
|
||||
static char *cli_connectivity_response;
|
||||
|
||||
static GOptionEntry config_options[] = {
|
||||
{ "config", 0, 0, G_OPTION_ARG_FILENAME, &cli_config_path, N_("Config file location"), N_("/path/to/config.file") },
|
||||
{ "config-dir", 0, 0, G_OPTION_ARG_FILENAME, &cli_config_dir, N_("Config directory location"), N_("/path/to/config/dir") },
|
||||
{ "no-auto-default", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME, &cli_no_auto_default_file, "no-auto-default.state location", NULL },
|
||||
{ "plugins", 0, 0, G_OPTION_ARG_STRING, &cli_plugins, N_("List of plugins separated by ','"), N_("plugin1,plugin2") },
|
||||
|
||||
/* These three are hidden for now, and should eventually just go away. */
|
||||
{ "connectivity-uri", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &cli_connectivity_uri, N_("An http(s) address for checking internet connectivity"), "http://example.com" },
|
||||
{ "connectivity-interval", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_INT, &cli_connectivity_interval, N_("The interval between connectivity checks (in seconds)"), "60" },
|
||||
{ "connectivity-response", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &cli_connectivity_response, N_("The expected start of the response"), N_("Bingo!") },
|
||||
{NULL}
|
||||
};
|
||||
GOptionEntry *
|
||||
nm_config_get_options (void)
|
||||
static void
|
||||
_nm_config_cmd_line_options_clear (NMConfigCmdLineOptions *cli)
|
||||
{
|
||||
return config_options;
|
||||
g_clear_pointer (&cli->config_main_file, g_free);
|
||||
g_clear_pointer (&cli->config_dir, g_free);
|
||||
g_clear_pointer (&cli->no_auto_default_file, g_free);
|
||||
g_clear_pointer (&cli->plugins, g_free);
|
||||
g_clear_pointer (&cli->connectivity_uri, g_free);
|
||||
g_clear_pointer (&cli->connectivity_response, g_free);
|
||||
cli->connectivity_interval = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
_nm_config_cmd_line_options_copy (const NMConfigCmdLineOptions *cli, NMConfigCmdLineOptions *dst)
|
||||
{
|
||||
g_return_if_fail (cli);
|
||||
g_return_if_fail (dst);
|
||||
g_return_if_fail (cli != dst);
|
||||
|
||||
_nm_config_cmd_line_options_clear (dst);
|
||||
dst->config_dir = g_strdup (cli->config_dir);
|
||||
dst->config_main_file = g_strdup (cli->config_main_file);
|
||||
dst->no_auto_default_file = g_strdup (cli->no_auto_default_file);
|
||||
dst->plugins = g_strdup (cli->plugins);
|
||||
dst->connectivity_uri = g_strdup (cli->connectivity_uri);
|
||||
dst->connectivity_response = g_strdup (cli->connectivity_response);
|
||||
dst->connectivity_interval = cli->connectivity_interval;
|
||||
}
|
||||
|
||||
NMConfigCmdLineOptions *
|
||||
nm_config_cmd_line_options_new ()
|
||||
{
|
||||
NMConfigCmdLineOptions *cli = g_new0 (NMConfigCmdLineOptions, 1);
|
||||
|
||||
_nm_config_cmd_line_options_clear (cli);
|
||||
return cli;
|
||||
}
|
||||
|
||||
void
|
||||
nm_config_cmd_line_options_free (NMConfigCmdLineOptions *cli)
|
||||
{
|
||||
g_return_if_fail (cli);
|
||||
|
||||
_nm_config_cmd_line_options_clear (cli);
|
||||
g_free (cli);
|
||||
}
|
||||
|
||||
void
|
||||
nm_config_cmd_line_options_add_to_entries (NMConfigCmdLineOptions *cli,
|
||||
GOptionContext *opt_ctx)
|
||||
{
|
||||
g_return_if_fail (opt_ctx);
|
||||
g_return_if_fail (cli);
|
||||
|
||||
{
|
||||
GOptionEntry config_options[] = {
|
||||
{ "config", 0, 0, G_OPTION_ARG_FILENAME, &cli->config_main_file, N_("Config file location"), N_("/path/to/config.file") },
|
||||
{ "config-dir", 0, 0, G_OPTION_ARG_FILENAME, &cli->config_dir, N_("Config directory location"), N_("/path/to/config/dir") },
|
||||
{ "no-auto-default", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME, &cli->no_auto_default_file, "no-auto-default.state location", NULL },
|
||||
{ "plugins", 0, 0, G_OPTION_ARG_STRING, &cli->plugins, N_("List of plugins separated by ','"), N_("plugin1,plugin2") },
|
||||
|
||||
/* These three are hidden for now, and should eventually just go away. */
|
||||
{ "connectivity-uri", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &cli->connectivity_uri, N_("An http(s) address for checking internet connectivity"), "http://example.com" },
|
||||
{ "connectivity-interval", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_INT, &cli->connectivity_interval, N_("The interval between connectivity checks (in seconds)"), "60" },
|
||||
{ "connectivity-response", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &cli->connectivity_response, N_("The expected start of the response"), N_("Bingo!") },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
g_option_context_add_main_entries (opt_ctx, config_options, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
GKeyFile *
|
||||
nm_config_create_keyfile ()
|
||||
{
|
||||
GKeyFile *keyfile;
|
||||
|
||||
keyfile = g_key_file_new ();
|
||||
g_key_file_set_list_separator (keyfile, ',');
|
||||
return keyfile;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
read_config (NMConfig *config, const char *path, GError **error)
|
||||
read_config (GKeyFile *keyfile, const char *path, GError **error)
|
||||
{
|
||||
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config);
|
||||
GKeyFile *kf;
|
||||
char **groups, **keys;
|
||||
gsize ngroups, nkeys;
|
||||
int g, k;
|
||||
|
||||
g_return_val_if_fail (keyfile, FALSE);
|
||||
g_return_val_if_fail (path, FALSE);
|
||||
g_return_val_if_fail (!error || !*error, FALSE);
|
||||
|
||||
if (g_file_test (path, G_FILE_TEST_EXISTS) == FALSE) {
|
||||
g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND, "file %s not found", path);
|
||||
return FALSE;
|
||||
@@ -388,8 +453,7 @@ read_config (NMConfig *config, const char *path, GError **error)
|
||||
|
||||
nm_log_dbg (LOGD_SETTINGS, "Reading config file '%s'", path);
|
||||
|
||||
kf = g_key_file_new ();
|
||||
g_key_file_set_list_separator (kf, ',');
|
||||
kf = nm_config_create_keyfile ();
|
||||
if (!g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, error)) {
|
||||
g_key_file_free (kf);
|
||||
return FALSE;
|
||||
@@ -407,22 +471,22 @@ read_config (NMConfig *config, const char *path, GError **error)
|
||||
|
||||
if (keys[k][len - 1] == '+') {
|
||||
char *base_key = g_strndup (keys[k], len - 1);
|
||||
const char *old_val = g_key_file_get_value (priv->keyfile, groups[g], base_key, NULL);
|
||||
const char *old_val = g_key_file_get_value (keyfile, groups[g], base_key, NULL);
|
||||
const char *new_val = g_key_file_get_value (kf, groups[g], keys[k], NULL);
|
||||
|
||||
if (old_val && *old_val) {
|
||||
char *combined = g_strconcat (old_val, ",", new_val, NULL);
|
||||
|
||||
g_key_file_set_value (priv->keyfile, groups[g], base_key, combined);
|
||||
g_key_file_set_value (keyfile, groups[g], base_key, combined);
|
||||
g_free (combined);
|
||||
} else
|
||||
g_key_file_set_value (priv->keyfile, groups[g], base_key, new_val);
|
||||
g_key_file_set_value (keyfile, groups[g], base_key, new_val);
|
||||
|
||||
g_free (base_key);
|
||||
continue;
|
||||
}
|
||||
|
||||
g_key_file_set_value (priv->keyfile, groups[g], keys[k],
|
||||
g_key_file_set_value (keyfile, groups[g], keys[k],
|
||||
v = g_key_file_get_value (kf, groups[g], keys[k], NULL));
|
||||
g_free (v);
|
||||
}
|
||||
@@ -435,16 +499,22 @@ read_config (NMConfig *config, const char *path, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
find_base_config (NMConfig *config, GError **error)
|
||||
read_base_config (GKeyFile *keyfile,
|
||||
const char *cli_config_main_file,
|
||||
char **out_config_main_file,
|
||||
GError **error)
|
||||
{
|
||||
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config);
|
||||
GError *my_error = NULL;
|
||||
|
||||
g_return_val_if_fail (keyfile, FALSE);
|
||||
g_return_val_if_fail (out_config_main_file && !*out_config_main_file, FALSE);
|
||||
g_return_val_if_fail (!error || !*error, FALSE);
|
||||
|
||||
/* Try a user-specified config file first */
|
||||
if (cli_config_path) {
|
||||
if (cli_config_main_file) {
|
||||
/* Bad user-specific config file path is a hard error */
|
||||
if (read_config (config, cli_config_path, error)) {
|
||||
priv->nm_conf_path = g_strdup (cli_config_path);
|
||||
if (read_config (keyfile, cli_config_main_file, error)) {
|
||||
*out_config_main_file = g_strdup (cli_config_main_file);
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
@@ -458,8 +528,8 @@ find_base_config (NMConfig *config, GError **error)
|
||||
*/
|
||||
|
||||
/* Try deprecated nm-system-settings.conf first */
|
||||
if (read_config (config, NM_OLD_SYSTEM_CONF_FILE, &my_error)) {
|
||||
priv->nm_conf_path = g_strdup (NM_OLD_SYSTEM_CONF_FILE);
|
||||
if (read_config (keyfile, NM_OLD_SYSTEM_CONF_FILE, &my_error)) {
|
||||
*out_config_main_file = g_strdup (NM_OLD_SYSTEM_CONF_FILE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -471,8 +541,8 @@ find_base_config (NMConfig *config, GError **error)
|
||||
g_clear_error (&my_error);
|
||||
|
||||
/* Try the standard config file location next */
|
||||
if (read_config (config, NM_DEFAULT_SYSTEM_CONF_FILE, &my_error)) {
|
||||
priv->nm_conf_path = g_strdup (NM_DEFAULT_SYSTEM_CONF_FILE);
|
||||
if (read_config (keyfile, NM_DEFAULT_SYSTEM_CONF_FILE, &my_error)) {
|
||||
*out_config_main_file = g_strdup (NM_DEFAULT_SYSTEM_CONF_FILE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -488,21 +558,12 @@ find_base_config (NMConfig *config, GError **error)
|
||||
/* If for some reason no config file exists, use the default
|
||||
* config file path.
|
||||
*/
|
||||
priv->nm_conf_path = g_strdup (NM_DEFAULT_SYSTEM_CONF_FILE);
|
||||
*out_config_main_file = g_strdup (NM_DEFAULT_SYSTEM_CONF_FILE);
|
||||
nm_log_info (LOGD_CORE, "No config file found or given; using %s\n",
|
||||
NM_DEFAULT_SYSTEM_CONF_FILE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
NMConfig *
|
||||
nm_config_get (void)
|
||||
{
|
||||
g_assert (singleton);
|
||||
return singleton;
|
||||
}
|
||||
|
||||
static int
|
||||
sort_asciibetically (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
@@ -512,45 +573,31 @@ sort_asciibetically (gconstpointer a, gconstpointer b)
|
||||
return strcmp (s1, s2);
|
||||
}
|
||||
|
||||
/* call this function only once! */
|
||||
NMConfig *
|
||||
nm_config_new (GError **error)
|
||||
static GPtrArray *
|
||||
_get_config_dir_files (const char *config_main_file,
|
||||
const char *config_dir,
|
||||
char **out_config_description)
|
||||
{
|
||||
NMConfigPrivate *priv = NULL;
|
||||
GFile *dir;
|
||||
GFileEnumerator *direnum;
|
||||
GFileInfo *info;
|
||||
GPtrArray *confs;
|
||||
const char *name;
|
||||
int i;
|
||||
GString *config_description;
|
||||
const char *name;
|
||||
|
||||
g_assert (!singleton);
|
||||
singleton = NM_CONFIG (g_object_new (NM_TYPE_CONFIG, NULL));
|
||||
priv = NM_CONFIG_GET_PRIVATE (singleton);
|
||||
|
||||
/* First read the base config file */
|
||||
if (!find_base_config (singleton, error)) {
|
||||
g_object_unref (singleton);
|
||||
singleton = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Now read the overrides in the config dir */
|
||||
if (cli_config_dir)
|
||||
priv->config_dir = g_strdup (cli_config_dir);
|
||||
else
|
||||
priv->config_dir = g_strdup (NM_DEFAULT_SYSTEM_CONF_DIR);
|
||||
g_return_val_if_fail (config_main_file, NULL);
|
||||
g_return_val_if_fail (config_dir, NULL);
|
||||
g_return_val_if_fail (out_config_description && !*out_config_description, NULL);
|
||||
|
||||
confs = g_ptr_array_new_with_free_func (g_free);
|
||||
config_description = g_string_new (priv->nm_conf_path);
|
||||
dir = g_file_new_for_path (priv->config_dir);
|
||||
config_description = g_string_new (config_main_file);
|
||||
dir = g_file_new_for_path (config_dir);
|
||||
direnum = g_file_enumerate_children (dir, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, NULL);
|
||||
if (direnum) {
|
||||
while ((info = g_file_enumerator_next_file (direnum, NULL, NULL))) {
|
||||
name = g_file_info_get_name (info);
|
||||
if (g_str_has_suffix (name, ".conf")) {
|
||||
g_ptr_array_add (confs, g_build_filename (priv->config_dir, name, NULL));
|
||||
g_ptr_array_add (confs, g_build_filename (config_dir, name, NULL));
|
||||
if (confs->len == 1)
|
||||
g_string_append (config_description, " and conf.d: ");
|
||||
else
|
||||
@@ -564,62 +611,273 @@ nm_config_new (GError **error)
|
||||
g_object_unref (dir);
|
||||
|
||||
g_ptr_array_sort (confs, sort_asciibetically);
|
||||
priv->config_description = g_string_free (config_description, FALSE);
|
||||
|
||||
*out_config_description = g_string_free (config_description, FALSE);
|
||||
return confs;
|
||||
}
|
||||
|
||||
static GKeyFile *
|
||||
read_entire_config (const NMConfigCmdLineOptions *cli,
|
||||
const char *config_dir,
|
||||
char **out_config_main_file,
|
||||
char **out_config_description,
|
||||
GError **error)
|
||||
{
|
||||
GKeyFile *keyfile = nm_config_create_keyfile ();
|
||||
GPtrArray *confs;
|
||||
guint i;
|
||||
char *o_config_main_file = NULL;
|
||||
char *o_config_description = NULL;
|
||||
char **plugins_tmp;
|
||||
|
||||
g_return_val_if_fail (config_dir, NULL);
|
||||
g_return_val_if_fail (out_config_main_file && !*out_config_main_file, FALSE);
|
||||
g_return_val_if_fail (out_config_description && !*out_config_description, NULL);
|
||||
g_return_val_if_fail (!error || !*error, FALSE);
|
||||
|
||||
/* First read the base config file */
|
||||
if ( cli
|
||||
&& !read_base_config (keyfile, cli->config_main_file, &o_config_main_file, error)) {
|
||||
g_key_file_free (keyfile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_assert (o_config_main_file);
|
||||
|
||||
confs = _get_config_dir_files (o_config_main_file, config_dir, &o_config_description);
|
||||
for (i = 0; i < confs->len; i++) {
|
||||
if (!read_config (singleton, confs->pdata[i], error)) {
|
||||
g_object_unref (singleton);
|
||||
singleton = NULL;
|
||||
break;
|
||||
if (!read_config (keyfile, confs->pdata[i], error)) {
|
||||
g_key_file_free (keyfile);
|
||||
g_free (o_config_main_file);
|
||||
g_free (o_config_description);
|
||||
g_ptr_array_unref (confs);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
g_ptr_array_unref (confs);
|
||||
if (!singleton)
|
||||
|
||||
/* Merge settings from command line. They overwrite everything read from
|
||||
* config files. */
|
||||
|
||||
if (cli && cli->plugins && cli->plugins[0])
|
||||
g_key_file_set_value (keyfile, "main", "plugins", cli->plugins);
|
||||
plugins_tmp = g_key_file_get_string_list (keyfile, "main", "plugins", NULL, NULL);
|
||||
if (!plugins_tmp) {
|
||||
if (STRLEN (CONFIG_PLUGINS_DEFAULT) > 0)
|
||||
g_key_file_set_value (keyfile, "main", "plugins", CONFIG_PLUGINS_DEFAULT);
|
||||
} else
|
||||
g_strfreev (plugins_tmp);
|
||||
|
||||
if (cli && cli->connectivity_uri && cli->connectivity_uri[0])
|
||||
g_key_file_set_value (keyfile, "connectivity", "uri", cli->connectivity_uri);
|
||||
if (cli && cli->connectivity_interval >= 0)
|
||||
g_key_file_set_integer (keyfile, "connectivity", "interval", cli->connectivity_interval);
|
||||
if (cli && cli->connectivity_response && cli->connectivity_response[0])
|
||||
g_key_file_set_value (keyfile, "connectivity", "response", cli->connectivity_response);
|
||||
|
||||
*out_config_main_file = o_config_main_file;
|
||||
*out_config_description = o_config_description;
|
||||
return keyfile;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
void
|
||||
nm_config_reload (NMConfig *self)
|
||||
{
|
||||
NMConfigPrivate *priv;
|
||||
GError *error = NULL;
|
||||
GKeyFile *keyfile;
|
||||
NMConfigData *new_data = NULL;
|
||||
char *config_main_file = NULL;
|
||||
char *config_description = NULL;
|
||||
|
||||
g_return_if_fail (NM_IS_CONFIG (self));
|
||||
|
||||
priv = NM_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
/* pass on the original command line options. This means, that
|
||||
* options specified at command line cannot ever be reloaded from
|
||||
* file. That seems desirable.
|
||||
*/
|
||||
keyfile = read_entire_config (&priv->cli,
|
||||
priv->config_dir,
|
||||
&config_main_file,
|
||||
&config_description,
|
||||
&error);
|
||||
if (!keyfile) {
|
||||
nm_log_err (LOGD_CORE, "Failed to reload the configuration: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
new_data = nm_config_data_new (config_main_file, config_description, nm_config_data_get_no_auto_default (priv->config_data), keyfile);
|
||||
g_free (config_main_file);
|
||||
g_free (config_description);
|
||||
g_key_file_unref (keyfile);
|
||||
|
||||
_set_config_data (self, new_data);
|
||||
}
|
||||
|
||||
static const char *
|
||||
_change_flags_one_to_string (NMConfigChangeFlags flag)
|
||||
{
|
||||
switch (flag) {
|
||||
case NM_CONFIG_CHANGE_CONFIG_FILES:
|
||||
return "config-files";
|
||||
case NM_CONFIG_CHANGE_VALUES:
|
||||
return "values";
|
||||
case NM_CONFIG_CHANGE_CONNECTIVITY:
|
||||
return "connectivity";
|
||||
case NM_CONFIG_CHANGE_NO_AUTO_DEFAULT:
|
||||
return "no-auto-default";
|
||||
default:
|
||||
g_return_val_if_reached ("unknown");
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
nm_config_change_flags_to_string (NMConfigChangeFlags flags)
|
||||
{
|
||||
GString *str = g_string_new ("");
|
||||
NMConfigChangeFlags s = 0x01;
|
||||
|
||||
while (flags) {
|
||||
if (NM_FLAGS_HAS (flags, s)) {
|
||||
if (str->len)
|
||||
g_string_append_c (str, ',');
|
||||
g_string_append (str, _change_flags_one_to_string (s));
|
||||
}
|
||||
flags = flags & ~s;
|
||||
s <<= 1;
|
||||
}
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
_set_config_data (NMConfig *self, NMConfigData *new_data)
|
||||
{
|
||||
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (self);
|
||||
NMConfigData *old_data = priv->config_data;
|
||||
NMConfigChangeFlags changes;
|
||||
gs_free char *log_str = NULL;
|
||||
|
||||
changes = nm_config_data_diff (old_data, new_data);
|
||||
if (changes == NM_CONFIG_CHANGE_NONE) {
|
||||
g_object_unref (new_data);
|
||||
return;
|
||||
}
|
||||
|
||||
nm_log_info (LOGD_CORE, "config: update %s (%s)", nm_config_data_get_config_description (new_data),
|
||||
(log_str = nm_config_change_flags_to_string (changes)));
|
||||
priv->config_data = new_data;
|
||||
g_signal_emit (self, signals[SIGNAL_CONFIG_CHANGED], 0, new_data, changes, old_data);
|
||||
g_object_unref (old_data);
|
||||
}
|
||||
|
||||
NM_DEFINE_SINGLETON_DESTRUCTOR (NMConfig);
|
||||
NM_DEFINE_SINGLETON_WEAK_REF (NMConfig);
|
||||
|
||||
NMConfig *
|
||||
nm_config_get (void)
|
||||
{
|
||||
g_assert (singleton_instance);
|
||||
return singleton_instance;
|
||||
}
|
||||
|
||||
NMConfig *
|
||||
nm_config_setup (const NMConfigCmdLineOptions *cli, GError **error)
|
||||
{
|
||||
g_assert (!singleton_instance);
|
||||
|
||||
singleton_instance = nm_config_new (cli, error);
|
||||
if (singleton_instance)
|
||||
nm_singleton_instance_weak_ref_register ();
|
||||
return singleton_instance;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
NMConfig *self = NM_CONFIG (initable);
|
||||
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (self);
|
||||
GKeyFile *keyfile;
|
||||
char *config_main_file = NULL;
|
||||
char *config_description = NULL;
|
||||
char **no_auto_default;
|
||||
char **no_auto_default_orig;
|
||||
|
||||
if (priv->config_dir) {
|
||||
/* Object is already initialized. */
|
||||
if (priv->config_data)
|
||||
return TRUE;
|
||||
g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND, "unspecified error");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (priv->cli.config_dir)
|
||||
priv->config_dir = g_strdup (priv->cli.config_dir);
|
||||
else
|
||||
priv->config_dir = g_strdup (NM_DEFAULT_SYSTEM_CONF_DIR);
|
||||
|
||||
keyfile = read_entire_config (&priv->cli,
|
||||
priv->config_dir,
|
||||
&config_main_file,
|
||||
&config_description,
|
||||
error);
|
||||
if (!keyfile)
|
||||
return FALSE;
|
||||
|
||||
/* Handle no-auto-default key and state file */
|
||||
priv->no_auto_default = g_key_file_get_string_list (priv->keyfile, "main", "no-auto-default", NULL, NULL);
|
||||
if (cli_no_auto_default_file)
|
||||
priv->no_auto_default_file = g_strdup (cli_no_auto_default_file);
|
||||
/* Initialize read only private members */
|
||||
|
||||
if (priv->cli.no_auto_default_file)
|
||||
priv->no_auto_default_file = g_strdup (priv->cli.no_auto_default_file);
|
||||
else
|
||||
priv->no_auto_default_file = g_strdup (NM_NO_AUTO_DEFAULT_STATE_FILE);
|
||||
merge_no_auto_default_state (singleton);
|
||||
|
||||
/* Now let command-line options override the config files, and fill in priv. */
|
||||
if (cli_plugins && cli_plugins[0])
|
||||
g_key_file_set_value (priv->keyfile, "main", "plugins", cli_plugins);
|
||||
priv->plugins = g_key_file_get_string_list (priv->keyfile, "main", "plugins", NULL, NULL);
|
||||
if (!priv->plugins && STRLEN (CONFIG_PLUGINS_DEFAULT) > 0)
|
||||
priv->plugins = g_strsplit (CONFIG_PLUGINS_DEFAULT, ",", -1);
|
||||
priv->plugins = g_key_file_get_string_list (keyfile, "main", "plugins", NULL, NULL);
|
||||
if (!priv->plugins)
|
||||
priv->plugins = g_new0 (char *, 1);
|
||||
|
||||
priv->monitor_connection_files = _get_bool_value (priv->keyfile, "main", "monitor-connection-files", FALSE);
|
||||
priv->monitor_connection_files = _get_bool_value (keyfile, "main", "monitor-connection-files", FALSE);
|
||||
|
||||
priv->auth_polkit = _get_bool_value (priv->keyfile, "main", "auth-polkit", NM_CONFIG_DEFAULT_AUTH_POLKIT);
|
||||
priv->auth_polkit = _get_bool_value (keyfile, "main", "auth-polkit", NM_CONFIG_DEFAULT_AUTH_POLKIT);
|
||||
|
||||
priv->dhcp_client = g_key_file_get_value (priv->keyfile, "main", "dhcp", NULL);
|
||||
priv->dns_mode = g_key_file_get_value (priv->keyfile, "main", "dns", NULL);
|
||||
priv->dhcp_client = g_key_file_get_value (keyfile, "main", "dhcp", NULL);
|
||||
priv->dns_mode = g_key_file_get_value (keyfile, "main", "dns", NULL);
|
||||
|
||||
priv->log_level = g_key_file_get_value (priv->keyfile, "logging", "level", NULL);
|
||||
priv->log_domains = g_key_file_get_value (priv->keyfile, "logging", "domains", NULL);
|
||||
priv->log_level = g_key_file_get_value (keyfile, "logging", "level", NULL);
|
||||
priv->log_domains = g_key_file_get_value (keyfile, "logging", "domains", NULL);
|
||||
|
||||
priv->debug = g_key_file_get_value (priv->keyfile, "main", "debug", NULL);
|
||||
priv->debug = g_key_file_get_value (keyfile, "main", "debug", NULL);
|
||||
|
||||
if (cli_connectivity_uri && cli_connectivity_uri[0])
|
||||
g_key_file_set_value (priv->keyfile, "connectivity", "uri", cli_connectivity_uri);
|
||||
priv->connectivity_uri = g_key_file_get_value (priv->keyfile, "connectivity", "uri", NULL);
|
||||
priv->ignore_carrier = g_key_file_get_string_list (keyfile, "main", "ignore-carrier", NULL, NULL);
|
||||
|
||||
if (cli_connectivity_interval >= 0)
|
||||
g_key_file_set_integer (priv->keyfile, "connectivity", "interval", cli_connectivity_interval);
|
||||
priv->connectivity_interval = g_key_file_get_integer (priv->keyfile, "connectivity", "interval", NULL);
|
||||
priv->configure_and_quit = _get_bool_value (keyfile, "main", "configure-and-quit", FALSE);
|
||||
|
||||
if (cli_connectivity_response && cli_connectivity_response[0])
|
||||
g_key_file_set_value (priv->keyfile, "connectivity", "response", cli_connectivity_response);
|
||||
priv->connectivity_response = g_key_file_get_value (priv->keyfile, "connectivity", "response", NULL);
|
||||
no_auto_default_orig = g_key_file_get_string_list (keyfile, "main", "no-auto-default", NULL, NULL);
|
||||
no_auto_default = no_auto_default_merge_from_file (priv->no_auto_default_file, (const char *const *) no_auto_default_orig);
|
||||
|
||||
priv->ignore_carrier = g_key_file_get_string_list (priv->keyfile, "main", "ignore-carrier", NULL, NULL);
|
||||
priv->config_data_orig = nm_config_data_new (config_main_file, config_description, (const char *const*) no_auto_default, keyfile);
|
||||
|
||||
priv->configure_and_quit = _get_bool_value (priv->keyfile, "main", "configure-and-quit", FALSE);
|
||||
g_strfreev (no_auto_default);
|
||||
g_strfreev (no_auto_default_orig);
|
||||
|
||||
return singleton;
|
||||
priv->config_data = g_object_ref (priv->config_data_orig);
|
||||
|
||||
g_free (config_main_file);
|
||||
g_free (config_description);
|
||||
g_key_file_unref (keyfile);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NMConfig *
|
||||
nm_config_new (const NMConfigCmdLineOptions *cli, GError **error)
|
||||
{
|
||||
return NM_CONFIG (g_initable_new (NM_TYPE_CONFIG,
|
||||
NULL,
|
||||
error,
|
||||
NM_CONFIG_CMD_LINE_OPTIONS, cli,
|
||||
NULL));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -628,11 +886,6 @@ nm_config_init (NMConfig *config)
|
||||
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config);
|
||||
|
||||
priv->auth_polkit = NM_CONFIG_DEFAULT_AUTH_POLKIT;
|
||||
|
||||
priv->keyfile = g_key_file_new ();
|
||||
g_key_file_set_list_separator (priv->keyfile, ',');
|
||||
|
||||
priv->connectivity_interval = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -640,34 +893,46 @@ finalize (GObject *gobject)
|
||||
{
|
||||
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (gobject);
|
||||
|
||||
g_free (priv->nm_conf_path);
|
||||
g_free (priv->config_dir);
|
||||
g_free (priv->config_description);
|
||||
g_free (priv->no_auto_default_file);
|
||||
g_clear_pointer (&priv->keyfile, g_key_file_unref);
|
||||
g_strfreev (priv->plugins);
|
||||
g_free (priv->dhcp_client);
|
||||
g_free (priv->dns_mode);
|
||||
g_free (priv->log_level);
|
||||
g_free (priv->log_domains);
|
||||
g_free (priv->debug);
|
||||
g_free (priv->connectivity_uri);
|
||||
g_free (priv->connectivity_response);
|
||||
g_strfreev (priv->no_auto_default);
|
||||
g_strfreev (priv->ignore_carrier);
|
||||
|
||||
singleton = NULL;
|
||||
_nm_config_cmd_line_options_clear (&priv->cli);
|
||||
|
||||
g_clear_pointer (&cli_config_path, g_free);
|
||||
g_clear_pointer (&cli_config_dir, g_free);
|
||||
g_clear_pointer (&cli_no_auto_default_file, g_free);
|
||||
g_clear_pointer (&cli_plugins, g_free);
|
||||
g_clear_pointer (&cli_connectivity_uri, g_free);
|
||||
g_clear_pointer (&cli_connectivity_response, g_free);
|
||||
g_clear_object (&priv->config_data);
|
||||
g_clear_object (&priv->config_data_orig);
|
||||
|
||||
G_OBJECT_CLASS (nm_config_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMConfig *self = NM_CONFIG (object);
|
||||
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (self);
|
||||
NMConfigCmdLineOptions *cli;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CMD_LINE_OPTIONS:
|
||||
/* construct only */
|
||||
cli = g_value_get_pointer (value);
|
||||
if (!cli)
|
||||
_nm_config_cmd_line_options_clear (&priv->cli);
|
||||
else
|
||||
_nm_config_cmd_line_options_copy (cli, &priv->cli);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nm_config_class_init (NMConfigClass *config_class)
|
||||
@@ -676,5 +941,27 @@ nm_config_class_init (NMConfigClass *config_class)
|
||||
|
||||
g_type_class_add_private (config_class, sizeof (NMConfigPrivate));
|
||||
object_class->finalize = finalize;
|
||||
object_class->set_property = set_property;
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_CMD_LINE_OPTIONS,
|
||||
g_param_spec_pointer (NM_CONFIG_CMD_LINE_OPTIONS, "", "",
|
||||
G_PARAM_WRITABLE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
signals[SIGNAL_CONFIG_CHANGED] =
|
||||
g_signal_new (NM_CONFIG_SIGNAL_CONFIG_CHANGED,
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMConfigClass, config_changed),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 3, NM_TYPE_CONFIG_DATA, NM_TYPE_CONFIG_CHANGE_FLAGS, NM_TYPE_CONFIG_DATA);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_config_initable_iface_init (GInitableIface *iface)
|
||||
{
|
||||
iface->init = init_sync;
|
||||
}
|
||||
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "nm-types.h"
|
||||
#include "nm-config-data.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -36,20 +37,33 @@ G_BEGIN_DECLS
|
||||
#define NM_IS_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_CONFIG))
|
||||
#define NM_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CONFIG, NMConfigClass))
|
||||
|
||||
typedef struct {
|
||||
/* Properties */
|
||||
#define NM_CONFIG_CMD_LINE_OPTIONS "cmd-line-options"
|
||||
|
||||
/* Signals */
|
||||
#define NM_CONFIG_SIGNAL_CONFIG_CHANGED "config-changed"
|
||||
|
||||
typedef struct NMConfigCmdLineOptions NMConfigCmdLineOptions;
|
||||
|
||||
struct _NMConfig {
|
||||
GObject parent;
|
||||
} NMConfig;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent;
|
||||
|
||||
/* Signals */
|
||||
void (*config_changed) (NMConfig *config, GHashTable *changes, NMConfigData *old_data);
|
||||
} NMConfigClass;
|
||||
|
||||
GType nm_config_get_type (void);
|
||||
|
||||
NMConfig *nm_config_get (void);
|
||||
|
||||
const char *nm_config_get_path (NMConfig *config);
|
||||
const char *nm_config_get_description (NMConfig *config);
|
||||
char *nm_config_change_flags_to_string (NMConfigChangeFlags flags);
|
||||
|
||||
NMConfigData *nm_config_get_data (NMConfig *config);
|
||||
NMConfigData *nm_config_get_data_orig (NMConfig *config);
|
||||
const char **nm_config_get_plugins (NMConfig *config);
|
||||
gboolean nm_config_get_monitor_connection_files (NMConfig *config);
|
||||
gboolean nm_config_get_auth_polkit (NMConfig *config);
|
||||
@@ -58,21 +72,24 @@ const char *nm_config_get_dns_mode (NMConfig *config);
|
||||
const char *nm_config_get_log_level (NMConfig *config);
|
||||
const char *nm_config_get_log_domains (NMConfig *config);
|
||||
const char *nm_config_get_debug (NMConfig *config);
|
||||
const char *nm_config_get_connectivity_uri (NMConfig *config);
|
||||
guint nm_config_get_connectivity_interval (NMConfig *config);
|
||||
const char *nm_config_get_connectivity_response (NMConfig *config);
|
||||
gboolean nm_config_get_configure_and_quit (NMConfig *config);
|
||||
|
||||
gboolean nm_config_get_ethernet_can_auto_default (NMConfig *config, NMDevice *device);
|
||||
void nm_config_set_ethernet_no_auto_default (NMConfig *config, NMDevice *device);
|
||||
|
||||
gboolean nm_config_get_ignore_carrier (NMConfig *config, NMDevice *device);
|
||||
|
||||
char *nm_config_get_value (NMConfig *config, const char *group, const char *key, GError **error);
|
||||
|
||||
/* for main.c only */
|
||||
GOptionEntry *nm_config_get_options (void);
|
||||
NMConfig *nm_config_new (GError **error);
|
||||
NMConfigCmdLineOptions *nm_config_cmd_line_options_new (void);
|
||||
void nm_config_cmd_line_options_free (NMConfigCmdLineOptions *cli);
|
||||
void nm_config_cmd_line_options_add_to_entries (NMConfigCmdLineOptions *cli,
|
||||
GOptionContext *opt_ctx);
|
||||
|
||||
gboolean nm_config_get_no_auto_default_for_device (NMConfig *config, NMDevice *device);
|
||||
void nm_config_set_no_auto_default_for_device (NMConfig *config, NMDevice *device);
|
||||
|
||||
NMConfig *nm_config_new (const NMConfigCmdLineOptions *cli, GError **error);
|
||||
NMConfig *nm_config_setup (const NMConfigCmdLineOptions *cli, GError **error);
|
||||
void nm_config_reload (NMConfig *config);
|
||||
|
||||
GKeyFile *nm_config_create_keyfile (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -28,7 +28,6 @@
|
||||
|
||||
#include "nm-connectivity.h"
|
||||
#include "nm-logging.h"
|
||||
#include "nm-config.h"
|
||||
|
||||
G_DEFINE_TYPE (NMConnectivity, nm_connectivity, G_TYPE_OBJECT)
|
||||
|
||||
@@ -37,14 +36,32 @@ G_DEFINE_TYPE (NMConnectivity, nm_connectivity, G_TYPE_OBJECT)
|
||||
|
||||
#define DEFAULT_RESPONSE "NetworkManager is online" /* NOT LOCALIZED */
|
||||
|
||||
#define _LOG_DEFAULT_DOMAIN LOGD_CONCHECK
|
||||
|
||||
#define _LOG(level, domain, ...) \
|
||||
G_STMT_START { \
|
||||
nm_log ((level), (domain), \
|
||||
"%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
|
||||
"connectivity: " \
|
||||
_NM_UTILS_MACRO_REST(__VA_ARGS__)); \
|
||||
} G_STMT_END
|
||||
|
||||
#define _LOGT(...) _LOG (LOGL_TRACE, _LOG_DEFAULT_DOMAIN, __VA_ARGS__)
|
||||
#define _LOGD(...) _LOG (LOGL_DEBUG, _LOG_DEFAULT_DOMAIN, __VA_ARGS__)
|
||||
#define _LOGI(...) _LOG (LOGL_INFO, _LOG_DEFAULT_DOMAIN, __VA_ARGS__)
|
||||
#define _LOGW(...) _LOG (LOGL_WARN, _LOG_DEFAULT_DOMAIN, __VA_ARGS__)
|
||||
#define _LOGE(...) _LOG (LOGL_ERR, _LOG_DEFAULT_DOMAIN, __VA_ARGS__)
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *uri;
|
||||
char *response;
|
||||
guint interval;
|
||||
gboolean online; /* whether periodic connectivity checking is enabled. */
|
||||
|
||||
#if WITH_CONCHECK
|
||||
SoupSession *soup_session;
|
||||
guint pending_checks;
|
||||
gboolean initial_check_obsoleted;
|
||||
guint check_id;
|
||||
#endif
|
||||
|
||||
@@ -69,8 +86,8 @@ nm_connectivity_get_state (NMConnectivity *connectivity)
|
||||
return NM_CONNECTIVITY_GET_PRIVATE (connectivity)->state;
|
||||
}
|
||||
|
||||
static const char *
|
||||
state_name (NMConnectivityState state)
|
||||
const char *
|
||||
nm_connectivity_state_to_string (NMConnectivityState state)
|
||||
{
|
||||
switch (state) {
|
||||
case NM_CONNECTIVITY_UNKNOWN:
|
||||
@@ -84,7 +101,7 @@ state_name (NMConnectivityState state)
|
||||
case NM_CONNECTIVITY_FULL:
|
||||
return "FULL";
|
||||
default:
|
||||
return "???";
|
||||
g_return_val_if_reached ("???");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,31 +111,41 @@ update_state (NMConnectivity *self, NMConnectivityState state)
|
||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
|
||||
if (priv->state != state) {
|
||||
nm_log_dbg (LOGD_CONCHECK, "Connectivity state changed from %s to %s",
|
||||
state_name (priv->state), state_name (state));
|
||||
_LOGD ("state changed from %s to %s",
|
||||
nm_connectivity_state_to_string (priv->state),
|
||||
nm_connectivity_state_to_string (state));
|
||||
priv->state = state;
|
||||
g_object_notify (G_OBJECT (self), NM_CONNECTIVITY_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
#if WITH_CONCHECK
|
||||
typedef struct {
|
||||
GSimpleAsyncResult *simple;
|
||||
char *uri;
|
||||
char *response;
|
||||
guint check_id_when_scheduled;
|
||||
} ConCheckCbData;
|
||||
|
||||
static void
|
||||
nm_connectivity_check_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *simple = user_data;
|
||||
NMConnectivity *self;
|
||||
NMConnectivityPrivate *priv;
|
||||
ConCheckCbData *cb_data = user_data;
|
||||
GSimpleAsyncResult *simple = cb_data->simple;
|
||||
NMConnectivityState new_state;
|
||||
const char *nm_header;
|
||||
const char *uri = cb_data->uri;
|
||||
const char *response = cb_data->response ? cb_data->response : DEFAULT_RESPONSE;
|
||||
|
||||
self = NM_CONNECTIVITY (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
|
||||
/* it is safe to unref @self here, @simple holds yet another reference. */
|
||||
g_object_unref (self);
|
||||
priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
priv->pending_checks--;
|
||||
|
||||
if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) {
|
||||
nm_log_info (LOGD_CONCHECK, "Connectivity check for uri '%s' failed with '%s'.",
|
||||
priv->uri, msg->reason_phrase);
|
||||
_LOGI ("check for uri '%s' failed with '%s'", uri, msg->reason_phrase);
|
||||
new_state = NM_CONNECTIVITY_LIMITED;
|
||||
goto done;
|
||||
}
|
||||
@@ -126,32 +153,47 @@ nm_connectivity_check_cb (SoupSession *session, SoupMessage *msg, gpointer user_
|
||||
/* Check headers; if we find the NM-specific one we're done */
|
||||
nm_header = soup_message_headers_get_one (msg->response_headers, "X-NetworkManager-Status");
|
||||
if (g_strcmp0 (nm_header, "online") == 0) {
|
||||
nm_log_dbg (LOGD_CONCHECK, "Connectivity check for uri '%s' with Status header successful.", priv->uri);
|
||||
_LOGD ("check for uri '%s' with Status header successful.", uri);
|
||||
new_state = NM_CONNECTIVITY_FULL;
|
||||
} else if (msg->status_code == SOUP_STATUS_OK) {
|
||||
/* check response */
|
||||
if (msg->response_body->data && (g_str_has_prefix (msg->response_body->data, priv->response))) {
|
||||
nm_log_dbg (LOGD_CONCHECK, "Connectivity check for uri '%s' successful.",
|
||||
priv->uri);
|
||||
if (msg->response_body->data && g_str_has_prefix (msg->response_body->data, response)) {
|
||||
_LOGD ("check for uri '%s' successful.", uri);
|
||||
new_state = NM_CONNECTIVITY_FULL;
|
||||
} else {
|
||||
nm_log_info (LOGD_CONCHECK, "Connectivity check for uri '%s' did not match expected response '%s'; assuming captive portal.",
|
||||
priv->uri, priv->response);
|
||||
_LOGI ("check for uri '%s' did not match expected response '%s'; assuming captive portal.",
|
||||
uri, response);
|
||||
new_state = NM_CONNECTIVITY_PORTAL;
|
||||
}
|
||||
} else {
|
||||
nm_log_info (LOGD_CONCHECK, "Connectivity check for uri '%s' returned status '%d %s'; assuming captive portal.",
|
||||
priv->uri, msg->status_code, msg->reason_phrase);
|
||||
_LOGI ("check for uri '%s' returned status '%d %s'; assuming captive portal.",
|
||||
uri, msg->status_code, msg->reason_phrase);
|
||||
new_state = NM_CONNECTIVITY_PORTAL;
|
||||
}
|
||||
|
||||
done:
|
||||
update_state (self, new_state);
|
||||
/* Only update the state, if the call was done from external, or if the periodic check
|
||||
* is still the one that called this async check. */
|
||||
if (!cb_data->check_id_when_scheduled || cb_data->check_id_when_scheduled == priv->check_id) {
|
||||
/* Only update the state, if the URI and response parameters did not change
|
||||
* since invocation.
|
||||
* The interval does not matter for exernal calls, and for internal calls
|
||||
* we don't reach this line if the interval changed. */
|
||||
if ( !g_strcmp0 (cb_data->uri, priv->uri)
|
||||
&& !g_strcmp0 (cb_data->response, priv->response))
|
||||
update_state (self, new_state);
|
||||
}
|
||||
|
||||
g_simple_async_result_set_op_res_gssize (simple, new_state);
|
||||
g_simple_async_result_complete (simple);
|
||||
|
||||
g_free (cb_data->uri);
|
||||
g_free (cb_data->response);
|
||||
g_slice_free (ConCheckCbData, cb_data);
|
||||
}
|
||||
|
||||
#define IS_PERIODIC_CHECK(callback) (callback == run_check_complete)
|
||||
|
||||
static void
|
||||
run_check_complete (GObject *object,
|
||||
GAsyncResult *result,
|
||||
@@ -162,7 +204,7 @@ run_check_complete (GObject *object,
|
||||
|
||||
nm_connectivity_check_finish (self, result, &error);
|
||||
if (error) {
|
||||
nm_log_err (LOGD_CONCHECK, "Connectivity check failed: %s", error->message);
|
||||
_LOGE ("check failed: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
@@ -183,39 +225,54 @@ idle_start_periodic_checks (gpointer user_data)
|
||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
|
||||
priv->check_id = g_timeout_add_seconds (priv->interval, run_check, self);
|
||||
if (!priv->pending_checks)
|
||||
if (!priv->initial_check_obsoleted)
|
||||
run_check (self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nm_connectivity_set_online (NMConnectivity *self,
|
||||
gboolean online)
|
||||
static void
|
||||
_reschedule_periodic_checks (NMConnectivity *self, gboolean force_reschedule)
|
||||
{
|
||||
#if WITH_CONCHECK
|
||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
#endif
|
||||
|
||||
nm_log_dbg (LOGD_CONCHECK, "nm_connectivity_set_online(%s)", online ? "TRUE" : "FALSE");
|
||||
|
||||
#if WITH_CONCHECK
|
||||
if (online && priv->uri && priv->interval) {
|
||||
if (!priv->check_id)
|
||||
if (priv->online && priv->uri && priv->interval) {
|
||||
if (force_reschedule || !priv->check_id) {
|
||||
if (priv->check_id)
|
||||
g_source_remove (priv->check_id);
|
||||
priv->check_id = g_timeout_add (0, idle_start_periodic_checks, self);
|
||||
|
||||
return;
|
||||
} else if (priv->check_id) {
|
||||
g_source_remove (priv->check_id);
|
||||
priv->check_id = 0;
|
||||
priv->initial_check_obsoleted = FALSE;
|
||||
}
|
||||
} else {
|
||||
if (priv->check_id) {
|
||||
g_source_remove (priv->check_id);
|
||||
priv->check_id = 0;
|
||||
}
|
||||
}
|
||||
if (priv->check_id)
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* Either @online is %TRUE but we aren't checking connectivity, or
|
||||
* @online is %FALSE. Either way we can update our status immediately.
|
||||
*/
|
||||
update_state (self, online ? NM_CONNECTIVITY_FULL : NM_CONNECTIVITY_NONE);
|
||||
update_state (self, priv->online ? NM_CONNECTIVITY_FULL : NM_CONNECTIVITY_NONE);
|
||||
}
|
||||
|
||||
void
|
||||
nm_connectivity_set_online (NMConnectivity *self,
|
||||
gboolean online)
|
||||
{
|
||||
NMConnectivityPrivate *priv= NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
|
||||
online = !!online;
|
||||
if (priv->online != online) {
|
||||
_LOGD ("set %s", online ? "online" : "offline");
|
||||
priv->online = online;
|
||||
_reschedule_periodic_checks (self, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -224,36 +281,42 @@ nm_connectivity_check_async (NMConnectivity *self,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMConnectivityPrivate *priv;
|
||||
#if WITH_CONCHECK
|
||||
SoupMessage *msg;
|
||||
#endif
|
||||
GSimpleAsyncResult *simple;
|
||||
|
||||
g_return_if_fail (NM_IS_CONNECTIVITY (self));
|
||||
priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
|
||||
#if WITH_CONCHECK
|
||||
if (callback == run_check_complete)
|
||||
nm_log_dbg (LOGD_CONCHECK, "Periodic connectivity check started with uri '%s'.", priv->uri);
|
||||
else
|
||||
#endif
|
||||
nm_log_dbg (LOGD_CONCHECK, "Connectivity check started with uri '%s'.", priv->uri);
|
||||
|
||||
simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
|
||||
nm_connectivity_check_async);
|
||||
|
||||
#if WITH_CONCHECK
|
||||
if (priv->uri && priv->interval) {
|
||||
SoupMessage *msg;
|
||||
ConCheckCbData *cb_data = g_slice_new (ConCheckCbData);
|
||||
|
||||
msg = soup_message_new ("GET", priv->uri);
|
||||
soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
|
||||
cb_data->simple = simple;
|
||||
cb_data->uri = g_strdup (priv->uri);
|
||||
cb_data->response = g_strdup (priv->response);
|
||||
|
||||
/* For internal calls (periodic), remember the check-id at time of scheduling. */
|
||||
cb_data->check_id_when_scheduled = IS_PERIODIC_CHECK (callback) ? priv->check_id : 0;
|
||||
|
||||
soup_session_queue_message (priv->soup_session,
|
||||
msg,
|
||||
nm_connectivity_check_cb,
|
||||
simple);
|
||||
priv->pending_checks++;
|
||||
cb_data);
|
||||
priv->initial_check_obsoleted = TRUE;
|
||||
|
||||
_LOGD ("check: send %srequest to '%s'", IS_PERIODIC_CHECK (callback) ? "periodic " : "", priv->uri);
|
||||
return;
|
||||
} else {
|
||||
g_warn_if_fail (!IS_PERIODIC_CHECK (callback));
|
||||
_LOGD ("check: faking request. Connectivity check disabled");
|
||||
}
|
||||
#else
|
||||
_LOGD ("check: faking request. Compiled without connectivity-check support");
|
||||
#endif
|
||||
|
||||
g_simple_async_result_set_op_res_gssize (simple, priv->state);
|
||||
@@ -275,38 +338,18 @@ nm_connectivity_check_finish (NMConnectivity *self,
|
||||
return (NMConnectivityState) g_simple_async_result_get_op_res_gssize (simple);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
NMConnectivity *
|
||||
nm_connectivity_new (void)
|
||||
nm_connectivity_new (const char *uri,
|
||||
guint interval,
|
||||
const char *response)
|
||||
{
|
||||
NMConnectivity *self;
|
||||
NMConfig *config;
|
||||
const char *check_response;
|
||||
|
||||
config = nm_config_get ();
|
||||
check_response = nm_config_get_connectivity_response (config);
|
||||
|
||||
self = g_object_new (NM_TYPE_CONNECTIVITY,
|
||||
NM_CONNECTIVITY_URI, nm_config_get_connectivity_uri (config),
|
||||
NM_CONNECTIVITY_INTERVAL, nm_config_get_connectivity_interval (config),
|
||||
NM_CONNECTIVITY_RESPONSE, check_response ? check_response : DEFAULT_RESPONSE,
|
||||
return g_object_new (NM_TYPE_CONNECTIVITY,
|
||||
NM_CONNECTIVITY_URI, uri,
|
||||
NM_CONNECTIVITY_INTERVAL, interval,
|
||||
NM_CONNECTIVITY_RESPONSE, response,
|
||||
NULL);
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
update_state (self, NM_CONNECTIVITY_NONE);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_non_empty_string_value (const GValue *val)
|
||||
{
|
||||
const char *s;
|
||||
|
||||
s = g_value_get_string (val);
|
||||
if (s && s[0])
|
||||
return g_strdup (s);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -315,32 +358,48 @@ set_property (GObject *object, guint property_id,
|
||||
{
|
||||
NMConnectivity *self = NM_CONNECTIVITY (object);
|
||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
const char *uri, *response;
|
||||
guint interval;
|
||||
|
||||
switch (property_id) {
|
||||
case PROP_URI:
|
||||
g_free (priv->uri);
|
||||
priv->uri = get_non_empty_string_value (value);
|
||||
|
||||
uri = g_value_get_string (value);
|
||||
if (uri && !*uri)
|
||||
uri = NULL;
|
||||
#if WITH_CONCHECK
|
||||
if (priv->uri) {
|
||||
SoupURI *uri = soup_uri_new (priv->uri);
|
||||
if (uri) {
|
||||
SoupURI *soup_uri = soup_uri_new (uri);
|
||||
|
||||
if (!uri || !SOUP_URI_VALID_FOR_HTTP (uri)) {
|
||||
nm_log_err (LOGD_CONCHECK, "Invalid uri '%s' for connectivity check.", priv->uri);
|
||||
g_free (priv->uri);
|
||||
priv->uri = NULL;
|
||||
if (!soup_uri || !SOUP_URI_VALID_FOR_HTTP (soup_uri)) {
|
||||
_LOGE ("invalid uri '%s' for connectivity check.", uri);
|
||||
uri = NULL;
|
||||
}
|
||||
if (uri)
|
||||
soup_uri_free (uri);
|
||||
if (soup_uri)
|
||||
soup_uri_free (soup_uri);
|
||||
}
|
||||
#endif
|
||||
if (g_strcmp0 (uri, priv->uri) != 0) {
|
||||
g_free (priv->uri);
|
||||
priv->uri = g_strdup (uri);
|
||||
_reschedule_periodic_checks (self, TRUE);
|
||||
}
|
||||
break;
|
||||
case PROP_INTERVAL:
|
||||
priv->interval = g_value_get_uint (value);
|
||||
interval = g_value_get_uint (value);
|
||||
if (priv->interval != interval) {
|
||||
priv->interval = interval;
|
||||
_reschedule_periodic_checks (self, TRUE);
|
||||
}
|
||||
break;
|
||||
case PROP_RESPONSE:
|
||||
g_free (priv->response);
|
||||
priv->response = get_non_empty_string_value (value);
|
||||
response = g_value_get_string (value);
|
||||
if (g_strcmp0 (response, priv->response) != 0) {
|
||||
/* a response %NULL means, DEFAULT_RESPONSE. Any other response
|
||||
* (including "") is accepted. */
|
||||
g_free (priv->response);
|
||||
priv->response = g_strdup (response);
|
||||
_reschedule_periodic_checks (self, TRUE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
@@ -363,7 +422,10 @@ get_property (GObject *object, guint property_id,
|
||||
g_value_set_uint (value, priv->interval);
|
||||
break;
|
||||
case PROP_RESPONSE:
|
||||
g_value_set_string (value, priv->response);
|
||||
if (priv->response)
|
||||
g_value_set_string (value, priv->response);
|
||||
else
|
||||
g_value_set_static_string (value, DEFAULT_RESPONSE);
|
||||
break;
|
||||
case PROP_STATE:
|
||||
g_value_set_uint (value, priv->state);
|
||||
@@ -378,11 +440,12 @@ get_property (GObject *object, guint property_id,
|
||||
static void
|
||||
nm_connectivity_init (NMConnectivity *self)
|
||||
{
|
||||
#if WITH_CONCHECK
|
||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
|
||||
#if WITH_CONCHECK
|
||||
priv->soup_session = soup_session_async_new_with_options (SOUP_SESSION_TIMEOUT, 15, NULL);
|
||||
#endif
|
||||
priv->state = NM_CONNECTIVITY_NONE;
|
||||
}
|
||||
|
||||
|
||||
@@ -392,8 +455,8 @@ dispose (GObject *object)
|
||||
NMConnectivity *self = NM_CONNECTIVITY (object);
|
||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
|
||||
g_free (priv->uri);
|
||||
g_free (priv->response);
|
||||
g_clear_pointer (&priv->uri, g_free);
|
||||
g_clear_pointer (&priv->response, g_free);
|
||||
|
||||
#if WITH_CONCHECK
|
||||
if (priv->soup_session) {
|
||||
@@ -422,31 +485,34 @@ nm_connectivity_class_init (NMConnectivityClass *klass)
|
||||
|
||||
/* properties */
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_URI,
|
||||
g_param_spec_string (NM_CONNECTIVITY_URI, "", "",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
(object_class, PROP_URI,
|
||||
g_param_spec_string (NM_CONNECTIVITY_URI, "", "",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_INTERVAL,
|
||||
g_param_spec_uint (NM_CONNECTIVITY_INTERVAL, "", "",
|
||||
0, G_MAXUINT, 300,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
(object_class, PROP_INTERVAL,
|
||||
g_param_spec_uint (NM_CONNECTIVITY_INTERVAL, "", "",
|
||||
0, G_MAXUINT, 300,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_RESPONSE,
|
||||
g_param_spec_string (NM_CONNECTIVITY_RESPONSE, "", "",
|
||||
DEFAULT_RESPONSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
(object_class, PROP_RESPONSE,
|
||||
g_param_spec_string (NM_CONNECTIVITY_RESPONSE, "", "",
|
||||
DEFAULT_RESPONSE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_STATE,
|
||||
g_param_spec_uint (NM_CONNECTIVITY_STATE, "", "",
|
||||
NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
(object_class, PROP_STATE,
|
||||
g_param_spec_uint (NM_CONNECTIVITY_STATE, "", "",
|
||||
NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
|
@@ -51,7 +51,11 @@ typedef struct {
|
||||
|
||||
GType nm_connectivity_get_type (void);
|
||||
|
||||
NMConnectivity *nm_connectivity_new (void);
|
||||
const char *nm_connectivity_state_to_string (NMConnectivityState state);
|
||||
|
||||
NMConnectivity *nm_connectivity_new (const char *uri,
|
||||
guint interval,
|
||||
const char *response);
|
||||
|
||||
void nm_connectivity_set_online (NMConnectivity *self,
|
||||
gboolean online);
|
||||
|
@@ -315,6 +315,7 @@ main (int argc, char *argv[])
|
||||
&argc,
|
||||
options,
|
||||
NULL,
|
||||
NULL,
|
||||
_("nm-iface-helper is a small, standalone process that manages a single network interface.")))
|
||||
exit (1);
|
||||
|
||||
@@ -480,6 +481,12 @@ main (int argc, char *argv[])
|
||||
/*******************************************************/
|
||||
/* Stub functions */
|
||||
|
||||
void
|
||||
nm_main_config_reload ()
|
||||
{
|
||||
nm_log_info (LOGD_CORE, "reloading configuration not supported");
|
||||
}
|
||||
|
||||
gconstpointer nm_config_get (void);
|
||||
const char *nm_config_get_dhcp_client (gpointer unused);
|
||||
gboolean nm_config_get_configure_and_quit (gpointer unused);
|
||||
|
@@ -167,6 +167,7 @@ typedef struct {
|
||||
|
||||
GSList *devices;
|
||||
NMState state;
|
||||
NMConfig *config;
|
||||
NMConnectivity *connectivity;
|
||||
|
||||
int ignore_link_added_cb;
|
||||
@@ -463,6 +464,18 @@ active_connection_get_by_path (NMManager *manager, const char *path)
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
_config_changed_cb (NMConfig *config, NMConfigData *config_data, NMConfigChangeFlags changes, NMConfigData *old_data, NMManager *self)
|
||||
{
|
||||
g_object_set (NM_MANAGER_GET_PRIVATE (self)->connectivity,
|
||||
NM_CONNECTIVITY_URI, nm_config_data_get_connectivity_uri (config_data),
|
||||
NM_CONNECTIVITY_INTERVAL, nm_config_data_get_connectivity_interval (config_data),
|
||||
NM_CONNECTIVITY_RESPONSE, nm_config_data_get_connectivity_response (config_data),
|
||||
NULL);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
static NMDevice *
|
||||
nm_manager_get_device_by_udi (NMManager *manager, const char *udi)
|
||||
{
|
||||
@@ -4274,12 +4287,9 @@ connectivity_changed (NMConnectivity *connectivity,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMManager *self = NM_MANAGER (user_data);
|
||||
NMConnectivityState state;
|
||||
static const char *connectivity_states[] = { "UNKNOWN", "NONE", "PORTAL", "LIMITED", "FULL" };
|
||||
|
||||
state = nm_connectivity_get_state (connectivity);
|
||||
nm_log_dbg (LOGD_CORE, "connectivity checking indicates %s",
|
||||
connectivity_states[state]);
|
||||
nm_connectivity_state_to_string (nm_connectivity_get_state (connectivity)));
|
||||
|
||||
nm_manager_update_state (self);
|
||||
g_object_notify (G_OBJECT (self), NM_MANAGER_CONNECTIVITY);
|
||||
@@ -4722,6 +4732,7 @@ nm_manager_new (NMSettings *settings,
|
||||
NMManagerPrivate *priv;
|
||||
DBusGConnection *bus;
|
||||
DBusConnection *dbus_connection;
|
||||
NMConfigData *config_data;
|
||||
|
||||
g_assert (settings);
|
||||
|
||||
@@ -4753,7 +4764,16 @@ nm_manager_new (NMSettings *settings,
|
||||
g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_DEVICE,
|
||||
G_CALLBACK (policy_activating_device_changed), singleton);
|
||||
|
||||
priv->connectivity = nm_connectivity_new ();
|
||||
priv->config = g_object_ref (nm_config_get ());
|
||||
g_signal_connect (G_OBJECT (priv->config),
|
||||
NM_CONFIG_SIGNAL_CONFIG_CHANGED,
|
||||
G_CALLBACK (_config_changed_cb),
|
||||
singleton);
|
||||
|
||||
config_data = nm_config_get_data (priv->config);
|
||||
priv->connectivity = nm_connectivity_new (nm_config_data_get_connectivity_uri (config_data),
|
||||
nm_config_data_get_connectivity_interval (config_data),
|
||||
nm_config_data_get_connectivity_response (config_data));
|
||||
g_signal_connect (priv->connectivity, "notify::" NM_CONNECTIVITY_STATE,
|
||||
G_CALLBACK (connectivity_changed), singleton);
|
||||
|
||||
@@ -5074,7 +5094,14 @@ dispose (GObject *object)
|
||||
g_clear_object (&priv->primary_connection);
|
||||
g_clear_object (&priv->activating_connection);
|
||||
|
||||
g_clear_object (&priv->connectivity);
|
||||
if (priv->config) {
|
||||
g_signal_handlers_disconnect_by_func (priv->config, _config_changed_cb, manager);
|
||||
g_clear_object (&priv->config);
|
||||
}
|
||||
if (priv->connectivity) {
|
||||
g_signal_handlers_disconnect_by_func (priv->connectivity, connectivity_changed, manager);
|
||||
g_clear_object (&priv->connectivity);
|
||||
}
|
||||
|
||||
g_free (priv->hostname);
|
||||
|
||||
|
@@ -26,6 +26,8 @@ typedef struct _NMActiveConnection NMActiveConnection;
|
||||
typedef struct _NMVpnConnection NMVpnConnection;
|
||||
typedef struct _NMActRequest NMActRequest;
|
||||
typedef struct _NMAuthSubject NMAuthSubject;
|
||||
typedef struct _NMConfig NMConfig;
|
||||
typedef struct _NMConfigData NMConfigData;
|
||||
typedef struct _NMConnectionProvider NMConnectionProvider;
|
||||
typedef struct _NMConnectivity NMConnectivity;
|
||||
typedef struct _NMDBusManager NMDBusManager;
|
||||
|
@@ -1669,7 +1669,7 @@ default_wired_clear_tag (NMSettings *self,
|
||||
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (default_wired_connection_updated_by_user_cb), self);
|
||||
|
||||
if (add_to_no_auto_default)
|
||||
nm_config_set_ethernet_no_auto_default (NM_SETTINGS_GET_PRIVATE (self)->config, device);
|
||||
nm_config_set_no_auto_default_for_device (NM_SETTINGS_GET_PRIVATE (self)->config, device);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -847,7 +847,7 @@ nm_system_config_factory (void)
|
||||
priv = SC_PLUGIN_EXAMPLE_GET_PRIVATE (singleton);
|
||||
|
||||
/* Cache the config file path */
|
||||
priv->conf_file = nm_config_get_path (nm_config_get ());
|
||||
priv->conf_file = nm_config_data_get_config_main_file (nm_config_get_data (nm_config_get ()));
|
||||
} else {
|
||||
/* This function should never be called twice */
|
||||
g_assert_not_reached ();
|
||||
|
@@ -123,9 +123,9 @@ is_managed_plugin (void)
|
||||
{
|
||||
char *result = NULL;
|
||||
|
||||
result = nm_config_get_value (nm_config_get (),
|
||||
IFNET_KEY_FILE_GROUP, IFNET_KEY_FILE_KEY_MANAGED,
|
||||
NULL);
|
||||
result = nm_config_data_get_value (nm_config_get_data_orig (nm_config_get ()),
|
||||
IFNET_KEY_FILE_GROUP, IFNET_KEY_FILE_KEY_MANAGED,
|
||||
NULL);
|
||||
if (result) {
|
||||
gboolean ret = is_true (result);
|
||||
g_free (result);
|
||||
@@ -264,9 +264,9 @@ reload_connections (NMSystemConfigInterface *config)
|
||||
|
||||
nm_log_info (LOGD_SETTINGS, "Loading connections");
|
||||
|
||||
str_auto_refresh = nm_config_get_value (nm_config_get (),
|
||||
IFNET_KEY_FILE_GROUP, "auto_refresh",
|
||||
NULL);
|
||||
str_auto_refresh = nm_config_data_get_value (nm_config_get_data_orig (nm_config_get ()),
|
||||
IFNET_KEY_FILE_GROUP, "auto_refresh",
|
||||
NULL);
|
||||
if (str_auto_refresh && is_true (str_auto_refresh))
|
||||
auto_refresh = TRUE;
|
||||
g_free (str_auto_refresh);
|
||||
|
@@ -456,12 +456,12 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config)
|
||||
g_hash_table_destroy (auto_ifaces);
|
||||
|
||||
/* Check the config file to find out whether to manage interfaces */
|
||||
value = nm_config_get_value (nm_config_get (),
|
||||
IFUPDOWN_KEY_FILE_GROUP, IFUPDOWN_KEY_FILE_KEY_MANAGED,
|
||||
&error);
|
||||
value = nm_config_data_get_value (nm_config_get_data_orig (nm_config_get ()),
|
||||
IFUPDOWN_KEY_FILE_GROUP, IFUPDOWN_KEY_FILE_KEY_MANAGED,
|
||||
&error);
|
||||
if (error) {
|
||||
nm_log_info (LOGD_SETTINGS, "loading system config file (%s) caused error: %s",
|
||||
nm_config_get_path (nm_config_get ()),
|
||||
nm_config_data_get_config_main_file (nm_config_get_data (nm_config_get ())),
|
||||
error->message);
|
||||
} else {
|
||||
gboolean manage_well_known;
|
||||
|
@@ -843,7 +843,7 @@ nm_settings_keyfile_plugin_new (void)
|
||||
singleton = SC_PLUGIN_KEYFILE (g_object_new (SC_TYPE_PLUGIN_KEYFILE, NULL));
|
||||
priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (singleton);
|
||||
|
||||
priv->conf_file = nm_config_get_path (nm_config_get ());
|
||||
priv->conf_file = nm_config_data_get_config_main_file (nm_config_get_data (nm_config_get ()));
|
||||
|
||||
/* plugin_set_hostname() has to be called *after* priv->conf_file is set */
|
||||
priv->hostname = plugin_get_hostname (singleton);
|
||||
|
@@ -27,9 +27,12 @@
|
||||
#include <nm-config.h>
|
||||
#include "nm-test-device.h"
|
||||
#include "nm-fake-platform.h"
|
||||
#include "nm-logging.h"
|
||||
|
||||
static void
|
||||
setup_config (const char *config_file, const char *config_dir, ...)
|
||||
#include "nm-test-utils.h"
|
||||
|
||||
static NMConfig *
|
||||
setup_config (GError **error, const char *config_file, const char *config_dir, ...)
|
||||
{
|
||||
va_list ap;
|
||||
GPtrArray *args;
|
||||
@@ -37,6 +40,11 @@ setup_config (const char *config_file, const char *config_dir, ...)
|
||||
int argc;
|
||||
GOptionContext *context;
|
||||
gboolean success;
|
||||
NMConfig *config;
|
||||
GError *local_error = NULL;
|
||||
NMConfigCmdLineOptions *cli;
|
||||
|
||||
g_assert (!error || !*error);
|
||||
|
||||
args = g_ptr_array_new ();
|
||||
g_ptr_array_add (args, "test-config");
|
||||
@@ -53,8 +61,10 @@ setup_config (const char *config_file, const char *config_dir, ...)
|
||||
argv = (char **)args->pdata;
|
||||
argc = args->len;
|
||||
|
||||
cli = nm_config_cmd_line_options_new ();
|
||||
|
||||
context = g_option_context_new (NULL);
|
||||
g_option_context_add_main_entries (context, nm_config_get_options (), NULL);
|
||||
nm_config_cmd_line_options_add_to_entries (cli, context);
|
||||
success = g_option_context_parse (context, &argc, &argv, NULL);
|
||||
g_option_context_free (context);
|
||||
|
||||
@@ -62,6 +72,18 @@ setup_config (const char *config_file, const char *config_dir, ...)
|
||||
g_printerr ("Invalid options.\n");
|
||||
|
||||
g_ptr_array_free (args, TRUE);
|
||||
|
||||
config = nm_config_setup (cli, &local_error);
|
||||
if (error) {
|
||||
g_assert (!config);
|
||||
g_assert (local_error);
|
||||
g_propagate_error (error, local_error);
|
||||
} else {
|
||||
g_assert (config);
|
||||
g_assert_no_error (local_error);
|
||||
}
|
||||
nm_config_cmd_line_options_free (cli);
|
||||
return config;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -72,14 +94,12 @@ test_config_simple (void)
|
||||
const char **plugins;
|
||||
char *value;
|
||||
|
||||
setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir", NULL);
|
||||
config = nm_config_new (&error);
|
||||
g_assert_no_error (error);
|
||||
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir", NULL);
|
||||
|
||||
g_assert_cmpstr (nm_config_get_path (config), ==, SRCDIR "/NetworkManager.conf");
|
||||
g_assert_cmpstr (nm_config_data_get_config_main_file (nm_config_get_data_orig (config)), ==, SRCDIR "/NetworkManager.conf");
|
||||
g_assert_cmpstr (nm_config_get_dhcp_client (config), ==, "dhclient");
|
||||
g_assert_cmpstr (nm_config_get_log_level (config), ==, "INFO");
|
||||
g_assert_cmpint (nm_config_get_connectivity_interval (config), ==, 100);
|
||||
g_assert_cmpint (nm_config_data_get_connectivity_interval (nm_config_get_data_orig (config)), ==, 100);
|
||||
|
||||
plugins = nm_config_get_plugins (config);
|
||||
g_assert_cmpint (g_strv_length ((char **)plugins), ==, 3);
|
||||
@@ -87,16 +107,16 @@ test_config_simple (void)
|
||||
g_assert_cmpstr (plugins[1], ==, "bar");
|
||||
g_assert_cmpstr (plugins[2], ==, "baz");
|
||||
|
||||
value = nm_config_get_value (config, "extra-section", "extra-key", NULL);
|
||||
value = nm_config_data_get_value (nm_config_get_data_orig (config), "extra-section", "extra-key", NULL);
|
||||
g_assert_cmpstr (value, ==, "some value");
|
||||
g_free (value);
|
||||
|
||||
value = nm_config_get_value (config, "extra-section", "no-key", &error);
|
||||
value = nm_config_data_get_value (nm_config_get_data_orig (config), "extra-section", "no-key", &error);
|
||||
g_assert (!value);
|
||||
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
|
||||
g_clear_error (&error);
|
||||
|
||||
value = nm_config_get_value (config, "no-section", "no-key", &error);
|
||||
value = nm_config_data_get_value (nm_config_get_data_orig (config), "no-section", "no-key", &error);
|
||||
g_assert (!value);
|
||||
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
|
||||
g_clear_error (&error);
|
||||
@@ -107,45 +127,38 @@ test_config_simple (void)
|
||||
static void
|
||||
test_config_non_existent (void)
|
||||
{
|
||||
NMConfig *config;
|
||||
GError *error = NULL;
|
||||
|
||||
setup_config (SRCDIR "/no-such-file", "/no/such/dir", NULL);
|
||||
config = nm_config_new (&error);
|
||||
g_assert (!config);
|
||||
setup_config (&error, SRCDIR "/no-such-file", "/no/such/dir", NULL);
|
||||
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
static void
|
||||
test_config_parse_error (void)
|
||||
{
|
||||
NMConfig *config;
|
||||
GError *error = NULL;
|
||||
|
||||
setup_config (SRCDIR "/bad.conf", "/no/such/dir", NULL);
|
||||
config = nm_config_new (&error);
|
||||
g_assert (!config);
|
||||
setup_config (&error, SRCDIR "/bad.conf", "/no/such/dir", NULL);
|
||||
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
static void
|
||||
test_config_override (void)
|
||||
{
|
||||
NMConfig *config;
|
||||
GError *error = NULL;
|
||||
const char **plugins;
|
||||
|
||||
setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir",
|
||||
"--plugins", "alpha,beta,gamma,delta",
|
||||
"--connectivity-interval", "12",
|
||||
NULL);
|
||||
config = nm_config_new (&error);
|
||||
g_assert_no_error (error);
|
||||
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir",
|
||||
"--plugins", "alpha,beta,gamma,delta",
|
||||
"--connectivity-interval", "12",
|
||||
NULL);
|
||||
|
||||
g_assert_cmpstr (nm_config_get_path (config), ==, SRCDIR "/NetworkManager.conf");
|
||||
g_assert_cmpstr (nm_config_data_get_config_main_file (nm_config_get_data_orig (config)), ==, SRCDIR "/NetworkManager.conf");
|
||||
g_assert_cmpstr (nm_config_get_dhcp_client (config), ==, "dhclient");
|
||||
g_assert_cmpstr (nm_config_get_log_level (config), ==, "INFO");
|
||||
g_assert_cmpint (nm_config_get_connectivity_interval (config), ==, 12);
|
||||
g_assert_cmpint (nm_config_data_get_connectivity_interval (nm_config_get_data_orig (config)), ==, 12);
|
||||
|
||||
plugins = nm_config_get_plugins (config);
|
||||
g_assert_cmpint (g_strv_length ((char **)plugins), ==, 4);
|
||||
@@ -175,37 +188,36 @@ test_config_no_auto_default (void)
|
||||
g_assert_cmpint (nwrote, ==, 18);
|
||||
close (fd);
|
||||
|
||||
setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir",
|
||||
"--no-auto-default", state_file,
|
||||
NULL);
|
||||
config = nm_config_new (&error);
|
||||
g_assert_no_error (error);
|
||||
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir",
|
||||
"--no-auto-default", state_file,
|
||||
NULL);
|
||||
|
||||
dev1 = nm_test_device_new ("11:11:11:11:11:11");
|
||||
dev2 = nm_test_device_new ("22:22:22:22:22:22");
|
||||
dev3 = nm_test_device_new ("33:33:33:33:33:33");
|
||||
dev4 = nm_test_device_new ("44:44:44:44:44:44");
|
||||
|
||||
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev1));
|
||||
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev2));
|
||||
g_assert (nm_config_get_ethernet_can_auto_default (config, dev3));
|
||||
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev4));
|
||||
g_assert (nm_config_get_no_auto_default_for_device (config, dev1));
|
||||
g_assert (nm_config_get_no_auto_default_for_device (config, dev2));
|
||||
g_assert (!nm_config_get_no_auto_default_for_device (config, dev3));
|
||||
g_assert (nm_config_get_no_auto_default_for_device (config, dev4));
|
||||
|
||||
nm_config_set_ethernet_no_auto_default (config, dev3);
|
||||
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev3));
|
||||
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*config: update * (no-auto-default)*");
|
||||
nm_config_set_no_auto_default_for_device (config, dev3);
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
g_assert (nm_config_get_no_auto_default_for_device (config, dev3));
|
||||
|
||||
g_object_unref (config);
|
||||
|
||||
setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir",
|
||||
"--no-auto-default", state_file,
|
||||
NULL);
|
||||
config = nm_config_new (&error);
|
||||
g_assert_no_error (error);
|
||||
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir",
|
||||
"--no-auto-default", state_file,
|
||||
NULL);
|
||||
|
||||
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev1));
|
||||
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev2));
|
||||
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev3));
|
||||
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev4));
|
||||
g_assert (nm_config_get_no_auto_default_for_device (config, dev1));
|
||||
g_assert (nm_config_get_no_auto_default_for_device (config, dev2));
|
||||
g_assert (nm_config_get_no_auto_default_for_device (config, dev3));
|
||||
g_assert (nm_config_get_no_auto_default_for_device (config, dev4));
|
||||
|
||||
g_object_unref (config);
|
||||
|
||||
@@ -222,20 +234,17 @@ static void
|
||||
test_config_confdir (void)
|
||||
{
|
||||
NMConfig *config;
|
||||
GError *error = NULL;
|
||||
const char **plugins;
|
||||
char *value;
|
||||
|
||||
setup_config (SRCDIR "/NetworkManager.conf", SRCDIR "/conf.d", NULL);
|
||||
config = nm_config_new (&error);
|
||||
g_assert_no_error (error);
|
||||
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", SRCDIR "/conf.d", NULL);
|
||||
|
||||
g_assert_cmpstr (nm_config_get_path (config), ==, SRCDIR "/NetworkManager.conf");
|
||||
g_assert_cmpstr (nm_config_data_get_config_main_file (nm_config_get_data_orig (config)), ==, SRCDIR "/NetworkManager.conf");
|
||||
g_assert_cmpstr (nm_config_get_dhcp_client (config), ==, "dhcpcd");
|
||||
g_assert_cmpstr (nm_config_get_log_level (config), ==, "INFO");
|
||||
g_assert_cmpstr (nm_config_get_log_domains (config), ==, "PLATFORM,DNS,WIFI");
|
||||
g_assert_cmpstr (nm_config_get_connectivity_uri (config), ==, "http://example.net");
|
||||
g_assert_cmpint (nm_config_get_connectivity_interval (config), ==, 100);
|
||||
g_assert_cmpstr (nm_config_data_get_connectivity_uri (nm_config_get_data_orig (config)), ==, "http://example.net");
|
||||
g_assert_cmpint (nm_config_data_get_connectivity_interval (nm_config_get_data_orig (config)), ==, 100);
|
||||
|
||||
plugins = nm_config_get_plugins (config);
|
||||
g_assert_cmpint (g_strv_length ((char **)plugins), ==, 5);
|
||||
@@ -245,21 +254,21 @@ test_config_confdir (void)
|
||||
g_assert_cmpstr (plugins[3], ==, "one");
|
||||
g_assert_cmpstr (plugins[4], ==, "two");
|
||||
|
||||
value = nm_config_get_value (config, "main", "extra", NULL);
|
||||
value = nm_config_data_get_value (nm_config_get_data_orig (config), "main", "extra", NULL);
|
||||
g_assert_cmpstr (value, ==, "hello");
|
||||
g_free (value);
|
||||
|
||||
value = nm_config_get_value (config, "main", "new", NULL);
|
||||
value = nm_config_data_get_value (nm_config_get_data_orig (config), "main", "new", NULL);
|
||||
g_assert_cmpstr (value, ==, "something"); /* not ",something" */
|
||||
g_free (value);
|
||||
|
||||
value = nm_config_get_value (config, "order", "a", NULL);
|
||||
value = nm_config_data_get_value (nm_config_get_data_orig (config), "order", "a", NULL);
|
||||
g_assert_cmpstr (value, ==, "90");
|
||||
g_free (value);
|
||||
value = nm_config_get_value (config, "order", "b", NULL);
|
||||
value = nm_config_data_get_value (nm_config_get_data_orig (config), "order", "b", NULL);
|
||||
g_assert_cmpstr (value, ==, "10");
|
||||
g_free (value);
|
||||
value = nm_config_get_value (config, "order", "c", NULL);
|
||||
value = nm_config_data_get_value (nm_config_get_data_orig (config), "order", "c", NULL);
|
||||
g_assert_cmpstr (value, ==, "0");
|
||||
g_free (value);
|
||||
|
||||
@@ -269,24 +278,20 @@ test_config_confdir (void)
|
||||
static void
|
||||
test_config_confdir_parse_error (void)
|
||||
{
|
||||
NMConfig *config;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Using SRCDIR as the conf dir will pick up bad.conf */
|
||||
setup_config (SRCDIR "/NetworkManager.conf", SRCDIR, NULL);
|
||||
config = nm_config_new (&error);
|
||||
g_assert (!config);
|
||||
setup_config (&error, SRCDIR "/NetworkManager.conf", SRCDIR, NULL);
|
||||
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
NMTST_DEFINE ();
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
#if !GLIB_CHECK_VERSION (2, 35, 0)
|
||||
g_type_init ();
|
||||
#endif
|
||||
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
nmtst_init_assert_logging (&argc, &argv);
|
||||
|
||||
nm_fake_platform_setup ();
|
||||
|
||||
|
Reference in New Issue
Block a user