From b1dfa609f915fb81e73b2b93693d20b56d349c04 Mon Sep 17 00:00:00 2001 From: Maximilian Wilhelm Date: Tue, 28 Jul 2020 22:41:27 +0200 Subject: [PATCH 1/6] dict: Add lif_dict_find_all(). As a dict can have multiple values for any given key we add a function to query all occurences of a given key and return them as a (new) list. Signed-off-by: Maximilian Wilhelm --- libifupdown/dict.c | 26 ++++++++++++++++++++++++++ libifupdown/dict.h | 2 ++ 2 files changed, 28 insertions(+) diff --git a/libifupdown/dict.c b/libifupdown/dict.c index 4ac7085..ce7333d 100644 --- a/libifupdown/dict.c +++ b/libifupdown/dict.c @@ -3,6 +3,7 @@ * Purpose: wrapping linked lists to provide a naive dictionary * * Copyright (c) 2020 Ariadne Conill + * Copyright (c) 2020 Maximilian Wilhelm * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -65,6 +66,31 @@ lif_dict_find(struct lif_dict *dict, const char *key) return NULL; } +struct lif_list * +lif_dict_find_all(struct lif_dict *dict, const char *key) +{ + struct lif_list *entries = calloc(1, sizeof(struct lif_list)); + struct lif_node *iter; + + LIF_LIST_FOREACH(iter, dict->list.head) + { + struct lif_dict_entry *entry = iter->data; + if (!strcmp(entry->key, key)) + { + struct lif_node *new = calloc(1, sizeof(struct lif_node)); + lif_node_insert_tail(new, entry->data, entries); + } + } + + if (entries->length == 0) + { + free(entries); + return NULL; + } + + return entries; +} + void lif_dict_delete(struct lif_dict *dict, const char *key) { diff --git a/libifupdown/dict.h b/libifupdown/dict.h index 298b349..f435916 100644 --- a/libifupdown/dict.h +++ b/libifupdown/dict.h @@ -3,6 +3,7 @@ * Purpose: wrapping linked lists to provide a naive dictionary * * Copyright (c) 2020 Ariadne Conill + * Copyright (c) 2020 Maximilian Wilhelm * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -38,6 +39,7 @@ extern void lif_dict_init(struct lif_dict *dict); extern void lif_dict_fini(struct lif_dict *dict); extern struct lif_dict_entry *lif_dict_add(struct lif_dict *dict, const char *key, void *data); extern struct lif_dict_entry *lif_dict_find(struct lif_dict *dict, const char *key); +extern struct lif_list *lif_dict_find_all(struct lif_dict *dict, const char *key); extern void lif_dict_delete(struct lif_dict *dict, const char *key); extern void lif_dict_delete_entry(struct lif_dict *dict, struct lif_dict_entry *entry); From f51c976b528fd21ea7177325f18d9db7fd54aa92 Mon Sep 17 00:00:00 2001 From: Maximilian Wilhelm Date: Tue, 28 Jul 2020 22:44:22 +0200 Subject: [PATCH 2/6] dict: Add lif_dict_add_once() Add a function to add a key/value pair to the dict only if it doesn't exist within the dict already. As the dict is type agnostic this requires a comparator function to be given. Signed-off-by: Maximilian Wilhelm --- libifupdown/dict.c | 25 +++++++++++++++++++++++++ libifupdown/dict.h | 1 + 2 files changed, 26 insertions(+) diff --git a/libifupdown/dict.c b/libifupdown/dict.c index ce7333d..a0b5f2a 100644 --- a/libifupdown/dict.c +++ b/libifupdown/dict.c @@ -50,6 +50,31 @@ lif_dict_add(struct lif_dict *dict, const char *key, void *data) return entry; } +struct lif_dict_entry * +lif_dict_add_once(struct lif_dict *dict, const char *key, void *data, + int (*compar)(const void *, const void *)) +{ + struct lif_list *existing = lif_dict_find_all(dict, key); + if (existing) + { + struct lif_node *iter; + LIF_LIST_FOREACH(iter, existing->head) + { + if (!compar(data, iter->data)) + return NULL; + } + } + + struct lif_dict_entry *entry = calloc(1, sizeof *entry); + + entry->key = strdup(key); + entry->data = data; + + lif_node_insert_tail(&entry->node, entry, &dict->list); + + return entry; +} + struct lif_dict_entry * lif_dict_find(struct lif_dict *dict, const char *key) { diff --git a/libifupdown/dict.h b/libifupdown/dict.h index f435916..2332c05 100644 --- a/libifupdown/dict.h +++ b/libifupdown/dict.h @@ -38,6 +38,7 @@ struct lif_dict_entry { extern void lif_dict_init(struct lif_dict *dict); extern void lif_dict_fini(struct lif_dict *dict); extern struct lif_dict_entry *lif_dict_add(struct lif_dict *dict, const char *key, void *data); +extern struct lif_dict_entry *lif_dict_add_once(struct lif_dict *dict, const char *key, void *data, int (*compar)(const void *, const void *)); extern struct lif_dict_entry *lif_dict_find(struct lif_dict *dict, const char *key); extern struct lif_list *lif_dict_find_all(struct lif_dict *dict, const char *key); extern void lif_dict_delete(struct lif_dict *dict, const char *key); From 2420023b74d843e4a31c356ab106ac88fbb4b822 Mon Sep 17 00:00:00 2001 From: Maximilian Wilhelm Date: Tue, 28 Jul 2020 22:37:41 +0200 Subject: [PATCH 3/6] Add comparator wrapper and type cast values properly. Signed-off-by: Maximilian Wilhelm --- Makefile | 1 + libifupdown/compar.c | 26 ++++++++++++++++++++++++++ libifupdown/compar.h | 21 +++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 libifupdown/compar.c create mode 100644 libifupdown/compar.h diff --git a/Makefile b/Makefile index ccd016e..d0eca05 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,7 @@ CPPFLAGS += -DEXECUTOR_PATH=\"${EXECUTOR_PATH}\" LIBIFUPDOWN_SRC = \ + libifupdown/compar.c \ libifupdown/list.c \ libifupdown/dict.c \ libifupdown/interface.c \ diff --git a/libifupdown/compar.c b/libifupdown/compar.c new file mode 100644 index 0000000..8705404 --- /dev/null +++ b/libifupdown/compar.c @@ -0,0 +1,26 @@ +/* + * libifupdown/compar.c + * Purpose: comparators + * + * Copyright (c) 2020 Maximilian Wilhelm + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * This software is provided 'as is' and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising + * from the use of this software. + */ + +#include +#include "libifupdown/compar.h" + +int +compar_str (const void *a, const void *b) +{ + const char *str_a = (const char *)a; + const char *str_b = (const char *)b; + + return strcmp (str_a, str_b); +} diff --git a/libifupdown/compar.h b/libifupdown/compar.h new file mode 100644 index 0000000..8652a26 --- /dev/null +++ b/libifupdown/compar.h @@ -0,0 +1,21 @@ +/* + * libifupdown/compar.h + * Purpose: Comparators + * + * Copyright (c) 2020 Maximilian Wilhelm + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * This software is provided 'as is' and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising + * from the use of this software. + */ + +#ifndef LIBIFUPDOWN_COMPAR_H__GUARD +#define LIBIFUPDOWN_COMPAR_H__GUARD + +int compar_str (const void *a, const void *b); + +#endif From 73f3690432e128f43751ac170ec2fddeeae710bd Mon Sep 17 00:00:00 2001 From: Maximilian Wilhelm Date: Tue, 28 Jul 2020 22:39:20 +0200 Subject: [PATCH 4/6] Deduce which addons to 'use' from parameters names (closes #6) Signed-off-by: Maximilian Wilhelm --- libifupdown/interface-file.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/libifupdown/interface-file.c b/libifupdown/interface-file.c index e8dd906..205c920 100644 --- a/libifupdown/interface-file.c +++ b/libifupdown/interface-file.c @@ -19,6 +19,7 @@ #include "libifupdown/interface-file.h" #include "libifupdown/fgetline.h" #include "libifupdown/tokenize.h" +#include "libifupdown/compar.h" bool lif_interface_file_parse(struct lif_dict *collection, const char *filename) @@ -138,6 +139,23 @@ lif_interface_file_parse(struct lif_dict *collection, const char *filename) else if (cur_iface != NULL) { lif_dict_add(&cur_iface->vars, token, strdup(bufp)); + + /* Check if token looks like - and assume is an addon */ + char *word_end = strchr(token, '-'); + if (word_end) + { + /* Copy word1 to not mangle *token */ + char *addon = strndup(token, word_end - token); + lif_dict_add_once(&cur_iface->vars, "use", addon, compar_str); + + /* pass requires as compatibility env vars to appropriate executors (bridge, bond) */ + if (!strcmp(addon, "dhcp")) + cur_iface->is_dhcp = true; + else if (!strcmp(addon, "bridge")) + cur_iface->is_bridge = true; + else if (!strcmp(addon, "bond")) + cur_iface->is_bond = true; + } } } From 9d958892ed8c3f2c47963deaf2a6ba834f499d65 Mon Sep 17 00:00:00 2001 From: Maximilian Wilhelm Date: Tue, 28 Jul 2020 23:25:01 +0200 Subject: [PATCH 5/6] Free nodes of a lif_dict_find_all() result. Signed-off-by: Maximilian Wilhelm --- libifupdown/dict.c | 13 +++++++++++-- libifupdown/list.c | 19 +++++++++++++++++++ libifupdown/list.h | 3 +++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/libifupdown/dict.c b/libifupdown/dict.c index a0b5f2a..3dea682 100644 --- a/libifupdown/dict.c +++ b/libifupdown/dict.c @@ -14,6 +14,7 @@ * from the use of this software. */ +#include #include #include #include "libifupdown/dict.h" @@ -55,14 +56,22 @@ lif_dict_add_once(struct lif_dict *dict, const char *key, void *data, int (*compar)(const void *, const void *)) { struct lif_list *existing = lif_dict_find_all(dict, key); - if (existing) + if (existing != NULL) { + bool found = false; struct lif_node *iter; LIF_LIST_FOREACH(iter, existing->head) { if (!compar(data, iter->data)) - return NULL; + { + found = true; + break; + } } + + lif_list_free_nodes (&existing); + if (found) + return NULL; } struct lif_dict_entry *entry = calloc(1, sizeof *entry); diff --git a/libifupdown/list.c b/libifupdown/list.c index 6a44f86..6b92b1c 100644 --- a/libifupdown/list.c +++ b/libifupdown/list.c @@ -3,6 +3,7 @@ * Purpose: linked lists * * Copyright (c) 2020 Ariadne Conill + * Copyright (c) 2020 Maximilian Wilhelm * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,8 +15,26 @@ */ #include +#include #include "libifupdown/list.h" +void +lif_list_free_nodes(struct lif_list **list) +{ + if (*list == NULL) + return; + + struct lif_node *iter; + + LIF_LIST_FOREACH (iter, (*list)->head) + { + free (iter->prev); + } + + free (iter); + free (*list); +} + void lif_node_insert(struct lif_node *node, void *data, struct lif_list *list) { diff --git a/libifupdown/list.h b/libifupdown/list.h index 326eca0..a0155d6 100644 --- a/libifupdown/list.h +++ b/libifupdown/list.h @@ -3,6 +3,7 @@ * Purpose: linked lists * * Copyright (c) 2020 Ariadne Conill + * Copyright (c) 2020 Maximilian Wilhelm * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -29,6 +30,8 @@ struct lif_list { size_t length; }; +extern void lif_list_free_nodes(struct lif_list **list); + extern void lif_node_insert(struct lif_node *node, void *data, struct lif_list *list); extern void lif_node_insert_tail(struct lif_node *node, void *data, struct lif_list *list); extern void lif_node_delete(struct lif_node *node, struct lif_list *list); From 80450810244cdf01da5e5d196d86b750d671cc3a Mon Sep 17 00:00:00 2001 From: Maximilian Wilhelm Date: Tue, 28 Jul 2020 23:30:09 +0200 Subject: [PATCH 6/6] list: Set pointer to free()ed list to NULL. Signed-off-by: Maximilian Wilhelm --- libifupdown/list.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libifupdown/list.c b/libifupdown/list.c index 6b92b1c..11cfcf5 100644 --- a/libifupdown/list.c +++ b/libifupdown/list.c @@ -33,6 +33,7 @@ lif_list_free_nodes(struct lif_list **list) free (iter); free (*list); + *list = NULL; } void