source: squid-ssl/trunk/fuentes/libltdl/ltdl.c @ 5495

Last change on this file since 5495 was 5495, checked in by Juanma, 2 years ago

Initial release

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