2011-09-22 10:16:07 -05:00
/* -*- 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 .
2013-01-15 18:48:51 +01:00
* Copyright ( C ) 2013 Thomas Bechtold < thomasbechtold @ jpberlin . de >
2011-09-22 10:16:07 -05:00
*/
2014-11-13 10:07:02 -05:00
# include "config.h"
2011-09-22 10:16:07 -05:00
# include <string.h>
# include <stdio.h>
# include "nm-config.h"
2013-03-11 12:23:57 -04:00
# include "nm-logging.h"
2013-03-12 13:14:54 -04:00
# include "nm-utils.h"
2013-04-03 12:56:13 -04:00
# include "nm-glib-compat.h"
2014-07-17 16:24:17 -04:00
# include "nm-device.h"
2014-07-09 18:54:47 +02:00
# include "NetworkManagerUtils.h"
2015-01-21 12:58:32 +01:00
# include "gsystem-local-alloc.h"
# include "nm-enum-types.h"
2015-02-09 16:36:53 +01:00
# include "nm-core-internal.h"
2011-09-22 10:16:07 -05:00
2013-03-14 14:34:36 -04:00
# include <gio/gio.h>
2013-03-11 12:06:38 -04:00
# include <glib/gi18n.h>
2013-03-12 13:14:54 -04:00
# define NM_DEFAULT_SYSTEM_CONF_FILE NMCONFDIR " / NetworkManager.conf"
2013-03-14 14:34:36 -04:00
# define NM_DEFAULT_SYSTEM_CONF_DIR NMCONFDIR " / conf.d"
2013-03-12 13:14:54 -04:00
# define NM_OLD_SYSTEM_CONF_FILE NMCONFDIR " / nm-system-settings.conf"
# define NM_NO_AUTO_DEFAULT_STATE_FILE NMSTATEDIR " / no-auto-default.state"
2011-09-22 10:16:07 -05:00
2014-07-09 15:17:01 +02:00
struct NMConfigCmdLineOptions {
2014-12-16 11:02:57 +01:00
char * config_main_file ;
2014-07-09 15:17:01 +02:00
char * config_dir ;
char * no_auto_default_file ;
char * plugins ;
2015-02-06 11:54:16 +01:00
gboolean configure_and_quit ;
2014-07-09 15:17:01 +02:00
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 ;
} ;
2013-01-15 18:48:51 +01:00
typedef struct {
2014-07-09 15:17:01 +02:00
NMConfigCmdLineOptions cli ;
2014-07-11 18:54:18 +02:00
NMConfigData * config_data ;
NMConfigData * config_data_orig ;
2013-03-14 14:34:36 -04:00
char * config_dir ;
2013-03-12 13:14:54 -04:00
char * no_auto_default_file ;
2011-09-22 10:16:07 -05:00
char * * plugins ;
2013-05-23 19:05:40 -03:00
gboolean monitor_connection_files ;
2014-08-14 13:34:57 +02:00
gboolean auth_polkit ;
2011-09-22 10:16:07 -05:00
char * dhcp_client ;
2013-03-19 10:24:35 -04:00
2011-09-22 10:16:07 -05:00
char * log_level ;
char * log_domains ;
2013-03-19 10:24:35 -04:00
2014-03-06 22:04:44 +01:00
char * debug ;
2014-04-02 12:41:04 -05:00
gboolean configure_and_quit ;
2013-01-15 18:48:51 +01:00
} NMConfigPrivate ;
2014-12-16 15:10:24 +01:00
enum {
PROP_0 ,
PROP_CMD_LINE_OPTIONS ,
LAST_PROP ,
} ;
2014-07-09 18:54:47 +02:00
enum {
SIGNAL_CONFIG_CHANGED ,
LAST_SIGNAL
} ;
static guint signals [ LAST_SIGNAL ] = { 0 } ;
2015-01-12 15:35:52 +01:00
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 ) ;
)
2013-01-15 18:48:51 +01:00
# define NM_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CONFIG, NMConfigPrivate))
2011-09-22 10:16:07 -05:00
/************************************************************************/
2015-06-25 21:10:32 +02:00
static void _set_config_data ( NMConfig * self , NMConfigData * new_data , int signal ) ;
2015-01-07 17:09:52 +01:00
/************************************************************************/
2015-05-15 17:00:31 +02:00
gboolean
nm_config_keyfile_get_boolean ( GKeyFile * keyfile ,
const char * section ,
const char * key ,
gboolean default_value )
2014-08-17 14:06:41 +02:00
{
2014-10-29 09:12:18 -05:00
gboolean value = default_value ;
char * str ;
g_return_val_if_fail ( keyfile ! = NULL , default_value ) ;
g_return_val_if_fail ( section ! = NULL , default_value ) ;
g_return_val_if_fail ( key ! = NULL , default_value ) ;
str = g_key_file_get_value ( keyfile , section , key , NULL ) ;
if ( ! str )
return default_value ;
g_strstrip ( str ) ;
if ( str [ 0 ] ) {
if ( ! g_ascii_strcasecmp ( str , " true " ) | | ! g_ascii_strcasecmp ( str , " yes " ) | | ! g_ascii_strcasecmp ( str , " on " ) | | ! g_ascii_strcasecmp ( str , " 1 " ) )
value = TRUE ;
else if ( ! g_ascii_strcasecmp ( str , " false " ) | | ! g_ascii_strcasecmp ( str , " no " ) | | ! g_ascii_strcasecmp ( str , " off " ) | | ! g_ascii_strcasecmp ( str , " 0 " ) )
value = FALSE ;
else {
nm_log_warn ( LOGD_CORE , " Unrecognized value for %s.%s: '%s'. Assuming '%s' " ,
section , key , str , default_value ? " true " : " false " ) ;
}
2014-08-17 14:06:41 +02:00
}
2014-10-29 09:12:18 -05:00
g_free ( str ) ;
return value ;
2014-08-17 14:06:41 +02:00
}
/************************************************************************/
2014-07-11 18:54:18 +02:00
NMConfigData *
nm_config_get_data ( NMConfig * config )
{
g_return_val_if_fail ( config ! = NULL , NULL ) ;
return NM_CONFIG_GET_PRIVATE ( config ) - > config_data ;
}
/* The NMConfigData instance is reloadable and will be swapped on reload.
* nm_config_get_data_orig ( ) returns the original configuration , when the NMConfig
* instance was created . */
NMConfigData *
nm_config_get_data_orig ( NMConfig * config )
{
g_return_val_if_fail ( config ! = NULL , NULL ) ;
return NM_CONFIG_GET_PRIVATE ( config ) - > config_data_orig ;
}
2011-09-22 10:16:07 -05:00
const char * *
nm_config_get_plugins ( NMConfig * config )
{
g_return_val_if_fail ( config ! = NULL , NULL ) ;
2013-01-15 18:48:51 +01:00
return ( const char * * ) NM_CONFIG_GET_PRIVATE ( config ) - > plugins ;
2011-09-22 10:16:07 -05:00
}
2013-05-23 19:05:40 -03:00
gboolean
nm_config_get_monitor_connection_files ( NMConfig * config )
{
g_return_val_if_fail ( config ! = NULL , FALSE ) ;
return NM_CONFIG_GET_PRIVATE ( config ) - > monitor_connection_files ;
}
2014-08-14 13:34:57 +02:00
gboolean
nm_config_get_auth_polkit ( NMConfig * config )
{
g_return_val_if_fail ( NM_IS_CONFIG ( config ) , NM_CONFIG_DEFAULT_AUTH_POLKIT ) ;
return NM_CONFIG_GET_PRIVATE ( config ) - > auth_polkit ;
}
2011-09-22 10:16:07 -05:00
const char *
nm_config_get_dhcp_client ( NMConfig * config )
{
g_return_val_if_fail ( config ! = NULL , NULL ) ;
2013-03-12 09:32:47 +01:00
return NM_CONFIG_GET_PRIVATE ( config ) - > dhcp_client ;
2011-09-22 10:16:07 -05:00
}
const char *
nm_config_get_log_level ( NMConfig * config )
{
g_return_val_if_fail ( config ! = NULL , NULL ) ;
2013-03-12 09:32:47 +01:00
return NM_CONFIG_GET_PRIVATE ( config ) - > log_level ;
2011-09-22 10:16:07 -05:00
}
const char *
nm_config_get_log_domains ( NMConfig * config )
{
g_return_val_if_fail ( config ! = NULL , NULL ) ;
2013-01-15 18:48:51 +01:00
return NM_CONFIG_GET_PRIVATE ( config ) - > log_domains ;
2011-09-22 10:16:07 -05:00
}
2014-03-06 22:04:44 +01:00
const char *
nm_config_get_debug ( NMConfig * config )
{
g_return_val_if_fail ( config ! = NULL , NULL ) ;
return NM_CONFIG_GET_PRIVATE ( config ) - > debug ;
}
2014-04-02 12:41:04 -05:00
gboolean
nm_config_get_configure_and_quit ( NMConfig * config )
{
return NM_CONFIG_GET_PRIVATE ( config ) - > configure_and_quit ;
}
2013-03-12 13:14:54 -04:00
/************************************************************************/
2015-01-07 16:12:01 +01:00
static char * *
no_auto_default_merge_from_file ( const char * no_auto_default_file , const char * const * no_auto_default )
2013-03-12 13:14:54 -04:00
{
GPtrArray * updated ;
char * * list ;
int i , j ;
char * data ;
updated = g_ptr_array_new ( ) ;
2015-01-07 16:12:01 +01:00
if ( no_auto_default ) {
for ( i = 0 ; no_auto_default [ i ] ; i + + )
g_ptr_array_add ( updated , g_strdup ( no_auto_default [ i ] ) ) ;
2013-03-12 13:14:54 -04:00
}
2015-01-07 16:12:01 +01:00
if ( no_auto_default_file
& & g_file_get_contents ( no_auto_default_file , & data , NULL , NULL ) ) {
2013-03-12 13:14:54 -04:00
list = g_strsplit ( data , " \n " , - 1 ) ;
for ( i = 0 ; list [ i ] ; i + + ) {
if ( ! * list [ i ] )
2015-01-15 14:11:26 +01:00
g_free ( list [ i ] ) ;
else {
for ( j = 0 ; j < updated - > len ; j + + ) {
if ( ! strcmp ( list [ i ] , updated - > pdata [ j ] ) )
break ;
}
if ( j = = updated - > len )
g_ptr_array_add ( updated , list [ i ] ) ;
else
g_free ( list [ i ] ) ;
2013-03-12 13:14:54 -04:00
}
}
g_free ( list ) ;
g_free ( data ) ;
}
g_ptr_array_add ( updated , NULL ) ;
2015-01-07 16:12:01 +01:00
return ( char * * ) g_ptr_array_free ( updated , FALSE ) ;
2013-03-12 13:14:54 -04:00
}
gboolean
2015-01-07 17:09:52 +01:00
nm_config_get_no_auto_default_for_device ( NMConfig * self , NMDevice * device )
2013-03-12 13:14:54 -04:00
{
2015-01-07 17:09:52 +01:00
NMConfigData * config_data ;
2014-07-17 16:24:17 -04:00
2015-01-07 17:09:52 +01:00
g_return_val_if_fail ( NM_IS_CONFIG ( self ) , FALSE ) ;
g_return_val_if_fail ( NM_IS_DEVICE ( device ) , FALSE ) ;
2013-03-12 13:14:54 -04:00
2015-01-07 17:09:52 +01:00
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 ) ) ;
2013-03-12 13:14:54 -04:00
}
void
2015-01-07 17:09:52 +01:00
nm_config_set_no_auto_default_for_device ( NMConfig * self , NMDevice * device )
2013-03-12 13:14:54 -04:00
{
2015-01-07 17:09:52 +01:00
NMConfigPrivate * priv = NM_CONFIG_GET_PRIVATE ( self ) ;
2014-06-21 12:44:56 -04:00
char * current ;
2013-03-12 13:14:54 -04:00
GString * updated ;
GError * error = NULL ;
2015-01-07 16:12:01 +01:00
char * * no_auto_default ;
2015-01-07 17:09:52 +01:00
NMConfigData * new_data = NULL ;
2013-03-12 13:14:54 -04:00
2015-01-07 17:09:52 +01:00
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 ) )
2013-03-12 13:14:54 -04:00
return ;
updated = g_string_new ( NULL ) ;
if ( g_file_get_contents ( priv - > no_auto_default_file , & current , NULL , NULL ) ) {
g_string_append ( updated , current ) ;
g_free ( current ) ;
if ( updated - > str [ updated - > len - 1 ] ! = ' \n ' )
g_string_append_c ( updated , ' \n ' ) ;
}
2014-06-21 12:44:56 -04:00
g_string_append ( updated , nm_device_get_hw_address ( device ) ) ;
2013-03-12 13:14:54 -04:00
g_string_append_c ( updated , ' \n ' ) ;
if ( ! g_file_set_contents ( priv - > no_auto_default_file , updated - > str , updated - > len , & error ) ) {
nm_log_warn ( LOGD_SETTINGS , " Could not update no-auto-default.state file: %s " ,
error - > message ) ;
g_error_free ( error ) ;
}
g_string_free ( updated , TRUE ) ;
2015-01-07 17:09:52 +01:00
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 ) ;
2015-06-25 21:10:32 +02:00
_set_config_data ( self , new_data , 0 ) ;
2013-03-12 13:14:54 -04:00
}
2013-03-11 12:06:38 -04:00
/************************************************************************/
2014-07-09 15:17:01 +02:00
static void
_nm_config_cmd_line_options_clear ( NMConfigCmdLineOptions * cli )
2013-03-11 12:06:38 -04:00
{
2014-12-16 11:02:57 +01:00
g_clear_pointer ( & cli - > config_main_file , g_free ) ;
2014-07-09 15:17:01 +02:00
g_clear_pointer ( & cli - > config_dir , g_free ) ;
g_clear_pointer ( & cli - > no_auto_default_file , g_free ) ;
g_clear_pointer ( & cli - > plugins , g_free ) ;
2015-02-06 11:54:16 +01:00
cli - > configure_and_quit = FALSE ;
2014-07-09 15:17:01 +02:00
g_clear_pointer ( & cli - > connectivity_uri , g_free ) ;
g_clear_pointer ( & cli - > connectivity_response , g_free ) ;
cli - > connectivity_interval = - 1 ;
}
static void
_nm_config_cmd_line_options_copy ( const NMConfigCmdLineOptions * cli , NMConfigCmdLineOptions * dst )
{
g_return_if_fail ( cli ) ;
g_return_if_fail ( dst ) ;
g_return_if_fail ( cli ! = dst ) ;
_nm_config_cmd_line_options_clear ( dst ) ;
dst - > config_dir = g_strdup ( cli - > config_dir ) ;
2014-12-16 11:02:57 +01:00
dst - > config_main_file = g_strdup ( cli - > config_main_file ) ;
2014-07-09 15:17:01 +02:00
dst - > no_auto_default_file = g_strdup ( cli - > no_auto_default_file ) ;
dst - > plugins = g_strdup ( cli - > plugins ) ;
2015-02-06 11:54:16 +01:00
dst - > configure_and_quit = cli - > configure_and_quit ;
2014-07-09 15:17:01 +02:00
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 [ ] = {
2014-12-16 11:02:57 +01:00
{ " config " , 0 , 0 , G_OPTION_ARG_FILENAME , & cli - > config_main_file , N_ ( " Config file location " ) , N_ ( " /path/to/config.file " ) } ,
2014-07-09 15:17:01 +02:00
{ " 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 " ) } ,
2015-02-06 11:54:16 +01:00
{ " configure-and-quit " , 0 , 0 , G_OPTION_ARG_NONE , & cli - > configure_and_quit , N_ ( " Quit after initial configuration " ) , NULL } ,
2014-07-09 15:17:01 +02:00
/* These three are hidden for now, and should eventually just go away. */
{ " connectivity-uri " , 0 , G_OPTION_FLAG_HIDDEN , G_OPTION_ARG_STRING , & cli - > connectivity_uri , N_ ( " An http(s) address for checking internet connectivity " ) , " http://example.com " } ,
{ " connectivity-interval " , 0 , G_OPTION_FLAG_HIDDEN , G_OPTION_ARG_INT , & cli - > connectivity_interval , N_ ( " The interval between connectivity checks (in seconds) " ) , " 60 " } ,
{ " connectivity-response " , 0 , G_OPTION_FLAG_HIDDEN , G_OPTION_ARG_STRING , & cli - > connectivity_response , N_ ( " The expected start of the response " ) , N_ ( " Bingo! " ) } ,
{ 0 } ,
} ;
g_option_context_add_main_entries ( opt_ctx , config_options , NULL ) ;
}
2013-03-11 12:06:38 -04:00
}
2011-10-21 21:21:30 +02:00
2011-09-22 10:16:07 -05:00
/************************************************************************/
2014-12-16 12:14:30 +01:00
GKeyFile *
nm_config_create_keyfile ( )
{
GKeyFile * keyfile ;
keyfile = g_key_file_new ( ) ;
g_key_file_set_list_separator ( keyfile , ' , ' ) ;
return keyfile ;
}
2011-09-22 10:16:07 -05:00
static gboolean
2014-12-16 10:53:58 +01:00
read_config ( GKeyFile * keyfile , const char * path , GError * * error )
2011-09-22 10:16:07 -05:00
{
GKeyFile * kf ;
2013-03-14 14:34:36 -04:00
char * * groups , * * keys ;
gsize ngroups , nkeys ;
int g , k ;
2011-09-22 10:16:07 -05:00
2014-12-16 10:53:58 +01:00
g_return_val_if_fail ( keyfile , FALSE ) ;
2014-12-16 12:14:30 +01:00
g_return_val_if_fail ( path , FALSE ) ;
g_return_val_if_fail ( ! error | | ! * error , FALSE ) ;
2014-12-16 10:53:58 +01:00
2011-09-22 10:16:07 -05:00
if ( g_file_test ( path , G_FILE_TEST_EXISTS ) = = FALSE ) {
2011-10-01 00:22:09 +02:00
g_set_error ( error , G_KEY_FILE_ERROR , G_KEY_FILE_ERROR_NOT_FOUND , " file %s not found " , path ) ;
2011-09-22 10:16:07 -05:00
return FALSE ;
}
2013-06-14 16:05:04 -04:00
nm_log_dbg ( LOGD_SETTINGS , " Reading config file '%s' " , path ) ;
2014-12-16 12:14:30 +01:00
kf = nm_config_create_keyfile ( ) ;
2013-03-14 14:34:36 -04:00
if ( ! g_key_file_load_from_file ( kf , path , G_KEY_FILE_NONE , error ) ) {
g_key_file_free ( kf ) ;
return FALSE ;
}
2011-09-22 10:16:07 -05:00
2013-03-14 14:34:36 -04:00
/* Override the current settings with the new ones */
groups = g_key_file_get_groups ( kf , & ngroups ) ;
for ( g = 0 ; groups [ g ] ; g + + ) {
keys = g_key_file_get_keys ( kf , groups [ g ] , & nkeys , NULL ) ;
if ( ! keys )
continue ;
for ( k = 0 ; keys [ k ] ; k + + ) {
int len = strlen ( keys [ k ] ) ;
2015-01-28 22:56:34 +01:00
char * v ;
2013-03-14 14:34:36 -04:00
if ( keys [ k ] [ len - 1 ] = = ' + ' ) {
char * base_key = g_strndup ( keys [ k ] , len - 1 ) ;
2015-02-08 10:04:06 +01:00
char * old_val = g_key_file_get_value ( keyfile , groups [ g ] , base_key , NULL ) ;
char * new_val = g_key_file_get_value ( kf , groups [ g ] , keys [ k ] , NULL ) ;
2013-03-14 14:34:36 -04:00
if ( old_val & & * old_val ) {
char * combined = g_strconcat ( old_val , " , " , new_val , NULL ) ;
2014-12-16 10:53:58 +01:00
g_key_file_set_value ( keyfile , groups [ g ] , base_key , combined ) ;
2013-03-14 14:34:36 -04:00
g_free ( combined ) ;
} else
2014-12-16 10:53:58 +01:00
g_key_file_set_value ( keyfile , groups [ g ] , base_key , new_val ) ;
2013-03-14 14:34:36 -04:00
g_free ( base_key ) ;
2015-02-08 10:04:06 +01:00
g_free ( old_val ) ;
g_free ( new_val ) ;
2013-03-14 14:34:36 -04:00
continue ;
}
2011-09-22 10:16:07 -05:00
2014-12-16 10:53:58 +01:00
g_key_file_set_value ( keyfile , groups [ g ] , keys [ k ] ,
2015-01-28 22:56:34 +01:00
v = g_key_file_get_value ( kf , groups [ g ] , keys [ k ] , NULL ) ) ;
g_free ( v ) ;
2013-03-14 14:34:36 -04:00
}
2015-01-28 22:56:34 +01:00
g_strfreev ( keys ) ;
2013-03-14 14:34:36 -04:00
}
2015-01-28 22:56:34 +01:00
g_strfreev ( groups ) ;
2013-03-14 14:34:36 -04:00
g_key_file_free ( kf ) ;
2011-09-22 10:16:07 -05:00
2013-03-14 14:34:36 -04:00
return TRUE ;
}
2011-09-22 10:16:07 -05:00
2013-03-14 14:34:36 -04:00
static gboolean
2014-12-16 10:53:58 +01:00
read_base_config ( GKeyFile * keyfile ,
2014-12-16 11:02:57 +01:00
const char * cli_config_main_file ,
char * * out_config_main_file ,
2014-12-16 10:53:58 +01:00
GError * * error )
2013-03-14 14:34:36 -04:00
{
GError * my_error = NULL ;
2011-10-21 21:21:30 +02:00
2014-12-16 10:53:58 +01:00
g_return_val_if_fail ( keyfile , FALSE ) ;
2014-12-16 11:02:57 +01:00
g_return_val_if_fail ( out_config_main_file & & ! * out_config_main_file , FALSE ) ;
2014-12-16 10:53:58 +01:00
g_return_val_if_fail ( ! error | | ! * error , FALSE ) ;
2013-03-14 14:34:36 -04:00
/* Try a user-specified config file first */
2014-12-16 11:02:57 +01:00
if ( cli_config_main_file ) {
2013-03-14 14:34:36 -04:00
/* Bad user-specific config file path is a hard error */
2014-12-16 11:02:57 +01:00
if ( read_config ( keyfile , cli_config_main_file , error ) ) {
* out_config_main_file = g_strdup ( cli_config_main_file ) ;
2013-03-14 14:34:36 -04:00
return TRUE ;
} else
return FALSE ;
}
2011-10-21 21:21:30 +02:00
2013-03-14 14:34:36 -04:00
/* Even though we prefer NetworkManager.conf, we need to check the
* old nm - system - settings . conf first to preserve compat with older
* setups . In package managed systems dropping a NetworkManager . conf
* onto the system would make NM use it instead of nm - system - settings . conf ,
* changing behavior during an upgrade . We don ' t want that .
*/
2011-10-21 21:21:30 +02:00
2013-03-14 14:34:36 -04:00
/* Try deprecated nm-system-settings.conf first */
2014-12-16 10:53:58 +01:00
if ( read_config ( keyfile , NM_OLD_SYSTEM_CONF_FILE , & my_error ) ) {
2014-12-16 11:02:57 +01:00
* out_config_main_file = g_strdup ( NM_OLD_SYSTEM_CONF_FILE ) ;
2013-03-14 14:34:36 -04:00
return TRUE ;
}
2011-10-21 21:21:30 +02:00
2013-03-14 14:34:36 -04:00
if ( ! g_error_matches ( my_error , G_KEY_FILE_ERROR , G_KEY_FILE_ERROR_NOT_FOUND ) ) {
2014-07-09 14:41:07 +02:00
nm_log_warn ( LOGD_CORE , " Old default config file %s invalid: %s \n " ,
NM_OLD_SYSTEM_CONF_FILE ,
my_error - > message ) ;
2013-03-14 14:34:36 -04:00
}
g_clear_error ( & my_error ) ;
2013-03-12 13:14:54 -04:00
2013-03-14 14:34:36 -04:00
/* Try the standard config file location next */
2014-12-16 10:53:58 +01:00
if ( read_config ( keyfile , NM_DEFAULT_SYSTEM_CONF_FILE , & my_error ) ) {
2014-12-16 11:02:57 +01:00
* out_config_main_file = g_strdup ( NM_DEFAULT_SYSTEM_CONF_FILE ) ;
2013-03-14 14:34:36 -04:00
return TRUE ;
}
2011-09-22 10:16:07 -05:00
2013-03-14 14:34:36 -04:00
if ( ! g_error_matches ( my_error , G_KEY_FILE_ERROR , G_KEY_FILE_ERROR_NOT_FOUND ) ) {
2014-07-09 14:41:07 +02:00
nm_log_warn ( LOGD_CORE , " Default config file %s invalid: %s \n " ,
NM_DEFAULT_SYSTEM_CONF_FILE ,
my_error - > message ) ;
2013-03-14 14:34:36 -04:00
g_propagate_error ( error , my_error ) ;
return FALSE ;
}
2014-07-09 14:37:54 +02:00
g_clear_error ( & my_error ) ;
2013-03-14 14:34:36 -04:00
/* If for some reason no config file exists, use the default
* config file path .
*/
2014-12-16 11:02:57 +01:00
* out_config_main_file = g_strdup ( NM_DEFAULT_SYSTEM_CONF_FILE ) ;
2014-07-09 14:41:07 +02:00
nm_log_info ( LOGD_CORE , " No config file found or given; using %s \n " ,
NM_DEFAULT_SYSTEM_CONF_FILE ) ;
2013-03-14 14:34:36 -04:00
return TRUE ;
2011-09-22 10:16:07 -05:00
}
2014-12-16 11:35:58 +01:00
static int
sort_asciibetically ( gconstpointer a , gconstpointer b )
{
const char * s1 = * ( const char * * ) a ;
const char * s2 = * ( const char * * ) b ;
return strcmp ( s1 , s2 ) ;
}
static GPtrArray *
_get_config_dir_files ( const char * config_main_file ,
const char * config_dir ,
char * * out_config_description )
{
GFile * dir ;
GFileEnumerator * direnum ;
GFileInfo * info ;
GPtrArray * confs ;
GString * config_description ;
const char * name ;
2015-04-17 13:24:32 +02:00
guint i ;
2014-12-16 11:35:58 +01:00
g_return_val_if_fail ( config_main_file , NULL ) ;
g_return_val_if_fail ( config_dir , NULL ) ;
g_return_val_if_fail ( out_config_description & & ! * out_config_description , NULL ) ;
confs = g_ptr_array_new_with_free_func ( g_free ) ;
config_description = g_string_new ( config_main_file ) ;
dir = g_file_new_for_path ( config_dir ) ;
direnum = g_file_enumerate_children ( dir , G_FILE_ATTRIBUTE_STANDARD_NAME , 0 , NULL , NULL ) ;
if ( direnum ) {
while ( ( info = g_file_enumerator_next_file ( direnum , NULL , NULL ) ) ) {
name = g_file_info_get_name ( info ) ;
2015-04-17 13:24:32 +02:00
if ( g_str_has_suffix ( name , " .conf " ) )
g_ptr_array_add ( confs , g_strdup ( name ) ) ;
2014-12-16 11:35:58 +01:00
g_object_unref ( info ) ;
}
g_object_unref ( direnum ) ;
}
g_object_unref ( dir ) ;
2015-04-17 13:24:32 +02:00
if ( confs - > len > 0 ) {
g_ptr_array_sort ( confs , sort_asciibetically ) ;
g_string_append ( config_description , " and conf.d: " ) ;
for ( i = 0 ; i < confs - > len ; i + + ) {
char * n = confs - > pdata [ i ] ;
if ( i > 0 )
g_string_append ( config_description , " , " ) ;
g_string_append ( config_description , n ) ;
confs - > pdata [ i ] = g_build_filename ( config_dir , n , NULL ) ;
g_free ( n ) ;
}
}
2014-12-16 11:35:58 +01:00
* out_config_description = g_string_free ( config_description , FALSE ) ;
return confs ;
}
2014-12-16 12:14:30 +01:00
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 ;
2014-12-16 15:36:56 +01:00
char * * plugins_tmp ;
2014-12-16 12:14:30 +01:00
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 */
2015-05-19 11:59:09 +02:00
if ( ! read_base_config ( keyfile , cli ? cli - > config_main_file : NULL , & o_config_main_file , error ) ) {
2014-12-16 12:14:30 +01:00
g_key_file_free ( keyfile ) ;
return NULL ;
}
g_assert ( o_config_main_file ) ;
confs = _get_config_dir_files ( o_config_main_file , config_dir , & o_config_description ) ;
for ( i = 0 ; i < confs - > len ; i + + ) {
if ( ! read_config ( keyfile , confs - > pdata [ i ] , error ) ) {
g_key_file_free ( keyfile ) ;
2014-12-16 15:36:56 +01:00
g_free ( o_config_main_file ) ;
g_free ( o_config_description ) ;
g_ptr_array_unref ( confs ) ;
return NULL ;
2014-12-16 12:14:30 +01:00
}
}
g_ptr_array_unref ( confs ) ;
2014-12-16 15:36:56 +01:00
/* 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 ) ;
2015-02-06 11:54:16 +01:00
if ( cli & & cli - > configure_and_quit )
g_key_file_set_value ( keyfile , " main " , " configure-and-quit " , " true " ) ;
2014-12-16 15:36:56 +01:00
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 ;
2014-12-16 12:14:30 +01:00
return keyfile ;
}
2015-02-09 16:36:53 +01:00
GSList *
nm_config_get_device_match_spec ( const GKeyFile * keyfile , const char * group , const char * key )
{
gs_free char * value = NULL ;
value = g_key_file_get_string ( ( GKeyFile * ) keyfile , group , key , NULL ) ;
return nm_match_spec_split ( value ) ;
}
2013-01-31 16:16:56 -06:00
/************************************************************************/
2014-07-09 18:54:47 +02:00
void
2015-06-25 21:10:32 +02:00
nm_config_reload ( NMConfig * self , int signal )
2014-07-09 18:54:47 +02:00
{
NMConfigPrivate * priv ;
GError * error = NULL ;
2014-12-16 16:52:34 +01:00
GKeyFile * keyfile ;
2014-07-09 18:54:47 +02:00
NMConfigData * new_data = NULL ;
2014-12-16 16:52:34 +01:00
char * config_main_file = NULL ;
char * config_description = NULL ;
2014-07-09 18:54:47 +02:00
g_return_if_fail ( NM_IS_CONFIG ( self ) ) ;
priv = NM_CONFIG_GET_PRIVATE ( self ) ;
2015-06-25 21:10:32 +02:00
if ( signal ! = SIGHUP ) {
_set_config_data ( self , NULL , signal ) ;
return ;
}
2014-07-09 18:54:47 +02:00
/* pass on the original command line options. This means, that
* options specified at command line cannot ever be reloaded from
* file . That seems desirable .
*/
2014-12-16 16:52:34 +01:00
keyfile = read_entire_config ( & priv - > cli ,
priv - > config_dir ,
& config_main_file ,
& config_description ,
& error ) ;
if ( ! keyfile ) {
2014-07-09 18:54:47 +02:00
nm_log_err ( LOGD_CORE , " Failed to reload the configuration: %s " , error - > message ) ;
g_clear_error ( & error ) ;
2015-06-25 21:10:32 +02:00
_set_config_data ( self , NULL , signal ) ;
2014-07-09 18:54:47 +02:00
return ;
}
2015-01-07 17:09:52 +01:00
new_data = nm_config_data_new ( config_main_file , config_description , nm_config_data_get_no_auto_default ( priv - > config_data ) , keyfile ) ;
2015-01-06 20:16:10 +01:00
g_free ( config_main_file ) ;
g_free ( config_description ) ;
2015-01-07 13:25:41 +01:00
g_key_file_unref ( keyfile ) ;
2014-07-09 18:54:47 +02:00
2015-06-25 21:10:32 +02:00
_set_config_data ( self , new_data , signal ) ;
2015-01-07 17:09:52 +01:00
}
2015-01-21 12:58:32 +01:00
static const char *
_change_flags_one_to_string ( NMConfigChangeFlags flag )
{
switch ( flag ) {
2015-06-25 21:10:32 +02:00
case NM_CONFIG_CHANGE_SIGHUP :
return " SIGHUP " ;
case NM_CONFIG_CHANGE_SIGUSR1 :
return " SIGUSR1 " ;
case NM_CONFIG_CHANGE_SIGUSR2 :
return " SIGUSR2 " ;
2015-01-21 12:58:32 +01:00
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 " ;
2015-02-12 17:35:14 +01:00
case NM_CONFIG_CHANGE_DNS_MODE :
return " dns-mode " ;
2015-04-20 11:11:32 +02:00
case NM_CONFIG_CHANGE_RC_MANAGER :
return " rc-manager " ;
2015-01-21 12:58:32 +01:00
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 ) ;
}
2015-01-07 17:09:52 +01:00
static void
2015-06-25 21:10:32 +02:00
_set_config_data ( NMConfig * self , NMConfigData * new_data , int signal )
2015-01-07 17:09:52 +01:00
{
NMConfigPrivate * priv = NM_CONFIG_GET_PRIVATE ( self ) ;
NMConfigData * old_data = priv - > config_data ;
2015-06-25 21:10:32 +02:00
NMConfigChangeFlags changes , changes_diff ;
2015-01-21 12:58:32 +01:00
gs_free char * log_str = NULL ;
2015-06-25 21:10:32 +02:00
gboolean had_new_data = ! ! new_data ;
switch ( signal ) {
case SIGHUP :
changes = NM_CONFIG_CHANGE_SIGHUP ;
break ;
case SIGUSR1 :
changes = NM_CONFIG_CHANGE_SIGUSR1 ;
break ;
case SIGUSR2 :
changes = NM_CONFIG_CHANGE_SIGUSR2 ;
break ;
default :
changes = NM_CONFIG_CHANGE_NONE ;
break ;
}
2015-01-07 17:09:52 +01:00
2015-06-25 21:10:32 +02:00
if ( new_data ) {
changes_diff = nm_config_data_diff ( old_data , new_data ) ;
if ( changes_diff = = NM_CONFIG_CHANGE_NONE )
g_clear_object ( & new_data ) ;
else
changes | = changes_diff ;
2014-07-09 18:54:47 +02:00
}
2015-06-25 21:10:32 +02:00
if ( changes = = NM_CONFIG_CHANGE_NONE )
return ;
if ( new_data ) {
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 ;
} else if ( had_new_data )
nm_log_info ( LOGD_CORE , " config: signal %s (no changes from disk) " , ( log_str = nm_config_change_flags_to_string ( changes ) ) ) ;
else
nm_log_info ( LOGD_CORE , " config: signal %s " , ( log_str = nm_config_change_flags_to_string ( changes ) ) ) ;
g_signal_emit ( self , signals [ SIGNAL_CONFIG_CHANGED ] , 0 ,
new_data ? new_data : old_data ,
changes , old_data ) ;
if ( new_data )
g_object_unref ( old_data ) ;
2014-07-09 18:54:47 +02:00
}
2014-07-09 15:17:01 +02:00
NM_DEFINE_SINGLETON_DESTRUCTOR ( NMConfig ) ;
NM_DEFINE_SINGLETON_WEAK_REF ( NMConfig ) ;
2013-01-31 16:16:56 -06:00
NMConfig *
nm_config_get ( void )
{
2014-07-09 15:17:01 +02:00
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 ;
2013-01-31 16:16:56 -06:00
}
2015-01-12 15:35:52 +01:00
static gboolean
init_sync ( GInitable * initable , GCancellable * cancellable , GError * * error )
2011-09-22 10:16:07 -05:00
{
2015-01-12 15:35:52 +01:00
NMConfig * self = NM_CONFIG ( initable ) ;
NMConfigPrivate * priv = NM_CONFIG_GET_PRIVATE ( self ) ;
2014-12-16 12:14:30 +01:00
GKeyFile * keyfile ;
2015-01-06 20:16:10 +01:00
char * config_main_file = NULL ;
char * config_description = NULL ;
2015-01-07 17:09:52 +01:00
char * * no_auto_default ;
2015-02-09 16:36:53 +01:00
GSList * no_auto_default_orig_list ;
GPtrArray * no_auto_default_orig ;
2014-07-09 15:17:01 +02:00
2015-01-12 15:35:52 +01:00
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 ;
}
2011-09-22 10:16:07 -05:00
2014-07-09 15:17:01 +02:00
if ( priv - > cli . config_dir )
priv - > config_dir = g_strdup ( priv - > cli . config_dir ) ;
2013-03-14 14:34:36 -04:00
else
priv - > config_dir = g_strdup ( NM_DEFAULT_SYSTEM_CONF_DIR ) ;
2014-12-16 12:14:30 +01:00
keyfile = read_entire_config ( & priv - > cli ,
priv - > config_dir ,
2015-01-06 20:16:10 +01:00
& config_main_file ,
& config_description ,
2014-12-16 12:14:30 +01:00
error ) ;
2015-01-12 15:35:52 +01:00
if ( ! keyfile )
return FALSE ;
2013-03-12 13:14:54 -04:00
2014-12-16 15:36:56 +01:00
/* Initialize read only private members */
2014-07-09 15:17:01 +02:00
if ( priv - > cli . no_auto_default_file )
priv - > no_auto_default_file = g_strdup ( priv - > cli . no_auto_default_file ) ;
2013-03-12 13:14:54 -04:00
else
priv - > no_auto_default_file = g_strdup ( NM_NO_AUTO_DEFAULT_STATE_FILE ) ;
2015-01-07 13:25:41 +01:00
priv - > plugins = g_key_file_get_string_list ( keyfile , " main " , " plugins " , NULL , NULL ) ;
2014-12-16 15:36:56 +01:00
if ( ! priv - > plugins )
priv - > plugins = g_new0 ( char * , 1 ) ;
2013-03-14 14:34:36 -04:00
2015-05-15 17:00:31 +02:00
priv - > monitor_connection_files = nm_config_keyfile_get_boolean ( keyfile , " main " , " monitor-connection-files " , FALSE ) ;
2013-05-23 19:05:40 -03:00
2015-05-15 17:00:31 +02:00
priv - > auth_polkit = nm_config_keyfile_get_boolean ( keyfile , " main " , " auth-polkit " , NM_CONFIG_DEFAULT_AUTH_POLKIT ) ;
2014-08-14 13:34:57 +02:00
2015-01-07 13:25:41 +01:00
priv - > dhcp_client = g_key_file_get_value ( keyfile , " main " , " dhcp " , NULL ) ;
2013-03-14 14:34:36 -04:00
2015-01-07 13:25:41 +01:00
priv - > log_level = g_key_file_get_value ( keyfile , " logging " , " level " , NULL ) ;
priv - > log_domains = g_key_file_get_value ( keyfile , " logging " , " domains " , NULL ) ;
2013-03-14 14:34:36 -04:00
2015-01-07 13:25:41 +01:00
priv - > debug = g_key_file_get_value ( keyfile , " main " , " debug " , NULL ) ;
2014-03-06 22:04:44 +01:00
2015-05-15 17:00:31 +02:00
priv - > configure_and_quit = nm_config_keyfile_get_boolean ( keyfile , " main " , " configure-and-quit " , FALSE ) ;
2014-04-02 12:41:04 -05:00
2015-02-09 16:36:53 +01:00
no_auto_default_orig_list = nm_config_get_device_match_spec ( keyfile , " main " , " no-auto-default " ) ;
no_auto_default_orig = _nm_utils_copy_slist_to_array ( no_auto_default_orig_list , NULL , NULL ) ;
g_ptr_array_add ( no_auto_default_orig , NULL ) ;
no_auto_default = no_auto_default_merge_from_file ( priv - > no_auto_default_file , ( const char * const * ) no_auto_default_orig - > pdata ) ;
g_ptr_array_unref ( no_auto_default_orig ) ;
g_slist_free_full ( no_auto_default_orig_list , g_free ) ;
2015-01-07 17:09:52 +01:00
priv - > config_data_orig = nm_config_data_new ( config_main_file , config_description , ( const char * const * ) no_auto_default , keyfile ) ;
g_strfreev ( no_auto_default ) ;
2014-12-16 16:52:34 +01:00
priv - > config_data = g_object_ref ( priv - > config_data_orig ) ;
2014-07-11 18:54:18 +02:00
2015-01-06 20:16:10 +01:00
g_free ( config_main_file ) ;
g_free ( config_description ) ;
2015-01-07 13:25:41 +01:00
g_key_file_unref ( keyfile ) ;
2015-01-12 15:35:52 +01:00
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 ) ) ;
2011-09-22 10:16:07 -05:00
}
2013-01-31 16:16:56 -06:00
static void
nm_config_init ( NMConfig * config )
{
2013-03-14 14:34:36 -04:00
NMConfigPrivate * priv = NM_CONFIG_GET_PRIVATE ( config ) ;
2014-08-14 13:34:57 +02:00
priv - > auth_polkit = NM_CONFIG_DEFAULT_AUTH_POLKIT ;
2013-01-31 16:16:56 -06:00
}
static void
2013-03-12 14:15:06 -04:00
finalize ( GObject * gobject )
2013-01-31 16:16:56 -06:00
{
2013-03-12 14:15:06 -04:00
NMConfigPrivate * priv = NM_CONFIG_GET_PRIVATE ( gobject ) ;
2013-01-31 16:16:56 -06:00
2013-03-14 14:34:36 -04:00
g_free ( priv - > config_dir ) ;
g_free ( priv - > no_auto_default_file ) ;
2013-03-12 14:15:06 -04:00
g_strfreev ( priv - > plugins ) ;
g_free ( priv - > dhcp_client ) ;
g_free ( priv - > log_level ) ;
g_free ( priv - > log_domains ) ;
2014-03-06 22:04:44 +01:00
g_free ( priv - > debug ) ;
2013-01-31 16:16:56 -06:00
2014-07-09 15:17:01 +02:00
_nm_config_cmd_line_options_clear ( & priv - > cli ) ;
2013-03-11 12:06:38 -04:00
2014-07-11 18:54:18 +02:00
g_clear_object ( & priv - > config_data ) ;
g_clear_object ( & priv - > config_data_orig ) ;
2013-01-31 16:16:56 -06:00
G_OBJECT_CLASS ( nm_config_parent_class ) - > finalize ( gobject ) ;
}
2014-12-16 15:10:24 +01:00
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 ;
}
}
2013-01-31 16:16:56 -06:00
static void
nm_config_class_init ( NMConfigClass * config_class )
{
GObjectClass * object_class = G_OBJECT_CLASS ( config_class ) ;
g_type_class_add_private ( config_class , sizeof ( NMConfigPrivate ) ) ;
object_class - > finalize = finalize ;
2014-12-16 15:10:24 +01:00
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 ) ) ;
2014-07-09 18:54:47 +02:00
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 ,
2015-01-21 12:58:32 +01:00
G_TYPE_NONE , 3 , NM_TYPE_CONFIG_DATA , NM_TYPE_CONFIG_CHANGE_FLAGS , NM_TYPE_CONFIG_DATA ) ;
2013-01-31 16:16:56 -06:00
}
2015-01-12 15:35:52 +01:00
static void
nm_config_initable_iface_init ( GInitableIface * iface )
{
iface - > init = init_sync ;
}