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.6 2006/01/18 05:35:11 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:	1991/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 = (char *) Tcl_GetVar2( interp,"env","_MODULESBEGINENV_",
137  | 	TCL_GLOBAL_ONLY);
138  |     if( filename) {
139  | 
140  | 	/**
141  | 	 **  Read the beginning environment
142  | 	 **/
143  | 	if( NULL != (file = fopen( filename, "r"))) {
144  | 
145  | 	    if((char *) NULL == (buf = stringer(NULL, buffer_size, NULL )))
146  | 		if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
147  | 		    goto unwind0;
148  | 
149  | 	    while( !feof( file)) {
150  | 
151  | 		/**
152  | 		 **  Trigger to entries of the type
153  | 		 **    <variable> = <value>
154  | 		 **/
155  | 
156  | 		ptr = buf;
157  | 		while( !feof( file)) {
158  | 		    
159  | 		    if((ptr-buf) >= buffer_size-10) {	/** 10 bytes safety  **/
160  | 			null_free((void *) &buf);
161  | 			if((char *) NULL == (buf = stringer(NULL,
162  | 				buffer_size += UPD_BUFSIZE, NULL )))
163  | 			    if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
164  | 				goto unwind0;
165  | 		    }
166  | 
167  | 		    /**
168  | 		     **  Read a character and put it into the read buffer. Check
169  | 		     **  for the lines (CR) or a terminator character ...
170  | 		     **/
171  | 		    if( '\n' == (*ptr++ = c = fgetc( file))) {
172  | 			*ptr++ = c = '\0';
173  | 			break;
174  | 		    }
175  | 
176  | 		    if( !c)
177  | 			break;
178  | 
179  | 		} /** while **/
180  | 
181  | 		/**
182  | 		 **  If there hasn't been a terminator so far, put it at the
183  | 		 **  end of the line. Therefor we've left a safety space at the
184  | 		 **  buffers end ;-)
185  | 		 **/
186  | 		if( c)
187  | 		    *ptr++ = '\0';
188  | 		 
189  | 		/**
190  | 		 **  Now let's evaluate the read line
191  | 		 **/
192  | 		if( var_ptr = strchr( buf, '=')) {
193  | 		
194  | 		    *var_ptr = '\0';
195  | 		    val_ptr = var_ptr+1;
196  | 		    var_ptr = buf;
197  | 
198  | 		    /**
199  | 		     **  Reset the environment to the values derivered from the
200  | 		     **  _MODULESBEGINENV_.
201  | 		     **  Do not change the LOADEDMODULES variable ;-)
202  | 		     **  Do not change the TCL_LIBRARY and TK_LIBRARY also.
203  | 		     **/
204  | 		    if( strncmp( var_ptr, "LOADEDMODULES", 12) &&
205  | 			strncmp( var_ptr, "TCL_LIBRARY", 10 ) &&
206  | 			strncmp( var_ptr, "TK_LIBRARY", 9 ))
207  | 			if( !strncmp( var_ptr, "MODULEPATH", 10))
208  | 			    moduleSetenv( interp, var_ptr, val_ptr, 1);
209  | 			else
210  | 			    Tcl_SetVar2( interp, "env", var_ptr, val_ptr,
211  | 					 TCL_GLOBAL_ONLY);
212  | 		} /** if( var_ptr) **/
213  | 	    } /** while **/
214  | 
215  | 	    /**
216  | 	     **  Close the _MODULESBEGINENV_ file anf free up the read buffer.
217  | 	     **/
218  | 	    null_free((void *) &buf);
219  | 
220  | 	    if( EOF == fclose( file))
221  | 		if( OK != ErrorLogger( ERR_CLOSE, LOC, filename, NULL))
222  | 		    goto unwind0;
223  | 
224  | 	} else { /** if( fopen) **/
225  | 
226  | 	    if( OK != ErrorLogger( ERR_OPEN, LOC, filename, "reading", NULL))
227  | 		goto unwind0;
228  | 
229  | 	} /** if( fopen) **/
230  |     } /** if( filename) **/
231  | 
232  |     /**
233  |      **  Allocate memory for a buffer to tokenize the list of loaded modules
234  |      **  and a list buffer
235  |      **/
236  |     if( NULL == (load_list = (char**) malloc( maxlist*sizeof(char**))))
237  | 	if( OK != ErrorLogger( ERR_ALLOC, LOC, NULL))
238  | 	    goto unwind0;
239  |     
240  |     if( NULL == (loaded = stringer(NULL, 0, tmpload, NULL)))
241  | 	if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
242  | 	    goto unwind1;
243  |     
244  |     /**
245  |      **  Tokenize and build the list
246  |      **/
247  |     if( *loaded) {
248  | 
249  | 	for( load_list[ list_count++] = strtok( loaded, ":");
250  | 	     load_list[ list_count-1];
251  |              load_list[ list_count++] = strtok( NULL, ":") ) {
252  | 
253  | 	    /**
254  | 	     **  Conditionally we have to double the space, we've allocated for
255  | 	     **  the list
256  | 	     **/
257  | 
258  |             if( list_count >= maxlist) {
259  |                 maxlist = maxlist<<1;
260  |             
261  |                 if( NULL == (load_list = (char**) realloc((char *) load_list,
262  | 		    maxlist*sizeof(char**))))
263  | 		    if( OK != ErrorLogger( ERR_ALLOC, LOC, NULL))
264  | 			goto unwind1;
265  | 
266  |             } /** if( maxlist) **/
267  | 	} /** for **/
268  | 
269  | 	/**
270  | 	 **  Load all the modules in the list
271  | 	 **/
272  |         ModuleCmd_Load( interp, 1, list_count, load_list);
273  |     }
274  | 
275  |     /**
276  |      **  Free up what has been allocated and return on success
277  |      **/
278  |     null_free((void *) &loaded);
279  |     null_free((void *) &load_list);
280  | 
281  | success0:
282  | #if WITH_DEBUGGING_MODULECMD
283  |     ErrorLogger( NO_ERR_END, LOC, _proc_ModuleCmd_Update, NULL);
284  | #endif
285  | 
286  |     return( TCL_OK);			/** -------- EXIT (SUCCESS) -------> **/
287  | 
288  | unwind1:
289  |     null_free((void *) &load_list);
290  | unwind0:
291  | #else	/* BEGINENV */
292  | 	ErrorLogger( ERR_BEGINENV, LOC, NULL);
293  | #endif	/* BEGINENV */
294  |     return( TCL_ERROR);			/** -------- EXIT (FAILURE) -------> **/
295  | 
296  | } /** End of 'ModuleCmd_Update' **/