mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-29 14:40:24 +01:00
Currently "src/" mostly contains the source code of the daemon. I say mostly, because that is not true, there are also the device, settings, wwan, ppp plugins, the initrd generator, the pppd and dhcp helper, and probably more. Also we have source code under libnm-core/, libnm/, clients/, and shared/ directories. That is all confusing. We should have one "src" directory, that contains subdirectories. Those subdirectories should contain individual parts (libraries or applications), that possibly have dependencies on other subdirectories. There should be a flat hierarchy of directories under src/, which contains individual modules. As the name "src/" is already taken, that prevents any sensible restructuring of the code. As a first step, move "src/" to "src/core/". This gives space to reorganize the code better by moving individual components into "src/". For inspiration, look at systemd's "src/" directory. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/743
161 lines
5 KiB
C
161 lines
5 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
/*
|
|
* Copyright (C) 2019 Red Hat, Inc.
|
|
*/
|
|
|
|
#include "nm-default.h"
|
|
|
|
#include "nm-settings-utils.h"
|
|
|
|
#include <sys/stat.h>
|
|
#include <sys/time.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
#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;
|
|
}
|