]> 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)
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 ssize_ter 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) + LT_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 messge store 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   char *        ext     = 0;
1511
1512   assert (filename);
1513
1514   ext = (char *) 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
1619   /* Can't have symbols hidden and visible at the same time!  */
1620   if (advise && advise->is_symlocal && advise->is_symglobal)
1621     {
1622       LT__SETERROR (CONFLICTING_FLAGS);
1623       return 0;
1624     }
1625
1626   if (!filename
1627       || !advise
1628       || !advise->try_ext
1629       || has_library_ext (filename))
1630     {
1631       /* Just incase we missed a code path in try_dlopen() that reports
1632          an error, but forgot to reset handle... */
1633       if (try_dlopen (&handle, filename, NULL, advise) != 0)
1634         return 0;
1635
1636       return handle;
1637     }
1638   else if (filename && *filename)
1639     {
1640
1641       /* First try appending ARCHIVE_EXT.  */
1642       errors += try_dlopen (&handle, filename, archive_ext, advise);
1643
1644       /* If we found FILENAME, stop searching -- whether we were able to
1645          load the file as a module or not.  If the file exists but loading
1646          failed, it is better to return an error message here than to
1647          report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
1648          in the module search path.  */
1649       if (handle || ((errors > 0) && !file_not_found ()))
1650         return handle;
1651
1652 #if defined(LT_MODULE_EXT)
1653       /* Try appending SHLIB_EXT.   */
1654       errors = try_dlopen (&handle, filename, shlib_ext, advise);
1655
1656       /* As before, if the file was found but loading failed, return now
1657          with the current error message.  */
1658       if (handle || ((errors > 0) && !file_not_found ()))
1659         return handle;
1660 #endif
1661     }
1662
1663   /* Still here?  Then we really did fail to locate any of the file
1664      names we tried.  */
1665   LT__SETERROR (FILE_NOT_FOUND);
1666   return 0;
1667 }
1668
1669
1670 static int
1671 lt_argz_insert (char **pargz, size_t *pargz_len, char *before,
1672                 const char *entry)
1673 {
1674   error_t error;
1675
1676   /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
1677      pargz_len, NULL, entry) failed with EINVAL.  */
1678   if (before)
1679     error = argz_insert (pargz, pargz_len, before, entry);
1680   else
1681     error = argz_append (pargz, pargz_len, entry, 1 + strlen (entry));
1682
1683   if (error)
1684     {
1685       switch (error)
1686         {
1687         case ENOMEM:
1688           LT__SETERROR (NO_MEMORY);
1689           break;
1690         default:
1691           LT__SETERROR (UNKNOWN);
1692           break;
1693         }
1694       return 1;
1695     }
1696
1697   return 0;
1698 }
1699
1700 static int
1701 lt_argz_insertinorder (char **pargz, size_t *pargz_len, const char *entry)
1702 {
1703   char *before = 0;
1704
1705   assert (pargz);
1706   assert (pargz_len);
1707   assert (entry && *entry);
1708
1709   if (*pargz)
1710     while ((before = argz_next (*pargz, *pargz_len, before)))
1711       {
1712         int cmp = strcmp (entry, before);
1713
1714         if (cmp < 0)  break;
1715         if (cmp == 0) return 0; /* No duplicates! */
1716       }
1717
1718   return lt_argz_insert (pargz, pargz_len, before, entry);
1719 }
1720
1721 static int
1722 lt_argz_insertdir (char **pargz, size_t *pargz_len, const char *dirnam,
1723                    struct dirent *dp)
1724 {
1725   char   *buf       = 0;
1726   size_t buf_len    = 0;
1727   char   *end       = 0;
1728   size_t end_offset = 0;
1729   size_t dir_len    = 0;
1730   int    errors     = 0;
1731
1732   assert (pargz);
1733   assert (pargz_len);
1734   assert (dp);
1735
1736   dir_len = LT_STRLEN (dirnam);
1737   end     = dp->d_name + D_NAMLEN(dp);
1738
1739   /* Ignore version numbers.  */
1740   {
1741     char *p;
1742     for (p = end; p -1 > dp->d_name; --p)
1743       if (strchr (".0123456789", p[-1]) == 0)
1744         break;
1745
1746     if (*p == '.')
1747       end = p;
1748   }
1749
1750   /* Ignore filename extension.  */
1751   {
1752     char *p;
1753     for (p = end -1; p > dp->d_name; --p)
1754       if (*p == '.')
1755         {
1756           end = p;
1757           break;
1758         }
1759   }
1760
1761   /* Prepend the directory name.  */
1762   end_offset    = end - dp->d_name;
1763   buf_len       = dir_len + 1+ end_offset;
1764   buf           = MALLOC (char, 1+ buf_len);
1765   if (!buf)
1766     return ++errors;
1767
1768   assert (buf);
1769
1770   strcpy  (buf, dirnam);
1771   strcat  (buf, "/");
1772   strncat (buf, dp->d_name, end_offset);
1773   buf[buf_len] = LT_EOS_CHAR;
1774
1775   /* Try to insert (in order) into ARGZ/ARGZ_LEN.  */
1776   if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
1777     ++errors;
1778
1779   FREE (buf);
1780
1781   return errors;
1782 }
1783
1784 static int
1785 list_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len)
1786 {
1787   DIR   *dirp     = 0;
1788   int    errors   = 0;
1789
1790   assert (dirnam && *dirnam);
1791   assert (pargz);
1792   assert (pargz_len);
1793   assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
1794
1795   dirp = opendir (dirnam);
1796   if (dirp)
1797     {
1798       struct dirent *dp = 0;
1799
1800       while ((dp = readdir (dirp)))
1801         if (dp->d_name[0] != '.')
1802           if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
1803             {
1804               ++errors;
1805               break;
1806             }
1807
1808       closedir (dirp);
1809     }
1810   else
1811     ++errors;
1812
1813   return errors;
1814 }
1815
1816
1817 /* If there are any files in DIRNAME, call the function passed in
1818    DATA1 (with the name of each file and DATA2 as arguments).  */
1819 static int
1820 foreachfile_callback (char *dirname, void *data1, void *data2)
1821 {
1822   file_worker_func *func = *(file_worker_func **) data1;
1823
1824   int     is_done  = 0;
1825   char   *argz     = 0;
1826   size_t  argz_len = 0;
1827
1828   if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
1829     goto cleanup;
1830   if (!argz)
1831     goto cleanup;
1832
1833   {
1834     char *filename = 0;
1835     while ((filename = argz_next (argz, argz_len, filename)))
1836       if ((is_done = (*func) (filename, data2)))
1837         break;
1838   }
1839
1840  cleanup:
1841   FREE (argz);
1842
1843   return is_done;
1844 }
1845
1846
1847 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
1848    with DATA.  The filenames passed to FUNC would be suitable for
1849    passing to lt_dlopenext.  The extensions are stripped so that
1850    individual modules do not generate several entries (e.g. libfoo.la,
1851    libfoo.so, libfoo.so.1, libfoo.so.1.0.0).  If SEARCH_PATH is NULL,
1852    then the same directories that lt_dlopen would search are examined.  */
1853 int
1854 lt_dlforeachfile (const char *search_path,
1855                   int (*func) (const char *filename, void *data),
1856                   void *data)
1857 {
1858   int is_done = 0;
1859   file_worker_func **fpptr = &func;
1860
1861   if (search_path)
1862     {
1863       /* If a specific path was passed, search only the directories
1864          listed in it.  */
1865       is_done = foreach_dirinpath (search_path, 0,
1866                                    foreachfile_callback, fpptr, data);
1867     }
1868   else
1869     {
1870       /* Otherwise search the default paths.  */
1871       is_done = foreach_dirinpath (user_search_path, 0,
1872                                    foreachfile_callback, fpptr, data);
1873       if (!is_done)
1874         {
1875           is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0,
1876                                        foreachfile_callback, fpptr, data);
1877         }
1878
1879 #if defined(LT_MODULE_PATH_VAR)
1880       if (!is_done)
1881         {
1882           is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0,
1883                                        foreachfile_callback, fpptr, data);
1884         }
1885 #endif
1886 #if defined(LT_DLSEARCH_PATH)
1887       if (!is_done && *sys_dlsearch_path)
1888         {
1889           is_done = foreach_dirinpath (sys_dlsearch_path, 0,
1890                                        foreachfile_callback, fpptr, data);
1891         }
1892 #endif
1893     }
1894
1895   return is_done;
1896 }
1897
1898 int
1899 lt_dlclose (lt_dlhandle handle)
1900 {
1901   lt_dlhandle cur, last;
1902   int errors = 0;
1903
1904   /* check whether the handle is valid */
1905   last = cur = handles;
1906   while (cur && handle != cur)
1907     {
1908       last = cur;
1909       cur = cur->next;
1910     }
1911
1912   if (!cur)
1913     {
1914       LT__SETERROR (INVALID_HANDLE);
1915       ++errors;
1916       goto done;
1917     }
1918
1919   cur = handle;
1920   cur->info.ref_count--;
1921
1922   /* Note that even with resident modules, we must track the ref_count
1923      correctly incase the user decides to reset the residency flag
1924      later (even though the API makes no provision for that at the
1925      moment).  */
1926   if (cur->info.ref_count <= 0 && !LT_DLIS_RESIDENT (cur))
1927     {
1928       lt_user_data data = cur->vtable->dlloader_data;
1929
1930       if (cur != handles)
1931         {
1932           last->next = cur->next;
1933         }
1934       else
1935         {
1936           handles = cur->next;
1937         }
1938
1939       errors += cur->vtable->module_close (data, cur->module);
1940       errors += unload_deplibs (handle);
1941
1942       /* It is up to the callers to free the data itself.  */
1943       FREE (cur->interface_data);
1944
1945       FREE (cur->info.filename);
1946       FREE (cur->info.name);
1947       FREE (cur);
1948
1949       goto done;
1950     }
1951
1952   if (LT_DLIS_RESIDENT (handle))
1953     {
1954       LT__SETERROR (CLOSE_RESIDENT_MODULE);
1955       ++errors;
1956     }
1957
1958  done:
1959   return errors;
1960 }
1961
1962 void *
1963 lt_dlsym (lt_dlhandle place, const char *symbol)
1964 {
1965   size_t lensym;
1966   char  lsym[LT_SYMBOL_LENGTH];
1967   char  *sym;
1968   void *address;
1969   lt_user_data data;
1970   lt_dlhandle handle;
1971
1972   if (!place)
1973     {
1974       LT__SETERROR (INVALID_HANDLE);
1975       return 0;
1976     }
1977
1978   handle = place;
1979
1980   if (!symbol)
1981     {
1982       LT__SETERROR (SYMBOL_NOT_FOUND);
1983       return 0;
1984     }
1985
1986   lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->vtable->sym_prefix)
1987                                         + LT_STRLEN (handle->info.name);
1988
1989   if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
1990     {
1991       sym = lsym;
1992     }
1993   else
1994     {
1995       sym = MALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
1996       if (!sym)
1997         {
1998           LT__SETERROR (BUFFER_OVERFLOW);
1999           return 0;
2000         }
2001     }
2002
2003   data = handle->vtable->dlloader_data;
2004   if (handle->info.name)
2005     {
2006       const char *saved_error;
2007
2008       LT__GETERROR (saved_error);
2009
2010       /* this is a libtool module */
2011       if (handle->vtable->sym_prefix)
2012         {
2013           strcpy(sym, handle->vtable->sym_prefix);
2014           strcat(sym, handle->info.name);
2015         }
2016       else
2017         {
2018           strcpy(sym, handle->info.name);
2019         }
2020
2021       strcat(sym, "_LTX_");
2022       strcat(sym, symbol);
2023
2024       /* try "modulename_LTX_symbol" */
2025       address = handle->vtable->find_sym (data, handle->module, sym);
2026       if (address)
2027         {
2028           if (sym != lsym)
2029             {
2030               FREE (sym);
2031             }
2032           return address;
2033         }
2034       LT__SETERRORSTR (saved_error);
2035     }
2036
2037   /* otherwise try "symbol" */
2038   if (handle->vtable->sym_prefix)
2039     {
2040       strcpy(sym, handle->vtable->sym_prefix);
2041       strcat(sym, symbol);
2042     }
2043   else
2044     {
2045       strcpy(sym, symbol);
2046     }
2047
2048   address = handle->vtable->find_sym (data, handle->module, sym);
2049   if (sym != lsym)
2050     {
2051       FREE (sym);
2052     }
2053
2054   return address;
2055 }
2056
2057 const char *
2058 lt_dlerror (void)
2059 {
2060   const char *error;
2061
2062   LT__GETERROR (error);
2063   LT__SETERRORSTR (0);
2064
2065   return error ? error : NULL;
2066 }
2067
2068 static int
2069 lt_dlpath_insertdir (char **ppath, char *before, const char *dir)
2070 {
2071   int    errors         = 0;
2072   char  *canonical      = 0;
2073   char  *argz           = 0;
2074   size_t argz_len       = 0;
2075
2076   assert (ppath);
2077   assert (dir && *dir);
2078
2079   if (canonicalize_path (dir, &canonical) != 0)
2080     {
2081       ++errors;
2082       goto cleanup;
2083     }
2084
2085   assert (canonical && *canonical);
2086
2087   /* If *PPATH is empty, set it to DIR.  */
2088   if (*ppath == 0)
2089     {
2090       assert (!before);         /* BEFORE cannot be set without PPATH.  */
2091       assert (dir);             /* Without DIR, don't call this function!  */
2092
2093       *ppath = lt__strdup (dir);
2094       if (*ppath == 0)
2095         ++errors;
2096
2097       goto cleanup;
2098     }
2099
2100   assert (ppath && *ppath);
2101
2102   if (argzize_path (*ppath, &argz, &argz_len) != 0)
2103     {
2104       ++errors;
2105       goto cleanup;
2106     }
2107
2108   /* Convert BEFORE into an equivalent offset into ARGZ.  This only works
2109      if *PPATH is already canonicalized, and hence does not change length
2110      with respect to ARGZ.  We canonicalize each entry as it is added to
2111      the search path, and don't call this function with (uncanonicalized)
2112      user paths, so this is a fair assumption.  */
2113   if (before)
2114     {
2115       assert (*ppath <= before);
2116       assert ((int) (before - *ppath) <= (int) strlen (*ppath));
2117
2118       before = before - *ppath + argz;
2119     }
2120
2121   if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
2122     {
2123       ++errors;
2124       goto cleanup;
2125     }
2126
2127   argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
2128   MEMREASSIGN(*ppath, argz);
2129
2130  cleanup:
2131   FREE (argz);
2132   FREE (canonical);
2133
2134   return errors;
2135 }
2136
2137 int
2138 lt_dladdsearchdir (const char *search_dir)
2139 {
2140   int errors = 0;
2141
2142   if (search_dir && *search_dir)
2143     {
2144       if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
2145         ++errors;
2146     }
2147
2148   return errors;
2149 }
2150
2151 int
2152 lt_dlinsertsearchdir (const char *before, const char *search_dir)
2153 {
2154   int errors = 0;
2155
2156   if (before)
2157     {
2158       if ((before < user_search_path)
2159           || (before >= user_search_path + LT_STRLEN (user_search_path)))
2160         {
2161           LT__SETERROR (INVALID_POSITION);
2162           return 1;
2163         }
2164     }
2165
2166   if (search_dir && *search_dir)
2167     {
2168       if (lt_dlpath_insertdir (&user_search_path,
2169                                (char *) before, search_dir) != 0)
2170         {
2171           ++errors;
2172         }
2173     }
2174
2175   return errors;
2176 }
2177
2178 int
2179 lt_dlsetsearchpath (const char *search_path)
2180 {
2181   int   errors      = 0;
2182
2183   FREE (user_search_path);
2184
2185   if (!search_path || !LT_STRLEN (search_path))
2186     {
2187       return errors;
2188     }
2189
2190   if (canonicalize_path (search_path, &user_search_path) != 0)
2191     ++errors;
2192
2193   return errors;
2194 }
2195
2196 const char *
2197 lt_dlgetsearchpath (void)
2198 {
2199   const char *saved_path;
2200
2201   saved_path = user_search_path;
2202
2203   return saved_path;
2204 }
2205
2206 int
2207 lt_dlmakeresident (lt_dlhandle handle)
2208 {
2209   int errors = 0;
2210
2211   if (!handle)
2212     {
2213       LT__SETERROR (INVALID_HANDLE);
2214       ++errors;
2215     }
2216   else
2217     {
2218       handle->info.is_resident = 1;
2219     }
2220
2221   return errors;
2222 }
2223
2224 int
2225 lt_dlisresident (lt_dlhandle handle)
2226 {
2227   if (!handle)
2228     {
2229       LT__SETERROR (INVALID_HANDLE);
2230       return -1;
2231     }
2232
2233   return LT_DLIS_RESIDENT (handle);
2234 }
2235
2236
2237
2238 /* --- MODULE INFORMATION --- */
2239
2240 typedef struct {
2241   const char *id_string;
2242   lt_dlhandle_interface *iface;
2243 } lt__interface_id;
2244
2245 lt_dlinterface_id
2246 lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface)
2247 {
2248   lt__interface_id *interface_id = (lt__interface_id *) lt__malloc (sizeof *interface_id);
2249
2250   /* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which
2251      can then be detected with lt_dlerror() if we return 0.  */
2252   if (interface_id)
2253     {
2254       interface_id->id_string = lt__strdup (id_string);
2255       if (!interface_id->id_string)
2256         FREE (interface_id);
2257       else
2258         interface_id->iface = iface;
2259     }
2260
2261   return (lt_dlinterface_id) interface_id;
2262 }
2263
2264 void lt_dlinterface_free (lt_dlinterface_id key)
2265 {
2266   lt__interface_id *interface_id = (lt__interface_id *)key;
2267   FREE (interface_id->id_string);
2268   FREE (interface_id);
2269 }
2270
2271 void *
2272 lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data)
2273 {
2274   int n_elements = 0;
2275   void *stale = (void *) 0;
2276   lt_dlhandle cur = handle;
2277   int i;
2278
2279   if (cur->interface_data)
2280     while (cur->interface_data[n_elements].key)
2281       ++n_elements;
2282
2283   for (i = 0; i < n_elements; ++i)
2284     {
2285       if (cur->interface_data[i].key == key)
2286         {
2287           stale = cur->interface_data[i].data;
2288           break;
2289         }
2290     }
2291
2292   /* Ensure that there is enough room in this handle's interface_data
2293      array to accept a new element (and an empty end marker).  */
2294   if (i == n_elements)
2295     {
2296       lt_interface_data *temp
2297         = REALLOC (lt_interface_data, cur->interface_data, 2+ n_elements);
2298
2299       if (!temp)
2300         {
2301           stale = 0;
2302           goto done;
2303         }
2304
2305       cur->interface_data = temp;
2306
2307       /* We only need this if we needed to allocate a new interface_data.  */
2308       cur->interface_data[i].key        = key;
2309       cur->interface_data[1+ i].key     = 0;
2310     }
2311
2312   cur->interface_data[i].data = data;
2313
2314  done:
2315   return stale;
2316 }
2317
2318 void *
2319 lt_dlcaller_get_data (lt_dlinterface_id key, lt_dlhandle handle)
2320 {
2321   void *result = (void *) 0;
2322   lt_dlhandle cur = handle;
2323
2324   /* Locate the index of the element with a matching KEY.  */
2325   if (cur->interface_data)
2326     {
2327       int i;
2328       for (i = 0; cur->interface_data[i].key; ++i)
2329         {
2330           if (cur->interface_data[i].key == key)
2331             {
2332               result = cur->interface_data[i].data;
2333               break;
2334             }
2335         }
2336     }
2337
2338   return result;
2339 }
2340
2341 const lt_dlinfo *
2342 lt_dlgetinfo (lt_dlhandle handle)
2343 {
2344   if (!handle)
2345     {
2346       LT__SETERROR (INVALID_HANDLE);
2347       return 0;
2348     }
2349
2350   return &(handle->info);
2351 }
2352
2353
2354 lt_dlhandle
2355 lt_dlhandle_iterate (lt_dlinterface_id iface, lt_dlhandle place)
2356 {
2357   lt_dlhandle handle = place;
2358   lt__interface_id *iterator = (lt__interface_id *) iface;
2359
2360   assert (iface); /* iface is a required argument */
2361
2362   if (!handle)
2363     handle = handles;
2364   else
2365     handle = handle->next;
2366
2367   /* advance while the interface check fails */
2368   while (handle && iterator->iface
2369          && ((*iterator->iface) (handle, iterator->id_string) != 0))
2370     {
2371       handle = handle->next;
2372     }
2373
2374   return handle;
2375 }
2376
2377
2378 lt_dlhandle
2379 lt_dlhandle_fetch (lt_dlinterface_id iface, const char *module_name)
2380 {
2381   lt_dlhandle handle = 0;
2382
2383   assert (iface); /* iface is a required argument */
2384
2385   while ((handle = lt_dlhandle_iterate (iface, handle)))
2386     {
2387       lt_dlhandle cur = handle;
2388       if (cur && cur->info.name && streq (cur->info.name, module_name))
2389         break;
2390     }
2391
2392   return handle;
2393 }
2394
2395
2396 int
2397 lt_dlhandle_map (lt_dlinterface_id iface,
2398                  int (*func) (lt_dlhandle handle, void *data), void *data)
2399 {
2400   lt__interface_id *iterator = (lt__interface_id *) iface;
2401   lt_dlhandle cur = handles;
2402
2403   assert (iface); /* iface is a required argument */
2404
2405   while (cur)
2406     {
2407       int errorcode = 0;
2408
2409       /* advance while the interface check fails */
2410       while (cur && iterator->iface
2411              && ((*iterator->iface) (cur, iterator->id_string) != 0))
2412         {
2413           cur = cur->next;
2414         }
2415
2416       if ((errorcode = (*func) (cur, data)) != 0)
2417         return errorcode;
2418     }
2419
2420   return 0;
2421 }