From patchwork Thu Aug 2 17:29:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geoff Levand X-Patchwork-Id: 952920 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41hHLc3gbyz9s3q for ; Fri, 3 Aug 2018 03:32:40 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=infradead.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="RfXnM+N0"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41hHLc29C5zF2DQ for ; Fri, 3 Aug 2018 03:32:40 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=infradead.org Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="RfXnM+N0"; dkim-atps=neutral X-Original-To: Petitboot@lists.ozlabs.org Delivered-To: Petitboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (mailfrom) smtp.mailfrom=infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=geoff@infradead.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=infradead.org Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="RfXnM+N0"; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41hHH9663CzF21T for ; Fri, 3 Aug 2018 03:29:41 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=Date:Cc:To:Subject:From:References: In-Reply-To:Message-Id:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=K4DcYaRzMfdkfyWBqtKjnUFK7/4ZsMlM9t+WjYSU0Oo=; b=RfXnM+N0lhzyFpVMVutwpLfww YQd0/EjDkHgE1YiekBmAh/n1BirYEM5iYdwFKizdBQViE6SxiXfChCGLspEl7dE45o7aYSBmn98tc ljlPlsV8xEZ9QdjFtZbghyRgVzstMGS6t855g+l1va9LQVEWpOoWkDCXUoElIcrbT5hr+OhRxndKQ uBm+rzh3L46UYdhzODDdEgti85hB+BxjYpWbXCOPisr+CohsO93irgi8Ngp+HyFjksB8NV9Z0DEYW 7pjjjzW0LQYc4CI8jRpt+uDSXvmRC+E2WE09A+1uaXUpqtYoNNUdEbqj/NsVzTkvc7iMsNdRcKlMN ji4wCbsSw==; Received: from geoff by merlin.infradead.org with local (Exim 4.90_1 #2 (Red Hat Linux)) id 1flHPu-0007Yy-1C; Thu, 02 Aug 2018 17:29:38 +0000 Message-Id: <22b172c971f9e5989aca8346f539cf14e8a212d5.1533230644.git.geoff@infradead.org> In-Reply-To: References: From: Geoff Levand Patch-Date: Thu, 2 Aug 2018 10:19:53 -0700 Subject: [PATCH v2 20/30] lib/param_list: Add new parameter list routines To: Samuel Mendoza-Jonas Date: Thu, 02 Aug 2018 17:29:38 +0000 X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ge Song , Petitboot@lists.ozlabs.org MIME-Version: 1.0 Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" Based on the powerpc param routines adds new generic routines to manage a name + value parameter list. Signed-off-by: Geoff Levand --- lib/Makefile.am | 4 +- lib/param_list/param_list.c | 118 ++++++++++++++++++++++++++++++++++++++++++++ lib/param_list/param_list.h | 48 ++++++++++++++++++ 3 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 lib/param_list/param_list.c create mode 100644 lib/param_list/param_list.h diff --git a/lib/Makefile.am b/lib/Makefile.am index 59d37ab..016a14d 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -67,7 +67,9 @@ lib_libpbcore_la_SOURCES = \ lib/flash/flash.h \ lib/security/security.h \ lib/efi/efivar.h \ - lib/efi/efivar.c + lib/efi/efivar.c \ + lib/param_list/param_list.c \ + lib/param_list/param_list.h if ENABLE_MTD lib_libpbcore_la_SOURCES += \ diff --git a/lib/param_list/param_list.c b/lib/param_list/param_list.c new file mode 100644 index 0000000..b3a45f8 --- /dev/null +++ b/lib/param_list/param_list.c @@ -0,0 +1,118 @@ + +#define _GNU_SOURCE + +#include +#include + +#include +#include +#include + +const char **common_known_params(void) +{ + static const char *common[] = { + "auto-boot?", + "petitboot,network", + "petitboot,timeout", + "petitboot,bootdevs", + "petitboot,language", + "petitboot,debug?", + "petitboot,write?", + "petitboot,snapshots?", + "petitboot,console", + "petitboot,http_proxy", + "petitboot,https_proxy", + NULL, + }; + + return common; +} + +void param_list_init(struct param_list *pl, const char *known_params[]) +{ + assert(known_params); + list_init(&pl->params); + pl->known_params = known_params; +} + +bool param_list_is_known_n(const struct param_list *pl, const char *name, + unsigned int name_len) +{ + const char **known; + + assert(pl->known_params); + + param_list_for_each_known_param(pl, known) { + if (name_len == strlen(*known) && !strncmp(name, *known, name_len)) { + return true; + } + } + + return false; +} + +bool param_list_is_known(const struct param_list *pl, const char *name) +{ + const char **known; + + assert(pl->known_params); + + param_list_for_each_known_param(pl, known) { + if (!strcmp(name, *known)) { + return true; + } + } + + return false; +} + +struct param *param_list_get_param(struct param_list *pl, const char *name) +{ + struct param *param; + + param_list_for_each(pl, param) { + if (!strcmp(param->name, name)) + return param; + } + return NULL; +} + +void param_list_set(struct param_list *pl, const char *name, const char *value, + bool modified_on_create) +{ + struct param *param; + + param_list_for_each(pl, param) { + if (strcmp(param->name, name)) + continue; + + if (!strcmp(param->value, value)) + return; + + /* Update existing list entry. */ + talloc_free(param->value); + param->value = talloc_strdup(param, value); + param->modified = true; + pb_debug_fn("Updated: %s:%s\n", name, value); + return; + } + + /* Add new entry to list. */ + param = talloc(pl, struct param); + param->modified = modified_on_create; + param->name = talloc_strdup(pl, name); + param->value = talloc_strdup(pl, value); + list_add(&pl->params, ¶m->list); + pb_debug_fn("Created: %s:%s\n", name, value); +} + +void param_list_set_non_empty(struct param_list *pl, const char *name, const char *value, + bool modified_on_create) +{ + if (!param_list_get_value(pl, name) && !strlen(value)) { + return; + } + + param_list_set(pl, name, value, modified_on_create); +} + diff --git a/lib/param_list/param_list.h b/lib/param_list/param_list.h new file mode 100644 index 0000000..89ef400 --- /dev/null +++ b/lib/param_list/param_list.h @@ -0,0 +1,48 @@ +#ifndef PARAM_LIST_H +#define PARAM_LIST_H + +#include + +#include + +struct param { + char *name; + char *value; + bool modified; + struct list_item list; +}; + +struct param_list { + struct list params; + const char **known_params; +}; + +#define param_list_for_each(_pl_ptr, _pos) \ + list_for_each_entry(&(_pl_ptr)->params, _pos, list) + +#define param_list_for_each_known_param(_pl_ptr, _pos) \ + for (_pos = (_pl_ptr)->known_params; *_pos; _pos++) + +const char **common_known_params(void); + +void param_list_init(struct param_list *pl, const char *known_params[]); +bool param_list_is_known(const struct param_list *pl, const char *name); +bool param_list_is_known_n(const struct param_list *pl, const char *name, + unsigned int name_len); +struct param *param_list_get_param(struct param_list *pl, const char *name); +static inline const char *param_list_get_value(const struct param_list *pl, + const char *name) +{ + const struct param *param = + param_list_get_param((struct param_list *)pl, name); + return param ? param->value : NULL; +} +void param_list_set(struct param_list *pl, const char *name, const char *value, + bool modified_on_create); + +/* param_list_set_non_empty - Won't create a new parameter that would be empty. */ +void param_list_set_non_empty(struct param_list *pl, const char *name, + const char *value, bool modified_on_create); + +#endif /* PARAM_LIST_H */ +