mirror of
https://github.com/envmodules/modules.git
synced 2026-06-10 00:56:30 +08:00
1235 lines
72 KiB
HTML
1235 lines
72 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
|
|
<!-- This HTML file generated by cxref (version 1.6a). -->
|
|
<!-- cxref program (c) Andrew M. Bishop 1995,96,97,98,99,2000,01,02,03,04,05. -->
|
|
|
|
<!--
|
|
Cxref: cxref -block-comments -verbatim-comments -xref-all -index-all -html-src -Oxref locate_module.c
|
|
CPP : cxref-cpp -lang-c -C -dD -dI
|
|
-->
|
|
|
|
<HTML>
|
|
|
|
<HEAD>
|
|
<TITLE>Source File locate_module.c</TITLE>
|
|
<LINK rel="stylesheet" href="cxref.css" type="text/css">
|
|
</HEAD>
|
|
|
|
<BODY>
|
|
|
|
<pre>
|
|
<a name="line1">1 |</a> /*****
|
|
<a name="line2">2 |</a> ** ** Module Header ******************************************************* **
|
|
<a name="line3">3 |</a> ** **
|
|
<a name="line4">4 |</a> ** Modules Revision 3.0 **
|
|
<a name="line5">5 |</a> ** Providing a flexible user environment **
|
|
<a name="line6">6 |</a> ** **
|
|
<a name="line7">7 |</a> ** File: locate_module.c **
|
|
<a name="line8">8 |</a> ** First Edition: 1991/10/23 **
|
|
<a name="line9">9 |</a> ** **
|
|
<a name="line10">10 |</a> ** Authors: John Furlan, jlf@behere.com **
|
|
<a name="line11">11 |</a> ** Jens Hamisch, jens@Strawberry.COM **
|
|
<a name="line12">12 |</a> ** **
|
|
<a name="line13">13 |</a> ** Description: Contains the routines which locate the actual **
|
|
<a name="line14">14 |</a> ** modulefile given a modulefilename by looking in all **
|
|
<a name="line15">15 |</a> ** of the paths in MODULEPATH. **
|
|
<a name="line16">16 |</a> ** **
|
|
<a name="line17">17 |</a> ** Exports: Locate_ModuleFile **
|
|
<a name="line18">18 |</a> ** SortedDirList **
|
|
<a name="line19">19 |</a> ** SplitIntoList **
|
|
<a name="line20">20 |</a> ** FreeList **
|
|
<a name="line21">21 |</a> ** SourceRC **
|
|
<a name="line22">22 |</a> ** SourceVers **
|
|
<a name="line23">23 |</a> ** **
|
|
<a name="line24">24 |</a> ** Notes: **
|
|
<a name="line25">25 |</a> ** **
|
|
<a name="line26">26 |</a> ** ************************************************************************ **
|
|
<a name="line27">27 |</a> ****/
|
|
<a name="line28">28 |</a>
|
|
<a name="line29">29 |</a> /** ** Copyright *********************************************************** **
|
|
<a name="line30">30 |</a> ** **
|
|
<a name="line31">31 |</a> ** Copyright 1991-1994 by John L. Furlan. **
|
|
<a name="line32">32 |</a> ** see LICENSE.GPL, which must be provided, for details **
|
|
<a name="line33">33 |</a> ** **
|
|
<a name="line34">34 |</a> ** ************************************************************************ **/
|
|
<a name="line35">35 |</a>
|
|
<a name="line36">36 |</a> static char Id[] = "@(#)$Id: locate_module.c.src.html,v 1.6 2006/01/18 05:35:11 rkowen Exp $";
|
|
<a name="line37">37 |</a> static void *UseId[] = { &UseId, Id };
|
|
<a name="line38">38 |</a>
|
|
<a name="line39">39 |</a> /** ************************************************************************ **/
|
|
<a name="line40">40 |</a> /** HEADERS **/
|
|
<a name="line41">41 |</a> /** ************************************************************************ **/
|
|
<a name="line42">42 |</a>
|
|
<a name="line43">43 |</a> #include "modules_def.h"
|
|
<a name="line44">44 |</a>
|
|
<a name="line45">45 |</a> /** ************************************************************************ **/
|
|
<a name="line46">46 |</a> /** LOCAL DATATYPES **/
|
|
<a name="line47">47 |</a> /** ************************************************************************ **/
|
|
<a name="line48">48 |</a>
|
|
<a name="line49">49 |</a> /** not applicable **/
|
|
<a name="line50">50 |</a>
|
|
<a name="line51">51 |</a> /** ************************************************************************ **/
|
|
<a name="line52">52 |</a> /** CONSTANTS **/
|
|
<a name="line53">53 |</a> /** ************************************************************************ **/
|
|
<a name="line54">54 |</a>
|
|
<a name="line55">55 |</a> #define SRCFRAG 100
|
|
<a name="line56">56 |</a>
|
|
<a name="line57">57 |</a> /** ************************************************************************ **/
|
|
<a name="line58">58 |</a> /** MACROS **/
|
|
<a name="line59">59 |</a> /** ************************************************************************ **/
|
|
<a name="line60">60 |</a>
|
|
<a name="line61">61 |</a> /** not applicable **/
|
|
<a name="line62">62 |</a>
|
|
<a name="line63">63 |</a> /** ************************************************************************ **/
|
|
<a name="line64">64 |</a> /** LOCAL DATA **/
|
|
<a name="line65">65 |</a> /** ************************************************************************ **/
|
|
<a name="line66">66 |</a>
|
|
<a name="line67">67 |</a> static char module_name[] = "locate_module.c"; /** File name of this module **/
|
|
<a name="line68">68 |</a>
|
|
<a name="line69">69 |</a> #if WITH_DEBUGGING_LOCATE
|
|
<a name="line70">70 |</a> static char _proc_Locate_ModuleFile[] = "Locate_ModuleFile";
|
|
<a name="line71">71 |</a> #endif
|
|
<a name="line72">72 |</a> #if WITH_DEBUGGING_LOCATE_1
|
|
<a name="line73">73 |</a> static char _proc_GetModuleName[] = "GetModuleName";
|
|
<a name="line74">74 |</a> #endif
|
|
<a name="line75">75 |</a> #if WITH_DEBUGGING_UTIL_1
|
|
<a name="line76">76 |</a> static char _proc_SortedDirList[] = "SortedDirList";
|
|
<a name="line77">77 |</a> static char _proc_SplitIntoList[] = "SplitIntoList";
|
|
<a name="line78">78 |</a> #endif
|
|
<a name="line79">79 |</a> #if WITH_DEBUGGING_UTIL_2
|
|
<a name="line80">80 |</a> static char _proc_FreeList[] = "FreeList";
|
|
<a name="line81">81 |</a> #endif
|
|
<a name="line82">82 |</a>
|
|
<a name="line83">83 |</a> static char buf[ MOD_BUFSIZE];
|
|
<a name="line84">84 |</a> static char modfil_buf[ MOD_BUFSIZE];
|
|
<a name="line85">85 |</a>
|
|
<a name="line86">86 |</a> /** ************************************************************************ **/
|
|
<a name="line87">87 |</a> /** PROTOTYPES **/
|
|
<a name="line88">88 |</a> /** ************************************************************************ **/
|
|
<a name="line89">89 |</a>
|
|
<a name="line90">90 |</a> static int filename_compare( const void*, const void*);
|
|
<a name="line91">91 |</a> static char *GetModuleName( Tcl_Interp*, char*, char*, char*);
|
|
<a name="line92">92 |</a>
|
|
<a name="line93">93 |</a> /*++++
|
|
<a name="line94">94 |</a> ** ** Function-Header ***************************************************** **
|
|
<a name="line95">95 |</a> ** **
|
|
<a name="line96">96 |</a> ** Function: filename_compare **
|
|
<a name="line97">97 |</a> ** **
|
|
<a name="line98">98 |</a> ** Description: This is a reverse compare function to reverse the **
|
|
<a name="line99">99 |</a> ** filename list. The function is used as compare func- **
|
|
<a name="line100">100 |</a> ** tion for qsort. **
|
|
<a name="line101">101 |</a> ** **
|
|
<a name="line102">102 |</a> ** First Edition: 1991/10/23 **
|
|
<a name="line103">103 |</a> ** **
|
|
<a name="line104">104 |</a> ** Parameters: const void *fi1 First filename to compare **
|
|
<a name="line105">105 |</a> ** const void *fi2 Second filename to compare **
|
|
<a name="line106">106 |</a> ** **
|
|
<a name="line107">107 |</a> ** Result: int -1 filename 1 > filename 2 **
|
|
<a name="line108">108 |</a> ** 0 filename 1 == filename 2 **
|
|
<a name="line109">109 |</a> ** 1 filename 1 < filename 2 **
|
|
<a name="line110">110 |</a> ** **
|
|
<a name="line111">111 |</a> ** Attached Globals: **
|
|
<a name="line112">112 |</a> ** **
|
|
<a name="line113">113 |</a> ** ************************************************************************ **
|
|
<a name="line114">114 |</a> ++++*/
|
|
<a name="line115">115 |</a>
|
|
<a name="line116">116 |</a> static int filename_compare( const void *fi1,
|
|
<a name="line117">117 |</a> const void *fi2)
|
|
<a name="line118">118 |</a> {
|
|
<a name="line119">119 |</a> return strcmp(*(char**)fi2, *(char**)fi1);
|
|
<a name="line120">120 |</a> }
|
|
<a name="line121">121 |</a>
|
|
<a name="line122">122 |</a> /*++++
|
|
<a name="line123">123 |</a> ** ** Function-Header ***************************************************** **
|
|
<a name="line124">124 |</a> ** **
|
|
<a name="line125">125 |</a> ** Function: Locate_ModuleFile **
|
|
<a name="line126">126 |</a> ** **
|
|
<a name="line127">127 |</a> ** Description: Searches for a modulefile given a string argument **
|
|
<a name="line128">128 |</a> ** which is either a full path or a modulefile name **
|
|
<a name="line129">129 |</a> ** -- usually the argument the user gave. If it's not a **
|
|
<a name="line130">130 |</a> ** full path, the directories in the MODULESPATH **
|
|
<a name="line131">131 |</a> ** environment variable are searched to find a match **
|
|
<a name="line132">132 |</a> ** for the given name. **
|
|
<a name="line133">133 |</a> ** **
|
|
<a name="line134">134 |</a> ** First Edition: 1991/10/23 **
|
|
<a name="line135">135 |</a> ** **
|
|
<a name="line136">136 |</a> ** Parameters: Tcl_Interp *interp Attached Tcl interpr.**
|
|
<a name="line137">137 |</a> ** char *modulename Name of the module to**
|
|
<a name="line138">138 |</a> ** be located **
|
|
<a name="line139">139 |</a> ** char *realname Real modulename (with**
|
|
<a name="line140">140 |</a> ** version) **
|
|
<a name="line141">141 |</a> ** char *filename Real full module **
|
|
<a name="line142">142 |</a> ** file path **
|
|
<a name="line143">143 |</a> ** **
|
|
<a name="line144">144 |</a> ** Result: int TCL_OK or TCL_ERROR **
|
|
<a name="line145">145 |</a> ** filename the full path of the required module **
|
|
<a name="line146">146 |</a> ** file is copied in here **
|
|
<a name="line147">147 |</a> ** **
|
|
<a name="line148">148 |</a> ** Attached Globals: g_current_module The module which is handled **
|
|
<a name="line149">149 |</a> ** by the current command **
|
|
<a name="line150">150 |</a> ** **
|
|
<a name="line151">151 |</a> ** ************************************************************************ **
|
|
<a name="line152">152 |</a> ++++*/
|
|
<a name="line153">153 |</a>
|
|
<a name="line154">154 |</a> int Locate_ModuleFile( Tcl_Interp *interp,
|
|
<a name="line155">155 |</a> char *modulename,
|
|
<a name="line156">156 |</a> char *realname,
|
|
<a name="line157">157 |</a> char *filename)
|
|
<a name="line158">158 |</a> {
|
|
<a name="line159">159 |</a> char *p; /** Tokenization pointer **/
|
|
<a name="line160">160 |</a> char *result = NULL; /** This functions result **/
|
|
<a name="line161">161 |</a> char **pathlist; /** List of paths to scan **/
|
|
<a name="line162">162 |</a> int numpaths, /** Size of this list **/
|
|
<a name="line163">163 |</a> i; /** Loop counter **/
|
|
<a name="line164">164 |</a> char *modulespath; /** Buffer for the contents of the **/
|
|
<a name="line165">165 |</a> /** environment variable MODULEPATH **/
|
|
<a name="line166">166 |</a> char *mod, *vers; /** Module and version name for sym- **/
|
|
<a name="line167">167 |</a> /** bolic name lookup **/
|
|
<a name="line168">168 |</a> /**
|
|
<a name="line169">169 |</a> ** If it is a full path name, that's the module file to load.
|
|
<a name="line170">170 |</a> **/
|
|
<a name="line171">171 |</a> #if WITH_DEBUGGING_LOCATE
|
|
<a name="line172">172 |</a> ErrorLogger( NO_ERR_START, LOC, _proc_Locate_ModuleFile, "modulename = '",
|
|
<a name="line173">173 |</a> modulename, "'", NULL);
|
|
<a name="line174">174 |</a> #endif
|
|
<a name="line175">175 |</a>
|
|
<a name="line176">176 |</a> if( !modulename)
|
|
<a name="line177">177 |</a> if( OK != ErrorLogger( ERR_PARAM, LOC, "modulename", NULL))
|
|
<a name="line178">178 |</a> goto unwind0;
|
|
<a name="line179">179 |</a>
|
|
<a name="line180">180 |</a> if( modulename[0] == '/' || modulename[0] == '.') {
|
|
<a name="line181">181 |</a>
|
|
<a name="line182">182 |</a> p = (char*) strrchr( modulename, '/');
|
|
<a name="line183">183 |</a> if(p) {
|
|
<a name="line184">184 |</a> *p = '\0';
|
|
<a name="line185">185 |</a> /**
|
|
<a name="line186">186 |</a> ** Check, if what has been specified is a valid version of
|
|
<a name="line187">187 |</a> ** the specified module ...
|
|
<a name="line188">188 |</a> **/
|
|
<a name="line189">189 |</a> if((char *) NULL ==
|
|
<a name="line190">190 |</a> (result = GetModuleName(interp, modulename, NULL,(p+1))))
|
|
<a name="line191">191 |</a> goto unwind0;
|
|
<a name="line192">192 |</a> /**
|
|
<a name="line193">193 |</a> ** Reinstall the 'modulefile' which has been corrupted by
|
|
<a name="line194">194 |</a> ** tokenization
|
|
<a name="line195">195 |</a> **/
|
|
<a name="line196">196 |</a> *p = '/';
|
|
<a name="line197">197 |</a> /**
|
|
<a name="line198">198 |</a> ** Reinstall the 'modulefile' which has been corrupted by
|
|
<a name="line199">199 |</a> ** tokenization
|
|
<a name="line200">200 |</a> **/
|
|
<a name="line201">201 |</a> *p = '/';
|
|
<a name="line202">202 |</a>
|
|
<a name="line203">203 |</a> /**
|
|
<a name="line204">204 |</a> ** ... Looks good! Conditionally (if there has been no version
|
|
<a name="line205">205 |</a> ** specified) we have to add the default version
|
|
<a name="line206">206 |</a> **/
|
|
<a name="line207">207 |</a> if( !strcmp((p + 1), result)) {
|
|
<a name="line208">208 |</a> if ((char *) NULL == stringer( filename, MOD_BUFSIZE,
|
|
<a name="line209">209 |</a> modulename, NULL))
|
|
<a name="line210">210 |</a> goto unwind1;
|
|
<a name="line211">211 |</a> } else {
|
|
<a name="line212">212 |</a> if ((char *) NULL == stringer( filename, MOD_BUFSIZE,
|
|
<a name="line213">213 |</a> modulename,"/",result, NULL))
|
|
<a name="line214">214 |</a> goto unwind1;
|
|
<a name="line215">215 |</a> }
|
|
<a name="line216">216 |</a> } else {
|
|
<a name="line217">217 |</a> /**
|
|
<a name="line218">218 |</a> ** Hmm! There's no backslash in 'modulename'. So it MUST begin
|
|
<a name="line219">219 |</a> ** on '.' and MUST be part of the current directory
|
|
<a name="line220">220 |</a> **/
|
|
<a name="line221">221 |</a> if( NULL == (result = GetModuleName( interp, modulename, NULL,
|
|
<a name="line222">222 |</a> modulename)))
|
|
<a name="line223">223 |</a> goto unwind0;
|
|
<a name="line224">224 |</a>
|
|
<a name="line225">225 |</a> if( !strcmp( modulename, result) ||
|
|
<a name="line226">226 |</a> (strlen( modulename) + 1 + strlen( result) + 1 > MOD_BUFSIZE)) {
|
|
<a name="line227">227 |</a> if ((char *) NULL == stringer( filename, MOD_BUFSIZE,
|
|
<a name="line228">228 |</a> modulename, NULL))
|
|
<a name="line229">229 |</a> goto unwind1;
|
|
<a name="line230">230 |</a> } else {
|
|
<a name="line231">231 |</a> if ((char *) NULL == stringer( filename, MOD_BUFSIZE,
|
|
<a name="line232">232 |</a> modulename,"/",result, NULL))
|
|
<a name="line233">233 |</a> goto unwind1;
|
|
<a name="line234">234 |</a> }
|
|
<a name="line235">235 |</a> }
|
|
<a name="line236">236 |</a> /**
|
|
<a name="line237">237 |</a> ** So it is not a full path name what has been specified. Scan the
|
|
<a name="line238">238 |</a> ** MODULESPATH
|
|
<a name="line239">239 |</a> **/
|
|
<a name="line240">240 |</a> } else {
|
|
<a name="line241">241 |</a> /**
|
|
<a name="line242">242 |</a> ** If I don't find a path in MODULEPATH, there's nothing to search.
|
|
<a name="line243">243 |</a> **/
|
|
<a name="line244">244 |</a> if( !( modulespath = (char *) getenv( "MODULEPATH"))) {
|
|
<a name="line245">245 |</a> if( OK != ErrorLogger( ERR_MODULE_PATH, LOC, NULL)) {
|
|
<a name="line246">246 |</a> g_current_module = NULL;
|
|
<a name="line247">247 |</a> goto unwind0;
|
|
<a name="line248">248 |</a> }
|
|
<a name="line249">249 |</a> }
|
|
<a name="line250">250 |</a> /**
|
|
<a name="line251">251 |</a> ** strip off any extraneous new lines
|
|
<a name="line252">252 |</a> **/
|
|
<a name="line253">253 |</a> { char *end;
|
|
<a name="line254">254 |</a> if ((char *) NULL != (end = strrchr(modulespath, '\n'))) *end = '\0';
|
|
<a name="line255">255 |</a> }
|
|
<a name="line256">256 |</a> /**
|
|
<a name="line257">257 |</a> ** Expand the module name (in case it is a symbolic one). This must
|
|
<a name="line258">258 |</a> ** be done once here in order to expand any aliases
|
|
<a name="line259">259 |</a> **/
|
|
<a name="line260">260 |</a> if( VersionLookup( modulename, &mod, &vers)) {
|
|
<a name="line261">261 |</a> if ((char *) NULL == stringer( buf, MOD_BUFSIZE,
|
|
<a name="line262">262 |</a> mod,"/",vers, NULL))
|
|
<a name="line263">263 |</a> goto unwind0;
|
|
<a name="line264">264 |</a> modulename = buf;
|
|
<a name="line265">265 |</a> }
|
|
<a name="line266">266 |</a> /**
|
|
<a name="line267">267 |</a> ** Split up the MODULEPATH values into multiple directories
|
|
<a name="line268">268 |</a> **/
|
|
<a name="line269">269 |</a> if( NULL == (pathlist = SplitIntoList(interp, modulespath, &numpaths)))
|
|
<a name="line270">270 |</a> goto unwind0;
|
|
<a name="line271">271 |</a> /**
|
|
<a name="line272">272 |</a> ** Check each directory to see if it contains the module
|
|
<a name="line273">273 |</a> **/
|
|
<a name="line274">274 |</a> for(i=0; i<numpaths; i++) {
|
|
<a name="line275">275 |</a> if( NULL != (result = GetModuleName( interp, pathlist[i], NULL,
|
|
<a name="line276">276 |</a> modulename))) {
|
|
<a name="line277">277 |</a>
|
|
<a name="line278">278 |</a> if( strlen( pathlist[i]) + 2 + strlen( result) > MOD_BUFSIZE) {
|
|
<a name="line279">279 |</a> if ((char *) NULL == stringer( filename, MOD_BUFSIZE,
|
|
<a name="line280">280 |</a> pathlist[i], NULL))
|
|
<a name="line281">281 |</a> goto unwind1;
|
|
<a name="line282">282 |</a> } else {
|
|
<a name="line283">283 |</a> if ((char *) NULL == stringer( filename, MOD_BUFSIZE,
|
|
<a name="line284">284 |</a> pathlist[i],"/",result, NULL))
|
|
<a name="line285">285 |</a> goto unwind1;
|
|
<a name="line286">286 |</a> }
|
|
<a name="line287">287 |</a> break;
|
|
<a name="line288">288 |</a> }
|
|
<a name="line289">289 |</a> /**
|
|
<a name="line290">290 |</a> ** If we havn't found it, we should try to re-expand the module
|
|
<a name="line291">291 |</a> ** name, because some rc file have been sourced
|
|
<a name="line292">292 |</a> **/
|
|
<a name="line293">293 |</a> if( VersionLookup( modulename, &mod, &vers)) {
|
|
<a name="line294">294 |</a> if ((char *) NULL == stringer( buf, MOD_BUFSIZE,
|
|
<a name="line295">295 |</a> mod,"/",vers, NULL))
|
|
<a name="line296">296 |</a> goto unwind1;
|
|
<a name="line297">297 |</a> modulename = buf;
|
|
<a name="line298">298 |</a> }
|
|
<a name="line299">299 |</a> } /** for **/
|
|
<a name="line300">300 |</a> /**
|
|
<a name="line301">301 |</a> ** Free the memory created from the call to SplitIntoList()
|
|
<a name="line302">302 |</a> **/
|
|
<a name="line303">303 |</a> FreeList( pathlist, numpaths);
|
|
<a name="line304">304 |</a> /**
|
|
<a name="line305">305 |</a> ** If result still NULL, then we really never found it and we should
|
|
<a name="line306">306 |</a> ** return ERROR and clear the full_path array for cleanliness.
|
|
<a name="line307">307 |</a> **/
|
|
<a name="line308">308 |</a> if( !result) {
|
|
<a name="line309">309 |</a> filename[0] = '\0';
|
|
<a name="line310">310 |</a> goto unwind0;
|
|
<a name="line311">311 |</a> }
|
|
<a name="line312">312 |</a> } /** not a full path name **/
|
|
<a name="line313">313 |</a> /**
|
|
<a name="line314">314 |</a> ** Free up what has been allocated and pass the result back to
|
|
<a name="line315">315 |</a> ** the caller and save the real module file name returned by
|
|
<a name="line316">316 |</a> ** GetModuleName
|
|
<a name="line317">317 |</a> **/
|
|
<a name="line318">318 |</a> strncpy( realname, result, MOD_BUFSIZE);
|
|
<a name="line319">319 |</a> if ((char *) NULL == stringer( realname, MOD_BUFSIZE, result, NULL))
|
|
<a name="line320">320 |</a> goto unwind1;
|
|
<a name="line321">321 |</a> null_free((void *) &result);
|
|
<a name="line322">322 |</a>
|
|
<a name="line323">323 |</a> #if WITH_DEBUGGING_LOCATE
|
|
<a name="line324">324 |</a> ErrorLogger( NO_ERR_END, LOC, _proc_Locate_ModuleFile, NULL);
|
|
<a name="line325">325 |</a> #endif
|
|
<a name="line326">326 |</a>
|
|
<a name="line327">327 |</a> return( TCL_OK);
|
|
<a name="line328">328 |</a>
|
|
<a name="line329">329 |</a> unwind1:
|
|
<a name="line330">330 |</a> null_free((void *) &result);
|
|
<a name="line331">331 |</a> unwind0:
|
|
<a name="line332">332 |</a> return( TCL_ERROR);
|
|
<a name="line333">333 |</a> }
|
|
<a name="line334">334 |</a>
|
|
<a name="line335">335 |</a> /*++++
|
|
<a name="line336">336 |</a> ** ** Function-Header ***************************************************** **
|
|
<a name="line337">337 |</a> ** **
|
|
<a name="line338">338 |</a> ** Function: GetModuleName **
|
|
<a name="line339">339 |</a> ** **
|
|
<a name="line340">340 |</a> ** Description: Given a path and a module filename, this function **
|
|
<a name="line341">341 |</a> ** checks to find the modulefile. **
|
|
<a name="line342">342 |</a> ** **
|
|
<a name="line343">343 |</a> ** Notes: This function is RECURSIVE **
|
|
<a name="line344">344 |</a> ** **
|
|
<a name="line345">345 |</a> ** First Edition: 1991/10/23 **
|
|
<a name="line346">346 |</a> ** **
|
|
<a name="line347">347 |</a> ** Parameters: Tcl_Interp *interp According Tcl Interp.**
|
|
<a name="line348">348 |</a> ** char *path Path to start seeking**
|
|
<a name="line349">349 |</a> ** char *prefix Module name prefix **
|
|
<a name="line350">350 |</a> ** char *modulename Name of the module **
|
|
<a name="line351">351 |</a> ** **
|
|
<a name="line352">352 |</a> ** Result: char* NULL Any failure( parameters, alloc) **
|
|
<a name="line353">353 |</a> ** else Pointer to an allocated buffer con- **
|
|
<a name="line354">354 |</a> ** taining the complete module file path**
|
|
<a name="line355">355 |</a> ** **
|
|
<a name="line356">356 |</a> ** Attached Globals: - **
|
|
<a name="line357">357 |</a> ** **
|
|
<a name="line358">358 |</a> ** ************************************************************************ **
|
|
<a name="line359">359 |</a> ++++*/
|
|
<a name="line360">360 |</a>
|
|
<a name="line361">361 |</a> static char *GetModuleName( Tcl_Interp *interp,
|
|
<a name="line362">362 |</a> char *path,
|
|
<a name="line363">363 |</a> char *prefix,
|
|
<a name="line364">364 |</a> char *modulename)
|
|
<a name="line365">365 |</a> {
|
|
<a name="line366">366 |</a> struct stat stats; /** Buffer for the stat() systemcall **/
|
|
<a name="line367">367 |</a> char *fullpath = NULL; /** Buffer for creating path names **/
|
|
<a name="line368">368 |</a> char *Result = NULL; /** Our return value **/
|
|
<a name="line369">369 |</a> char **filelist = NULL; /** Buffer for a list of possible **/
|
|
<a name="line370">370 |</a> /** module files **/
|
|
<a name="line371">371 |</a> int numlist; /** Size of this list **/
|
|
<a name="line372">372 |</a> int i, slen, is_def;
|
|
<a name="line373">373 |</a> char *s, *t; /** Private string buffer **/
|
|
<a name="line374">374 |</a> char *mod, *ver; /** Pointer to module and version **/
|
|
<a name="line375">375 |</a> char *mod1, *ver1; /** Temp pointer **/
|
|
<a name="line376">376 |</a>
|
|
<a name="line377">377 |</a> #if WITH_DEBUGGING_LOCATE_1
|
|
<a name="line378">378 |</a> ErrorLogger( NO_ERR_START, LOC, _proc_GetModuleName, NULL);
|
|
<a name="line379">379 |</a> #endif
|
|
<a name="line380">380 |</a> /**
|
|
<a name="line381">381 |</a> ** Split the modulename into module and version. Use a private buffer
|
|
<a name="line382">382 |</a> ** for this
|
|
<a name="line383">383 |</a> **/
|
|
<a name="line384">384 |</a> if((char *) NULL == (s = stringer(NULL, 0, modulename, NULL))) {
|
|
<a name="line385">385 |</a> ErrorLogger( ERR_ALLOC, LOC, NULL);
|
|
<a name="line386">386 |</a> goto unwind0;
|
|
<a name="line387">387 |</a> }
|
|
<a name="line388">388 |</a> slen = strlen( s) + 1;
|
|
<a name="line389">389 |</a> mod = s;
|
|
<a name="line390">390 |</a> if( ver = strchr( mod, '/'))
|
|
<a name="line391">391 |</a> *ver++ = '\0';
|
|
<a name="line392">392 |</a> /**
|
|
<a name="line393">393 |</a> ** Allocate a buffer for full pathname building
|
|
<a name="line394">394 |</a> **/
|
|
<a name="line395">395 |</a> if((char *) NULL == (fullpath = stringer(NULL, MOD_BUFSIZE, NULL))) {
|
|
<a name="line396">396 |</a> if( OK != ErrorLogger( ERR_STRING, LOC, NULL)) {
|
|
<a name="line397">397 |</a> goto unwind1;
|
|
<a name="line398">398 |</a> }
|
|
<a name="line399">399 |</a> }
|
|
<a name="line400">400 |</a> /**
|
|
<a name="line401">401 |</a> ** Check whether $path/$prefix/$mod is a directory
|
|
<a name="line402">402 |</a> **/
|
|
<a name="line403">403 |</a> if( prefix) {
|
|
<a name="line404">404 |</a> if((char *) NULL == stringer(fullpath, MOD_BUFSIZE,
|
|
<a name="line405">405 |</a> path,"/",prefix,"/",mod, NULL))
|
|
<a name="line406">406 |</a> goto unwind1;
|
|
<a name="line407">407 |</a> } else {
|
|
<a name="line408">408 |</a> if((char *) NULL == stringer(fullpath, MOD_BUFSIZE,
|
|
<a name="line409">409 |</a> path,"/",mod, NULL))
|
|
<a name="line410">410 |</a> goto unwind1;
|
|
<a name="line411">411 |</a> }
|
|
<a name="line412">412 |</a> is_def = !strcmp( mod, _default);
|
|
<a name="line413">413 |</a>
|
|
<a name="line414">414 |</a> if( is_def || !stat( fullpath, &stats)) {
|
|
<a name="line415">415 |</a> /**
|
|
<a name="line416">416 |</a> ** If it is a directory
|
|
<a name="line417">417 |</a> **/
|
|
<a name="line418">418 |</a> if( !is_def && S_ISDIR( stats.st_mode)) {
|
|
<a name="line419">419 |</a> /**
|
|
<a name="line420">420 |</a> ** Source the ".modulerc" file if it exists
|
|
<a name="line421">421 |</a> ** For compatibility source the .version file, too
|
|
<a name="line422">422 |</a> **/
|
|
<a name="line423">423 |</a> if( prefix) {
|
|
<a name="line424">424 |</a> if((char *) NULL == stringer(modfil_buf, MOD_BUFSIZE,
|
|
<a name="line425">425 |</a> path,"/",mod, NULL))
|
|
<a name="line426">426 |</a> goto unwind2;
|
|
<a name="line427">427 |</a> } else {
|
|
<a name="line428">428 |</a> if((char *) NULL == stringer(modfil_buf, MOD_BUFSIZE,mod, NULL))
|
|
<a name="line429">429 |</a> goto unwind2;
|
|
<a name="line430">430 |</a> }
|
|
<a name="line431">431 |</a>
|
|
<a name="line432">432 |</a> if((char *) NULL == stringer(fullpath, MOD_BUFSIZE,
|
|
<a name="line433">433 |</a> path,"/",modfil_buf, NULL))
|
|
<a name="line434">434 |</a> goto unwind2;
|
|
<a name="line435">435 |</a> g_current_module = modfil_buf;
|
|
<a name="line436">436 |</a>
|
|
<a name="line437">437 |</a> if( TCL_ERROR == SourceRC( interp, fullpath, modulerc_file) ||
|
|
<a name="line438">438 |</a> TCL_ERROR == SourceVers( interp, fullpath, modfil_buf)) {
|
|
<a name="line439">439 |</a> /* flags = save_flags; */
|
|
<a name="line440">440 |</a> goto unwind2;
|
|
<a name="line441">441 |</a> }
|
|
<a name="line442">442 |</a> /**
|
|
<a name="line443">443 |</a> ** After sourcing the RC files, we have to look up versions again
|
|
<a name="line444">444 |</a> **/
|
|
<a name="line445">445 |</a> if( VersionLookup( modulename, &mod1, &ver1)) {
|
|
<a name="line446">446 |</a> int len = strlen( mod1) + strlen( ver1) + 2;
|
|
<a name="line447">447 |</a> /**
|
|
<a name="line448">448 |</a> ** Maybe we have to enlarge s
|
|
<a name="line449">449 |</a> **/
|
|
<a name="line450">450 |</a> if( len > slen) {
|
|
<a name="line451">451 |</a> null_free((void *) &s);
|
|
<a name="line452">452 |</a> if((char *) NULL == (s = stringer( NULL, len, NULL))) {
|
|
<a name="line453">453 |</a> ErrorLogger( ERR_STRING, LOC, NULL);
|
|
<a name="line454">454 |</a> goto unwind2;
|
|
<a name="line455">455 |</a> }
|
|
<a name="line456">456 |</a> slen = len;
|
|
<a name="line457">457 |</a> }
|
|
<a name="line458">458 |</a> /**
|
|
<a name="line459">459 |</a> ** Print the new module/version in the buffer
|
|
<a name="line460">460 |</a> **/
|
|
<a name="line461">461 |</a> if((char *) NULL == stringer( s, len, mod1,"/", ver1, NULL)) {
|
|
<a name="line462">462 |</a> ErrorLogger( ERR_STRING, LOC, NULL);
|
|
<a name="line463">463 |</a> goto unwind2;
|
|
<a name="line464">464 |</a> }
|
|
<a name="line465">465 |</a> mod = s;
|
|
<a name="line466">466 |</a> if( ver = strchr( s, '/'))
|
|
<a name="line467">467 |</a> *ver++ = '\0';
|
|
<a name="line468">468 |</a> }
|
|
<a name="line469">469 |</a> /**
|
|
<a name="line470">470 |</a> ** recursively delve into subdirectories (until ver == NULL).
|
|
<a name="line471">471 |</a> **/
|
|
<a name="line472">472 |</a> if( ver) {
|
|
<a name="line473">473 |</a> int len = strlen( mod) + 1;
|
|
<a name="line474">474 |</a>
|
|
<a name="line475">475 |</a> if( prefix)
|
|
<a name="line476">476 |</a> len += strlen( prefix) +1;
|
|
<a name="line477">477 |</a> /**
|
|
<a name="line478">478 |</a> ** Build the new prefix
|
|
<a name="line479">479 |</a> **/
|
|
<a name="line480">480 |</a> if((char *) NULL == (t = stringer(NULL, len, NULL))) {
|
|
<a name="line481">481 |</a> ErrorLogger( ERR_STRING, LOC, NULL);
|
|
<a name="line482">482 |</a> goto unwind2;
|
|
<a name="line483">483 |</a> }
|
|
<a name="line484">484 |</a>
|
|
<a name="line485">485 |</a> if( prefix) {
|
|
<a name="line486">486 |</a> if((char *) NULL == stringer(t, len, prefix,"/",mod, NULL)){
|
|
<a name="line487">487 |</a> ErrorLogger( ERR_STRING, LOC, NULL);
|
|
<a name="line488">488 |</a> goto unwindt;
|
|
<a name="line489">489 |</a> }
|
|
<a name="line490">490 |</a> } else {
|
|
<a name="line491">491 |</a> if((char *) NULL == stringer(t, len, mod, NULL)){
|
|
<a name="line492">492 |</a> ErrorLogger( ERR_STRING, LOC, NULL);
|
|
<a name="line493">493 |</a> goto unwindt;
|
|
<a name="line494">494 |</a> }
|
|
<a name="line495">495 |</a> }
|
|
<a name="line496">496 |</a> /**
|
|
<a name="line497">497 |</a> ** This is the recursion
|
|
<a name="line498">498 |</a> **/
|
|
<a name="line499">499 |</a> Result = GetModuleName( interp, path, t, ver);
|
|
<a name="line500">500 |</a>
|
|
<a name="line501">501 |</a> /**
|
|
<a name="line502">502 |</a> ** Free our temporary prefix buffer
|
|
<a name="line503">503 |</a> **/
|
|
<a name="line504">504 |</a> null_free((void *) &t);
|
|
<a name="line505">505 |</a> if (0) { /* an error occurred */
|
|
<a name="line506">506 |</a> unwindt:
|
|
<a name="line507">507 |</a> null_free((void *) &t);
|
|
<a name="line508">508 |</a> goto unwind2;
|
|
<a name="line509">509 |</a> }
|
|
<a name="line510">510 |</a> }
|
|
<a name="line511">511 |</a> } else { /** if( $path/$prefix/$mod is a directory) **/
|
|
<a name="line512">512 |</a> /**
|
|
<a name="line513">513 |</a> ** Now 'mod' should be either a file or the word 'default'
|
|
<a name="line514">514 |</a> ** In case of default get the file with the highest verion number
|
|
<a name="line515">515 |</a> ** in the current directory
|
|
<a name="line516">516 |</a> **/
|
|
<a name="line517">517 |</a> if( is_def) {
|
|
<a name="line518">518 |</a> if( !prefix)
|
|
<a name="line519">519 |</a> prefix = ".";
|
|
<a name="line520">520 |</a> if( NULL == (filelist = SortedDirList( interp, path, prefix,
|
|
<a name="line521">521 |</a> &numlist)))
|
|
<a name="line522">522 |</a> goto unwind1;
|
|
<a name="line523">523 |</a>
|
|
<a name="line524">524 |</a> prefix = (char *) NULL;
|
|
<a name="line525">525 |</a> /**
|
|
<a name="line526">526 |</a> ** Select the first one on the list which is either a
|
|
<a name="line527">527 |</a> ** modulefile or another directory. We start at the highest
|
|
<a name="line528">528 |</a> ** lexicographical name in the directory since the filelist
|
|
<a name="line529">529 |</a> ** is reverse sorted.
|
|
<a name="line530">530 |</a> ** If it's a directory, we delve into it.
|
|
<a name="line531">531 |</a> **/
|
|
<a name="line532">532 |</a> for( i=0; i<numlist && Result==NULL; i++) {
|
|
<a name="line533">533 |</a> /**
|
|
<a name="line534">534 |</a> ** Build the full path name and check if it is a
|
|
<a name="line535">535 |</a> ** directory. If it is, recursivly try to find there what
|
|
<a name="line536">536 |</a> ** we're seeking for
|
|
<a name="line537">537 |</a> **/
|
|
<a name="line538">538 |</a> if ((char *)NULL == stringer(fullpath, MOD_BUFSIZE,
|
|
<a name="line539">539 |</a> path, "/", filelist[i], NULL))
|
|
<a name="line540">540 |</a> goto unwind2;
|
|
<a name="line541">541 |</a>
|
|
<a name="line542">542 |</a> if( !stat( fullpath, &stats) && S_ISDIR( stats.st_mode)) {
|
|
<a name="line543">543 |</a> Result = GetModuleName( interp, path, prefix,
|
|
<a name="line544">544 |</a> filelist[ i]);
|
|
<a name="line545">545 |</a> } else {
|
|
<a name="line546">546 |</a> /**
|
|
<a name="line547">547 |</a> ** Otherwise check the file for a magic cookie ...
|
|
<a name="line548">548 |</a> **/
|
|
<a name="line549">549 |</a> if( check_magic( fullpath, MODULES_MAGIC_COOKIE,
|
|
<a name="line550">550 |</a> MODULES_MAGIC_COOKIE_LENGTH))
|
|
<a name="line551">551 |</a> Result = filelist[ i];
|
|
<a name="line552">552 |</a> } /** if( !stat) **/
|
|
<a name="line553">553 |</a> } /** for **/
|
|
<a name="line554">554 |</a> } else { /** default **/
|
|
<a name="line555">555 |</a> /**
|
|
<a name="line556">556 |</a> ** If mod names a file, we have to check wheter it exists and
|
|
<a name="line557">557 |</a> ** is a valid module file
|
|
<a name="line558">558 |</a> **/
|
|
<a name="line559">559 |</a> if( check_magic( fullpath, MODULES_MAGIC_COOKIE,
|
|
<a name="line560">560 |</a> MODULES_MAGIC_COOKIE_LENGTH))
|
|
<a name="line561">561 |</a> Result = mod;
|
|
<a name="line562">562 |</a> else {
|
|
<a name="line563">563 |</a> ErrorLogger( ERR_MAGIC, LOC, fullpath, NULL);
|
|
<a name="line564">564 |</a> Result = NULL;
|
|
<a name="line565">565 |</a> }
|
|
<a name="line566">566 |</a> } /** if( mod is a filename) **/
|
|
<a name="line567">567 |</a> /**
|
|
<a name="line568">568 |</a> ** Build the full filename (using prefix and Result) if
|
|
<a name="line569">569 |</a> ** Result is defined
|
|
<a name="line570">570 |</a> **/
|
|
<a name="line571">571 |</a> if( Result) {
|
|
<a name="line572">572 |</a> int len = strlen( Result) + 1;
|
|
<a name="line573">573 |</a>
|
|
<a name="line574">574 |</a> if( prefix)
|
|
<a name="line575">575 |</a> len += strlen( prefix) + 1;
|
|
<a name="line576">576 |</a>
|
|
<a name="line577">577 |</a> if((char *) NULL == (t = stringer(NULL, len, NULL))) {
|
|
<a name="line578">578 |</a> ErrorLogger( ERR_STRING, LOC, NULL);
|
|
<a name="line579">579 |</a> goto unwind2;
|
|
<a name="line580">580 |</a> }
|
|
<a name="line581">581 |</a> if( prefix) {
|
|
<a name="line582">582 |</a> if((char *) NULL == stringer(t,len, prefix,"/",Result,NULL))
|
|
<a name="line583">583 |</a> goto unwindt2;
|
|
<a name="line584">584 |</a> } else {
|
|
<a name="line585">585 |</a> if((char *) NULL == stringer(t,len, Result,NULL))
|
|
<a name="line586">586 |</a> goto unwindt2;
|
|
<a name="line587">587 |</a> }
|
|
<a name="line588">588 |</a> Result = t;
|
|
<a name="line589">589 |</a> if (0) { /* an error occurred */
|
|
<a name="line590">590 |</a> unwindt2:
|
|
<a name="line591">591 |</a> null_free((void *) &t);
|
|
<a name="line592">592 |</a> goto unwind2;
|
|
<a name="line593">593 |</a> }
|
|
<a name="line594">594 |</a> }
|
|
<a name="line595">595 |</a> } /** mod is a file **/
|
|
<a name="line596">596 |</a> } /** mod exists **/
|
|
<a name="line597">597 |</a> /**
|
|
<a name="line598">598 |</a> ** Free up temporary values and return what we've found
|
|
<a name="line599">599 |</a> **/
|
|
<a name="line600">600 |</a> null_free((void*) &fullpath);
|
|
<a name="line601">601 |</a> null_free((void*) &s);
|
|
<a name="line602">602 |</a> FreeList( filelist, numlist);
|
|
<a name="line603">603 |</a>
|
|
<a name="line604">604 |</a> #if WITH_DEBUGGING_LOCATE_1
|
|
<a name="line605">605 |</a> ErrorLogger( NO_ERR_END, LOC, _proc_GetModuleName, NULL);
|
|
<a name="line606">606 |</a> #endif
|
|
<a name="line607">607 |</a> return( Result); /** -------- EXIT (SUCCESS) -------> **/
|
|
<a name="line608">608 |</a>
|
|
<a name="line609">609 |</a> unwind2:
|
|
<a name="line610">610 |</a> null_free((void *) &fullpath);
|
|
<a name="line611">611 |</a> unwind1:
|
|
<a name="line612">612 |</a> null_free((void *) &s);
|
|
<a name="line613">613 |</a> unwind0:
|
|
<a name="line614">614 |</a> return(NULL); /** -------- EXIT (FAILURE) -------> **/
|
|
<a name="line615">615 |</a>
|
|
<a name="line616">616 |</a> } /** End of 'GetModuleName' **/
|
|
<a name="line617">617 |</a>
|
|
<a name="line618">618 |</a> /*++++
|
|
<a name="line619">619 |</a> ** ** Function-Header ***************************************************** **
|
|
<a name="line620">620 |</a> ** **
|
|
<a name="line621">621 |</a> ** Function: SortedDirList **
|
|
<a name="line622">622 |</a> ** **
|
|
<a name="line623">623 |</a> ** Description: Checks the given path for the given modulefile. **
|
|
<a name="line624">624 |</a> ** If the path + the module filename is the modulefile, **
|
|
<a name="line625">625 |</a> ** then it is returned as the first element in the list.**
|
|
<a name="line626">626 |</a> ** If the path + the module filename is a directory, the**
|
|
<a name="line627">627 |</a> ** directory is read and sorted as the list. **
|
|
<a name="line628">628 |</a> ** **
|
|
<a name="line629">629 |</a> ** First Edition: 1991/10/23 **
|
|
<a name="line630">630 |</a> ** **
|
|
<a name="line631">631 |</a> ** Parameters: Tcl_Interp *interp According Tcl Interp.**
|
|
<a name="line632">632 |</a> ** char *path Path to start seeking**
|
|
<a name="line633">633 |</a> ** char *modulename Name of the module **
|
|
<a name="line634">634 |</a> ** int *listcnt Buffer to return the **
|
|
<a name="line635">635 |</a> ** size of the created **
|
|
<a name="line636">636 |</a> ** list in elements **
|
|
<a name="line637">637 |</a> ** **
|
|
<a name="line638">638 |</a> ** Result: char** NULL Any failure (alloc, param) **
|
|
<a name="line639">639 |</a> ** else Base pointer to the newly **
|
|
<a name="line640">640 |</a> ** created list. **
|
|
<a name="line641">641 |</a> ** *listcnt Number of elements in the **
|
|
<a name="line642">642 |</a> ** list if one was created, un- **
|
|
<a name="line643">643 |</a> ** changed otherwise **
|
|
<a name="line644">644 |</a> ** **
|
|
<a name="line645">645 |</a> ** Attached Globals: - **
|
|
<a name="line646">646 |</a> ** **
|
|
<a name="line647">647 |</a> ** ************************************************************************ **
|
|
<a name="line648">648 |</a> ++++*/
|
|
<a name="line649">649 |</a>
|
|
<a name="line650">650 |</a> char **SortedDirList( Tcl_Interp *interp,
|
|
<a name="line651">651 |</a> char *path,
|
|
<a name="line652">652 |</a> char *modulename,
|
|
<a name="line653">653 |</a> int *listcnt)
|
|
<a name="line654">654 |</a> {
|
|
<a name="line655">655 |</a> struct dirent *file; /** Directory entry **/
|
|
<a name="line656">656 |</a> struct stat stats; /** Stat buffer **/
|
|
<a name="line657">657 |</a> DIR *subdirp; /** Subdirectoy handle **/
|
|
<a name="line658">658 |</a> char *full_path; /** Sugg. full path (path + module) **/
|
|
<a name="line659">659 |</a> char **filelist; /** Temp. base pointer of the list **/
|
|
<a name="line660">660 |</a> int i, /** Number of entries in the subdir **/
|
|
<a name="line661">661 |</a> j, /** Counts the number of list-entries**/
|
|
<a name="line662">662 |</a> n, /** Size of the allocated array **/
|
|
<a name="line663">663 |</a> pathlen; /** String length of 'fullpath' **/
|
|
<a name="line664">664 |</a>
|
|
<a name="line665">665 |</a> #if WITH_DEBUGGING_UTIL_1
|
|
<a name="line666">666 |</a> ErrorLogger( NO_ERR_START, LOC, _proc_SortedDirList, NULL);
|
|
<a name="line667">667 |</a> #endif
|
|
<a name="line668">668 |</a> /**
|
|
<a name="line669">669 |</a> ** Allocate memory for the list to be created. Suggest a list size of
|
|
<a name="line670">670 |</a> ** 100 Elements. This may be changed later on.
|
|
<a name="line671">671 |</a> **/
|
|
<a name="line672">672 |</a> if( NULL == (filelist = (char**) calloc( n = 100, sizeof(char*))))
|
|
<a name="line673">673 |</a> if( OK != ErrorLogger( ERR_ALLOC, LOC, NULL))
|
|
<a name="line674">674 |</a> goto unwind0;
|
|
<a name="line675">675 |</a> /**
|
|
<a name="line676">676 |</a> ** Form the suggested module file name out of the passed path and
|
|
<a name="line677">677 |</a> ** the name of the module. Alloc memory in order to do this.
|
|
<a name="line678">678 |</a> **/
|
|
<a name="line679">679 |</a> if((char *) NULL == (full_path = stringer(NULL, 0,
|
|
<a name="line680">680 |</a> path,"/",modulename, NULL)))
|
|
<a name="line681">681 |</a> if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
|
|
<a name="line682">682 |</a> goto unwind0;
|
|
<a name="line683">683 |</a> pathlen = strlen(full_path);
|
|
<a name="line684">684 |</a>
|
|
<a name="line685">685 |</a> #if WITH_DEBUGGING_UTIL_2
|
|
<a name="line686">686 |</a> ErrorLogger( NO_ERR_DEBUG, LOC, "full_path='", full_path, "'", NULL);
|
|
<a name="line687">687 |</a> #endif
|
|
<a name="line688">688 |</a> /**
|
|
<a name="line689">689 |</a> ** Check whether this file exists. If it doesn't free up everything
|
|
<a name="line690">690 |</a> ** and return on failure
|
|
<a name="line691">691 |</a> **/
|
|
<a name="line692">692 |</a> if( stat( full_path, &stats))
|
|
<a name="line693">693 |</a> goto unwind2;
|
|
<a name="line694">694 |</a> /**
|
|
<a name="line695">695 |</a> ** If the suggested module file is a regular one, we've found what we've
|
|
<a name="line696">696 |</a> ** seeked for. Put it on the top of the list and return.
|
|
<a name="line697">697 |</a> **/
|
|
<a name="line698">698 |</a> if( S_ISREG( stats.st_mode)) {
|
|
<a name="line699">699 |</a> *listcnt = 1;
|
|
<a name="line700">700 |</a> filelist[0] = strdup( modulename);
|
|
<a name="line701">701 |</a>
|
|
<a name="line702">702 |</a> #if WITH_DEBUGGING_UTIL_2
|
|
<a name="line703">703 |</a> ErrorLogger( NO_ERR_DEBUG, LOC, "Module '", modulename, "' found", NULL);
|
|
<a name="line704">704 |</a> #endif
|
|
<a name="line705">705 |</a>
|
|
<a name="line706">706 |</a> null_free((void*) &full_path);
|
|
<a name="line707">707 |</a> return( filelist); /** --- EXIT PROCEDURE (SUCCESS) --> **/
|
|
<a name="line708">708 |</a> }
|
|
<a name="line709">709 |</a> /**
|
|
<a name="line710">710 |</a> ** What we've found is a directory
|
|
<a name="line711">711 |</a> **/
|
|
<a name="line712">712 |</a> if( S_ISDIR( stats.st_mode)) {
|
|
<a name="line713">713 |</a> char *tbuf; /** Buffer for the whole filename for each **/
|
|
<a name="line714">714 |</a> /** content of the directory **/
|
|
<a name="line715">715 |</a> char *mpath; /** Pointer into *tbuf where to write the dir**/
|
|
<a name="line716">716 |</a> /** entry **/
|
|
<a name="line717">717 |</a>
|
|
<a name="line718">718 |</a> /**
|
|
<a name="line719">719 |</a> ** Open the directory for reading
|
|
<a name="line720">720 |</a> **/
|
|
<a name="line721">721 |</a> if( NULL == (subdirp = opendir( full_path))) {
|
|
<a name="line722">722 |</a> #if 0
|
|
<a name="line723">723 |</a> /* if you can't open the directory ... is that really an error? */
|
|
<a name="line724">724 |</a> if( OK != ErrorLogger( ERR_OPENDIR, LOC, full_path, NULL))
|
|
<a name="line725">725 |</a> #endif
|
|
<a name="line726">726 |</a> goto unwind2;
|
|
<a name="line727">727 |</a> }
|
|
<a name="line728">728 |</a> /**
|
|
<a name="line729">729 |</a> ** Allocate a buffer for constructing complete file names
|
|
<a name="line730">730 |</a> ** and initialize it with the directory part we do already know.
|
|
<a name="line731">731 |</a> **/
|
|
<a name="line732">732 |</a> if( NULL == (tbuf = stringer(NULL, MOD_BUFSIZE, full_path,"/", NULL)))
|
|
<a name="line733">733 |</a> if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
|
|
<a name="line734">734 |</a> goto unwind3;
|
|
<a name="line735">735 |</a>
|
|
<a name="line736">736 |</a> mpath = (tbuf + pathlen + 1);
|
|
<a name="line737">737 |</a> /**
|
|
<a name="line738">738 |</a> ** Now scan all entries of the just opened directory
|
|
<a name="line739">739 |</a> **/
|
|
<a name="line740">740 |</a> #if WITH_DEBUGGING_UTIL_2
|
|
<a name="line741">741 |</a> ErrorLogger( NO_ERR_DEBUG, LOC, "Reading directory '", full_path, "'", NULL);
|
|
<a name="line742">742 |</a> #endif
|
|
<a name="line743">743 |</a> for( file = readdir( subdirp), i = 0, j = 0;
|
|
<a name="line744">744 |</a> file != NULL;
|
|
<a name="line745">745 |</a> file = readdir( subdirp), i++) {
|
|
<a name="line746">746 |</a> /**
|
|
<a name="line747">747 |</a> ** Oops! This one exceeds our array. Enlarge it.
|
|
<a name="line748">748 |</a> **/
|
|
<a name="line749">749 |</a> if( j == n)
|
|
<a name="line750">750 |</a> if( NULL == (filelist =
|
|
<a name="line751">751 |</a> (char**) realloc((char*) filelist, n *= 2)))
|
|
<a name="line752">752 |</a> if( OK != ErrorLogger( ERR_ALLOC, LOC, NULL))
|
|
<a name="line753">753 |</a> goto unwindt;
|
|
<a name="line754">754 |</a> /**
|
|
<a name="line755">755 |</a> ** Now, if we got a real entry which is not '.*' or '..' and
|
|
<a name="line756">756 |</a> ** finally is not a temporary file (which are defined to end
|
|
<a name="line757">757 |</a> ** on '~' ...
|
|
<a name="line758">758 |</a> **/
|
|
<a name="line759">759 |</a> if( file->d_name &&
|
|
<a name="line760">760 |</a> *file->d_name != '.' &&
|
|
<a name="line761">761 |</a> strcmp( file->d_name, "..") &&
|
|
<a name="line762">762 |</a> file->d_name[ NLENGTH( file) - 1] != '~') {
|
|
<a name="line763">763 |</a> /**
|
|
<a name="line764">764 |</a> ** ... build the full pathname and check for the magic
|
|
<a name="line765">765 |</a> ** cookie or for another directory level in order to
|
|
<a name="line766">766 |</a> ** validate this as a modulefile entry we're seeking for.
|
|
<a name="line767">767 |</a> **/
|
|
<a name="line768">768 |</a> strcpy( mpath, file->d_name);
|
|
<a name="line769">769 |</a> if( check_magic( tbuf, MODULES_MAGIC_COOKIE,
|
|
<a name="line770">770 |</a> MODULES_MAGIC_COOKIE_LENGTH) ||
|
|
<a name="line771">771 |</a> !stat(tbuf, &stats) ) {
|
|
<a name="line772">772 |</a> /**
|
|
<a name="line773">773 |</a> ** Yep! Found! Put it on the list
|
|
<a name="line774">774 |</a> **/
|
|
<a name="line775">775 |</a> if((char *) NULL == (filelist[j] = stringer(NULL,0,
|
|
<a name="line776">776 |</a> modulename,"/",file->d_name, NULL)))
|
|
<a name="line777">777 |</a> if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
|
|
<a name="line778">778 |</a> goto unwindt;
|
|
<a name="line779">779 |</a> j++;
|
|
<a name="line780">780 |</a> } /** if( mag. cookie or directory) **/
|
|
<a name="line781">781 |</a> } /** if( not a dotfile) **/
|
|
<a name="line782">782 |</a> } /** for **/
|
|
<a name="line783">783 |</a> /**
|
|
<a name="line784">784 |</a> ** Put a terminator at the lists end and then sort the list
|
|
<a name="line785">785 |</a> **/
|
|
<a name="line786">786 |</a> filelist[ j] = NULL;
|
|
<a name="line787">787 |</a> qsort( (void*) filelist, (size_t) j, sizeof(char*), filename_compare);
|
|
<a name="line788">788 |</a> /**
|
|
<a name="line789">789 |</a> ** Free up temporary values ...
|
|
<a name="line790">790 |</a> **/
|
|
<a name="line791">791 |</a> if( -1 == closedir( subdirp))
|
|
<a name="line792">792 |</a> if( OK != ErrorLogger( ERR_CLOSEDIR, LOC, full_path, NULL)) {
|
|
<a name="line793">793 |</a> goto unwind2;
|
|
<a name="line794">794 |</a> }
|
|
<a name="line795">795 |</a> null_free((void*) &full_path);
|
|
<a name="line796">796 |</a> null_free((void*) &tbuf);
|
|
<a name="line797">797 |</a> /**
|
|
<a name="line798">798 |</a> ** Set up return values and pass the created list to the caller
|
|
<a name="line799">799 |</a> **/
|
|
<a name="line800">800 |</a> *listcnt = j;
|
|
<a name="line801">801 |</a> return( filelist); /** --- EXIT PROCEDURE (SUCCESS) --> **/
|
|
<a name="line802">802 |</a>
|
|
<a name="line803">803 |</a> if(0) {
|
|
<a name="line804">804 |</a> unwindt:
|
|
<a name="line805">805 |</a> null_free((void*) &tbuf);
|
|
<a name="line806">806 |</a> goto unwind3;
|
|
<a name="line807">807 |</a> }
|
|
<a name="line808">808 |</a> }
|
|
<a name="line809">809 |</a> /**
|
|
<a name="line810">810 |</a> ** If it is nor a regular file, neither a directory, we don't support
|
|
<a name="line811">811 |</a> ** it at all ...
|
|
<a name="line812">812 |</a> **/
|
|
<a name="line813">813 |</a> /** ??? What about links ??? **/
|
|
<a name="line814">814 |</a>
|
|
<a name="line815">815 |</a> unwind3:
|
|
<a name="line816">816 |</a> if( -1 == closedir( subdirp))
|
|
<a name="line817">817 |</a> ErrorLogger( ERR_CLOSEDIR, LOC, full_path, NULL);
|
|
<a name="line818">818 |</a> unwind2:
|
|
<a name="line819">819 |</a> null_free((void*) &full_path);
|
|
<a name="line820">820 |</a> unwind1:
|
|
<a name="line821">821 |</a> FreeList( filelist, n);
|
|
<a name="line822">822 |</a>
|
|
<a name="line823">823 |</a> unwind0:
|
|
<a name="line824">824 |</a> #if WITH_DEBUGGING_UTIL_1
|
|
<a name="line825">825 |</a> ErrorLogger( NO_ERR_END, LOC, _proc_SortedDirList, NULL);
|
|
<a name="line826">826 |</a> #endif
|
|
<a name="line827">827 |</a>
|
|
<a name="line828">828 |</a> return( NULL); /** --- EXIT PROCEDURE (FAILURE) --> **/
|
|
<a name="line829">829 |</a>
|
|
<a name="line830">830 |</a> } /** End of 'SortedDirList' **/
|
|
<a name="line831">831 |</a>
|
|
<a name="line832">832 |</a> /*++++
|
|
<a name="line833">833 |</a> ** ** Function-Header ***************************************************** **
|
|
<a name="line834">834 |</a> ** **
|
|
<a name="line835">835 |</a> ** Function: SplitIntoList **
|
|
<a name="line836">836 |</a> ** **
|
|
<a name="line837">837 |</a> ** Description: Splits a path-type environment variable into an array**
|
|
<a name="line838">838 |</a> ** of char* list. **
|
|
<a name="line839">839 |</a> ** **
|
|
<a name="line840">840 |</a> ** First Edition: 1991/10/23 **
|
|
<a name="line841">841 |</a> ** **
|
|
<a name="line842">842 |</a> ** Parameters: Tcl_Interp *interp According Tcl Interp.**
|
|
<a name="line843">843 |</a> ** char *pathenv Path to split **
|
|
<a name="line844">844 |</a> ** int *numpaths Buffer to write the **
|
|
<a name="line845">845 |</a> ** number of array ele- **
|
|
<a name="line846">846 |</a> ** ments to. **
|
|
<a name="line847">847 |</a> ** **
|
|
<a name="line848">848 |</a> ** Result: char** NULL Any failure (alloc, param.) **
|
|
<a name="line849">849 |</a> ** else Base pointer of the created **
|
|
<a name="line850">850 |</a> ** array **
|
|
<a name="line851">851 |</a> ** *numpaths Number of elements if an ar- **
|
|
<a name="line852">852 |</a> ** ray has been created, unchan-**
|
|
<a name="line853">853 |</a> ** ged otherwise. **
|
|
<a name="line854">854 |</a> ** **
|
|
<a name="line855">855 |</a> ** Attached Globals: - **
|
|
<a name="line856">856 |</a> ** **
|
|
<a name="line857">857 |</a> ** ************************************************************************ **
|
|
<a name="line858">858 |</a> ++++*/
|
|
<a name="line859">859 |</a>
|
|
<a name="line860">860 |</a> char **SplitIntoList( Tcl_Interp *interp,
|
|
<a name="line861">861 |</a> char *pathenv,
|
|
<a name="line862">862 |</a> int *numpaths)
|
|
<a name="line863">863 |</a> {
|
|
<a name="line864">864 |</a> char **pathlist = NULL; /** Temporary base pointer for the **/
|
|
<a name="line865">865 |</a> /** array to be created **/
|
|
<a name="line866">866 |</a> char *givenpath = NULL; /** Temporary buffer used to tokenize**/
|
|
<a name="line867">867 |</a> /** the passed input path **/
|
|
<a name="line868">868 |</a> char *dirname = NULL; /** Token pointer **/
|
|
<a name="line869">869 |</a> int i, /** Counts the number of elements **/
|
|
<a name="line870">870 |</a> n; /** Size of the array **/
|
|
<a name="line871">871 |</a>
|
|
<a name="line872">872 |</a> #if WITH_DEBUGGING_UTIL_1
|
|
<a name="line873">873 |</a> ErrorLogger( NO_ERR_START, LOC, _proc_SplitIntoList, NULL);
|
|
<a name="line874">874 |</a> #endif
|
|
<a name="line875">875 |</a> /**
|
|
<a name="line876">876 |</a> ** Paramter check
|
|
<a name="line877">877 |</a> **/
|
|
<a name="line878">878 |</a> if( !pathenv)
|
|
<a name="line879">879 |</a> if( OK != ErrorLogger( ERR_PARAM, LOC, "pathenv", NULL))
|
|
<a name="line880">880 |</a> goto unwind0;
|
|
<a name="line881">881 |</a> /**
|
|
<a name="line882">882 |</a> ** Allocate space to copy in the value of the path value to
|
|
<a name="line883">883 |</a> ** split. Thus this procedure doesn't change its input parameters.
|
|
<a name="line884">884 |</a> **/
|
|
<a name="line885">885 |</a> if( (char *) NULL == (givenpath = stringer(NULL,0, pathenv,NULL)))
|
|
<a name="line886">886 |</a> if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
|
|
<a name="line887">887 |</a> goto unwind0;
|
|
<a name="line888">888 |</a> /**
|
|
<a name="line889">889 |</a> ** Allocate the list which is an array of char*. n is used to
|
|
<a name="line890">890 |</a> ** manage the array's growth if there are more than 100 paths in
|
|
<a name="line891">891 |</a> ** the list.
|
|
<a name="line892">892 |</a> ** Copy the passed path into the new buffer.
|
|
<a name="line893">893 |</a> **/
|
|
<a name="line894">894 |</a> if((char **) NULL == (pathlist = (char**) calloc( n = 100, sizeof( char*))))
|
|
<a name="line895">895 |</a> if( OK != ErrorLogger( ERR_ALLOC, LOC, NULL))
|
|
<a name="line896">896 |</a> goto unwind1;
|
|
<a name="line897">897 |</a> /**
|
|
<a name="line898">898 |</a> ** Split the given path environment variable into its components.
|
|
<a name="line899">899 |</a> **/
|
|
<a name="line900">900 |</a> for( i=0, dirname = strtok( givenpath, ": ");
|
|
<a name="line901">901 |</a> dirname;
|
|
<a name="line902">902 |</a> dirname = strtok( NULL, ": ")) {
|
|
<a name="line903">903 |</a> /**
|
|
<a name="line904">904 |</a> ** Oops! The number of tokens exceed my array - reallocate it
|
|
<a name="line905">905 |</a> ** and double its size!
|
|
<a name="line906">906 |</a> **/
|
|
<a name="line907">907 |</a> if( i == n )
|
|
<a name="line908">908 |</a> if((char **) NULL == (pathlist = (char**) realloc((char*) pathlist,
|
|
<a name="line909">909 |</a> n *= 2)))
|
|
<a name="line910">910 |</a> if( OK != ErrorLogger( ERR_ALLOC, LOC, NULL))
|
|
<a name="line911">911 |</a> goto unwind1;
|
|
<a name="line912">912 |</a> /**
|
|
<a name="line913">913 |</a> ** Put the token into the array. Therefor a new area is allocated for
|
|
<a name="line914">914 |</a> ** the token using 'xdup' - which expands 1 level of env.vars.
|
|
<a name="line915">915 |</a> **/
|
|
<a name="line916">916 |</a> if( NULL == (pathlist[ i++] = xdup( dirname)))
|
|
<a name="line917">917 |</a> if( OK != ErrorLogger( ERR_ALLOC, LOC, NULL)) {
|
|
<a name="line918">918 |</a> FreeList( pathlist, --i);
|
|
<a name="line919">919 |</a> goto unwind1;
|
|
<a name="line920">920 |</a> }
|
|
<a name="line921">921 |</a> } /** for **/
|
|
<a name="line922">922 |</a> /**
|
|
<a name="line923">923 |</a> ** Free up the temporary working array
|
|
<a name="line924">924 |</a> **/
|
|
<a name="line925">925 |</a> if( givenpath)
|
|
<a name="line926">926 |</a> null_free((void*) &givenpath);
|
|
<a name="line927">927 |</a> /**
|
|
<a name="line928">928 |</a> ** Set up the return value (Number of elements allocated) and pass
|
|
<a name="line929">929 |</a> ** the arrays base pointer to the caller
|
|
<a name="line930">930 |</a> **/
|
|
<a name="line931">931 |</a> *numpaths = i;
|
|
<a name="line932">932 |</a> return( pathlist);
|
|
<a name="line933">933 |</a>
|
|
<a name="line934">934 |</a> unwind1:
|
|
<a name="line935">935 |</a> null_free((void *) &givenpath);
|
|
<a name="line936">936 |</a> unwind0:
|
|
<a name="line937">937 |</a> return( NULL); /** -------- EXIT FAILURE -------> **/
|
|
<a name="line938">938 |</a> } /** End of 'SplitIntoList' **/
|
|
<a name="line939">939 |</a>
|
|
<a name="line940">940 |</a> #ifndef FreeList
|
|
<a name="line941">941 |</a>
|
|
<a name="line942">942 |</a> /*++++
|
|
<a name="line943">943 |</a> ** ** Function-Header ***************************************************** **
|
|
<a name="line944">944 |</a> ** **
|
|
<a name="line945">945 |</a> ** Function: FreeList **
|
|
<a name="line946">946 |</a> ** **
|
|
<a name="line947">947 |</a> ** Description: Frees a char* array type list. **
|
|
<a name="line948">948 |</a> ** **
|
|
<a name="line949">949 |</a> ** First Edition: 1991/10/23 **
|
|
<a name="line950">950 |</a> ** **
|
|
<a name="line951">951 |</a> ** Parameters: char **list Pointer to the list **
|
|
<a name="line952">952 |</a> ** int numelem Number of elements in the **
|
|
<a name="line953">953 |</a> ** list **
|
|
<a name="line954">954 |</a> ** Result: - **
|
|
<a name="line955">955 |</a> ** **
|
|
<a name="line956">956 |</a> ** Attached Globals: - **
|
|
<a name="line957">957 |</a> ** **
|
|
<a name="line958">958 |</a> ** ************************************************************************ **
|
|
<a name="line959">959 |</a> ++++*/
|
|
<a name="line960">960 |</a>
|
|
<a name="line961">961 |</a> void FreeList( char **list,
|
|
<a name="line962">962 |</a> int numelem)
|
|
<a name="line963">963 |</a> {
|
|
<a name="line964">964 |</a> register int j;
|
|
<a name="line965">965 |</a>
|
|
<a name="line966">966 |</a> #if WITH_DEBUGGING_UTIL_2
|
|
<a name="line967">967 |</a> ErrorLogger( NO_ERR_START, LOC, _proc_FreeList, NULL);
|
|
<a name="line968">968 |</a> #endif
|
|
<a name="line969">969 |</a> /**
|
|
<a name="line970">970 |</a> ** Nothing to do ?
|
|
<a name="line971">971 |</a> **/
|
|
<a name="line972">972 |</a> if( !list)
|
|
<a name="line973">973 |</a> return;
|
|
<a name="line974">974 |</a> /**
|
|
<a name="line975">975 |</a> ** Free all elements of the list
|
|
<a name="line976">976 |</a> **/
|
|
<a name="line977">977 |</a> for( j = 0; j < numelem; j++)
|
|
<a name="line978">978 |</a> if( list[j] != NULL)
|
|
<a name="line979">979 |</a> null_free((void *) (list + j));
|
|
<a name="line980">980 |</a> /**
|
|
<a name="line981">981 |</a> ** Free the entire list
|
|
<a name="line982">982 |</a> **/
|
|
<a name="line983">983 |</a> null_free((void *) &list);
|
|
<a name="line984">984 |</a>
|
|
<a name="line985">985 |</a> } /** End of 'FreeList' **/
|
|
<a name="line986">986 |</a>
|
|
<a name="line987">987 |</a> #endif
|
|
<a name="line988">988 |</a>
|
|
<a name="line989">989 |</a> /*++++
|
|
<a name="line990">990 |</a> ** ** Function-Header ***************************************************** **
|
|
<a name="line991">991 |</a> ** **
|
|
<a name="line992">992 |</a> ** Function: SourceRC **
|
|
<a name="line993">993 |</a> ** **
|
|
<a name="line994">994 |</a> ** Description: Source the passed global RC file **
|
|
<a name="line995">995 |</a> ** **
|
|
<a name="line996">996 |</a> ** First Edition: 1991/10/23 **
|
|
<a name="line997">997 |</a> ** **
|
|
<a name="line998">998 |</a> ** Parameters: Tcl_Interp *interp Tcl interpreter **
|
|
<a name="line999">999 |</a> ** char *path Path to be used **
|
|
<a name="line1000">1000 |</a> ** char *name Name of the RC file **
|
|
<a name="line1001">1001 |</a> ** **
|
|
<a name="line1002">1002 |</a> ** Result: int TCL_OK Success **
|
|
<a name="line1003">1003 |</a> ** TCL_ERROR Failure **
|
|
<a name="line1004">1004 |</a> ** **
|
|
<a name="line1005">1005 |</a> ** Attached Globals: g_flags These are set up accordingly before **
|
|
<a name="line1006">1006 |</a> ** this function is called in order to **
|
|
<a name="line1007">1007 |</a> ** control everything **
|
|
<a name="line1008">1008 |</a> ** **
|
|
<a name="line1009">1009 |</a> ** ************************************************************************ **
|
|
<a name="line1010">1010 |</a> ++++*/
|
|
<a name="line1011">1011 |</a>
|
|
<a name="line1012">1012 |</a> int SourceRC( Tcl_Interp *interp, char *path, char *name)
|
|
<a name="line1013">1013 |</a> {
|
|
<a name="line1014">1014 |</a> struct stat stats; /** Buffer for the stat() systemcall **/
|
|
<a name="line1015">1015 |</a> int save_flags, i;
|
|
<a name="line1016">1016 |</a> char *buffer;
|
|
<a name="line1017">1017 |</a> int Result = TCL_OK;
|
|
<a name="line1018">1018 |</a> static char **srclist = (char **) NULL;
|
|
<a name="line1019">1019 |</a> static int listsize = 0, listndx = 0;
|
|
<a name="line1020">1020 |</a>
|
|
<a name="line1021">1021 |</a> /**
|
|
<a name="line1022">1022 |</a> ** If there's a problem with the input parameters it means, that
|
|
<a name="line1023">1023 |</a> ** we do not have to source anything
|
|
<a name="line1024">1024 |</a> ** Only a valid TCL interpreter should be there
|
|
<a name="line1025">1025 |</a> **/
|
|
<a name="line1026">1026 |</a> if( !path || !name)
|
|
<a name="line1027">1027 |</a> return( TCL_OK);
|
|
<a name="line1028">1028 |</a>
|
|
<a name="line1029">1029 |</a> if( !interp)
|
|
<a name="line1030">1030 |</a> return( TCL_ERROR);
|
|
<a name="line1031">1031 |</a> /**
|
|
<a name="line1032">1032 |</a> ** Build the full name of the RC file
|
|
<a name="line1033">1033 |</a> ** Avoid duplicate sourcing
|
|
<a name="line1034">1034 |</a> **/
|
|
<a name="line1035">1035 |</a> if ((char *) NULL == (buffer = stringer(NULL, 0, path,"/",name, NULL)))
|
|
<a name="line1036">1036 |</a> if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
|
|
<a name="line1037">1037 |</a> goto unwind0;
|
|
<a name="line1038">1038 |</a> for( i=0; i<listndx; i++)
|
|
<a name="line1039">1039 |</a> if( !strcmp( srclist[ i], buffer))
|
|
<a name="line1040">1040 |</a> goto unwind1;
|
|
<a name="line1041">1041 |</a> /**
|
|
<a name="line1042">1042 |</a> ** Check whether the RC file exists and has the magic cookie inside
|
|
<a name="line1043">1043 |</a> **/
|
|
<a name="line1044">1044 |</a> if( !stat( buffer, &stats)) {
|
|
<a name="line1045">1045 |</a> if( check_magic( buffer, MODULES_MAGIC_COOKIE,
|
|
<a name="line1046">1046 |</a> MODULES_MAGIC_COOKIE_LENGTH)) {
|
|
<a name="line1047">1047 |</a> /**
|
|
<a name="line1048">1048 |</a> ** Set the flags to 'load only'. This prevents from accidently
|
|
<a name="line1049">1049 |</a> ** printing something
|
|
<a name="line1050">1050 |</a> **/
|
|
<a name="line1051">1051 |</a> save_flags = g_flags;
|
|
<a name="line1052">1052 |</a> g_flags = M_LOAD;
|
|
<a name="line1053">1053 |</a> /**
|
|
<a name="line1054">1054 |</a> ** Source now
|
|
<a name="line1055">1055 |</a> **/
|
|
<a name="line1056">1056 |</a> if( TCL_ERROR == Execute_TclFile( interp, buffer))
|
|
<a name="line1057">1057 |</a> if( OK != ErrorLogger( ERR_SOURCE, LOC, buffer, NULL))
|
|
<a name="line1058">1058 |</a> Result = TCL_ERROR;
|
|
<a name="line1059">1059 |</a> g_flags = save_flags;
|
|
<a name="line1060">1060 |</a> /**
|
|
<a name="line1061">1061 |</a> ** Save the currently sourced file in the list
|
|
<a name="line1062">1062 |</a> ** Check whether the list is big enough to fit in a new entry
|
|
<a name="line1063">1063 |</a> **/
|
|
<a name="line1064">1064 |</a> if( !listsize) {
|
|
<a name="line1065">1065 |</a> listsize = SRCFRAG;
|
|
<a name="line1066">1066 |</a> if((char **) NULL == (srclist = (char **) malloc( listsize *
|
|
<a name="line1067">1067 |</a> sizeof( char **)))) {
|
|
<a name="line1068">1068 |</a> ErrorLogger( ERR_ALLOC, LOC, NULL);
|
|
<a name="line1069">1069 |</a> goto unwind1;
|
|
<a name="line1070">1070 |</a> }
|
|
<a name="line1071">1071 |</a> } else if( listndx + 1 >= listsize) {
|
|
<a name="line1072">1072 |</a> listsize += SRCFRAG;
|
|
<a name="line1073">1073 |</a> if((char **) NULL == (srclist = (char **) realloc( srclist,
|
|
<a name="line1074">1074 |</a> listsize * sizeof( char **)))) {
|
|
<a name="line1075">1075 |</a> ErrorLogger( ERR_ALLOC, LOC, NULL);
|
|
<a name="line1076">1076 |</a> goto unwind1;
|
|
<a name="line1077">1077 |</a> }
|
|
<a name="line1078">1078 |</a> }
|
|
<a name="line1079">1079 |</a> /**
|
|
<a name="line1080">1080 |</a> ** Put the current RC files name on the list
|
|
<a name="line1081">1081 |</a> **/
|
|
<a name="line1082">1082 |</a> srclist[ listndx++] = buffer;
|
|
<a name="line1083">1083 |</a>
|
|
<a name="line1084">1084 |</a> } else {
|
|
<a name="line1085">1085 |</a> ErrorLogger( ERR_MAGIC, LOC, buffer, NULL);
|
|
<a name="line1086">1086 |</a> null_free((void *) &buffer);
|
|
<a name="line1087">1087 |</a> }
|
|
<a name="line1088">1088 |</a> } /** if( !stat) **/
|
|
<a name="line1089">1089 |</a> /**
|
|
<a name="line1090">1090 |</a> ** Return our result
|
|
<a name="line1091">1091 |</a> **/
|
|
<a name="line1092">1092 |</a> return( Result);
|
|
<a name="line1093">1093 |</a>
|
|
<a name="line1094">1094 |</a> unwind1:
|
|
<a name="line1095">1095 |</a> null_free((void *) &buffer);
|
|
<a name="line1096">1096 |</a> unwind0:
|
|
<a name="line1097">1097 |</a> return( TCL_ERROR);
|
|
<a name="line1098">1098 |</a>
|
|
<a name="line1099">1099 |</a> } /** End of 'SourceRC' **/
|
|
<a name="line1100">1100 |</a>
|
|
<a name="line1101">1101 |</a> /*++++
|
|
<a name="line1102">1102 |</a> ** ** Function-Header ***************************************************** **
|
|
<a name="line1103">1103 |</a> ** **
|
|
<a name="line1104">1104 |</a> ** Function: SourceVers **
|
|
<a name="line1105">1105 |</a> ** **
|
|
<a name="line1106">1106 |</a> ** Description: Source the '.version' file **
|
|
<a name="line1107">1107 |</a> ** **
|
|
<a name="line1108">1108 |</a> ** First Edition: 1991/10/23 **
|
|
<a name="line1109">1109 |</a> ** **
|
|
<a name="line1110">1110 |</a> ** Parameters: Tcl_Interp *interp Tcl interpreter **
|
|
<a name="line1111">1111 |</a> ** char *path Path to be used **
|
|
<a name="line1112">1112 |</a> ** char *name Name of the module **
|
|
<a name="line1113">1113 |</a> ** **
|
|
<a name="line1114">1114 |</a> ** Result: int TCL_OK Success **
|
|
<a name="line1115">1115 |</a> ** TCL_ERROR Failure **
|
|
<a name="line1116">1116 |</a> ** **
|
|
<a name="line1117">1117 |</a> ** Attached Globals: g_flags These are set up accordingly before **
|
|
<a name="line1118">1118 |</a> ** this function is called in order to **
|
|
<a name="line1119">1119 |</a> ** control everything **
|
|
<a name="line1120">1120 |</a> ** **
|
|
<a name="line1121">1121 |</a> ** ************************************************************************ **
|
|
<a name="line1122">1122 |</a> ++++*/
|
|
<a name="line1123">1123 |</a>
|
|
<a name="line1124">1124 |</a> int SourceVers( Tcl_Interp *interp, char *path, char *name)
|
|
<a name="line1125">1125 |</a> {
|
|
<a name="line1126">1126 |</a> struct stat stats; /** Buffer for the stat() systemcall **/
|
|
<a name="line1127">1127 |</a> int save_flags;
|
|
<a name="line1128">1128 |</a> char *buffer;
|
|
<a name="line1129">1129 |</a> int Result = TCL_OK;
|
|
<a name="line1130">1130 |</a> char *version;
|
|
<a name="line1131">1131 |</a> char *new_argv[3];
|
|
<a name="line1132">1132 |</a> char *mod, *ver;
|
|
<a name="line1133">1133 |</a>
|
|
<a name="line1134">1134 |</a> /**
|
|
<a name="line1135">1135 |</a> ** If there's a problem with the input parameters it means, that
|
|
<a name="line1136">1136 |</a> ** we do not have to source anything
|
|
<a name="line1137">1137 |</a> ** Only a valid TCL interpreter should be there
|
|
<a name="line1138">1138 |</a> **/
|
|
<a name="line1139">1139 |</a> if( !path || !name)
|
|
<a name="line1140">1140 |</a> return( TCL_OK);
|
|
<a name="line1141">1141 |</a> if( !interp)
|
|
<a name="line1142">1142 |</a> return( TCL_ERROR);
|
|
<a name="line1143">1143 |</a> /**
|
|
<a name="line1144">1144 |</a> ** No default version defined so far?
|
|
<a name="line1145">1145 |</a> **/
|
|
<a name="line1146">1146 |</a> if( VersionLookup( name, &mod, &ver) &&
|
|
<a name="line1147">1147 |</a> strcmp( ver, _default))
|
|
<a name="line1148">1148 |</a> return( TCL_OK);
|
|
<a name="line1149">1149 |</a> /**
|
|
<a name="line1150">1150 |</a> ** Build the full name of the RC file and check whether it exists and
|
|
<a name="line1151">1151 |</a> ** has the magic cookie inside
|
|
<a name="line1152">1152 |</a> **/
|
|
<a name="line1153">1153 |</a> if ((char *) NULL == (buffer = stringer(NULL, 0, path,"/",version_file,
|
|
<a name="line1154">1154 |</a> NULL)))
|
|
<a name="line1155">1155 |</a> if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
|
|
<a name="line1156">1156 |</a> return( TCL_ERROR);
|
|
<a name="line1157">1157 |</a> if( !stat( buffer, &stats)) {
|
|
<a name="line1158">1158 |</a> if(
|
|
<a name="line1159">1159 |</a> #if VERSION_MAGIC != 0
|
|
<a name="line1160">1160 |</a> check_magic( buffer, MODULES_MAGIC_COOKIE,
|
|
<a name="line1161">1161 |</a> MODULES_MAGIC_COOKIE_LENGTH)
|
|
<a name="line1162">1162 |</a> #else
|
|
<a name="line1163">1163 |</a> 1
|
|
<a name="line1164">1164 |</a> #endif
|
|
<a name="line1165">1165 |</a> ) {
|
|
<a name="line1166">1166 |</a> save_flags = g_flags;
|
|
<a name="line1167">1167 |</a> g_flags = M_LOAD;
|
|
<a name="line1168">1168 |</a>
|
|
<a name="line1169">1169 |</a> if( TCL_ERROR != (Result = Execute_TclFile( interp, buffer)) &&
|
|
<a name="line1170">1170 |</a> (version = (char *) Tcl_GetVar(interp, "ModulesVersion", 0))) {
|
|
<a name="line1171">1171 |</a> /**
|
|
<a name="line1172">1172 |</a> ** The version has been specified in the
|
|
<a name="line1173">1173 |</a> ** '.version' file. Set up the result code
|
|
<a name="line1174">1174 |</a> **/
|
|
<a name="line1175">1175 |</a> null_free((void *) &buffer);
|
|
<a name="line1176">1176 |</a> if ((char *) NULL == (buffer = stringer(NULL, 0,
|
|
<a name="line1177">1177 |</a> name,"/",version, NULL)))
|
|
<a name="line1178">1178 |</a> if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
|
|
<a name="line1179">1179 |</a> return( TCL_ERROR);
|
|
<a name="line1180">1180 |</a>
|
|
<a name="line1181">1181 |</a> new_argv[0] = "module-version";
|
|
<a name="line1182">1182 |</a> new_argv[1] = buffer;
|
|
<a name="line1183">1183 |</a> new_argv[2] = _default;
|
|
<a name="line1184">1184 |</a> /**
|
|
<a name="line1185">1185 |</a> ** Define the default version
|
|
<a name="line1186">1186 |</a> **/
|
|
<a name="line1187">1187 |</a> if( TCL_OK != cmdModuleVersion( (ClientData) 0,
|
|
<a name="line1188">1188 |</a> (Tcl_Interp *) NULL, 3, (CONST84 char **) new_argv)) {
|
|
<a name="line1189">1189 |</a> Result = TCL_ERROR;
|
|
<a name="line1190">1190 |</a> }
|
|
<a name="line1191">1191 |</a> } /** if( Execute...) **/
|
|
<a name="line1192">1192 |</a>
|
|
<a name="line1193">1193 |</a> g_flags = save_flags;
|
|
<a name="line1194">1194 |</a>
|
|
<a name="line1195">1195 |</a> } else
|
|
<a name="line1196">1196 |</a> ErrorLogger( ERR_MAGIC, LOC, buffer, NULL);
|
|
<a name="line1197">1197 |</a>
|
|
<a name="line1198">1198 |</a> } /** if( !stat) **/
|
|
<a name="line1199">1199 |</a> /**
|
|
<a name="line1200">1200 |</a> ** free buffer memory
|
|
<a name="line1201">1201 |</a> **/
|
|
<a name="line1202">1202 |</a> null_free((void *) &buffer);
|
|
<a name="line1203">1203 |</a> /**
|
|
<a name="line1204">1204 |</a> ** Result determines if this was successfull
|
|
<a name="line1205">1205 |</a> **/
|
|
<a name="line1206">1206 |</a>
|
|
<a name="line1207">1207 |</a> return( Result);
|
|
<a name="line1208">1208 |</a>
|
|
<a name="line1209">1209 |</a> } /** End of 'SourceVers' **/
|
|
<a name="line1210">1210 |</a>
|
|
</pre>
|
|
|
|
</BODY>
|
|
</HTML>
|