1    | /*****
2    |  ** ** Module Header ******************************************************* **
3    |  ** 									     **
4    |  **   Modules Revision 3.0						     **
5    |  **   Providing a flexible user environment				     **
6    |  ** 									     **
7    |  **   File:		ModuleCmd_Update.c				     **
8    |  **   First Edition:	1991/10/23					     **
9    |  ** 									     **
10   |  **   Authors:	John Furlan, jlf@behere.com				     **
11   |  **		Jens Hamisch, jens@Strawberry.COM			     **
12   |  ** 									     **
13   |  **   Description: 	Uses the beginning environment stored the first time **
14   |  **			each login session to reload all of the currently    **
15   |  ** 									     **
16   |  **   Notes:								     **
17   |  ** 									     **
18   |  ** ************************************************************************ **
19   |  ****/
20   | 
21   | /** ** Copyright *********************************************************** **
22   |  ** 									     **
23   |  ** Copyright 1991-1994 by John L. Furlan.                      	     **
24   |  ** see LICENSE.GPL, which must be provided, for details		     **
25   |  ** 									     ** 
26   |  ** ************************************************************************ **/
27   | 
28   | static char Id[] = "@(#)$Id: ModuleCmd_Update.c.src.html,v 1.1 2005/11/15 03:43:35 rkowen Exp $";
29   | static void *UseId[] = { &UseId, Id };
30   | 
31   | /** ************************************************************************ **/
32   | /** 				      HEADERS				     **/
33   | /** ************************************************************************ **/
34   | 
35   | #include "modules_def.h"
36   | 
37   | /** ************************************************************************ **/
38   | /** 				  LOCAL DATATYPES			     **/
39   | /** ************************************************************************ **/
40   | 
41   | /** not applicable **/
42   | 
43   | /** ************************************************************************ **/
44   | /** 				     CONSTANTS				     **/
45   | /** ************************************************************************ **/
46   | 
47   | #define	UPD_BUFSIZE	1024
48   | 
49   | /** ************************************************************************ **/
50   | /**				      MACROS				     **/
51   | /** ************************************************************************ **/
52   | 
53   | /** not applicable **/
54   | 
55   | /** ************************************************************************ **/
56   | /** 				    LOCAL DATA				     **/
57   | /** ************************************************************************ **/
58   | 
59   | static	char	module_name[] = "ModuleCmd_Update.c";	/** File name of this module **/
60   | #if WITH_DEBUGGING_MODULECMD
61   | static	char	_proc_ModuleCmd_Update[] = "ModuleCmd_Update";
62   | #endif
63   | 
64   | /** ************************************************************************ **/
65   | /**				    PROTOTYPES				     **/
66   | /** ************************************************************************ **/
67   | 
68   | /** not applicable **/
69   | 
70   | 
71   | /*++++
72   |  ** ** Function-Header ***************************************************** **
73   |  ** 									     **
74   |  **   Function:		ModuleCmd_Update				     **
75   |  ** 									     **
76   |  **   Description:	Execution of the module-command 'update'	     **
77   |  ** 									     **
78   |  **   First Edition:	91/10/23					     **
79   |  ** 									     **
80   |  **   Parameters:	Tcl_Interp	*interp		Attached Tcl Interp. **
81   |  **			int		 argc		Number of arguments  **
82   |  **			char 		*argv[]		Argument list	     **
83   |  ** 									     **
84   |  **   Result:		int	TCL_ERROR	Failure			     **
85   |  **				TCL_OK		Successfull operation	     **
86   |  ** 									     **
87   |  **   Attached Globals:	flags		Controllig the callback functions    **
88   |  ** 									     **
89   |  ** ************************************************************************ **
90   |  ++++*/
91   | 
92   | int	ModuleCmd_Update(	Tcl_Interp	*interp,
93   |                  		int		 count,
94   |                  		char		*module_list[])
95   | {
96   | #ifdef  BEGINENV
97   |     char	 *buf,			/** Read buffer			     **/
98   | 		 *var_ptr,		/** Pointer to a variables name	     **/
99   | 		 *val_ptr,		/** Pointer to a variables value     **/
100  | 		**load_list,		/** List of loaded modules	     **/
101  | 		 *tmpload,		/** LOADEDMODULES contents	     **/
102  | 		 *loaded,		/** Buffer for tokenization	     **/
103  | 		 *filename;		/** The name of the file, where the  **/
104  | 					/** beginning environment resides    **/
105  |     FILE	 *file;			/** Handle to read in a file	     **/
106  |     int		  list_count = 0,
107  | 		  maxlist = 16,		/** Max. number of list entries	     **/
108  | 		  buffer_size = UPD_BUFSIZE;	
109  |     					/** Current size of the input buffer **/
110  |     char	 *ptr, c;		/** Read pointers and char buffer    **/
111  | 
112  | #if WITH_DEBUGGING_MODULECMD
113  |     ErrorLogger( NO_ERR_START, LOC, _proc_ModuleCmd_Update, NULL);
114  | #endif
115  | 
116  | #if BEGINENV == 99
117  |     	if (!Tcl_GetVar2( interp,"env","MODULESBEGINENV", TCL_GLOBAL_ONLY)) {
118  | 		ErrorLogger( ERR_BEGINENVX, LOC, NULL);
119  | 		return( TCL_ERROR);	/** -------- EXIT (FAILURE) -------> **/
120  | 	}
121  | #endif
122  |     /**
123  |      **  Nothing loaded so far - we're ready!
124  |      **/
125  | 
126  |     if( !( tmpload = (char *) getenv("LOADEDMODULES"))) {
127  | 	if( OK != ErrorLogger( ERR_MODULE_PATH, LOC, NULL))
128  | 	    goto unwind0;
129  | 	else
130  | 	    goto success0;
131  |     }
132  | 
133  |     /**
134  |      **  First I'll update the environment with what's in _MODULESBEGINENV_
135  |      **/
136  |     filename = Tcl_GetVar2( interp,"env","_MODULESBEGINENV_", TCL_GLOBAL_ONLY);
137  |     if( filename) {
138  | 
139  | 	/**
140  | 	 **  Read the beginning environment
141  | 	 **/
142  | 	if( NULL != (file = fopen( filename, "r"))) {
143  | 
144  | 	    if((char *) NULL == (buf = stringer(NULL, buffer_size, NULL )))
145  | 		if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
146  | 		    goto unwind0;
147  | 
148  | 	    while( !feof( file)) {
149  | 
150  | 		/**
151  | 		 **  Trigger to entries of the type
152  | 		 **    <variable> = <value>
153  | 		 **/
154  | 
155  | 		ptr = buf;
156  | 		while( !feof( file)) {
157  | 		    
158  | 		    if((ptr-buf) >= buffer_size-10) {	/** 10 bytes safety  **/
159  | 			null_free((void *) &buf);
160  | 			if((char *) NULL == (buf = stringer(NULL,
161  | 				buffer_size += UPD_BUFSIZE, NULL )))
162  | 			    if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
163  | 				goto unwind0;
164  | 		    }
165  | 
166  | 		    /**
167  | 		     **  Read a character and put it into the read buffer. Check
168  | 		     **  for the lines (CR) or a terminator character ...
169  | 		     **/
170  | 		    if( '\n' == (*ptr++ = c = fgetc( file))) {
171  | 			*ptr++ = c = '\0';
172  | 			break;
173  | 		    }
174  | 
175  | 		    if( !c)
176  | 			break;
177  | 
178  | 		} /** while **/
179  | 
180  | 		/**
181  | 		 **  If there hasn't been a terminator so far, put it at the
182  | 		 **  end of the line. Therefor we've left a safety space at the
183  | 		 **  buffers end ;-)
184  | 		 **/
185  | 		if( c)
186  | 		    *ptr++ = '\0';
187  | 		 
188  | 		/**
189  | 		 **  Now let's evaluate the read line
190  | 		 **/
191  | 		if( var_ptr = strchr( buf, '=')) {
192  | 		
193  | 		    *var_ptr = '\0';
194  | 		    val_ptr = var_ptr+1;
195  | 		    var_ptr = buf;
196  | 
197  | 		    /**
198  | 		     **  Reset the environment to the values derivered from the
199  | 		     **  _MODULESBEGINENV_.
200  | 		     **  Do not change the LOADEDMODULES variable ;-)
201  | 		     **  Do not change the TCL_LIBRARY and TK_LIBRARY also.
202  | 		     **/
203  | 		    if( strncmp( var_ptr, "LOADEDMODULES", 12) &&
204  | 			strncmp( var_ptr, "TCL_LIBRARY", 10 ) &&
205  | 			strncmp( var_ptr, "TK_LIBRARY", 9 ))
206  | 			if( !strncmp( var_ptr, "MODULEPATH", 10))
207  | 			    moduleSetenv( interp, var_ptr, val_ptr, 1);
208  | 			else
209  | 			    Tcl_SetVar2( interp, "env", var_ptr, val_ptr,
210  | 					 TCL_GLOBAL_ONLY);
211  | 		} /** if( var_ptr) **/
212  | 	    } /** while **/
213  | 
214  | 	    /**
215  | 	     **  Close the _MODULESBEGINENV_ file anf free up the read buffer.
216  | 	     **/
217  | 	    null_free((void *) &buf);
218  | 
219  | 	    if( EOF == fclose( file))
220  | 		if( OK != ErrorLogger( ERR_CLOSE, LOC, filename, NULL))
221  | 		    goto unwind0;
222  | 
223  | 	} else { /** if( fopen) **/
224  | 
225  | 	    if( OK != ErrorLogger( ERR_OPEN, LOC, filename, "reading", NULL))
226  | 		goto unwind0;
227  | 
228  | 	} /** if( fopen) **/
229  |     } /** if( filename) **/
230  | 
231  |     /**
232  |      **  Allocate memory for a buffer to tokenize the list of loaded modules
233  |      **  and a list buffer
234  |      **/
235  |     if( NULL == (load_list = (char**) malloc( maxlist*sizeof(char**))))
236  | 	if( OK != ErrorLogger( ERR_ALLOC, LOC, NULL))
237  | 	    goto unwind0;
238  |     
239  |     if( NULL == (loaded = stringer(NULL, 0, tmpload, NULL)))
240  | 	if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
241  | 	    goto unwind1;
242  |     
243  |     /**
244  |      **  Tokenize and build the list
245  |      **/
246  |     if( *loaded) {
247  | 
248  | 	for( load_list[ list_count++] = strtok( loaded, ":");
249  | 	     load_list[ list_count-1];
250  |              load_list[ list_count++] = strtok( NULL, ":") ) {
251  | 
252  | 	    /**
253  | 	     **  Conditionally we have to double the space, we've allocated for
254  | 	     **  the list
255  | 	     **/
256  | 
257  |             if( list_count >= maxlist) {
258  |                 maxlist = maxlist<<1;
259  |             
260  |                 if( NULL == (load_list = (char**) realloc((char *) load_list,
261  | 		    maxlist*sizeof(char**))))
262  | 		    if( OK != ErrorLogger( ERR_ALLOC, LOC, NULL))
263  | 			goto unwind1;
264  | 
265  |             } /** if( maxlist) **/
266  | 	} /** for **/
267  | 
268  | 	/**
269  | 	 **  Load all the modules in the list
270  | 	 **/
271  |         ModuleCmd_Load( interp, 1, list_count, load_list);
272  |     }
273  | 
274  |     /**
275  |      **  Free up what has been allocated and return on success
276  |      **/
277  |     null_free((void *) &loaded);
278  |     null_free((void *) &load_list);
279  | 
280  | #if WITH_DEBUGGING_MODULECMD
281  |     ErrorLogger( NO_ERR_END, LOC, _proc_ModuleCmd_Update, NULL);
282  | #endif
283  | 
284  | success0:
285  |     return( TCL_OK);			/** -------- EXIT (SUCCESS) -------> **/
286  | 
287  | unwind1:
288  |     null_free((void *) &load_list);
289  | unwind0:
290  | #else	/* BEGINENV */
291  | 	ErrorLogger( ERR_BEGINENV, LOC, NULL);
292  | #endif	/* BEGINENV */
293  |     return( TCL_ERROR);			/** -------- EXIT (FAILURE) -------> **/
294  | 
295  | } /** End of 'ModuleCmd_Update' **/