/[ascend]/trunk/base/generic/utilities/ascDynaLoad.c
ViewVC logotype

Annotation of /trunk/base/generic/utilities/ascDynaLoad.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1597 - (hide annotations) (download) (as text)
Fri Aug 17 05:26:05 2007 UTC (17 years, 2 months ago) by jpye
File MIME type: text/x-csrc
File size: 18390 byte(s)
New external library naming scheme on Windows: 'name_ascend.dll' instead of 'name.dll'.
This applies to solvers as well as external methods, extpy, import handlers, etc.
1 johnpye 478 /* ASCEND modelling environment
2     Copyright (C) 2006 Carnegie Mellon University
3 aw0a 1
4 johnpye 478 This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2, or (at your option)
7     any later version.
8    
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12     GNU General Public License for more details.
13    
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 59 Temple Place - Suite 330,
17     Boston, MA 02111-1307, USA.
18 johnpye 791 *//**
19     @file
20    
21 johnpye 427 This file *should* support unix/linux-style systems (dlfcn.h)
22     and Windows.
23 aw0a 1
24 johnpye 427 Note that under many systems, profiling does not work
25     with dynamic libraries!
26 johnpye 158 */
27    
28 aw0a 1 #include <stdio.h>
29     #include <stdlib.h>
30 ben.allan 45 #include <stdarg.h>
31 johnpye 399 #include "ascConfig.h"
32     #include "error.h"
33     #include "ascPrint.h"
34     #include "ascPanic.h"
35     #include "ascMalloc.h"
36     #include "ascDynaLoad.h"
37 johnpye 862 #include "ascEnvVar.h"
38 jds 59
39 johnpye 791 #include <general/env.h>
40     #include <general/ospath.h>
41 johnpye 399 #include <compiler/instance_enum.h>
42     #include <general/list.h>
43     #include <compiler/extfunc.h>
44 johnpye 862 #include <compiler/importhandler.h>
45 johnpye 380
46 johnpye 466 typedef int (*ExternalLibraryRegister_fptr_t)(void);
47 johnpye 380
48 johnpye 158 /*--------------------------------------
49     GENERIC STUFF
50     */
51    
52 aw0a 1 struct ascend_dlrecord {
53 jds 59 char *path; /* library name */
54 aw0a 1 void *dlreturn; /* return from dlopen */
55     struct ascend_dlrecord *next;
56     };
57    
58 jds 59 /* Linked list of library names & dlopen() return values. */
59 johnpye 791 static struct ascend_dlrecord *g_ascend_dllist = NULL;
60 aw0a 1
61     /*
62 jds 59 * Adds a record of the path and handle to the list.
63     * If it fails to do this, returns 1, else 0.
64 aw0a 1 */
65 johnpye 791 static int AscAddRecord(void *dlreturn, CONST char *path){
66 aw0a 1 struct ascend_dlrecord *new;
67     char *keeppath;
68     if (dlreturn == NULL || path == NULL) {
69     return 1;
70     }
71 johnpye 1220 keeppath = ASC_STRDUP((char *)path);
72 aw0a 1 if (keeppath==NULL) return 1;
73 johnpye 709 new = ASC_NEW(struct ascend_dlrecord);
74 aw0a 1 if (new==NULL) {
75 jds 103 ascfree(keeppath);
76 aw0a 1 return 1;
77     }
78     new->next = g_ascend_dllist; /* insert at head */
79     g_ascend_dllist = new;
80     new->path = keeppath;
81     new->dlreturn = dlreturn;
82     return 0;
83     }
84    
85     /*
86     * Finds a record of the path given and returns the associated handle.
87     * If it fails to do this, returns NULL.
88     */
89     static
90     void *AscFindDLRecord(CONST char *path)
91     {
92     struct ascend_dlrecord *new;
93     if (path == NULL) {
94     return NULL;
95     }
96     new = g_ascend_dllist;
97     while (new != NULL && strcmp(new->path,path) != 0) {
98     /* advance new until no more new or new with path found */
99     new = new->next;
100     }
101     return (new != NULL) ? new->dlreturn : NULL;
102     }
103    
104     /*
105     * Finds and returns the handle to path, if one matches, and
106 jds 59 * deletes the record from the list. Returns NULL if not found.
107 aw0a 1 */
108     static
109 jds 103 void *AscDeleteRecord(CONST char *path)
110 aw0a 1 {
111     struct ascend_dlrecord *nextptr, *lastptr, *old;
112     void *dlreturn = NULL;
113 jds 59
114 jds 61 if ((g_ascend_dllist == NULL) || (NULL == path)) return NULL;
115 jds 59
116 aw0a 1 if (strcmp(path,g_ascend_dllist->path)==0) {
117     /* head case */
118     old = g_ascend_dllist;
119     g_ascend_dllist = old->next;
120     dlreturn = old->dlreturn;
121 jds 103 ascfree(old->path);
122     ascfree(old);
123 aw0a 1 } else {
124     lastptr = g_ascend_dllist;
125     nextptr = lastptr->next;
126     while (nextptr != NULL && strcmp(nextptr->path,path) != 0) {
127     lastptr = nextptr;
128     nextptr = nextptr->next;
129     }
130     /* so either nextptr is NULL and not in list, or nextptr is
131     * what we want to delete and lastptr is the link to it.
132     */
133     if (nextptr != NULL) {
134     old = nextptr;
135     lastptr->next = nextptr->next;
136     dlreturn = old->dlreturn;
137 jds 103 ascfree(old->path);
138     ascfree(old);
139 aw0a 1 }
140     }
141     return dlreturn;
142     }
143    
144     /*
145 jds 59 * Checks the list for a conflicting handle so we can issue
146 aw0a 1 * a more helpful warning, if need be, than the standard message.
147     */
148 jds 59 static
149 aw0a 1 void AscCheckDuplicateLoad(CONST char *path)
150     {
151     struct ascend_dlrecord *r;
152 jds 59
153     if (NULL == path) {
154 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Null path");
155 jds 59 return;
156     }
157    
158 aw0a 1 r = g_ascend_dllist;
159     while (r != NULL) {
160     if (strcmp(path,r->path)==0) {
161 johnpye 972 ERROR_REPORTER_HERE(ASC_PROG_WARNING,"Attempt to load already loaded '%s'.",path);
162 aw0a 1 return;
163     }
164     r = r->next;
165     }
166     }
167    
168 johnpye 791
169 johnpye 427 /*-----------------------------------------------
170     WINDOWS
171 johnpye 158 */
172 johnpye 427 #if defined(__WIN32__)
173     # include <windows.h>
174 johnpye 158
175 johnpye 485 int Asc_DynamicLoad(CONST char *path, CONST char *initFun){
176 aw0a 1 HINSTANCE xlib;
177 johnpye 380 ExternalLibraryRegister_fptr_t install = NULL;
178 aw0a 1
179 jds 59 if (NULL == path) {
180 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed: Null path\n");
181 jds 59 return 1;
182     }
183    
184 aw0a 1 AscCheckDuplicateLoad(path); /* whine if we've see it before */
185     /*
186     * If the named library does not exist, if it's not loadable or if
187     * it does not define the named install proc, report an error
188     */
189    
190     xlib = LoadLibrary(path);
191     if (xlib == NULL) {
192 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"LoadLibrary failed\n'%s'",path);
193 aw0a 1 return 1;
194     }
195 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_NOTE,"LoadLibrary succeeded, '%s'\n",path);
196 johnpye 543
197 jds 59 if (NULL != initFun) {
198 wangym 489 install = (int (*)(void))GetProcAddress(xlib,initFun);
199 jds 59 if (install == NULL) {
200 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Required function '%s' not found", initFun);
201 jds 59 (void)FreeLibrary(xlib);
202     return 1;
203 jpye 1597 #if 0
204     }else{
205 johnpye 66 FPRINTF(ASCERR,"FOUND INITFCN %s AT %d\n",initFun,install);
206 jpye 1597 #endif
207 johnpye 62 }
208 aw0a 1 }
209 jds 59 if (0 != AscAddRecord(xlib,path)) {
210 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed to record library (%s)\n",path);
211 aw0a 1 }
212 johnpye 466 return (install == NULL) ? 0 : (*install)();
213 aw0a 1 }
214 johnpye 485 #define ASCDL_OK /* this line should appear inside each Asc_DynamicLoad */
215 johnpye 427
216     # define UNLOAD FreeLibrary
217     # define DLLSYM GetProcAddress
218     # define DLL_CAST (HINSTANCE)
219     # define ASC_DLERRSTRING "unknown"
220     # define UNLOAD_SUCCESS TRUE
221    
222 aw0a 1 #endif /* __WIN32__ */
223 jds 61
224 johnpye 427 /*-----------------------------------------------
225     UNIX/LINUX
226     */
227 johnpye 62 /*
228     SOLARIS and LINUX
229     */
230 johnpye 158 /* NOTE, added defined(__unix__) here, not sure if that's a bad thing or not -- johnpye */
231 johnpye 62 /*
232 johnpye 190 From a quick Google, it appears that AIX 5.1 now provides dlfcn.h,
233 johnpye 158 so I'll remove the code that was emulating it here. -- johnpye
234 johnpye 62 */
235 ben.allan 467 #if (defined(sun) || defined(linux) || defined(__unix__) || defined(solaris) || defined(_AIX) || defined(_SGI_SOURCE))
236 johnpye 158 # ifndef MACH
237     # include <dlfcn.h>
238     # else
239     # error "MACH unsupported"
240 ben.allan 467 # endif /* mach */
241 jds 59
242 aw0a 1 int Asc_DynamicLoad(CONST char *path, CONST char *initFun)
243     {
244     void *xlib;
245 johnpye 380 ExternalLibraryRegister_fptr_t install = NULL;
246 jds 59
247     if (NULL == path) {
248 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed: null path");
249 jds 59 return 1;
250     }
251    
252 aw0a 1 AscCheckDuplicateLoad(path); /* whine if we've see it before */
253    
254     /*
255     * If the named library does not exist, if it's not loadable or if
256     * it does not define the named install proc, report an error
257     */
258     xlib = dlopen(path, 1);
259 jds 61 if (xlib == NULL) {
260 johnpye 190 ERROR_REPORTER_NOLINE(ASC_PROG_ERR,"%s",(char *)dlerror());
261 aw0a 1 return 1;
262     }
263 jds 61 if (NULL != initFun) {
264 johnpye 1228 /* https://www.opengroup.org/sophocles/show_mail.tpl?source=L&listname=austin-review-l&id=2252 */
265     *(void**)(&install) = dlsym(xlib, initFun);
266 jds 61 if (install == NULL) {
267 johnpye 190 ERROR_REPORTER_NOLINE(ASC_PROG_ERR,"%s",(char *)dlerror());
268 jds 61 dlclose(xlib);
269     return 1;
270     }
271     }
272 johnpye 190
273 jds 59 if (0 != AscAddRecord(xlib,path)) {
274 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed to record library (%s)",path);
275 aw0a 1 }
276 johnpye 466 return (install == NULL) ? 0 : (*install)();
277 aw0a 1 }
278 johnpye 485 #define ASCDL_OK /* this line should appear inside each Asc_DynamicLoad */
279 aw0a 1
280 johnpye 427 # define UNLOAD dlclose
281     # define DLLSYM dlsym
282     # define DLL_CAST (void *)
283     # define ASC_DLERRSTRING dlerror()
284     # define UNLOAD_SUCCESS 0
285    
286 johnpye 158 #endif /* posix: linux, unix, solaris,sgi */
287 aw0a 1
288 johnpye 427 /*-----------------------------------------------
289     HPUX
290     */
291 aw0a 1 #ifdef __hpux
292     /*
293 johnpye 427 Kirk Abbott last fiddled with the following, which was
294     originally put in place my Michael Moore for an
295     HP/UX 9.X Operating Sys back in 1993. Arrr. No idea if
296     it still works.
297     */
298 aw0a 1
299 johnpye 158 # include <dl.h>
300     # include <errno.h>
301 aw0a 1
302     int Asc_DynamicLoad(CONST char *path, CONST char *initFun)
303     {
304     shl_t xlib;
305 johnpye 380 ExternalLibraryRegister_fptr_t install = NULL;
306 aw0a 1 int i;
307 jds 59
308     if (NULL == path) {
309 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed: Null path");
310 jds 59 return 1;
311     }
312    
313 aw0a 1 AscCheckDuplicateLoad(path); /* whine if we've see it before */
314    
315     /*
316     * If the named library does not exist, if it's not loadable or if
317     * it does not define the named install proc, report an error
318     */
319     xlib = shl_load(path, BIND_IMMEDIATE | BIND_VERBOSE, 0L);
320     if (xlib == (shl_t) NULL) {
321 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unable to load shared library: %s",strerror(errno));
322 aw0a 1 return 1;
323     }
324 jds 59 if (NULL != initFun) {
325     i = shl_findsym(&xlib, initFun, TYPE_PROCEDURE, &install);
326     if (i == -1) {
327 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unable to find needed symbol '%s': %s",
328 jds 59 initFun, strerror(errno));
329     shl_unload(xlib); /* baa */
330     return 1;
331 aw0a 1 }
332 johnpye 790 if(install == NULL) {
333     ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unable to find needed symbol '%s'. Error type unknown",initFun);
334 jds 59 shl_unload(xlib); /* baa */
335     return 1;
336     }
337 aw0a 1 }
338 jds 59 if (0 != AscAddRecord(xlib,path)) {
339 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed to record library (%s)",path);
340 aw0a 1 }
341 johnpye 466 return (install == NULL) ? 0 : (*install)();
342 aw0a 1 }
343 johnpye 485 # define ASCDL_OK /* this line should appear inside each Asc_DynamicLoad */
344 aw0a 1
345 johnpye 158 # define UNLOAD shl_unload
346     # define DLL_CAST (shl_t)
347     # define ASC_DLERRSTRING "NULL definition"
348     # define UNLOAD_SUCCESS 0
349 johnpye 427
350 aw0a 1 #endif /* __hpux */
351    
352 johnpye 427 /*-----------------------------------------------
353     Did we get something from the above?
354 johnpye 158 */
355    
356 johnpye 478 #ifndef ASCDL_OK
357 johnpye 427 # error "Unable to define an Asc_DynamicLoad function. Check your compiler options and installed system libraries."
358     #endif
359    
360     /**-----------------------------------------------
361     DYNAMIC UNLOADING
362     */
363    
364 jds 103 int Asc_DynamicUnLoad(CONST char *path)
365 aw0a 1 {
366     void *dlreturn;
367 jds 61 int retval;
368 johnpye 190
369 jds 59 if (NULL == path) {
370 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR, "Failed: Null path");
371 jds 59 return -3;
372     }
373    
374 aw0a 1 dlreturn = AscDeleteRecord(path);
375     if (dlreturn == NULL) {
376 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR, "Unable to remember or unload %s", path);
377 aw0a 1 return -3;
378     }
379 johnpye 790 CONSOLE_DEBUG("Asc_DynamicUnLoad: forgetting & unloading %s", path);
380 johnpye 190 /*
381 jds 61 * dlclose() returns 0 on success, FreeLibrary() returns TRUE.
382     * A uniform convention is preferable, so trap and return 0 on success.
383     */
384     retval = UNLOAD(DLL_CAST dlreturn);
385     return (retval == UNLOAD_SUCCESS) ? 0 : retval;
386 aw0a 1 }
387    
388 johnpye 427 /**-----------------------------------------------
389     DYNAMIC VARIABLE LINKING
390     */
391 jds 103 void *Asc_DynamicVariable(CONST char *libname, CONST char *symbol)
392 aw0a 1 {
393     void *dlreturn;
394     void *symreturn;
395     #ifdef __hpux
396     int i;
397     #endif
398    
399 jds 59 if (libname == NULL) {
400 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed: Null libname");
401 aw0a 1 return NULL;
402     }
403 jds 59 if (symbol == NULL) {
404 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed: Null symbol");
405 jds 59 return NULL;
406     }
407    
408 aw0a 1 dlreturn = AscFindDLRecord(libname);
409     if (dlreturn == NULL) {
410 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unable to find requested library %s", libname);
411 aw0a 1 return NULL;
412     }
413     #ifdef __hpux
414     i = shl_findsym(&dlreturn, symbol, TYPE_UNDEFINED, &symreturn);
415     if (i == -1) {
416 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unable to find requested symbol '%s' in %s (%s)",
417 aw0a 1 symbol, libname, strerror(errno));
418     symreturn = NULL;
419     }
420 jds 103 #elif defined(__WIN32__)
421     /*
422     * Here's a bit of possibly-misdirected casting horror.
423     * ISO C forbids casting between function and data pointers, so, naturally,
424     * we cast between function and data pointers. Well, we don't have much
425     * choice. GetProcAddress() returns a function pointer for both functions
426 johnpye 190 * and variables so we have to do the cast for variables. This is ok on
427     * 32 bit Windows since the pointers are compatible. Then, to avoid
428     * being reminded by the compiler that we're doing something illegal,
429 jds 103 * we apply convoluted casting to shut it up.
430     * Oh, the crap you can find on the internet... JDS
431     */
432     *(FARPROC*)(&symreturn) = GetProcAddress((HINSTANCE)dlreturn, symbol);
433 aw0a 1 #else
434 jds 103 /* no problem on POSIX systems - dlsym() returns a void *. */
435     symreturn = dlsym(dlreturn, symbol);
436 aw0a 1 #endif
437     if (symreturn == NULL) {
438 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unable to find requested symbol '%s' in %s",symbol,libname);
439     ERROR_REPORTER_NOLINE(ASC_PROG_ERR,"Error type: %s",ASC_DLERRSTRING);
440 aw0a 1 }
441     return symreturn;
442     }
443 jds 103
444 johnpye 427 /**-----------------------------------------------
445     DYNAMIC FUNCTION LINKING
446     */
447 jds 103 DynamicF Asc_DynamicFunction(CONST char *libname, CONST char *symbol)
448     {
449     void *dlreturn;
450     DynamicF symreturn;
451     #ifdef __hpux
452     int i;
453     #endif
454    
455     if (libname == NULL) {
456 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed: null library name");
457 jds 103 return NULL;
458     }
459     if (symbol == NULL) {
460 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed: null function name");
461 jds 103 return NULL;
462     }
463    
464     dlreturn = AscFindDLRecord(libname);
465     if (dlreturn == NULL) {
466 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unable to find requested library %s", libname);
467 jds 103 return NULL;
468     }
469     #ifdef __hpux
470     i = shl_findsym(&dlreturn, symbol, TYPE_UNDEFINED, &symreturn);
471     if (i == -1) {
472 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unable to find requested function '%s' in %s (%s)",
473 jds 103 symbol, libname, strerror(errno));
474     symreturn = NULL;
475     }
476     #elif defined(__WIN32__)
477     /* no problem on Windows - GetProcAddress() returns a function pointer. */
478     symreturn = (DynamicF)GetProcAddress((HINSTANCE)dlreturn, symbol);
479     #else
480     /*
481     * Here's the corresponding bit of possibly-misdirected casting horror.
482     * ISO C forbids casting between function and data pointers, so, naturally,
483 johnpye 190 * we cast between function and data pointers. Well, we don't have much
484 jds 103 * choice. dlsym() returns a void* for both variables and functions so we
485 johnpye 190 * have to do the cast for functions. This is ok on POSIX systems since the
486     * pointer types are compatible. Then, to avoid being reminded by the
487     * compiler that we're doing something illegal, we apply convoluted casting
488 jds 103 * to shut it up. Oh, the crap you can find on the internet... JDS
489     */
490     *(void**)(&symreturn) = dlsym(dlreturn, symbol);
491     #endif
492     if (symreturn == NULL) {
493 johnpye 790 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unable to find requested function '%s' in %s",symbol,libname);
494     ERROR_REPORTER_NOLINE(ASC_PROG_ERR,"Error type: %s",ASC_DLERRSTRING);
495 jds 103 }
496     return symreturn;
497     }
498 johnpye 427
499 johnpye 791
500     /*-----------------------------------------------------------------------------
501     SEARCHING FOR LIBRARIES
502     */
503    
504 jpye 1597
505 johnpye 791 /**
506 jpye 1597 Create a library filename according to platform standard naming.
507    
508     @param partialname The partial filename (eg 'mylib')
509     @return Complete filename (eg 'libmylib.so' or 'mylib.dlll', etc)
510    
511     Basically just adds ASC_SHLIBPREFIX to start and ASC_SHLIBSUFFIX to end.
512    
513     No allowance made for 'soname' suffixes eg 'libsomething.so.1' etc. But
514     that's probably OK as those methods aren't really applicable to dlopened
515     libraries (eg the soname symlink mechanism breaks down).
516     */
517     char *dynaload_lib_filename(const char *partialname){
518     char *buffer;
519     buffer = ASC_NEW_ARRAY(char,PATH_MAX);
520     #if !defined(ASC_SHLIBSUFFIX) || !defined(ASC_SHLIBPREFIX)
521     # error "ASC_SHLIBSUFFIX and ASC_SHLIBPREFIX are not defined"
522     #endif
523     snprintf(buffer,PATH_MAX,"%s%s%s",ASC_SHLIBPREFIX,partialname,ASC_SHLIBSUFFIX);
524     return buffer;
525     }
526    
527    
528     /**
529 johnpye 791 A little structure to help with searching for libraries
530    
531     @see test_librarysearch
532     */
533     struct LibrarySearch{
534     struct FilePath *partialpath;
535     char fullpath[PATH_MAX];
536     };
537    
538     FilePathTestFn test_librarysearch;
539    
540     /**
541     A 'test' function for passing to the ospath_searchpath_iterate function.
542     This test function will return a match when a library having the required
543     name is present in the fully resolved path.
544     */
545     int test_librarysearch(struct FilePath *path, void *userdata){
546     /* user data = the relative path, plus a place
547     to store the full path when found */
548     FILE *f;
549     struct LibrarySearch *ls;
550     struct FilePath *fp;
551    
552     ls = (struct LibrarySearch *)userdata;
553     fp = ospath_concat(path,ls->partialpath);
554     if(fp==NULL){
555     char *tmp;
556     tmp = ospath_str(path);
557     CONSOLE_DEBUG("Unable to concatenate '%s'...",tmp);
558     ospath_free_str(tmp);
559     tmp = ospath_str(ls->partialpath);
560     CONSOLE_DEBUG("... and '%s'...",tmp);
561     ospath_free_str(tmp);
562     return 0;
563     }
564    
565     ospath_strncpy(fp,ls->fullpath,PATH_MAX);
566 johnpye 895 /* CONSOLE_DEBUG("SEARCHING FOR %s",ls->fullpath); */
567 johnpye 791
568     f = ospath_fopen(fp,"r");
569     if(f==NULL){
570     ospath_free(fp);
571     return 0;
572     }
573     fclose(f);
574    
575     /* ERROR_REPORTER_HERE(ASC_PROG_NOTE,"FOUND! %s\n",ls->fullpath); */
576     ospath_free(fp);
577     return 1;
578     }
579    
580 johnpye 862 /**
581     @DEPRECATED this function needs to be rewritten to use 'ImportHandler'
582     functionality.
583     */
584 johnpye 1072 char *SearchArchiveLibraryPath(CONST char *name, char *dpath, const char *envv){
585 johnpye 791 struct FilePath *fp1, *fp2, *fp3; /* relative path */
586     char *s1;
587 johnpye 862 char *buffer;
588 johnpye 791
589     struct LibrarySearch ls;
590     struct FilePath **sp;
591     char *path, *foundpath;
592     ospath_stat_t buf;
593     FILE *f;
594    
595     fp1 = ospath_new_noclean(name);
596     if(fp1==NULL){
597     ERROR_REPORTER_HERE(ASC_USER_ERROR,"Invalid partial path '%s'",name);
598     ospath_free(fp1);
599     return NULL;
600     }
601    
602     s1 = ospath_getfilestem(fp1);
603     if(s1==NULL){
604     /* not a file, so fail... */
605     return NULL;
606     }
607    
608     fp2 = ospath_getdir(fp1);
609     if(fp2==NULL){
610     ERROR_REPORTER_HERE(ASC_PROG_ERR,"unable to retrieve file dir");
611     return NULL;
612     }
613    
614 jpye 1597 buffer = dynaload_lib_filename(s1);
615 johnpye 791
616     fp3 = ospath_new(buffer);
617 johnpye 862 ASC_FREE(buffer);
618 johnpye 791 ospath_free(fp1);
619     fp1 = ospath_concat(fp2,fp3);
620     ospath_free(fp2);
621     ospath_free(fp3);
622     ospath_free_str(s1);
623    
624     /* attempt to open "name" directly */
625     if(0==ospath_stat(fp1,&buf) && NULL!=(f = ospath_fopen(fp1,"r")) ){
626     char *tmp;
627     tmp = ospath_str(fp1);
628     CONSOLE_DEBUG("Library '%s' opened directly, without path search",tmp);
629     ospath_free_str(tmp);
630     fp2 = ospath_getabs(fp1);
631     foundpath = ospath_str(fp2);
632     ospath_free(fp2);
633     fclose(f);
634     }else{
635    
636     ls.partialpath = fp1;
637    
638     path=Asc_GetEnv(envv);
639     if(path==NULL){
640 johnpye 895 /* CONSOLE_DEBUG("Library search path env var '%s' not found, using default path '%s'",envv,dpath); */
641 johnpye 791 path=dpath;
642     }
643    
644     /* CONSOLE_DEBUG("SEARCHPATH IS %s",path); */
645     sp = ospath_searchpath_new(path);
646    
647     if(NULL==ospath_searchpath_iterate(sp,&test_librarysearch,&ls)){
648     ospath_free(fp1);
649     ospath_searchpath_free(sp);
650     return NULL;
651     }
652    
653     foundpath = ASC_NEW_ARRAY(char,strlen(ls.fullpath)+1);
654     strcpy(foundpath,ls.fullpath);
655     ospath_searchpath_free(sp);
656     }
657    
658     ospath_free(fp1);
659     return foundpath;
660     }

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22