keyfile-aux: add nm_key_file_db_prune() helper

A helper function to remove entires that are no longer
relevant.

(cherry picked from commit f59def45c1)
This commit is contained in:
Thomas Haller 2021-06-24 21:42:36 +02:00
parent 1afc327c5d
commit 697a445f6b
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
2 changed files with 80 additions and 2 deletions

View file

@ -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;
}
}
}
}

View file

@ -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__ */