Rename getenv_r() into getenv_f()
[oweals/u-boot.git] / common / cmd_nvedit.c
index 85a0f94f0fec0a0a11d2d39fd8d95a25b3e2f2fa..16d5ff74d9e03d1225a1713f5fafa61e811d432e 100644 (file)
@@ -42,6 +42,9 @@
 #include <common.h>
 #include <command.h>
 #include <environment.h>
+#if defined(CONFIG_CMD_EDITENV)
+#include <malloc.h>
+#endif
 #include <watchdog.h>
 #include <serial.h>
 #include <linux/stddef.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#if !defined(CFG_ENV_IS_IN_NVRAM)      && \
-    !defined(CFG_ENV_IS_IN_EEPROM)     && \
-    !defined(CFG_ENV_IS_IN_FLASH)      && \
-    !defined(CFG_ENV_IS_IN_DATAFLASH)  && \
-    !defined(CFG_ENV_IS_IN_NAND)       && \
-    !defined(CFG_ENV_IS_IN_ONENAND)    && \
-    !defined(CFG_ENV_IS_IN_SPI_FLASH)  && \
-    !defined(CFG_ENV_IS_NOWHERE)
-# error Define one of CFG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|ONENAND|SPI_FLASH|NOWHERE}
+#if !defined(CONFIG_ENV_IS_IN_EEPROM)  && \
+    !defined(CONFIG_ENV_IS_IN_FLASH)   && \
+    !defined(CONFIG_ENV_IS_IN_DATAFLASH)       && \
+    !defined(CONFIG_ENV_IS_IN_MG_DISK) && \
+    !defined(CONFIG_ENV_IS_IN_NAND)    && \
+    !defined(CONFIG_ENV_IS_IN_NVRAM)   && \
+    !defined(CONFIG_ENV_IS_IN_ONENAND) && \
+    !defined(CONFIG_ENV_IS_IN_SPI_FLASH)       && \
+    !defined(CONFIG_ENV_IS_NOWHERE)
+# error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\
+SPI_FLASH|MG_DISK|NVRAM|NOWHERE}
 #endif
 
 #define XMK_STR(x)     #x
@@ -72,63 +77,92 @@ DECLARE_GLOBAL_DATA_PTR;
 /*
  * Table with supported baudrates (defined in config_xyz.h)
  */
-static const unsigned long baudrate_table[] = CFG_BAUDRATE_TABLE;
+static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE;
 #define        N_BAUDRATES (sizeof(baudrate_table) / sizeof(baudrate_table[0]))
 
+/*
+ * This variable is incremented on each do_setenv (), so it can
+ * be used via get_env_id() as an indication, if the environment
+ * has changed or not. So it is possible to reread an environment
+ * variable only if the environment was changed ... done so for
+ * example in NetInitLoop()
+ */
+static int env_id = 1;
 
+int get_env_id (void)
+{
+       return env_id;
+}
 /************************************************************************
  * Command interface: print one or all environment variables
  */
 
-int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+/*
+ * state 0: finish printing this string and return (matched!)
+ * state 1: no matching to be done; print everything
+ * state 2: continue searching for matched name
+ */
+static int printenv(char *name, int state)
 {
-       int i, j, k, nxt;
-       int rcode = 0;
-
-       if (argc == 1) {                /* Print all env variables      */
-               for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
-                       for (nxt=i; env_get_char(nxt) != '\0'; ++nxt)
-                               ;
-                       for (k=i; k<nxt; ++k)
-                               putc(env_get_char(k));
-                       putc  ('\n');
-
-                       if (ctrlc()) {
-                               puts ("\n ** Abort\n");
-                               return 1;
+       int i, j;
+       char c, buf[17];
+
+       i = 0;
+       buf[16] = '\0';
+
+       while (state && env_get_char(i) != '\0') {
+               if (state == 2 && envmatch((uchar *)name, i) >= 0)
+                       state = 0;
+
+               j = 0;
+               do {
+                       buf[j++] = c = env_get_char(i++);
+                       if (j == sizeof(buf) - 1) {
+                               if (state <= 1)
+                                       puts(buf);
+                               j = 0;
                        }
-               }
+               } while (c != '\0');
 
-               printf("\nEnvironment size: %d/%d bytes\n", i, ENV_SIZE);
+               if (state <= 1) {
+                       if (j)
+                               puts(buf);
+                       putc('\n');
+               }
 
-               return 0;
+               if (ctrlc())
+                       return -1;
        }
 
-       for (i=1; i<argc; ++i) {        /* print single env variables   */
-               char *name = argv[i];
+       if (state == 0)
+               i = 0;
+       return i;
+}
 
-               k = -1;
+int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       int i;
+       int rcode = 0;
 
-               for (j=0; env_get_char(j) != '\0'; j=nxt+1) {
+       if (argc == 1) {
+               /* print all env vars */
+               rcode = printenv(NULL, 1);
+               if (rcode < 0)
+                       return 1;
+               printf("\nEnvironment size: %d/%ld bytes\n",
+                       rcode, (ulong)ENV_SIZE);
+               return 0;
+       }
 
-                       for (nxt=j; env_get_char(nxt) != '\0'; ++nxt)
-                               ;
-                       k = envmatch((uchar *)name, j);
-                       if (k < 0) {
-                               continue;
-                       }
-                       puts (name);
-                       putc ('=');
-                       while (k < nxt)
-                               putc(env_get_char(k++));
-                       putc ('\n');
-                       break;
-               }
-               if (k < 0) {
-                       printf ("## Error: \"%s\" not defined\n", name);
-                       rcode ++;
+       /* print selected env vars */
+       for (i = 1; i < argc; ++i) {
+               char *name = argv[i];
+               if (printenv(name, 2)) {
+                       printf("## Error: \"%s\" not defined\n", name);
+                       ++rcode;
                }
        }
+
        return rcode;
 }
 
@@ -139,7 +173,7 @@ int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  * This function will ONLY work with a in-RAM copy of the environment
  */
 
-int _do_setenv (int flag, int argc, char *argv[])
+int _do_setenv (int flag, int argc, char * const argv[])
 {
        int   i, len, oldval;
        int   console = -1;
@@ -159,6 +193,7 @@ int _do_setenv (int flag, int argc, char *argv[])
                return 1;
        }
 
+       env_id++;
        /*
         * search if variable with this name already exists
         */
@@ -170,6 +205,37 @@ int _do_setenv (int flag, int argc, char *argv[])
                        break;
        }
 
+       /* Check for console redirection */
+       if (strcmp(name,"stdin") == 0) {
+               console = stdin;
+       } else if (strcmp(name,"stdout") == 0) {
+               console = stdout;
+       } else if (strcmp(name,"stderr") == 0) {
+               console = stderr;
+       }
+
+       if (console != -1) {
+               if (argc < 3) {         /* Cannot delete it! */
+                       printf("Can't delete \"%s\"\n", name);
+                       return 1;
+               }
+
+#ifdef CONFIG_CONSOLE_MUX
+               i = iomux_doenv(console, argv[2]);
+               if (i)
+                       return i;
+#else
+               /* Try assigning specified device */
+               if (console_assign (console, argv[2]) < 0)
+                       return 1;
+
+#ifdef CONFIG_SERIAL_MULTI
+               if (serial_assign (argv[2]) < 0)
+                       return 1;
+#endif
+#endif /* CONFIG_CONSOLE_MUX */
+       }
+
        /*
         * Delete any existing definition
         */
@@ -197,31 +263,6 @@ int _do_setenv (int flag, int argc, char *argv[])
                }
 #endif
 
-               /* Check for console redirection */
-               if (strcmp(name,"stdin") == 0) {
-                       console = stdin;
-               } else if (strcmp(name,"stdout") == 0) {
-                       console = stdout;
-               } else if (strcmp(name,"stderr") == 0) {
-                       console = stderr;
-               }
-
-               if (console != -1) {
-                       if (argc < 3) {         /* Cannot delete it! */
-                               printf("Can't delete \"%s\"\n", name);
-                               return 1;
-                       }
-
-                       /* Try assigning specified device */
-                       if (console_assign (console, argv[2]) < 0)
-                               return 1;
-
-#ifdef CONFIG_SERIAL_MULTI
-                       if (serial_assign (argv[2]) < 0)
-                               return 1;
-#endif
-               }
-
                /*
                 * Switch to new baudrate if new baudrate is supported
                 */
@@ -270,18 +311,6 @@ int _do_setenv (int flag, int argc, char *argv[])
                *++env = '\0';
        }
 
-#ifdef CONFIG_NET_MULTI
-       if (strncmp(name, "eth", 3) == 0) {
-               char *end;
-               int   num = simple_strtoul(name+3, &end, 10);
-
-               if (strcmp(end, "addr") == 0) {
-                       eth_set_enetaddr(num, argv[2]);
-               }
-       }
-#endif
-
-
        /* Delete only ? */
        if ((argc < 3) || argv[2] == NULL) {
                env_crc_update ();
@@ -329,18 +358,8 @@ int _do_setenv (int flag, int argc, char *argv[])
         * entry in the enviornment is changed
         */
 
-       if (strcmp(argv[1],"ethaddr") == 0) {
-               char *s = argv[2];      /* always use only one arg */
-               char *e;
-               for (i=0; i<6; ++i) {
-                       bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0;
-                       if (s) s = (*e) ? e+1 : e;
-               }
-#ifdef CONFIG_NET_MULTI
-               eth_set_enetaddr(0, argv[2]);
-#endif
+       if (strcmp(argv[1],"ethaddr") == 0)
                return 0;
-       }
 
        if (strcmp(argv[1],"ipaddr") == 0) {
                char *s = argv[2];      /* always use only one arg */
@@ -366,25 +385,13 @@ int _do_setenv (int flag, int argc, char *argv[])
                return 0;
        }
 #endif
-
-#ifdef CONFIG_AMIGAONEG3SE
-       if (strcmp(argv[1], "vga_fg_color") == 0 ||
-           strcmp(argv[1], "vga_bg_color") == 0 ) {
-               extern void video_set_color(unsigned char attr);
-               extern unsigned char video_get_attr(void);
-
-               video_set_color(video_get_attr());
-               return 0;
-       }
-#endif /* CONFIG_AMIGAONEG3SE */
-
        return 0;
 }
 
 int setenv (char *varname, char *varvalue)
 {
-       char *argv[4] = { "setenv", varname, varvalue, NULL };
-       if (varvalue == NULL)
+       char * const argv[4] = { "setenv", varname, varvalue, NULL };
+       if ((varvalue == NULL) || (varvalue[0] == '\0'))
                return _do_setenv (0, 2, argv);
        else
                return _do_setenv (0, 3, argv);
@@ -393,17 +400,15 @@ int setenv (char *varname, char *varvalue)
 #ifdef CONFIG_HAS_UID
 void forceenv (char *varname, char *varvalue)
 {
-       char *argv[4] = { "forceenv", varname, varvalue, NULL };
+       char * const argv[4] = { "forceenv", varname, varvalue, NULL };
        _do_setenv (0xdeaf4add, 3, argv);
 }
 #endif
 
-int do_setenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_setenv (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       if (argc < 2) {
-               printf ("Usage:\n%s\n", cmdtp->usage);
-               return 1;
-       }
+       if (argc < 2)
+               return cmd_usage(cmdtp);
 
        return _do_setenv (flag, argc, argv);
 }
@@ -413,11 +418,11 @@ int do_setenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  */
 
 #if defined(CONFIG_CMD_ASKENV)
-int do_askenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_askenv ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       extern char console_buffer[CFG_CBSIZE];
-       char message[CFG_CBSIZE];
-       int size = CFG_CBSIZE - 1;
+       extern char console_buffer[CONFIG_SYS_CBSIZE];
+       char message[CONFIG_SYS_CBSIZE];
+       int size = CONFIG_SYS_CBSIZE - 1;
        int len;
        char *local_args[4];
 
@@ -426,15 +431,13 @@ int do_askenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        local_args[2] = NULL;
        local_args[3] = NULL;
 
-       if (argc < 2) {
-               printf ("Usage:\n%s\n", cmdtp->usage);
-               return 1;
-       }
+       if (argc < 2)
+               return cmd_usage(cmdtp);
+
        /* Check the syntax */
        switch (argc) {
        case 1:
-               printf ("Usage:\n%s\n", cmdtp->usage);
-               return 1;
+               return cmd_usage(cmdtp);
 
        case 2:         /* askenv envname */
                sprintf (message, "Please enter '%s':", argv[1]);
@@ -463,8 +466,8 @@ int do_askenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                break;
        }
 
-       if (size >= CFG_CBSIZE)
-               size = CFG_CBSIZE - 1;
+       if (size >= CONFIG_SYS_CBSIZE)
+               size = CONFIG_SYS_CBSIZE - 1;
 
        if (size <= 0)
                return 1;
@@ -486,6 +489,32 @@ int do_askenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 }
 #endif
 
+/************************************************************************
+ * Interactively edit an environment variable
+ */
+#if defined(CONFIG_CMD_EDITENV)
+int do_editenv(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       char buffer[CONFIG_SYS_CBSIZE];
+       char *init_val;
+       int len;
+
+       if (argc < 2)
+               return cmd_usage(cmdtp);
+
+       /* Set read buffer to initial value or empty sting */
+       init_val = getenv(argv[1]);
+       if (init_val)
+               len = sprintf(buffer, "%s", init_val);
+       else
+               buffer[0] = '\0';
+
+       readline_into_buffer("edit: ", buffer);
+
+       return setenv(argv[1], buffer);
+}
+#endif /* CONFIG_CMD_EDITENV */
+
 /************************************************************************
  * Look up variable from environment,
  * return address of storage for that variable,
@@ -502,7 +531,7 @@ char *getenv (char *name)
                int val;
 
                for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) {
-                       if (nxt >= CFG_ENV_SIZE) {
+                       if (nxt >= CONFIG_ENV_SIZE) {
                                return (NULL);
                        }
                }
@@ -514,7 +543,7 @@ char *getenv (char *name)
        return (NULL);
 }
 
-int getenv_(char *name, char *buf, unsigned len)
+int getenv_f(char *name, char *buf, unsigned len)
 {
        int i, nxt;
 
@@ -522,7 +551,7 @@ int getenv_r (char *name, char *buf, unsigned len)
                int val, n;
 
                for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) {
-                       if (nxt >= CFG_ENV_SIZE) {
+                       if (nxt >= CONFIG_ENV_SIZE) {
                                return (-1);
                        }
                }
@@ -539,12 +568,9 @@ int getenv_r (char *name, char *buf, unsigned len)
        return (-1);
 }
 
-#if ((defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) \
-    || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_FLASH)) \
-    || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_NAND)) \
-    || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_ONENAND))) \
-    && !defined(CFG_ENV_IS_NOWHERE))
-int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
+
+int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        extern char * env_name_spec;
 
@@ -553,6 +579,12 @@ int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        return (saveenv() ? 1 : 0);
 }
 
+U_BOOT_CMD(
+       saveenv, 1, 0,  do_saveenv,
+       "save environment variables to persistent storage",
+       ""
+);
+
 #endif
 
 
@@ -578,41 +610,37 @@ int envmatch (uchar *s1, int i2)
 
 /**************************************************/
 
+#if defined(CONFIG_CMD_EDITENV)
+U_BOOT_CMD(
+       editenv, 2, 0,  do_editenv,
+       "edit environment variable",
+       "name\n"
+       "    - edit environment variable 'name'"
+);
+#endif
+
 U_BOOT_CMD(
-       printenv, CFG_MAXARGS, 1,       do_printenv,
-       "printenv- print environment variables\n",
+       printenv, CONFIG_SYS_MAXARGS, 1,        do_printenv,
+       "print environment variables",
        "\n    - print values of all environment variables\n"
        "printenv name ...\n"
-       "    - print value of environment variable 'name'\n"
+       "    - print value of environment variable 'name'"
 );
 
 U_BOOT_CMD(
-       setenv, CFG_MAXARGS, 0, do_setenv,
-       "setenv  - set environment variables\n",
+       setenv, CONFIG_SYS_MAXARGS, 0,  do_setenv,
+       "set environment variables",
        "name value ...\n"
        "    - set environment variable 'name' to 'value ...'\n"
        "setenv name\n"
-       "    - delete environment variable 'name'\n"
+       "    - delete environment variable 'name'"
 );
 
-#if ((defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) \
-    || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_FLASH)) \
-    || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_NAND)) \
-    || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_ONENAND))) \
-    && !defined(CFG_ENV_IS_NOWHERE))
-U_BOOT_CMD(
-       saveenv, 1, 0,  do_saveenv,
-       "saveenv - save environment variables to persistent storage\n",
-       NULL
-);
-
-#endif
-
 #if defined(CONFIG_CMD_ASKENV)
 
 U_BOOT_CMD(
-       askenv, CFG_MAXARGS,    1,      do_askenv,
-       "askenv  - get environment variables from stdin\n",
+       askenv, CONFIG_SYS_MAXARGS,     1,      do_askenv,
+       "get environment variables from stdin",
        "name [message] [size]\n"
        "    - get environment variable 'name' from stdin (max 'size' chars)\n"
        "askenv name\n"
@@ -621,16 +649,16 @@ U_BOOT_CMD(
        "    - get environment variable 'name' from stdin (max 'size' chars)\n"
        "askenv name [message] size\n"
        "    - display 'message' string and get environment variable 'name'"
-       "from stdin (max 'size' chars)\n"
+       "from stdin (max 'size' chars)"
 );
 #endif
 
 #if defined(CONFIG_CMD_RUN)
-int do_run (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+int do_run (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 U_BOOT_CMD(
-       run,    CFG_MAXARGS,    1,      do_run,
-       "run     - run commands in an environment variable\n",
+       run,    CONFIG_SYS_MAXARGS,     1,      do_run,
+       "run commands in an environment variable",
        "var [...]\n"
-       "    - run the commands in the environment variable(s) 'var'\n"
+       "    - run the commands in the environment variable(s) 'var'"
 );
 #endif