tools: env: bug: config structs must be defined in tools library
[platform/kernel/u-boot.git] / tools / env / fw_env.c
index 1173eea..1420ac5 100644 (file)
@@ -8,10 +8,14 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
+#define _GNU_SOURCE
+
+#include <compiler.h>
 #include <errno.h>
 #include <env_flags.h>
 #include <fcntl.h>
 #include <linux/stringify.h>
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
 
 #include "fw_env.h"
 
-#include <aes.h>
+struct common_args common_args;
+struct printenv_args printenv_args;
+struct setenv_args setenv_args;
 
 #define DIV_ROUND_UP(n, d)     (((n) + (d) - 1) / (d))
 
-#define WHITESPACE(c) ((c == '\t') || (c == ' '))
-
 #define min(x, y) ({                           \
        typeof(x) _min1 = (x);                  \
        typeof(y) _min2 = (y);                  \
@@ -102,9 +106,6 @@ static struct environment environment = {
        .flag_scheme = FLAG_NONE,
 };
 
-/* Is AES encryption used? */
-static int aes_flag;
-static uint8_t aes_key[AES_KEY_LENGTH] = { 0 };
 static int env_aes_cbc_crypt(char *data, const int enc);
 
 static int HaveRedundEnv = 0;
@@ -130,26 +131,28 @@ static inline ulong getenvsize (void)
        if (HaveRedundEnv)
                rc -= sizeof (char);
 
-       if (aes_flag)
+       if (common_args.aes_flag)
                rc &= ~(AES_KEY_LENGTH - 1);
 
        return rc;
 }
 
