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