From patchwork Wed Jul 17 08:25:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1133186 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="HByhdpZO"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 45pVr16fkdz9sLt for ; Wed, 17 Jul 2019 18:32:17 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 844DFC21DF3; Wed, 17 Jul 2019 08:31:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 5DCB1C21E50; Wed, 17 Jul 2019 08:26:20 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 43387C21E6A; Wed, 17 Jul 2019 08:25:49 +0000 (UTC) Received: from mail-pf1-f194.google.com (mail-pf1-f194.google.com [209.85.210.194]) by lists.denx.de (Postfix) with ESMTPS id CFDE7C21C3F for ; Wed, 17 Jul 2019 08:25:43 +0000 (UTC) Received: by mail-pf1-f194.google.com with SMTP id u14so10482267pfn.2 for ; Wed, 17 Jul 2019 01:25:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=gR+lBD2btWBef444mTaj/zRvQGPgJ5rgauqUy+VmigQ=; b=HByhdpZOCSn7AjmH8Yq25Pxh+zmuJQYLLY6jG5QUZb9VJt48txhho9yWt0uOZ7ICik ijvAG+XhTWx6FFacOxYSAZkwrPL/8vatJIECLG1d650wu8NEs8qnaIvcXSF+A9/f/P6K kJm0KHcBz+aWpYCb0zyjM9OH2OBm44cBtxhfmU9QZ18Nd9xh3S0oX8o03nqVerk8KDz5 4evT4hb9Rc3fLvR0EemdKOEt8iOnj8ViQ1c3JIItiQbPjeQ3Zi6LomOtnYia5aVGZn1y hwf4+D6v/ecWo42ZyQdTWqh0t8exl8pkpRll7IAkQWodDUu1b6VrIh3htyITeL4jJ7ub ZegQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gR+lBD2btWBef444mTaj/zRvQGPgJ5rgauqUy+VmigQ=; b=t9sFOmFvGORyCJ51CRWBeqzEB8umLiQPIQTV1RyWIPrQ6ciK82jYdWRKY8D1l14ORm IQIuvndVNBwt09sRkduCv0mFGNMqo4+LyNwgI8aElvm0E6PnxXMKhWeOxXszLj/ydUQv rbhQIHU7fMOg76ygLnvLkzy0ynkH8updrnfwTNoyNKNAqmwTthAekXICc4ut2D72rQt2 GGzK7nNSBVAmFJCJlmGUoOm6FUNM/WvzansQ0XVf5auWR4OUYm95xqRNh2/2X00szTE3 iw0seg3NogWd7fyckJyYLNN4tYR2wc0lIak7pn9y3dbQw/4+/OdvKCw1L0SrB7aIQ2ED MtiQ== X-Gm-Message-State: APjAAAV70qV/27v15/ddveqYzaOBI9lFk6eJfPE+OfmqYhNSXEFfi43n dPHNPPgTNV0kkWtq5X0iTjH2xQ== X-Google-Smtp-Source: APXvYqy3GaqC1P+gUUO7vbv9QyrrDMHxhVMFUjbmTe1jJlKYb73WD9mx5dW7E12QbQtrbLGycXm2Rw== X-Received: by 2002:a63:fb43:: with SMTP id w3mr6556174pgj.403.1563351942438; Wed, 17 Jul 2019 01:25:42 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id x22sm27938627pff.5.2019.07.17.01.25.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 17 Jul 2019 01:25:42 -0700 (PDT) From: AKASHI Takahiro To: trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de, wd@denx.de Date: Wed, 17 Jul 2019 17:25:17 +0900 Message-Id: <20190717082525.891-9-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190717082525.891-1-takahiro.akashi@linaro.org> References: <20190717082525.891-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 Cc: u-boot@lists.denx.de Subject: [U-Boot] [RFC, PATCH v4 08/16] hashtable: import/export entries with flags X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" 'flags' value of all the entries in hashtable should be preserved across save/load of U-Boot environment context. To hold such information in an exported file, its text format is now expanded as follows: name:attr=value ... \0 where "attr" must be a fixed-length(ENV_FLAGS_ATTR_MAX_LEN) string which complies with a existing format of ".flags" variable and used by env_attr_lookup(). Signed-off-by: AKASHI Takahiro --- include/search.h | 1 + lib/hashtable.c | 61 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/include/search.h b/include/search.h index 9cece695d726..ab0d7ccb5f8c 100644 --- a/include/search.h +++ b/include/search.h @@ -133,6 +133,7 @@ extern int hwalk_r(struct hsearch_data *__htab, int (*callback)(ENTRY *)); #define H_MATCH_REGEX (1 << 8) /* search for regular expression matches */ #define H_MATCH_METHOD (H_MATCH_IDENT | H_MATCH_SUBSTR | H_MATCH_REGEX) #define H_PROGRAMMATIC (1 << 9) /* indicate that an import is from env_set() */ +#define H_MATCH_FLAGS (1 << 10) /* search/grep key = variable flags */ #define H_ORIGIN_FLAGS (H_INTERACTIVE | H_PROGRAMMATIC) #endif /* _SEARCH_H_ */ diff --git a/lib/hashtable.c b/lib/hashtable.c index d6975d9cafc6..3fe1d38c827e 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -248,6 +248,15 @@ static inline int _compare_and_overwrite_entry(ENTRY item, ACTION action, /* Overwrite existing value? */ if ((action == ENTER) && (item.data != NULL)) { + /* attributes cannot be changed */ + if (item.flags != htab->table[idx].entry.flags) { + debug("attributes cannot be changed %s\n", + item.key); + __set_errno(EINVAL); + *retval = NULL; + return 0; + } + /* check for permission */ if (htab->change_ok != NULL && htab->change_ok( &htab->table[idx].entry, item.data, @@ -389,6 +398,8 @@ int hsearch_ext(ENTRY item, ACTION action, ENTRY ** retval, htab->table[idx].used = hval; htab->table[idx].entry.context = item.context; htab->table[idx].entry.key = strdup(item.key); + /* TODO: can be overwritten by env_flags_init() */ + htab->table[idx].entry.flags = item.flags; htab->table[idx].entry.data = strdup(item.data); if (!htab->table[idx].entry.key || !htab->table[idx].entry.data) { @@ -402,7 +413,9 @@ int hsearch_ext(ENTRY item, ACTION action, ENTRY ** retval, /* This is a new entry, so look up a possible callback */ env_callback_init(&htab->table[idx].entry); /* Also look for flags */ - env_flags_init(&htab->table[idx].entry); + /* TODO: or we may want to add another argument? */ + if (!item.flags) + env_flags_init(&htab->table[idx].entry); /* check for permission */ if (htab->change_ok != NULL && htab->change_ok( @@ -596,6 +609,21 @@ static int match_string(int flag, const char *str, const char *pat, void *priv) return 0; } +/* TODO: we always need some kind of regex matching */ +static int match_attr(int flag, const char *attr, const char *pat, void *priv) +{ + int found, i; + + for (found = 1, i = 0; i < ENV_FLAGS_ATTR_MAX_LEN; i++) { + if (pat[i] != '.' && attr[i] != pat[i]) { + found = 0; + break; + } + } + + return found; +} + static int match_entry(ENTRY *ep, int flag, int argc, char * const argv[]) { @@ -617,6 +645,14 @@ static int match_entry(ENTRY *ep, int flag, if (match_string(flag, ep->key, argv[arg], priv)) return 1; } + if (flag & H_MATCH_FLAGS) { + char attr[ENV_FLAGS_ATTR_MAX_LEN + 1]; + + env_flags_encode_attr_from_binflags(attr, ep->flags); + attr[ENV_FLAGS_ATTR_MAX_LEN] = '\0'; + if (match_attr(flag, attr, argv[arg], priv)) + return 1; + } if (flag & H_MATCH_DATA) { if (match_string(flag, ep->data, argv[arg], priv)) return 1; @@ -680,6 +716,7 @@ ssize_t hexport_ext(struct hsearch_data *htab, unsigned int ctx, ++s; } } + totlen += ENV_FLAGS_ATTR_MAX_LEN + 1; /* for :xxx */ totlen += 2; /* for '=' and 'sep' char */ } } @@ -731,6 +768,9 @@ ssize_t hexport_ext(struct hsearch_data *htab, unsigned int ctx, s = list[i]->key; while (*s) *p++ = *s++; + *p++ = ':'; + env_flags_encode_attr_from_binflags(p, list[i]->flags); + p += ENV_FLAGS_ATTR_MAX_LEN; *p++ = '='; s = list[i]->data; @@ -829,9 +869,9 @@ int himport_ext(struct hsearch_data *htab, unsigned int ctx, const char *env, size_t size, const char sep, int flag, int crlf_is_lf, int nvars, char * const vars[]) { - char *data, *sp, *dp, *name, *value; + char *data, *sp, *dp, *name, *value, *attr; char *localvars[nvars]; - int i; + int flags, i; /* Test for correct arguments. */ if (htab == NULL) { @@ -927,8 +967,10 @@ int himport_ext(struct hsearch_data *htab, unsigned int ctx, } /* parse name */ - for (name = dp; *dp != '=' && *dp && *dp != sep; ++dp) - ; + for (name = dp, attr = NULL; *dp != '=' && *dp && *dp != sep; + ++dp) + if (*dp == ':') + attr = dp; /* deal with "name" and "name=" entries (delete var) */ if (*dp == '\0' || *(dp + 1) == '\0' || @@ -936,6 +978,8 @@ int himport_ext(struct hsearch_data *htab, unsigned int ctx, if (*dp == '=') *dp++ = '\0'; *dp++ = '\0'; /* terminate name */ + if (attr) + *attr = '\0'; debug("DELETE CANDIDATE: \"%s\"\n", name); if (!drop_var_from_set(name, nvars, localvars)) @@ -947,6 +991,12 @@ int himport_ext(struct hsearch_data *htab, unsigned int ctx, continue; } *dp++ = '\0'; /* terminate name */ + if (attr) { + *attr = '\0'; + flags = env_parse_flags_to_bin(++attr); + } else { + flags = 0; /* TODO: default? */ + } /* parse value; deal with escapes */ for (value = sp = dp; *dp && (*dp != sep); ++dp) { @@ -971,6 +1021,7 @@ int himport_ext(struct hsearch_data *htab, unsigned int ctx, /* enter into hash table */ e.context = ctx; e.key = name; + e.flags = flags; e.data = value; hsearch_ext(e, ENTER, &rv, htab, flag);