mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-09-16 06:40:41 +00:00
settings: return new connection object path from AddConnection
Finally.
This commit is contained in:
parent
856a1c6b2c
commit
37845af954
|
@ -29,6 +29,11 @@
|
|||
Connection settings and properties.
|
||||
</tp:docstring>
|
||||
</arg>
|
||||
<arg name="path" type="o" direction="out">
|
||||
<tp:docstring>
|
||||
Object path of the new connection that was just added.
|
||||
</tp:docstring>
|
||||
</arg>
|
||||
</method>
|
||||
|
||||
<method name="SaveHostname">
|
||||
|
|
|
@ -154,12 +154,12 @@ connection_init_result_cb (NMRemoteConnection *remote,
|
|||
g_signal_emit (self, signals[CONNECTIONS_READ], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
static NMRemoteConnection *
|
||||
new_connection_cb (DBusGProxy *proxy, const char *path, gpointer user_data)
|
||||
{
|
||||
NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data);
|
||||
NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
|
||||
NMRemoteConnection *connection;
|
||||
NMRemoteConnection *connection = NULL;
|
||||
|
||||
connection = nm_remote_connection_new (priv->bus, path);
|
||||
if (connection) {
|
||||
|
@ -177,6 +177,7 @@ new_connection_cb (DBusGProxy *proxy, const char *path, gpointer user_data)
|
|||
*/
|
||||
g_hash_table_insert (priv->pending, g_strdup (path), connection);
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -205,17 +206,17 @@ fetch_connections_done (DBusGProxy *proxy,
|
|||
}
|
||||
|
||||
/* Let listeners know we are done getting connections */
|
||||
if (connections->len == 0) {
|
||||
if (connections->len == 0)
|
||||
g_signal_emit (self, signals[CONNECTIONS_READ], 0);
|
||||
return;
|
||||
else {
|
||||
for (i = 0; i < connections->len; i++) {
|
||||
char *path = g_ptr_array_index (connections, i);
|
||||
|
||||
new_connection_cb (proxy, path, user_data);
|
||||
g_free (path);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; connections && (i < connections->len); i++) {
|
||||
char *path = g_ptr_array_index (connections, i);
|
||||
|
||||
new_connection_cb (proxy, path, user_data);
|
||||
g_free (path);
|
||||
}
|
||||
g_ptr_array_free (connections, TRUE);
|
||||
}
|
||||
|
||||
|
@ -268,13 +269,19 @@ typedef struct {
|
|||
|
||||
static void
|
||||
add_connection_done (DBusGProxy *proxy,
|
||||
char *path,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
AddConnectionInfo *info = user_data;
|
||||
NMRemoteConnection *connection;
|
||||
|
||||
connection = new_connection_cb (proxy, path, info->self);
|
||||
g_assert (connection);
|
||||
info->callback (info->self, connection, error, info->callback_data);
|
||||
|
||||
info->callback (info->self, error, info->callback_data);
|
||||
g_free (info);
|
||||
g_free (path);
|
||||
}
|
||||
/**
|
||||
* nm_remote_settings_add_connection:
|
||||
|
|
|
@ -51,6 +51,7 @@ typedef struct _NMRemoteSettingsClass NMRemoteSettingsClass;
|
|||
|
||||
|
||||
typedef void (*NMRemoteSettingsAddConnectionFunc) (NMRemoteSettings *settings,
|
||||
NMRemoteConnection *connection,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
|
|
|
@ -129,7 +129,6 @@ enum {
|
|||
NEW_CONNECTION, /* exported, not used internally */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
enum {
|
||||
|
@ -575,16 +574,45 @@ load_plugins (NMSettings *self, const char *plugins, GError **error)
|
|||
return success;
|
||||
}
|
||||
|
||||
#define REMOVED_ID_TAG "removed-id-tag"
|
||||
#define UPDATED_ID_TAG "updated-id-tag"
|
||||
#define VISIBLE_ID_TAG "visible-id-tag"
|
||||
|
||||
static void
|
||||
connection_removed (NMSysconfigConnection *connection, gpointer user_data)
|
||||
connection_removed (NMSysconfigConnection *obj, gpointer user_data)
|
||||
{
|
||||
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (user_data);
|
||||
GObject *connection = G_OBJECT (obj);
|
||||
guint id;
|
||||
|
||||
g_object_ref (connection);
|
||||
|
||||
g_hash_table_remove (NM_SETTINGS_GET_PRIVATE (user_data)->connections, connection);
|
||||
/* Disconnect signal handlers, as plugins might still keep references
|
||||
* to the connection (and thus the signal handlers would still be live)
|
||||
* even after NMSettings has dropped all its references.
|
||||
*/
|
||||
|
||||
id = GPOINTER_TO_UINT (g_object_get_data (connection, REMOVED_ID_TAG));
|
||||
if (id)
|
||||
g_signal_handler_disconnect (connection, id);
|
||||
|
||||
id = GPOINTER_TO_UINT (g_object_get_data (connection, UPDATED_ID_TAG));
|
||||
if (id)
|
||||
g_signal_handler_disconnect (connection, id);
|
||||
|
||||
id = GPOINTER_TO_UINT (g_object_get_data (connection, VISIBLE_ID_TAG));
|
||||
if (id)
|
||||
g_signal_handler_disconnect (connection, id);
|
||||
|
||||
/* Unregister the connection with D-Bus and forget about it */
|
||||
dbus_g_connection_unregister_g_object (priv->bus, connection);
|
||||
g_hash_table_remove (NM_SETTINGS_GET_PRIVATE (user_data)->connections,
|
||||
(gpointer) nm_connection_get_path (NM_CONNECTION (connection)));
|
||||
g_signal_emit (NM_SETTINGS (user_data),
|
||||
signals[CONNECTION_REMOVED],
|
||||
0,
|
||||
connection);
|
||||
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
|
@ -619,6 +647,7 @@ claim_connection (NMSettings *self,
|
|||
GHashTableIter iter;
|
||||
gpointer data;
|
||||
char *path;
|
||||
guint id;
|
||||
|
||||
g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection));
|
||||
|
||||
|
@ -640,19 +669,20 @@ claim_connection (NMSettings *self,
|
|||
/* Ensure it's initial visibility is up-to-date */
|
||||
nm_sysconfig_connection_recheck_visibility (connection);
|
||||
|
||||
g_signal_connect (connection,
|
||||
NM_SYSCONFIG_CONNECTION_REMOVED,
|
||||
G_CALLBACK (connection_removed),
|
||||
self);
|
||||
id = g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_REMOVED,
|
||||
G_CALLBACK (connection_removed),
|
||||
self);
|
||||
g_object_set_data (G_OBJECT (connection), REMOVED_ID_TAG, GUINT_TO_POINTER (id));
|
||||
|
||||
g_signal_connect (connection,
|
||||
NM_SYSCONFIG_CONNECTION_UPDATED,
|
||||
G_CALLBACK (connection_updated),
|
||||
self);
|
||||
id = g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_UPDATED,
|
||||
G_CALLBACK (connection_updated),
|
||||
self);
|
||||
g_object_set_data (G_OBJECT (connection), UPDATED_ID_TAG, GUINT_TO_POINTER (id));
|
||||
|
||||
g_signal_connect (connection, "notify::" NM_SYSCONFIG_CONNECTION_VISIBLE,
|
||||
G_CALLBACK (connection_visibility_changed),
|
||||
self);
|
||||
id = g_signal_connect (connection, "notify::" NM_SYSCONFIG_CONNECTION_VISIBLE,
|
||||
G_CALLBACK (connection_visibility_changed),
|
||||
self);
|
||||
g_object_set_data (G_OBJECT (connection), VISIBLE_ID_TAG, GUINT_TO_POINTER (id));
|
||||
|
||||
/* Export the connection over D-Bus */
|
||||
g_warn_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL);
|
||||
|
@ -750,7 +780,7 @@ polkit_call_free (PolkitCall *call)
|
|||
g_free (call);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static NMSysconfigConnection *
|
||||
add_new_connection (NMSettings *self,
|
||||
NMConnection *connection,
|
||||
GError **error)
|
||||
|
@ -758,29 +788,28 @@ add_new_connection (NMSettings *self,
|
|||
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
||||
GError *tmp_error = NULL, *last_error = NULL;
|
||||
GSList *iter;
|
||||
gboolean success = FALSE;
|
||||
NMSysconfigConnection *added = NULL;
|
||||
|
||||
/* Here's how it works:
|
||||
1) plugin writes a connection.
|
||||
2) plugin notices that a new connection is available for reading.
|
||||
3) plugin reads the new connection (the one it wrote in 1) and emits 'connection-added' signal.
|
||||
4) NMSettings receives the signal and adds it to it's connection list.
|
||||
*/
|
||||
|
||||
for (iter = priv->plugins; iter && !success; iter = iter->next) {
|
||||
success = nm_system_config_interface_add_connection (NM_SYSTEM_CONFIG_INTERFACE (iter->data),
|
||||
connection,
|
||||
&tmp_error);
|
||||
/* 1) plugin writes the NMConnection to disk
|
||||
* 2) plugin creates a new NMSysconfigConnection subclass with the settings
|
||||
* from the NMConnection and returns it to the settings service
|
||||
* 3) settings service exports the new NMSysconfigConnection subclass
|
||||
* 4) plugin notices that something on the filesystem has changed
|
||||
* 5) plugin reads the changes and ignores them because they will
|
||||
* contain the same data as the connection it already knows about
|
||||
*/
|
||||
for (iter = priv->plugins; iter && !added; iter = g_slist_next (iter)) {
|
||||
added = nm_system_config_interface_add_connection (NM_SYSTEM_CONFIG_INTERFACE (iter->data),
|
||||
connection,
|
||||
&tmp_error);
|
||||
g_clear_error (&last_error);
|
||||
if (!success) {
|
||||
last_error = tmp_error;
|
||||
tmp_error = NULL;
|
||||
}
|
||||
if (!added)
|
||||
g_propagate_error (&last_error, tmp_error);
|
||||
}
|
||||
|
||||
if (!success)
|
||||
*error = last_error;
|
||||
return success;
|
||||
if (!added)
|
||||
g_propagate_error (error, last_error);
|
||||
return added;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -791,6 +820,7 @@ pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data)
|
|||
NMSettingsPrivate *priv;
|
||||
PolkitAuthorizationResult *pk_result;
|
||||
GError *error = NULL, *add_error = NULL;
|
||||
NMSysconfigConnection *added_connection;
|
||||
|
||||
/* If NMSettings is already gone, do nothing */
|
||||
if (call->disposed) {
|
||||
|
@ -825,8 +855,9 @@ pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (add_new_connection (self, call->connection, &add_error))
|
||||
dbus_g_method_return (call->context);
|
||||
added_connection = add_new_connection (self, call->connection, &add_error);
|
||||
if (added_connection)
|
||||
dbus_g_method_return (call->context, added_connection);
|
||||
else {
|
||||
error = g_error_new (NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_ADD_FAILED,
|
||||
|
@ -1201,6 +1232,7 @@ default_wired_try_update (NMDefaultWiredConnection *wired,
|
|||
GError *error = NULL;
|
||||
NMSettingConnection *s_con;
|
||||
const char *id;
|
||||
NMSysconfigConnection *added;
|
||||
|
||||
/* Try to move this default wired conneciton to a plugin so that it has
|
||||
* persistent storage.
|
||||
|
@ -1213,7 +1245,8 @@ default_wired_try_update (NMDefaultWiredConnection *wired,
|
|||
g_assert (id);
|
||||
|
||||
remove_default_wired_connection (self, NM_SYSCONFIG_CONNECTION (wired), FALSE);
|
||||
if (add_new_connection (self, NM_CONNECTION (wired), &error)) {
|
||||
added = add_new_connection (self, NM_CONNECTION (wired), &error);
|
||||
if (added) {
|
||||
nm_sysconfig_connection_delete (NM_SYSCONFIG_CONNECTION (wired),
|
||||
delete_cb,
|
||||
NULL);
|
||||
|
@ -1229,6 +1262,7 @@ default_wired_try_update (NMDefaultWiredConnection *wired,
|
|||
id,
|
||||
error ? error->code : -1,
|
||||
(error && error->message) ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
|
||||
/* If there was an error, don't destroy the default wired connection,
|
||||
* but add it back to the system settings service. Connection is already
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Red Hat, Inc.
|
||||
* Copyright (C) 2007 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
|
@ -146,18 +146,16 @@ nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
NMSysconfigConnection *
|
||||
nm_system_config_interface_add_connection (NMSystemConfigInterface *config,
|
||||
NMConnection *connection,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (config != NULL, FALSE);
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
|
||||
|
||||
if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection)
|
||||
success = NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection (config, connection, error);
|
||||
return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection (config, connection, error);
|
||||
|
||||
return success;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -117,11 +117,13 @@ struct _NMSystemConfigInterface {
|
|||
GSList * (*get_unmanaged_specs) (NMSystemConfigInterface *config);
|
||||
|
||||
/*
|
||||
* Add a new connection.
|
||||
* Save the given connection to backing storage, and return a new
|
||||
* NMSysconfigConnection subclass that contains the same settings as the
|
||||
* original connection.
|
||||
*/
|
||||
gboolean (*add_connection) (NMSystemConfigInterface *config,
|
||||
NMConnection *connection,
|
||||
GError **error);
|
||||
NMSysconfigConnection * (*add_connection) (NMSystemConfigInterface *config,
|
||||
NMConnection *connection,
|
||||
GError **error);
|
||||
|
||||
/* Signals */
|
||||
|
||||
|
@ -142,9 +144,9 @@ GSList *nm_system_config_interface_get_connections (NMSystemConfigInterface *con
|
|||
|
||||
GSList *nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config);
|
||||
|
||||
gboolean nm_system_config_interface_add_connection (NMSystemConfigInterface *config,
|
||||
NMConnection *connection,
|
||||
GError **error);
|
||||
NMSysconfigConnection *nm_system_config_interface_add_connection (NMSystemConfigInterface *config,
|
||||
NMConnection *connection,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2008 - 2009 Red Hat, Inc.
|
||||
* Copyright (C) 2008 - 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
@ -47,7 +47,7 @@ G_DEFINE_TYPE (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_SYSCONFIG_CONNECT
|
|||
typedef struct {
|
||||
gulong ih_event_id;
|
||||
|
||||
char *filename;
|
||||
char *path;
|
||||
int file_wd;
|
||||
|
||||
char *keyfile;
|
||||
|
@ -64,9 +64,7 @@ typedef struct {
|
|||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_FILENAME,
|
||||
PROP_UNMANAGED,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
|
@ -87,7 +85,10 @@ files_changed_cb (NMInotifyHelper *ih,
|
|||
NMIfcfgConnection *self = NM_IFCFG_CONNECTION (user_data);
|
||||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
if ((evt->wd != priv->file_wd) && (evt->wd != priv->keyfile_wd) && (evt->wd != priv->routefile_wd) && (evt->wd != priv->route6file_wd))
|
||||
if ( (evt->wd != priv->file_wd)
|
||||
&& (evt->wd != priv->keyfile_wd)
|
||||
&& (evt->wd != priv->routefile_wd)
|
||||
&& (evt->wd != priv->route6file_wd))
|
||||
return;
|
||||
|
||||
/* push the event up to the plugin */
|
||||
|
@ -95,7 +96,8 @@ files_changed_cb (NMInotifyHelper *ih,
|
|||
}
|
||||
|
||||
NMIfcfgConnection *
|
||||
nm_ifcfg_connection_new (const char *filename,
|
||||
nm_ifcfg_connection_new (const char *full_path,
|
||||
NMConnection *source,
|
||||
GError **error,
|
||||
gboolean *ignore_error)
|
||||
{
|
||||
|
@ -108,14 +110,24 @@ nm_ifcfg_connection_new (const char *filename,
|
|||
char *route6file = NULL;
|
||||
NMInotifyHelper *ih;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
g_return_val_if_fail (full_path != NULL, NULL);
|
||||
|
||||
tmp = connection_from_file (filename, NULL, NULL, NULL, &unmanaged, &keyfile, &routefile, &route6file, error, ignore_error);
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
/* If we're given a connection already, prefer that instead of re-reading */
|
||||
if (source)
|
||||
tmp = g_object_ref (source);
|
||||
else {
|
||||
tmp = connection_from_file (full_path, NULL, NULL, NULL,
|
||||
&unmanaged,
|
||||
&keyfile,
|
||||
&routefile,
|
||||
&route6file,
|
||||
error,
|
||||
ignore_error);
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
object = (GObject *) g_object_new (NM_TYPE_IFCFG_CONNECTION,
|
||||
NM_IFCFG_CONNECTION_FILENAME, filename,
|
||||
NM_IFCFG_CONNECTION_UNMANAGED, unmanaged,
|
||||
NULL);
|
||||
if (!object) {
|
||||
|
@ -128,11 +140,12 @@ nm_ifcfg_connection_new (const char *filename,
|
|||
g_object_unref (tmp);
|
||||
|
||||
priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
|
||||
priv->path = g_strdup (full_path);
|
||||
|
||||
ih = nm_inotify_helper_get ();
|
||||
priv->ih_event_id = g_signal_connect (ih, "event", G_CALLBACK (files_changed_cb), object);
|
||||
|
||||
priv->file_wd = nm_inotify_helper_add_watch (ih, filename);
|
||||
priv->file_wd = nm_inotify_helper_add_watch (ih, full_path);
|
||||
|
||||
priv->keyfile = keyfile;
|
||||
priv->keyfile_wd = nm_inotify_helper_add_watch (ih, keyfile);
|
||||
|
@ -147,11 +160,11 @@ nm_ifcfg_connection_new (const char *filename,
|
|||
}
|
||||
|
||||
const char *
|
||||
nm_ifcfg_connection_get_filename (NMIfcfgConnection *self)
|
||||
nm_ifcfg_connection_get_path (NMIfcfgConnection *self)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL);
|
||||
|
||||
return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->filename;
|
||||
return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->path;
|
||||
}
|
||||
|
||||
const char *
|
||||
|
@ -176,7 +189,7 @@ commit_changes (NMSysconfigConnection *connection,
|
|||
* processes on-disk, read the existing connection back in and only rewrite
|
||||
* it if it's really changed.
|
||||
*/
|
||||
reread = connection_from_file (priv->filename, NULL, NULL, NULL,
|
||||
reread = connection_from_file (priv->path, NULL, NULL, NULL,
|
||||
&unmanaged, &keyfile, &routefile, &route6file,
|
||||
NULL, NULL);
|
||||
g_free (unmanaged);
|
||||
|
@ -191,7 +204,7 @@ commit_changes (NMSysconfigConnection *connection,
|
|||
|
||||
if (!writer_update_connection (NM_CONNECTION (connection),
|
||||
IFCFG_DIR,
|
||||
priv->filename,
|
||||
priv->path,
|
||||
priv->keyfile,
|
||||
&error)) {
|
||||
callback (connection, error, user_data);
|
||||
|
@ -212,7 +225,7 @@ do_delete (NMSysconfigConnection *connection,
|
|||
{
|
||||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection);
|
||||
|
||||
g_unlink (priv->filename);
|
||||
g_unlink (priv->path);
|
||||
if (priv->keyfile)
|
||||
g_unlink (priv->keyfile);
|
||||
if (priv->routefile)
|
||||
|
@ -243,7 +256,7 @@ finalize (GObject *object)
|
|||
|
||||
g_signal_handler_disconnect (ih, priv->ih_event_id);
|
||||
|
||||
g_free (priv->filename);
|
||||
g_free (priv->path);
|
||||
if (priv->file_wd >= 0)
|
||||
nm_inotify_helper_remove_watch (ih, priv->file_wd);
|
||||
|
||||
|
@ -269,10 +282,6 @@ set_property (GObject *object, guint prop_id,
|
|||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_FILENAME:
|
||||
/* Construct only */
|
||||
priv->filename = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_UNMANAGED:
|
||||
priv->unmanaged = g_value_dup_string (value);
|
||||
break;
|
||||
|
@ -289,9 +298,6 @@ get_property (GObject *object, guint prop_id,
|
|||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_FILENAME:
|
||||
g_value_set_string (value, priv->filename);
|
||||
break;
|
||||
case PROP_UNMANAGED:
|
||||
g_value_set_string (value, priv->unmanaged);
|
||||
break;
|
||||
|
@ -317,14 +323,6 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class)
|
|||
sysconfig_class->commit_changes = commit_changes;
|
||||
|
||||
/* Properties */
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_FILENAME,
|
||||
g_param_spec_string (NM_IFCFG_CONNECTION_FILENAME,
|
||||
"FileName",
|
||||
"File name",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_UNMANAGED,
|
||||
g_param_spec_string (NM_IFCFG_CONNECTION_UNMANAGED,
|
||||
|
|
|
@ -33,7 +33,6 @@ G_BEGIN_DECLS
|
|||
#define NM_IS_IFCFG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_IFCFG_CONNECTION))
|
||||
#define NM_IFCFG_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionClass))
|
||||
|
||||
#define NM_IFCFG_CONNECTION_FILENAME "filename"
|
||||
#define NM_IFCFG_CONNECTION_UNMANAGED "unmanaged"
|
||||
|
||||
typedef struct {
|
||||
|
@ -47,10 +46,11 @@ typedef struct {
|
|||
GType nm_ifcfg_connection_get_type (void);
|
||||
|
||||
NMIfcfgConnection *nm_ifcfg_connection_new (const char *filename,
|
||||
NMConnection *source,
|
||||
GError **error,
|
||||
gboolean *ignore_error);
|
||||
|
||||
const char *nm_ifcfg_connection_get_filename (NMIfcfgConnection *self);
|
||||
const char *nm_ifcfg_connection_get_path (NMIfcfgConnection *self);
|
||||
|
||||
const char *nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self);
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Red Hat, Inc.
|
||||
* Copyright (C) 2007 - 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
@ -62,20 +62,12 @@ static gboolean impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin,
|
|||
|
||||
#include "nm-ifcfg-rh-glue.h"
|
||||
|
||||
static void connection_new_or_changed (SCPluginIfcfg *plugin,
|
||||
const char *path,
|
||||
NMIfcfgConnection *existing);
|
||||
|
||||
static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
|
||||
|
||||
static void connection_changed_handler (SCPluginIfcfg *plugin,
|
||||
const char *path,
|
||||
NMIfcfgConnection *connection,
|
||||
gboolean *do_remove,
|
||||
gboolean *do_new);
|
||||
|
||||
static void handle_connection_remove_or_new (SCPluginIfcfg *plugin,
|
||||
const char *path,
|
||||
NMIfcfgConnection *connection,
|
||||
gboolean do_remove,
|
||||
gboolean do_new);
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0,
|
||||
G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE,
|
||||
system_config_interface_init))
|
||||
|
@ -109,65 +101,67 @@ static void
|
|||
connection_ifcfg_changed (NMIfcfgConnection *connection, gpointer user_data)
|
||||
{
|
||||
SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data);
|
||||
gboolean do_remove = FALSE, do_new = FALSE;
|
||||
const char *path;
|
||||
|
||||
path = nm_ifcfg_connection_get_filename (connection);
|
||||
path = nm_ifcfg_connection_get_path (connection);
|
||||
g_return_if_fail (path != NULL);
|
||||
|
||||
connection_changed_handler (plugin, path, connection, &do_remove, &do_new);
|
||||
handle_connection_remove_or_new (plugin, path, connection, do_remove, do_new);
|
||||
connection_new_or_changed (plugin, path, connection);
|
||||
}
|
||||
|
||||
static NMIfcfgConnection *
|
||||
read_one_connection (SCPluginIfcfg *plugin, const char *filename)
|
||||
_internal_new_connection (SCPluginIfcfg *self,
|
||||
const char *path,
|
||||
NMConnection *source,
|
||||
GError **error)
|
||||
{
|
||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
|
||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
|
||||
NMIfcfgConnection *connection;
|
||||
GError *error = NULL;
|
||||
NMSettingConnection *s_con;
|
||||
const char *cid;
|
||||
GError *local = NULL;
|
||||
gboolean ignore_error = FALSE;
|
||||
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "parsing %s ... ", filename);
|
||||
if (!source) {
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "parsing %s ... ", path);
|
||||
}
|
||||
|
||||
connection = nm_ifcfg_connection_new (filename, &error, &ignore_error);
|
||||
if (connection) {
|
||||
NMSettingConnection *s_con;
|
||||
const char *cid;
|
||||
|
||||
s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION);
|
||||
g_assert (s_con);
|
||||
|
||||
cid = nm_setting_connection_get_id (s_con);
|
||||
g_assert (cid);
|
||||
|
||||
g_hash_table_insert (priv->connections,
|
||||
(gpointer) nm_ifcfg_connection_get_filename (connection),
|
||||
g_object_ref (connection));
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " read connection '%s'", cid);
|
||||
|
||||
if (nm_ifcfg_connection_get_unmanaged_spec (connection)) {
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' and its "
|
||||
"device due to NM_CONTROLLED/BRIDGE/VLAN.", cid);
|
||||
g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
|
||||
} else {
|
||||
/* Wait for the connection to become unmanaged once it knows the
|
||||
* UDI of it's device, if/when the device gets plugged in.
|
||||
*/
|
||||
g_signal_connect (G_OBJECT (connection), "notify::unmanaged",
|
||||
G_CALLBACK (connection_unmanaged_changed), plugin);
|
||||
}
|
||||
|
||||
/* watch changes of ifcfg hardlinks */
|
||||
g_signal_connect (G_OBJECT (connection), "ifcfg-changed",
|
||||
G_CALLBACK (connection_ifcfg_changed), plugin);
|
||||
} else {
|
||||
connection = nm_ifcfg_connection_new (path, source, &local, &ignore_error);
|
||||
if (!connection) {
|
||||
if (!ignore_error) {
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " error: %s",
|
||||
(error && error->message) ? error->message : "(unknown)");
|
||||
(local && local->message) ? local->message : "(unknown)");
|
||||
}
|
||||
g_clear_error (&error);
|
||||
g_propagate_error (error, local);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION);
|
||||
g_assert (s_con);
|
||||
cid = nm_setting_connection_get_id (s_con);
|
||||
g_assert (cid);
|
||||
|
||||
g_hash_table_insert (priv->connections,
|
||||
(gpointer) nm_ifcfg_connection_get_path (connection),
|
||||
connection);
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " read connection '%s'", cid);
|
||||
|
||||
if (nm_ifcfg_connection_get_unmanaged_spec (connection)) {
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' and its "
|
||||
"device due to NM_CONTROLLED/BRIDGE/VLAN.", cid);
|
||||
g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
|
||||
} else {
|
||||
/* Wait for the connection to become unmanaged once it knows the
|
||||
* hardware IDs of its device, if/when the device gets plugged in.
|
||||
*/
|
||||
g_signal_connect (G_OBJECT (connection), "notify::" NM_IFCFG_CONNECTION_UNMANAGED,
|
||||
G_CALLBACK (connection_unmanaged_changed), self);
|
||||
}
|
||||
|
||||
/* watch changes of ifcfg hardlinks */
|
||||
g_signal_connect (G_OBJECT (connection), "ifcfg-changed",
|
||||
G_CALLBACK (connection_ifcfg_changed), self);
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
@ -188,7 +182,7 @@ read_connections (SCPluginIfcfg *plugin)
|
|||
continue;
|
||||
|
||||
full_path = g_build_filename (IFCFG_DIR, item, NULL);
|
||||
read_one_connection (plugin, full_path);
|
||||
_internal_new_connection (plugin, full_path, NULL, NULL);
|
||||
g_free (full_path);
|
||||
}
|
||||
|
||||
|
@ -213,26 +207,53 @@ commit_cb (NMSysconfigConnection *connection, GError *error, gpointer unused)
|
|||
}
|
||||
|
||||
static void
|
||||
connection_changed_handler (SCPluginIfcfg *plugin,
|
||||
const char *path,
|
||||
NMIfcfgConnection *connection,
|
||||
gboolean *do_remove,
|
||||
gboolean *do_new)
|
||||
remove_connection (SCPluginIfcfg *self, NMIfcfgConnection *connection)
|
||||
{
|
||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
|
||||
gboolean managed = FALSE;
|
||||
const char *path;
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (connection != NULL);
|
||||
|
||||
managed = !!nm_ifcfg_connection_get_unmanaged_spec (connection);
|
||||
path = nm_ifcfg_connection_get_path (connection);
|
||||
|
||||
g_hash_table_remove (priv->connections, path);
|
||||
g_signal_emit_by_name (connection, NM_SYSCONFIG_CONNECTION_REMOVED);
|
||||
|
||||
/* Emit unmanaged changes _after_ removing the connection */
|
||||
if (managed == FALSE)
|
||||
g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
|
||||
}
|
||||
|
||||
static void
|
||||
connection_new_or_changed (SCPluginIfcfg *self,
|
||||
const char *path,
|
||||
NMIfcfgConnection *existing)
|
||||
{
|
||||
NMIfcfgConnection *new;
|
||||
GError *error = NULL;
|
||||
gboolean ignore_error = FALSE;
|
||||
const char *new_unmanaged = NULL, *old_unmanaged = NULL;
|
||||
|
||||
g_return_if_fail (plugin != NULL);
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (path != NULL);
|
||||
g_return_if_fail (connection != NULL);
|
||||
g_return_if_fail (do_remove != NULL);
|
||||
g_return_if_fail (do_new != NULL);
|
||||
|
||||
if (!existing) {
|
||||
/* Completely new connection */
|
||||
new = _internal_new_connection (self, path, NULL, NULL);
|
||||
if (new && !nm_ifcfg_connection_get_unmanaged_spec (new)) {
|
||||
/* Only managed connections are announced to the settings service */
|
||||
g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Existing connection that got changed */
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "updating %s", path);
|
||||
|
||||
new = (NMIfcfgConnection *) nm_ifcfg_connection_new (path, &error, &ignore_error);
|
||||
new = (NMIfcfgConnection *) nm_ifcfg_connection_new (path, NULL, &error, &ignore_error);
|
||||
if (!new) {
|
||||
/* errors reading connection; remove it */
|
||||
if (!ignore_error) {
|
||||
|
@ -242,19 +263,23 @@ connection_changed_handler (SCPluginIfcfg *plugin,
|
|||
g_clear_error (&error);
|
||||
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "removed %s.", path);
|
||||
*do_remove = TRUE;
|
||||
remove_connection (self, existing);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Successfully read connection changes */
|
||||
/* Successfully read connection */
|
||||
|
||||
old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (connection));
|
||||
old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (existing));
|
||||
new_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (new));
|
||||
|
||||
if (new_unmanaged) {
|
||||
if (!old_unmanaged) {
|
||||
/* Unexport the connection by destroying it, then re-creating it as unmanaged */
|
||||
*do_remove = *do_new = TRUE;
|
||||
/* Unexport the connection by telling the settings service it's
|
||||
* been removed, and notify the settings service by signalling that
|
||||
* unmanaged specs have changed.
|
||||
*/
|
||||
g_signal_emit_by_name (existing, NM_SYSCONFIG_CONNECTION_REMOVED);
|
||||
g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
|
||||
}
|
||||
} else {
|
||||
if (old_unmanaged) { /* now managed */
|
||||
|
@ -263,60 +288,25 @@ connection_changed_handler (SCPluginIfcfg *plugin,
|
|||
|
||||
s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (new), NM_TYPE_SETTING_CONNECTION);
|
||||
g_assert (s_con);
|
||||
|
||||
cid = nm_setting_connection_get_id (s_con);
|
||||
g_assert (cid);
|
||||
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Managing connection '%s' and its "
|
||||
"device because NM_CONTROLLED was true.", cid);
|
||||
g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection);
|
||||
g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, existing);
|
||||
}
|
||||
|
||||
nm_sysconfig_connection_replace_and_commit (NM_SYSCONFIG_CONNECTION (connection),
|
||||
nm_sysconfig_connection_replace_and_commit (NM_SYSCONFIG_CONNECTION (existing),
|
||||
NM_CONNECTION (new),
|
||||
commit_cb, NULL);
|
||||
|
||||
/* Update unmanaged status */
|
||||
g_object_set (connection, "unmanaged", new_unmanaged, NULL);
|
||||
g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
|
||||
g_object_set (existing, NM_IFCFG_CONNECTION_UNMANAGED, new_unmanaged, NULL);
|
||||
g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
|
||||
}
|
||||
g_object_unref (new);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_connection_remove_or_new (SCPluginIfcfg *plugin,
|
||||
const char *path,
|
||||
NMIfcfgConnection *connection,
|
||||
gboolean do_remove,
|
||||
gboolean do_new)
|
||||
{
|
||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
|
||||
|
||||
g_return_if_fail (plugin != NULL);
|
||||
g_return_if_fail (path != NULL);
|
||||
|
||||
if (do_remove) {
|
||||
const char *unmanaged;
|
||||
|
||||
g_return_if_fail (connection != NULL);
|
||||
|
||||
unmanaged = nm_ifcfg_connection_get_unmanaged_spec (connection);
|
||||
g_hash_table_remove (priv->connections, path);
|
||||
g_signal_emit_by_name (connection, "removed");
|
||||
|
||||
/* Emit unmanaged changes _after_ removing the connection */
|
||||
if (unmanaged)
|
||||
g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
|
||||
}
|
||||
|
||||
if (do_new) {
|
||||
connection = read_one_connection (plugin, path);
|
||||
if (connection) {
|
||||
if (!nm_ifcfg_connection_get_unmanaged_spec (connection))
|
||||
g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void
|
||||
dir_changed (GFileMonitor *monitor,
|
||||
GFile *file,
|
||||
|
@ -328,7 +318,6 @@ dir_changed (GFileMonitor *monitor,
|
|||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
|
||||
char *path, *name;
|
||||
NMIfcfgConnection *connection;
|
||||
gboolean do_remove = FALSE, do_new = FALSE;
|
||||
|
||||
path = g_file_get_path (file);
|
||||
if (utils_should_ignore_file (path, FALSE)) {
|
||||
|
@ -345,17 +334,12 @@ dir_changed (GFileMonitor *monitor,
|
|||
case G_FILE_MONITOR_EVENT_DELETED:
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "removed %s.", name);
|
||||
if (connection)
|
||||
handle_connection_remove_or_new (plugin, name, connection, TRUE, FALSE);
|
||||
remove_connection (plugin, connection);
|
||||
break;
|
||||
case G_FILE_MONITOR_EVENT_CREATED:
|
||||
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
|
||||
/* Update */
|
||||
if (!connection)
|
||||
do_new = TRUE;
|
||||
else
|
||||
connection_changed_handler (plugin, name, connection, &do_remove, &do_new);
|
||||
|
||||
handle_connection_remove_or_new (plugin, name, connection, do_remove, do_new);
|
||||
/* Update or new */
|
||||
connection_new_or_changed (plugin, name, connection);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -445,12 +429,22 @@ get_unmanaged_specs (NMSystemConfigInterface *config)
|
|||
return list;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static NMSysconfigConnection *
|
||||
add_connection (NMSystemConfigInterface *config,
|
||||
NMConnection *connection,
|
||||
GError **error)
|
||||
{
|
||||
return writer_new_connection (connection, IFCFG_DIR, NULL, error);
|
||||
SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config);
|
||||
NMIfcfgConnection *added = NULL;
|
||||
char *path = NULL;
|
||||
|
||||
/* Write it out first, then add the connection to our internal list */
|
||||
if (writer_new_connection (connection, IFCFG_DIR, &path, error)) {
|
||||
added = _internal_new_connection (self, path, connection, error);
|
||||
g_free (path);
|
||||
}
|
||||
return NM_SYSCONFIG_CONNECTION (added);
|
||||
|
||||
}
|
||||
|
||||
#define SC_NETWORK_FILE SYSCONFDIR"/sysconfig/network"
|
||||
|
|
|
@ -2973,8 +2973,8 @@ get_wireless_name (NMConnection * connection)
|
|||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ifnet_add_new_connection (NMConnection * connection,
|
||||
char *
|
||||
ifnet_add_new_connection (NMConnection *connection,
|
||||
const char *config_file,
|
||||
const char *wpa_file,
|
||||
GError **error)
|
||||
|
@ -3024,10 +3024,10 @@ ifnet_add_new_connection (NMConnection * connection,
|
|||
}
|
||||
|
||||
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Added new connection: %s, result: %s",
|
||||
new_name, success ? "success" : "fail");
|
||||
new_name, success ? "success" : "fail");
|
||||
|
||||
out:
|
||||
if (new_name)
|
||||
if (!success)
|
||||
g_free (new_name);
|
||||
return success;
|
||||
return success ? new_name : NULL;
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ gboolean ifnet_delete_connection_in_parsers (const char *conn_name,
|
|||
const char *config_file,
|
||||
const char *wpa_file);
|
||||
|
||||
gboolean ifnet_add_new_connection (NMConnection *connection,
|
||||
const char *config_file,
|
||||
const char *wpa_file,
|
||||
GError ** error);
|
||||
char * ifnet_add_new_connection (NMConnection *connection,
|
||||
const char *config_file,
|
||||
const char *wpa_file,
|
||||
GError ** error);
|
||||
#endif
|
||||
|
|
|
@ -57,25 +57,32 @@ typedef struct {
|
|||
} NMIfnetConnectionPrivate;
|
||||
|
||||
NMIfnetConnection *
|
||||
nm_ifnet_connection_new (gchar * conn_name)
|
||||
nm_ifnet_connection_new (const char *conn_name, NMConnection *source)
|
||||
{
|
||||
NMConnection *tmp;
|
||||
GObject *object;
|
||||
GError **error = NULL;
|
||||
|
||||
g_return_val_if_fail (conn_name != NULL, NULL);
|
||||
tmp = ifnet_update_connection_from_config_block (conn_name, error);
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
object = (GObject *) g_object_new (NM_TYPE_IFNET_CONNECTION,
|
||||
NM_IFNET_CONNECTION_CONN_NAME,
|
||||
conn_name, NULL);
|
||||
|
||||
if (source)
|
||||
tmp = g_object_ref (source);
|
||||
else {
|
||||
tmp = ifnet_update_connection_from_config_block (conn_name, error);
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
object = (GObject *) g_object_new (NM_TYPE_IFNET_CONNECTION, NULL);
|
||||
if (!object) {
|
||||
g_object_unref (tmp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NM_IFNET_CONNECTION_GET_PRIVATE (object)->conn_name = g_strdup (conn_name);
|
||||
nm_sysconfig_connection_replace_settings (NM_SYSCONFIG_CONNECTION (object), tmp, NULL);
|
||||
g_object_unref (tmp);
|
||||
|
||||
return NM_IFNET_CONNECTION (object);
|
||||
}
|
||||
|
||||
|
@ -144,44 +151,6 @@ do_delete (NMSysconfigConnection *connection,
|
|||
g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
NMIfnetConnectionPrivate *priv =
|
||||
NM_IFNET_CONNECTION_GET_PRIVATE (object);
|
||||
g_return_if_fail (priv);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CONN_NAME:
|
||||
if (priv->conn_name)
|
||||
g_free (priv->conn_name);
|
||||
priv->conn_name = g_strdup (g_value_get_pointer (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
NMIfnetConnectionPrivate *priv =
|
||||
NM_IFNET_CONNECTION_GET_PRIVATE (object);
|
||||
g_return_if_fail (priv);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CONN_NAME:
|
||||
g_value_set_pointer (value, priv->conn_name);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject * object)
|
||||
{
|
||||
|
@ -203,19 +172,10 @@ nm_ifnet_connection_class_init (NMIfnetConnectionClass * ifnet_connection_class)
|
|||
g_type_class_add_private (ifnet_connection_class,
|
||||
sizeof (NMIfnetConnectionPrivate));
|
||||
|
||||
object_class->set_property = set_property;
|
||||
object_class->get_property = get_property;
|
||||
object_class->finalize = finalize;
|
||||
sysconfig_class->delete = do_delete;
|
||||
sysconfig_class->commit_changes = commit_changes;
|
||||
|
||||
/* Properties */
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_CONN_NAME,
|
||||
g_param_spec_pointer (NM_IFNET_CONNECTION_CONN_NAME,
|
||||
"config_block",
|
||||
"",
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
signals[IFNET_SETUP_MONITORS] =
|
||||
g_signal_new ("ifnet_setup_monitors",
|
||||
G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST,
|
||||
|
|
|
@ -26,14 +26,15 @@
|
|||
#include "net_parser.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NM_TYPE_IFNET_CONNECTION (nm_ifnet_connection_get_type ())
|
||||
#define NM_IFNET_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnection))
|
||||
#define NM_IFNET_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass))
|
||||
#define NM_IS_IFNET_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IFNET_CONNECTION))
|
||||
#define NM_IS_IFNET_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_IFNET_CONNECTION))
|
||||
#define NM_IFNET_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass))
|
||||
#define NM_IFNET_CONNECTION_CONN_NAME "connection_name"
|
||||
typedef struct {
|
||||
|
||||
typedef struct {
|
||||
NMSysconfigConnection parent;
|
||||
} NMIfnetConnection;
|
||||
|
||||
|
@ -43,7 +44,8 @@ typedef struct {
|
|||
|
||||
GType nm_ifnet_connection_get_type (void);
|
||||
|
||||
NMIfnetConnection *nm_ifnet_connection_new (gchar * conn_name);
|
||||
NMIfnetConnection *nm_ifnet_connection_new (const char *conn_name,
|
||||
NMConnection *source);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* NM_IFNET_CONNECTION_H */
|
||||
|
|
|
@ -201,18 +201,6 @@ commit_cb (NMSysconfigConnection *connection, GError *error, gpointer unused)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_old_connection (gchar * conn_name,
|
||||
NMIfnetConnection * old_conn,
|
||||
NMIfnetConnection * new_conn,
|
||||
SCPluginIfnetPrivate * priv)
|
||||
{
|
||||
nm_sysconfig_connection_replace_and_commit (NM_SYSCONFIG_CONNECTION (old_conn),
|
||||
NM_CONNECTION (new_conn),
|
||||
commit_cb, NULL);
|
||||
g_object_unref (new_conn);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_monitors (NMIfnetConnection * connection, gpointer user_data)
|
||||
{
|
||||
|
@ -267,90 +255,85 @@ reload_connections (gpointer config)
|
|||
|
||||
if (!reload_parsers ())
|
||||
return;
|
||||
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Loading connections");
|
||||
conn_names = ifnet_get_connection_names ();
|
||||
new_conn_names =
|
||||
g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
for (n_iter = conn_names; n_iter; n_iter = g_list_next (n_iter)) {
|
||||
NMIfnetConnection *exported;
|
||||
NMIfnetConnection *old;
|
||||
gchar *conn_name = g_strdup (n_iter->data);
|
||||
|
||||
/* add the new connection */
|
||||
exported = nm_ifnet_connection_new (conn_name);
|
||||
if (!exported) {
|
||||
g_free (conn_name);
|
||||
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Loading connections");
|
||||
|
||||
conn_names = ifnet_get_connection_names ();
|
||||
new_conn_names = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
|
||||
for (n_iter = conn_names; n_iter; n_iter = g_list_next (n_iter)) {
|
||||
NMIfnetConnection *new;
|
||||
NMIfnetConnection *old;
|
||||
const char *conn_name = n_iter->data;
|
||||
|
||||
/* read the new connection */
|
||||
new = nm_ifnet_connection_new (conn_name, NULL);
|
||||
if (!new)
|
||||
continue;
|
||||
}
|
||||
g_signal_connect (G_OBJECT (exported), "ifnet_setup_monitors",
|
||||
G_CALLBACK (setup_monitors), config);
|
||||
g_signal_connect (G_OBJECT (exported), "ifnet_cancel_monitors",
|
||||
G_CALLBACK (cancel_monitors), config);
|
||||
|
||||
g_signal_connect (G_OBJECT (new), "ifnet_setup_monitors",
|
||||
G_CALLBACK (setup_monitors), config);
|
||||
g_signal_connect (G_OBJECT (new), "ifnet_cancel_monitors",
|
||||
G_CALLBACK (cancel_monitors), config);
|
||||
|
||||
old = g_hash_table_lookup (priv->config_connections, conn_name);
|
||||
if (old && exported) {
|
||||
if (old && new) {
|
||||
const char *auto_refresh;
|
||||
|
||||
auto_refresh = ifnet_get_global_setting (IFNET_KEY_FILE_GROUP, "auto_refresh");
|
||||
if (auto_refresh && is_true (auto_refresh)) {
|
||||
if (!nm_connection_compare (NM_CONNECTION (old),
|
||||
NM_CONNECTION
|
||||
(exported),
|
||||
NM_SETTING_COMPARE_FLAG_EXACT))
|
||||
{
|
||||
PLUGIN_PRINT (IFNET_PLUGIN_NAME,
|
||||
"Auto refreshing %s",
|
||||
conn_name);
|
||||
g_signal_emit_by_name (old, "removed");
|
||||
g_hash_table_remove
|
||||
(priv->config_connections,
|
||||
conn_name);
|
||||
g_hash_table_insert
|
||||
(priv->config_connections,
|
||||
g_strdup (conn_name), exported);
|
||||
NM_CONNECTION (new),
|
||||
NM_SETTING_COMPARE_FLAG_EXACT)) {
|
||||
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Auto refreshing %s", conn_name);
|
||||
|
||||
/* Remove and re-add to disconnect and reconnect with new settings */
|
||||
g_signal_emit_by_name (old, NM_SYSCONFIG_CONNECTION_REMOVED);
|
||||
g_hash_table_remove (priv->config_connections, conn_name);
|
||||
g_hash_table_insert (priv->config_connections, g_strdup (conn_name), new);
|
||||
if (is_managed (conn_name))
|
||||
g_signal_emit_by_name (self,
|
||||
NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED,
|
||||
exported);
|
||||
g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new);
|
||||
}
|
||||
} else
|
||||
update_old_connection (conn_name, old,
|
||||
exported, priv);
|
||||
g_signal_emit_by_name (self,
|
||||
NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
|
||||
} else if (exported) {
|
||||
g_hash_table_insert (priv->config_connections,
|
||||
g_strdup (conn_name), exported);
|
||||
} else {
|
||||
/* Update existing connection with new settings */
|
||||
nm_sysconfig_connection_replace_and_commit (NM_SYSCONFIG_CONNECTION (old),
|
||||
NM_CONNECTION (new),
|
||||
commit_cb, NULL);
|
||||
g_object_unref (new);
|
||||
}
|
||||
g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
|
||||
} else if (new) {
|
||||
g_hash_table_insert (priv->config_connections, g_strdup (conn_name), new);
|
||||
if (is_managed (conn_name))
|
||||
g_signal_emit_by_name (self,
|
||||
NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED,
|
||||
exported);
|
||||
g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new);
|
||||
}
|
||||
g_hash_table_insert (new_conn_names, conn_name, conn_name);
|
||||
g_hash_table_insert (new_conn_names, (gpointer) conn_name, (gpointer) conn_name);
|
||||
}
|
||||
|
||||
/* remove unused connections */
|
||||
g_hash_table_iter_init (&iter, priv->config_connections);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||
if (!g_hash_table_lookup (new_conn_names, key)) {
|
||||
g_signal_emit_by_name (value, "removed");
|
||||
g_signal_emit_by_name (value, NM_SYSCONFIG_CONNECTION_REMOVED);
|
||||
g_hash_table_remove (priv->config_connections, key);
|
||||
}
|
||||
}
|
||||
g_hash_table_remove_all (new_conn_names);
|
||||
g_hash_table_destroy (new_conn_names);
|
||||
g_list_free (conn_names);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static NMSysconfigConnection *
|
||||
add_connection (NMSystemConfigInterface *config,
|
||||
NMConnection *connection,
|
||||
NMConnection *source,
|
||||
GError **error)
|
||||
{
|
||||
gboolean result;
|
||||
NMIfnetConnection *connection = NULL;
|
||||
char *conn_name;
|
||||
|
||||
result = ifnet_add_new_connection (connection, CONF_NET_FILE,
|
||||
WPA_SUPPLICANT_CONF, error);
|
||||
conn_name = ifnet_add_new_connection (source, CONF_NET_FILE, WPA_SUPPLICANT_CONF, error);
|
||||
if (conn_name)
|
||||
connection = nm_ifnet_connection_new (conn_name, source);
|
||||
reload_connections (config);
|
||||
return result;
|
||||
return connection ? NM_SYSCONFIG_CONNECTION (connection) : NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -37,40 +37,38 @@ G_DEFINE_TYPE (NMKeyfileConnection, nm_keyfile_connection, NM_TYPE_SYSCONFIG_CON
|
|||
#define NM_KEYFILE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionPrivate))
|
||||
|
||||
typedef struct {
|
||||
char *filename;
|
||||
char *path;
|
||||
} NMKeyfileConnectionPrivate;
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_FILENAME,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
NMKeyfileConnection *
|
||||
nm_keyfile_connection_new (const char *filename, GError **error)
|
||||
nm_keyfile_connection_new (const char *full_path,
|
||||
NMConnection *source,
|
||||
GError **error)
|
||||
{
|
||||
GObject *object;
|
||||
NMKeyfileConnectionPrivate *priv;
|
||||
NMSettingConnection *s_con;
|
||||
NMConnection *tmp;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
g_return_val_if_fail (full_path != NULL, NULL);
|
||||
|
||||
tmp = connection_from_file (filename, error);
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
/* If we're given a connection already, prefer that instead of re-reading */
|
||||
if (source)
|
||||
tmp = g_object_ref (source);
|
||||
else {
|
||||
tmp = connection_from_file (full_path, error);
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
object = (GObject *) g_object_new (NM_TYPE_KEYFILE_CONNECTION,
|
||||
NM_KEYFILE_CONNECTION_FILENAME, filename,
|
||||
NULL);
|
||||
object = (GObject *) g_object_new (NM_TYPE_KEYFILE_CONNECTION, NULL);
|
||||
if (!object) {
|
||||
g_object_unref (tmp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object);
|
||||
g_assert (priv->filename);
|
||||
priv->path = g_strdup (full_path);
|
||||
|
||||
/* Update our settings with what was read from the file */
|
||||
nm_sysconfig_connection_replace_settings (NM_SYSCONFIG_CONNECTION (object), tmp, NULL);
|
||||
|
@ -100,11 +98,11 @@ nm_keyfile_connection_new (const char *filename, GError **error)
|
|||
}
|
||||
|
||||
const char *
|
||||
nm_keyfile_connection_get_filename (NMKeyfileConnection *self)
|
||||
nm_keyfile_connection_get_path (NMKeyfileConnection *self)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_KEYFILE_CONNECTION (self), NULL);
|
||||
|
||||
return NM_KEYFILE_CONNECTION_GET_PRIVATE (self)->filename;
|
||||
return NM_KEYFILE_CONNECTION_GET_PRIVATE (self)->path;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -113,21 +111,21 @@ commit_changes (NMSysconfigConnection *connection,
|
|||
gpointer user_data)
|
||||
{
|
||||
NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection);
|
||||
char *filename = NULL;
|
||||
char *path = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!write_connection (NM_CONNECTION (connection), KEYFILE_DIR, 0, 0, &filename, &error)) {
|
||||
if (!write_connection (NM_CONNECTION (connection), KEYFILE_DIR, 0, 0, &path, &error)) {
|
||||
callback (connection, error, user_data);
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (priv->filename, filename)) {
|
||||
if (g_strcmp0 (priv->path, path)) {
|
||||
/* Update the filename if it changed */
|
||||
g_free (priv->filename);
|
||||
priv->filename = filename;
|
||||
g_free (priv->path);
|
||||
priv->path = path;
|
||||
} else
|
||||
g_free (filename);
|
||||
g_free (path);
|
||||
|
||||
NM_SYSCONFIG_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->commit_changes (connection,
|
||||
callback,
|
||||
|
@ -141,7 +139,7 @@ do_delete (NMSysconfigConnection *connection,
|
|||
{
|
||||
NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection);
|
||||
|
||||
g_unlink (priv->filename);
|
||||
g_unlink (priv->path);
|
||||
|
||||
NM_SYSCONFIG_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->delete (connection,
|
||||
callback,
|
||||
|
@ -162,44 +160,11 @@ finalize (GObject *object)
|
|||
|
||||
nm_connection_clear_secrets (NM_CONNECTION (object));
|
||||
|
||||
g_free (priv->filename);
|
||||
g_free (priv->path);
|
||||
|
||||
G_OBJECT_CLASS (nm_keyfile_connection_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_FILENAME:
|
||||
/* Construct only */
|
||||
priv->filename = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_FILENAME:
|
||||
g_value_set_string (value, priv->filename);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nm_keyfile_connection_class_init (NMKeyfileConnectionClass *keyfile_connection_class)
|
||||
{
|
||||
|
@ -209,18 +174,7 @@ nm_keyfile_connection_class_init (NMKeyfileConnectionClass *keyfile_connection_c
|
|||
g_type_class_add_private (keyfile_connection_class, sizeof (NMKeyfileConnectionPrivate));
|
||||
|
||||
/* Virtual methods */
|
||||
object_class->set_property = set_property;
|
||||
object_class->get_property = get_property;
|
||||
object_class->finalize = finalize;
|
||||
sysconfig_class->commit_changes = commit_changes;
|
||||
sysconfig_class->delete = do_delete;
|
||||
|
||||
/* Properties */
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_FILENAME,
|
||||
g_param_spec_string (NM_KEYFILE_CONNECTION_FILENAME,
|
||||
"FileName",
|
||||
"File name",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
|
|
@ -33,8 +33,6 @@ G_BEGIN_DECLS
|
|||
#define NM_IS_KEYFILE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_KEYFILE_CONNECTION))
|
||||
#define NM_KEYFILE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionClass))
|
||||
|
||||
#define NM_KEYFILE_CONNECTION_FILENAME "filename"
|
||||
|
||||
typedef struct {
|
||||
NMSysconfigConnection parent;
|
||||
} NMKeyfileConnection;
|
||||
|
@ -45,9 +43,11 @@ typedef struct {
|
|||
|
||||
GType nm_keyfile_connection_get_type (void);
|
||||
|
||||
NMKeyfileConnection *nm_keyfile_connection_new (const char *filename, GError **error);
|
||||
NMKeyfileConnection *nm_keyfile_connection_new (const char *filename,
|
||||
NMConnection *source,
|
||||
GError **error);
|
||||
|
||||
const char *nm_keyfile_connection_get_filename (NMKeyfileConnection *self);
|
||||
const char *nm_keyfile_connection_get_path (NMKeyfileConnection *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -67,13 +67,49 @@ typedef struct {
|
|||
gboolean disposed;
|
||||
} SCPluginKeyfilePrivate;
|
||||
|
||||
static NMSysconfigConnection *
|
||||
_internal_new_connection (SCPluginKeyfile *self,
|
||||
const char *full_path,
|
||||
NMConnection *source,
|
||||
const char **out_cid,
|
||||
GError **error)
|
||||
{
|
||||
SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self);
|
||||
NMSettingConnection *s_con;
|
||||
const char *cid, *uuid;
|
||||
NMKeyfileConnection *connection;
|
||||
|
||||
g_return_val_if_fail (full_path != NULL, NULL);
|
||||
|
||||
connection = nm_keyfile_connection_new (full_path, source, error);
|
||||
if (!connection)
|
||||
return NULL;
|
||||
|
||||
s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection),
|
||||
NM_TYPE_SETTING_CONNECTION);
|
||||
g_assert (s_con);
|
||||
|
||||
cid = nm_setting_connection_get_id (s_con);
|
||||
g_assert (cid);
|
||||
uuid = nm_setting_connection_get_uuid (s_con);
|
||||
g_assert (uuid);
|
||||
|
||||
g_hash_table_insert (priv->hash,
|
||||
(gpointer) nm_keyfile_connection_get_path (connection),
|
||||
connection);
|
||||
|
||||
if (out_cid)
|
||||
*out_cid = cid;
|
||||
return NM_SYSCONFIG_CONNECTION (connection);
|
||||
}
|
||||
|
||||
static void
|
||||
read_connections (NMSystemConfigInterface *config)
|
||||
{
|
||||
SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
|
||||
SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config);
|
||||
GDir *dir;
|
||||
GError *error = NULL;
|
||||
const char *item;
|
||||
const char *item, *cid;
|
||||
|
||||
dir = g_dir_open (KEYFILE_DIR, 0, &error);
|
||||
if (!dir) {
|
||||
|
@ -86,62 +122,28 @@ read_connections (NMSystemConfigInterface *config)
|
|||
}
|
||||
|
||||
while ((item = g_dir_read_name (dir))) {
|
||||
NMKeyfileConnection *connection;
|
||||
NMSysconfigConnection *connection;
|
||||
char *full_path;
|
||||
|
||||
full_path = g_build_filename (KEYFILE_DIR, item, NULL);
|
||||
PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "parsing %s ... ", item);
|
||||
connection = nm_keyfile_connection_new (full_path, &error);
|
||||
|
||||
connection = _internal_new_connection (self, full_path, NULL, &cid, &error);
|
||||
if (connection) {
|
||||
NMSettingConnection *s_con;
|
||||
const char *cid;
|
||||
|
||||
s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION);
|
||||
g_assert (s_con);
|
||||
|
||||
cid = nm_setting_connection_get_id (s_con);
|
||||
g_assert (cid);
|
||||
|
||||
g_hash_table_insert (priv->hash,
|
||||
(gpointer) nm_keyfile_connection_get_filename (connection),
|
||||
connection);
|
||||
|
||||
PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " read connection '%s'", cid);
|
||||
} else {
|
||||
PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s",
|
||||
(error && error->message) ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
}
|
||||
g_clear_error (&error);
|
||||
g_free (full_path);
|
||||
}
|
||||
g_dir_close (dir);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *uuid;
|
||||
NMKeyfileConnection *found;
|
||||
} FindByUUIDInfo;
|
||||
|
||||
static void
|
||||
find_by_uuid (gpointer key, gpointer data, gpointer user_data)
|
||||
update_connection_settings_commit_cb (NMSysconfigConnection *orig, GError *error, gpointer user_data)
|
||||
{
|
||||
NMKeyfileConnection *keyfile = NM_KEYFILE_CONNECTION (data);
|
||||
FindByUUIDInfo *info = user_data;
|
||||
NMSettingConnection *s_con;
|
||||
const char *uuid;
|
||||
|
||||
if (info->found)
|
||||
return;
|
||||
|
||||
s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (keyfile), NM_TYPE_SETTING_CONNECTION);
|
||||
|
||||
uuid = s_con ? nm_setting_connection_get_uuid (s_con) : NULL;
|
||||
if (uuid && !strcmp (info->uuid, uuid))
|
||||
info->found = keyfile;
|
||||
}
|
||||
|
||||
static void
|
||||
update_connection_settings_commit_cb (NMSysconfigConnection *orig, GError *error, gpointer user_data) {
|
||||
if (error) {
|
||||
g_warning ("%s: '%s' / '%s' invalid: %d",
|
||||
__func__,
|
||||
|
@ -180,6 +182,28 @@ remove_connection (SCPluginKeyfile *self,
|
|||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
static NMKeyfileConnection *
|
||||
find_by_uuid (SCPluginKeyfile *self, const char *uuid)
|
||||
{
|
||||
SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self);
|
||||
GHashTableIter iter;
|
||||
gpointer data = NULL;
|
||||
|
||||
g_return_val_if_fail (uuid != NULL, NULL);
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->hash);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &data)) {
|
||||
NMConnection *candidate = NM_CONNECTION (data);
|
||||
NMSettingConnection *s_con;
|
||||
|
||||
s_con = (NMSettingConnection *) nm_connection_get_setting (candidate, NM_TYPE_SETTING_CONNECTION);
|
||||
g_assert (s_con);
|
||||
if (strcmp (uuid, nm_setting_connection_get_uuid (s_con)) == 0)
|
||||
return NM_KEYFILE_CONNECTION (candidate);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
dir_changed (GFileMonitor *monitor,
|
||||
GFile *file,
|
||||
|
@ -188,30 +212,31 @@ dir_changed (GFileMonitor *monitor,
|
|||
gpointer user_data)
|
||||
{
|
||||
NMSystemConfigInterface *config = NM_SYSTEM_CONFIG_INTERFACE (user_data);
|
||||
SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
|
||||
char *name;
|
||||
SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config);
|
||||
SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self);
|
||||
char *full_path;
|
||||
NMKeyfileConnection *connection;
|
||||
GError *error = NULL;
|
||||
|
||||
name = g_file_get_path (file);
|
||||
connection = g_hash_table_lookup (priv->hash, name);
|
||||
full_path = g_file_get_path (file);
|
||||
connection = g_hash_table_lookup (priv->hash, full_path);
|
||||
|
||||
switch (event_type) {
|
||||
case G_FILE_MONITOR_EVENT_DELETED:
|
||||
if (connection) {
|
||||
PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "removed %s.", name);
|
||||
remove_connection (SC_PLUGIN_KEYFILE (config), connection, name);
|
||||
PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "removed %s.", full_path);
|
||||
remove_connection (SC_PLUGIN_KEYFILE (config), connection, full_path);
|
||||
}
|
||||
break;
|
||||
case G_FILE_MONITOR_EVENT_CREATED:
|
||||
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
|
||||
PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", name);
|
||||
PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", full_path);
|
||||
|
||||
if (connection) {
|
||||
/* Update */
|
||||
NMKeyfileConnection *tmp;
|
||||
|
||||
tmp = nm_keyfile_connection_new (name, &error);
|
||||
tmp = nm_keyfile_connection_new (full_path, NULL, &error);
|
||||
if (tmp) {
|
||||
update_connection_settings (connection, tmp);
|
||||
g_object_unref (tmp);
|
||||
|
@ -220,40 +245,33 @@ dir_changed (GFileMonitor *monitor,
|
|||
PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s",
|
||||
(error && error->message) ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
remove_connection (SC_PLUGIN_KEYFILE (config), connection, name);
|
||||
remove_connection (SC_PLUGIN_KEYFILE (config), connection, full_path);
|
||||
}
|
||||
} else {
|
||||
/* New */
|
||||
connection = nm_keyfile_connection_new (name, &error);
|
||||
connection = nm_keyfile_connection_new (full_path, NULL, &error);
|
||||
if (connection) {
|
||||
NMSettingConnection *s_con;
|
||||
const char *connection_uuid;
|
||||
NMKeyfileConnection *found = NULL;
|
||||
NMSettingConnection *s_con;
|
||||
|
||||
/* Connection renames will show up as different files but with
|
||||
* the same UUID. Try to find the original connection.
|
||||
*/
|
||||
s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION);
|
||||
connection_uuid = s_con ? nm_setting_connection_get_uuid (s_con) : NULL;
|
||||
|
||||
if (connection_uuid) {
|
||||
FindByUUIDInfo info = { .found = NULL, .uuid = connection_uuid };
|
||||
|
||||
g_hash_table_foreach (priv->hash, find_by_uuid, &info);
|
||||
found = info.found;
|
||||
}
|
||||
g_assert (s_con);
|
||||
|
||||
/* A connection rename is treated just like an update except
|
||||
* there's a bit more housekeeping with the hash table.
|
||||
*/
|
||||
found = find_by_uuid (self, nm_setting_connection_get_uuid (s_con));
|
||||
if (found) {
|
||||
const char *old_filename = nm_keyfile_connection_get_filename (connection);
|
||||
const char *old_path = nm_keyfile_connection_get_path (connection);
|
||||
|
||||
/* Removing from the hash table should drop the last reference,
|
||||
* but of course we want to keep the connection around.
|
||||
*/
|
||||
g_object_ref (found);
|
||||
g_hash_table_remove (priv->hash, old_filename);
|
||||
g_hash_table_remove (priv->hash, old_path);
|
||||
|
||||
/* Updating settings should update the NMKeyfileConnection's
|
||||
* filename property too.
|
||||
|
@ -262,14 +280,14 @@ dir_changed (GFileMonitor *monitor,
|
|||
|
||||
/* Re-insert the connection back into the hash with the new filename */
|
||||
g_hash_table_insert (priv->hash,
|
||||
(gpointer) nm_keyfile_connection_get_filename (found),
|
||||
(gpointer) nm_keyfile_connection_get_path (found),
|
||||
found);
|
||||
|
||||
/* Get rid of the temporary connection */
|
||||
g_object_unref (connection);
|
||||
} else {
|
||||
g_hash_table_insert (priv->hash,
|
||||
(gpointer) nm_keyfile_connection_get_filename (connection),
|
||||
(gpointer) nm_keyfile_connection_get_path (connection),
|
||||
connection);
|
||||
g_signal_emit_by_name (config, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection);
|
||||
}
|
||||
|
@ -284,7 +302,7 @@ dir_changed (GFileMonitor *monitor,
|
|||
break;
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
g_free (full_path);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -352,38 +370,42 @@ setup_monitoring (NMSystemConfigInterface *config)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hash_to_slist (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
GSList **list = (GSList **) user_data;
|
||||
|
||||
*list = g_slist_prepend (*list, value);
|
||||
}
|
||||
|
||||
/* Plugin */
|
||||
|
||||
static GSList *
|
||||
get_connections (NMSystemConfigInterface *config)
|
||||
{
|
||||
SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
|
||||
GSList *connections = NULL;
|
||||
GHashTableIter iter;
|
||||
gpointer data = NULL;
|
||||
GSList *list = NULL;
|
||||
|
||||
if (!priv->hash) {
|
||||
setup_monitoring (config);
|
||||
read_connections (config);
|
||||
}
|
||||
|
||||
g_hash_table_foreach (priv->hash, hash_to_slist, &connections);
|
||||
|
||||
return connections;
|
||||
g_hash_table_iter_init (&iter, priv->hash);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &data))
|
||||
list = g_slist_prepend (list, data);
|
||||
return list;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static NMSysconfigConnection *
|
||||
add_connection (NMSystemConfigInterface *config,
|
||||
NMConnection *connection,
|
||||
GError **error)
|
||||
{
|
||||
return write_connection (connection, KEYFILE_DIR, 0, 0, NULL, error);
|
||||
SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config);
|
||||
NMSysconfigConnection *added = NULL;
|
||||
char *path = NULL;
|
||||
|
||||
/* Write it out first, then add the connection to our internal list */
|
||||
if (write_connection (connection, KEYFILE_DIR, 0, 0, &path, error)) {
|
||||
added = _internal_new_connection (self, path, connection, NULL, error);
|
||||
g_free (path);
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
static GSList *
|
||||
|
|
Loading…
Reference in a new issue