/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2019 Red Hat, Inc. */ #include "src/core/nm-default-daemon.h" #include "nm-settings-utils.h" #include #include #include #include #include "nm-settings-plugin.h" /*****************************************************************************/ const struct timespec * nm_sett_util_stat_mtime(const char *filename, gboolean do_lstat, struct timespec *out_val) { struct stat st; struct timeval now_tv; if (filename) { if (do_lstat) { if (lstat(filename, &st) == 0) { *out_val = st.st_mtim; return out_val; } } else { if (stat(filename, &st) == 0) { *out_val = st.st_mtim; return out_val; } } } if (gettimeofday(&now_tv, NULL) == 0) { *out_val = (struct timespec){ .tv_sec = now_tv.tv_sec, .tv_nsec = now_tv.tv_usec * 1000u, }; return out_val; } *out_val = (struct timespec){}; return out_val; } /*****************************************************************************/ gboolean nm_sett_util_allow_filename_cb(const char *filename, gpointer user_data) { const NMSettUtilAllowFilenameData *allow_filename_data = user_data; if (allow_filename_data->allowed_filename && nm_streq(allow_filename_data->allowed_filename, filename)) return TRUE; return !g_hash_table_contains(allow_filename_data->idx_by_filename, filename); } /*****************************************************************************/ void nm_sett_util_storage_by_uuid_head_destroy(NMSettUtilStorageByUuidHead *sbuh) { CList *iter; while ((iter = c_list_first(&sbuh->_storage_by_uuid_lst_head))) c_list_unlink(iter); g_free(sbuh); } /*****************************************************************************/ void nm_sett_util_storages_clear(NMSettUtilStorages *storages) { nm_clear_pointer(&storages->idx_by_uuid, g_hash_table_destroy); nm_clear_pointer(&storages->idx_by_filename, g_hash_table_destroy); nm_assert(c_list_is_empty(&storages->_storage_lst_head)); } void nm_sett_util_storages_add_take(NMSettUtilStorages *storages, gpointer storage_take_p /* NMSettingsStorage *, take reference */) { NMSettingsStorage *storage_take = storage_take_p; NMSettUtilStorageByUuidHead *sbuh; const char *uuid; nm_assert(storage_take); nm_assert(c_list_is_empty(&storage_take->_storage_lst)); nm_assert(c_list_is_empty(&storage_take->_storage_by_uuid_lst)); nm_assert(nm_settings_storage_get_filename(storage_take)); if (!g_hash_table_replace(storages->idx_by_filename, (char *) nm_settings_storage_get_filename(storage_take), storage_take /* takes ownership of reference. */)) nm_assert_not_reached(); uuid = nm_settings_storage_get_uuid_opt(storage_take); if (uuid) { sbuh = nm_sett_util_storages_lookup_by_uuid(storages, uuid); if (!sbuh) { gsize l = strlen(uuid) + 1; sbuh = g_malloc(sizeof(NMSettUtilStorageByUuidHead) + l); sbuh->uuid = sbuh->uuid_data; c_list_init(&sbuh->_storage_by_uuid_lst_head); memcpy(sbuh->uuid_data, uuid, l); g_hash_table_add(storages->idx_by_uuid, sbuh); } c_list_link_tail(&sbuh->_storage_by_uuid_lst_head, &storage_take->_storage_by_uuid_lst); } c_list_link_tail(&storages->_storage_lst_head, &storage_take->_storage_lst); } gpointer /* NMSettingsStorage * */ nm_sett_util_storages_steal(NMSettUtilStorages *storages, gpointer storage_p /* NMSettingsStorage **/) { NMSettingsStorage *storage = storage_p; NMSettUtilStorageByUuidHead *sbuh; const char *uuid; nm_assert(storage); nm_assert(nm_sett_util_storages_lookup_by_filename(storages, nm_settings_storage_get_filename(storage)) == storage); nm_assert(c_list_contains(&storages->_storage_lst_head, &storage->_storage_lst)); uuid = nm_settings_storage_get_uuid_opt(storage); if (!uuid) { nm_assert(c_list_is_empty(&storage->_storage_by_uuid_lst)); } else { nm_assert(!c_list_is_empty(&storage->_storage_by_uuid_lst)); sbuh = nm_sett_util_storages_lookup_by_uuid(storages, uuid); nm_assert(sbuh); nm_assert( c_list_contains(&sbuh->_storage_by_uuid_lst_head, &storage->_storage_by_uuid_lst)); c_list_unlink(&storage->_storage_by_uuid_lst); if (c_list_is_empty(&sbuh->_storage_by_uuid_lst_head)) g_hash_table_remove(storages->idx_by_uuid, sbuh); } c_list_unlink(&storage->_storage_lst); g_hash_table_steal(storages->idx_by_filename, nm_settings_storage_get_filename(storage)); return storage; }