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 diff --git a/libifupdown/dict.c b/libifupdown/dict.c index 4ac7085..3dea682 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 @@ -13,6 +14,7 @@ * from the use of this software. */ +#include #include #include #include "libifupdown/dict.h" @@ -49,6 +51,39 @@ 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 != NULL) + { + bool found = false; + struct lif_node *iter; + LIF_LIST_FOREACH(iter, existing->head) + { + if (!compar(data, iter->data)) + { + found = true; + break; + } + } + + lif_list_free_nodes (&existing); + if (found) + 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) { @@ -65,6 +100,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..2332c05 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 @@ -37,7 +38,9 @@ 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); extern void lif_dict_delete_entry(struct lif_dict *dict, struct lif_dict_entry *entry); 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; + } } } diff --git a/libifupdown/list.c b/libifupdown/list.c index 6a44f86..11cfcf5 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,27 @@ */ #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); + *list = NULL; +} + 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);