]> granicus.if.org Git - imagemagick/blob - ltdl/ltdl.c
(no commit message)
[imagemagick] / ltdl / ltdl.c
1 /* ltdl.c -- system independent dlopen wrapper
2
3    Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006,
4                  2007, 2008 Free Software Foundation, Inc.
5    Written by Thomas Tanner, 1998
6
7    NOTE: The canonical source of this file is maintained with the
8    GNU Libtool package.  Report bugs to bug-libtool@gnu.org.
9
10 GNU Libltdl is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
14
15 As a special exception to the GNU Lesser General Public License,
16 if you distribute this file as part of a program or library that
17 is built using GNU Libtool, you may include this file under the
18 same distribution terms that you use for the rest of that program.
19
20 GNU Libltdl is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 GNU Lesser General Public License for more details.
24
25 You should have received a copy of the GNU Lesser General Public
26 License along with GNU Libltdl; see the file COPYING.LIB.  If not, a
27 copy can be downloaded from  http://www.gnu.org/licenses/lgpl.html,
28 or obtained by writing to the Free Software Foundation, Inc.,
29 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30 */
31
32 #include "lt__private.h"
33 #include "lt_system.h"
34 #include "lt_dlloader.h"
35
36
37 /* --- MANIFEST CONSTANTS --- */
38
39
40 /* Standard libltdl search path environment variable name  */
41 #undef  LTDL_SEARCHPATH_VAR
42 #define LTDL_SEARCHPATH_VAR     "LTDL_LIBRARY_PATH"
43
44 /* Standard libtool archive file extension.  */
45 #undef  LT_ARCHIVE_EXT
46 #define LT_ARCHIVE_EXT  ".la"
47
48 /* max. filename length */
49 #if !defined(LT_FILENAME_MAX)
50 #  define LT_FILENAME_MAX       1024
51 #endif
52
53 #if !defined(LT_LIBEXT)
54 #  define LT_LIBEXT "a"
55 #endif
56
57 /* This is the maximum symbol size that won't require malloc/free */
58 #undef  LT_SYMBOL_LENGTH
59 #define LT_SYMBOL_LENGTH        128
60
61 /* This accounts for the _LTX_ separator */
62 #undef  LT_SYMBOL_OVERHEAD
63 #define LT_SYMBOL_OVERHEAD      5
64
65 /* Various boolean flags can be stored in the flags field of an
66    lt_dlhandle... */
67 #define LT_DLIS_RESIDENT(handle)  ((handle)->info.is_resident)
68 #define LT_DLIS_SYMGLOBAL(handle) ((handle)->info.is_symglobal)
69 #define LT_DLIS_SYMLOCAL(handle)  ((handle)->info.is_symlocal)
70
71
72 static  const char      objdir[]                = LT_OBJDIR;
73 static  const char      archive_ext[]           = LT_ARCHIVE_EXT;
74 static  const char      libext[]                = LT_LIBEXT;
75 #if defined(LT_MODULE_EXT)
76 static  const char      shlib_ext[]             = LT_MODULE_EXT;
77 #endif
78 #if defined(LT_DLSEARCH_PATH)
79 static  const char      sys_dlsearch_path[]     = LT_DLSEARCH_PATH;
80 #endif
81
82
83
84 \f
85 /* --- DYNAMIC MODULE LOADING --- */
86
87
88 /* The type of a function used at each iteration of  foreach_dirinpath().  */
89 typedef int     foreach_callback_func (char *filename, void *data1,
90                                        void *data2);
91 /* foreachfile_callback itself calls a function of this type: */
92 typedef int     file_worker_func      (const char *filename, void *data);
93
94
95 static  int     foreach_dirinpath     (const char *search_path,
96                                        const char *base_name,
97                                        foreach_callback_func *func,
98                                        void *data1, void *data2);
99 static  int     find_file_callback    (char *filename, void *data1,
100                                        void *data2);
101 static  int     find_handle_callback  (char *filename, void *data,
102                                        void *ignored);
103 static  int     foreachfile_callback  (char *filename, void *data1,
104                                        void *data2);
105
106
107 static  int     canonicalize_path     (const char *path, char **pcanonical);
108 static  int     argzize_path          (const char *path,
109                                        char **pargz, size_t *pargz_len);
110 static  FILE   *find_file             (const char *search_path,
111                                        const char *base_name, char **pdir);
112 static  lt_dlhandle *find_handle      (const char *search_path,
113                                        const char *base_name,
114                                        lt_dlhandle *handle,
115                                        lt_dladvise advise);
116 static  int     find_module           (lt_dlhandle *handle, const char *dir,
117                                        const char *libdir, const char *dlname,
118                                        const char *old_name, int installed,
119                                        lt_dladvise advise);
120 static  int     has_library_ext       (const char *filename);
121 static  int     load_deplibs          (lt_dlhandle handle,  char *deplibs);
122 static  int     trim                  (char **dest, const char *str);
123 static  int     try_dlopen            (lt_dlhandle *handle,
124                                        const char *filename, const char *ext,
125                                        lt_dladvise advise);
126 static  int     tryall_dlopen         (lt_dlhandle *handle,
127                                        const char *filename,
128                                        lt_dladvise padvise,
129                                        const lt_dlvtable *vtable);
130 static  int     unload_deplibs        (lt_dlhandle handle);
131 static  int     lt_argz_insert        (char **pargz, size_t *pargz_len,
132                                        char *before, const char *entry);
133 static  int     lt_argz_insertinorder (char **pargz, size_t *pargz_len,
134                                        const char *entry);
135 static  int     lt_argz_insertdir     (char **pargz, size_t *pargz_len,
136                                        const char *dirnam, struct dirent *dp);
137 static  int     lt_dlpath_insertdir   (char **ppath, char *before,
138                                        const char *dir);
139 static  int     list_files_by_dir     (const char *dirnam,
140                                        char **pargz, size_t *pargz_len);
141 static  int     file_not_found        (void);
142
143 #ifdef HAVE_LIBDLLOADER
144 static  int     loader_init_callback  (lt_dlhandle handle);
145 #endif /* HAVE_LIBDLLOADER */
146
147 static  int     loader_init           (lt_get_vtable *vtable_func,
148                                        lt_user_data data);
149
150 static  char           *user_search_path= 0;
151 static  lt_dlhandle     handles = 0;
152 static  int             initialized     = 0;
153
154 /* Our memory failure callback sets the error message to be passed back
155    up to the client, so we must be careful to return from mallocation
156    callers if allocation fails (as this callback returns!!).  */
157 void
158 lt__alloc_die_callback (void)
159 {
160   LT__SETERROR (NO_MEMORY);
161 }
162
163 #ifdef HAVE_LIBDLLOADER
164 /* This function is called to initialise each preloaded module loader,
165    and hook it into the list of loaders to be used when attempting to
166    dlopen an application module.  */
167 static int
168 loader_init_callback (lt_dlhandle handle)
169 {
170   lt_get_vtable *vtable_func = (lt_get_vtable *) lt_dlsym (handle, "get_vtable");
171   return loader_init (vtable_func, 0);
172 }
173 #endif /* HAVE_LIBDLLOADER */
174
175 static int
176 loader_init (lt_get_vtable *vtable_func, lt_user_data data)
177 {
178   const lt_dlvtable *vtable = 0;
179   int errors = 0;
180
181   if (vtable_func)
182     {
183       vtable = (*vtable_func) (data);
184     }
185
186   /* lt_dlloader_add will LT__SETERROR if it fails.  */
187   errors += lt_dlloader_add (vtable);
188
189   assert (errors || vtable);
190
191   if ((!errors) && vtable->dlloader_init)
192     {
193       if ((*vtable->dlloader_init) (vtable->dlloader_data))
194         {
195           LT__SETERROR (INIT_LOADER);
196           ++errors;
197         }
198     }
199
200   return errors;
201 }
202
203 /* Bootstrap the loader loading with the preopening loader.  */
204 #define get_vtable              preopen_LTX_get_vtable
205 #define preloaded_symbols       LT_CONC3(lt_, LTDLOPEN, _LTX_preloaded_symbols)
206
207 LT_BEGIN_C_DECLS
208 LT_SCOPE const lt_dlvtable *    get_vtable (lt_user_data data);
209 LT_END_C_DECLS
210 #ifdef HAVE_LIBDLLOADER
211 extern lt_dlsymlist             preloaded_symbols[];
212 #endif
213
214 /* Initialize libltdl. */
215 int
216 lt_dlinit (void)
217 {
218   int   errors  = 0;
219
220   /* Initialize only at first call. */
221   if (++initialized == 1)
222     {
223       lt__alloc_die     = lt__alloc_die_callback;
224       handles           = 0;
225       user_search_path  = 0; /* empty search path */
226
227       /* First set up the statically loaded preload module loader, so
228          we can use it to preopen the other loaders we linked in at
229          compile time.  */
230       errors += loader_init (get_vtable, 0);
231
232       /* Now open all the preloaded module loaders, so the application
233          can use _them_ to lt_dlopen its own modules.  */
234 #ifdef HAVE_LIBDLLOADER
235       if (!errors)
236         {
237           errors += lt_dlpreload (preloaded_symbols);
238         }
239
240       if (!errors)
241         {
242           errors += lt_dlpreload_open (LT_STR(LTDLOPEN), loader_init_callback);
243         }
244 #endif /* HAVE_LIBDLLOADER */
245     }
246
247 #ifdef LT_DEBUG_LOADERS
248   lt_dlloader_dump();
249 #endif
250
251   return errors;
252 }
253
254 int
255 lt_dlexit (void)
256 {
257   /* shut down libltdl */
258   lt_dlloader *loader   = 0;
259   lt_dlhandle  handle   = handles;
260   int          errors   = 0;
261
262   if (!initialized)
263     {
264       LT__SETERROR (SHUTDOWN);
265       ++errors;
266       goto done;
267     }
268
269   /* shut down only at last call. */
270   if (--initialized == 0)
271     {
272       int       level;
273
274       while (handles && LT_DLIS_RESIDENT (handles))
275         {
276           handles = handles->next;
277         }
278
279       /* close all modules */
280       for (level = 1; handle; ++level)
281         {
282           lt_dlhandle cur = handles;
283           int saw_nonresident = 0;
284
285           while (cur)
286             {
287               lt_dlhandle tmp = cur;
288               cur = cur->next;
289               if (!LT_DLIS_RESIDENT (tmp))
290                 {
291                   saw_nonresident = 1;
292                   if (tmp->info.ref_count <= level)
293                     {
294                       if (lt_dlclose (tmp))
295                         {
296                           ++errors;
297                         }
298                       /* Make sure that the handle pointed to by 'cur' still exists.
299                          lt_dlclose recursively closes dependent libraries which removes
300                          them from the linked list.  One of these might be the one
301                          pointed to by 'cur'.  */
302                       if (cur)
303                         {
304                           for (tmp = handles; tmp; tmp = tmp->next)
305                             if (tmp == cur)
306                               break;
307                           if (! tmp)
308                             cur = handles;
309                         }
310                     }
311                 }
312             }
313           /* done if only resident modules are left */
314           if (!saw_nonresident)
315             break;
316         }
317
318       /* When removing loaders, we can only find out failure by testing
319          the error string, so avoid a spurious one from an earlier
320          failed command. */
321       if (!errors)
322         LT__SETERRORSTR (0);
323
324       /* close all loaders */
325       for (loader = (lt_dlloader *) lt_dlloader_next (NULL); loader;)
326         {
327           lt_dlloader *next   = (lt_dlloader *) lt_dlloader_next (loader);
328           lt_dlvtable *vtable = (lt_dlvtable *) lt_dlloader_get (loader);
329
330           if ((vtable = lt_dlloader_remove ((char *) vtable->name)))
331             {
332               FREE (vtable);
333             }
334           else
335             {
336               /* ignore errors due to resident modules */
337               const char *err;
338               LT__GETERROR (err);
339               if (err)
340                 ++errors;
341             }
342
343           loader = next;
344         }
345
346       FREE(user_search_path);
347     }
348
349  done:
350   return errors;
351 }
352
353
354 /* Try VTABLE or, if VTABLE is NULL, all available loaders for FILENAME.
355    If the library is not successfully loaded, return non-zero.  Otherwise,
356    the dlhandle is stored at the address given in PHANDLE.  */
357 static int
358 tryall_dlopen (lt_dlhandle *phandle, const char *filename,
359                lt_dladvise advise, const lt_dlvtable *vtable)
360 {
361   lt_dlhandle   handle          = handles;
362   const char *  saved_error     = 0;
363   int           errors          = 0;
364
365 #ifdef LT_DEBUG_LOADERS
366   fprintf (stderr, "tryall_dlopen (%s, %s)\n",
367            filename ? filename : "(null)",
368            vtable ? vtable->name : "(ALL)");
369 #endif
370
371   LT__GETERROR (saved_error);
372
373   /* check whether the module was already opened */
374   for (;handle; handle = handle->next)
375     {
376       if ((handle->info.filename == filename) /* dlopen self: 0 == 0 */
377           || (handle->info.filename && filename
378               && streq (handle->info.filename, filename)))
379         {
380           break;
381         }
382     }
383
384   if (handle)
385     {
386       ++handle->info.ref_count;
387       *phandle = handle;
388       goto done;
389     }
390
391   handle = *phandle;
392   if (filename)
393     {
394       /* Comment out the check of file permissions using access.
395          This call seems to always return -1 with error EACCES.
396       */
397       /* We need to catch missing file errors early so that
398          file_not_found() can detect what happened.
399       if (access (filename, R_OK) != 0)
400         {
401           LT__SETERROR (FILE_NOT_FOUND);
402           ++errors;
403           goto done;
404         } */
405
406       handle->info.filename = lt__strdup (filename);
407       if (!handle->info.filename)
408         {
409           ++errors;
410           goto done;
411         }
412     }
413   else
414     {
415       handle->info.filename = 0;
416     }
417
418   {
419     lt_dlloader loader = lt_dlloader_next (0);
420     const lt_dlvtable *loader_vtable;
421
422     do
423       {
424         if (vtable)
425           loader_vtable = vtable;
426         else
427           loader_vtable = lt_dlloader_get (loader);
428
429 #ifdef LT_DEBUG_LOADERS
430         fprintf (stderr, "Calling %s->module_open (%s)\n",
431                  (loader_vtable && loader_vtable->name) ? loader_vtable->name : "(null)",
432                  filename ? filename : "(null)");
433 #endif
434         handle->module = (*loader_vtable->module_open) (loader_vtable->dlloader_data,
435                                                         filename, advise);
436 #ifdef LT_DEBUG_LOADERS
437         fprintf (stderr, "  Result: %s\n",
438                  handle->module ? "Success" : "Failed");
439 #endif
440
441         if (handle->module != 0)
442           {
443             if (advise)
444               {
445                 handle->info.is_resident  = advise->is_resident;
446                 handle->info.is_symglobal = advise->is_symglobal;
447                 handle->info.is_symlocal  = advise->is_symlocal;
448               }
449             break;
450           }
451       }
452     while (!vtable && (loader = lt_dlloader_next (loader)));
453
454     /* If VTABLE was given but couldn't open the module, or VTABLE wasn't
455        given but we exhausted all loaders without opening the module, bail
456        out!  */
457     if ((vtable && !handle->module)
458         || (!vtable && !loader))
459       {
460         FREE (handle->info.filename);
461         ++errors;
462         goto done;
463       }
464
465     handle->vtable = loader_vtable;
466   }
467
468   LT__SETERRORSTR (saved_error);
469
470  done:
471   return errors;
472 }
473
474
475 static int
476 tryall_dlopen_module (lt_dlhandle *handle, const char *prefix,
477                       const char *dirname, const char *dlname,
478                       lt_dladvise advise)
479 {
480   int      error        = 0;
481   char     *filename    = 0;
482   size_t   filename_len = 0;
483   size_t   dirname_len  = LT_STRLEN (dirname);
484
485   assert (handle);
486   assert (dirname);
487   assert (dlname);
488 #if defined(LT_DIRSEP_CHAR)
489   /* Only canonicalized names (i.e. with DIRSEP chars already converted)
490      should make it into this function:  */
491   assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
492 #endif
493
494   if (dirname_len > 0)
495     if (dirname[dirname_len -1] == '/')
496       --dirname_len;
497   filename_len = dirname_len + 1 + LT_STRLEN (dlname);
498
499   /* Allocate memory, and combine DIRNAME and MODULENAME into it.
500      The PREFIX (if any) is handled below.  */
501   filename  = MALLOC (char, filename_len + 1);
502   if (!filename)
503     return 1;
504
505   sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
506
507   /* Now that we have combined DIRNAME and MODULENAME, if there is
508      also a PREFIX to contend with, simply recurse with the arguments
509      shuffled.  Otherwise, attempt to open FILENAME as a module.  */
510   if (prefix)
511     {
512       error += tryall_dlopen_module (handle, (const char *) 0,
513                                      prefix, filename, advise);
514     }
515   else if (tryall_dlopen (handle, filename, advise, 0) != 0)
516     {
517       ++error;
518     }
519
520   FREE (filename);
521   return error;
522 }
523
524 static int
525 find_module (lt_dlhandle *handle, const char *dir, const char *libdir,
526              const char *dlname,  const char *old_name, int installed,
527              lt_dladvise advise)
528 {
529   /* Try to open the old library first; if it was dlpreopened,
530      we want the preopened version of it, even if a dlopenable
531      module is available.  */
532   if (old_name && tryall_dlopen (handle, old_name,
533                           advise, lt_dlloader_find ("lt_preopen") ) == 0)
534     {
535       return 0;
536     }
537
538   /* Try to open the dynamic library.  */
539   if (dlname)
540     {
541       /* try to open the installed module */
542       if (installed && libdir)
543         {
544           if (tryall_dlopen_module (handle, (const char *) 0,
545                                     libdir, dlname, advise) == 0)
546             return 0;
547         }
548
549       /* try to open the not-installed module */
550       if (!installed)
551         {
552           if (tryall_dlopen_module (handle, dir, objdir,
553                                     dlname, advise) == 0)
554             return 0;
555         }
556
557       /* maybe it was moved to another directory */
558       {
559           if (dir && (tryall_dlopen_module (handle, (const char *) 0,
560                                             dir, dlname, advise) == 0))
561             return 0;
562       }
563     }
564
565   return 1;
566 }
567
568
569 static int
570 canonicalize_path (const char *path, char **pcanonical)
571 {
572   char *canonical = 0;
573
574   assert (path && *path);
575   assert (pcanonical);
576
577   canonical = MALLOC (char, 1+ LT_STRLEN (path));
578   if (!canonical)
579     return 1;
580
581   {
582     size_t dest = 0;
583     size_t src;
584     for (src = 0; path[src] != LT_EOS_CHAR; ++src)
585       {
586         /* Path separators are not copied to the beginning or end of
587            the destination, or if another separator would follow
588            immediately.  */
589         if (path[src] == LT_PATHSEP_CHAR)
590           {
591             if ((dest == 0)
592                 || (path[1+ src] == LT_PATHSEP_CHAR)
593                 || (path[1+ src] == LT_EOS_CHAR))
594               continue;
595           }
596
597         /* Anything other than a directory separator is copied verbatim.  */
598         if ((path[src] != '/')
599 #if defined(LT_DIRSEP_CHAR)
600             && (path[src] != LT_DIRSEP_CHAR)
601 #endif
602             )
603           {
604             canonical[dest++] = path[src];
605           }
606         /* Directory separators are converted and copied only if they are
607            not at the end of a path -- i.e. before a path separator or
608            NULL terminator.  */
609         else if ((path[1+ src] != LT_PATHSEP_CHAR)
610                  && (path[1+ src] != LT_EOS_CHAR)
611 #if defined(LT_DIRSEP_CHAR)
612                  && (path[1+ src] != LT_DIRSEP_CHAR)
613 #endif
614                  && (path[1+ src] != '/'))
615           {
616             canonical[dest++] = '/';
617           }
618       }
619
620     /* Add an end-of-string marker at the end.  */
621     canonical[dest] = LT_EOS_CHAR;
622   }
623
624   /* Assign new value.  */
625   *pcanonical = canonical;
626
627   return 0;
628 }
629
630 static int
631 argzize_path (const char *path, char **pargz, size_t *pargz_len)
632 {
633   error_t error;
634
635   assert (path);
636   assert (pargz);
637   assert (pargz_len);
638
639   if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
640     {
641       switch (error)
642         {
643         case ENOMEM:
644           LT__SETERROR (NO_MEMORY);
645           break;
646         default:
647           LT__SETERROR (UNKNOWN);
648           break;
649         }
650
651       return 1;
652     }
653
654   return 0;
655 }
656
657 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
658    of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
659    non-zero or all elements are exhausted.  If BASE_NAME is non-NULL,
660    it is appended to each SEARCH_PATH element before FUNC is called.  */
661 static int
662 foreach_dirinpath (const char *search_path, const char *base_name,
663                    foreach_callback_func *func, void *data1, void *data2)
664 {
665   int    result         = 0;
666   size_t filenamesize   = 0;
667   size_t lenbase        = LT_STRLEN (base_name);
668   size_t argz_len       = 0;
669   char *argz            = 0;
670   char *filename        = 0;
671   char *canonical       = 0;
672
673   if (!search_path || !*search_path)
674     {
675       LT__SETERROR (FILE_NOT_FOUND);
676       goto cleanup;
677     }
678
679   if (canonicalize_path (search_path, &canonical) != 0)
680     goto cleanup;
681
682   if (argzize_path (canonical, &argz, &argz_len) != 0)
683     goto cleanup;
684
685   {
686     char *dir_name = 0;
687     while ((dir_name = argz_next (argz, argz_len, dir_name)))
688       {
689         size_t lendir = LT_STRLEN (dir_name);
690
691         if (1+ lendir + lenbase >= filenamesize)
692         {
693           FREE (filename);
694           filenamesize  = 1+ lendir + 1+ lenbase; /* "/d" + '/' + "f" + '\0' */
695           filename      = MALLOC (char, filenamesize);
696           if (!filename)
697             goto cleanup;
698         }
699
700         assert (filenamesize > lendir);
701         strcpy (filename, dir_name);
702
703         if (base_name && *base_name)
704           {
705             if (filename[lendir -1] != '/')
706               filename[lendir++] = '/';
707             strcpy (filename +lendir, base_name);
708           }
709
710         if ((result = (*func) (filename, data1, data2)))
711           {
712             break;
713           }
714       }
715   }
716
717  cleanup:
718   FREE (argz);
719   FREE (canonical);
720   FREE (filename);
721
722   return result;
723 }
724
725 /* If FILEPATH can be opened, store the name of the directory component
726    in DATA1, and the opened FILE* structure address in DATA2.  Otherwise
727    DATA1 is unchanged, but DATA2 is set to a pointer to NULL.  */
728 static int
729 find_file_callback (char *filename, void *data1, void *data2)
730 {
731   char       **pdir     = (char **) data1;
732   FILE       **pfile    = (FILE **) data2;
733   int        is_done    = 0;
734
735   assert (filename && *filename);
736   assert (pdir);
737   assert (pfile);
738
739   if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
740     {
741       char *dirend = strrchr (filename, '/');
742
743       if (dirend > filename)
744         *dirend   = LT_EOS_CHAR;
745
746       FREE (*pdir);
747       *pdir   = lt__strdup (filename);
748       is_done = (*pdir == 0) ? -1 : 1;
749     }
750
751   return is_done;
752 }
753
754 static FILE *
755 find_file (const char *search_path, const char *base_name, char **pdir)
756 {
757   FILE *file = 0;
758
759   foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
760
761   return file;
762 }
763
764 static int
765 find_handle_callback (char *filename, void *data, void *data2)
766 {
767   lt_dlhandle  *phandle         = (lt_dlhandle *) data;
768   int           notfound        = access (filename, R_OK);
769   lt_dladvise   advise          = (lt_dladvise) data2;
770
771   /* Bail out if file cannot be read...  */
772   if (notfound)
773     return 0;
774
775   /* Try to dlopen the file, but do not continue searching in any
776      case.  */
777   if (tryall_dlopen (phandle, filename, advise, 0) != 0)
778     *phandle = 0;
779
780   return 1;
781 }
782
783 /* If HANDLE was found return it, otherwise return 0.  If HANDLE was
784    found but could not be opened, *HANDLE will be set to 0.  */
785 static lt_dlhandle *
786 find_handle (const char *search_path, const char *base_name,
787              lt_dlhandle *phandle, lt_dladvise advise)
788 {
789   if (!search_path)
790     return 0;
791
792   if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
793                           phandle, advise))
794     return 0;
795
796   return phandle;
797 }
798
799 #if !defined(LTDL_DLOPEN_DEPLIBS)
800 static int
801 load_deplibs (lt_dlhandle handle, char * LT__UNUSED deplibs)
802 {
803   handle->depcount = 0;
804   return 0;
805 }
806
807 #else /* defined(LTDL_DLOPEN_DEPLIBS) */
808 static int
809 load_deplibs (lt_dlhandle handle, char *deplibs)
810 {
811   char  *p, *save_search_path = 0;
812   int   depcount = 0;
813   int   i;
814   char  **names = 0;
815   int   errors = 0;
816
817   handle->depcount = 0;
818
819   if (!deplibs)
820     {
821       return errors;
822     }
823   ++errors;
824
825   if (user_search_path)
826     {
827       save_search_path = lt__strdup (user_search_path);
828       if (!save_search_path)
829         goto cleanup;
830     }
831
832   /* extract search paths and count deplibs */
833   p = deplibs;
834   while (*p)
835     {
836       if (!isspace ((unsigned char) *p))
837         {
838           char *end = p+1;
839           while (*end && !isspace((unsigned char) *end))
840             {
841               ++end;
842             }
843
844           if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
845             {
846               char save = *end;
847               *end = 0; /* set a temporary string terminator */
848               if (lt_dladdsearchdir(p+2))
849                 {
850                   goto cleanup;
851                 }
852               *end = save;
853             }
854           else
855             {
856               ++depcount;
857             }
858
859           p = end;
860         }
861       else
862         {
863           ++p;
864         }
865     }
866
867
868   if (!depcount)
869     {
870       errors = 0;
871       goto cleanup;
872     }
873
874   names = MALLOC (char *, depcount);
875   if (!names)
876     goto cleanup;
877
878   /* now only extract the actual deplibs */
879   depcount = 0;
880   p = deplibs;
881   while (*p)
882     {
883       if (isspace ((unsigned char) *p))
884         {
885           ++p;
886         }
887       else
888         {
889           char *end = p+1;
890           while (*end && !isspace ((unsigned char) *end))
891             {
892               ++end;
893             }
894
895           if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
896             {
897               char *name;
898               char save = *end;
899               *end = 0; /* set a temporary string terminator */
900               if (strncmp(p, "-l", 2) == 0)
901                 {
902                   size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
903                   name = MALLOC (char, 1+ name_len);
904                   if (name)
905                     sprintf (name, "lib%s", p+2);
906                 }
907               else
908                 name = lt__strdup(p);
909
910               if (!name)
911                 goto cleanup_names;
912
913               names[depcount++] = name;
914               *end = save;
915             }
916           p = end;
917         }
918     }
919
920   /* load the deplibs (in reverse order)
921      At this stage, don't worry if the deplibs do not load correctly,
922      they may already be statically linked into the loading application
923      for instance.  There will be a more enlightening error message
924      later on if the loaded module cannot resolve all of its symbols.  */
925   if (depcount)
926     {
927       lt_dlhandle cur = handle;
928       int       j = 0;
929
930       cur->deplibs = MALLOC (lt_dlhandle, depcount);
931       if (!cur->deplibs)
932         goto cleanup_names;
933
934       for (i = 0; i < depcount; ++i)
935         {
936           cur->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
937           if (cur->deplibs[j])
938             {
939               ++j;
940             }
941         }
942
943       cur->depcount     = j;    /* Number of successfully loaded deplibs */
944       errors            = 0;
945     }
946
947  cleanup_names:
948   for (i = 0; i < depcount; ++i)
949     {
950       FREE (names[i]);
951     }
952
953  cleanup:
954   FREE (names);
955   /* restore the old search path */
956   if (save_search_path) {
957     MEMREASSIGN (user_search_path, save_search_path);
958   }
959
960   return errors;
961 }
962 #endif /* defined(LTDL_DLOPEN_DEPLIBS) */
963
964 static int
965 unload_deplibs (lt_dlhandle handle)
966 {
967   int i;
968   int errors = 0;
969   lt_dlhandle cur = handle;
970
971   if (cur->depcount)
972     {
973       for (i = 0; i < cur->depcount; ++i)
974         {
975           if (!LT_DLIS_RESIDENT (cur->deplibs[i]))
976             {
977               errors += lt_dlclose (cur->deplibs[i]);
978             }
979         }
980       FREE (cur->deplibs);
981     }
982
983   return errors;
984 }
985
986 static int
987 trim (char **dest, const char *str)
988 {
989   /* remove the leading and trailing "'" from str
990      and store the result in dest */
991   const char *end   = strrchr (str, '\'');
992   size_t len        = LT_STRLEN (str);
993   char *tmp;
994
995   FREE (*dest);
996
997   if (!end || end == str)
998     return 1;
999
1000   if (len > 3 && str[0] == '\'')
1001     {
1002       tmp = MALLOC (char, end - str);
1003       if (!tmp)
1004         return 1;
1005
1006       memcpy(tmp, &str[1], (end - str) - 1);
1007       tmp[(end - str) - 1] = LT_EOS_CHAR;
1008       *dest = tmp;
1009     }
1010   else
1011     {
1012       *dest = 0;
1013     }
1014
1015   return 0;
1016 }
1017
1018 /* Read the .la file FILE. */
1019 static int
1020 parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs,
1021     char **old_name, int *installed)
1022 {
1023   int           errors = 0;
1024   size_t        line_len = LT_FILENAME_MAX;
1025   char *        line = MALLOC (char, line_len);
1026
1027   if (!line)
1028     {
1029       LT__SETERROR (FILE_NOT_FOUND);
1030       return 1;
1031     }
1032
1033   while (!feof (file))
1034     {
1035       line[line_len-2] = '\0';
1036       if (!fgets (line, (int) line_len, file))
1037         {
1038           break;
1039         }
1040
1041       /* Handle the case where we occasionally need to read a line
1042          that is longer than the initial buffer size.
1043          Behave even if the file contains NUL bytes due to corruption. */
1044       while (line[line_len-2] != '\0' && line[line_len-2] != '\n' && !feof (file))
1045         {
1046           line = REALLOC (char, line, line_len *2);
1047           if (!line)
1048             {
1049               ++errors;
1050               goto cleanup;
1051             }
1052           line[line_len * 2 - 2] = '\0';
1053           if (!fgets (&line[line_len -1], (int) line_len +1, file))
1054             {
1055               break;
1056             }
1057           line_len *= 2;
1058         }
1059
1060       if (line[0] == '\n' || line[0] == '#')
1061         {
1062           continue;
1063         }
1064
1065 #undef  STR_DLNAME
1066 #define STR_DLNAME      "dlname="
1067       if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
1068         {
1069           errors += trim (dlname, &line[sizeof (STR_DLNAME) - 1]);
1070         }
1071
1072 #undef  STR_OLD_LIBRARY
1073 #define STR_OLD_LIBRARY "old_library="
1074       else if (strncmp (line, STR_OLD_LIBRARY,
1075             sizeof (STR_OLD_LIBRARY) - 1) == 0)
1076         {
1077           errors += trim (old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
1078         }
1079 #undef  STR_LIBDIR
1080 #define STR_LIBDIR      "libdir="
1081       else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
1082         {
1083           errors += trim (libdir, &line[sizeof(STR_LIBDIR) - 1]);
1084         }
1085
1086 #undef  STR_DL_DEPLIBS
1087 #define STR_DL_DEPLIBS  "dependency_libs="
1088       else if (strncmp (line, STR_DL_DEPLIBS,
1089             sizeof (STR_DL_DEPLIBS) - 1) == 0)
1090         {
1091           errors += trim (deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
1092         }
1093       else if (streq (line, "installed=yes\n"))
1094         {
1095           *installed = 1;
1096         }
1097       else if (streq (line, "installed=no\n"))
1098         {
1099           *installed = 0;
1100         }
1101
1102 #undef  STR_LIBRARY_NAMES
1103 #define STR_LIBRARY_NAMES "library_names="
1104       else if (!*dlname && strncmp (line, STR_LIBRARY_NAMES,
1105             sizeof (STR_LIBRARY_NAMES) - 1) == 0)
1106         {
1107           char *last_libname;
1108           errors += trim (dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
1109           if (!errors
1110               && *dlname
1111               && (last_libname = strrchr (*dlname, ' ')) != 0)
1112             {
1113               last_libname = lt__strdup (last_libname + 1);
1114               if (!last_libname)
1115                 {
1116                   ++errors;
1117                   goto cleanup;
1118                 }
1119               MEMREASSIGN (*dlname, last_libname);
1120             }
1121         }
1122
1123       if (errors)
1124         break;
1125     }
1126 cleanup:
1127   FREE (line);
1128   return errors;
1129 }
1130
1131
1132 /* Try to open FILENAME as a module. */
1133 static int
1134 try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
1135             lt_dladvise advise)
1136 {
1137   const char *  saved_error     = 0;
1138   char *        archive_name    = 0;
1139   char *        canonical       = 0;
1140   char *        base_name       = 0;
1141   char *        dir             = 0;
1142   char *        name            = 0;
1143   char *        attempt         = 0;
1144   int           errors          = 0;
1145   lt_dlhandle   newhandle;
1146
1147   assert (phandle);
1148   assert (*phandle == 0);
1149
1150 #ifdef LT_DEBUG_LOADERS
1151   fprintf (stderr, "try_dlopen (%s, %s)\n",
1152            filename ? filename : "(null)",
1153            ext ? ext : "(null)");
1154 #endif
1155
1156   LT__GETERROR (saved_error);
1157
1158   /* dlopen self? */
1159   if (!filename)
1160     {
1161       *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1162       if (*phandle == 0)
1163         return 1;
1164
1165       newhandle = *phandle;
1166
1167       /* lt_dlclose()ing yourself is very bad!  Disallow it.  */
1168       newhandle->info.is_resident = 1;
1169
1170       if (tryall_dlopen (&newhandle, 0, advise, 0) != 0)
1171         {
1172           FREE (*phandle);
1173           return 1;
1174         }
1175
1176       goto register_handle;
1177     }
1178
1179   assert (filename && *filename);
1180
1181   if (ext)
1182     {
1183       attempt = MALLOC (char, LT_STRLEN (filename) + LT_STRLEN (ext) + 1);
1184       if (!attempt)
1185         return 1;
1186
1187       sprintf(attempt, "%s%s", filename, ext);
1188     }
1189   else
1190     {
1191       attempt = lt__strdup (filename);
1192       if (!attempt)
1193         return 1;
1194     }
1195
1196   /* Doing this immediately allows internal functions to safely
1197      assume only canonicalized paths are passed.  */
1198   if (canonicalize_path (attempt, &canonical) != 0)
1199     {
1200       ++errors;
1201       goto cleanup;
1202     }
1203
1204   /* If the canonical module name is a path (relative or absolute)
1205      then split it into a directory part and a name part.  */
1206   base_name = strrchr (canonical, '/');
1207   if (base_name)
1208     {
1209       size_t dirlen = (1+ base_name) - canonical;
1210
1211       dir = MALLOC (char, 1+ dirlen);
1212       if (!dir)
1213         {
1214           ++errors;
1215           goto cleanup;
1216         }
1217
1218       strncpy (dir, canonical, dirlen);
1219       dir[dirlen] = LT_EOS_CHAR;
1220
1221       ++base_name;
1222     }
1223   else
1224     MEMREASSIGN (base_name, canonical);
1225
1226   assert (base_name && *base_name);
1227
1228   ext = strrchr (base_name, '.');
1229   if (!ext)
1230     {
1231       ext = base_name + LT_STRLEN (base_name);
1232     }
1233
1234   /* extract the module name from the file name */
1235   name = MALLOC (char, ext - base_name + 1);
1236   if (!name)
1237     {
1238       ++errors;
1239       goto cleanup;
1240     }
1241
1242   /* canonicalize the module name */
1243   {
1244     int i;
1245     for (i = 0; i < ext - base_name; ++i)
1246       {
1247         if (isalnum ((unsigned char)(base_name[i])))
1248           {
1249             name[i] = base_name[i];
1250           }
1251         else
1252           {
1253             name[i] = '_';
1254           }
1255       }
1256     name[ext - base_name] = LT_EOS_CHAR;
1257   }
1258
1259   /* Before trawling through the filesystem in search of a module,
1260      check whether we are opening a preloaded module.  */
1261   if (!dir)
1262     {
1263       const lt_dlvtable *vtable = lt_dlloader_find ("lt_preopen");
1264
1265       if (vtable)
1266         {
1267           /* name + "." + libext + NULL */
1268           archive_name = MALLOC (char, LT_STRLEN (name) + strlen (libext) + 2);
1269           *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1270
1271           if ((*phandle == NULL) || (archive_name == NULL))
1272             {
1273               ++errors;
1274               goto cleanup;
1275             }
1276           newhandle = *phandle;
1277
1278           /* Preloaded modules are always named according to their old
1279              archive name.  */
1280           sprintf (archive_name, "%s.%s", name, libext);
1281
1282           if (tryall_dlopen (&newhandle, archive_name, advise, vtable) == 0)
1283             {
1284               goto register_handle;
1285             }
1286
1287           /* If we're still here, there was no matching preloaded module,
1288              so put things back as we found them, and continue searching.  */
1289           FREE (*phandle);
1290           newhandle = NULL;
1291         }
1292     }
1293
1294   /* If we are allowing only preloaded modules, and we didn't find
1295      anything yet, give up on the search here.  */
1296   if (advise && advise->try_preload_only)
1297     {
1298       goto cleanup;
1299     }
1300
1301   /* Check whether we are opening a libtool module (.la extension).  */
1302   if (ext && streq (ext, archive_ext))
1303     {
1304       /* this seems to be a libtool module */
1305       FILE *    file     = 0;
1306       char *    dlname   = 0;
1307       char *    old_name = 0;
1308       char *    libdir   = 0;
1309       char *    deplibs  = 0;
1310
1311       /* if we can't find the installed flag, it is probably an
1312          installed libtool archive, produced with an old version
1313          of libtool */
1314       int       installed = 1;
1315
1316       /* Now try to open the .la file.  If there is no directory name
1317          component, try to find it first in user_search_path and then other
1318          prescribed paths.  Otherwise (or in any case if the module was not
1319          yet found) try opening just the module name as passed.  */
1320       if (!dir)
1321         {
1322           const char *search_path = user_search_path;
1323
1324           if (search_path)
1325             file = find_file (user_search_path, base_name, &dir);
1326
1327           if (!file)
1328             {
1329               search_path = getenv (LTDL_SEARCHPATH_VAR);
1330               if (search_path)
1331                 file = find_file (search_path, base_name, &dir);
1332             }
1333
1334 #if defined(LT_MODULE_PATH_VAR)
1335           if (!file)
1336             {
1337               search_path = getenv (LT_MODULE_PATH_VAR);
1338               if (search_path)
1339                 file = find_file (search_path, base_name, &dir);
1340             }
1341 #endif
1342 #if defined(LT_DLSEARCH_PATH)
1343           if (!file && *sys_dlsearch_path)
1344             {
1345               file = find_file (sys_dlsearch_path, base_name, &dir);
1346             }
1347 #endif
1348         }
1349       else
1350         {
1351           file = fopen (attempt, LT_READTEXT_MODE);
1352         }
1353
1354       /* If we didn't find the file by now, it really isn't there.  Set
1355          the status flag, and bail out.  */
1356       if (!file)
1357         {
1358           LT__SETERROR (FILE_NOT_FOUND);
1359           ++errors;
1360           goto cleanup;
1361         }
1362
1363       /* read the .la file */
1364       if (parse_dotla_file(file, &dlname, &libdir, &deplibs,
1365             &old_name, &installed) != 0)
1366         ++errors;
1367
1368       fclose (file);
1369
1370       /* allocate the handle */
1371       *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1372       if (*phandle == 0)
1373         ++errors;
1374
1375       if (errors)
1376         {
1377           FREE (dlname);
1378           FREE (old_name);
1379           FREE (libdir);
1380           FREE (deplibs);
1381           FREE (*phandle);
1382           goto cleanup;
1383         }
1384
1385       assert (*phandle);
1386
1387       if (load_deplibs (*phandle, deplibs) == 0)
1388         {
1389           newhandle = *phandle;
1390           /* find_module may replace newhandle */
1391           if (find_module (&newhandle, dir, libdir, dlname, old_name,
1392                            installed, advise))
1393             {
1394               unload_deplibs (*phandle);
1395               ++errors;
1396             }
1397         }
1398       else
1399         {
1400           ++errors;
1401         }
1402
1403       FREE (dlname);
1404       FREE (old_name);
1405       FREE (libdir);
1406       FREE (deplibs);
1407
1408       if (errors)
1409         {
1410           FREE (*phandle);
1411           goto cleanup;
1412         }
1413
1414       if (*phandle != newhandle)
1415         {
1416           unload_deplibs (*phandle);
1417         }
1418     }
1419   else
1420     {
1421       /* not a libtool module */
1422       *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1423       if (*phandle == 0)
1424         {
1425           ++errors;
1426           goto cleanup;
1427         }
1428
1429       newhandle = *phandle;
1430
1431       /* If the module has no directory name component, try to find it
1432          first in user_search_path and then other prescribed paths.
1433          Otherwise (or in any case if the module was not yet found) try
1434          opening just the module name as passed.  */
1435       if ((dir || (!find_handle (user_search_path, base_name,
1436                                  &newhandle, advise)
1437                    && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
1438                                     &newhandle, advise)
1439 #if defined(LT_MODULE_PATH_VAR)
1440                    && !find_handle (getenv (LT_MODULE_PATH_VAR), base_name,
1441                                     &newhandle, advise)
1442 #endif
1443 #if defined(LT_DLSEARCH_PATH)
1444                    && !find_handle (sys_dlsearch_path, base_name,
1445                                     &newhandle, advise)
1446 #endif
1447                    )))
1448         {
1449           if (tryall_dlopen (&newhandle, attempt, advise, 0) != 0)
1450             {
1451               newhandle = NULL;
1452             }
1453         }
1454
1455       if (!newhandle)
1456         {
1457           FREE (*phandle);
1458           ++errors;
1459           goto cleanup;
1460         }
1461     }
1462
1463  register_handle:
1464   MEMREASSIGN (*phandle, newhandle);
1465
1466   if ((*phandle)->info.ref_count == 0)
1467     {
1468       (*phandle)->info.ref_count        = 1;
1469       MEMREASSIGN ((*phandle)->info.name, name);
1470
1471       (*phandle)->next  = handles;
1472       handles           = *phandle;
1473     }
1474
1475   LT__SETERRORSTR (saved_error);
1476
1477  cleanup:
1478   FREE (dir);
1479   FREE (attempt);
1480   FREE (name);
1481   if (!canonical)               /* was MEMREASSIGNed */
1482     FREE (base_name);
1483   FREE (canonical);
1484   FREE (archive_name);
1485
1486   return errors;
1487 }
1488
1489
1490 /* If the last error message stored was `FILE_NOT_FOUND', then return
1491    non-zero.  */
1492 static int
1493 file_not_found (void)
1494 {
1495   const char *error = 0;
1496
1497   LT__GETERROR (error);
1498   if (error == LT__STRERROR (FILE_NOT_FOUND))
1499     return 1;
1500
1501   return 0;
1502 }
1503
1504
1505 /* Unless FILENAME already bears a suitable library extension, then
1506    return 0.  */
1507 static int
1508 has_library_ext (const char *filename)
1509 {
1510   const char *  ext     = 0;
1511
1512   assert (filename);
1513
1514   ext = strrchr (filename, '.');
1515
1516   if (ext && ((streq (ext, archive_ext))
1517 #if defined(LT_MODULE_EXT)
1518              || (streq (ext, shlib_ext))
1519 #endif
1520     ))
1521     {
1522       return 1;
1523     }
1524
1525   return 0;
1526 }
1527
1528
1529 /* Initialise and configure a user lt_dladvise opaque object.  */
1530
1531 int
1532 lt_dladvise_init (lt_dladvise *padvise)
1533 {
1534   lt_dladvise advise = (lt_dladvise) lt__zalloc (sizeof (struct lt__advise));
1535   *padvise = advise;
1536   return (advise ? 0 : 1);
1537 }
1538
1539 int
1540 lt_dladvise_destroy (lt_dladvise *padvise)
1541 {
1542   if (padvise)
1543     FREE(*padvise);
1544   return 0;
1545 }
1546
1547 int
1548 lt_dladvise_ext (lt_dladvise *padvise)
1549 {
1550   assert (padvise && *padvise);
1551   (*padvise)->try_ext = 1;
1552   return 0;
1553 }
1554
1555 int
1556 lt_dladvise_resident (lt_dladvise *padvise)
1557 {
1558   assert (padvise && *padvise);
1559   (*padvise)->is_resident = 1;
1560   return 0;
1561 }
1562
1563 int
1564 lt_dladvise_local (lt_dladvise *padvise)
1565 {
1566   assert (padvise && *padvise);
1567   (*padvise)->is_symlocal = 1;
1568   return 0;
1569 }
1570
1571 int
1572 lt_dladvise_global (lt_dladvise *padvise)
1573 {
1574   assert (padvise && *padvise);
1575   (*padvise)->is_symglobal = 1;
1576   return 0;
1577 }
1578
1579 int
1580 lt_dladvise_preload (lt_dladvise *padvise)
1581 {
1582   assert (padvise && *padvise);
1583   (*padvise)->try_preload_only = 1;
1584   return 0;
1585 }
1586
1587 /* Libtool-1.5.x interface for loading a new module named FILENAME.  */
1588 lt_dlhandle
1589 lt_dlopen (const char *filename)
1590 {
1591   return lt_dlopenadvise (filename, NULL);
1592 }
1593
1594
1595 /* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to
1596    open the FILENAME as passed.  Otherwise try appending ARCHIVE_EXT,
1597    and if a file is still not found try again with MODULE_EXT appended
1598    instead.  */
1599 lt_dlhandle
1600 lt_dlopenext (const char *filename)
1601 {
1602   lt_dlhandle   handle  = 0;
1603   lt_dladvise   advise;
1604
1605   if (!lt_dladvise_init (&advise) && !lt_dladvise_ext (&advise))
1606     handle = lt_dlopenadvise (filename, advise);
1607
1608   lt_dladvise_destroy (&advise);
1609   return handle;
1610 }
1611
1612
1613 lt_dlhandle
1614 lt_dlopenadvise (const char *filename, lt_dladvise advise)
1615 {
1616   lt_dlhandle   handle  = 0;
1617   int           errors  = 0;
1618   const char *  saved_error     = 0;
1619
1620   LT__GETERROR (saved_error);
1621
1622   /* Can't have symbols hidden and visible at the same time!  */
1623   if (advise && advise->is_symlocal && advise->is_symglobal)
1624     {
1625       LT__SETERROR (CONFLICTING_FLAGS);
1626       return 0;
1627     }
1628
1629   if (!filename
1630       || !advise
1631       || !advise->try_ext
1632       || has_library_ext (filename))
1633     {
1634       /* Just incase we missed a code path in try_dlopen() that reports
1635          an error, but forgot to reset handle... */
1636       if (try_dlopen (&handle, filename, NULL, advise) != 0)
1637         return 0;
1638
1639       return handle;
1640     }
1641   else if (filename && *filename)
1642     {
1643
1644       /* First try appending ARCHIVE_EXT.  */
1645       errors += try_dlopen (&handle, filename, archive_ext, advise);
1646
1647       /* If we found FILENAME, stop searching -- whether we were able to
1648          load the file as a module or not.  If the file exists but loading
1649          failed, it is better to return an error message here than to
1650          report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
1651          in the module search path.  */
1652       if (handle || ((errors > 0) && !file_not_found ()))
1653         return handle;
1654
1655 #if defined(LT_MODULE_EXT)
1656       /* Try appending SHLIB_EXT.   */
1657       LT__SETERRORSTR (saved_error);
1658       errors = try_dlopen (&handle, filename, shlib_ext, advise);
1659
1660       /* As before, if the file was found but loading failed, return now
1661          with the current error message.  */
1662       if (handle || ((errors > 0) && !file_not_found ()))
1663         return handle;
1664 #endif
1665     }
1666
1667   /* Still here?  Then we really did fail to locate any of the file
1668      names we tried.  */
1669   LT__SETERROR (FILE_NOT_FOUND);
1670   return 0;
1671 }
1672
1673
1674 static int
1675 lt_argz_insert (char **pargz, size_t *pargz_len, char *before,
1676                 const char *entry)
1677 {
1678   error_t error;
1679
1680   /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
1681      pargz_len, NULL, entry) failed with EINVAL.  */
1682   if (before)
1683     error = argz_insert (pargz, pargz_len, before, entry);
1684   else
1685     error = argz_append (pargz, pargz_len, entry, 1 + strlen (entry));
1686
1687   if (error)
1688     {
1689       switch (error)
1690         {
1691         case ENOMEM:
1692           LT__SETERROR (NO_MEMORY);
1693           break;
1694         default:
1695           LT__SETERROR (UNKNOWN);
1696           break;
1697         }
1698       return 1;
1699     }
1700
1701   return 0;
1702 }
1703
1704 static int
1705 lt_argz_insertinorder (char **pargz, size_t *pargz_len, const char *entry)
1706 {
1707   char *before = 0;
1708
1709   assert (pargz);
1710   assert (pargz_len);
1711   assert (entry && *entry);
1712
1713   if (*pargz)
1714     while ((before = argz_next (*pargz, *pargz_len, before)))
1715       {
1716         int cmp = strcmp (entry, before);
1717
1718         if (cmp < 0)  break;
1719         if (cmp == 0) return 0; /* No duplicates! */
1720       }
1721
1722   return lt_argz_insert (pargz, pargz_len, before, entry);
1723 }
1724
1725 static int
1726 lt_argz_insertdir (char **pargz, size_t *pargz_len, const char *dirnam,
1727                    struct dirent *dp)
1728 {
1729   char   *buf       = 0;
1730   size_t buf_len    = 0;
1731   char   *end       = 0;
1732   size_t end_offset = 0;
1733   size_t dir_len    = 0;
1734   int    errors     = 0;
1735
1736   assert (pargz);
1737   assert (pargz_len);
1738   assert (dp);
1739
1740   dir_len = LT_STRLEN (dirnam);
1741   end     = dp->d_name + D_NAMLEN(dp);
1742
1743   /* Ignore version numbers.  */
1744   {
1745     char *p;
1746     for (p = end; p -1 > dp->d_name; --p)
1747       if (strchr (".0123456789", p[-1]) == 0)
1748         break;
1749
1750     if (*p == '.')
1751       end = p;
1752   }
1753
1754   /* Ignore filename extension.  */
1755   {
1756     char *p;
1757     for (p = end -1; p > dp->d_name; --p)
1758       if (*p == '.')
1759         {
1760           end = p;
1761           break;
1762         }
1763   }
1764
1765   /* Prepend the directory name.  */
1766   end_offset    = end - dp->d_name;
1767   buf_len       = dir_len + 1+ end_offset;
1768   buf           = MALLOC (char, 1+ buf_len);
1769   if (!buf)
1770     return ++errors;
1771
1772   assert (buf);
1773
1774   strcpy  (buf, dirnam);
1775   strcat  (buf, "/");
1776   strncat (buf, dp->d_name, end_offset);
1777   buf[buf_len] = LT_EOS_CHAR;
1778
1779   /* Try to insert (in order) into ARGZ/ARGZ_LEN.  */
1780   if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
1781     ++errors;
1782
1783   FREE (buf);
1784
1785   return errors;
1786 }
1787
1788 static int
1789 list_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len)
1790 {
1791   DIR   *dirp     = 0;
1792   int    errors   = 0;
1793
1794   assert (dirnam && *dirnam);
1795   assert (pargz);
1796   assert (pargz_len);
1797   assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
1798
1799   dirp = opendir (dirnam);
1800   if (dirp)
1801     {
1802       struct dirent *dp = 0;
1803
1804       while ((dp = readdir (dirp)))
1805         if (dp->d_name[0] != '.')
1806           if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
1807             {
1808               ++errors;
1809               break;
1810             }
1811
1812       closedir (dirp);
1813     }
1814   else
1815     ++errors;
1816
1817   return errors;
1818 }
1819
1820
1821 /* If there are any files in DIRNAME, call the function passed in
1822    DATA1 (with the name of each file and DATA2 as arguments).  */
1823 static int
1824 foreachfile_callback (char *dirname, void *data1, void *data2)
1825 {
1826   file_worker_func *func = *(file_worker_func **) data1;
1827
1828   int     is_done  = 0;
1829   char   *argz     = 0;
1830   size_t  argz_len = 0;
1831
1832   if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
1833     goto cleanup;
1834   if (!argz)
1835     goto cleanup;
1836
1837   {
1838     char *filename = 0;
1839     while ((filename = argz_next (argz, argz_len, filename)))
1840       if ((is_done = (*func) (filename, data2)))
1841         break;
1842   }
1843
1844  cleanup:
1845   FREE (argz);
1846
1847   return is_done;
1848 }
1849
1850
1851 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
1852    with DATA.  The filenames passed to FUNC would be suitable for
1853    passing to lt_dlopenext.  The extensions are stripped so that
1854    individual modules do not generate several entries (e.g. libfoo.la,
1855    libfoo.so, libfoo.so.1, libfoo.so.1.0.0).  If SEARCH_PATH is NULL,
1856    then the same directories that lt_dlopen would search are examined.  */
1857 int
1858 lt_dlforeachfile (const char *search_path,
1859                   int (*func) (const char *filename, void *data),
1860                   void *data)
1861 {
1862   int is_done = 0;
1863   file_worker_func **fpptr = &func;
1864
1865   if (search_path)
1866     {
1867       /* If a specific path was passed, search only the directories
1868          listed in it.  */
1869       is_done = foreach_dirinpath (search_path, 0,
1870                                    foreachfile_callback, fpptr, data);
1871     }
1872   else
1873     {
1874       /* Otherwise search the default paths.  */
1875       is_done = foreach_dirinpath (user_search_path, 0,
1876                                    foreachfile_callback, fpptr, data);
1877       if (!is_done)
1878         {
1879           is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0,
1880                                        foreachfile_callback, fpptr, data);
1881         }
1882
1883 #if defined(LT_MODULE_PATH_VAR)
1884       if (!is_done)
1885         {
1886           is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0,
1887                                        foreachfile_callback, fpptr, data);
1888         }
1889 #endif
1890 #if defined(LT_DLSEARCH_PATH)
1891       if (!is_done && *sys_dlsearch_path)
1892         {
1893           is_done = foreach_dirinpath (sys_dlsearch_path, 0,
1894                                        foreachfile_callback, fpptr, data);
1895         }
1896 #endif
1897     }
1898
1899   return is_done;
1900 }
1901
1902 int
1903 lt_dlclose (lt_dlhandle handle)
1904 {
1905   lt_dlhandle cur, last;
1906   int errors = 0;
1907
1908   /* check whether the handle is valid */
1909   last = cur = handles;
1910   while (cur && handle != cur)
1911     {
1912       last = cur;
1913       cur = cur->next;
1914     }
1915
1916   if (!cur)
1917     {
1918       LT__SETERROR (INVALID_HANDLE);
1919       ++errors;
1920       goto done;
1921     }
1922
1923   cur = handle;
1924   cur->info.ref_count--;
1925
1926   /* Note that even with resident modules, we must track the ref_count
1927      correctly incase the user decides to reset the residency flag
1928      later (even though the API makes no provision for that at the
1929      moment).  */
1930   if (cur->info.ref_count <= 0 && !LT_DLIS_RESIDENT (cur))
1931     {
1932       lt_user_data data = cur->vtable->dlloader_data;
1933
1934       if (cur != handles)
1935         {
1936           last->next = cur->next;
1937         }
1938       else
1939         {
1940           handles = cur->next;
1941         }
1942
1943       errors += cur->vtable->module_close (data, cur->module);
1944       errors += unload_deplibs (handle);
1945
1946       /* It is up to the callers to free the data itself.  */
1947       FREE (cur->interface_data);
1948
1949       FREE (cur->info.filename);
1950       FREE (cur->info.name);
1951       FREE (cur);
1952
1953       goto done;
1954     }
1955
1956   if (LT_DLIS_RESIDENT (handle))
1957     {
1958       LT__SETERROR (CLOSE_RESIDENT_MODULE);
1959       ++errors;
1960     }
1961
1962  done:
1963   return errors;
1964 }
1965
1966 void *
1967 lt_dlsym (lt_dlhandle place, const char *symbol)
1968 {
1969   size_t lensym;
1970   char  lsym[LT_SYMBOL_LENGTH];
1971   char  *sym;
1972   void *address;
1973   lt_user_data data;
1974   lt_dlhandle handle;
1975
1976   if (!place)
1977     {
1978       LT__SETERROR (INVALID_HANDLE);
1979       return 0;
1980     }
1981
1982   handle = place;
1983
1984   if (!symbol)
1985     {
1986       LT__SETERROR (SYMBOL_NOT_FOUND);
1987       return 0;
1988     }
1989
1990   lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->vtable->sym_prefix)
1991                                         + LT_STRLEN (handle->info.name);
1992
1993   if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
1994     {
1995       sym = lsym;
1996     }
1997   else
1998     {
1999       sym = MALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
2000       if (!sym)
2001         {
2002           LT__SETERROR (BUFFER_OVERFLOW);
2003           return 0;
2004         }
2005     }
2006
2007   data = handle->vtable->dlloader_data;
2008   if (handle->info.name)
2009     {
2010       const char *saved_error;
2011
2012       LT__GETERROR (saved_error);
2013
2014       /* this is a libtool module */
2015       if (handle->vtable->sym_prefix)
2016         {
2017           strcpy(sym, handle->vtable->sym_prefix);
2018           strcat(sym, handle->info.name);
2019         }
2020       else
2021         {
2022           strcpy(sym, handle->info.name);
2023         }
2024
2025       strcat(sym, "_LTX_");
2026       strcat(sym, symbol);
2027
2028       /* try "modulename_LTX_symbol" */
2029       address = handle->vtable->find_sym (data, handle->module, sym);
2030       if (address)
2031         {
2032           if (sym != lsym)
2033             {
2034               FREE (sym);
2035             }
2036           return address;
2037         }
2038       LT__SETERRORSTR (saved_error);
2039     }
2040
2041   /* otherwise try "symbol" */
2042   if (handle->vtable->sym_prefix)
2043     {
2044       strcpy(sym, handle->vtable->sym_prefix);
2045       strcat(sym, symbol);
2046     }
2047   else
2048     {
2049       strcpy(sym, symbol);
2050     }
2051
2052   address = handle->vtable->find_sym (data, handle->module, sym);
2053   if (sym != lsym)
2054     {
2055       FREE (sym);
2056     }
2057
2058   return address;
2059 }
2060
2061 const char *
2062 lt_dlerror (void)
2063 {
2064   const char *error;
2065
2066   LT__GETERROR (error);
2067   LT__SETERRORSTR (0);
2068
2069   return error;
2070 }
2071
2072 static int
2073 lt_dlpath_insertdir (char **ppath, char *before, const char *dir)
2074 {
2075   int    errors         = 0;
2076   char  *canonical      = 0;
2077   char  *argz           = 0;
2078   size_t argz_len       = 0;
2079
2080   assert (ppath);
2081   assert (dir && *dir);
2082
2083   if (canonicalize_path (dir, &canonical) != 0)
2084     {
2085       ++errors;
2086       goto cleanup;
2087     }
2088
2089   assert (canonical && *canonical);
2090
2091   /* If *PPATH is empty, set it to DIR.  */
2092   if (*ppath == 0)
2093     {
2094       assert (!before);         /* BEFORE cannot be set without PPATH.  */
2095       assert (dir);             /* Without DIR, don't call this function!  */
2096
2097       *ppath = lt__strdup (dir);
2098       if (*ppath == 0)
2099         ++errors;
2100
2101       goto cleanup;
2102     }
2103
2104   assert (ppath && *ppath);
2105
2106   if (argzize_path (*ppath, &argz, &argz_len) != 0)
2107     {
2108       ++errors;
2109       goto cleanup;
2110     }
2111
2112   /* Convert BEFORE into an equivalent offset into ARGZ.  This only works
2113      if *PPATH is already canonicalized, and hence does not change length
2114      with respect to ARGZ.  We canonicalize each entry as it is added to
2115      the search path, and don't call this function with (uncanonicalized)
2116      user paths, so this is a fair assumption.  */
2117   if (before)
2118     {
2119       assert (*ppath <= before);
2120       assert ((int) (before - *ppath) <= (int) strlen (*ppath));
2121
2122       before = before - *ppath + argz;
2123     }
2124
2125   if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
2126     {
2127       ++errors;
2128       goto cleanup;
2129     }
2130
2131   argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
2132   MEMREASSIGN(*ppath, argz);
2133
2134  cleanup:
2135   FREE (argz);
2136   FREE (canonical);
2137
2138   return errors;
2139 }
2140
2141 int
2142 lt_dladdsearchdir (const char *search_dir)
2143 {
2144   int errors = 0;
2145
2146   if (search_dir && *search_dir)
2147     {
2148       if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
2149         ++errors;
2150     }
2151
2152   return errors;
2153 }
2154
2155 int
2156 lt_dlinsertsearchdir (const char *before, const char *search_dir)
2157 {
2158   int errors = 0;
2159
2160   if (before)
2161     {
2162       if ((before < user_search_path)
2163           || (before >= user_search_path + LT_STRLEN (user_search_path)))
2164         {
2165           LT__SETERROR (INVALID_POSITION);
2166           return 1;
2167         }
2168     }
2169
2170   if (search_dir && *search_dir)
2171     {
2172       if (lt_dlpath_insertdir (&user_search_path,
2173                                (char *) before, search_dir) != 0)
2174         {
2175           ++errors;
2176         }
2177     }
2178
2179   return errors;
2180 }
2181
2182 int
2183 lt_dlsetsearchpath (const char *search_path)
2184 {
2185   int   errors      = 0;
2186
2187   FREE (user_search_path);
2188
2189   if (!search_path || !LT_STRLEN (search_path))
2190     {
2191       return errors;
2192     }
2193
2194   if (canonicalize_path (search_path, &user_search_path) != 0)
2195     ++errors;
2196
2197   return errors;
2198 }
2199
2200 const char *
2201 lt_dlgetsearchpath (void)
2202 {
2203   const char *saved_path;
2204
2205   saved_path = user_search_path;
2206
2207   return saved_path;
2208 }
2209
2210 int
2211 lt_dlmakeresident (lt_dlhandle handle)
2212 {
2213   int errors = 0;
2214
2215   if (!handle)
2216     {
2217       LT__SETERROR (INVALID_HANDLE);
2218       ++errors;
2219     }
2220   else
2221     {
2222       handle->info.is_resident = 1;
2223     }
2224
2225   return errors;
2226 }
2227
2228 int
2229 lt_dlisresident (lt_dlhandle handle)
2230 {
2231   if (!handle)
2232     {
2233       LT__SETERROR (INVALID_HANDLE);
2234       return -1;
2235     }
2236
2237   return LT_DLIS_RESIDENT (handle);
2238 }
2239
2240
2241
2242 /* --- MODULE INFORMATION --- */
2243
2244 typedef struct {
2245   const char *id_string;
2246   lt_dlhandle_interface *iface;
2247 } lt__interface_id;
2248
2249 lt_dlinterface_id
2250 lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface)
2251 {
2252   lt__interface_id *interface_id = (lt__interface_id *) lt__malloc (sizeof *interface_id);
2253
2254   /* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which
2255      can then be detected with lt_dlerror() if we return 0.  */
2256   if (interface_id)
2257     {
2258       interface_id->id_string = lt__strdup (id_string);
2259       if (!interface_id->id_string)
2260         FREE (interface_id);
2261       else
2262         interface_id->iface = iface;
2263     }
2264
2265   return (lt_dlinterface_id) interface_id;
2266 }
2267
2268 void lt_dlinterface_free (lt_dlinterface_id key)
2269 {
2270   lt__interface_id *interface_id = (lt__interface_id *)key;
2271   FREE (interface_id->id_string);
2272   FREE (interface_id);
2273 }
2274
2275 void *
2276 lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data)
2277 {
2278   int n_elements = 0;
2279   void *stale = (void *) 0;
2280   lt_dlhandle cur = handle;
2281   int i;
2282
2283   if (cur->interface_data)
2284     while (cur->interface_data[n_elements].key)
2285       ++n_elements;
2286
2287   for (i = 0; i < n_elements; ++i)
2288     {
2289       if (cur->interface_data[i].key == key)
2290         {
2291           stale = cur->interface_data[i].data;
2292           break;
2293         }
2294     }
2295
2296   /* Ensure that there is enough room in this handle's interface_data
2297      array to accept a new element (and an empty end marker).  */
2298   if (i == n_elements)
2299     {
2300       lt_interface_data *temp
2301         = REALLOC (lt_interface_data, cur->interface_data, 2+ n_elements);
2302
2303       if (!temp)
2304         {
2305           stale = 0;
2306           goto done;
2307         }
2308
2309       cur->interface_data = temp;
2310
2311       /* We only need this if we needed to allocate a new interface_data.  */
2312       cur->interface_data[i].key        = key;
2313       cur->interface_data[1+ i].key     = 0;
2314     }
2315
2316   cur->interface_data[i].data = data;
2317
2318  done:
2319   return stale;
2320 }
2321
2322 void *
2323 lt_dlcaller_get_data (lt_dlinterface_id key, lt_dlhandle handle)
2324 {
2325   void *result = (void *) 0;
2326   lt_dlhandle cur = handle;
2327
2328   /* Locate the index of the element with a matching KEY.  */
2329   if (cur->interface_data)
2330     {
2331       int i;
2332       for (i = 0; cur->interface_data[i].key; ++i)
2333         {
2334           if (cur->interface_data[i].key == key)
2335             {
2336               result = cur->interface_data[i].data;
2337               break;
2338             }
2339         }
2340     }
2341
2342   return result;
2343 }
2344
2345 const lt_dlinfo *
2346 lt_dlgetinfo (lt_dlhandle handle)
2347 {
2348   if (!handle)
2349     {
2350       LT__SETERROR (INVALID_HANDLE);
2351       return 0;
2352     }
2353
2354   return &(handle->info);
2355 }
2356
2357
2358 lt_dlhandle
2359 lt_dlhandle_iterate (lt_dlinterface_id iface, lt_dlhandle place)
2360 {
2361   lt_dlhandle handle = place;
2362   lt__interface_id *iterator = (lt__interface_id *) iface;
2363
2364   assert (iface); /* iface is a required argument */
2365
2366   if (!handle)
2367     handle = handles;
2368   else
2369     handle = handle->next;
2370
2371   /* advance while the interface check fails */
2372   while (handle && iterator->iface
2373          && ((*iterator->iface) (handle, iterator->id_string) != 0))
2374     {
2375       handle = handle->next;
2376     }
2377
2378   return handle;
2379 }
2380
2381
2382 lt_dlhandle
2383 lt_dlhandle_fetch (lt_dlinterface_id iface, const char *module_name)
2384 {
2385   lt_dlhandle handle = 0;
2386
2387   assert (iface); /* iface is a required argument */
2388
2389   while ((handle = lt_dlhandle_iterate (iface, handle)))
2390     {
2391       lt_dlhandle cur = handle;
2392       if (cur && cur->info.name && streq (cur->info.name, module_name))
2393         break;
2394     }
2395
2396   return handle;
2397 }
2398
2399
2400 int
2401 lt_dlhandle_map (lt_dlinterface_id iface,
2402                  int (*func) (lt_dlhandle handle, void *data), void *data)
2403 {
2404   lt__interface_id *iterator = (lt__interface_id *) iface;
2405   lt_dlhandle cur = handles;
2406
2407   assert (iface); /* iface is a required argument */
2408
2409   while (cur)
2410     {
2411       int errorcode = 0;
2412
2413       /* advance while the interface check fails */
2414       while (cur && iterator->iface
2415              && ((*iterator->iface) (cur, iterator->id_string) != 0))
2416         {
2417           cur = cur->next;
2418         }
2419
2420       if ((errorcode = (*func) (cur, data)) != 0)
2421         return errorcode;
2422     }
2423
2424   return 0;
2425 }