svn_rev_386
remove old saveenv, allow setenv/getenv to change device parameters
This commit is contained in:
parent
f6feb18cdc
commit
20294d061c
216
common/env.c
216
common/env.c
|
@ -2,11 +2,9 @@
|
|||
#include <command.h>
|
||||
#include <driver.h>
|
||||
#include <malloc.h>
|
||||
#include <xfuncs.h>
|
||||
#include <errno.h>
|
||||
|
||||
static ulong env_size;
|
||||
static char *env_name_spec;
|
||||
|
||||
struct variable_d {
|
||||
struct variable_d *next;
|
||||
char data[0];
|
||||
|
@ -14,7 +12,8 @@ struct variable_d {
|
|||
|
||||
#define VARIABLE_D_SIZE(name, value) (sizeof(struct variable_d) + strlen(name) + strlen(value) + 2)
|
||||
|
||||
static struct variable_d *env_list;
|
||||
static struct variable_d _env_list;
|
||||
static struct variable_d *env_list = &_env_list;
|
||||
|
||||
static char *var_val(struct variable_d *var)
|
||||
{
|
||||
|
@ -30,10 +29,20 @@ char *getenv (const char *name)
|
|||
{
|
||||
struct variable_d *var;
|
||||
|
||||
if (!env_list) {
|
||||
printf("getenv(%s): not initialized\n",name);
|
||||
return NULL;
|
||||
}
|
||||
if (strchr(name, '.')) {
|
||||
char *ret = 0;
|
||||
char *devstr = strdup(name);
|
||||
char *par = strchr(devstr, '.');
|
||||
struct device_d *dev;
|
||||
*par = 0;
|
||||
dev = get_device_by_id(devstr);
|
||||
if (dev) {
|
||||
par++;
|
||||
ret = dev_get_param(dev, par);
|
||||
}
|
||||
free(devstr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
var = env_list->next;
|
||||
|
||||
|
@ -45,25 +54,32 @@ char *getenv (const char *name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void setenv (const char *name, const char *value)
|
||||
int setenv (const char *name, const char *value)
|
||||
{
|
||||
struct variable_d *var = env_list;
|
||||
struct variable_d *newvar = NULL;
|
||||
char *par;
|
||||
|
||||
if (!env_list) {
|
||||
printf("setenv(%s): not initialized\n",name);
|
||||
return;
|
||||
}
|
||||
if ((par = strchr(name, '.'))) {
|
||||
struct device_d *dev;
|
||||
*par++ = 0;
|
||||
dev = get_device_by_id(name);
|
||||
if (dev) {
|
||||
int ret = dev_set_param(dev, par, value);
|
||||
if (ret < 0)
|
||||
perror("set parameter");
|
||||
errno = 0;
|
||||
} else {
|
||||
errno = -ENODEV;
|
||||
perror("set parameter");
|
||||
}
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (value) {
|
||||
newvar = malloc(VARIABLE_D_SIZE(name, value));
|
||||
if (!newvar) {
|
||||
printf("cannot setenv: out of mem\n");
|
||||
return;
|
||||
}
|
||||
newvar = xzalloc(VARIABLE_D_SIZE(name, value));
|
||||
strcpy(&newvar->data[0], name);
|
||||
strcpy(&newvar->data[strlen(name) + 1], value);
|
||||
newvar->next = NULL;
|
||||
}
|
||||
|
||||
while (var->next) {
|
||||
|
@ -72,161 +88,20 @@ void setenv (const char *name, const char *value)
|
|||
newvar->next = var->next->next;
|
||||
free(var->next);
|
||||
var->next = newvar;
|
||||
return;
|
||||
return 0;
|
||||
} else {
|
||||
struct variable_d *tmp;
|
||||
tmp = var->next;
|
||||
var->next = var->next->next;
|
||||
free(var->next);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
var = var->next;
|
||||
}
|
||||
var->next = newvar;
|
||||
}
|
||||
|
||||
int add_env_spec(char *spec)
|
||||
{
|
||||
char *env;
|
||||
char *data;
|
||||
int err;
|
||||
unsigned long crc;
|
||||
struct memarea_info info;
|
||||
|
||||
printf("%s\n",__FUNCTION__);
|
||||
|
||||
if (spec_str_to_info(spec, &info)) {
|
||||
printf("-ENOPARSE\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Do it the simple way for now: Assume that the whole
|
||||
* environment sector plus the environment list fits in
|
||||
* memory.
|
||||
*/
|
||||
|
||||
env_size = info.size;
|
||||
env_name_spec = spec;
|
||||
|
||||
env = malloc(env_size);
|
||||
if (!env) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
env_list = malloc(sizeof(struct variable_d));
|
||||
if (!env_list) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
env_list->next = NULL;
|
||||
|
||||
err = dev_read(info.device, env, env_size, info.start, 0);
|
||||
if (err != env_size)
|
||||
goto err_out;
|
||||
|
||||
/* Make sure we don't go crazy with a corrupted environment */
|
||||
*(env + env_size - 1) = 0;
|
||||
*(env + env_size - 2) = 0;
|
||||
|
||||
crc = *(ulong *)env;
|
||||
if (crc != crc32(0, env + sizeof(ulong), env_size - sizeof(ulong))) {
|
||||
printf("environment is corrupt\n");
|
||||
err = -ENODEV;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
data = env + sizeof(env);
|
||||
|
||||
while(*data) {
|
||||
char *delim = strchr(data, '=');
|
||||
int len = strlen(data);
|
||||
printf("data: %s\n", data);
|
||||
|
||||
if (!delim)
|
||||
goto err_out;
|
||||
|
||||
*delim = 0;
|
||||
setenv(data, delim + 1);
|
||||
data += len + 1;
|
||||
}
|
||||
|
||||
free(env);
|
||||
|
||||
return 0;
|
||||
err_out:
|
||||
printf("error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int saveenv(void)
|
||||
{
|
||||
struct variable_d *var = env_list->next;
|
||||
struct memarea_info info;
|
||||
unsigned char *env;
|
||||
int left, ret = 0, ofs;
|
||||
|
||||
if (spec_str_to_info(env_name_spec, &info)) {
|
||||
printf("-ENOPARSE\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
env = malloc(env_size);
|
||||
if (!env) {
|
||||
printf("out of memory\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
memset(env, 0, env_size);
|
||||
|
||||
left = env_size - 2;
|
||||
ofs = 4;
|
||||
|
||||
while (var) {
|
||||
int nlen = strlen(var_name(var));
|
||||
int vlen = strlen(var_val(var));
|
||||
|
||||
if (ofs + nlen + 1 + vlen + 2 >= env_size) {
|
||||
printf("no space left in environment\n");
|
||||
ret = -ENOSPC;
|
||||
goto err_out;
|
||||
}
|
||||
strcpy(env + ofs, var_name(var));
|
||||
ofs += nlen;
|
||||
*(env + ofs) = '=';
|
||||
ofs++;
|
||||
strcpy(env + ofs, var_val(var));
|
||||
ofs += vlen + 1;
|
||||
|
||||
var = var->next;
|
||||
}
|
||||
|
||||
*(ulong *)env = crc32(0, env + sizeof(ulong), env_size - sizeof(ulong));
|
||||
|
||||
ret = dev_erase(info.device, info.size, info.start);
|
||||
if (ret) {
|
||||
printf("unable to erase\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
ret = dev_write(info.device, env, info.size, info.start, 0);
|
||||
if (ret < 0) {
|
||||
printf("unable to write\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
free(env);
|
||||
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
if (env)
|
||||
free(env);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
|
@ -259,6 +134,7 @@ U_BOOT_CMD(
|
|||
" - print value of environment variable 'name'\n"
|
||||
);
|
||||
|
||||
#ifdef CONFIG_SIMPLE_PARSER
|
||||
int do_setenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
if (argc < 2) {
|
||||
|
@ -279,17 +155,5 @@ U_BOOT_CMD(
|
|||
"setenv name\n"
|
||||
" - delete environment variable 'name'\n"
|
||||
);
|
||||
|
||||
int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
printf ("Saving Environment to %s...\n", env_name_spec);
|
||||
|
||||
return saveenv();
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
saveenv, 1, 0, do_saveenv,
|
||||
"saveenv - save environment variables to persistent storage\n",
|
||||
NULL
|
||||
);
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue