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-active-connection.h \
|
||||||
nm-config.c \
|
nm-config.c \
|
||||||
nm-config.h \
|
nm-config.h \
|
||||||
|
nm-config-data.c \
|
||||||
|
nm-config-data.h \
|
||||||
nm-connection-provider.c \
|
nm-connection-provider.c \
|
||||||
nm-connection-provider.h \
|
nm-connection-provider.h \
|
||||||
nm-connectivity.c \
|
nm-connectivity.c \
|
||||||
|
@@ -1463,7 +1463,7 @@ new_default_connection (NMDevice *self)
|
|||||||
const char *hw_address;
|
const char *hw_address;
|
||||||
char *defname, *uuid;
|
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;
|
return NULL;
|
||||||
|
|
||||||
hw_address = nm_device_get_hw_address (self);
|
hw_address = nm_device_get_hw_address (self);
|
||||||
|
@@ -40,9 +40,7 @@
|
|||||||
static gboolean
|
static gboolean
|
||||||
sighup_handler (gpointer user_data)
|
sighup_handler (gpointer user_data)
|
||||||
{
|
{
|
||||||
/* Reread config stuff like system config files, VPN service files, etc */
|
nm_main_config_reload ();
|
||||||
nm_log_info (LOGD_CORE, "caught SIGHUP, not supported yet.");
|
|
||||||
|
|
||||||
return G_SOURCE_CONTINUE;
|
return G_SOURCE_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +175,8 @@ nm_main_utils_early_setup (const char *progname,
|
|||||||
char **argv[],
|
char **argv[],
|
||||||
int *argc,
|
int *argc,
|
||||||
GOptionEntry *options,
|
GOptionEntry *options,
|
||||||
GOptionEntry *more_options,
|
void (*option_context_hook) (gpointer user_data, GOptionContext *opt_ctx),
|
||||||
|
gpointer option_context_hook_data,
|
||||||
const char *summary)
|
const char *summary)
|
||||||
{
|
{
|
||||||
GOptionContext *opt_ctx = NULL;
|
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_ignore_unknown_options (opt_ctx, FALSE);
|
||||||
g_option_context_set_help_enabled (opt_ctx, TRUE);
|
g_option_context_set_help_enabled (opt_ctx, TRUE);
|
||||||
g_option_context_add_main_entries (opt_ctx, options, NULL);
|
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);
|
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);
|
success = g_option_context_parse (opt_ctx, argc, argv, &error);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
@@ -33,7 +33,13 @@ gboolean nm_main_utils_early_setup (const char *progname,
|
|||||||
char **argv[],
|
char **argv[],
|
||||||
int *argc,
|
int *argc,
|
||||||
GOptionEntry *options,
|
GOptionEntry *options,
|
||||||
GOptionEntry *more_options,
|
void (*option_context_hook) (gpointer user_data, GOptionContext *opt_ctx),
|
||||||
|
gpointer option_context_hook_data,
|
||||||
const char *summary);
|
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__ */
|
#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
|
static void
|
||||||
manager_configure_quit (NMManager *manager, gpointer user_data)
|
manager_configure_quit (NMManager *manager, gpointer user_data)
|
||||||
{
|
{
|
||||||
@@ -204,6 +217,7 @@ main (int argc, char *argv[])
|
|||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
gboolean wrote_pidfile = FALSE;
|
gboolean wrote_pidfile = FALSE;
|
||||||
char *bad_domains = NULL;
|
char *bad_domains = NULL;
|
||||||
|
NMConfigCmdLineOptions *config_cli;
|
||||||
|
|
||||||
GOptionEntry options[] = {
|
GOptionEntry options[] = {
|
||||||
{ "version", 'V', 0, G_OPTION_ARG_NONE, &show_version, N_("Print NetworkManager version and exit"), NULL },
|
{ "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);
|
main_loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
|
config_cli = nm_config_cmd_line_options_new ();
|
||||||
if (!nm_main_utils_early_setup ("NetworkManager",
|
if (!nm_main_utils_early_setup ("NetworkManager",
|
||||||
&argv,
|
&argv,
|
||||||
&argc,
|
&argc,
|
||||||
options,
|
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.")))
|
_("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);
|
exit (1);
|
||||||
|
|
||||||
@@ -290,7 +306,9 @@ main (int argc, char *argv[])
|
|||||||
exit (1);
|
exit (1);
|
||||||
|
|
||||||
/* Read the config file and CLI overrides */
|
/* 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) {
|
if (config == NULL) {
|
||||||
fprintf (stderr, _("Failed to read configuration: (%d) %s\n"),
|
fprintf (stderr, _("Failed to read configuration: (%d) %s\n"),
|
||||||
error ? error->code : -1,
|
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...");
|
nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting...");
|
||||||
success = FALSE;
|
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",
|
nm_log_info (LOGD_CORE, "WEXT support is %s",
|
||||||
#if HAVE_WEXT
|
#if HAVE_WEXT
|
||||||
"enabled"
|
"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 */
|
||||||
|
|
703
src/nm-config.c
703
src/nm-config.c
@@ -29,6 +29,9 @@
|
|||||||
#include "nm-utils.h"
|
#include "nm-utils.h"
|
||||||
#include "nm-glib-compat.h"
|
#include "nm-glib-compat.h"
|
||||||
#include "nm-device.h"
|
#include "nm-device.h"
|
||||||
|
#include "NetworkManagerUtils.h"
|
||||||
|
#include "gsystem-local-alloc.h"
|
||||||
|
#include "nm-enum-types.h"
|
||||||
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
@@ -38,12 +41,28 @@
|
|||||||
#define NM_OLD_SYSTEM_CONF_FILE NMCONFDIR "/nm-system-settings.conf"
|
#define NM_OLD_SYSTEM_CONF_FILE NMCONFDIR "/nm-system-settings.conf"
|
||||||
#define NM_NO_AUTO_DEFAULT_STATE_FILE NMSTATEDIR "/no-auto-default.state"
|
#define NM_NO_AUTO_DEFAULT_STATE_FILE NMSTATEDIR "/no-auto-default.state"
|
||||||
|
|
||||||
typedef struct {
|
struct NMConfigCmdLineOptions {
|
||||||
char *nm_conf_path;
|
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_dir;
|
||||||
char *config_description;
|
|
||||||
char *no_auto_default_file;
|
char *no_auto_default_file;
|
||||||
GKeyFile *keyfile;
|
|
||||||
|
|
||||||
char **plugins;
|
char **plugins;
|
||||||
gboolean monitor_connection_files;
|
gboolean monitor_connection_files;
|
||||||
@@ -56,24 +75,40 @@ typedef struct {
|
|||||||
|
|
||||||
char *debug;
|
char *debug;
|
||||||
|
|
||||||
char *connectivity_uri;
|
|
||||||
gint connectivity_interval;
|
|
||||||
char *connectivity_response;
|
|
||||||
|
|
||||||
char **no_auto_default;
|
|
||||||
char **ignore_carrier;
|
char **ignore_carrier;
|
||||||
|
|
||||||
gboolean configure_and_quit;
|
gboolean configure_and_quit;
|
||||||
} NMConfigPrivate;
|
} 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))
|
#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
|
static gboolean
|
||||||
_get_bool_value (GKeyFile *keyfile,
|
_get_bool_value (GKeyFile *keyfile,
|
||||||
const char *section,
|
const char *section,
|
||||||
@@ -109,20 +144,23 @@ _get_bool_value (GKeyFile *keyfile,
|
|||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
const char *
|
NMConfigData *
|
||||||
nm_config_get_path (NMConfig *config)
|
nm_config_get_data (NMConfig *config)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (config != NULL, NULL);
|
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 *
|
/* The NMConfigData instance is reloadable and will be swapped on reload.
|
||||||
nm_config_get_description (NMConfig *config)
|
* 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);
|
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 **
|
const char **
|
||||||
@@ -189,47 +227,12 @@ nm_config_get_debug (NMConfig *config)
|
|||||||
return NM_CONFIG_GET_PRIVATE (config)->debug;
|
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
|
gboolean
|
||||||
nm_config_get_configure_and_quit (NMConfig *config)
|
nm_config_get_configure_and_quit (NMConfig *config)
|
||||||
{
|
{
|
||||||
return NM_CONFIG_GET_PRIVATE (config)->configure_and_quit;
|
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
|
gboolean
|
||||||
nm_config_get_ignore_carrier (NMConfig *config, NMDevice *device)
|
nm_config_get_ignore_carrier (NMConfig *config, NMDevice *device)
|
||||||
{
|
{
|
||||||
@@ -252,72 +255,71 @@ nm_config_get_ignore_carrier (NMConfig *config, NMDevice *device)
|
|||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
static void
|
static char **
|
||||||
merge_no_auto_default_state (NMConfig *config)
|
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;
|
GPtrArray *updated;
|
||||||
char **list;
|
char **list;
|
||||||
int i, j;
|
int i, j;
|
||||||
char *data;
|
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 ();
|
updated = g_ptr_array_new ();
|
||||||
if (priv->no_auto_default) {
|
if (no_auto_default) {
|
||||||
for (i = 0; priv->no_auto_default[i]; i++)
|
for (i = 0; no_auto_default[i]; i++)
|
||||||
g_ptr_array_add (updated, priv->no_auto_default[i]);
|
g_ptr_array_add (updated, g_strdup (no_auto_default[i]));
|
||||||
g_free (priv->no_auto_default);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
list = g_strsplit (data, "\n", -1);
|
||||||
for (i = 0; list[i]; i++) {
|
for (i = 0; list[i]; i++) {
|
||||||
if (!*list[i])
|
if (!*list[i])
|
||||||
continue;
|
g_free (list[i]);
|
||||||
|
else {
|
||||||
for (j = 0; j < updated->len; j++) {
|
for (j = 0; j < updated->len; j++) {
|
||||||
if (!strcmp (list[i], updated->pdata[j]))
|
if (!strcmp (list[i], updated->pdata[j]))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (j == updated->len)
|
if (j == updated->len)
|
||||||
g_ptr_array_add (updated, list[i]);
|
g_ptr_array_add (updated, list[i]);
|
||||||
|
else
|
||||||
|
g_free (list[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g_free (list);
|
g_free (list);
|
||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_ptr_array_add (updated, NULL);
|
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
|
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);
|
NMConfigData *config_data;
|
||||||
GSList *specs = NULL;
|
|
||||||
int i;
|
|
||||||
gboolean match;
|
|
||||||
|
|
||||||
for (i = 0; priv->no_auto_default[i]; i++)
|
g_return_val_if_fail (NM_IS_CONFIG (self), FALSE);
|
||||||
specs = g_slist_prepend (specs, priv->no_auto_default[i]);
|
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
|
||||||
|
|
||||||
match = nm_device_spec_match_list (device, specs);
|
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));
|
||||||
g_slist_free (specs);
|
|
||||||
return !match;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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;
|
char *current;
|
||||||
GString *updated;
|
GString *updated;
|
||||||
GError *error = NULL;
|
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;
|
return;
|
||||||
|
|
||||||
updated = g_string_new (NULL);
|
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);
|
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 void
|
||||||
static char *cli_config_dir;
|
_nm_config_cmd_line_options_clear (NMConfigCmdLineOptions *cli)
|
||||||
static char *cli_no_auto_default_file;
|
{
|
||||||
static char *cli_plugins;
|
g_clear_pointer (&cli->config_main_file, g_free);
|
||||||
static char *cli_connectivity_uri;
|
g_clear_pointer (&cli->config_dir, g_free);
|
||||||
static int cli_connectivity_interval = -1;
|
g_clear_pointer (&cli->no_auto_default_file, g_free);
|
||||||
static char *cli_connectivity_response;
|
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 GOptionEntry config_options[] = {
|
static void
|
||||||
{ "config", 0, 0, G_OPTION_ARG_FILENAME, &cli_config_path, N_("Config file location"), N_("/path/to/config.file") },
|
_nm_config_cmd_line_options_copy (const NMConfigCmdLineOptions *cli, NMConfigCmdLineOptions *dst)
|
||||||
{ "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 },
|
g_return_if_fail (cli);
|
||||||
{ "plugins", 0, 0, G_OPTION_ARG_STRING, &cli_plugins, N_("List of plugins separated by ','"), N_("plugin1,plugin2") },
|
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. */
|
/* 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-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-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!") },
|
{ "connectivity-response", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &cli->connectivity_response, N_("The expected start of the response"), N_("Bingo!") },
|
||||||
{NULL}
|
{ 0 },
|
||||||
};
|
};
|
||||||
GOptionEntry *
|
|
||||||
nm_config_get_options (void)
|
g_option_context_add_main_entries (opt_ctx, config_options, NULL);
|
||||||
{
|
}
|
||||||
return config_options;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
static gboolean
|
GKeyFile *
|
||||||
read_config (NMConfig *config, const char *path, GError **error)
|
nm_config_create_keyfile ()
|
||||||
|
{
|
||||||
|
GKeyFile *keyfile;
|
||||||
|
|
||||||
|
keyfile = g_key_file_new ();
|
||||||
|
g_key_file_set_list_separator (keyfile, ',');
|
||||||
|
return keyfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
read_config (GKeyFile *keyfile, const char *path, GError **error)
|
||||||
{
|
{
|
||||||
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config);
|
|
||||||
GKeyFile *kf;
|
GKeyFile *kf;
|
||||||
char **groups, **keys;
|
char **groups, **keys;
|
||||||
gsize ngroups, nkeys;
|
gsize ngroups, nkeys;
|
||||||
int g, k;
|
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) {
|
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);
|
g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND, "file %s not found", path);
|
||||||
return FALSE;
|
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);
|
nm_log_dbg (LOGD_SETTINGS, "Reading config file '%s'", path);
|
||||||
|
|
||||||
kf = g_key_file_new ();
|
kf = nm_config_create_keyfile ();
|
||||||
g_key_file_set_list_separator (kf, ',');
|
|
||||||
if (!g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, error)) {
|
if (!g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, error)) {
|
||||||
g_key_file_free (kf);
|
g_key_file_free (kf);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -407,22 +471,22 @@ read_config (NMConfig *config, const char *path, GError **error)
|
|||||||
|
|
||||||
if (keys[k][len - 1] == '+') {
|
if (keys[k][len - 1] == '+') {
|
||||||
char *base_key = g_strndup (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);
|
const char *new_val = g_key_file_get_value (kf, groups[g], keys[k], NULL);
|
||||||
|
|
||||||
if (old_val && *old_val) {
|
if (old_val && *old_val) {
|
||||||
char *combined = g_strconcat (old_val, ",", new_val, NULL);
|
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);
|
g_free (combined);
|
||||||
} else
|
} 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);
|
g_free (base_key);
|
||||||
continue;
|
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));
|
v = g_key_file_get_value (kf, groups[g], keys[k], NULL));
|
||||||
g_free (v);
|
g_free (v);
|
||||||
}
|
}
|
||||||
@@ -435,16 +499,22 @@ read_config (NMConfig *config, const char *path, GError **error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
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;
|
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 */
|
/* 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 */
|
/* Bad user-specific config file path is a hard error */
|
||||||
if (read_config (config, cli_config_path, error)) {
|
if (read_config (keyfile, cli_config_main_file, error)) {
|
||||||
priv->nm_conf_path = g_strdup (cli_config_path);
|
*out_config_main_file = g_strdup (cli_config_main_file);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} else
|
} else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -458,8 +528,8 @@ find_base_config (NMConfig *config, GError **error)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Try deprecated nm-system-settings.conf first */
|
/* Try deprecated nm-system-settings.conf first */
|
||||||
if (read_config (config, NM_OLD_SYSTEM_CONF_FILE, &my_error)) {
|
if (read_config (keyfile, NM_OLD_SYSTEM_CONF_FILE, &my_error)) {
|
||||||
priv->nm_conf_path = g_strdup (NM_OLD_SYSTEM_CONF_FILE);
|
*out_config_main_file = g_strdup (NM_OLD_SYSTEM_CONF_FILE);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,8 +541,8 @@ find_base_config (NMConfig *config, GError **error)
|
|||||||
g_clear_error (&my_error);
|
g_clear_error (&my_error);
|
||||||
|
|
||||||
/* Try the standard config file location next */
|
/* Try the standard config file location next */
|
||||||
if (read_config (config, NM_DEFAULT_SYSTEM_CONF_FILE, &my_error)) {
|
if (read_config (keyfile, NM_DEFAULT_SYSTEM_CONF_FILE, &my_error)) {
|
||||||
priv->nm_conf_path = g_strdup (NM_DEFAULT_SYSTEM_CONF_FILE);
|
*out_config_main_file = g_strdup (NM_DEFAULT_SYSTEM_CONF_FILE);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,21 +558,12 @@ find_base_config (NMConfig *config, GError **error)
|
|||||||
/* If for some reason no config file exists, use the default
|
/* If for some reason no config file exists, use the default
|
||||||
* config file path.
|
* 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_log_info (LOGD_CORE, "No config file found or given; using %s\n",
|
||||||
NM_DEFAULT_SYSTEM_CONF_FILE);
|
NM_DEFAULT_SYSTEM_CONF_FILE);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
|
|
||||||
NMConfig *
|
|
||||||
nm_config_get (void)
|
|
||||||
{
|
|
||||||
g_assert (singleton);
|
|
||||||
return singleton;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sort_asciibetically (gconstpointer a, gconstpointer b)
|
sort_asciibetically (gconstpointer a, gconstpointer b)
|
||||||
{
|
{
|
||||||
@@ -512,45 +573,31 @@ sort_asciibetically (gconstpointer a, gconstpointer b)
|
|||||||
return strcmp (s1, s2);
|
return strcmp (s1, s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* call this function only once! */
|
static GPtrArray *
|
||||||
NMConfig *
|
_get_config_dir_files (const char *config_main_file,
|
||||||
nm_config_new (GError **error)
|
const char *config_dir,
|
||||||
|
char **out_config_description)
|
||||||
{
|
{
|
||||||
NMConfigPrivate *priv = NULL;
|
|
||||||
GFile *dir;
|
GFile *dir;
|
||||||
GFileEnumerator *direnum;
|
GFileEnumerator *direnum;
|
||||||
GFileInfo *info;
|
GFileInfo *info;
|
||||||
GPtrArray *confs;
|
GPtrArray *confs;
|
||||||
const char *name;
|
|
||||||
int i;
|
|
||||||
GString *config_description;
|
GString *config_description;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
g_assert (!singleton);
|
g_return_val_if_fail (config_main_file, NULL);
|
||||||
singleton = NM_CONFIG (g_object_new (NM_TYPE_CONFIG, NULL));
|
g_return_val_if_fail (config_dir, NULL);
|
||||||
priv = NM_CONFIG_GET_PRIVATE (singleton);
|
g_return_val_if_fail (out_config_description && !*out_config_description, NULL);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
confs = g_ptr_array_new_with_free_func (g_free);
|
confs = g_ptr_array_new_with_free_func (g_free);
|
||||||
config_description = g_string_new (priv->nm_conf_path);
|
config_description = g_string_new (config_main_file);
|
||||||
dir = g_file_new_for_path (priv->config_dir);
|
dir = g_file_new_for_path (config_dir);
|
||||||
direnum = g_file_enumerate_children (dir, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, NULL);
|
direnum = g_file_enumerate_children (dir, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, NULL);
|
||||||
if (direnum) {
|
if (direnum) {
|
||||||
while ((info = g_file_enumerator_next_file (direnum, NULL, NULL))) {
|
while ((info = g_file_enumerator_next_file (direnum, NULL, NULL))) {
|
||||||
name = g_file_info_get_name (info);
|
name = g_file_info_get_name (info);
|
||||||
if (g_str_has_suffix (name, ".conf")) {
|
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)
|
if (confs->len == 1)
|
||||||
g_string_append (config_description, " and conf.d: ");
|
g_string_append (config_description, " and conf.d: ");
|
||||||
else
|
else
|
||||||
@@ -564,62 +611,273 @@ nm_config_new (GError **error)
|
|||||||
g_object_unref (dir);
|
g_object_unref (dir);
|
||||||
|
|
||||||
g_ptr_array_sort (confs, sort_asciibetically);
|
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++) {
|
for (i = 0; i < confs->len; i++) {
|
||||||
if (!read_config (singleton, confs->pdata[i], error)) {
|
if (!read_config (keyfile, confs->pdata[i], error)) {
|
||||||
g_object_unref (singleton);
|
g_key_file_free (keyfile);
|
||||||
singleton = NULL;
|
g_free (o_config_main_file);
|
||||||
break;
|
g_free (o_config_description);
|
||||||
|
g_ptr_array_unref (confs);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_ptr_array_unref (confs);
|
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;
|
return FALSE;
|
||||||
|
|
||||||
/* Handle no-auto-default key and state file */
|
/* Initialize read only private members */
|
||||||
priv->no_auto_default = g_key_file_get_string_list (priv->keyfile, "main", "no-auto-default", NULL, NULL);
|
|
||||||
if (cli_no_auto_default_file)
|
if (priv->cli.no_auto_default_file)
|
||||||
priv->no_auto_default_file = g_strdup (cli_no_auto_default_file);
|
priv->no_auto_default_file = g_strdup (priv->cli.no_auto_default_file);
|
||||||
else
|
else
|
||||||
priv->no_auto_default_file = g_strdup (NM_NO_AUTO_DEFAULT_STATE_FILE);
|
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. */
|
priv->plugins = g_key_file_get_string_list (keyfile, "main", "plugins", NULL, NULL);
|
||||||
if (cli_plugins && cli_plugins[0])
|
if (!priv->plugins)
|
||||||
g_key_file_set_value (priv->keyfile, "main", "plugins", cli_plugins);
|
priv->plugins = g_new0 (char *, 1);
|
||||||
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->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->dhcp_client = g_key_file_get_value (keyfile, "main", "dhcp", NULL);
|
||||||
priv->dns_mode = g_key_file_get_value (priv->keyfile, "main", "dns", 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_level = g_key_file_get_value (keyfile, "logging", "level", NULL);
|
||||||
priv->log_domains = g_key_file_get_value (priv->keyfile, "logging", "domains", 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])
|
priv->ignore_carrier = g_key_file_get_string_list (keyfile, "main", "ignore-carrier", NULL, NULL);
|
||||||
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);
|
|
||||||
|
|
||||||
if (cli_connectivity_interval >= 0)
|
priv->configure_and_quit = _get_bool_value (keyfile, "main", "configure-and-quit", FALSE);
|
||||||
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);
|
|
||||||
|
|
||||||
if (cli_connectivity_response && cli_connectivity_response[0])
|
no_auto_default_orig = g_key_file_get_string_list (keyfile, "main", "no-auto-default", NULL, NULL);
|
||||||
g_key_file_set_value (priv->keyfile, "connectivity", "response", cli_connectivity_response);
|
no_auto_default = no_auto_default_merge_from_file (priv->no_auto_default_file, (const char *const *) no_auto_default_orig);
|
||||||
priv->connectivity_response = g_key_file_get_value (priv->keyfile, "connectivity", "response", NULL);
|
|
||||||
|
|
||||||
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
|
static void
|
||||||
@@ -628,11 +886,6 @@ nm_config_init (NMConfig *config)
|
|||||||
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config);
|
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config);
|
||||||
|
|
||||||
priv->auth_polkit = NM_CONFIG_DEFAULT_AUTH_POLKIT;
|
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
|
static void
|
||||||
@@ -640,34 +893,46 @@ finalize (GObject *gobject)
|
|||||||
{
|
{
|
||||||
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (gobject);
|
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (gobject);
|
||||||
|
|
||||||
g_free (priv->nm_conf_path);
|
|
||||||
g_free (priv->config_dir);
|
g_free (priv->config_dir);
|
||||||
g_free (priv->config_description);
|
|
||||||
g_free (priv->no_auto_default_file);
|
g_free (priv->no_auto_default_file);
|
||||||
g_clear_pointer (&priv->keyfile, g_key_file_unref);
|
|
||||||
g_strfreev (priv->plugins);
|
g_strfreev (priv->plugins);
|
||||||
g_free (priv->dhcp_client);
|
g_free (priv->dhcp_client);
|
||||||
g_free (priv->dns_mode);
|
g_free (priv->dns_mode);
|
||||||
g_free (priv->log_level);
|
g_free (priv->log_level);
|
||||||
g_free (priv->log_domains);
|
g_free (priv->log_domains);
|
||||||
g_free (priv->debug);
|
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);
|
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_object (&priv->config_data);
|
||||||
g_clear_pointer (&cli_config_dir, g_free);
|
g_clear_object (&priv->config_data_orig);
|
||||||
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_OBJECT_CLASS (nm_config_parent_class)->finalize (gobject);
|
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
|
static void
|
||||||
nm_config_class_init (NMConfigClass *config_class)
|
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));
|
g_type_class_add_private (config_class, sizeof (NMConfigPrivate));
|
||||||
object_class->finalize = finalize;
|
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 <glib-object.h>
|
||||||
|
|
||||||
#include "nm-types.h"
|
#include "nm-types.h"
|
||||||
|
#include "nm-config-data.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
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_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))
|
#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;
|
GObject parent;
|
||||||
} NMConfig;
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GObjectClass parent;
|
GObjectClass parent;
|
||||||
|
|
||||||
|
/* Signals */
|
||||||
|
void (*config_changed) (NMConfig *config, GHashTable *changes, NMConfigData *old_data);
|
||||||
} NMConfigClass;
|
} NMConfigClass;
|
||||||
|
|
||||||
GType nm_config_get_type (void);
|
GType nm_config_get_type (void);
|
||||||
|
|
||||||
NMConfig *nm_config_get (void);
|
NMConfig *nm_config_get (void);
|
||||||
|
|
||||||
const char *nm_config_get_path (NMConfig *config);
|
char *nm_config_change_flags_to_string (NMConfigChangeFlags flags);
|
||||||
const char *nm_config_get_description (NMConfig *config);
|
|
||||||
|
NMConfigData *nm_config_get_data (NMConfig *config);
|
||||||
|
NMConfigData *nm_config_get_data_orig (NMConfig *config);
|
||||||
const char **nm_config_get_plugins (NMConfig *config);
|
const char **nm_config_get_plugins (NMConfig *config);
|
||||||
gboolean nm_config_get_monitor_connection_files (NMConfig *config);
|
gboolean nm_config_get_monitor_connection_files (NMConfig *config);
|
||||||
gboolean nm_config_get_auth_polkit (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_level (NMConfig *config);
|
||||||
const char *nm_config_get_log_domains (NMConfig *config);
|
const char *nm_config_get_log_domains (NMConfig *config);
|
||||||
const char *nm_config_get_debug (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_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);
|
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 */
|
/* for main.c only */
|
||||||
GOptionEntry *nm_config_get_options (void);
|
NMConfigCmdLineOptions *nm_config_cmd_line_options_new (void);
|
||||||
NMConfig *nm_config_new (GError **error);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
|
@@ -28,7 +28,6 @@
|
|||||||
|
|
||||||
#include "nm-connectivity.h"
|
#include "nm-connectivity.h"
|
||||||
#include "nm-logging.h"
|
#include "nm-logging.h"
|
||||||
#include "nm-config.h"
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (NMConnectivity, nm_connectivity, G_TYPE_OBJECT)
|
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 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 {
|
typedef struct {
|
||||||
char *uri;
|
char *uri;
|
||||||
char *response;
|
char *response;
|
||||||
guint interval;
|
guint interval;
|
||||||
|
gboolean online; /* whether periodic connectivity checking is enabled. */
|
||||||
|
|
||||||
#if WITH_CONCHECK
|
#if WITH_CONCHECK
|
||||||
SoupSession *soup_session;
|
SoupSession *soup_session;
|
||||||
guint pending_checks;
|
gboolean initial_check_obsoleted;
|
||||||
guint check_id;
|
guint check_id;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -69,8 +86,8 @@ nm_connectivity_get_state (NMConnectivity *connectivity)
|
|||||||
return NM_CONNECTIVITY_GET_PRIVATE (connectivity)->state;
|
return NM_CONNECTIVITY_GET_PRIVATE (connectivity)->state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
const char *
|
||||||
state_name (NMConnectivityState state)
|
nm_connectivity_state_to_string (NMConnectivityState state)
|
||||||
{
|
{
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case NM_CONNECTIVITY_UNKNOWN:
|
case NM_CONNECTIVITY_UNKNOWN:
|
||||||
@@ -84,7 +101,7 @@ state_name (NMConnectivityState state)
|
|||||||
case NM_CONNECTIVITY_FULL:
|
case NM_CONNECTIVITY_FULL:
|
||||||
return "FULL";
|
return "FULL";
|
||||||
default:
|
default:
|
||||||
return "???";
|
g_return_val_if_reached ("???");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,31 +111,41 @@ update_state (NMConnectivity *self, NMConnectivityState state)
|
|||||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||||
|
|
||||||
if (priv->state != state) {
|
if (priv->state != state) {
|
||||||
nm_log_dbg (LOGD_CONCHECK, "Connectivity state changed from %s to %s",
|
_LOGD ("state changed from %s to %s",
|
||||||
state_name (priv->state), state_name (state));
|
nm_connectivity_state_to_string (priv->state),
|
||||||
|
nm_connectivity_state_to_string (state));
|
||||||
priv->state = state;
|
priv->state = state;
|
||||||
g_object_notify (G_OBJECT (self), NM_CONNECTIVITY_STATE);
|
g_object_notify (G_OBJECT (self), NM_CONNECTIVITY_STATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WITH_CONCHECK
|
#if WITH_CONCHECK
|
||||||
|
typedef struct {
|
||||||
|
GSimpleAsyncResult *simple;
|
||||||
|
char *uri;
|
||||||
|
char *response;
|
||||||
|
guint check_id_when_scheduled;
|
||||||
|
} ConCheckCbData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nm_connectivity_check_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
|
nm_connectivity_check_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
|
||||||
{
|
{
|
||||||
GSimpleAsyncResult *simple = user_data;
|
|
||||||
NMConnectivity *self;
|
NMConnectivity *self;
|
||||||
NMConnectivityPrivate *priv;
|
NMConnectivityPrivate *priv;
|
||||||
|
ConCheckCbData *cb_data = user_data;
|
||||||
|
GSimpleAsyncResult *simple = cb_data->simple;
|
||||||
NMConnectivityState new_state;
|
NMConnectivityState new_state;
|
||||||
const char *nm_header;
|
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)));
|
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);
|
g_object_unref (self);
|
||||||
priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||||
priv->pending_checks--;
|
|
||||||
|
|
||||||
if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) {
|
if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) {
|
||||||
nm_log_info (LOGD_CONCHECK, "Connectivity check for uri '%s' failed with '%s'.",
|
_LOGI ("check for uri '%s' failed with '%s'", uri, msg->reason_phrase);
|
||||||
priv->uri, msg->reason_phrase);
|
|
||||||
new_state = NM_CONNECTIVITY_LIMITED;
|
new_state = NM_CONNECTIVITY_LIMITED;
|
||||||
goto done;
|
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 */
|
/* 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");
|
nm_header = soup_message_headers_get_one (msg->response_headers, "X-NetworkManager-Status");
|
||||||
if (g_strcmp0 (nm_header, "online") == 0) {
|
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;
|
new_state = NM_CONNECTIVITY_FULL;
|
||||||
} else if (msg->status_code == SOUP_STATUS_OK) {
|
} else if (msg->status_code == SOUP_STATUS_OK) {
|
||||||
/* check response */
|
/* check response */
|
||||||
if (msg->response_body->data && (g_str_has_prefix (msg->response_body->data, priv->response))) {
|
if (msg->response_body->data && g_str_has_prefix (msg->response_body->data, response)) {
|
||||||
nm_log_dbg (LOGD_CONCHECK, "Connectivity check for uri '%s' successful.",
|
_LOGD ("check for uri '%s' successful.", uri);
|
||||||
priv->uri);
|
|
||||||
new_state = NM_CONNECTIVITY_FULL;
|
new_state = NM_CONNECTIVITY_FULL;
|
||||||
} else {
|
} else {
|
||||||
nm_log_info (LOGD_CONCHECK, "Connectivity check for uri '%s' did not match expected response '%s'; assuming captive portal.",
|
_LOGI ("check for uri '%s' did not match expected response '%s'; assuming captive portal.",
|
||||||
priv->uri, priv->response);
|
uri, response);
|
||||||
new_state = NM_CONNECTIVITY_PORTAL;
|
new_state = NM_CONNECTIVITY_PORTAL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nm_log_info (LOGD_CONCHECK, "Connectivity check for uri '%s' returned status '%d %s'; assuming captive portal.",
|
_LOGI ("check for uri '%s' returned status '%d %s'; assuming captive portal.",
|
||||||
priv->uri, msg->status_code, msg->reason_phrase);
|
uri, msg->status_code, msg->reason_phrase);
|
||||||
new_state = NM_CONNECTIVITY_PORTAL;
|
new_state = NM_CONNECTIVITY_PORTAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
/* 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);
|
update_state (self, new_state);
|
||||||
|
}
|
||||||
|
|
||||||
g_simple_async_result_set_op_res_gssize (simple, new_state);
|
g_simple_async_result_set_op_res_gssize (simple, new_state);
|
||||||
g_simple_async_result_complete (simple);
|
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
|
static void
|
||||||
run_check_complete (GObject *object,
|
run_check_complete (GObject *object,
|
||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
@@ -162,7 +204,7 @@ run_check_complete (GObject *object,
|
|||||||
|
|
||||||
nm_connectivity_check_finish (self, result, &error);
|
nm_connectivity_check_finish (self, result, &error);
|
||||||
if (error) {
|
if (error) {
|
||||||
nm_log_err (LOGD_CONCHECK, "Connectivity check failed: %s", error->message);
|
_LOGE ("check failed: %s", error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,39 +225,54 @@ idle_start_periodic_checks (gpointer user_data)
|
|||||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||||
|
|
||||||
priv->check_id = g_timeout_add_seconds (priv->interval, run_check, 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);
|
run_check (self);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
static void
|
||||||
nm_connectivity_set_online (NMConnectivity *self,
|
_reschedule_periodic_checks (NMConnectivity *self, gboolean force_reschedule)
|
||||||
gboolean online)
|
|
||||||
{
|
{
|
||||||
#if WITH_CONCHECK
|
|
||||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
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 WITH_CONCHECK
|
||||||
if (online && priv->uri && priv->interval) {
|
if (priv->online && priv->uri && priv->interval) {
|
||||||
if (!priv->check_id)
|
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);
|
priv->check_id = g_timeout_add (0, idle_start_periodic_checks, self);
|
||||||
|
priv->initial_check_obsoleted = FALSE;
|
||||||
return;
|
}
|
||||||
} else if (priv->check_id) {
|
} else {
|
||||||
|
if (priv->check_id) {
|
||||||
g_source_remove (priv->check_id);
|
g_source_remove (priv->check_id);
|
||||||
priv->check_id = 0;
|
priv->check_id = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (priv->check_id)
|
||||||
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Either @online is %TRUE but we aren't checking connectivity, or
|
/* Either @online is %TRUE but we aren't checking connectivity, or
|
||||||
* @online is %FALSE. Either way we can update our status immediately.
|
* @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
|
void
|
||||||
@@ -224,36 +281,42 @@ nm_connectivity_check_async (NMConnectivity *self,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
NMConnectivityPrivate *priv;
|
NMConnectivityPrivate *priv;
|
||||||
#if WITH_CONCHECK
|
|
||||||
SoupMessage *msg;
|
|
||||||
#endif
|
|
||||||
GSimpleAsyncResult *simple;
|
GSimpleAsyncResult *simple;
|
||||||
|
|
||||||
g_return_if_fail (NM_IS_CONNECTIVITY (self));
|
g_return_if_fail (NM_IS_CONNECTIVITY (self));
|
||||||
priv = NM_CONNECTIVITY_GET_PRIVATE (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,
|
simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
|
||||||
nm_connectivity_check_async);
|
nm_connectivity_check_async);
|
||||||
|
|
||||||
#if WITH_CONCHECK
|
#if WITH_CONCHECK
|
||||||
if (priv->uri && priv->interval) {
|
if (priv->uri && priv->interval) {
|
||||||
|
SoupMessage *msg;
|
||||||
|
ConCheckCbData *cb_data = g_slice_new (ConCheckCbData);
|
||||||
|
|
||||||
msg = soup_message_new ("GET", priv->uri);
|
msg = soup_message_new ("GET", priv->uri);
|
||||||
soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
|
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,
|
soup_session_queue_message (priv->soup_session,
|
||||||
msg,
|
msg,
|
||||||
nm_connectivity_check_cb,
|
nm_connectivity_check_cb,
|
||||||
simple);
|
cb_data);
|
||||||
priv->pending_checks++;
|
priv->initial_check_obsoleted = TRUE;
|
||||||
|
|
||||||
|
_LOGD ("check: send %srequest to '%s'", IS_PERIODIC_CHECK (callback) ? "periodic " : "", priv->uri);
|
||||||
return;
|
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
|
#endif
|
||||||
|
|
||||||
g_simple_async_result_set_op_res_gssize (simple, priv->state);
|
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);
|
return (NMConnectivityState) g_simple_async_result_get_op_res_gssize (simple);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
NMConnectivity *
|
NMConnectivity *
|
||||||
nm_connectivity_new (void)
|
nm_connectivity_new (const char *uri,
|
||||||
|
guint interval,
|
||||||
|
const char *response)
|
||||||
{
|
{
|
||||||
NMConnectivity *self;
|
return g_object_new (NM_TYPE_CONNECTIVITY,
|
||||||
NMConfig *config;
|
NM_CONNECTIVITY_URI, uri,
|
||||||
const char *check_response;
|
NM_CONNECTIVITY_INTERVAL, interval,
|
||||||
|
NM_CONNECTIVITY_RESPONSE, 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,
|
|
||||||
NULL);
|
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
|
static void
|
||||||
@@ -315,32 +358,48 @@ set_property (GObject *object, guint property_id,
|
|||||||
{
|
{
|
||||||
NMConnectivity *self = NM_CONNECTIVITY (object);
|
NMConnectivity *self = NM_CONNECTIVITY (object);
|
||||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||||
|
const char *uri, *response;
|
||||||
|
guint interval;
|
||||||
|
|
||||||
switch (property_id) {
|
switch (property_id) {
|
||||||
case PROP_URI:
|
case PROP_URI:
|
||||||
g_free (priv->uri);
|
uri = g_value_get_string (value);
|
||||||
priv->uri = get_non_empty_string_value (value);
|
if (uri && !*uri)
|
||||||
|
uri = NULL;
|
||||||
#if WITH_CONCHECK
|
#if WITH_CONCHECK
|
||||||
if (priv->uri) {
|
if (uri) {
|
||||||
SoupURI *uri = soup_uri_new (priv->uri);
|
SoupURI *soup_uri = soup_uri_new (uri);
|
||||||
|
|
||||||
if (!uri || !SOUP_URI_VALID_FOR_HTTP (uri)) {
|
if (!soup_uri || !SOUP_URI_VALID_FOR_HTTP (soup_uri)) {
|
||||||
nm_log_err (LOGD_CONCHECK, "Invalid uri '%s' for connectivity check.", priv->uri);
|
_LOGE ("invalid uri '%s' for connectivity check.", uri);
|
||||||
g_free (priv->uri);
|
uri = NULL;
|
||||||
priv->uri = NULL;
|
|
||||||
}
|
}
|
||||||
if (uri)
|
if (soup_uri)
|
||||||
soup_uri_free (uri);
|
soup_uri_free (soup_uri);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (g_strcmp0 (uri, priv->uri) != 0) {
|
||||||
|
g_free (priv->uri);
|
||||||
|
priv->uri = g_strdup (uri);
|
||||||
|
_reschedule_periodic_checks (self, TRUE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_INTERVAL:
|
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;
|
break;
|
||||||
case PROP_RESPONSE:
|
case PROP_RESPONSE:
|
||||||
|
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);
|
g_free (priv->response);
|
||||||
priv->response = get_non_empty_string_value (value);
|
priv->response = g_strdup (response);
|
||||||
|
_reschedule_periodic_checks (self, TRUE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
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);
|
g_value_set_uint (value, priv->interval);
|
||||||
break;
|
break;
|
||||||
case PROP_RESPONSE:
|
case PROP_RESPONSE:
|
||||||
|
if (priv->response)
|
||||||
g_value_set_string (value, priv->response);
|
g_value_set_string (value, priv->response);
|
||||||
|
else
|
||||||
|
g_value_set_static_string (value, DEFAULT_RESPONSE);
|
||||||
break;
|
break;
|
||||||
case PROP_STATE:
|
case PROP_STATE:
|
||||||
g_value_set_uint (value, priv->state);
|
g_value_set_uint (value, priv->state);
|
||||||
@@ -378,11 +440,12 @@ get_property (GObject *object, guint property_id,
|
|||||||
static void
|
static void
|
||||||
nm_connectivity_init (NMConnectivity *self)
|
nm_connectivity_init (NMConnectivity *self)
|
||||||
{
|
{
|
||||||
#if WITH_CONCHECK
|
|
||||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
#if WITH_CONCHECK
|
||||||
priv->soup_session = soup_session_async_new_with_options (SOUP_SESSION_TIMEOUT, 15, NULL);
|
priv->soup_session = soup_session_async_new_with_options (SOUP_SESSION_TIMEOUT, 15, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
priv->state = NM_CONNECTIVITY_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -392,8 +455,8 @@ dispose (GObject *object)
|
|||||||
NMConnectivity *self = NM_CONNECTIVITY (object);
|
NMConnectivity *self = NM_CONNECTIVITY (object);
|
||||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||||
|
|
||||||
g_free (priv->uri);
|
g_clear_pointer (&priv->uri, g_free);
|
||||||
g_free (priv->response);
|
g_clear_pointer (&priv->response, g_free);
|
||||||
|
|
||||||
#if WITH_CONCHECK
|
#if WITH_CONCHECK
|
||||||
if (priv->soup_session) {
|
if (priv->soup_session) {
|
||||||
@@ -426,20 +489,23 @@ nm_connectivity_class_init (NMConnectivityClass *klass)
|
|||||||
g_param_spec_string (NM_CONNECTIVITY_URI, "", "",
|
g_param_spec_string (NM_CONNECTIVITY_URI, "", "",
|
||||||
NULL,
|
NULL,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(object_class, PROP_INTERVAL,
|
(object_class, PROP_INTERVAL,
|
||||||
g_param_spec_uint (NM_CONNECTIVITY_INTERVAL, "", "",
|
g_param_spec_uint (NM_CONNECTIVITY_INTERVAL, "", "",
|
||||||
0, G_MAXUINT, 300,
|
0, G_MAXUINT, 300,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(object_class, PROP_RESPONSE,
|
(object_class, PROP_RESPONSE,
|
||||||
g_param_spec_string (NM_CONNECTIVITY_RESPONSE, "", "",
|
g_param_spec_string (NM_CONNECTIVITY_RESPONSE, "", "",
|
||||||
DEFAULT_RESPONSE,
|
DEFAULT_RESPONSE,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
|
@@ -51,7 +51,11 @@ typedef struct {
|
|||||||
|
|
||||||
GType nm_connectivity_get_type (void);
|
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,
|
void nm_connectivity_set_online (NMConnectivity *self,
|
||||||
gboolean online);
|
gboolean online);
|
||||||
|
@@ -315,6 +315,7 @@ main (int argc, char *argv[])
|
|||||||
&argc,
|
&argc,
|
||||||
options,
|
options,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
_("nm-iface-helper is a small, standalone process that manages a single network interface.")))
|
_("nm-iface-helper is a small, standalone process that manages a single network interface.")))
|
||||||
exit (1);
|
exit (1);
|
||||||
|
|
||||||
@@ -480,6 +481,12 @@ main (int argc, char *argv[])
|
|||||||
/*******************************************************/
|
/*******************************************************/
|
||||||
/* Stub functions */
|
/* Stub functions */
|
||||||
|
|
||||||
|
void
|
||||||
|
nm_main_config_reload ()
|
||||||
|
{
|
||||||
|
nm_log_info (LOGD_CORE, "reloading configuration not supported");
|
||||||
|
}
|
||||||
|
|
||||||
gconstpointer nm_config_get (void);
|
gconstpointer nm_config_get (void);
|
||||||
const char *nm_config_get_dhcp_client (gpointer unused);
|
const char *nm_config_get_dhcp_client (gpointer unused);
|
||||||
gboolean nm_config_get_configure_and_quit (gpointer unused);
|
gboolean nm_config_get_configure_and_quit (gpointer unused);
|
||||||
|
@@ -167,6 +167,7 @@ typedef struct {
|
|||||||
|
|
||||||
GSList *devices;
|
GSList *devices;
|
||||||
NMState state;
|
NMState state;
|
||||||
|
NMConfig *config;
|
||||||
NMConnectivity *connectivity;
|
NMConnectivity *connectivity;
|
||||||
|
|
||||||
int ignore_link_added_cb;
|
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 *
|
static NMDevice *
|
||||||
nm_manager_get_device_by_udi (NMManager *manager, const char *udi)
|
nm_manager_get_device_by_udi (NMManager *manager, const char *udi)
|
||||||
{
|
{
|
||||||
@@ -4274,12 +4287,9 @@ connectivity_changed (NMConnectivity *connectivity,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
NMManager *self = NM_MANAGER (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",
|
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);
|
nm_manager_update_state (self);
|
||||||
g_object_notify (G_OBJECT (self), NM_MANAGER_CONNECTIVITY);
|
g_object_notify (G_OBJECT (self), NM_MANAGER_CONNECTIVITY);
|
||||||
@@ -4722,6 +4732,7 @@ nm_manager_new (NMSettings *settings,
|
|||||||
NMManagerPrivate *priv;
|
NMManagerPrivate *priv;
|
||||||
DBusGConnection *bus;
|
DBusGConnection *bus;
|
||||||
DBusConnection *dbus_connection;
|
DBusConnection *dbus_connection;
|
||||||
|
NMConfigData *config_data;
|
||||||
|
|
||||||
g_assert (settings);
|
g_assert (settings);
|
||||||
|
|
||||||
@@ -4753,7 +4764,16 @@ nm_manager_new (NMSettings *settings,
|
|||||||
g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_DEVICE,
|
g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_DEVICE,
|
||||||
G_CALLBACK (policy_activating_device_changed), singleton);
|
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_signal_connect (priv->connectivity, "notify::" NM_CONNECTIVITY_STATE,
|
||||||
G_CALLBACK (connectivity_changed), singleton);
|
G_CALLBACK (connectivity_changed), singleton);
|
||||||
|
|
||||||
@@ -5074,7 +5094,14 @@ dispose (GObject *object)
|
|||||||
g_clear_object (&priv->primary_connection);
|
g_clear_object (&priv->primary_connection);
|
||||||
g_clear_object (&priv->activating_connection);
|
g_clear_object (&priv->activating_connection);
|
||||||
|
|
||||||
|
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_clear_object (&priv->connectivity);
|
||||||
|
}
|
||||||
|
|
||||||
g_free (priv->hostname);
|
g_free (priv->hostname);
|
||||||
|
|
||||||
|
@@ -26,6 +26,8 @@ typedef struct _NMActiveConnection NMActiveConnection;
|
|||||||
typedef struct _NMVpnConnection NMVpnConnection;
|
typedef struct _NMVpnConnection NMVpnConnection;
|
||||||
typedef struct _NMActRequest NMActRequest;
|
typedef struct _NMActRequest NMActRequest;
|
||||||
typedef struct _NMAuthSubject NMAuthSubject;
|
typedef struct _NMAuthSubject NMAuthSubject;
|
||||||
|
typedef struct _NMConfig NMConfig;
|
||||||
|
typedef struct _NMConfigData NMConfigData;
|
||||||
typedef struct _NMConnectionProvider NMConnectionProvider;
|
typedef struct _NMConnectionProvider NMConnectionProvider;
|
||||||
typedef struct _NMConnectivity NMConnectivity;
|
typedef struct _NMConnectivity NMConnectivity;
|
||||||
typedef struct _NMDBusManager NMDBusManager;
|
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);
|
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (default_wired_connection_updated_by_user_cb), self);
|
||||||
|
|
||||||
if (add_to_no_auto_default)
|
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
|
void
|
||||||
|
@@ -847,7 +847,7 @@ nm_system_config_factory (void)
|
|||||||
priv = SC_PLUGIN_EXAMPLE_GET_PRIVATE (singleton);
|
priv = SC_PLUGIN_EXAMPLE_GET_PRIVATE (singleton);
|
||||||
|
|
||||||
/* Cache the config file path */
|
/* 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 {
|
} else {
|
||||||
/* This function should never be called twice */
|
/* This function should never be called twice */
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
|
@@ -123,7 +123,7 @@ is_managed_plugin (void)
|
|||||||
{
|
{
|
||||||
char *result = NULL;
|
char *result = NULL;
|
||||||
|
|
||||||
result = nm_config_get_value (nm_config_get (),
|
result = nm_config_data_get_value (nm_config_get_data_orig (nm_config_get ()),
|
||||||
IFNET_KEY_FILE_GROUP, IFNET_KEY_FILE_KEY_MANAGED,
|
IFNET_KEY_FILE_GROUP, IFNET_KEY_FILE_KEY_MANAGED,
|
||||||
NULL);
|
NULL);
|
||||||
if (result) {
|
if (result) {
|
||||||
@@ -264,7 +264,7 @@ reload_connections (NMSystemConfigInterface *config)
|
|||||||
|
|
||||||
nm_log_info (LOGD_SETTINGS, "Loading connections");
|
nm_log_info (LOGD_SETTINGS, "Loading connections");
|
||||||
|
|
||||||
str_auto_refresh = nm_config_get_value (nm_config_get (),
|
str_auto_refresh = nm_config_data_get_value (nm_config_get_data_orig (nm_config_get ()),
|
||||||
IFNET_KEY_FILE_GROUP, "auto_refresh",
|
IFNET_KEY_FILE_GROUP, "auto_refresh",
|
||||||
NULL);
|
NULL);
|
||||||
if (str_auto_refresh && is_true (str_auto_refresh))
|
if (str_auto_refresh && is_true (str_auto_refresh))
|
||||||
|
@@ -456,12 +456,12 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config)
|
|||||||
g_hash_table_destroy (auto_ifaces);
|
g_hash_table_destroy (auto_ifaces);
|
||||||
|
|
||||||
/* Check the config file to find out whether to manage interfaces */
|
/* Check the config file to find out whether to manage interfaces */
|
||||||
value = nm_config_get_value (nm_config_get (),
|
value = nm_config_data_get_value (nm_config_get_data_orig (nm_config_get ()),
|
||||||
IFUPDOWN_KEY_FILE_GROUP, IFUPDOWN_KEY_FILE_KEY_MANAGED,
|
IFUPDOWN_KEY_FILE_GROUP, IFUPDOWN_KEY_FILE_KEY_MANAGED,
|
||||||
&error);
|
&error);
|
||||||
if (error) {
|
if (error) {
|
||||||
nm_log_info (LOGD_SETTINGS, "loading system config file (%s) caused error: %s",
|
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);
|
error->message);
|
||||||
} else {
|
} else {
|
||||||
gboolean manage_well_known;
|
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));
|
singleton = SC_PLUGIN_KEYFILE (g_object_new (SC_TYPE_PLUGIN_KEYFILE, NULL));
|
||||||
priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (singleton);
|
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 */
|
/* plugin_set_hostname() has to be called *after* priv->conf_file is set */
|
||||||
priv->hostname = plugin_get_hostname (singleton);
|
priv->hostname = plugin_get_hostname (singleton);
|
||||||
|
@@ -27,9 +27,12 @@
|
|||||||
#include <nm-config.h>
|
#include <nm-config.h>
|
||||||
#include "nm-test-device.h"
|
#include "nm-test-device.h"
|
||||||
#include "nm-fake-platform.h"
|
#include "nm-fake-platform.h"
|
||||||
|
#include "nm-logging.h"
|
||||||
|
|
||||||
static void
|
#include "nm-test-utils.h"
|
||||||
setup_config (const char *config_file, const char *config_dir, ...)
|
|
||||||
|
static NMConfig *
|
||||||
|
setup_config (GError **error, const char *config_file, const char *config_dir, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
GPtrArray *args;
|
GPtrArray *args;
|
||||||
@@ -37,6 +40,11 @@ setup_config (const char *config_file, const char *config_dir, ...)
|
|||||||
int argc;
|
int argc;
|
||||||
GOptionContext *context;
|
GOptionContext *context;
|
||||||
gboolean success;
|
gboolean success;
|
||||||
|
NMConfig *config;
|
||||||
|
GError *local_error = NULL;
|
||||||
|
NMConfigCmdLineOptions *cli;
|
||||||
|
|
||||||
|
g_assert (!error || !*error);
|
||||||
|
|
||||||
args = g_ptr_array_new ();
|
args = g_ptr_array_new ();
|
||||||
g_ptr_array_add (args, "test-config");
|
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;
|
argv = (char **)args->pdata;
|
||||||
argc = args->len;
|
argc = args->len;
|
||||||
|
|
||||||
|
cli = nm_config_cmd_line_options_new ();
|
||||||
|
|
||||||
context = g_option_context_new (NULL);
|
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);
|
success = g_option_context_parse (context, &argc, &argv, NULL);
|
||||||
g_option_context_free (context);
|
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_printerr ("Invalid options.\n");
|
||||||
|
|
||||||
g_ptr_array_free (args, TRUE);
|
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
|
static void
|
||||||
@@ -72,14 +94,12 @@ test_config_simple (void)
|
|||||||
const char **plugins;
|
const char **plugins;
|
||||||
char *value;
|
char *value;
|
||||||
|
|
||||||
setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir", NULL);
|
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir", NULL);
|
||||||
config = nm_config_new (&error);
|
|
||||||
g_assert_no_error (error);
|
|
||||||
|
|
||||||
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_dhcp_client (config), ==, "dhclient");
|
||||||
g_assert_cmpstr (nm_config_get_log_level (config), ==, "INFO");
|
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);
|
plugins = nm_config_get_plugins (config);
|
||||||
g_assert_cmpint (g_strv_length ((char **)plugins), ==, 3);
|
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[1], ==, "bar");
|
||||||
g_assert_cmpstr (plugins[2], ==, "baz");
|
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_assert_cmpstr (value, ==, "some value");
|
||||||
g_free (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 (!value);
|
||||||
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
|
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
|
||||||
g_clear_error (&error);
|
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 (!value);
|
||||||
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
|
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
@@ -107,45 +127,38 @@ test_config_simple (void)
|
|||||||
static void
|
static void
|
||||||
test_config_non_existent (void)
|
test_config_non_existent (void)
|
||||||
{
|
{
|
||||||
NMConfig *config;
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
setup_config (SRCDIR "/no-such-file", "/no/such/dir", NULL);
|
setup_config (&error, SRCDIR "/no-such-file", "/no/such/dir", NULL);
|
||||||
config = nm_config_new (&error);
|
|
||||||
g_assert (!config);
|
|
||||||
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND);
|
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND);
|
||||||
|
g_clear_error (&error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_config_parse_error (void)
|
test_config_parse_error (void)
|
||||||
{
|
{
|
||||||
NMConfig *config;
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
setup_config (SRCDIR "/bad.conf", "/no/such/dir", NULL);
|
setup_config (&error, SRCDIR "/bad.conf", "/no/such/dir", NULL);
|
||||||
config = nm_config_new (&error);
|
|
||||||
g_assert (!config);
|
|
||||||
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE);
|
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE);
|
||||||
|
g_clear_error (&error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_config_override (void)
|
test_config_override (void)
|
||||||
{
|
{
|
||||||
NMConfig *config;
|
NMConfig *config;
|
||||||
GError *error = NULL;
|
|
||||||
const char **plugins;
|
const char **plugins;
|
||||||
|
|
||||||
setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir",
|
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir",
|
||||||
"--plugins", "alpha,beta,gamma,delta",
|
"--plugins", "alpha,beta,gamma,delta",
|
||||||
"--connectivity-interval", "12",
|
"--connectivity-interval", "12",
|
||||||
NULL);
|
NULL);
|
||||||
config = nm_config_new (&error);
|
|
||||||
g_assert_no_error (error);
|
|
||||||
|
|
||||||
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_dhcp_client (config), ==, "dhclient");
|
||||||
g_assert_cmpstr (nm_config_get_log_level (config), ==, "INFO");
|
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);
|
plugins = nm_config_get_plugins (config);
|
||||||
g_assert_cmpint (g_strv_length ((char **)plugins), ==, 4);
|
g_assert_cmpint (g_strv_length ((char **)plugins), ==, 4);
|
||||||
@@ -175,37 +188,36 @@ test_config_no_auto_default (void)
|
|||||||
g_assert_cmpint (nwrote, ==, 18);
|
g_assert_cmpint (nwrote, ==, 18);
|
||||||
close (fd);
|
close (fd);
|
||||||
|
|
||||||
setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir",
|
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir",
|
||||||
"--no-auto-default", state_file,
|
"--no-auto-default", state_file,
|
||||||
NULL);
|
NULL);
|
||||||
config = nm_config_new (&error);
|
|
||||||
g_assert_no_error (error);
|
|
||||||
|
|
||||||
dev1 = nm_test_device_new ("11:11:11:11:11:11");
|
dev1 = nm_test_device_new ("11:11:11:11:11:11");
|
||||||
dev2 = nm_test_device_new ("22:22:22:22:22:22");
|
dev2 = nm_test_device_new ("22:22:22:22:22:22");
|
||||||
dev3 = nm_test_device_new ("33:33:33:33:33:33");
|
dev3 = nm_test_device_new ("33:33:33:33:33:33");
|
||||||
dev4 = nm_test_device_new ("44:44:44:44:44:44");
|
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_no_auto_default_for_device (config, dev1));
|
||||||
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev2));
|
g_assert (nm_config_get_no_auto_default_for_device (config, dev2));
|
||||||
g_assert (nm_config_get_ethernet_can_auto_default (config, dev3));
|
g_assert (!nm_config_get_no_auto_default_for_device (config, dev3));
|
||||||
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev4));
|
g_assert (nm_config_get_no_auto_default_for_device (config, dev4));
|
||||||
|
|
||||||
nm_config_set_ethernet_no_auto_default (config, dev3);
|
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*config: update * (no-auto-default)*");
|
||||||
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev3));
|
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);
|
g_object_unref (config);
|
||||||
|
|
||||||
setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir",
|
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir",
|
||||||
"--no-auto-default", state_file,
|
"--no-auto-default", state_file,
|
||||||
NULL);
|
NULL);
|
||||||
config = nm_config_new (&error);
|
|
||||||
g_assert_no_error (error);
|
|
||||||
|
|
||||||
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev1));
|
g_assert (nm_config_get_no_auto_default_for_device (config, dev1));
|
||||||
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev2));
|
g_assert (nm_config_get_no_auto_default_for_device (config, dev2));
|
||||||
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev3));
|
g_assert (nm_config_get_no_auto_default_for_device (config, dev3));
|
||||||
g_assert (!nm_config_get_ethernet_can_auto_default (config, dev4));
|
g_assert (nm_config_get_no_auto_default_for_device (config, dev4));
|
||||||
|
|
||||||
g_object_unref (config);
|
g_object_unref (config);
|
||||||
|
|
||||||
@@ -222,20 +234,17 @@ static void
|
|||||||
test_config_confdir (void)
|
test_config_confdir (void)
|
||||||
{
|
{
|
||||||
NMConfig *config;
|
NMConfig *config;
|
||||||
GError *error = NULL;
|
|
||||||
const char **plugins;
|
const char **plugins;
|
||||||
char *value;
|
char *value;
|
||||||
|
|
||||||
setup_config (SRCDIR "/NetworkManager.conf", SRCDIR "/conf.d", NULL);
|
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", SRCDIR "/conf.d", NULL);
|
||||||
config = nm_config_new (&error);
|
|
||||||
g_assert_no_error (error);
|
|
||||||
|
|
||||||
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_dhcp_client (config), ==, "dhcpcd");
|
||||||
g_assert_cmpstr (nm_config_get_log_level (config), ==, "INFO");
|
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_log_domains (config), ==, "PLATFORM,DNS,WIFI");
|
||||||
g_assert_cmpstr (nm_config_get_connectivity_uri (config), ==, "http://example.net");
|
g_assert_cmpstr (nm_config_data_get_connectivity_uri (nm_config_get_data_orig (config)), ==, "http://example.net");
|
||||||
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);
|
plugins = nm_config_get_plugins (config);
|
||||||
g_assert_cmpint (g_strv_length ((char **)plugins), ==, 5);
|
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[3], ==, "one");
|
||||||
g_assert_cmpstr (plugins[4], ==, "two");
|
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_assert_cmpstr (value, ==, "hello");
|
||||||
g_free (value);
|
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_assert_cmpstr (value, ==, "something"); /* not ",something" */
|
||||||
g_free (value);
|
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_assert_cmpstr (value, ==, "90");
|
||||||
g_free (value);
|
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_assert_cmpstr (value, ==, "10");
|
||||||
g_free (value);
|
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_assert_cmpstr (value, ==, "0");
|
||||||
g_free (value);
|
g_free (value);
|
||||||
|
|
||||||
@@ -269,24 +278,20 @@ test_config_confdir (void)
|
|||||||
static void
|
static void
|
||||||
test_config_confdir_parse_error (void)
|
test_config_confdir_parse_error (void)
|
||||||
{
|
{
|
||||||
NMConfig *config;
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
/* Using SRCDIR as the conf dir will pick up bad.conf */
|
/* Using SRCDIR as the conf dir will pick up bad.conf */
|
||||||
setup_config (SRCDIR "/NetworkManager.conf", SRCDIR, NULL);
|
setup_config (&error, SRCDIR "/NetworkManager.conf", SRCDIR, NULL);
|
||||||
config = nm_config_new (&error);
|
|
||||||
g_assert (!config);
|
|
||||||
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE);
|
g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE);
|
||||||
|
g_clear_error (&error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NMTST_DEFINE ();
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
#if !GLIB_CHECK_VERSION (2, 35, 0)
|
nmtst_init_assert_logging (&argc, &argv);
|
||||||
g_type_init ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
g_test_init (&argc, &argv, NULL);
|
|
||||||
|
|
||||||
nm_fake_platform_setup ();
|
nm_fake_platform_setup ();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user