~ubuntu-branches/ubuntu/utopic/modules/utopic-proposed

1 by Alastair McKinstry
Import upstream version 3.2.9c
1
/*****
2
 ** ** Module Header ******************************************************* **
3
 ** 									     **
4
 **   Modules Revision 3.0						     **
5
 **   Providing a flexible user environment				     **
6
 ** 									     **
7
 **   File:		cmdConflict.c					     **
8
 **   First Edition:	1991/10/23					     **
9
 ** 									     **
10
 **   Authors:	John Furlan, jlf@behere.com				     **
11
 **		Jens Hamisch, jens@Strawberry.COM			     **
12
 ** 									     **
13
 **   Description:	The Tcl conflict and prereq commands.		     **
14
 ** 									     **
15
 **   Exports:		cmdConflict					     **
16
 **			cmdPrereq					     **
17
 ** 									     **
18
 **   Notes:								     **
19
 ** 									     **
20
 ** ************************************************************************ **
21
 ****/
22
23
/** ** Copyright *********************************************************** **
24
 ** 									     **
25
 ** Copyright 1991-1994 by John L. Furlan.                      	     **
26
 ** see LICENSE.GPL, which must be provided, for details		     **
27
 ** 									     ** 
28
 ** ************************************************************************ **/
29
1.1.1 by Alastair McKinstry
Import upstream version 3.2.10
30
static char Id[] = "@(#)$Id: 729617d8bb5db0ac3250d01b322bcee750b8c540 $";
1 by Alastair McKinstry
Import upstream version 3.2.9c
31
static void *UseId[] = { &UseId, Id };
32
33
/** ************************************************************************ **/
34
/** 				      HEADERS				     **/
35
/** ************************************************************************ **/
36
37
#include "modules_def.h"
38
39
/** ************************************************************************ **/
40
/** 				  LOCAL DATATYPES			     **/
41
/** ************************************************************************ **/
42
43
/** not applicable **/
44
45
/** ************************************************************************ **/
46
/** 				     CONSTANTS				     **/
47
/** ************************************************************************ **/
48
49
/** not applicable **/
50
51
/** ************************************************************************ **/
52
/**				      MACROS				     **/
53
/** ************************************************************************ **/
54
55
/** not applicable **/
56
57
/** ************************************************************************ **/
58
/** 				    LOCAL DATA				     **/
59
/** ************************************************************************ **/
60
61
static char error_module[ MOD_BUFSIZE];
62
static	char	module_name[] = "cmdConflict.c";	/** File name of this module **/
63
#if WITH_DEBUGGING_UTIL
64
static	char	_proc_checkConflict[] = "checkConflict";
65
#endif
66
#if WITH_DEBUGGING_CALLBACK
67
static	char	_proc_cmdConflict[] = "cmdConflict";
68
static	char	_proc_cmdPrereq[] = "cmdPrereq";
69
#endif
70
71
/** ************************************************************************ **/
72
/**				    PROTOTYPES				     **/
73
/** ************************************************************************ **/
74
75
/** not applicable **/
76
77

78
/*++++
79
 ** ** Function-Header ***************************************************** **
80
 ** 									     **
81
 **   Function:		checkConflict					     **
82
 ** 									     **
83
 **   Description:	Check whether the 'g_current_module' is in the list  **
84
 **			of passed modules				     **
85
 ** 									     **
86
 **   First Edition:	1991/10/23					     **
87
 ** 									     **
88
 **   Parameters:	Tcl_Interp	*interp		According Tcl interp.**
89
 **			char		*path		Modulepath to be chk.**
90
 **			char		**modulelist	List of loaded mod.  **
91
 **			int		 nummodules	Number of loaded mod.**
92
 ** 									     **
93
 **   Result:		int	TCL_OK		Successful completion	     **
94
 **				TCL_ERROR	Any error		     **
95
 ** 									     **
96
 **   Attached Globals:	g_flags		These are set up accordingly before  **
97
 **					this function is called in order to  **
98
 **					control everything		     **
99
 **									     **
100
 **		  	g_current_module	Module to check for	     **
101
 ** 									     **
102
 ** ************************************************************************ **
103
 ++++*/
104
105
static	int	checkConflict(	Tcl_Interp	*interp,
106
       		       		char		*path,
107
              			char		**modulelist,
108
              			unsigned	  int nummodules)
