]> git.ipfire.org Git - people/ms/network.git/blobdiff - src/networkd/config.c
config: Add string buffer type
[people/ms/network.git] / src / networkd / config.c
index b142d17d452e1eef405f18415443152351d8068e..c6281cb249021a4c1d25111b75f2d5af58d4d008 100644 (file)
@@ -43,18 +43,17 @@ struct nw_config_option {
 
        const char* key;
        void* value;
+       size_t length;
 
        // Callbacks
        nw_config_option_read_callback_t read_callback;
        nw_config_option_write_callback_t write_callback;
+       void* data;
 };
 
 struct nw_config {
        int nrefs;
 
-       // The path to the configuration file
-       char path[PATH_MAX];
-
        STAILQ_HEAD(config_entries, nw_config_entry) entries;
 
        // Options
@@ -117,7 +116,7 @@ static void nw_config_free(nw_config* config) {
        free(config);
 }
 
-int nw_config_create(nw_config** config, const char* path) {
+int nw_config_create(nw_config** config, FILE* f) {
        int r;
 
        nw_config* c = calloc(1, sizeof(*c));
@@ -133,15 +132,10 @@ int nw_config_create(nw_config** config, const char* path) {
        // Initialise options
        STAILQ_INIT(&c->options);
 
-       // Store the path
-       if (path) {
-               r = nw_string_set(c->path, path);
-               if (r)
-                       goto ERROR;
-
-               // Try to read the configuration from path
-               r = nw_config_read(c);
-               if (r)
+       // Read configuration
+       if (f) {
+               r = nw_config_read(c, f);
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -155,6 +149,25 @@ ERROR:
        return r;
 }
 
+int nw_config_open(nw_config** config, const char* path) {
+       FILE* f = NULL;
+       int r;
+
+       // Open path
+       f = fopen(path, "r");
+       if (!f)
+               return -errno;
+
+       // Create a new configuration
+       r = nw_config_create(config, f);
+
+ERROR:
+       if (f)
+               fclose(f);
+
+       return r;
+}
+
 nw_config* nw_config_ref(nw_config* config) {
        config->nrefs++;
 
@@ -169,17 +182,6 @@ nw_config* nw_config_unref(nw_config* config) {
        return NULL;
 }
 
-int nw_config_destroy(nw_config* config) {
-       int r;
-
-       // Drop all entries
-       r = nw_config_flush(config);
-       if (r)
-               return r;
-
-       return unlink(config->path);
-}
-
 int nw_config_copy(nw_config* config, nw_config** copy) {
        struct nw_config_entry* entry = NULL;
        nw_config* c = NULL;
@@ -207,13 +209,6 @@ ERROR:
        return r;
 }
 
-const char* nw_config_path(nw_config* config) {
-       if (*config->path)
-               return config->path;
-
-       return NULL;
-}
-
 int nw_config_flush(nw_config* config) {
        struct nw_config_entry* entry = NULL;
 
@@ -228,7 +223,7 @@ int nw_config_flush(nw_config* config) {
        return 0;
 }
 
-static int nw_config_readf(nw_config* config, FILE* f) {
+int nw_config_read(nw_config* config, FILE* f) {
        char* line = NULL;
        size_t length = 0;
        int r;
@@ -274,39 +269,7 @@ static int nw_config_readf(nw_config* config, FILE* f) {
        return r;
 }
 
-int nw_config_read(nw_config* config) {
-       FILE* f = NULL;
-       int r;
-
-       // We cannot read if path is not set
-       if (!*config->path) {
-               errno = ENOTSUP;
-               return 1;
-       }
-
-       // Open the file
-       f = fopen(config->path, "r");
-       if (!f) {
-               // Silently ignore if the file does not exist
-               if (errno == ENOENT)
-                       return 0;
-
-               ERROR("Could not read configuration file %s: %m\n", config->path);
-               r = 1;
-               goto ERROR;
-       }
-
-       // Read from file
-       r = nw_config_readf(config, f);
-
-ERROR:
-       if (f)
-               fclose(f);
-
-       return r;
-}
-
-static int nw_config_writef(nw_config* config, FILE* f) {
+int nw_config_write(nw_config* config, FILE* f) {
        struct nw_config_entry* entry = NULL;
        int r;
 
@@ -326,32 +289,6 @@ static int nw_config_writef(nw_config* config, FILE* f) {
        return 0;
 }
 
-int nw_config_write(nw_config* config) {
-       int r;
-
-       // We cannot write if path is not set
-       if (!*config->path) {
-               errno = ENOTSUP;
-               return 1;
-       }
-
-       FILE* f = fopen(config->path, "w");
-       if (!f) {
-               ERROR("Failed to open %s for writing: %m\n", config->path);
-               r = 1;
-               goto ERROR;
-       }
-
-       // Write configuration
-       r = nw_config_writef(config, f);
-
-ERROR:
-       if (f)
-               fclose(f);
-
-       return r;
-}
-
 static struct nw_config_entry* nw_config_find(nw_config* config, const char* key) {
        struct nw_config_entry* entry = NULL;
 
@@ -491,7 +428,8 @@ int nw_config_options_read(nw_config* config) {
        int r;
 
        STAILQ_FOREACH(option, &config->options, nodes) {
-               r = option->read_callback(config, option->key, option->value);
+               r = option->read_callback(config,
+                       option->key, option->value, option->length, option->data);
                if (r < 0)
                        return r;
        }
@@ -504,7 +442,8 @@ int nw_config_options_write(nw_config* config) {
        int r;
 
        STAILQ_FOREACH(option, &config->options, nodes) {
-               r = option->write_callback(config, option->key, option->value);
+               r = option->write_callback(config,
+                       option->key, option->value, option->length, option->data);
                if (r < 0)
                        return r;
        }
@@ -512,9 +451,10 @@ int nw_config_options_write(nw_config* config) {
        return 0;
 }
 
-int nw_config_option_add(nw_config* config, const char* key, void* value,
+int nw_config_option_add(nw_config* config,
+               const char* key, void* value, const size_t length,
                nw_config_option_read_callback_t read_callback,
-               nw_config_option_write_callback_t write_callback) {
+               nw_config_option_write_callback_t write_callback, void* data) {
        // Check input
        if (!key || !value || !read_callback || !write_callback)
                return -EINVAL;
@@ -529,10 +469,12 @@ int nw_config_option_add(nw_config* config, const char* key, void* value,
 
        // Set value
        option->value = value;
+       option->length = length;
 
        // Set callbacks
        option->read_callback = read_callback;
        option->write_callback = write_callback;
+       option->data = data;
 
        // Append the new option
        STAILQ_INSERT_TAIL(&config->options, option, nodes);
@@ -540,20 +482,23 @@ int nw_config_option_add(nw_config* config, const char* key, void* value,
        return 0;
 }
 
-int nw_config_read_int(nw_config* config, const char* key, void* value) {
+int nw_config_read_int(nw_config* config,
+               const char* key, void* value, const size_t length, void* data) {
        // Fetch the value
        *(int*)value = nw_config_get_int(config, key, -1);
 
        return 0;
 }
 
-int nw_config_write_int(nw_config* config, const char* key, const void* value) {
+int nw_config_write_int(nw_config* config,
+               const char* key, const void* value, const size_t length, void* data) {
        return 0;
 }
 
 // String
 
-int nw_config_read_string(nw_config* config, const char* key, void* value) {
+int nw_config_read_string(nw_config* config,
+               const char* key, void* value, const size_t length, void* data) {
        // Fetch the value
        const char* p = nw_config_get(config, key);
        if (p)
@@ -562,13 +507,67 @@ int nw_config_read_string(nw_config* config, const char* key, void* value) {
        return 0;
 }
 
-int nw_config_write_string(nw_config* config, const char* key, const void* value) {
+int nw_config_write_string(nw_config* config,
+               const char* key, const void* value, const size_t length, void* data) {
        return nw_config_set(config, key, *(const char**)value);
 }
 
+// String Buffer
+
+int nw_config_read_string_buffer(nw_config* config,
+               const char* key, void* value, const size_t length, void* data) {
+       char* string = (char*)value;
+
+       // Fetch the value
+       const char* p = nw_config_get(config, key);
+       if (p)
+               return __nw_string_set(string, length, p);
+
+       return 0;
+}
+
+// String Table
+
+int nw_config_read_string_table(nw_config* config,
+               const char* key, void* value, const size_t length, void* data) {
+       const char* s = NULL;
+       int* v = (int*)value;
+
+       const nw_string_table_t* table = (nw_string_table_t*)data;
+
+       // Fetch the string
+       s = nw_config_get(config, key);
+       if (!s)
+               return -errno;
+
+       // Lookup the string in the table
+       *v = nw_string_table_lookup_id(table, s);
+
+       // If the result is negative, nothing was found
+       if (*v < 0)
+               return -EINVAL;
+
+       return 0;
+}
+
+int nw_config_write_string_table(nw_config* config,
+               const char* key, const void* value, const size_t length, void* data) {
+       int* v = (int*)value;
+
+       const nw_string_table_t* table = (nw_string_table_t*)data;
+
+       // Lookup the string
+       const char* s = nw_string_table_lookup_string(table, *v);
+       if (!s)
+               return -errno;
+
+       return nw_config_set(config, key, s);
+}
+
 // Address
 
-int nw_config_read_address(nw_config* config, const char* key, void* value) {
+int nw_config_read_address(nw_config* config,
+               const char* key, void* value, const size_t length, void* data) {
        nw_address_t* address = (nw_address_t*)value;
        int r;
 
@@ -584,7 +583,8 @@ int nw_config_read_address(nw_config* config, const char* key, void* value) {
        return r;
 }
 
-int nw_config_write_address(nw_config* config, const char* key, const void* value) {
+int nw_config_write_address(nw_config* config,
+               const char* key, const void* value, const size_t length, void* data) {
        const nw_address_t* address = (nw_address_t*)value;
        int r;