From patchwork Fri Jan 12 14:58:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Stefan Herbrechtsmeier X-Patchwork-Id: 859994 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=googlegroups.com (client-ip=2a00:1450:4010:c07::238; helo=mail-lf0-x238.google.com; envelope-from=swupdate+bncbdn7dbh5yqibbl434pjakgqe77forka@googlegroups.com; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.b="jXXwMkt5"; dkim-atps=neutral Received: from mail-lf0-x238.google.com (mail-lf0-x238.google.com [IPv6:2a00:1450:4010:c07::238]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zJ5Xy53Scz9t3G for ; Sat, 13 Jan 2018 02:01:06 +1100 (AEDT) Received: by mail-lf0-x238.google.com with SMTP id c184sf1560695lfc.17 for ; Fri, 12 Jan 2018 07:01:06 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1515769263; cv=pass; d=google.com; s=arc-20160816; b=kTe3Q/nVbeQ7B/1hrI/N1q88JpWhzTUSbVeXKIBL84v+PKXPRcHg5UxkwKRbeV9Ivf C4oGldI8JAiY1enBy711H58ly3Wi5XgdkrOZG/PdSssLIp0dS1LkGSdiYIt7BJNvZX9w 4prIux3wh7kao1VF3ZcG/iNeM0B/K5J6qAp8J3EvVfyAuwoXdkfyJoPLEecaFYnzyb21 bL7ApGg4Qe7Wrrks11t8oi6Xaf3fYz1r1cq+n94IDGX6mLkn3HiO8bYGqT4N+6UTFnZD xB5rL9nFfg6E7ZS3z/CLzYQqqLGj6tZ/BfsBL5Zp6KRNJcNhy/0R4K+clDX3ibI1uC05 ec0g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:arc-authentication-results:arc-message-signature:sender :dkim-signature:arc-authentication-results; bh=RQAKkxiOMKengnnn5/9doTOIyBZyDAg6wBdAakYUfS0=; b=sY3j3+/I2Fm9Xc4Y7UbrhbeAUGJ53aIHiDnnRh0OV8kRGm47VUkD4lzJ0w3Rqxk8VB TND4kcFz0uRbaq/cLNNyrxPEU8aOJD8Nmzeh3R26xtK8jBfoXwxYzZv7RMsmTf4hJrk1 kWdB7SkqXOY3AQkeAOQN4a5ucw8JyqDzMcCUwySOCYfZDqT24Z/GpyNH52mizbHpKHV/ MnHNJ43pfeWlaiipDCMwL3fWI8OGFK6UjJfaScDwPwY6moaZYgfH2OV7D92HFN2J68n5 gQeWebgxF9MdSDvBTtX4p/CV5PVz/D0b6k0wz0mWzj2U9ftNzIWSsqoEq2rGHUXBS6a0 pIlg== ARC-Authentication-Results: i=2; gmr-mx.google.com; spf=neutral (google.com: 85.13.157.12 is neither permitted nor denied by best guess record for domain of stefan@herbrechtsmeier.net) smtp.mailfrom=stefan@herbrechtsmeier.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-subscribe:list-unsubscribe; bh=RQAKkxiOMKengnnn5/9doTOIyBZyDAg6wBdAakYUfS0=; b=jXXwMkt5gi3Y1L55ZhSsSQbdU5DWq9GBPsND61ZBHhwU78qedON/HJs/Smw2/sVj9P uIo6oTsAp86MsxQ8qgHAKHj6U7PR5YlWmLBnmXSL5ASxuS8gZe1Bu52Q1j/s53ZWmb/Y eKWOnrsPOmkgS8kAsjFz5fkV/nIdB4jqQgVTmAHHh4qzDq6xMmX4Ml+YWsxoidARafz4 9TdddkzKnwsTFZMrFObjCBQOf0oJD1AZQCZ+PGdQdZLDHwDU7E4TpixgHdePAeni+0Fr v1GKOJg1+26tRgIkUylX1s2hdddw4UB7sSWgxke/nhQEyVIKb9M39yaXDvAyJlz3kbkF 67GA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=sender:x-gm-message-state:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding :x-original-sender:x-original-authentication-results:precedence :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help :list-archive:list-subscribe:list-unsubscribe; bh=RQAKkxiOMKengnnn5/9doTOIyBZyDAg6wBdAakYUfS0=; b=mbVU7R4MYjF1lFeR2JNtZ4kLZqLn1pEA5PoR1whsJtZh+EqdIK3Iugk+DXJ/wlJedl F3oaXR6HfPfCLuJQgBIH+k+CdlE+Hm0qK7aQ/KkjzIf6Iw7DOK+LX6r+bAewqf3ZXdCT 6TsGkAQjnFIb2EwMtCGgICeZjI8qtthlAnu3SlSkH1j3f/qr9ZFvDVhnnPwADyqOQCXA uptboRN4RI4/w2BE55LT3wBFHoruIOIYRPzeh3EW7eUbJU71dmwOKMiNCsFMpLxL/BEZ BaTy3F4iMTgEr5T2WScNqs8zjeCmqubeIyZ1q6RtYjiITnQujdN8Oq5ERfeZ2hDvSAAb 6Q4Q== Sender: swupdate@googlegroups.com X-Gm-Message-State: AKGB3mIOCG1ZtBnJ60Mjv3CQYalmM61DB97qU7vf4qaL6CJtYnRTSSQx gemP84ja7RTh1GNwijvu7Vk= X-Google-Smtp-Source: ACJfBotCsLuPwlyGFudpJCufKJxAzZgz15BUDRl83lmFHv8/hiXJnrBFQ8G9YfzLAbsJaINkSjhTLw== X-Received: by 10.46.44.8 with SMTP id s8mr67551ljs.6.1515769263764; Fri, 12 Jan 2018 07:01:03 -0800 (PST) X-BeenThere: swupdate@googlegroups.com Received: by 10.25.74.214 with SMTP id x205ls93203lfa.4.gmail; Fri, 12 Jan 2018 07:01:02 -0800 (PST) X-Received: by 10.46.91.199 with SMTP id m68mr1910870lje.42.1515769262690; Fri, 12 Jan 2018 07:01:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515769262; cv=none; d=google.com; s=arc-20160816; b=ZyqhvypJymNwgwPb1Qq/dgsOxSJPdBVpmBrsea0P94gs6/LD2dZ9pquGEaGQ71hTtK 50Gh+rCfXC32gr2Q0JjWnkoNzRAMaunYrVhWAYpefLqd7aB9JYAKT3OOCNmgzk6FpCnp A51rnn++3J1mssf6nOZHKJJ88xfD2msrlvgNl93C6kzKgsbs/nplgjv16uQmMCwIdIeH oO/uPpZlhxwtmTpYG6UgLwISLCjfPQvSRcB8TT8Cz/BYReDO76V7A40dQmqLKP6CIFkN 0UazI13F3IkEDRBaw+bGuvaDKFnhUu1chDnr8nMbc8V/Id10/67AmMlV1SgRycSqhrdJ wLfg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=Pj5R/Hn2ktr0vsS8b6FwtSp1SbMXy7xdBHW6YTXvcp4=; b=LwvLcLxg70S9AHOvtx9eUZFZsD/vgYcuk0fvsYLb9hqWkJfUtloY8+5wOMLwQVuG5s i6T7bu1FvzfWS3KiLD5rGNlq7uM1ihsLSWJb/KCDjet7g6BJPSZCSJMfn+vD9A74pXxQ MTAazBbpP4dsaPNuVgVi/SDbB6jSBia4q3vqTzPK3FPAkd8Z0HE5i1tJ9pbkk/O/omrh QJUVyUD9PHUcJWNcB4ZYnkVB3nuW+XnCX9bt7ra6B46Bg0xullKAZudFECXWx5vLrRTT jJNFIGGcOsz3ZnDL9OG8LXfZ2gtKmkO3w0/tE1YfIHa20nhXMWPG+5zs6u/+l1QpUeG2 Zt0g== ARC-Authentication-Results: i=1; gmr-mx.google.com; spf=neutral (google.com: 85.13.157.12 is neither permitted nor denied by best guess record for domain of stefan@herbrechtsmeier.net) smtp.mailfrom=stefan@herbrechtsmeier.net Received: from dd41138.kasserver.com (dd41138.kasserver.com. [85.13.157.12]) by gmr-mx.google.com with ESMTPS id v124si526627lfa.2.2018.01.12.07.01.02 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 12 Jan 2018 07:01:02 -0800 (PST) Received-SPF: neutral (google.com: 85.13.157.12 is neither permitted nor denied by best guess record for domain of stefan@herbrechtsmeier.net) client-ip=85.13.157.12; Received: from WS08941.weidmueller.com (unknown [217.244.7.16]) by dd41138.kasserver.com (Postfix) with ESMTPSA id A80EF11A033E; Fri, 12 Jan 2018 16:01:01 +0100 (CET) From: stefan@herbrechtsmeier.net To: swupdate@googlegroups.com Cc: Stefan Herbrechtsmeier Subject: [swupdate] [PATCH v2 2/5] corelib: Rework dictionary to support multiple values per key Date: Fri, 12 Jan 2018 15:58:45 +0100 Message-Id: <1515769128-29657-2-git-send-email-stefan@herbrechtsmeier.net> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515769128-29657-1-git-send-email-stefan@herbrechtsmeier.net> References: <1515769128-29657-1-git-send-email-stefan@herbrechtsmeier.net> MIME-Version: 1.0 X-Original-Sender: stefan@herbrechtsmeier.net X-Original-Authentication-Results: gmr-mx.google.com; spf=neutral (google.com: 85.13.157.12 is neither permitted nor denied by best guess record for domain of stefan@herbrechtsmeier.net) smtp.mailfrom=stefan@herbrechtsmeier.net Precedence: list Mailing-list: list swupdate@googlegroups.com; contact swupdate+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: swupdate@googlegroups.com X-Google-Group-Id: 605343134186 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , From: Stefan Herbrechtsmeier Signed-off-by: Stefan Herbrechtsmeier --- Changes in v2: None bootloader/grub.c | 20 +++---- corelib/installer.c | 8 +-- corelib/swupdate_dict.c | 124 ++++++++++++++++++++++++++++++++---------- handlers/swuforward_handler.c | 6 +- include/swupdate_dict.h | 16 +++++- parser/parser.c | 2 +- suricatta/server_hawkbit.c | 14 +++-- 7 files changed, 138 insertions(+), 52 deletions(-) diff --git a/bootloader/grub.c b/bootloader/grub.c index 93682f0..966498f 100644 --- a/bootloader/grub.c +++ b/bootloader/grub.c @@ -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 diff --git a/corelib/installer.c b/corelib/installer.c index e25c30c..7da49b2 100644 --- a/corelib/installer.c +++ b/corelib/installer.c @@ -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; diff --git a/corelib/swupdate_dict.c b/corelib/swupdate_dict.c index 352c13a..46137a0 100644 --- a/corelib/swupdate_dict.c +++ b/corelib/swupdate_dict.c @@ -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 + * * 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); } } diff --git a/handlers/swuforward_handler.c b/handlers/swuforward_handler.c index 54aef4b..72d6cff 100644 --- a/handlers/swuforward_handler.c +++ b/handlers/swuforward_handler.c @@ -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 */ diff --git a/include/swupdate_dict.h b/include/swupdate_dict.h index f8b696f..cd6b80c 100644 --- a/include/swupdate_dict.h +++ b/include/swupdate_dict.h @@ -23,19 +23,29 @@ #include +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 diff --git a/parser/parser.c b/parser/parser.c index 3a1d6a5..3ecc2da 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -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..."); } diff --git a/suricatta/server_hawkbit.c b/suricatta/server_hawkbit.c index 51ed32f..b899715 100644 --- a/suricatta/server_hawkbit.c +++ b/suricatta/server_hawkbit.c @@ -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);