109
{
110
    char	**new_modulelist;
111
    int		  new_nummodules, k;
112
    struct stat	  stat_info;
113
    char	 *buffer;
114
    
115
#if WITH_DEBUGGING_UTIL
116
    ErrorLogger( NO_ERR_START, LOC, _proc_checkConflict, NULL);
117
#endif
118
119
    memset( error_module, '\0', MOD_BUFSIZE);
120
121
    /**
122
     **  Check all modules passed to me as parameter
123
     **  At first clarify if they really so exist ...
124
     **/
125
126
    for( k=0; k<nummodules; k++) {
127
128
	if ((char *) NULL == (buffer = stringer(NULL,0,
129
		path,"/", modulelist[k], NULL)))
130
	    if( OK != ErrorLogger( ERR_STRING, LOC,NULL))
131
		goto unwind0;
132
133
        if( stat( buffer, &stat_info) < 0) {
134
	    if( OK != ErrorLogger( ERR_FILEINDIR,LOC,modulelist[k], path,NULL))
135
		if ((char *) NULL == stringer(error_module,MOD_BUFSIZE,
136
			modulelist[k], NULL))
137
		    if( OK != ErrorLogger( ERR_STRING, LOC,NULL))
138
			goto unwind1;
139
	    goto unwind1;
140
	}
141
142
	/**
143
	 **  Is it a directory what has been passed? If it is, list the
144
	 **  according directory and call myself recursively in order to
145
	 **/
146
147
        if( S_ISDIR( stat_info.st_mode)) {
148
149
            if( NULL == (new_modulelist = SortedDirList( interp, path, 
150
		modulelist[k], &new_nummodules)))
151
                continue;
152
153
            if( TCL_ERROR == checkConflict( interp, path, new_modulelist,
154
		new_nummodules)) {
155
                FreeList( new_modulelist, new_nummodules);
156
		goto unwind1;
157
            }
158
159
            FreeList( new_modulelist, new_nummodules);
160
161
	/**
162
	 **  If it isn't a directory, check the current one for to be the
163
	 **  required module file
164
	 **/
165
166
        } else {
167
168
            if( IsLoaded_ExactMatch( interp, modulelist[k], NULL, NULL) &&
169
                strcmp( g_current_module, modulelist[k])) {
170
171
                /**
172
                 **  Save the name of the offending module in a buffer
173
                 **  for reporting purposes when we get back to the top.
174
                 **/
175
176
		if ((char *) NULL == stringer(error_module,MOD_BUFSIZE,
177
			modulelist[k], NULL))
178
		    if( OK != ErrorLogger( ERR_STRING, LOC,NULL))
179
			goto unwind1;
180
		goto unwind1;
181
            }
182
183
        } /** if( directory) **/
184
    } /** for **/
185
186
#if WITH_DEBUGGING_UTIL
187
    ErrorLogger( NO_ERR_END, LOC, _proc_checkConflict, NULL);
188
#endif
189
    /**
190
     ** free resources
191
     **/
192
    null_free((void *) &buffer);
193
194
    return( TCL_OK);			/** -------- EXIT (SUCCESS) -------> **/
195
196
unwind1:
197
    null_free((void *) &buffer);
198
unwind0:
199
    return( TCL_ERROR);			/** -------- EXIT (FAILURE) -------> **/
200
201
} /** End of 'checkConflict' **/
202

203
/*++++
204
 ** ** Function-Header ***************************************************** **
205
 ** 									     **
206
 **   Function:		cmdConflict					     **
207
 ** 									     **
208
 **   Description:	Callback function for 'confilct'		     **
209
 ** 									     **
210
 **   First Edition:	1991/10/23					     **
211
 ** 									     **
212
 **   Parameters:	ClientData	 client_data			     **
213
 **			Tcl_Interp	*interp		According Tcl interp.**
214
 **			int		 argc		Number of arguments  **
215
 **			char		*argv[]		Argument array	     **
216
 ** 									     **
217
 **   Result:		int	TCL_OK		Successful completion	     **
218
 **				TCL_ERROR	Any error		     **
219
 ** 									     **
220
 **   Attached Globals:	g_flags		These are set up accordingly before  **
221
 **					this function is called in order to  **
222
 **					control everything		     **
223
 ** 									     **
224
 ** ************************************************************************ **
225
 ++++*/
