static void ifcfg_dir_changed (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer user_data) { SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data); char *path, *base, *ifcfg_path; NMIfcfgConnection *connection; path = g_file_get_path (file); if (utils_should_ignore_file (path, FALSE)) { g_free (path); return; } _LOGD ("ifcfg_dir_changed(%s) = %d", path, event_type); base = g_file_get_basename (file); if (utils_is_ifcfg_alias_file (base, NULL)) { /* Alias file changed. Get the base ifcfg file from it */ ifcfg_path = utils_get_ifcfg_from_alias (path); } else { /* Given any ifcfg, keys, or routes file, get the ifcfg file path */ ifcfg_path = utils_get_ifcfg_path (path); } if (ifcfg_path) { connection = find_by_path (plugin, ifcfg_path); switch (event_type) { case G_FILE_MONITOR_EVENT_DELETED: if (connection) remove_connection (plugin, connection); break; case G_FILE_MONITOR_EVENT_CREATED: case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: /* Update or new */ update_connection (plugin, NULL, ifcfg_path, connection, TRUE, NULL, NULL); break; default: break; } g_free (ifcfg_path); } g_free (path); g_free (base); }
char * utils_detect_ifcfg_path (const char *path, gboolean only_ifcfg) { gs_free char *base = NULL; char *ptr, *ifcfg = NULL; g_return_val_if_fail (path != NULL, NULL); if (utils_should_ignore_file (path, only_ifcfg)) return NULL; base = g_path_get_basename (path); if (strncmp (base, IFCFG_TAG, NM_STRLEN (IFCFG_TAG)) == 0) { if (base[NM_STRLEN (IFCFG_TAG)] == '\0') return NULL; if (utils_is_ifcfg_alias_file (base, NULL)) { ifcfg = g_strdup (path); ptr = strrchr (ifcfg, ':'); if (ptr && ptr > ifcfg) { *ptr = '\0'; if (g_file_test (ifcfg, G_FILE_TEST_EXISTS)) { /* the file has a colon, so it is probably an alias. * To be ~more~ certain that this is an alias file, * check whether a corresponding base file exists. */ if (only_ifcfg) { g_free (ifcfg); return NULL; } return ifcfg; } } g_free (ifcfg); } return g_strdup (path); } if (only_ifcfg) return NULL; return utils_get_ifcfg_path (path); }
char * utils_get_ifcfg_from_alias (const char *alias) { char *base, *ptr, *ifcfg = NULL; g_return_val_if_fail (alias != NULL, NULL); base = g_path_get_basename (alias); g_return_val_if_fail (base != NULL, NULL); if (utils_is_ifcfg_alias_file (base, NULL)) { ifcfg = g_strdup (alias); ptr = strrchr (ifcfg, ':'); if (ptr) *ptr = '\0'; else { g_free (ifcfg); ifcfg = NULL; } } g_free (base); return ifcfg; }
static void read_connections (SCPluginIfcfg *plugin) { SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); GDir *dir; GError *err = NULL; const char *item; GHashTable *alive_connections; GHashTableIter iter; NMIfcfgConnection *connection; GPtrArray *dead_connections = NULL; guint i; GPtrArray *filenames; GHashTable *paths; dir = g_dir_open (IFCFG_DIR, 0, &err); if (!dir) { _LOGW ("Could not read directory '%s': %s", IFCFG_DIR, err->message); g_error_free (err); return; } alive_connections = g_hash_table_new (NULL, NULL); filenames = g_ptr_array_new_with_free_func (g_free); while ((item = g_dir_read_name (dir))) { char *full_path; if (utils_should_ignore_file (item, TRUE)) continue; if (utils_is_ifcfg_alias_file (item, NULL)) continue; full_path = g_build_filename (IFCFG_DIR, item, NULL); if (!utils_get_ifcfg_name (full_path, TRUE)) g_free (full_path); else g_ptr_array_add (filenames, full_path); } g_dir_close (dir); /* While reloading, we don't replace connections that we already loaded while * iterating over the files. * * To have sensible, reproducible behavior, sort the paths by last modification * time prefering older files. */ paths = _paths_from_connections (priv->connections); g_ptr_array_sort_with_data (filenames, (GCompareDataFunc) _sort_paths, paths); g_hash_table_destroy (paths); for (i = 0; i < filenames->len; i++) { connection = update_connection (plugin, NULL, filenames->pdata[i], NULL, FALSE, alive_connections, NULL); if (connection) g_hash_table_add (alive_connections, connection); } g_ptr_array_free (filenames, TRUE); g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &connection)) { if ( !g_hash_table_contains (alive_connections, connection) && nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection))) { if (!dead_connections) dead_connections = g_ptr_array_new (); g_ptr_array_add (dead_connections, connection); } } g_hash_table_destroy (alive_connections); if (dead_connections) { for (i = 0; i < dead_connections->len; i++) remove_connection (plugin, dead_connections->pdata[i]); g_ptr_array_free (dead_connections, TRUE); } }