-static char *fw_string_blank(char *s, int noblank)
+static char *skip_chars(char *s)
 {
-       int i;
-       int len = strlen(s);
-
-       for (i = 0; i < len; i++, s++) {
-               if ((noblank && !WHITESPACE(*s)) ||
-                       (!noblank && WHITESPACE(*s)))
-                       break;
+       for (; *s != '\0'; s++) {
+               if (isblank(*s))
+                       return s;
        }
-       if (i == len)
-               return NULL;
+       return NULL;
+}
 
-       return s;
+static char *skip_blanks(char *s)
+{
+       for (; *s != '\0'; s++) {
+               if (!isblank(*s))
+                       return s;
+       }
+       return NULL;
 }
 
 /*
@@ -204,7 +207,7 @@ char *fw_getdefenv(char *name)
        return NULL;
 }
 
-static int parse_aes_key(char *key)
+int parse_aes_key(char *key, uint8_t *bin_key)
 {
        char tmp[5] = { '0', 'x', 0, 0, 0 };
        unsigned long ul;
@@ -226,11 +229,9 @@ static int parse_aes_key(char *key)
                                "## Error: '-a' option requires valid AES key\n");
                        return -1;
                }
-               aes_key[i] = ul & 0xff;
+               bin_key[i] = ul & 0xff;
                key += 2;
        }
-       aes_flag = 1;
-
        return 0;
 }
 
@@ -241,26 +242,12 @@ static int parse_aes_key(char *key)
 int fw_printenv (int argc, char *argv[])
 {
        char *env, *nxt;
-       int i, n_flag;
-       int rc = 0;
-
-       if (argc >= 2 && strcmp(argv[1], "-a") == 0) {
-               if (argc < 3) {
-                       fprintf(stderr,
-                               "## Error: '-a' option requires AES key\n");
-                       return -1;
-               }
-               rc = parse_aes_key(argv[2]);
-               if (rc)
-                       return rc;
-               argv += 2;
-               argc -= 2;
-       }
+       int i, rc = 0;
 
        if (fw_env_open())
                return -1;
 
-       if (argc == 1) {                /* Print all env variables  */
+       if (argc == 0) {                /* Print all env variables  */
                for (env = environment.data; *env; env = nxt + 1) {
                        for (nxt = env; *nxt; ++nxt) {
                                if (nxt >= &environment.data[ENV_SIZE]) {
@@ -275,20 +262,13 @@ int fw_printenv (int argc, char *argv[])
                return 0;
        }
 
-       if (strcmp (argv[1], "-n") == 0) {
-               n_flag = 1;
-               ++argv;
-               --argc;
-               if (argc != 2) {
-                       fprintf (stderr, "## Error: "
-                               "`-n' option requires exactly one argument\n");
-                       return -1;
-               }
-       } else {
-               n_flag = 0;
+       if (printenv_args.name_suppress && argc != 1) {
+               fprintf(stderr,
+                       "## Error: `-n' option requires exactly one argument\n");
+               return -1;
        }
 
-       for (i = 1; i < argc; ++i) {    /* print single env variables   */
+       for (i = 0; i < argc; ++i) {    /* print single env variables   */
                char *name = argv[i];
                char *val = NULL;
 
@@ -303,7 +283,7 @@ int fw_printenv (int argc, char *argv[])
                        }
                        val = envmatch (name, env);
                        if (val) {
-                               if (!n_flag) {
+                               if (!printenv_args.name_suppress) {
                                        fputs (name, stdout);
                                        putc ('=', stdout);
                                }
@@ -323,7 +303,7 @@ int fw_printenv (int argc, char *argv[])
 int fw_env_close(void)
 {
        int ret;
-       if (aes_flag) {
+       if (common_args.aes_flag) {
                ret = env_aes_cbc_crypt(environment.data, 1);
                if (ret) {
                        fprintf(stderr,
@@ -479,30 +459,14 @@ int fw_env_write(char *name, char *value)
  */
 int fw_setenv(int argc, char *argv[])
 {
-       int i, rc;
+       int i;
        size_t len;
-       char *name;
+       char *name, **valv;
        char *value = NULL;
+       int valc;
 
-       if (argc < 2) {
-               errno = EINVAL;
-               return -1;
-       }
-
-       if (strcmp(argv[1], "-a") == 0) {
-               if (argc < 3) {
-                       fprintf(stderr,
-                               "## Error: '-a' option requires AES key\n");
-                       return -1;
-               }
-               rc = parse_aes_key(argv[2]);
-               if (rc)
-                       return rc;
-               argv += 2;
-               argc -= 2;
-       }
-
-       if (argc < 2) {
+       if (argc < 1) {
+               fprintf(stderr, "## Error: variable name missing\n");
                errno = EINVAL;
                return -1;
        }
@@ -512,14 +476,16 @@ int fw_setenv(int argc, char *argv[])
                return -1;
        }
 
-       name = argv[1];
+       name = argv[0];
+       valv = argv + 1;
+       valc = argc - 1;
 
-       if (env_flags_validate_env_set_params(argc, argv) < 0)
+       if (env_flags_validate_env_set_params(name, valv, valc) < 0)
                return 1;
 
        len = 0;
-       for (i = 2; i < argc; ++i) {
-               char *val = argv[i];
+       for (i = 0; i < valc; ++i) {
+               char *val = valv[i];
                size_t val_len = strlen(val);
 
                if (value)
@@ -604,31 +570,29 @@ int fw_parse_script(char *fname)
                }
 
                /* Drop ending line feed / carriage return */
-               while (len > 0 && (dump[len - 1] == '\n' ||
-                               dump[len - 1] == '\r')) {
-                       dump[len - 1] = '\0';
-                       len--;
-               }
+               dump[--len] = '\0';
+               if (len && dump[len - 1] == '\r')
+                       dump[--len] = '\0';
 
                /* Skip comment or empty lines */
-               if ((len == 0) || dump[0] == '#')
+               if (len == 0 || dump[0] == '#')
                        continue;
 
                /*
                 * Search for variable's name,
                 * remove leading whitespaces
                 */
-               name = fw_string_blank(dump, 1);
+               name = skip_blanks(dump);
                if (!name)
                        continue;
 
                /* The first white space is the end of variable name */
-               val = fw_string_blank(name, 0);
+               val = skip_chars(name);
                len = strlen(name);
                if (val) {
                        *val++ = '\0';
                        if ((val - name) < len)
-                               val = fw_string_blank(val, 1);
+                               val = skip_blanks(val);
                        else
                                val = NULL;
                }
@@ -993,7 +957,7 @@ static int env_aes_cbc_crypt(char *payload, const int enc)
        uint32_t aes_blocks;
 
        /* First we expand the key. */
-       aes_expand_key(aes_key, key_exp);
+       aes_expand_key(common_args.aes_key, key_exp);
 
        /* Calculate the number of AES blocks to encrypt. */
        aes_blocks = DIV_ROUND_UP(len, AES_KEY_LENGTH);
@@ -1221,7 +1185,7 @@ int fw_env_open(void)
 
        crc0 = crc32 (0, (uint8_t *) environment.data, ENV_SIZE);
 
-       if (aes_flag) {
+       if (common_args.aes_flag) {
                ret = env_aes_cbc_crypt(environment.data, 0);
                if (ret)
                        return ret;
@@ -1278,7 +1242,7 @@ int fw_env_open(void)
 
                crc1 = crc32 (0, (uint8_t *) redundant->data, ENV_SIZE);
 
-               if (aes_flag) {
+               if (common_args.aes_flag) {
                        ret = env_aes_cbc_crypt(redundant->data, 0);
                        if (ret)
                                return ret;
@@ -1362,9 +1326,9 @@ static int parse_config ()
 
 #if defined(CONFIG_FILE)
        /* Fills in DEVNAME(), ENVSIZE(), DEVESIZE(). Or don't. */
-       if (get_config (CONFIG_FILE)) {
-               fprintf (stderr,
-                       "Cannot parse config file: %s\n", strerror (errno));
+       if (get_config(common_args.config_file)) {
+               fprintf(stderr, "Cannot parse config file '%s': %m\n",
+                       common_args.config_file);
                return -1;
        }
 #else