/***** ** ** Module Header ******************************************************* ** ** ** ** Modules Revision 3.0 ** ** Providing a flexible user environment ** ** ** ** File: cmdSetenv.c ** ** First Edition: 1991/10/23 ** ** ** ** Authors: John Furlan, jlf@behere.com ** ** Jens Hamisch, jens@Strawberry.COM ** ** ** ** Description: The routines for setting and unsetting environment ** ** variables from within modulefiles. ** ** ** ** Exports: cmdSetEnv ** ** cmdUnsetEnv ** ** moduleSetenv ** ** moduleUnsetenv ** ** ** ** Notes: ** ** ** ** ************************************************************************ ** ****/ /** ** Copyright *********************************************************** ** ** ** ** Copyright 1991-1994 by John L. Furlan. ** ** see LICENSE.GPL, which must be provided, for details ** ** ** ** ************************************************************************ **/ static char Id[] = "@(#)$Id: c7add002bfd4245181fa551c05d0426cd79abc76 $"; static void *UseId[] = { &UseId, Id }; /** ************************************************************************ **/ /** HEADERS **/ /** ************************************************************************ **/ #include "modules_def.h" /** ************************************************************************ **/ /** LOCAL DATATYPES **/ /** ************************************************************************ **/ /** not applicable **/ /** ************************************************************************ **/ /** CONSTANTS **/ /** ************************************************************************ **/ /** not applicable **/ /** ************************************************************************ **/ /** MACROS **/ /** ************************************************************************ **/ /** not applicable **/ /** ************************************************************************ **/ /** LOCAL DATA **/ /** ************************************************************************ **/ static char module_name[] = "cmdSetenv.c"; /** File name of this module **/ #if WITH_DEBUGGING_CALLBACK static char _proc_cmdSetEnv[] = "cmdSetEnv"; static char _proc_cmdUnsetEnv[] = "cmdUnsetEnv"; #endif #if WITH_DEBUGGING_UTIL_1 static char _proc_moduleSetenv[] = "moduleSetenv"; static char _proc_moduleUnsetenv[] = "moduleUnsetenv"; #endif /** ************************************************************************ **/ /** PROTOTYPES **/ /** ************************************************************************ **/ /** not applicable **/ /*++++ ** ** Function-Header ***************************************************** ** ** ** ** Function: cmdSetEnv ** ** ** ** Description: Callback function for the 'setenv' command ** ** ** ** First Edition: 1991/10/23 ** ** ** ** Parameters: ClientData client_data ** ** Tcl_Interp *interp According Tcl interp.** ** int argc Number of arguments ** ** char *argv[] Argument array ** ** ** ** Result: int TCL_OK Successful completion ** ** TCL_ERROR Any error ** ** ** ** Attached Globals: g_flags These are set up accordingly before ** ** this function is called in order to ** ** control everything ** ** ** ** ************************************************************************ ** ++++*/ int cmdSetEnv( ClientData client_data, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { int force; /** Force removale of variables **/ char *var; /** Varibales name **/ char *val; /** Varibales value **/ #if WITH_DEBUGGING_CALLBACK ErrorLogger( NO_ERR_START, LOC, _proc_cmdSetEnv, NULL); #endif /** ** Check parameters. Usage is: [-force] variable value **/ if( argc < 3 || argc > 4) { if( OK != ErrorLogger( ERR_USAGE, LOC, argv[0], "[-force] variable value", NULL)) return( TCL_ERROR); /** -------- EXIT (FAILURE) -------> **/ } /** ** Get variables name and value from the argument array **/ if( *argv[1] == '-') { if( !strncmp( argv[1], "-force", 6)) { force = 1; var = (char *) argv[2]; val = (char *) argv[3]; } else { if( OK != ErrorLogger( ERR_USAGE, LOC, argv[0], "[-force] variable value", NULL)) return( TCL_ERROR); /** -------- EXIT (FAILURE) -------> **/ } } else { force = 0; var = (char *) argv[1]; val = (char *) argv[2]; } moduleSetenv( interp, var, val, force); /** ** This has to be done after everything has been set because the ** variables may be needed later in the modulefile. **/ if( g_flags & M_DISPLAY) { fprintf( stderr, "%s\t\t ", argv[ 0]); while( --argc) fprintf( stderr, "%s ", *++argv); fprintf( stderr, "\n"); } #if WITH_DEBUGGING_CALLBACK ErrorLogger( NO_ERR_END, LOC, _proc_cmdSetEnv, NULL); #endif return( TCL_OK); } /** End of 'cmdSetEnv' **/ /*++++ ** ** Function-Header ***************************************************** ** ** ** ** Function: moduleSetenv ** ** ** ** Description: Set or unset environment variables ** ** ** ** First Edition: 1991/10/23 ** ** ** ** Parameters: Tcl_Interp *interp According Tcl interp.** ** char *variable Name of the variable ** ** char *value Value to be set ** ** int force Force removal ** ** ** ** Result: int TCL_OK Successful completion ** ** TCL_ERROR Any error ** ** ** ** Attached Globals: g_flags These are set up accordingly before ** ** this function is called in order to ** ** control everything ** ** ** ** ************************************************************************ ** ++++*/ int moduleSetenv( Tcl_Interp *interp, char *variable, char *value, int force) { char *oldval; /** Old value of 'variable' **/ #if WITH_DEBUGGING_UTIL_1 ErrorLogger( NO_ERR_START, LOC, _proc_moduleSetenv, NULL); #endif oldval = EMGetEnv( interp, variable); if (!oldval || !*oldval) null_free((void *)&oldval); /** ** Check to see if variable is already set correctly... **/ if( !(g_flags & (M_REMOVE|M_DISPLAY|M_SWITCH|M_NONPERSIST)) && oldval) { if( !strcmp( value, oldval)) { return( TCL_OK); /** -------- EXIT (SUCCESS) -------> **/ } } /** ** If I'm in SWSTATE1, I'm removing stuff from the old modulefile, so ** I'll just mark the variables that were used with the SWSTATE1 flag and ** return. ** ** When I come back through in SWSTATE2, I'm setting the variables that ** are in the new modulefile. So, I'll keep track of these by marking ** them as touched by SWSTATE2 and then actually setting their values in ** the environment down below. ** ** Finally, in SWSTATE3, I'll check to see if the variables in the old ** modulefiles that have been marked are still marked as SWSTATE1. If ** they are still the same, then I'll just unset them and return. ** ** And, if I'm not doing any switching, then just unset the variable if ** I'm in remove mode. **/ if( g_flags & M_SWSTATE1) { set_marked_entry( markVariableHashTable, variable, M_SWSTATE1); return( TCL_OK); /** -------- EXIT (SUCCESS) -------> **/ } else if( g_flags & M_SWSTATE2) { set_marked_entry( markVariableHashTable, variable, M_SWSTATE2); } else if( g_flags & M_SWSTATE3) { intptr_t marked_val; marked_val = chk_marked_entry( markVariableHashTable, variable); if( marked_val) { if( marked_val == M_SWSTATE1) return( moduleUnsetenv(interp, variable)); /** -------> **/ else return( TCL_OK); /** -------- EXIT (SUCCESS) -------> **/ } } else if( (g_flags & M_REMOVE) && !force) { return( moduleUnsetenv( interp, variable)); /** -------> **/ } /** ** Keep track of our changes just in case we have to bail out and restore ** the environment. **/ if( !(g_flags & (M_NONPERSIST | M_DISPLAY | M_WHATIS | M_HELP))) { store_hash_value( setenvHashTable, variable, value); clear_hash_value( unsetenvHashTable, variable); } /** ** Store the value into the environment **/ EMSetEnv( interp, variable, value); #if WITH_DEBUGGING_UTIL_1 ErrorLogger( NO_ERR_END, LOC, _proc_moduleSetenv, NULL); #endif return( TCL_OK); } /** End of 'moduleSetenv' **/ /*++++ ** ** Function-Header ***************************************************** ** ** ** ** Function: cmdUnsetEnv ** ** ** ** Description: Callback function for the 'unset' command ** ** ** ** First Edition: 1991/10/23 ** ** ** ** Parameters: ClientData client_data ** ** Tcl_Interp *interp According Tcl interp.** ** int argc Number of arguments ** ** char *argv[] Argument array ** ** ** ** Result: int TCL_OK Successful completion ** ** TCL_ERROR Any error ** ** ** ** Attached Globals: g_flags These are set up accordingly before ** ** this function is called in order to ** ** control everything ** ** ** ** ************************************************************************ ** ++++*/ int cmdUnsetEnv( ClientData client_data, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { /** ** Parameter check. The name of the variable has to be specified **/ #if WITH_DEBUGGING_CALLBACK ErrorLogger( NO_ERR_START, LOC, _proc_cmdUnsetEnv, NULL); #endif if( argc < 2 || argc > 3) { if( OK != ErrorLogger( ERR_USAGE, LOC, argv[0], "variable [value]", NULL)) return( TCL_ERROR); /** -------- EXIT (FAILURE) -------> **/ } /** ** Non-persist mode? **/ if (g_flags & M_NONPERSIST) { return (TCL_OK); } /** ** Unset the variable or just display what to do ... **/ if( g_flags & M_DISPLAY) { fprintf( stderr, "%s\t ", argv[ 0]); while( --argc) fprintf( stderr, "%s ", *++argv); fprintf( stderr, "\n"); } else if( g_flags & M_REMOVE && argc == 3) { int save_flags = g_flags; /** allow an optional 3rd argument to set the env.var. to on removal **/ g_flags = (g_flags & ~M_REMOVE) | M_LOAD; moduleSetenv( interp, (char *) argv[1], (char *) argv[2], 0); g_flags = save_flags; } else { moduleUnsetenv( interp, (char *) argv[1]); } /** ** Return on success **/ #if WITH_DEBUGGING_CALLBACK ErrorLogger( NO_ERR_END, LOC, _proc_cmdUnsetEnv, NULL); #endif return( TCL_OK); } /** End of 'cmdUnsetEnv' **/ /*++++ ** ** Function-Header ***************************************************** ** ** ** ** Function: moduleUnsetenv ** ** ** ** Description: Unset environment variables ** ** ** ** First Edition: 1991/10/23 ** ** ** ** Parameters: Tcl_Interp *interp According Tcl interp.** ** char *variable Name of the variable ** ** ** ** Result: int TCL_OK Successful completion ** ** TCL_ERROR Any error ** ** ** ** Attached Globals: g_flags These are set up accordingly before ** ** this function is called in order to ** ** control everything ** ** ** ** ************************************************************************ ** ++++*/ int moduleUnsetenv( Tcl_Interp *interp, char *variable) { #if WITH_DEBUGGING_UTIL_1 ErrorLogger( NO_ERR_START, LOC, _proc_moduleUnsetenv, NULL); #endif /** ** Don't unset the variable in Tcl Space. ** If module writer *REALLY* wants it gone, use $env **/ if( !(g_flags & (M_NONPERSIST | M_DISPLAY | M_WHATIS | M_HELP))) { store_hash_value( unsetenvHashTable, variable, NULL); clear_hash_value( setenvHashTable, variable); } #if WITH_DEBUGGING_UTIL_1 ErrorLogger( NO_ERR_END, LOC, _proc_moduleUnsetenv, NULL); #endif return( TCL_OK); } /** end of 'moduleUnsetenv' **/