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}
2472