diff options
author | Thomas Haller <thaller@redhat.com> | 2021-06-24 21:42:36 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2021-07-01 11:17:06 +0200 |
commit | f59def45c1b3e9d9892930a424a3f9d576ea9352 (patch) | |
tree | 66474d9b68b695e8b469dbdac3757f752abbc95a | |
parent | 8278719840fe926bf103cd47547ecc38fc882477 (diff) | |
download | NetworkManager-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.c | 78 | ||||
-rw-r--r-- | src/libnm-glib-aux/nm-keyfile-aux.h | 4 |
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__ */ |