@@ -165,8 +165,10 @@ static inline void grubenv_update_size(struct grubenv_t *grubenv)
/* lengths of strings + '=' and '\n' characters */
LIST_FOREACH(grubvar, &grubenv->vars, next) {
- size = size + strlen(grubvar->key) +
- strlen(grubvar->value) + 2;
+ char *key = dict_entry_get_key(grubvar);
+ char *value = dict_entry_get_value(grubvar);
+
+ size = size + strlen(key) + strlen(value) + 2;
}
size += strlen(GRUBENV_HEADER);
grubenv->size = size;
@@ -206,10 +208,12 @@ static int grubenv_write(struct grubenv_t *grubenv)
strncpy(buf, GRUBENV_HEADER, strlen(GRUBENV_HEADER) + 1);
LIST_FOREACH(grubvar, &grubenv->vars, next) {
- llen = strlen(grubvar->key) + strlen(grubvar->value) + 2;
+ char *key = dict_entry_get_key(grubvar);
+ char *value = dict_entry_get_value(grubvar);
+
+ llen = strlen(key) + strlen(value) + 2;
/* +1 for null termination */
- snprintf(line, llen + 1, "%s=%s\n", grubvar->key,
- grubvar->value);
+ snprintf(line, llen + 1, "%s=%s\n", key, value);
strncat(buf, line, llen);
}
@@ -249,11 +253,7 @@ cleanup:
* allocation */
static inline void grubenv_close(struct grubenv_t *grubenv)
{
- struct dict_entry *grubvar;
-
- LIST_FOREACH(grubvar, &grubenv->vars, next) {
- dict_remove(&grubenv->vars, grubvar->key);
- }
+ dict_drop_db(&grubenv->vars);
}
/* I feel that '#' and '=' characters should be forbidden. Although it's not
@@ -218,11 +218,11 @@ static int prepare_boot_script(struct swupdate_cfg *cfg, const char *script)
return -1;
LIST_FOREACH(bootvar, &cfg->bootloader, next) {
- if (!bootvar->key || !bootvar->value)
+ char *key = dict_entry_get_key(bootvar);
+ char *value = dict_entry_get_value(bootvar);
+ if (!key || !value)
continue;
- snprintf(buf, sizeof(buf), "%s %s\n",
- bootvar->key,
- bootvar->value);
+ snprintf(buf, sizeof(buf), "%s %s\n", key, value);
if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf)) {
TRACE("Error saving temporary file");
ret = -1;
@@ -2,6 +2,9 @@
* (C) Copyright 2016
* Stefano Babic, DENX Software Engineering, sbabic@denx.de.
*
+ * Copyright (C) 2018 Weidmüller Interface GmbH & Co. KG
+ * Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
+ *
* 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 2 of
@@ -31,6 +34,51 @@
#include "util.h"
#include "swupdate_dict.h"
+static int insert_list_elem(struct dict_list *list, char *value)
+{
+ struct dict_list_elem *elem = (struct dict_list_elem *)malloc(sizeof(*elem));
+
+ if (!elem)
+ return -ENOMEM;
+
+ memset(elem, 0, sizeof(*elem));
+ elem->value = strdup(value);
+
+ LIST_INSERT_HEAD(list, elem, next);
+
+ return 0;
+}
+
+static void remove_list_elem(struct dict_list_elem *elem)
+{
+ LIST_REMOVE(elem, next);
+ free(elem->value);
+ free(elem);
+}
+
+static void remove_list(struct dict_list *list)
+{
+ struct dict_list_elem *elem;
+
+ LIST_FOREACH(elem, list, next) {
+ remove_list_elem(elem);
+ }
+}
+
+static struct dict_entry *insert_entry(struct dict *dictionary, char *key)
+{
+ struct dict_entry *entry = (struct dict_entry *)malloc(sizeof(*entry));
+ if (!entry)
+ return NULL;
+
+ memset(entry, 0, sizeof(*entry));
+ entry->key = strdup(key);
+
+ LIST_INSERT_HEAD(dictionary, entry, next);
+
+ return entry;
+}
+
static struct dict_entry *get_entry(struct dict *dictionary, char *key)
{
struct dict_entry *entry;
@@ -43,20 +91,38 @@ static struct dict_entry *get_entry(struct dict *dictionary, char *key)
return NULL;
}
-int dict_insert_entry(struct dict *dictionary, char *key, char *value)
+static void remove_entry(struct dict_entry *entry)
{
- struct dict_entry *entry = (struct dict_entry *)malloc(sizeof(*entry));
+ LIST_REMOVE(entry, next);
+ free(entry->key);
+ remove_list(&entry->list);
+ free(entry);
+}
+char *dict_entry_get_key(struct dict_entry *entry)
+{
if (!entry)
- return -ENOMEM;
+ return NULL;
- memset(entry, 0, sizeof(*entry));
- entry->key = strdup(key);
- entry->value = strdup(value);
+ return entry->key;
+}
- LIST_INSERT_HEAD(dictionary, entry, next);
+char *dict_entry_get_value(struct dict_entry *entry)
+{
+ if (!entry || !LIST_FIRST(&entry->list))
+ return NULL;
- return 0;
+ return LIST_FIRST(&entry->list)->value;
+}
+
+struct dict_list *dict_get_list(struct dict *dictionary, char *key)
+{
+ struct dict_entry *entry = get_entry(dictionary, key);
+
+ if (!entry)
+ return NULL;
+
+ return &entry->list;
}
char *dict_get_value(struct dict *dictionary, char *key)
@@ -66,49 +132,51 @@ char *dict_get_value(struct dict *dictionary, char *key)
if (!entry)
return NULL;
- return entry->value;
+ return dict_entry_get_value(entry);
}
-int dict_set_value(struct dict *dictionary, char *key, char *value)
+int dict_insert_value(struct dict *dictionary, char *key, char *value)
{
struct dict_entry *entry = get_entry(dictionary, key);
- /*
- * Set to new value if key is already in
- * dictionary
- */
- if (entry) {
- LIST_REMOVE(entry, next);
- free(entry);
+ if (!entry) {
+ entry = insert_entry(dictionary, key);
+ if (!entry)
+ return -ENOMEM;
}
- return dict_insert_entry(dictionary, key, value);
+ return insert_list_elem(&entry->list, value);
}
-void dict_remove_entry(struct dict_entry *entry)
+int dict_set_value(struct dict *dictionary, char *key, char *value)
{
- LIST_REMOVE(entry, next);
- free(entry->key);
- free(entry->value);
- free(entry);
+ struct dict_entry *entry = get_entry(dictionary, key);
+
+ if (entry)
+ remove_entry(entry);
+
+ entry = insert_entry(dictionary, key);
+ if (!entry)
+ return -ENOMEM;
+
+ return insert_list_elem(&entry->list, value);
}
void dict_remove(struct dict *dictionary, char *key)
{
-
struct dict_entry *entry = get_entry(dictionary, key);
if (!entry)
return;
- dict_remove_entry(entry);
+ remove_entry(entry);
}
void dict_drop_db(struct dict *dictionary)
{
- struct dict_entry *var;
+ struct dict_entry *entry;
- LIST_FOREACH(var, dictionary, next) {
- dict_remove_entry(var);
+ LIST_FOREACH(entry, dictionary, next) {
+ remove_entry(entry);
}
}
@@ -338,8 +338,10 @@ static int install_remote_swu(struct img_type *img,
*/
LIST_FOREACH(url, &img->properties, next) {
char curlheader[SWUPDATE_GENERAL_STRING_SIZE + strlen(CUSTOM_HEADER)];
+ char *key = dict_entry_get_key(url);
+ char *value = dict_entry_get_value(url);
- if (!url->key || !url->value || strcmp(url->key, "url"))
+ if (!key || !value || strcmp(key, "url"))
continue;
conn = (struct curlconn *)calloc(1, sizeof(struct curlconn));
@@ -352,7 +354,7 @@ static int install_remote_swu(struct img_type *img,
headerlist = NULL;
conn->curl_handle = curl_easy_init();
- conn->url = url->value;
+ conn->url = value;
if (!conn->curl_handle) {
/* something very bad, it should never happen */
@@ -23,19 +23,29 @@
#include <bsdqueue.h>
+struct dict_list_elem {
+ char *value;
+ LIST_ENTRY(dict_list_elem) next;
+};
+
+LIST_HEAD(dict_list, dict_list_elem);
+
struct dict_entry {
char *key;
- char *value;
+ struct dict_list list;
LIST_ENTRY(dict_entry) next;
};
LIST_HEAD(dict, dict_entry);
+char *dict_entry_get_key(struct dict_entry *entry);
+char *dict_entry_get_value(struct dict_entry *entry);
+
+struct dict_list *dict_get_list(struct dict *dictionary, char *key);
char *dict_get_value(struct dict *dictionary, char *key);
int dict_set_value(struct dict *dictionary, char *key, char *value);
-int dict_insert_entry(struct dict *dictionary, char *key, char *value);
+int dict_insert_value(struct dict *dictionary, char *key, char *value);
void dict_remove(struct dict *dictionary, char *key);
-void dict_remove_entry(struct dict_entry *entry);
void dict_drop_db(struct dict *dictionary);
#endif
@@ -174,7 +174,7 @@ static void add_properties(parsertype p, void *node, struct img_type *image)
key,
value
);
- if (dict_insert_entry(&image->properties, key, value))
+ if (dict_insert_value(&image->properties, key, value))
ERROR("Property not stored, skipping...");
}
@@ -1348,7 +1348,10 @@ int get_target_data_length(void)
struct dict_entry *entry;
LIST_FOREACH(entry, &server_hawkbit.configdata, next) {
- len += strlen(entry->key) + strlen(entry->value) + strlen (" : ") + 6;
+ char *key = dict_entry_get_key(entry);
+ char *value = dict_entry_get_value(entry);
+
+ len += strlen(key) + strlen(value) + strlen (" : ") + 6;
}
return len;
@@ -1379,17 +1382,20 @@ server_op_res_t server_send_target_data(void)
char *keyvalue = NULL;
LIST_FOREACH(entry, &server_hawkbit.configdata, next) {
+ char *key = dict_entry_get_key(entry);
+ char *value = dict_entry_get_value(entry);
+
if (ENOMEM_ASPRINTF ==
asprintf(&keyvalue, config_data,
((first) ? ' ' : ','),
- entry->key,
- entry->value)) {
+ key,
+ value)) {
ERROR("hawkBit server reply cannot be sent because of OOM.\n");
result = SERVER_EINIT;
goto cleanup;
}
first = false;
- TRACE("KEYVALUE=%s %s %s", keyvalue, entry->key, entry->value);
+ TRACE("KEYVALUE=%s %s %s", keyvalue, key, value);
strcat(configData, keyvalue);
free(keyvalue);