@ -45,8 +45,7 @@
# include "fw_env.h"
# define CMD_GETENV "fw_printenv"
# define CMD_SETENV "fw_setenv"
# define WHITESPACE(c) ((c == '\t') || (c == ' '))
# define min(x, y) ({ \
typeof ( x ) _min1 = ( x ) ; \
@ -210,7 +209,6 @@ static char default_environment[] = {
static int flash_io ( int mode ) ;
static char * envmatch ( char * s1 , char * s2 ) ;
static int env_init ( void ) ;
static int parse_config ( void ) ;
# if defined(CONFIG_FILE)
@ -225,6 +223,22 @@ static inline ulong getenvsize (void)
return rc ;
}
static char * fw_string_blank ( char * s , int noblank )
{
int i ;
int len = strlen ( s ) ;
for ( i = 0 ; i < len ; i + + , s + + ) {
if ( ( noblank & & ! WHITESPACE ( * s ) ) | |
( ! noblank & & WHITESPACE ( * s ) ) )
break ;
}
if ( i = = len )
return NULL ;
return s ;
}
/*
* Search the environment for a variable .
* Return the value , if found , or NULL , if not found .
@ -233,7 +247,7 @@ char *fw_getenv (char *name)
{
char * env , * nxt ;
if ( env_init ( ) )
if ( fw_env_open ( ) )
return NULL ;
for ( env = environment . data ; * env ; env = nxt + 1 ) {
@ -264,7 +278,7 @@ int fw_printenv (int argc, char *argv[])
int i , n_flag ;
int rc = 0 ;
if ( env_init ( ) )
if ( fw_env_open ( ) )
return - 1 ;
if ( argc = = 1 ) { /* Print all env variables */
@ -327,30 +341,34 @@ int fw_printenv (int argc, char *argv[])
return rc ;
}
/*
* Deletes or sets environment variables . Returns - 1 and sets errno error codes :
* 0 - OK
* EINVAL - need at least 1 argument
* EROFS - certain variables ( " ethaddr " , " serial# " ) cannot be
* modified or deleted
*
*/
int fw_setenv ( int argc , char * argv [ ] )
int fw_env_close ( void )
{
int i , len ;
char * env , * nxt ;
char * oldval = NULL ;
char * name ;
/*
* Update CRC
*/
* environment . crc = crc32 ( 0 , ( uint8_t * ) environment . data , ENV_SIZE ) ;
if ( argc < 2 ) {
errno = EINVAL ;
return - 1 ;
/* write environment back to flash */
if ( flash_io ( O_RDWR ) ) {
fprintf ( stderr ,
" Error: can't write fw_env to flash \n " ) ;
return - 1 ;
}
if ( env_init ( ) )
return - 1 ;
return 0 ;
}
name = argv [ 1 ] ;
/*
* Set / Clear a single variable in the environment .
* This is called in sequence to update the environment
* in RAM without updating the copy in flash after each set
*/
int fw_env_write ( char * name , char * value )
{
int len ;
char * env , * nxt ;
char * oldval = NULL ;
/*
* search if variable with this name already exists
@ -358,7 +376,7 @@ int fw_setenv (int argc, char *argv[])
for ( nxt = env = environment . data ; * env ; env = nxt + 1 ) {
for ( nxt = env ; * nxt ; + + nxt ) {
if ( nxt > = & environment . data [ ENV_SIZE ] ) {
fprintf ( stderr , " ## Error: "
fprintf ( stderr , " ## Error: "
" environment not terminated \n " ) ;
errno = EINVAL ;
return - 1 ;
@ -396,8 +414,8 @@ int fw_setenv (int argc, char *argv[])
}
/* Delete only ? */
if ( argc < 3 )
goto WRITE_FLASH ;
if ( ! value | | ! strlen ( value ) )
return 0 ;
/*
* Append new definition at the end
@ -411,41 +429,202 @@ int fw_setenv (int argc, char *argv[])
*/
len = strlen ( name ) + 2 ;
/* add '=' for first arg, ' ' for all others */
for ( i = 2 ; i < argc ; + + i ) {
len + = strlen ( argv [ i ] ) + 1 ;
}
len + = strlen ( value ) + 1 ;
if ( len > ( & environment . data [ ENV_SIZE ] - env ) ) {
fprintf ( stderr ,
" Error: environment overflow, \" %s \" deleted \n " ,
name ) ;
return - 1 ;
}
while ( ( * env = * name + + ) ! = ' \0 ' )
env + + ;
* env = ' = ' ;
while ( ( * + + env = * value + + ) ! = ' \0 ' )
;
/* end is marked with double '\0' */
* + + env = ' \0 ' ;
return 0 ;
}
/*
* Deletes or sets environment variables . Returns - 1 and sets errno error codes :
* 0 - OK
* EINVAL - need at least 1 argument
* EROFS - certain variables ( " ethaddr " , " serial# " ) cannot be
* modified or deleted
*
*/
int fw_setenv ( int argc , char * argv [ ] )
{
int i , len ;
char * name ;
char * value = NULL ;
char * tmpval = NULL ;
if ( argc < 2 ) {
errno = EINVAL ;
return - 1 ;
}
if ( fw_env_open ( ) ) {
fprintf ( stderr , " Error: environment not initialized \n " ) ;
return - 1 ;
}
name = argv [ 1 ] ;
len = strlen ( name ) + 2 ;
for ( i = 2 ; i < argc ; + + i )
len + = strlen ( argv [ i ] ) + 1 ;
/* Allocate enough place to the data string */
for ( i = 2 ; i < argc ; + + i ) {
char * val = argv [ i ] ;
* env = ( i = = 2 ) ? ' = ' : ' ' ;
while ( ( * + + env = * val + + ) ! = ' \0 ' ) ;
if ( ! value ) {
value = ( char * ) malloc ( len - strlen ( name ) ) ;
if ( ! value ) {
fprintf ( stderr ,
" Cannot malloc %u bytes: %s \n " ,
len - strlen ( name ) , strerror ( errno ) ) ;
return - 1 ;
}
memset ( value , 0 , len - strlen ( name ) ) ;
tmpval = value ;
}
if ( i ! = 2 )
* tmpval + + = ' ' ;
while ( * val ! = ' \0 ' )
* tmpval + + = * val + + ;
}
/* end is marked with double '\0' */
* + + env = ' \0 ' ;
fw_env_write ( name , value ) ;
WRITE_FLASH :
if ( value )
free ( value ) ;
/*
* Update CRC
*/
* environment . crc = crc32 ( 0 , ( uint8_t * ) environment . data , ENV_SIZE ) ;
return fw_env_close ( ) ;
}
/* write environment back to flash */
if ( flash_io ( O_RDWR ) ) {
fprintf ( stderr , " Error: can't write fw_env to flash \n " ) ;
/*
* Parse a file and configure the u - boot variables .
* The script file has a very simple format , as follows :
*
* Each line has a couple with name , value :
* < white spaces > variable_name < white spaces > variable_value
*
* Both variable_name and variable_value are interpreted as strings .
* Any character after < white spaces > and before ending \ r \ n is interpreted
* as variable ' s value ( no comment allowed on these lines ! )
*
* Comments are allowed if the first character in the line is #
*
* Returns - 1 and sets errno error codes :
* 0 - OK
* - 1 - Error
*/
int fw_parse_script ( char * fname )
{
FILE * fp ;
char dump [ 1024 ] ; /* Maximum line length in the file */
char * name ;
char * val ;
int lineno = 0 ;
int len ;
int ret = 0 ;
if ( fw_env_open ( ) ) {
fprintf ( stderr , " Error: environment not initialized \n " ) ;
return - 1 ;
}
return 0 ;
if ( strcmp ( fname , " - " ) = = 0 )
fp = stdin ;
else {
fp = fopen ( fname , " r " ) ;
if ( fp = = NULL ) {
fprintf ( stderr , " I cannot open %s for reading \n " ,
fname ) ;
return - 1 ;
}
}
while ( fgets ( dump , sizeof ( dump ) , fp ) ) {
lineno + + ;
len = strlen ( dump ) ;
/*
* Read a whole line from the file . If the line is too long
* or is not terminated , reports an error and exit .
*/
if ( dump [ len - 1 ] ! = ' \n ' ) {
fprintf ( stderr ,
" Line %d not corrected terminated or too long \n " ,
lineno ) ;
ret = - 1 ;
break ;
}
/* Drop ending line feed / carriage return */
while ( len > 0 & & ( dump [ len - 1 ] = = ' \n ' | |
dump [ len - 1 ] = = ' \r ' ) ) {
dump [ len - 1 ] = ' \0 ' ;
len - - ;
}
/* Skip comment or empty lines */
if ( ( len = = 0 ) | | dump [ 0 ] = = ' # ' )
continue ;
/*
* Search for variable ' s name ,
* remove leading whitespaces
*/
name = fw_string_blank ( dump , 1 ) ;
if ( ! name )
continue ;
/* The first white space is the end of variable name */
val = fw_string_blank ( name , 0 ) ;
len = strlen ( name ) ;
if ( val ) {
* val + + = ' \0 ' ;
if ( ( val - name ) < len )
val = fw_string_blank ( val , 1 ) ;
else
val = NULL ;
}
# ifdef DEBUG
fprintf ( stderr , " Setting %s : %s \n " ,
name , val ? val : " removed " ) ;
# endif
/*
* If there is an error setting a variable ,
* try to save the environment and returns an error
*/
if ( fw_env_write ( name , val ) ) {
fprintf ( stderr ,
" fw_env_write returns with error : %s \n " ,
strerror ( errno ) ) ;
ret = - 1 ;
break ;
}
}
/* Close file if not stdin */
if ( strcmp ( fname , " - " ) ! = 0 )
fclose ( fp ) ;
ret | = fw_env_close ( ) ;
return ret ;
}
/*
@ -880,7 +1059,7 @@ static char *envmatch (char * s1, char * s2)
/*
* Prevent confusion if running from erased flash memory
*/
static int env_init ( void )
int fw_env_open ( void )
{
int crc0 , crc0_ok ;
char flag0 ;