static gboolean load_connection (NMSystemConfigInterface *config, const char *filename) { SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); NMKeyfileConnection *connection; int dir_len = strlen (KEYFILE_DIR); if ( strncmp (filename, KEYFILE_DIR, dir_len) != 0 || filename[dir_len] != '/' || strchr (filename + dir_len + 1, '/') != NULL) return FALSE; if (nm_keyfile_plugin_utils_should_ignore_file (filename + dir_len + 1)) return FALSE; connection = update_connection (self, NULL, filename, find_by_path (self, filename), TRUE, NULL, NULL); return (connection != NULL); }
static void read_connections (NMSystemConfigInterface *config) { SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); GDir *dir; GError *error = NULL; const char *item; dir = g_dir_open (KEYFILE_DIR, 0, &error); if (!dir) { PLUGIN_WARN (KEYFILE_PLUGIN_NAME, "Cannot read directory '%s': (%d) %s", KEYFILE_DIR, error ? error->code : -1, error && error->message ? error->message : "(unknown)"); g_clear_error (&error); return; } while ((item = g_dir_read_name (dir))) { NMSettingsConnection *connection; char *full_path; if (nm_keyfile_plugin_utils_should_ignore_file (item)) continue; full_path = g_build_filename (KEYFILE_DIR, item, NULL); PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "parsing %s ... ", item); connection = _internal_new_connection (self, full_path, NULL, &error); if (connection) { PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " read connection '%s'", nm_connection_get_id (NM_CONNECTION (connection))); } else { PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s", (error && error->message) ? error->message : "(unknown)"); } g_clear_error (&error); g_free (full_path); } g_dir_close (dir); }
static void dir_changed (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer user_data) { NMSystemConfigInterface *config = NM_SYSTEM_CONFIG_INTERFACE (user_data); SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); NMKeyfileConnection *connection; char *full_path; gboolean exists; full_path = g_file_get_path (file); if (nm_keyfile_plugin_utils_should_ignore_file (full_path)) { g_free (full_path); return; } exists = g_file_test (full_path, G_FILE_TEST_EXISTS); nm_log_dbg (LOGD_SETTINGS, "dir_changed(%s) = %d; file %s", full_path, event_type, exists ? "exists" : "does not exist"); connection = find_by_path (self, full_path); switch (event_type) { case G_FILE_MONITOR_EVENT_DELETED: if (!exists && connection) remove_connection (SC_PLUGIN_KEYFILE (config), connection); break; case G_FILE_MONITOR_EVENT_CREATED: case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: if (exists) update_connection (SC_PLUGIN_KEYFILE (config), NULL, full_path, connection, TRUE, NULL, NULL); break; default: break; } g_free (full_path); }
static void read_connections (NMSystemConfigInterface *config) { SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); GDir *dir; GError *error = NULL; const char *item; GHashTable *alive_connections; GHashTableIter iter; NMKeyfileConnection *connection; GPtrArray *dead_connections = NULL; guint i; GPtrArray *filenames; GHashTable *paths; dir = g_dir_open (KEYFILE_DIR, 0, &error); if (!dir) { nm_log_warn (LOGD_SETTINGS, "keyfile: cannot read directory '%s': (%d) %s", KEYFILE_DIR, error ? error->code : -1, error && error->message ? error->message : "(unknown)"); g_clear_error (&error); 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))) { if (nm_keyfile_plugin_utils_should_ignore_file (item)) continue; g_ptr_array_add (filenames, g_build_filename (KEYFILE_DIR, item, NULL)); } 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 (self, 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 (self, dead_connections->pdata[i]); g_ptr_array_free (dead_connections, TRUE); } }