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' **/