#include <linux/string.h>
#include <linux/ctype.h>
+#include <stdio.h>
#ifdef USE_HOSTCC /* Eliminate "ANSI does not permit..." warnings */
#include <stdint.h>
-#include <stdio.h>
#include "fw_env_private.h"
#include "fw_env.h"
#include <env_attr.h>
#define env_get fw_getenv
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#else
-#include <common.h>
+#include <linux/kernel.h>
#include <env_internal.h>
#endif
-#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_NET
#define ENV_FLAGS_NET_VARTYPE_REPS "im"
#else
#define ENV_FLAGS_NET_VARTYPE_REPS ""
#endif
+#ifdef CONFIG_ENV_WRITEABLE_LIST
+#define ENV_FLAGS_WRITEABLE_VARACCESS_REPS "w"
+#else
+#define ENV_FLAGS_WRITEABLE_VARACCESS_REPS ""
+#endif
+
static const char env_flags_vartype_rep[] = "sdxb" ENV_FLAGS_NET_VARTYPE_REPS;
-static const char env_flags_varaccess_rep[] = "aroc";
+static const char env_flags_varaccess_rep[] =
+ "aroc" ENV_FLAGS_WRITEABLE_VARACCESS_REPS;
static const int env_flags_varaccess_mask[] = {
0,
ENV_FLAGS_VARACCESS_PREVENT_DELETE |
ENV_FLAGS_VARACCESS_PREVENT_DELETE |
ENV_FLAGS_VARACCESS_PREVENT_OVERWR,
ENV_FLAGS_VARACCESS_PREVENT_DELETE |
- ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR};
+ ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR,
+#ifdef CONFIG_ENV_WRITEABLE_LIST
+ ENV_FLAGS_VARACCESS_WRITEABLE,
+#endif
+ };
#ifdef CONFIG_CMD_ENV_FLAGS
static const char * const env_flags_vartype_names[] = {
"decimal",
"hexadecimal",
"boolean",
-#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_NET
"IP address",
"MAC address",
#endif
"read-only",
"write-once",
"change-default",
+#ifdef CONFIG_ENV_WRITEABLE_LIST
+ "writeable",
+#endif
};
/*
*/
enum env_flags_varaccess env_flags_parse_varaccess(const char *flags)
{
+ enum env_flags_varaccess va_default = env_flags_varaccess_any;
+ enum env_flags_varaccess va;
char *access;
if (strlen(flags) <= ENV_FLAGS_VARACCESS_LOC)
- return env_flags_varaccess_any;
+ return va_default;
access = strchr(env_flags_varaccess_rep,
flags[ENV_FLAGS_VARACCESS_LOC]);
- if (access != NULL)
- return (enum env_flags_varaccess)
+ if (access != NULL) {
+ va = (enum env_flags_varaccess)
(access - &env_flags_varaccess_rep[0]);
+ return va;
+ }
printf("## Warning: Unknown environment variable access method '%c'\n",
flags[ENV_FLAGS_VARACCESS_LOC]);
- return env_flags_varaccess_any;
+ return va_default;
}
/*
*/
enum env_flags_varaccess env_flags_parse_varaccess_from_binflags(int binflags)
{
+ enum env_flags_varaccess va_default = env_flags_varaccess_any;
+ enum env_flags_varaccess va;
int i;
for (i = 0; i < ARRAY_SIZE(env_flags_varaccess_mask); i++)
if (env_flags_varaccess_mask[i] ==
- (binflags & ENV_FLAGS_VARACCESS_BIN_MASK))
- return (enum env_flags_varaccess)i;
+ (binflags & ENV_FLAGS_VARACCESS_BIN_MASK)) {
+ va = (enum env_flags_varaccess)i;
+ return va;
+ }
printf("Warning: Non-standard access flags. (0x%x)\n",
binflags & ENV_FLAGS_VARACCESS_BIN_MASK);
- return env_flags_varaccess_any;
+ return va_default;
}
static inline int is_hex_prefix(const char *value)
*end = value;
}
-#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_NET
int eth_validate_ethaddr_str(const char *addr)
{
const char *end;
enum env_flags_vartype type)
{
const char *end;
-#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_NET
const char *cur;
int i;
#endif
if (value[1] != '\0')
return -1;
break;
-#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_NET
case env_flags_vartype_ipaddr:
cur = value;
for (i = 0; i < 4; i++) {
enum env_flags_varaccess env_flags_get_varaccess(const char *name)
{
const char *flags_list = env_get(ENV_FLAGS_VAR);
+ enum env_flags_varaccess va_default = env_flags_varaccess_any;
char flags[ENV_FLAGS_ATTR_MAX_LEN + 1];
if (env_flags_lookup(flags_list, name, flags))
- return env_flags_varaccess_any;
+ return va_default;
if (strlen(flags) <= ENV_FLAGS_VARACCESS_LOC)
- return env_flags_varaccess_any;
+ return va_default;
return env_flags_parse_varaccess(flags);
}
int ret = 1;
if (first_call) {
+#ifdef CONFIG_ENV_WRITEABLE_LIST
+ flags_list = ENV_FLAGS_LIST_STATIC;
+#else
flags_list = env_get(ENV_FLAGS_VAR);
+#endif
first_call = 0;
}
/* look in the ".flags" and static for a reference to this variable */
e.key = name;
e.data = NULL;
- e.callback = NULL;
hsearch_r(e, ENV_FIND, &ep, &env_htab, 0);
/* does the env variable actually exist? */
}
/* check for access permission */
-#ifndef CONFIG_ENV_ACCESS_IGNORE_FORCE
- if (flag & H_FORCE)
+#ifdef CONFIG_ENV_WRITEABLE_LIST
+ if (flag & H_DEFAULT)
+ return 0; /* Default env is always OK */
+
+ /*
+ * External writeable variables can be overwritten by external env,
+ * anything else can not be overwritten by external env.
+ */
+ if ((flag & H_EXTERNAL) &&
+ !(item->flags & ENV_FLAGS_VARACCESS_WRITEABLE))
+ return 1;
+#endif
+
+ if (flag & H_FORCE) {
+#ifdef CONFIG_ENV_ACCESS_IGNORE_FORCE
+ printf("## Error: Can't force access to \"%s\"\n", name);
+#else
return 0;
#endif
+ }
switch (op) {
case env_op_delete:
if (item->flags & ENV_FLAGS_VARACCESS_PREVENT_DELETE) {