Esempio n. 1
0
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' **/