]> git.ipfire.org Git - network.git/commitdiff
networkd: Implement setting configuration values
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 30 Jan 2023 03:04:01 +0000 (03:04 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 30 Jan 2023 03:04:01 +0000 (03:04 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/networkd/config.c
src/networkd/config.h
src/networkd/string.h [new file with mode: 0644]

index 50a6034a0b6dec769a3417a0a49ad7f74758422b..1b18f62bbf99286818a63195ca08decc913d815b 100644 (file)
@@ -311,7 +311,8 @@ dist_networkd_SOURCES = \
        src/networkd/daemon.c \
        src/networkd/daemon.h \
        src/networkd/logging.h \
-       src/networkd/main.c
+       src/networkd/main.c \
+       src/networkd/string.h
 
 networkd_CPPFLAGS = \
        $(AM_CPPFLAGS)
index e808531b4949130b545b6be5c0f30c3444342b5d..72a0cfbb2c597a9b7d1c91d9703f693332faf640 100644 (file)
 #                                                                             #
 #############################################################################*/
 
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <sys/queue.h>
 
 #include "config.h"
 #include "logging.h"
+#include "string.h"
+
+struct nw_config_entry {
+       STAILQ_ENTRY(nw_config_entry) nodes;
+
+       char key[NETWORK_CONFIG_KEY_MAX_LENGTH];
+       char value[NETWORK_CONFIG_KEY_MAX_LENGTH];
+};
 
 struct nw_config {
        int nrefs;
+
+       STAILQ_HEAD(entries, nw_config_entry) entries;
 };
 
+static void nw_config_entry_free(struct nw_config_entry* entry) {
+       free(entry);
+}
+
+static struct nw_config_entry* nw_config_entry_create(
+               struct nw_config* config, const char* key) {
+       int r;
+
+       // Check input value
+       if (!key) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       // Allocate a new object
+       struct nw_config_entry* entry = calloc(1, sizeof(*entry));
+       if (!entry)
+               return NULL;
+
+       // Store the key
+       r = nw_string_set(entry->key, key);
+       if (r)
+               goto ERROR;
+
+       // Append the new entry
+       STAILQ_INSERT_TAIL(&config->entries, entry, nodes);
+
+ERROR:
+       nw_config_entry_free(entry);
+       return NULL;
+}
+
 static void nw_config_free(struct nw_config* config) {
+       struct nw_config_entry* entry = NULL;
+
+       while (!STAILQ_EMPTY(&config->entries)) {
+               entry = STAILQ_FIRST(&config->entries);
+               STAILQ_REMOVE_HEAD(&config->entries, nodes);
+
+               // Free the entry
+               nw_config_entry_free(entry);
+       }
+
        free(config);
 }
 
@@ -40,6 +95,9 @@ int nw_config_create(struct nw_config** config) {
        // Initialize reference counter
        c->nrefs = 1;
 
+       // Initialise entries
+       STAILQ_INIT(&c->entries);
+
        *config = c;
 
        return 0;
@@ -106,3 +164,59 @@ ERROR:
 
        return r;
 }
+
+static struct nw_config_entry* nw_config_find(struct nw_config* config, const char* key) {
+       struct nw_config_entry* entry = NULL;
+
+       STAILQ_FOREACH(entry, &config->entries, nodes) {
+               // Key must match
+               if (strcmp(entry->key, key) != 0)
+                       continue;
+
+               // Match!
+               return entry;
+       }
+
+       // No match
+       return NULL;
+}
+
+int nw_config_del(struct nw_config* config, const char* key) {
+       struct nw_config_entry* entry = NULL;
+
+       // Find an entry matching the key
+       entry = nw_config_find(config, key);
+
+       // If there is no entry, there is nothing to do
+       if (!entry)
+               return 0;
+
+       // Otherwise remove the object
+       STAILQ_REMOVE(&config->entries, entry, nw_config_entry, nodes);
+
+       // Free the entry
+       nw_config_entry_free(entry);
+
+       return 0;
+}
+
+int nw_config_set(struct nw_config* config, const char* key, const char* value) {
+       struct nw_config_entry* entry = NULL;
+
+       // Delete the entry if val is NULL
+       if (!value)
+               return nw_config_del(config, key);
+
+       // Find any existing entries
+       entry = nw_config_find(config, key);
+
+       // Create a new entry if it doesn't exist, yet
+       if (!entry) {
+               entry = nw_config_entry_create(config, key);
+               if (!entry)
+                       return 1;
+       }
+
+       // Store the new value
+       return nw_string_set(entry->value, value);
+}
index 559ba9484fc577ed92caad6863d18582df44fb16..a793229ce9669b3625359a775f3f05a809eab296 100644 (file)
@@ -21,6 +21,9 @@
 #ifndef NETWORKD_CONFIG_H
 #define NETWORKD_CONFIG_H
 
+#define NETWORK_CONFIG_KEY_MAX_LENGTH          128
+#define NETWORK_CONFIG_VALUE_MAX_LENGTH                2048
+
 struct nw_config;
 
 int nw_config_create(struct nw_config** config);
@@ -31,4 +34,8 @@ struct nw_config* nw_config_unref(struct nw_config* config);
 int nw_config_readf(struct nw_config** config, FILE* f);
 int nw_config_read(struct nw_config** config, const char* path);
 
+int nw_config_del(struct nw_config* config, const char* key);
+
+int nw_config_set(struct nw_config* config, const char* key, const char* value);
+
 #endif /* NETWORKD_CONFIG_H */
diff --git a/src/networkd/string.h b/src/networkd/string.h
new file mode 100644 (file)
index 0000000..3ac4846
--- /dev/null
@@ -0,0 +1,76 @@
+/*#############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2023 IPFire Network Development Team                          #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#ifndef NETWORKD_STRING_H
+#define NETWORKD_STRING_H
+
+#include <stdarg.h>
+
+static inline int __nw_string_vformat(char* s, const size_t length,
+               const char* format, va_list args) {
+       // Write string to buffer
+       const ssize_t required = vsnprintf(s, length, format, args);
+
+       // Catch any errors
+       if (required < 0)
+               return 1;
+
+       // Check if the entire string could be written
+       if ((size_t)required >= length) {
+               errno = ENOMEM;
+               return 1;
+       }
+
+       // Success
+       return 0;
+}
+
+#define nw_string_format(s, format, ...) \
+       __nw_string_format(s, sizeof(s), format, __VA_ARGS__)
+
+static inline int __nw_string_format(char* s, const size_t length,
+               const char* format, ...) {
+       va_list args;
+       int r;
+
+       // Call __nw_string_vformat
+       va_start(args, format);
+       r = __nw_string_vformat(s, length, format, args);
+       va_end(args);
+
+       return r;
+}
+
+#define nw_string_set(s, value) __nw_string_set(s, sizeof(s), value)
+
+static inline int __nw_string_set(char* s, const size_t length, const char* value) {
+       // If value is NULL, we will overwrite the buffer with just zeros
+       if (!value) {
+               for (unsigned int i = 0; i < length; i++)
+                       s[i] = '\0';
+
+               return 0;
+       }
+
+       // Otherwise just copy
+       return __nw_string_format(s, length, "%s", value);
+}
+
+#endif /* NETWORKD_STRING_H */