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