226
227
int	cmdConflict(	ClientData	 client_data,
228
	    		Tcl_Interp	*interp,
229
	    		int		 argc,
230
	    		CONST84 char 	*argv[])
231
{
232
    char	 **pathlist,		/** List of module-pathes	     **/
233
    		 **modulelist;		/** List of modules		     **/
234
    char	  *modulepath;		/** Contents of MODULEPATH	     **/
235
    int		   i, j,		/** Loop counters		     **/
236
   		   numpaths, nummodules;/** Size of the according arrays     **/
237
238
#if WITH_DEBUGGING_CALLBACK
239
    ErrorLogger( NO_ERR_START, LOC, _proc_cmdConflict, NULL);
240
#endif
241
242
    /**
243
     **  Whatis mode
244
     **/
245
246
    if( g_flags & (M_WHATIS | M_HELP))
247
	goto success0;
248
249
    /**
250
     **  Check the parameters. Usage is 'conflict <module> [<module> ...]'
251
     **/
252
253
    if( argc < 2)
254
	if( OK != ErrorLogger( ERR_USAGE, LOC, argv[0],
255
	    "conflicting-modulefiles", NULL))
256
	    goto unwind0;
257
258
    /**
259
     **  There will be no conflicts in case of switch or unload
260
     **/
261
262
    if( g_flags & (M_REMOVE | M_SWITCH))
263
        goto success0;
264
265
    /**
266
     **  Load the MODULEPATH and split it into a list of paths. Assume success
267
     **  if no list to be built...
268
     **/
269
    if((char *) NULL == (modulepath = xgetenv( "MODULEPATH")))
270
	if( OK != ErrorLogger( ERR_MODULE_PATH, LOC, NULL))
271
	    goto unwind0;
272
273
    if((char **) NULL==(pathlist=SplitIntoList(interp, modulepath, &numpaths,
274
	_colon)))
275
        goto success1;
276
277
    /**
278
     **  Non-persist mode?
279
     **/
280
    
281
    if (g_flags & M_NONPERSIST) {
282
	return (TCL_OK);
283
    }
284
285
    /**
286
     **  Display?
287
     **/
288
289
    if( g_flags & M_DISPLAY) {
290
	fprintf( stderr, "%s\t ", argv[ 0]);
291
	while( --argc)
292
	    fprintf( stderr, "%s ", *++argv);
293
	fprintf( stderr, "\n");
294
        goto success2;
295
    }
296
297
    /**
298
     **  Now check/display all passed modules ...
299
     **/
300
301
    for( i=1; i<argc && argv[i]; i++) {
302
        for( j = 0; j < numpaths; j++) {
303
304
            if((char **)NULL == (modulelist = SortedDirList(interp,
305
			pathlist[j], (char *) argv[i], &nummodules)))
306
                continue;		/** not browseable		     **/
307
308
	    /**
309
	     **  Actually checking for conflicts is done here
310
	     **/
311
            if( TCL_ERROR == checkConflict( interp, pathlist[j], modulelist,
312
		nummodules))
313
		if( OK != ErrorLogger( ERR_CONFLICT, LOC, g_current_module,
314
		    error_module, NULL)) {
315
		    FreeList( modulelist, nummodules);
316
		    goto unwind2;
317
		}
318
319
	    /**
320
	     **  Free the list of modules used in the loops body above.
321
	     **/
322
            FreeList( modulelist, nummodules);
323
324
        } /** for( j) **/
325
    } /** for( i) **/
326
327
#if WITH_DEBUGGING_CALLBACK
328
    ErrorLogger( NO_ERR_END, LOC, _proc_cmdConflict, NULL);
329
#endif
330
331
    /**
332
     ** free resources
333
     **/
334
success2:
335
    FreeList( pathlist, numpaths);
336
success1:
337
    null_free((void *) &modulepath);
338
success0:
339
    return( TCL_OK);			/** -------- EXIT (SUCCESS) -------> **/
340
341
unwind2:
342
    FreeList( pathlist, numpaths);
343
unwind1:
344
    null_free((void *) &modulepath);
345
unwind0:
346
    return( TCL_ERROR);			/** -------- EXIT (FAILURE) -------> **/
347
348
} /** End of 'cmdConflict' **/
349

