mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-04 15:20:28 +01:00
2008-02-12 Dan Williams <dcbw@redhat.com>
* system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (load_connections): get_connections() should now return an allocated GSList that the system settings service will free * system-settings/plugins/ifcfg-fedora/plugin.c system-settings/plugins/ifcfg-fedora/parser.h system-settings/plugins/ifcfg-fedora/parser.c - Fix up inotify issues; handle keys-* files, handle new files appearing in the profile directory, handle resolv.conf file changes git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3309 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
parent
e476f3a6e5
commit
5b87ceab92
6 changed files with 371 additions and 108 deletions
13
ChangeLog
13
ChangeLog
|
|
@ -1,3 +1,16 @@
|
|||
2008-02-12 Dan Williams <dcbw@redhat.com>
|
||||
|
||||
* system-settings/src/nm-system-config-interface.c
|
||||
system-settings/src/nm-system-config-interface.h
|
||||
- (load_connections): get_connections() should now return an allocated
|
||||
GSList that the system settings service will free
|
||||
|
||||
* system-settings/plugins/ifcfg-fedora/plugin.c
|
||||
system-settings/plugins/ifcfg-fedora/parser.h
|
||||
system-settings/plugins/ifcfg-fedora/parser.c
|
||||
- Fix up inotify issues; handle keys-* files, handle new files appearing
|
||||
in the profile directory, handle resolv.conf file changes
|
||||
|
||||
2008-02-10 Dan Williams <dcbw@redhat.com>
|
||||
|
||||
* src/nm-device-802-3-ethernet.c
|
||||
|
|
|
|||
|
|
@ -184,29 +184,23 @@ make_connection_setting (const char *file,
|
|||
#define SEARCH_TAG "search "
|
||||
#define NS_TAG "nameserver "
|
||||
|
||||
static void
|
||||
read_profile_resolv_conf (shvarFile *ifcfg, NMSettingIP4Config *s_ip4)
|
||||
void
|
||||
connection_update_from_resolv_conf (char **lines, NMSettingIP4Config *s_ip4)
|
||||
{
|
||||
char *file = NULL;
|
||||
char *dir = NULL;
|
||||
char *contents = NULL;
|
||||
char **lines = NULL;
|
||||
char **line;
|
||||
|
||||
dir = g_path_get_dirname (ifcfg->fileName);
|
||||
if (!dir)
|
||||
goto out;
|
||||
/* lines == NULL means clear out existing settings */
|
||||
if (!lines) {
|
||||
if (s_ip4->dns) {
|
||||
g_array_free (s_ip4->dns, TRUE);
|
||||
s_ip4->dns = NULL;
|
||||
}
|
||||
|
||||
file = g_strdup_printf ("%s/resolv.conf", dir);
|
||||
if (!file)
|
||||
goto out;
|
||||
|
||||
if (!g_file_get_contents (file, &contents, NULL, NULL))
|
||||
goto out;
|
||||
|
||||
lines = g_strsplit (contents, "\n", 0);
|
||||
if (!lines || !*lines)
|
||||
goto out;
|
||||
g_slist_foreach (s_ip4->dns_search, (GFunc) g_free, NULL);
|
||||
g_slist_free (s_ip4->dns_search);
|
||||
s_ip4->dns_search = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
s_ip4->dns = g_array_new (FALSE, FALSE, sizeof (guint32));
|
||||
|
||||
|
|
@ -237,9 +231,36 @@ read_profile_resolv_conf (shvarFile *ifcfg, NMSettingIP4Config *s_ip4)
|
|||
}
|
||||
}
|
||||
|
||||
if (!s_ip4->dns->len) {
|
||||
g_array_free (s_ip4->dns, TRUE);
|
||||
s_ip4->dns = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
read_profile_resolv_conf (const char *dir, NMSettingIP4Config *s_ip4)
|
||||
{
|
||||
char *file = NULL;
|
||||
char *contents = NULL;
|
||||
char **lines = NULL;
|
||||
|
||||
file = g_strdup_printf ("%s/resolv.conf", dir);
|
||||
if (!file)
|
||||
goto out;
|
||||
|
||||
if (!g_file_get_contents (file, &contents, NULL, NULL))
|
||||
goto out;
|
||||
|
||||
lines = g_strsplit (contents, "\n", 0);
|
||||
if (!lines || !*lines)
|
||||
goto out;
|
||||
|
||||
connection_update_from_resolv_conf (lines, s_ip4);
|
||||
|
||||
out:
|
||||
if (lines)
|
||||
g_strfreev (lines);
|
||||
g_free (contents);
|
||||
g_free (file);
|
||||
}
|
||||
|
||||
|
|
@ -250,6 +271,7 @@ make_ip4_setting (shvarFile *ifcfg, GError **error)
|
|||
char *value = NULL;
|
||||
NMSettingIP4Address tmp = { 0, 0, 0 };
|
||||
gboolean manual = TRUE;
|
||||
char *dir;
|
||||
|
||||
value = svGetValue (ifcfg, "BOOTPROTO");
|
||||
if (!value)
|
||||
|
|
@ -308,7 +330,15 @@ make_ip4_setting (shvarFile *ifcfg, GError **error)
|
|||
s_ip4->addresses = g_slist_append (s_ip4->addresses, addr);
|
||||
}
|
||||
|
||||
read_profile_resolv_conf (ifcfg, s_ip4);
|
||||
dir = g_path_get_dirname (ifcfg->fileName);
|
||||
if (dir) {
|
||||
read_profile_resolv_conf (dir, s_ip4);
|
||||
g_free (dir);
|
||||
} else {
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Not enough memory to parse resolv.conf");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return NM_SETTING (s_ip4);
|
||||
|
||||
|
|
@ -433,7 +463,7 @@ get_keys_ifcfg (const char *parent)
|
|||
if (!tmp)
|
||||
goto out;
|
||||
|
||||
keys_file = g_strdup_printf ("%s/keys-%s", tmp, ifcfg_name);
|
||||
keys_file = g_strdup_printf ("%s/" KEYS_TAG "%s", tmp, ifcfg_name);
|
||||
if (!keys_file)
|
||||
goto out;
|
||||
|
||||
|
|
@ -746,6 +776,8 @@ parser_parse_file (const char *file, GError **error)
|
|||
char *nmc = NULL;
|
||||
NMSetting *s_ip4;
|
||||
char *ifcfg_name = NULL;
|
||||
gboolean ignored = FALSE;
|
||||
ConnectionData *cdata;
|
||||
|
||||
g_return_val_if_fail (file != NULL, NULL);
|
||||
|
||||
|
|
@ -778,12 +810,8 @@ parser_parse_file (const char *file, GError **error)
|
|||
lower = g_ascii_strdown (nmc, -1);
|
||||
g_free (nmc);
|
||||
|
||||
if (!strcmp (lower, "no") || !strcmp (lower, "n") || !strcmp (lower, "false")) {
|
||||
g_free (lower);
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Ignoring connection '%s' because NM_CONTROLLED was false.", file);
|
||||
goto done;
|
||||
}
|
||||
if (!strcmp (lower, "no") || !strcmp (lower, "n") || !strcmp (lower, "false"))
|
||||
ignored = TRUE;
|
||||
g_free (lower);
|
||||
}
|
||||
|
||||
|
|
@ -810,6 +838,10 @@ parser_parse_file (const char *file, GError **error)
|
|||
nm_connection_add_setting (connection, s_ip4);
|
||||
}
|
||||
|
||||
/* Update the ignored tag */
|
||||
cdata = connection_data_get (connection);
|
||||
cdata->ignored = ignored;
|
||||
|
||||
if (!nm_connection_verify (connection)) {
|
||||
g_object_unref (connection);
|
||||
connection = NULL;
|
||||
|
|
|
|||
|
|
@ -24,17 +24,24 @@
|
|||
|
||||
#include <glib.h>
|
||||
#include <nm-connection.h>
|
||||
#include <nm-setting-ip4-config.h>
|
||||
|
||||
#define IFCFG_TAG "ifcfg-"
|
||||
#define KEYS_TAG "keys-"
|
||||
#define BAK_TAG ".bak"
|
||||
|
||||
typedef struct {
|
||||
char *ifcfg_path;
|
||||
gboolean ignored;
|
||||
gboolean exported;
|
||||
|
||||
GHashTable *secrets;
|
||||
} ConnectionData;
|
||||
|
||||
NMConnection * parser_parse_file (const char *file, GError **error);
|
||||
|
||||
void connection_update_from_resolv_conf (char **lines, NMSettingIP4Config *s_ip4);
|
||||
|
||||
ConnectionData *connection_data_get (NMConnection *connection);
|
||||
ConnectionData *connection_data_add (NMConnection *connection, const char *ifcfg_path);
|
||||
void connection_data_copy_secrets (ConnectionData *from, ConnectionData *to);
|
||||
|
|
|
|||
|
|
@ -111,61 +111,87 @@ find_watched_path (gpointer key, gpointer value, gpointer user_data)
|
|||
static void
|
||||
watch_path (const char *path, const int inotify_fd, GHashTable *table)
|
||||
{
|
||||
char *dirname;
|
||||
int wd;
|
||||
struct FindInfo info;
|
||||
|
||||
dirname = g_path_get_dirname (path);
|
||||
g_return_if_fail (dirname != NULL);
|
||||
g_return_if_fail (g_path_is_absolute (path));
|
||||
|
||||
info.found = FALSE;
|
||||
info.path = dirname;
|
||||
info.path = path;
|
||||
g_hash_table_foreach (table, find_watched_path, &info);
|
||||
if (info.found)
|
||||
goto error;
|
||||
return;
|
||||
|
||||
wd = inotify_add_watch (inotify_fd, dirname,
|
||||
IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | IN_MOVE);
|
||||
wd = inotify_add_watch (inotify_fd, path,
|
||||
IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | IN_MOVE | IN_MOVE_SELF);
|
||||
if (wd == -1) {
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " inotify error watching '%s': errno %d",
|
||||
dirname, errno);
|
||||
goto error;
|
||||
path, errno);
|
||||
} else {
|
||||
g_hash_table_insert (table, GINT_TO_POINTER (wd), g_strdup (path));
|
||||
}
|
||||
|
||||
g_hash_table_insert (table, GINT_TO_POINTER (wd), dirname);
|
||||
return;
|
||||
|
||||
error:
|
||||
g_free (dirname);
|
||||
}
|
||||
|
||||
static NMConnection *
|
||||
build_one_connection (const char *profile_path, const char *filename)
|
||||
{
|
||||
NMConnection *connection;
|
||||
char *ifcfg_file = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_val_if_fail (profile_path != NULL, NULL);
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
|
||||
ifcfg_file = g_build_filename (profile_path, filename, NULL);
|
||||
g_return_val_if_fail (ifcfg_file != NULL, NULL);
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "parsing %s ... ", filename);
|
||||
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "parsing %s ... ", ifcfg_file);
|
||||
|
||||
connection = parser_parse_file (ifcfg_file, &error);
|
||||
connection = parser_parse_file (filename, &error);
|
||||
if (connection) {
|
||||
NMSettingConnection *s_con;
|
||||
|
||||
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
|
||||
g_assert (s_con);
|
||||
g_assert (s_con->id);
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " found connection '%s'", s_con->id);
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " read connection '%s'", s_con->id);
|
||||
} else {
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " error: %s",
|
||||
error->message ? error->message : "(unknown)");
|
||||
g_free (ifcfg_file);
|
||||
}
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
static NMConnection *
|
||||
handle_new_ifcfg (const char *profile_path,
|
||||
const char *file,
|
||||
const int inotify_fd,
|
||||
GHashTable *watch_table)
|
||||
{
|
||||
NMConnection *connection;
|
||||
ConnectionData *cdata;
|
||||
char *keys_file, *basename;
|
||||
|
||||
connection = build_one_connection (profile_path, file);
|
||||
if (!connection)
|
||||
return NULL;
|
||||
|
||||
/* Watch the file too so we can match up the watch descriptor with the
|
||||
* path we care about if the file is a hardlink.
|
||||
*/
|
||||
watch_path (file, inotify_fd, watch_table);
|
||||
|
||||
/* If there's a keys file watch that too */
|
||||
basename = g_path_get_basename (file);
|
||||
if (basename) {
|
||||
keys_file = g_strdup_printf ("%s" KEYS_TAG "%s", profile_path, basename + strlen (IFCFG_TAG));
|
||||
if (keys_file && g_file_test (keys_file, G_FILE_TEST_EXISTS))
|
||||
watch_path (keys_file, inotify_fd, watch_table);
|
||||
g_free (keys_file);
|
||||
g_free (basename);
|
||||
}
|
||||
|
||||
cdata = connection_data_get (connection);
|
||||
if (cdata->ignored) {
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' because "
|
||||
"NM_CONTROLLED was false.", file);
|
||||
}
|
||||
|
||||
return connection;
|
||||
|
|
@ -179,6 +205,7 @@ get_connections_for_profile (const char *profile_path,
|
|||
GSList *connections = NULL;
|
||||
GDir *dir;
|
||||
const char *item;
|
||||
char *resolv_conf;
|
||||
|
||||
g_return_val_if_fail (profile_path != NULL, NULL);
|
||||
g_return_val_if_fail (watch_table != NULL, NULL);
|
||||
|
|
@ -191,17 +218,29 @@ get_connections_for_profile (const char *profile_path,
|
|||
|
||||
while ((item = g_dir_read_name (dir))) {
|
||||
NMConnection *connection;
|
||||
char *ifcfg_file;
|
||||
|
||||
if (strncmp (item, IFCFG_TAG, strlen (IFCFG_TAG)))
|
||||
continue;
|
||||
|
||||
connection = build_one_connection (profile_path, item);
|
||||
ifcfg_file = g_build_filename (profile_path, item, NULL);
|
||||
|
||||
connection = handle_new_ifcfg (profile_path, ifcfg_file, inotify_fd, watch_table);
|
||||
if (connection)
|
||||
connections = g_slist_append (connections, connection);
|
||||
|
||||
g_free (ifcfg_file);
|
||||
}
|
||||
g_dir_close (dir);
|
||||
|
||||
watch_path (profile_path, inotify_fd, watch_table);
|
||||
|
||||
/* Watch resolv.conf too */
|
||||
resolv_conf = g_strdup_printf ("%sresolv.conf", profile_path);
|
||||
if (g_file_test (resolv_conf, G_FILE_TEST_EXISTS))
|
||||
watch_path (resolv_conf, inotify_fd, watch_table);
|
||||
g_free (resolv_conf);
|
||||
|
||||
return connections;
|
||||
}
|
||||
|
||||
|
|
@ -262,11 +301,23 @@ get_connections (NMSystemConfigInterface *config)
|
|||
{
|
||||
SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config);
|
||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
|
||||
GSList *list = NULL, *iter;
|
||||
|
||||
if (!priv->initialized)
|
||||
reload_all_connections (plugin);
|
||||
|
||||
return priv->connections;
|
||||
for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
|
||||
NMConnection *connection = NM_CONNECTION (iter->data);
|
||||
ConnectionData *cdata;
|
||||
|
||||
cdata = connection_data_get (connection);
|
||||
if (!cdata->ignored) {
|
||||
list = g_slist_append (list, connection);
|
||||
cdata->exported = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static GHashTable *
|
||||
|
|
@ -308,67 +359,200 @@ find_connection_by_path (GSList *connections, const char *path)
|
|||
}
|
||||
|
||||
static void
|
||||
handle_profile_item_changed (SCPluginIfcfg *plugin,
|
||||
struct inotify_event *evt,
|
||||
const char *filename)
|
||||
handle_connection_changed (SCPluginIfcfg *plugin,
|
||||
const char *filename)
|
||||
{
|
||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
|
||||
const char *path;
|
||||
NMConnection *new_connection;
|
||||
NMConnection *existing;
|
||||
ConnectionData *new_cdata;
|
||||
GHashTable *new_settings;
|
||||
ConnectionData *existing_cdata;
|
||||
gboolean remove = FALSE;
|
||||
|
||||
/* Could return NULL if the connection got deleted */
|
||||
new_connection = build_one_connection (priv->profile, filename);
|
||||
|
||||
existing = find_connection_by_path (priv->connections, filename);
|
||||
if (!existing) {
|
||||
if (new_connection) {
|
||||
new_cdata = connection_data_get (new_connection);
|
||||
g_assert (new_cdata);
|
||||
|
||||
/* totally new connection */
|
||||
priv->connections = g_slist_append (priv->connections, new_connection);
|
||||
if (!new_cdata->ignored) {
|
||||
new_cdata->exported = TRUE;
|
||||
g_signal_emit_by_name (plugin, "connection-added", new_connection);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
existing_cdata = connection_data_get (existing);
|
||||
g_assert (existing_cdata);
|
||||
|
||||
if (new_connection) {
|
||||
/* update the settings of the existing connection for this
|
||||
* ifcfg file and notify listeners that something has changed.
|
||||
*/
|
||||
new_settings = nm_connection_to_hash (new_connection);
|
||||
if (!nm_connection_replace_settings (existing, new_settings)) {
|
||||
/* couldn't replace the settings for some reason; have to
|
||||
* remove the connection then.
|
||||
*/
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, "couldn't update connection for '%s'.", filename);
|
||||
remove = TRUE;
|
||||
} else {
|
||||
/* Success */
|
||||
new_cdata = connection_data_get (new_connection);
|
||||
g_assert (new_cdata);
|
||||
|
||||
connection_data_copy_secrets (new_cdata, existing_cdata);
|
||||
|
||||
if (new_cdata->ignored && !existing_cdata->ignored) {
|
||||
/* connection now ignored */
|
||||
existing_cdata->ignored = TRUE;
|
||||
g_signal_emit_by_name (plugin, "connection-removed", existing);
|
||||
existing_cdata->exported = FALSE;
|
||||
} else if (!new_cdata->ignored && existing_cdata->ignored) {
|
||||
/* connection no longer ignored, let the system settings
|
||||
* service know about it now.
|
||||
*/
|
||||
existing_cdata->ignored = FALSE;
|
||||
existing_cdata->exported = TRUE;
|
||||
g_signal_emit_by_name (plugin, "connection-added", existing);
|
||||
} else if (!new_cdata->ignored && !existing_cdata->ignored) {
|
||||
/* connection updated and not ignored */
|
||||
g_signal_emit_by_name (plugin, "connection-updated", existing);
|
||||
} else if (new_cdata->ignored && existing_cdata->ignored) {
|
||||
/* do nothing */
|
||||
}
|
||||
}
|
||||
g_object_unref (new_connection);
|
||||
} else {
|
||||
remove = TRUE;
|
||||
}
|
||||
|
||||
if (remove) {
|
||||
priv->connections = g_slist_remove (priv->connections, existing);
|
||||
if (!existing_cdata->ignored)
|
||||
g_signal_emit_by_name (plugin, "connection-removed", existing);
|
||||
g_object_unref (existing);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_resolv_conf_changed (SCPluginIfcfg *plugin, const char *path)
|
||||
{
|
||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
|
||||
char *contents = NULL;
|
||||
char **lines = NULL;
|
||||
GSList *iter;
|
||||
|
||||
g_return_if_fail (path != NULL);
|
||||
|
||||
g_file_get_contents (path, &contents, NULL, NULL);
|
||||
if (contents) {
|
||||
lines = g_strsplit (contents, "\n", 0);
|
||||
if (lines && !*lines) {
|
||||
g_strfreev (lines);
|
||||
lines = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (lines) {
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Updating connections because %s changed.", path);
|
||||
} else {
|
||||
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Updating connections because %s was deleted.", path);
|
||||
}
|
||||
|
||||
for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
|
||||
NMConnection *connection = NM_CONNECTION (iter->data);
|
||||
NMSettingIP4Config *s_ip4;
|
||||
|
||||
s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
|
||||
if (s_ip4) {
|
||||
ConnectionData *cdata;
|
||||
|
||||
cdata = connection_data_get (connection);
|
||||
g_assert (cdata);
|
||||
|
||||
connection_update_from_resolv_conf (lines, s_ip4);
|
||||
|
||||
if (!cdata->ignored)
|
||||
g_signal_emit_by_name (plugin, "connection-updated", connection);
|
||||
}
|
||||
}
|
||||
|
||||
if (lines)
|
||||
g_strfreev (lines);
|
||||
g_free (contents);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_profile_item_changed (SCPluginIfcfg *plugin, const char *path)
|
||||
{
|
||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
|
||||
char *basename;
|
||||
|
||||
g_return_if_fail (plugin != NULL);
|
||||
g_return_if_fail (evt != NULL);
|
||||
g_return_if_fail (path != NULL);
|
||||
|
||||
path = g_hash_table_lookup (priv->watch_table, GINT_TO_POINTER (evt->wd));
|
||||
basename = g_path_get_basename (path);
|
||||
if (!basename) {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, "not enough memory to parse connection change.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strncmp (basename, IFCFG_TAG, strlen (IFCFG_TAG)))
|
||||
handle_connection_changed (plugin, path);
|
||||
else if (!strncmp (basename, KEYS_TAG, strlen (KEYS_TAG))) {
|
||||
char *ifcfg;
|
||||
|
||||
ifcfg = g_strdup_printf ("%s" IFCFG_TAG "%s", priv->profile, basename + strlen (KEYS_TAG));
|
||||
if (ifcfg)
|
||||
handle_connection_changed (plugin, ifcfg);
|
||||
g_free (ifcfg);
|
||||
} else if (!strcmp (basename, "resolv.conf"))
|
||||
handle_resolv_conf_changed (plugin, path);
|
||||
|
||||
g_free (basename);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_profile_item_new (SCPluginIfcfg *plugin, const char *filename)
|
||||
{
|
||||
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
|
||||
char *path;
|
||||
|
||||
path = g_strdup_printf ("%s%s", priv->profile, filename);
|
||||
if (!path)
|
||||
return;
|
||||
|
||||
if (!strncmp (filename, IFCFG_TAG, strlen (IFCFG_TAG))) {
|
||||
NMConnection *new_connection;
|
||||
NMConnection *existing;
|
||||
ConnectionData *new_cdata;
|
||||
if (!strcmp (filename, "resolv.conf")) {
|
||||
watch_path (path, priv->ifd, priv->watch_table);
|
||||
handle_resolv_conf_changed (plugin, path);
|
||||
} else if (!strncmp (filename, IFCFG_TAG, strlen (IFCFG_TAG))) {
|
||||
NMConnection *connection;
|
||||
|
||||
new_connection = build_one_connection (priv->profile, filename);
|
||||
if (!new_connection)
|
||||
goto out;
|
||||
connection = handle_new_ifcfg (priv->profile, path, priv->ifd, priv->watch_table);
|
||||
if (connection) {
|
||||
ConnectionData *cdata;
|
||||
|
||||
new_cdata = connection_data_get (new_connection);
|
||||
g_assert (new_cdata);
|
||||
cdata = connection_data_get (connection);
|
||||
g_assert (cdata);
|
||||
|
||||
existing = find_connection_by_path (priv->connections, new_cdata->ifcfg_path);
|
||||
if (existing) {
|
||||
GHashTable *new_settings;
|
||||
ConnectionData *existing_cdata;
|
||||
|
||||
/* update the settings of the existing connection for this
|
||||
* ifcfg file and notify listeners that something has changed.
|
||||
*/
|
||||
new_settings = nm_connection_to_hash (new_connection);
|
||||
if (!nm_connection_replace_settings (existing, new_settings)) {
|
||||
/* couldn't replace the settings for some reason; have to
|
||||
* remove the connection then.
|
||||
*/
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, "couldn't update connection for '%s'.", filename);
|
||||
priv->connections = g_slist_remove (priv->connections, existing);
|
||||
g_signal_emit_by_name (plugin, "connection-removed", existing);
|
||||
g_object_unref (existing);
|
||||
} else {
|
||||
existing_cdata = connection_data_get (existing);
|
||||
g_assert (existing_cdata);
|
||||
connection_data_copy_secrets (new_cdata, existing_cdata);
|
||||
g_signal_emit_by_name (plugin, "connection-updated", existing);
|
||||
/* new connection */
|
||||
priv->connections = g_slist_append (priv->connections, connection);
|
||||
if (!cdata->ignored) {
|
||||
cdata->exported = TRUE;
|
||||
g_signal_emit_by_name (plugin, "connection-added", connection);
|
||||
}
|
||||
g_object_unref (new_connection);
|
||||
} else {
|
||||
/* totally new connection */
|
||||
priv->connections = g_slist_append (priv->connections, new_connection);
|
||||
g_signal_emit_by_name (plugin, "connection-added", new_connection);
|
||||
}
|
||||
} else if (!strcmp (filename, "resolv.conf")) {
|
||||
// Update dns entries in all connections
|
||||
}
|
||||
|
||||
out:
|
||||
return;
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -380,18 +564,30 @@ stuff_changed (GIOChannel *channel, GIOCondition cond, gpointer user_data)
|
|||
|
||||
/* read the notifications from the watch descriptor */
|
||||
while (g_io_channel_read_chars (channel, (gchar *) &evt, sizeof (struct inotify_event), NULL, NULL) == G_IO_STATUS_NORMAL) {
|
||||
const char *path;
|
||||
gchar filename[PATH_MAX + 1];
|
||||
|
||||
if (evt.len <= 0)
|
||||
continue;
|
||||
path = g_hash_table_lookup (priv->watch_table, GINT_TO_POINTER (evt.wd));
|
||||
|
||||
g_io_channel_read_chars (channel,
|
||||
filename,
|
||||
evt.len > PATH_MAX ? PATH_MAX : evt.len,
|
||||
NULL, NULL);
|
||||
filename[0] = '\0';
|
||||
if (evt.len > 0) {
|
||||
g_io_channel_read_chars (channel,
|
||||
filename,
|
||||
evt.len > PATH_MAX ? PATH_MAX : evt.len,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
if (!path && !strlen (filename)) {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, "unhandled inotify event.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (evt.wd == priv->profile_wd) {
|
||||
if (!strcmp (filename, "network")) {
|
||||
char *basename;
|
||||
|
||||
basename = g_path_get_basename (filename);
|
||||
|
||||
if (basename && !strcmp (basename, "network")) {
|
||||
char *new_profile;
|
||||
|
||||
new_profile = get_current_profile_path ();
|
||||
|
|
@ -406,8 +602,21 @@ stuff_changed (GIOChannel *channel, GIOCondition cond, gpointer user_data)
|
|||
}
|
||||
g_free (new_profile);
|
||||
}
|
||||
} else
|
||||
handle_profile_item_changed (plugin, &evt, filename);
|
||||
g_free (basename);
|
||||
} else {
|
||||
/* If the item was deleted, stop tracking its watch */
|
||||
if (evt.mask & (IN_DELETE | IN_DELETE_SELF)) {
|
||||
inotify_rm_watch (priv->ifd, evt.wd);
|
||||
g_hash_table_remove (priv->watch_table, GINT_TO_POINTER (evt.wd));
|
||||
}
|
||||
|
||||
if (strlen (filename) && !strcmp (path, priv->profile)) {
|
||||
/* Some file appeared */
|
||||
handle_profile_item_new (plugin, filename);
|
||||
} else {
|
||||
handle_profile_item_changed (plugin, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -261,6 +261,8 @@ load_connections (gpointer user_data)
|
|||
g_object_set_data (G_OBJECT (elt->data), NM_SS_PLUGIN_TAG, plugin);
|
||||
connection_added_cb (NM_SYSTEM_CONFIG_INTERFACE (plugin), NM_CONNECTION (elt->data), app);
|
||||
}
|
||||
|
||||
g_slist_free (plugin_connections);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ struct _NMSystemConfigInterface {
|
|||
void (*init) (NMSystemConfigInterface *config);
|
||||
|
||||
/* Returns the plugins currently known list of connections. The returned
|
||||
* list is owned by the plugin and not freed by the system settings service.
|
||||
* list is freed by the system settings service.
|
||||
*/
|
||||
GSList * (*get_connections) (NMSystemConfigInterface *config);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue