Skip to content
Snippets Groups Projects
cmd_nvedit.c 30 KiB
Newer Older
Wolfgang Denk's avatar
Wolfgang Denk committed
/*
 * (C) Copyright 2000-2013
Wolfgang Denk's avatar
Wolfgang Denk committed
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Andreas Heppel <aheppel@sysgo.de>
 *
 * Copyright 2011 Freescale Semiconductor, Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
Wolfgang Denk's avatar
Wolfgang Denk committed
 */

Wolfgang Denk's avatar
Wolfgang Denk committed
 * Support for persistent environment data
 *
 * The "environment" is stored on external storage as a list of '\0'
 * terminated "name=value" strings. The end of the list is marked by
 * a double '\0'. The environment is preceeded by a 32 bit CRC over
 * the data part and, in case of redundant environment, a byte of
 * flags.
Wolfgang Denk's avatar
Wolfgang Denk committed
 *
 * This linearized representation will also be used before
 * relocation, i. e. as long as we don't have a full C runtime
 * environment. After that, we use a hash table.
Wolfgang Denk's avatar
Wolfgang Denk committed
 */

#include <common.h>
#include <cli.h>
Wolfgang Denk's avatar
Wolfgang Denk committed
#include <command.h>
#include <environment.h>
#include <search.h>
#include <errno.h>
Peter Tyser's avatar
Peter Tyser committed
#include <malloc.h>
Wolfgang Denk's avatar
Wolfgang Denk committed
#include <linux/stddef.h>
#include <asm/byteorder.h>
#include <asm/io.h>
Wolfgang Denk's avatar
Wolfgang Denk committed

#if	!defined(CONFIG_ENV_IS_IN_EEPROM)	&& \
	!defined(CONFIG_ENV_IS_IN_FLASH)	&& \
	!defined(CONFIG_ENV_IS_IN_DATAFLASH)	&& \
	!defined(CONFIG_ENV_IS_IN_MMC)		&& \
	!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_IN_REMOTE)	&& \
	!defined(CONFIG_ENV_IS_IN_UBI)		&& \
	!defined(CONFIG_ENV_IS_NOWHERE)
# error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\
SPI_FLASH|NVRAM|MMC|FAT|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE
Wolfgang Denk's avatar
Wolfgang Denk committed
#endif

/*
 * Maximum expected input data size for import command
 */
#define	MAX_ENV_SIZE	(1 << 20)	/* 1 MiB */
Wolfgang Denk's avatar
Wolfgang Denk committed

 * This variable is incremented on each do_env_set(), 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;
Wolfgang Denk's avatar
Wolfgang Denk committed

int get_env_id(void)
{
	return env_id;
}
Wolfgang Denk's avatar
Wolfgang Denk committed

#ifndef CONFIG_SPL_BUILD
 * Command interface: print one or all environment variables
 *
 * Returns 0 in case of error, or length of printed string
static int env_print(char *name, int flag)
Wolfgang Denk's avatar
Wolfgang Denk committed
{

	if (name) {		/* print a single name */
		ENTRY e, *ep;

		e.key = name;
		e.data = NULL;
		hsearch_r(e, FIND, &ep, &env_htab, flag);
		len = printf("%s=%s\n", ep->key, ep->data);
Wolfgang Denk's avatar
Wolfgang Denk committed

	len = hexport_r(&env_htab, '\n', flag, &res, 0, 0, NULL);
Wolfgang Denk's avatar
Wolfgang Denk committed

	if (len > 0) {
		puts(res);
		free(res);
		return len;
Wolfgang Denk's avatar
Wolfgang Denk committed
	}

	printf("## Error: cannot export environment\n");
Wolfgang Denk's avatar
Wolfgang Denk committed

static int do_env_print(cmd_tbl_t *cmdtp, int flag, int argc,
			char * const argv[])
{
	int i;
	int rcode = 0;
	int env_flag = H_HIDE_DOT;

	if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'a') {
		argc--;
		argv++;
		env_flag &= ~H_HIDE_DOT;
	}
Wolfgang Denk's avatar
Wolfgang Denk committed

	if (argc == 1) {
		/* print all env vars */
		rcode = env_print(NULL, env_flag);
			return 1;
		printf("\nEnvironment size: %d/%ld bytes\n",
			rcode, (ulong)ENV_SIZE);
		return 0;
	}
Wolfgang Denk's avatar
Wolfgang Denk committed

	/* print selected env vars */
	env_flag &= ~H_HIDE_DOT;
	for (i = 1; i < argc; ++i) {
		int rc = env_print(argv[i], env_flag);
		if (!rc) {
			printf("## Error: \"%s\" not defined\n", argv[i]);
Wolfgang Denk's avatar
Wolfgang Denk committed
		}
	}
Wolfgang Denk's avatar
Wolfgang Denk committed
	return rcode;
}

#ifdef CONFIG_CMD_GREPENV
static int do_env_grep(cmd_tbl_t *cmdtp, int flag,
		       int argc, char * const argv[])
	int len, grep_how, grep_what;

	if (argc < 2)
	grep_how  = H_MATCH_SUBSTR;	/* default: substring search	*/
	grep_what = H_MATCH_BOTH;	/* default: grep names and values */
	while (--argc > 0 && **++argv == '-') {
		char *arg = *argv;
		while (*++arg) {
			switch (*arg) {
#ifdef CONFIG_REGEX
			case 'e':		/* use regex matching */
				grep_how  = H_MATCH_REGEX;
				break;
#endif
			case 'n':		/* grep for name */
				grep_what = H_MATCH_KEY;
				break;
			case 'v':		/* grep for value */
				grep_what = H_MATCH_DATA;
				break;
			case 'b':		/* grep for both */
				grep_what = H_MATCH_BOTH;
				break;
			case '-':
				goto DONE;
			default:
				return CMD_RET_USAGE;
			}
		}
	}

DONE:
	len = hexport_r(&env_htab, '\n',
			flag | grep_what | grep_how,
			&res, 0, argc, argv);
	if (len > 0) {
		puts(res);
		free(res);
Loading
Loading full blame...