예제 #1
0
static int checkConflict(
	Tcl_Interp * interp,
	char *path,
	char **modulelist,
	unsigned int nummodules
) {
	uvec           *new_modulelist;
	int             new_nummodules, k;
	is_Result       fstate;
	char           *buffer;

	memset(error_module, '\0', MOD_BUFSIZE);

    /**
     **  Check all modules passed to me as parameter
     **  At first clarify if they really do exist ...
     **/
	for (k = 0; k < nummodules; k++) {
		if (!(buffer = stringer(NULL,0,path,psep,modulelist[k],NULL)))
			if (OK != ErrorLogger(ERR_STRING, LOC, NULL))
				goto unwind0;
		if (!(fstate = is_("what", buffer))) {
			if (OK != ErrorLogger(ERR_FILEINDIR, LOC,
				modulelist[k], path, NULL))
				if (!stringer(error_module, MOD_BUFSIZE,
					     modulelist[k], NULL))
					if (OK !=
					    ErrorLogger(ERR_STRING, LOC, NULL))
						goto unwind1;
			goto unwind1;
		}
	/**
	 **  Is it a directory what has been passed? If it is, list the
	 **  according directory and call myself recursively in order to
	 **/
		if (fstate == IS_DIR) {
			if (!(new_modulelist = SortedDirList(path,
				modulelist[k], &new_nummodules)))
				continue;

			if (TCL_ERROR == checkConflict(interp, path,
			uvec_vector(new_modulelist), new_nummodules)) {
				FreeList(&new_modulelist);
				goto unwind1;
			}
			FreeList(&new_modulelist);
	/**
	 **  If it isn't a directory, check the current one for to be the
	 **  required module file
	 **/
		} else {
			if (IsLoaded_ExactMatch (interp,modulelist[k],NULL,NULL)
			    && strcmp(g_current_module, modulelist[k])) {

		/**
                 **  Save the name of the offending module in a buffer
                 **  for reporting purposes when we get back to the top.
                 **/

				if (!stringer(error_module, MOD_BUFSIZE,
					     modulelist[k], NULL))
					if (OK !=
					    ErrorLogger(ERR_STRING, LOC, NULL))
						goto unwind1;
				goto unwind1;
			}

		} /** if( directory) **/
	} /** for **/
    /**
     ** free resources
     **/
	null_free((void *)&buffer);

	return (TCL_OK);		/** -------- EXIT (SUCCESS) -------> **/

unwind1:
	null_free((void *)&buffer);
unwind0:
	return (TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/

} /** End of 'checkConflict' **/
static char *GetModuleName(Tcl_Interp *interp, char *path, char *prefix,
						   char *modulename)
{
    struct stat	  stats;		/** Buffer for the stat() systemcall **/
    char	 *fullpath = NULL;	/** Buffer for creating path names   **/
    char	 *Result = NULL;	/** Our return value		     **/
    char	**filelist = NULL;	/** Buffer for a list of possible
								 ** module files		     **/
    int		  numlist;		/** Size of this list		     **/
    int		  i, slen, is_def;
    char	 *s, *t;		/** Private string buffer	     **/
    char	 *mod, *ver;		/** Pointer to module and version    **/
    char	 *mod1, *ver1;		/** Temp pointer		     **/

#if WITH_DEBUGGING_LOCATE_1
    ErrorLogger(NO_ERR_START, LOC, _proc_GetModuleName, NULL);
#endif /* WITH_DEBUGGING_LOCATE_1 */
    /**
     **  Split the modulename into module and version. Use a private buffer
     **  for this
     **/
    if ((char *)NULL == (s = stringer(NULL, 0,  modulename, NULL))) {
		ErrorLogger(ERR_ALLOC, LOC, NULL);
		goto unwind0;
    }
    slen = (int)(strlen(s) + 1);
    mod = s;
	/* assume that the '=' here is correct, because otherwise 'ver' would not
	 * be initialized here yet (I think): */
    if ((ver = strrchr(mod, '/'))) {
		*ver++ = '\0';
	}
    /**
     **  Allocate a buffer for full pathname building:
     **/
    if ((char *)NULL == (fullpath = stringer(NULL, MOD_BUFSIZE, NULL))) {
		if (OK != ErrorLogger(ERR_STRING, LOC, NULL)) {
			goto unwind1;
		}
    }
    /**
     **  Check whether $path/$prefix/$modulename is a directory.
     **/
    if (prefix) {
		if ((char *)NULL == stringer(fullpath, MOD_BUFSIZE, path, "/", prefix,
									 "/", modulename, NULL)) {
			goto unwind1;
		}
    } else {
		if ((char *)NULL == stringer(fullpath, MOD_BUFSIZE, path, "/",
									 modulename, NULL)) {
			goto unwind1;
		}
    }
    if (!stat(fullpath, &stats) && S_ISDIR(stats.st_mode)) {
		/**
		 ** So the full modulename is $modulename/default.  Recurse on that.
		 **/
		if ((char *)NULL == (t = stringer(NULL, 0, modulename, "/",
										  _default, NULL))) {
			goto unwind1;
		}
		Result = GetModuleName(interp, path, prefix, t);
		null_free((void *)&t);
		null_free((void *)&fullpath);
		null_free((void *)&s);
		return (Result);
    }

    /**
     **  Check whether $path/$prefix/$mod is a directory:
     **/
    if (prefix) {
		if ((char *)NULL == stringer(fullpath, MOD_BUFSIZE, path, "/", prefix,
									 "/", mod, NULL)) {
			goto unwind1;
		}
    } else {
		if ((char *)NULL == stringer(fullpath, MOD_BUFSIZE, path, "/",
									 mod, NULL)) {
			goto unwind1;
		}
    }
    is_def = !strcmp(mod, _default);

    if (is_def || !stat(fullpath, &stats)) {
		/**
		 **  If it is a directory, then do this:
		 **/
    	if (!is_def && S_ISDIR( stats.st_mode)) {
			/**
			 **  Source the ".modulerc" file if it exists.
			 **  For compatibility source the .version file, too.
			 **/
			if (prefix) {
				if ((char *)NULL == stringer(modfil_buf, MOD_BUFSIZE,
											 prefix, "/", mod, NULL)) {
					goto unwind2;
				}
			} else {
				if ((char *)NULL == stringer(modfil_buf, MOD_BUFSIZE,
											 mod, NULL)) {
					goto unwind2;
				}
			}

			if ((char *)NULL == stringer(fullpath, MOD_BUFSIZE, path, "/",
										 modfil_buf, NULL)) {
				goto unwind2;
			}
			g_current_module = modfil_buf;

			if ((TCL_ERROR == SourceRC(interp, fullpath, modulerc_file)) ||
				(TCL_ERROR == SourceVers(interp, fullpath, modfil_buf))) {
				/* flags = save_flags; */
				goto unwind2;
			}
			/**
			 **  After sourcing the RC files, we have to look up the
			 **  versions again:
			 **/
			if (VersionLookup(modulename, &mod1, &ver1)) {
				int len = (int)(strlen(mod1) + strlen(ver1) + 2);
				/**
				 **  Maybe we have to enlarge s:
				 **/
				if (len > slen) {
					null_free((void *)&s);
					if((char *)NULL == (s = stringer( NULL, len, NULL))) {
						ErrorLogger( ERR_STRING, LOC, NULL);
						goto unwind2;
					}
					slen = len;
					/* dummy condition to use 'slen': */
					if (slen == 0) {
						;
					}
				}
				/**
				 **  Print the new module/version in the buffer:
				 **/
				if ((char *)NULL == stringer(s, len, mod1, "/", ver1, NULL)) {
					ErrorLogger(ERR_STRING, LOC, NULL);
					goto unwind2;
				}
				mod = s;
				if (ver = strchr(s, (int)'/')) {
					*ver++ = '\0';
				}
			}
			/**
			 **  recursively delve into subdirectories (until ver == NULL).
			 **/
	    if (ver) {
			int len;
			len = (int)(strlen(mod) + 1);

			if (prefix) {
				len += (strlen(prefix) + 1);
			}
		/**
		 **  Build the new prefix
		 **/
		if((char *) NULL == (t = stringer(NULL, len, NULL))) {
		    ErrorLogger( ERR_STRING, LOC, NULL);
		    goto unwind2;
		}

		if( prefix) {
		    if((char *) NULL == stringer(t, len, prefix,"/",mod, NULL)){
			ErrorLogger( ERR_STRING, LOC, NULL);
			goto unwindt;
		    }
		} else {
		    if((char *) NULL == stringer(t, len, mod, NULL)){
			ErrorLogger( ERR_STRING, LOC, NULL);
			goto unwindt;
		    }
		}
		/**
		 **  This is the recursion
		 **/
		Result = GetModuleName( interp, path, t, ver);

		/**
		 **  Free our temporary prefix buffer
		 **/
		null_free((void *) &t);
		if (0) {	/* an error occurred */
unwindt:
		    null_free((void *) &t);
		    goto unwind2;
		}
	    }
	} else {     /** if ($path/$prefix/$mod is a directory) **/
	    /**
	     **  Now 'mod' should be either a file or the word 'default'
	     **  In case of default get the file with the highest version number
	     **  in the current directory
	     **/
	    if( is_def) {
		if( !prefix)
		    prefix = ".";
		if( NULL == (filelist = SortedDirList( interp, path, prefix,
		&numlist)))
		    goto unwind1;

		prefix = (char *)NULL;
		/**
		 **  Select the first one on the list which is either a
		 **  modulefile or another directory. We start at the highest
		 **  lexicographical name in the directory since the filelist
		 **  is reverse sorted.
		 **  If it is a directory, then we delve into it.
		 **/
		for( i=0; i<numlist && Result==NULL; i++) {
		    /**
		     **  Build the full path name and check if it is a
		     **  directory. If it is, recursively try to find there what
		     **  we are/were seeking for
		     **/
		    if ((char *)NULL == stringer(fullpath, MOD_BUFSIZE,
			path, "/", filelist[i], NULL))
			    goto unwind2;

		    if( !stat( fullpath, &stats) && S_ISDIR( stats.st_mode)) {
			Result = GetModuleName( interp, path, prefix,
			    filelist[ i]);
		    } else {
			/**
			 **  Otherwise check the file for a magic cookie ...
			 **/
			if( check_magic( fullpath, MODULES_MAGIC_COOKIE,
			    MODULES_MAGIC_COOKIE_LENGTH))
			    Result = filelist[ i];
		    } /** end "if (!stat)" **/
		} /** end for-loop **/
	    } else {  /** default **/
		/**
		 **  If mod names a file, we have to check wheter it exists and
		 **  is a valid module file
		 **/
		if( check_magic( fullpath, MODULES_MAGIC_COOKIE,
		    MODULES_MAGIC_COOKIE_LENGTH))
		    Result = mod;
		else {
		    ErrorLogger( ERR_MAGIC, LOC, fullpath, NULL);
		    Result = NULL;
		}
	    } /** if( mod is a filename) **/
	    /**
	     **  Build the full filename (using prefix and Result) if
	     **  Result is defined
	     **/
	    if (Result) {
			int len;
			len = (int)(strlen(Result) + 1);

			if (prefix) {
				len += (strlen(prefix) + 1);
			}

		if((char *) NULL == (t = stringer(NULL, len, NULL))) {
		   ErrorLogger( ERR_STRING, LOC, NULL);
		   goto unwind2;
		}
		if( prefix) {
		    if((char *) NULL == stringer(t,len, prefix,"/",Result,NULL))
			goto unwindt2;
		} else {
		    if((char *) NULL == stringer(t,len, Result,NULL))
			goto unwindt2;
		}
		Result = t;
		if (0) {	/* an error occurred */
unwindt2:
		    null_free((void *) &t);
		    goto unwind2;
		}
	    }
	} /** mod is a file **/
    } /** mod exists **/
    /**
     **  Free up temporary values and return what we've found
     **/
    null_free((void*) &fullpath);
    null_free((void*) &s);
    FreeList(filelist, numlist);

#if WITH_DEBUGGING_LOCATE_1
    ErrorLogger(NO_ERR_END, LOC, _proc_GetModuleName, NULL);
#endif /* WITH_DEBUGGING_LOCATE_1 */
    return (Result);			/** -------- EXIT (SUCCESS) -------> **/

unwind2:
    null_free((void *)&fullpath);
unwind1:
    null_free((void *)&s);
unwind0:
    return(NULL);			/** -------- EXIT (FAILURE) -------> **/

} /** End of 'GetModuleName' (that was a lengthy function...) **/