summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2021-06-24 21:42:36 +0200
committerThomas Haller <thaller@redhat.com>2021-07-01 11:17:06 +0200
commitf59def45c1b3e9d9892930a424a3f9d576ea9352 (patch)
tree66474d9b68b695e8b469dbdac3757f752abbc95a
parent8278719840fe926bf103cd47547ecc38fc882477 (diff)
downloadNetworkManager-f59def45c1b3e9d9892930a424a3f9d576ea9352.tar.gz
keyfile-aux: add nm_key_file_db_prune() helper
A helper function to remove entires that are no longer relevant.
-rw-r--r--src/libnm-glib-aux/nm-keyfile-aux.c78
-rw-r--r--src/libnm-glib-aux/nm-keyfile-aux.h4
2 files changed, 80 insertions, 2 deletions
diff --git a/src/libnm-glib-aux/nm-keyfile-aux.c b/src/libnm-glib-aux/nm-keyfile-aux.c
index 75abe53848..5d2c0028f7 100644
--- a/src/libnm-glib-aux/nm-keyfile-aux.c
+++ b/src/libnm-glib-aux/nm-keyfile-aux.c
@@ -27,6 +27,8 @@ struct _NMKeyFileDB {
bool dirty : 1;
bool destroyed : 1;
+ bool groups_pruned : 1;
+
char filename[];
};
@@ -62,6 +64,16 @@ _IS_KEY_FILE_DB(NMKeyFileDB *self, gboolean require_is_started, gboolean allow_d
return TRUE;
}
+static GKeyFile *
+_key_file_new(void)
+{
+ GKeyFile *kf;
+
+ kf = g_key_file_new();
+ g_key_file_set_list_separator(kf, ',');
+ return kf;
+}
+
/*****************************************************************************/
NMKeyFileDB *
@@ -86,8 +98,7 @@ nm_key_file_db_new(const char * filename,
self->log_fcn = log_fcn;
self->got_dirty_fcn = got_dirty_fcn;
self->user_data = user_data;
- self->kf = g_key_file_new();
- g_key_file_set_list_separator(self->kf, ',');
+ self->kf = _key_file_new();
memcpy(self->filename, filename, l_filename + 1);
self->group_name = &self->filename[l_filename + 1];
memcpy((char *) self->group_name, group_name, l_group + 1);
@@ -371,3 +382,66 @@ nm_key_file_db_to_file(NMKeyFileDB *self, gboolean force)
} else
_LOGD("write keyfile: \"%s\"", self->filename);
}
+
+/*****************************************************************************/
+
+void
+nm_key_file_db_prune(NMKeyFileDB *self,
+ gboolean (*predicate)(const char *key, gpointer user_data),
+ gpointer user_data)
+{
+ gs_strfreev char ** keys = NULL;
+ nm_auto_unref_keyfile GKeyFile *kf_to_free = NULL;
+ GKeyFile * kf_src = NULL;
+ GKeyFile * kf_dst = NULL;
+ guint k;
+
+ g_return_if_fail(_IS_KEY_FILE_DB(self, TRUE, FALSE));
+ nm_assert(predicate);
+
+ _LOGD("prune keyfile of old entries: \"%s\"", self->filename);
+
+ if (!self->groups_pruned) {
+ /* When we prune the first time, we swap the GKeyfile instance.
+ * The instance loaded from disk might have unrelated groups and
+ * comments. Let's get rid of them by creating a new instance.
+ *
+ * Otherwise, we know that self->kf only contains good keys,
+ * and at most we need to remove some of them. */
+ kf_to_free = g_steal_pointer(&self->kf);
+ self->kf = _key_file_new();
+ kf_src = kf_to_free;
+ self->groups_pruned = TRUE;
+ self->dirty = TRUE;
+ } else
+ kf_src = self->kf;
+ kf_dst = self->kf;
+
+ keys = g_key_file_get_keys(kf_src, self->group_name, NULL, NULL);
+ if (keys) {
+ for (k = 0; keys[k]; k++) {
+ const char *key = keys[k];
+ gboolean keep;
+
+ keep = predicate(key, user_data);
+
+ if (!keep) {
+ if (kf_dst == kf_src) {
+ g_key_file_remove_key(kf_dst, self->group_name, key, NULL);
+ self->dirty = TRUE;
+ }
+ continue;
+ }
+
+ if (kf_dst != kf_src) {
+ gs_free char *value = NULL;
+
+ value = g_key_file_get_value(kf_src, self->group_name, key, NULL);
+ if (value)
+ g_key_file_set_value(kf_dst, self->group_name, key, value);
+ else
+ self->dirty = TRUE;
+ }
+ }
+ }
+}
diff --git a/src/libnm-glib-aux/nm-keyfile-aux.h b/src/libnm-glib-aux/nm-keyfile-aux.h
index 72d2f418f9..c4d4e65111 100644
--- a/src/libnm-glib-aux/nm-keyfile-aux.h
+++ b/src/libnm-glib-aux/nm-keyfile-aux.h
@@ -50,6 +50,10 @@ void nm_key_file_db_set_string_list(NMKeyFileDB * self,
void nm_key_file_db_to_file(NMKeyFileDB *self, gboolean force);
+void nm_key_file_db_prune(NMKeyFileDB *self,
+ gboolean (*predicate)(const char *key, gpointer user_data),
+ gpointer user_data);
+
/*****************************************************************************/
#endif /* __NM_KEYFILE_AUX_H__ */