1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
/* 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 <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;
}
|