int ModuleCmd_Switch( Tcl_Interp *interp, int argc, char *argv[]) { char *oldmodule, *newmodule, *realname, *oldfile, *newfile, *oldname, *newname, *oldmodule_buffer = (char *) NULL; int ret_val = TCL_OK; /** ** allocate buffer memory **/ if (!(oldfile = stringer(NULL, MOD_BUFSIZE, NULL))) if( OK != ErrorLogger( ERR_STRING, LOC, NULL)) goto unwind0; if (!(newfile = stringer(NULL, MOD_BUFSIZE, NULL))) if( OK != ErrorLogger( ERR_STRING, LOC, NULL)) goto unwind1; if (!(oldname = stringer(NULL, MOD_BUFSIZE, NULL))) if( OK != ErrorLogger( ERR_STRING, LOC, NULL)) goto unwind2; if (!(newname = stringer(NULL, MOD_BUFSIZE, NULL))) if( OK != ErrorLogger( ERR_STRING, LOC, NULL)) goto unwind3; /** ** Parameter check. the required syntax is: ** module switch [ <old> ] <new> ** If <old> is not specified, then the pathname of <new> is assumed. **/ if( argc == 1) { newmodule = argv[0]; if(!(oldmodule_buffer = stringer(NULL,0,newmodule,NULL))) if( OK != ErrorLogger( ERR_STRING, LOC, NULL)) goto unwind4; /* starting from the end of the module name, find the first * forward slash and replace with null */ if ((oldmodule = strrchr(oldmodule_buffer, *psep))) { *oldmodule = 0; } oldmodule = oldmodule_buffer; } else if( argc == 2) { oldmodule = argv[0]; newmodule = argv[1]; } else { if( OK != ErrorLogger( ERR_USAGE, LOC, "switch oldmodule newmodule", NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ } /** ** Set the name of the module specified on the command line **/ g_specified_module = oldmodule; /** ** First try to find a match for the modulefile out of the LOADEDMODULES. **/ if( !IsLoaded( interp, oldmodule, &realname, oldfile)) if( OK != ErrorLogger( ERR_NOTLOADED, LOC, oldmodule, NULL)) goto unwind4; /** ** If we have another name to try, try finding it on disk. **/ if( realname) ret_val = Locate_ModuleFile( interp, realname, oldname, oldfile); /** ** If we've made it this far without finding a file, then look using the ** exact name the user gave me -- i.e. the old method. **/ if( ret_val == TCL_ERROR) { if( TCL_ERROR == (ret_val = Locate_ModuleFile( interp, oldmodule, oldname, oldfile))) if( OK != ErrorLogger( ERR_LOCATE, LOC, oldmodule, NULL)) goto unwind4; /** ** OK, this one is known. Is it loaded, too? **/ if( !IsLoaded( interp, oldname, NULL, oldfile)) if( OK != ErrorLogger( ERR_NOTLOADED, LOC, oldmodule, NULL)) goto unwind4; } /** ** Set the name of the module specified on the command line **/ g_specified_module = newmodule; /** ** Now try to find the new file to swap with. **/ if( TCL_ERROR == (ret_val = Locate_ModuleFile( interp, newmodule, newname, newfile))) if( OK != ErrorLogger( ERR_LOCATE, LOC, newmodule, NULL)) goto unwind4; ErrorLogger( NO_ERR_VERBOSE, LOC, "Switching '$1' to '$2'", oldmodule, newmodule, NULL); /** ** We'll remove the current modulefile with the SWITCH1 state set. ** This means that instead of really removing the paths, markers will ** be put in its place for later use. **/ g_flags |= (M_REMOVE | M_SWSTATE1); g_specified_module = oldmodule; g_current_module = oldname; if( Read_Modulefile( interp, oldfile) == 0) Update_LoadedList( interp, oldname, oldfile); else { ErrorLogger( NO_ERR_VERBOSE, LOC, "failed", NULL); goto unwind4; } g_flags &= ~(M_REMOVE | M_SWSTATE1); /** ** Move on to state SWITCH2. This loads the modulefile at the append ** and prepend markers. **/ g_flags |= M_SWSTATE2; g_specified_module = newmodule; g_current_module = newname; if( Read_Modulefile( interp, newfile) == 0) Update_LoadedList( interp, newname, newfile); else { ErrorLogger( NO_ERR_VERBOSE, LOC, "failed", NULL); goto unwind4; } g_flags &= ~M_SWSTATE2; /** ** This actually unsets environment variables and gets rid of the ** markers. **/ g_flags |= (M_REMOVE | M_SWSTATE3); g_specified_module = oldmodule; g_current_module = oldname; if( Read_Modulefile( interp, oldfile) == 0) Update_LoadedList( interp, newname, newfile); else { ErrorLogger( NO_ERR_VERBOSE, LOC, "failed", NULL); goto unwind4; } /** ** Return on success **/ ErrorLogger( NO_ERR_VERBOSE, LOC, "done", NULL); /** ** free space ** assume don't need what's pointed to by g_current_module ** and g_specified_module **/ null_free((void *) &newname); null_free((void *) &oldname); null_free((void *) &newfile); null_free((void *) &oldfile); return( TCL_OK); /** ------- EXIT (SUCCESS) --------> **/ unwind4: if (oldmodule == oldmodule_buffer) null_free((void *) &oldmodule); null_free((void *) &newname); unwind3: null_free((void *) &oldname); unwind2: null_free((void *) &newfile); unwind1: null_free((void *) &oldfile); unwind0: return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ } /** End of 'ModuleCmd_Switch' **/
int CallModuleProcedure( Tcl_Interp *interp, Tcl_DString *cmdptr, char *modulefile, char *procname, int suppress_output) { char cmdline[ LINELENGTH]; char *cmd; int result; int saved_stdout = 0, saved_stderr = 0, devnull; #if WITH_DEBUGGING_UTIL_1 ErrorLogger( NO_ERR_START, LOC, _proc_CallModuleProcedure, NULL); #endif /** ** Must send stdout and stderr to /dev/null until the ** ModulesHelp procedure is called. **/ if( suppress_output) { if( 0 > (devnull = open( _fil_devnull, O_RDWR))) { if( OK != ErrorLogger( ERR_OPEN, LOC, _fil_devnull, "changing", NULL)) return( TCL_ERROR); /** -------- EXIT (FAILURE) -------> **/ } /** ** Close STDOUT and reopen it as /dev/null **/ if( -1 == ( saved_stdout = dup( 1))) if( OK != ErrorLogger( ERR_DUP, LOC, _fil_stdout, NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ if( -1 == close( 1)) if( OK != ErrorLogger( ERR_CLOSE, LOC, _fil_stdout, NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ if( -1 == dup( devnull)) if( OK != ErrorLogger( ERR_DUP, LOC, _fil_devnull, NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ /** ** Close STDERR and reopen it as /dev/null **/ if( -1 == ( saved_stdout = dup( 2))) if( OK != ErrorLogger( ERR_DUP, LOC, _fil_stderr, NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ if( -1 == close( 2)) if( OK != ErrorLogger( ERR_CLOSE, LOC, _fil_stderr, NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ if( -1 == dup( devnull)) if( OK != ErrorLogger( ERR_DUP, LOC, _fil_devnull, NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ } /** ** Read the passed module file **/ Read_Modulefile( interp, modulefile); /** ** Reinstall stdout and stderr **/ if( suppress_output) { /** ** Reinstall STDOUT **/ if( EOF == fflush( stdout)) if( OK != ErrorLogger( ERR_FLUSH, LOC, _fil_stdout, NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ if( EOF == fflush( stderr)) if( OK != ErrorLogger( ERR_FLUSH, LOC, _fil_stderr, NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ if( -1 == close( 1)) if( OK != ErrorLogger( ERR_CLOSE, LOC, _fil_stdout, NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ /** ** Reinstall STDERR **/ if( -1 == dup( saved_stdout)) if( OK != ErrorLogger( ERR_DUP, LOC, _fil_stdout, NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ if( -1 == close( 2)) if( OK != ErrorLogger( ERR_CLOSE, LOC, _fil_stderr, NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ if( -1 == dup( saved_stderr)) if( OK != ErrorLogger( ERR_DUP, LOC, _fil_stderr, NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ } /** ** Now evaluate the Tcl Procedure **/ /* sprintf( cmdline, "%s\n", procname); */ strcpy( cmdline, procname); strcat( cmdline, "\n"); cmd = Tcl_DStringAppend( cmdptr, cmdline, (-1)); result = Tcl_Eval( interp, cmd); Tcl_DStringTrunc( cmdptr, 0); #if WITH_DEBUGGING_UTIL_1 ErrorLogger( NO_ERR_END, LOC, _proc_CallModuleProcedure, NULL); #endif return( result); } /** End of 'CallModuleProcedure' **/