diff --git a/env.c b/env.c index a396f67da..1a19ffb5e 100644 --- a/env.c +++ b/env.c @@ -148,19 +148,6 @@ static buffer_t export_buffer; */ static int has_changed = 1; -/** - Free hash key and hash value -*/ -static void clear_hash_entry( const void *key, const void *data ) -{ - var_entry_t *entry = (var_entry_t *)data; - if( entry->export ) - has_changed = 1; - - free( (void *)key ); - free( (void *)data ); -} - /** This stringbuffer is used to store the value of dynamically generated variables, such as history. @@ -178,6 +165,36 @@ static int get_names_show_exported; */ static int get_names_show_unexported; +/** + List of all locale variable names +*/ +static const wchar_t *locale_variable[] = +{ + L"LANG", + L"LC_ALL", + L"LC_COLLATE", + L"LC_CTYPE", + L"LC_MESSAGES", + L"LC_MONETARY", + L"LC_NUMERIC", + L"LC_TIME", + (void *)0 +} + ; + +/** + Free hash key and hash value +*/ +static void clear_hash_entry( const void *key, const void *data ) +{ + var_entry_t *entry = (var_entry_t *)data; + if( entry->export ) + has_changed = 1; + + free( (void *)key ); + free( (void *)data ); +} + /** When fishd isn't started, this function is provided to env_universal as a callback, it tries to start up fishd. It's @@ -189,7 +206,7 @@ static void start_fishd() { string_buffer_t cmd; struct passwd *pw; - + sb_init( &cmd ); pw = getpwuid(getuid()); @@ -220,15 +237,6 @@ static mode_t get_umask() return res; } -/** - List of all locale variable names -*/ -static const wchar_t *locale_variable[] = -{ - L"LANG", L"LC_ALL", L"LC_COLLATE", L"LC_CTYPE", L"LC_MESSAGES", L"LC_MONETARY", L"LC_NUMERIC", L"LC_TIME", (void *)0 -} - ; - /** Checks if the specified variable is a locale variable */ @@ -256,7 +264,14 @@ static void handle_locale() */ static const int cat[] = { - 0, LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME + 0, + LC_ALL, + LC_COLLATE, + LC_CTYPE, + LC_MESSAGES, + LC_MONETARY, + LC_NUMERIC, + LC_TIME } ; @@ -286,9 +301,9 @@ static void handle_locale() /* Try to make change known to gettext. */ #ifdef HAVE__NL_MSG_CAT_CNTR { - extern int _nl_msg_cat_cntr; + extern int _nl_msg_cat_cntr; ++_nl_msg_cat_cntr; - } + } #elif HAVE_DCGETTEXT dcgettext("fish","",LC_MESSAGES); #endif @@ -349,22 +364,99 @@ static void universal_callback( int type, } } +/** + Make sure the PATH variable contains the essaential directories +*/ +static void setup_path() +{ + wchar_t *path; + + int i, j; + array_list_t l; + + const wchar_t *path_el[] = + { + L"/bin", + L"/usr/bin", + PREFIX L"/bin", + 0 + } + ; + + path = env_get( L"PATH" ); + if( !path ) + { + env_set( L"PATH", 0, ENV_EXPORT | ENV_GLOBAL | ENV_USER ); + path=0; + } + + al_init( &l ); + + if( path ) + expand_variable_array( path, &l ); + + for( j=0; path_el[j]; j++ ) + { + int has_el=0; + + for( i=0; i 0) && (el[len-1]==L'/') ) + len--; + if( (wcslen( path_el[j] ) == len) && (wcsncmp( el, path_el[j], len)==0) ) + { + has_el = 1; + } + } + + if( !has_el ) + { + string_buffer_t b; + + debug( 3, L"directory %ls was missing", path_el[j] ); + + sb_init( &b ); + if( path ) + { + sb_append( &b, path ); + } + + sb_append2( &b, + ARRAY_SEP_STR, + path_el[j], + (void *)0 ); + + env_set( L"PATH", (wchar_t *)b.buff, ENV_GLOBAL | ENV_EXPORT ); + + sb_destroy( &b ); + + al_foreach( &l, &free ); + path = env_get( L"PATH" ); + al_truncate( &l, 0 ); + expand_variable_array( path, &l ); + } + } + + al_foreach( &l, (void (*)(const void *))&free ); + al_destroy( &l ); +} + void env_init() { char **p; struct passwd *pw; - wchar_t *uname, *path; + wchar_t *uname; sb_init( &dyn_var ); - b_init( &export_buffer ); - /* These variables can not be altered directly by the user */ hash_init( &env_read_only, &hash_wcs_func, &hash_wcs_cmp ); - + hash_put( &env_read_only, L"status", L"" ); hash_put( &env_read_only, L"history", L"" ); hash_put( &env_read_only, L"_", L"" ); @@ -397,6 +489,11 @@ void env_init() hash_init( &top->env, &hash_wcs_func, &hash_wcs_cmp ); global_env = top; global = &top->env; + + /* + Now the environemnt variable handling is set up, the next step + is to insert valid data + */ /* Import environment variables @@ -434,77 +531,14 @@ void env_init() free(key); } - path = env_get( L"PATH" ); - if( !path ) - { - env_set( L"PATH", L"/bin" ARRAY_SEP_STR L"/usr/bin", ENV_EXPORT | ENV_GLOBAL ); - path = env_get( L"PATH" ); - } - else - { - int i, j; - array_list_t l; - - al_init( &l ); - expand_variable_array( path, &l ); + /* + Set up the PATH variable + */ + setup_path(); - debug( 3, L"PATH is %ls", path ); - - - const wchar_t *path_el[] = - { - L"/bin", - L"/usr/bin", - PREFIX L"/bin", - 0 - } - ; - - for( j=0; path_el[j]; j++ ) - { - int has_el=0; - - debug( 3, L"Check directory %ls", path_el[j] ); - - - for( i=0; i 0) && (el[len-1]==L'/') ) - len--; - if( (wcslen( path_el[j] ) == len) && (wcsncmp( el, path_el[j], len)==0) ) - { - has_el = 1; - } - } - - if( !has_el ) - { - string_buffer_t b; - debug( 3, L"directory %ls was missing", path_el[j] ); - sb_init( &b ); - sb_append2( &b, path, - ARRAY_SEP_STR, - path_el[j], - (void *)0 ); - - env_set( L"PATH", (wchar_t *)b.buff, ENV_GLOBAL | ENV_EXPORT ); - sb_destroy( &b ); - path = env_get( L"PATH" ); - - } - } - - debug( 3, L"After: PATH is %ls", path ); - - al_foreach( &l, (void (*)(const void *))&free ); - al_destroy( &l ); - - } - - - + /* + Set up the USER variable + */ pw = getpwuid( getuid() ); if( pw ) { @@ -775,8 +809,6 @@ void env_set( const wchar_t *key, } - - /** Attempt to remove/free the specified key/value pair from the specified hash table. @@ -1048,7 +1080,9 @@ static void add_key_to_hash( const void *key, var_entry_t *e = (var_entry_t *)data; if( ( e->export && get_names_show_exported) || ( !e->export && get_names_show_unexported) ) + { hash_put( (hash_table_t *)aux, key, 0 ); + } } /** diff --git a/init/fish.in b/init/fish.in index 0c1844ece..0b2302ea7 100644 --- a/init/fish.in +++ b/init/fish.in @@ -17,6 +17,7 @@ set -g IFS \ \t\n set -l path_list /bin /usr/bin /usr/X11R6/bin @PREFIX@/bin +# Root should also have the sbin directories in the path set -l uid (id -u 2>/dev/null) if test "$uid" = 0 set path_list $path_list /sbin /usr/sbin /usr/local/sbin