350
/*++++
351
 ** ** Function-Header ***************************************************** **
352
 ** 									     **
353
 **   Function:		cmdPrereq					     **
354
 ** 									     **
355
 **   Description:	Callback function for 'prereq'			     **
356
 ** 									     **
357
 **   First Edition:	1991/10/23					     **
358
 ** 									     **
359
 **   Parameters:	ClientData	 client_data			     **
360
 **			Tcl_Interp	*interp		According Tcl interp.**
361
 **			int		 argc		Number of arguments  **
362
 **			char		*argv[]		Argument array	     **
363
 ** 									     **
364
 **   Result:		int	TCL_OK		Successful completion	     **
365
 **				TCL_ERROR	Any error		     **
366
 ** 									     **
367
 **   Attached Globals:	g_flags		These are set up accordingly before  **
368
 **					this function is called in order to  **
369
 **					control everything		     **
370
 ** 									     **
371
 ** ************************************************************************ **
372
 ++++*/
373
374
int	cmdPrereq(	ClientData	 client_data,
375
	    		Tcl_Interp	*interp,
376
	    		int		 argc,
377
	    		CONST84 char	*argv[])
378
{
379
    char	***savedlists = (char ***) NULL;
380
    int		  *savedlens = (int *) NULL;
381
    char	 **pathlist,
382
		 **modulelist,
383
		  *modulepath,
384
		  *notloaded_flag = (char *) argv[1];
385
    int     	   i, j, k, numpaths, nummodules, listcnt = 0,
386
		   Result = TCL_OK;
387
    char	   buffer[ MOD_BUFSIZE];
388
	
389
#if WITH_DEBUGGING_CALLBACK
390
    ErrorLogger( NO_ERR_START, LOC, _proc_cmdPrereq, NULL);
391
#endif
392
393
    /** 
394
     **  Parameter check. Usage is 'prereq <module> [<module> ...]'
395
     **/
396
397
    if( argc < 2)
398
	if( OK != ErrorLogger( ERR_USAGE, LOC, argv[0],
399
	    " prerequisite-modules", NULL))
400
	    goto unwind0;
401
402
    /**
403
     **  There's no prerequisite check in case of removal
404
     **/
405
406
    if( g_flags & (M_REMOVE | M_WHATIS))
407
        goto success0;
408
409
  
410
    /**
411
     **  Non-persist mode?
412
     **/
413
    
414
    if (g_flags & M_NONPERSIST) {
415
	return (TCL_OK);
416
    }
417
418
    /**
419
     **  Display mode
420
     **/
421
422
    if( g_flags & M_DISPLAY) {
423
	fprintf( stderr, "%s\t ", argv[ 0]);
424
	while( --argc)
425
	    fprintf( stderr, "%s ", *++argv);
426
	fprintf( stderr, "\n");
427
        goto success0;
428
    }
429
430
    /**
431
     **  Load the MODULEPATH and split it into a list of paths. Assume success
432
     **  if no list to be built...
433
     **/
434
    if((char *) NULL == (modulepath = xgetenv( "MODULEPATH")))
435
	if( OK != ErrorLogger( ERR_MODULE_PATH, LOC, NULL))
436
	    goto unwind0;
437
438
#if WITH_DEBUGGING_CALLBACK_1
439
    ErrorLogger( NO_ERR_DEBUG, LOC, "Got modulepath: '", modulepath, "'", NULL);
440
#endif
441
442
    if((char **) NULL==(pathlist=SplitIntoList(interp, modulepath, &numpaths,
443
	_colon)))
444
        goto success1;
445
446
    /**
447
     **  Allocate memory for the lists of conflict modules
448
     **/
449
    if((char ***) NULL==(savedlists=(char***) module_malloc(numpaths * (argc-1)
450
	* sizeof(char**))))
451
	if( OK != ErrorLogger( ERR_ALLOC, LOC, NULL))
452
	    goto unwind1;
453
454
    if((int *) NULL == (savedlens = (int*) module_malloc(numpaths * (argc-1)
455
	* sizeof( int))))
456
	if( OK != ErrorLogger( ERR_ALLOC, LOC, NULL))
457
	    goto unwind2;
458
459
    /**
460
     **  Check/Display all passed modules
461
     **/
462
463
#if WITH_DEBUGGING_CALLBACK_1
464
    ErrorLogger( NO_ERR_DEBUG, LOC, "Scanning all ", (sprintf( buffer, "%d",
465
	numpaths), buffer), "modulepaths", NULL);
466
#endif
467
468
    for( i=1; i<argc && argv[i] && notloaded_flag; i++) {
469
        for( j = 0; j < numpaths && notloaded_flag; j++) {
470
471
            if((char **) NULL == (modulelist = SortedDirList(interp,pathlist[j],
472
	        (char *) argv[i], &nummodules)))
473
                continue;
474
475
	    /**
476
	     **  save the list of file to be printed in case of missing pre-
477
	     **  requisites or 
478
	     **/
479
480
#if WITH_DEBUGGING_CALLBACK_1
481
	    ErrorLogger( NO_ERR_DEBUG, LOC, "Save directory list. # = ",
482
		(sprintf( buffer, "%d", listcnt), buffer), NULL);
483
#endif
484
485
	    savedlens[ listcnt]    = nummodules;
486
	    savedlists[ listcnt++] = modulelist;
487
488
	    /**
489
	     **  Now actually check if the prerequisites are fullfilled
490
	     **  The notloaded_flag controls the exit from both loops in case
491
	     **  a prerequisite is missing.
492
	     **/
493
494
            for( k=0; k < nummodules && notloaded_flag; k++) {
495
                if( !IsLoaded( interp, modulelist[k], NULL, NULL)) {
496
                    notloaded_flag = (char *) argv[i];
497
                } else {
498
                    notloaded_flag = NULL;
499
                }
500
            }
501
        } /** for( j) **/
502
    } /** for( i) **/
503
504
#if WITH_DEBUGGING_CALLBACK_1
505
    ErrorLogger( NO_ERR_DEBUG, LOC, "Done. Missing prerequisite: '",
506
	(notloaded_flag ? notloaded_flag : "none"), "'", NULL);
507
#endif
508
509
    /**
510
     **  Display an error message if this was *NOT* display mode and a
511
     **  missing prerequisite has been found
512
     **/
513
    if( notloaded_flag) {
514
515
	/**
516
	 **  Add the whole list of prerequired module files to the Tcl result
517
	 **  string
518
	 **/
519
	for( k=0; k<listcnt; k++) {
520
	    char **listptr = savedlists[k];
521
522
	    *buffer = '\0';
523
	    for( i=0; listptr && i<savedlens[k]; i++, listptr++) {
524
		if ((char *) NULL == stringer(
525
			buffer + strlen(buffer), MOD_BUFSIZE-strlen(buffer),
526
			*listptr, " ", NULL))
527
		    if( OK != ErrorLogger( ERR_STRING, LOC,NULL)) {
528
	    		FreeList( savedlists[k], savedlens[k]);
529
			goto unwind2;
530
		    }
531
	    }
532
533
	    FreeList( savedlists[k], savedlens[k]);
534
	}
535
536
	buffer[strlen(buffer)-1] = '\0';	/* remove last blank */
537
538
	if( OK != ErrorLogger( ERR_PREREQ, LOC, g_current_module, buffer, NULL))
539
	    Result = TCL_ERROR;	
540
541
    } else {
542
543
	/**
544
	 **  We have to free the saved module names again
545
	 **/
546
547
	for( k=0; k<listcnt; k++)
548
	    FreeList( savedlists[k], savedlens[k]);
549
550
    }
551
552
    /**
553
     **  Free up the list of prerequisites and return ...
554
     **/
555
556
    null_free((void *) &savedlens);
557
    null_free((void *) &savedlists);
558
559
#if WITH_DEBUGGING_CALLBACK
560
    ErrorLogger( NO_ERR_END, LOC, _proc_cmdPrereq, NULL);
561
#endif
562
563
success1:
564
    null_free((void *) &modulepath);
565
success0:
566
    return( Result);			/** -------- EXIT (Result)  -------> **/
567
568
unwind3:
569
    null_free((void *) &savedlens);
570
unwind2:
571
    null_free((void *) &savedlists);
572
unwind1:
573
    null_free((void *) &modulepath);
574
unwind0:
575
    return( TCL_ERROR);			/** -------- EXIT (FAILURE) -------> **/
576
} /** End of 'cmdPrereq' **/