1 /*#############################################################################
3 # IPFire.org - A linux based firewall #
4 # Copyright (C) 2023 IPFire Network Development Team #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 #############################################################################*/
25 #include <sys/queue.h>
31 struct nw_config_entry
{
32 STAILQ_ENTRY(nw_config_entry
) nodes
;
34 char key
[NETWORK_CONFIG_KEY_MAX_LENGTH
];
35 char value
[NETWORK_CONFIG_KEY_MAX_LENGTH
];
41 STAILQ_HEAD(entries
, nw_config_entry
) entries
;
44 static void nw_config_entry_free(struct nw_config_entry
* entry
) {
48 static struct nw_config_entry
* nw_config_entry_create(
49 struct nw_config
* config
, const char* key
) {
58 // Allocate a new object
59 struct nw_config_entry
* entry
= calloc(1, sizeof(*entry
));
64 r
= nw_string_set(entry
->key
, key
);
68 // Append the new entry
69 STAILQ_INSERT_TAIL(&config
->entries
, entry
, nodes
);
72 nw_config_entry_free(entry
);
76 static void nw_config_free(struct nw_config
* config
) {
77 struct nw_config_entry
* entry
= NULL
;
79 while (!STAILQ_EMPTY(&config
->entries
)) {
80 entry
= STAILQ_FIRST(&config
->entries
);
81 STAILQ_REMOVE_HEAD(&config
->entries
, nodes
);
84 nw_config_entry_free(entry
);
90 int nw_config_create(struct nw_config
** config
) {
91 struct nw_config
* c
= calloc(1, sizeof(*c
));
95 // Initialize reference counter
99 STAILQ_INIT(&c
->entries
);
106 struct nw_config
* nw_config_ref(struct nw_config
* config
) {
112 struct nw_config
* nw_config_unref(struct nw_config
* config
) {
113 if (--config
->nrefs
> 0)
116 nw_config_free(config
);
120 static int nw_config_parse(struct nw_config
* config
, FILE* f
) {
126 int nw_config_readf(struct nw_config
** config
, FILE* f
) {
129 // Create a new config object
130 r
= nw_config_create(config
);
134 // Parse the configuration
135 r
= nw_config_parse(*config
, f
);
142 nw_config_free(*config
);
146 int nw_config_read(struct nw_config
** config
, const char* path
) {
151 f
= fopen(path
, "r");
153 ERROR("Could not read configuration file %s: %m\n", path
);
159 r
= nw_config_readf(config
, f
);
168 int nw_config_writef(struct nw_config
* config
, FILE* f
) {
169 struct nw_config_entry
* entry
= NULL
;
172 STAILQ_FOREACH(entry
, &config
->entries
, nodes
) {
173 // Skip if value is NULL
178 r
= fprintf(f
, "%s=\"%s\"\n", entry
->key
, entry
->value
);
180 ERROR("Failed to write configuration: %m\n");
188 int nw_config_write(struct nw_config
* config
, const char* path
) {
191 FILE* f
= fopen(path
, "w");
193 ERROR("Failed to open %s for writing: %m\n", path
);
198 // Write configuration
199 r
= nw_config_writef(config
, f
);
208 static struct nw_config_entry
* nw_config_find(struct nw_config
* config
, const char* key
) {
209 struct nw_config_entry
* entry
= NULL
;
211 STAILQ_FOREACH(entry
, &config
->entries
, nodes
) {
213 if (strcmp(entry
->key
, key
) != 0)
224 int nw_config_del(struct nw_config
* config
, const char* key
) {
225 struct nw_config_entry
* entry
= NULL
;
227 // Find an entry matching the key
228 entry
= nw_config_find(config
, key
);
230 // If there is no entry, there is nothing to do
234 // Otherwise remove the object
235 STAILQ_REMOVE(&config
->entries
, entry
, nw_config_entry
, nodes
);
238 nw_config_entry_free(entry
);
243 int nw_config_set(struct nw_config
* config
, const char* key
, const char* value
) {
244 struct nw_config_entry
* entry
= NULL
;
246 // Delete the entry if val is NULL
248 return nw_config_del(config
, key
);
250 // Find any existing entries
251 entry
= nw_config_find(config
, key
);
253 // Create a new entry if it doesn't exist, yet
255 entry
= nw_config_entry_create(config
, key
);
260 // Store the new value
261 return nw_string_set(entry
->value
, value
);
264 const char* nw_config_get(struct nw_config
* config
, const char* key
) {
265 struct nw_config_entry
* entry
= nw_config_find(config
, key
);
267 // Return the value if found and set
268 if (entry
&& *entry
->value
)
271 // Otherwise return NULL
275 unsigned int nw_config_get_unsigned_int(struct nw_config
* config
, const char* key
) {
276 const char* value
= nw_config_get(config
, key
);
278 // Return zero if not set
282 return strtoul(value
, NULL
, 10);