// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2019 Red Hat, Inc. */ #include "nm-default.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; }