2005-01-28 Martin Schwidefsky <schwidefsky@de.ibm.com>
[glibc.git] / elf / ldconfig.c
blob2502f854a622a9566f075e38e2835725111d2b96
1 /* Copyright (C) 1999-2004, 2005 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Andreas Jaeger <aj@suse.de>, 1999.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #define PROCINFO_CLASS static
21 #include <alloca.h>
22 #include <argp.h>
23 #include <dirent.h>
24 #include <elf.h>
25 #include <error.h>
26 #include <errno.h>
27 #include <inttypes.h>
28 #include <libintl.h>
29 #include <stdbool.h>
30 #include <stdio.h>
31 #include <stdio_ext.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35 #include <sys/fcntl.h>
36 #include <sys/mman.h>
37 #include <sys/stat.h>
38 #include <sys/types.h>
39 #include <glob.h>
40 #include <libgen.h>
42 #include "ldconfig.h"
43 #include "dl-cache.h"
45 #include "dl-procinfo.h"
47 #ifndef LD_SO_CONF
48 # define LD_SO_CONF SYSCONFDIR "/ld.so.conf"
49 #endif
51 /* Get libc version number. */
52 #include <version.h>
54 #define PACKAGE _libc_intl_domainname
56 static const struct
58 const char *name;
59 int flag;
60 } lib_types[] =
62 {"libc4", FLAG_LIBC4},
63 {"libc5", FLAG_ELF_LIBC5},
64 {"libc6", FLAG_ELF_LIBC6},
65 {"glibc2", FLAG_ELF_LIBC6}
69 /* List of directories to handle. */
70 struct dir_entry
72 char *path;
73 int flag;
74 ino64_t ino;
75 dev_t dev;
76 struct dir_entry *next;
79 /* The list is unsorted, contains no duplicates. Entries are added at
80 the end. */
81 static struct dir_entry *dir_entries;
83 /* Flags for different options. */
84 /* Print Cache. */
85 static int opt_print_cache;
87 /* Be verbose. */
88 int opt_verbose;
90 /* Format to support. */
91 /* 0: only libc5/glibc2; 1: both; 2: only glibc 2.2. */
92 int opt_format = 1;
94 /* Build cache. */
95 static int opt_build_cache = 1;
97 /* Generate links. */
98 static int opt_link = 1;
100 /* Only process directories specified on the command line. */
101 static int opt_only_cline;
103 /* Path to root for chroot. */
104 static char *opt_chroot;
106 /* Manually link given shared libraries. */
107 static int opt_manual_link;
109 /* Cache file to use. */
110 static char *cache_file;
112 /* Configuration file. */
113 static const char *config_file;
115 /* Mask to use for important hardware capabilities. */
116 static unsigned long int hwcap_mask = HWCAP_IMPORTANT;
118 /* Name and version of program. */
119 static void print_version (FILE *stream, struct argp_state *state);
120 void (*argp_program_version_hook) (FILE *, struct argp_state *)
121 = print_version;
123 /* Definitions of arguments for argp functions. */
124 static const struct argp_option options[] =
126 { "print-cache", 'p', NULL, 0, N_("Print cache"), 0},
127 { "verbose", 'v', NULL, 0, N_("Generate verbose messages"), 0},
128 { NULL, 'N', NULL, 0, N_("Don't build cache"), 0},
129 { NULL, 'X', NULL, 0, N_("Don't generate links"), 0},
130 { NULL, 'r', N_("ROOT"), 0, N_("Change to and use ROOT as root directory"), 0},
131 { NULL, 'C', N_("CACHE"), 0, N_("Use CACHE as cache file"), 0},
132 { NULL, 'f', N_("CONF"), 0, N_("Use CONF as configuration file"), 0},
133 { NULL, 'n', NULL, 0, N_("Only process directories specified on the command line. Don't build cache."), 0},
134 { NULL, 'l', NULL, 0, N_("Manually link individual libraries."), 0},
135 { "format", 'c', N_("FORMAT"), 0, N_("Format to use: new, old or compat (default)"), 0},
136 { NULL, 0, NULL, 0, NULL, 0 }
139 #define PROCINFO_CLASS static
140 #include <dl-procinfo.c>
142 /* Short description of program. */
143 static const char doc[] = N_("Configure Dynamic Linker Run Time Bindings.");
145 /* Prototype for option handler. */
146 static error_t parse_opt (int key, char *arg, struct argp_state *state);
148 /* Data structure to communicate with argp functions. */
149 static struct argp argp =
151 options, parse_opt, NULL, doc, NULL, NULL, NULL
154 /* Check if string corresponds to an important hardware capability or
155 a platform. */
156 static int
157 is_hwcap_platform (const char *name)
159 int hwcap_idx = _dl_string_hwcap (name);
161 if (hwcap_idx != -1 && ((1 << hwcap_idx) & hwcap_mask))
162 return 1;
164 hwcap_idx = _dl_string_platform (name);
165 if (hwcap_idx != -1)
166 return 1;
168 #ifdef USE_TLS
169 if (strcmp (name, "tls") == 0)
170 return 1;
171 #endif
173 return 0;
176 /* Get hwcap (including platform) encoding of path. */
177 static uint64_t
178 path_hwcap (const char *path)
180 char *str = xstrdup (path);
181 char *ptr;
182 uint64_t hwcap = 0;
183 uint64_t h;
185 size_t len;
187 len = strlen (str);
188 if (str[len] == '/')
189 str[len] = '\0';
191 /* Search pathname from the end and check for hwcap strings. */
192 for (;;)
194 ptr = strrchr (str, '/');
196 if (ptr == NULL)
197 break;
199 h = _dl_string_hwcap (ptr + 1);
201 if (h == (uint64_t) -1)
203 h = _dl_string_platform (ptr + 1);
204 if (h == (uint64_t) -1)
206 #ifdef USE_TLS
207 if (strcmp (ptr + 1, "tls") == 0)
208 h = 63;
209 else
210 #endif
211 break;
214 hwcap += 1ULL << h;
216 /* Search the next part of the path. */
217 *ptr = '\0';
220 free (str);
221 return hwcap;
224 /* Handle program arguments. */
225 static error_t
226 parse_opt (int key, char *arg, struct argp_state *state)
228 switch (key)
230 case 'C':
231 cache_file = arg;
232 break;
233 case 'f':
234 config_file = arg;
235 break;
236 case 'l':
237 opt_manual_link = 1;
238 break;
239 case 'N':
240 opt_build_cache = 0;
241 break;
242 case 'n':
243 opt_build_cache = 0;
244 opt_only_cline = 1;
245 break;
246 case 'p':
247 opt_print_cache = 1;
248 break;
249 case 'r':
250 opt_chroot = arg;
251 break;
252 case 'v':
253 opt_verbose = 1;
254 break;
255 case 'X':
256 opt_link = 0;
257 break;
258 case 'c':
259 if (strcmp (arg, "old") == 0)
260 opt_format = 0;
261 else if (strcmp (arg, "compat") == 0)
262 opt_format = 1;
263 else if (strcmp (arg, "new") == 0)
264 opt_format = 2;
265 break;
266 default:
267 return ARGP_ERR_UNKNOWN;
270 return 0;
273 /* Print the version information. */
274 static void
275 print_version (FILE *stream, struct argp_state *state)
277 fprintf (stream, "ldconfig (GNU %s) %s\n", PACKAGE, VERSION);
278 fprintf (stream, gettext ("\
279 Copyright (C) %s Free Software Foundation, Inc.\n\
280 This is free software; see the source for copying conditions. There is NO\n\
281 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
282 "), "2005");
283 fprintf (stream, gettext ("Written by %s.\n"),
284 "Andreas Jaeger");
287 /* Add a single directory entry. */
288 static void
289 add_single_dir (struct dir_entry *entry, int verbose)
291 struct dir_entry *ptr, *prev;
293 ptr = dir_entries;
294 prev = ptr;
295 while (ptr != NULL)
297 /* Check for duplicates. */
298 if (ptr->ino == entry->ino && ptr->dev == entry->dev)
300 if (opt_verbose && verbose)
301 error (0, 0, _("Path `%s' given more than once"), entry->path);
302 /* Use the newer information. */
303 ptr->flag = entry->flag;
304 free (entry->path);
305 free (entry);
306 break;
308 prev = ptr;
309 ptr = ptr->next;
311 /* Is this the first entry? */
312 if (ptr == NULL && dir_entries == NULL)
313 dir_entries = entry;
314 else if (ptr == NULL)
315 prev->next = entry;
318 /* Add one directory to the list of directories to process. */
319 static void
320 add_dir (const char *line)
322 unsigned int i;
323 struct dir_entry *entry = xmalloc (sizeof (struct dir_entry));
324 entry->next = NULL;
326 /* Search for an '=' sign. */
327 entry->path = xstrdup (line);
328 char *equal_sign = strchr (entry->path, '=');
329 if (equal_sign)
331 *equal_sign = '\0';
332 ++equal_sign;
333 entry->flag = FLAG_ANY;
334 for (i = 0; i < sizeof (lib_types) / sizeof (lib_types[0]); ++i)
335 if (strcmp (equal_sign, lib_types[i].name) == 0)
337 entry->flag = lib_types[i].flag;
338 break;
340 if (entry->flag == FLAG_ANY)
341 error (0, 0, _("%s is not a known library type"), equal_sign);
343 else
345 entry->flag = FLAG_ANY;
348 /* Canonify path: for now only remove leading and trailing
349 whitespace and the trailing slashes slashes. */
350 i = strlen (entry->path) - 1;
352 while (isspace (entry->path[i]) && i > 0)
353 entry->path[i--] = '\0';
355 while (entry->path[i] == '/' && i > 0)
356 entry->path[i--] = '\0';
358 char *path = entry->path;
359 if (opt_chroot)
360 path = chroot_canon (opt_chroot, path);
362 struct stat64 stat_buf;
363 if (path == NULL || stat64 (path, &stat_buf))
365 if (opt_verbose)
366 error (0, errno, _("Can't stat %s"), entry->path);
367 free (entry->path);
368 free (entry);
370 else
372 entry->ino = stat_buf.st_ino;
373 entry->dev = stat_buf.st_dev;
375 add_single_dir (entry, 1);
378 if (opt_chroot)
379 free (path);
383 static int
384 chroot_stat (const char *real_path, const char *path, struct stat64 *st)
386 int ret;
387 char *canon_path;
389 if (!opt_chroot)
390 return stat64 (real_path, st);
392 ret = lstat64 (real_path, st);
393 if (ret || !S_ISLNK (st->st_mode))
394 return ret;
396 canon_path = chroot_canon (opt_chroot, path);
397 if (canon_path == NULL)
398 return -1;
400 ret = stat64 (canon_path, st);
401 free (canon_path);
402 return ret;
405 /* Create a symbolic link from soname to libname in directory path. */
406 static void
407 create_links (const char *real_path, const char *path, const char *libname,
408 const char *soname)
410 char *full_libname, *full_soname;
411 char *real_full_libname, *real_full_soname;
412 struct stat64 stat_lib, stat_so, lstat_so;
413 int do_link = 1;
414 int do_remove = 1;
415 /* XXX: The logics in this function should be simplified. */
417 /* Get complete path. */
418 full_libname = alloca (strlen (path) + strlen (libname) + 2);
419 full_soname = alloca (strlen (path) + strlen (soname) + 2);
420 sprintf (full_libname, "%s/%s", path, libname);
421 sprintf (full_soname, "%s/%s", path, soname);
422 if (opt_chroot)
424 real_full_libname = alloca (strlen (real_path) + strlen (libname) + 2);
425 real_full_soname = alloca (strlen (real_path) + strlen (soname) + 2);
426 sprintf (real_full_libname, "%s/%s", real_path, libname);
427 sprintf (real_full_soname, "%s/%s", real_path, soname);
429 else
431 real_full_libname = full_libname;
432 real_full_soname = full_soname;
435 /* Does soname already exist and point to the right library? */
436 if (chroot_stat (real_full_soname, full_soname, &stat_so) == 0)
438 if (chroot_stat (real_full_libname, full_libname, &stat_lib))
440 error (0, 0, _("Can't stat %s\n"), full_libname);
441 return;
443 if (stat_lib.st_dev == stat_so.st_dev
444 && stat_lib.st_ino == stat_so.st_ino)
445 /* Link is already correct. */
446 do_link = 0;
447 else if (lstat64 (full_soname, &lstat_so) == 0
448 && !S_ISLNK (lstat_so.st_mode))
450 error (0, 0, _("%s is not a symbolic link\n"), full_soname);
451 do_link = 0;
452 do_remove = 0;
455 else if (lstat64 (real_full_soname, &lstat_so) != 0
456 || !S_ISLNK (lstat_so.st_mode))
457 /* Unless it is a stale symlink, there is no need to remove. */
458 do_remove = 0;
460 if (opt_verbose)
461 printf ("\t%s -> %s", soname, libname);
463 if (do_link && opt_link)
465 /* Remove old link. */
466 if (do_remove)
467 if (unlink (real_full_soname))
469 error (0, 0, _("Can't unlink %s"), full_soname);
470 do_link = 0;
472 /* Create symbolic link. */
473 if (do_link && symlink (libname, real_full_soname))
475 error (0, 0, _("Can't link %s to %s"), full_soname, libname);
476 do_link = 0;
478 if (opt_verbose)
480 if (do_link)
481 fputs (_(" (changed)\n"), stdout);
482 else
483 fputs (_(" (SKIPPED)\n"), stdout);
486 else if (opt_verbose)
487 fputs ("\n", stdout);
490 /* Manually link the given library. */
491 static void
492 manual_link (char *library)
494 char *path;
495 char *real_path;
496 char *real_library;
497 char *libname;
498 char *soname;
499 struct stat64 stat_buf;
500 int flag;
501 unsigned int osversion;
503 /* Prepare arguments for create_links call. Split library name in
504 directory and filename first. Since path is allocated, we've got
505 to be careful to free at the end. */
506 path = xstrdup (library);
507 libname = strrchr (path, '/');
509 if (libname)
511 /* Successfully split names. Check if path is just "/" to avoid
512 an empty path. */
513 if (libname == path)
515 libname = library + 1;
516 path = xrealloc (path, 2);
517 strcpy (path, "/");
519 else
521 *libname = '\0';
522 ++libname;
525 else
527 /* There's no path, construct one. */
528 libname = library;
529 path = xrealloc (path, 2);
530 strcpy (path, ".");
533 if (opt_chroot)
535 real_path = chroot_canon (opt_chroot, path);
536 if (real_path == NULL)
538 error (0, errno, _("Can't find %s"), path);
539 free (path);
540 return;
542 real_library = alloca (strlen (real_path) + strlen (libname) + 2);
543 sprintf (real_library, "%s/%s", real_path, libname);
545 else
547 real_path = path;
548 real_library = library;
551 /* Do some sanity checks first. */
552 if (lstat64 (real_library, &stat_buf))
554 error (0, errno, _("Can't lstat %s"), library);
555 free (path);
556 return;
558 /* We don't want links here! */
559 else if (!S_ISREG (stat_buf.st_mode))
561 error (0, 0, _("Ignored file %s since it is not a regular file."),
562 library);
563 free (path);
564 return;
566 if (process_file (real_library, library, libname, &flag, &osversion,
567 &soname, 0))
569 error (0, 0, _("No link created since soname could not be found for %s"),
570 library);
571 free (path);
572 return;
574 create_links (real_path, path, libname, soname);
575 free (soname);
576 free (path);
580 /* Read a whole directory and search for libraries.
581 The purpose is two-fold:
582 - search for libraries which will be added to the cache
583 - create symbolic links to the soname for each library
585 This has to be done separatly for each directory.
587 To keep track of which libraries to add to the cache and which
588 links to create, we save a list of all libraries.
590 The algorithm is basically:
591 for all libraries in the directory do
592 get soname of library
593 if soname is already in list
594 if new library is newer, replace entry
595 otherwise ignore this library
596 otherwise add library to list
598 For example, if the two libraries libxy.so.1.1 and libxy.so.1.2
599 exist and both have the same soname, e.g. libxy.so, a symbolic link
600 is created from libxy.so.1.2 (the newer one) to libxy.so.
601 libxy.so.1.2 and libxy.so are added to the cache - but not
602 libxy.so.1.1. */
604 /* Information for one library. */
605 struct dlib_entry
607 char *name;
608 char *soname;
609 int flag;
610 int is_link;
611 unsigned int osversion;
612 struct dlib_entry *next;
616 static void
617 search_dir (const struct dir_entry *entry)
619 DIR *dir;
620 struct dirent64 *direntry;
621 char *file_name, *dir_name, *real_file_name, *real_name;
622 int file_name_len, real_file_name_len, len;
623 char *soname;
624 struct dlib_entry *dlibs;
625 struct dlib_entry *dlib_ptr;
626 struct stat64 lstat_buf, stat_buf;
627 int is_link, is_dir;
628 uint64_t hwcap = path_hwcap (entry->path);
629 unsigned int osversion;
631 file_name_len = PATH_MAX;
632 file_name = alloca (file_name_len);
634 dlibs = NULL;
636 if (opt_verbose)
638 if (hwcap != 0)
639 printf ("%s: (hwcap: 0x%" PRIx64 ")\n", entry->path, hwcap);
640 else
641 printf ("%s:\n", entry->path);
644 if (opt_chroot)
646 dir_name = chroot_canon (opt_chroot, entry->path);
647 real_file_name_len = PATH_MAX;
648 real_file_name = alloca (real_file_name_len);
650 else
652 dir_name = entry->path;
653 real_file_name_len = 0;
654 real_file_name = file_name;
657 if (dir_name == NULL || (dir = opendir (dir_name)) == NULL)
659 if (opt_verbose)
660 error (0, errno, _("Can't open directory %s"), entry->path);
661 if (opt_chroot && dir_name)
662 free (dir_name);
663 return;
666 while ((direntry = readdir64 (dir)) != NULL)
668 int flag;
669 #ifdef _DIRENT_HAVE_D_TYPE
670 /* We only look at links and regular files. */
671 if (direntry->d_type != DT_UNKNOWN
672 && direntry->d_type != DT_LNK
673 && direntry->d_type != DT_REG
674 && direntry->d_type != DT_DIR)
675 continue;
676 #endif /* _DIRENT_HAVE_D_TYPE */
677 /* Does this file look like a shared library or is it a hwcap
678 subdirectory? The dynamic linker is also considered as
679 shared library. */
680 if (((strncmp (direntry->d_name, "lib", 3) != 0
681 && strncmp (direntry->d_name, "ld-", 3) != 0)
682 || strstr (direntry->d_name, ".so") == NULL)
683 && (
684 #ifdef _DIRENT_HAVE_D_TYPE
685 direntry->d_type == DT_REG ||
686 #endif
687 !is_hwcap_platform (direntry->d_name)))
688 continue;
689 len = strlen (entry->path) + strlen (direntry->d_name);
690 if (len > file_name_len)
692 file_name_len = len + 1;
693 file_name = alloca (file_name_len);
694 if (!opt_chroot)
695 real_file_name = file_name;
697 sprintf (file_name, "%s/%s", entry->path, direntry->d_name);
698 if (opt_chroot)
700 len = strlen (dir_name) + strlen (direntry->d_name);
701 if (len > real_file_name_len)
703 real_file_name_len = len + 1;
704 real_file_name = alloca (real_file_name_len);
706 sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name);
708 #ifdef _DIRENT_HAVE_D_TYPE
709 if (direntry->d_type != DT_UNKNOWN)
710 lstat_buf.st_mode = DTTOIF (direntry->d_type);
711 else
712 #endif
713 if (__builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
715 error (0, errno, _("Cannot lstat %s"), file_name);
716 continue;
719 is_link = S_ISLNK (lstat_buf.st_mode);
720 if (is_link)
722 /* In case of symlink, we check if the symlink refers to
723 a directory. */
724 if (__builtin_expect (stat64 (real_file_name, &stat_buf), 0))
726 if (opt_verbose)
727 error (0, errno, _("Cannot stat %s"), file_name);
729 /* Remove stale symlinks. */
730 if (strstr (direntry->d_name, ".so."))
731 unlink (real_file_name);
732 continue;
734 is_dir = S_ISDIR (stat_buf.st_mode);
736 else
737 is_dir = S_ISDIR (lstat_buf.st_mode);
739 if (is_dir && is_hwcap_platform (direntry->d_name))
741 /* Handle subdirectory later. */
742 struct dir_entry *new_entry;
744 new_entry = xmalloc (sizeof (struct dir_entry));
745 new_entry->path = xstrdup (file_name);
746 new_entry->flag = entry->flag;
747 new_entry->next = NULL;
748 if (is_link)
750 new_entry->ino = stat_buf.st_ino;
751 new_entry->dev = stat_buf.st_dev;
753 else
755 #ifdef _DIRENT_HAVE_D_TYPE
756 /* We have filled in lstat only #ifndef
757 _DIRENT_HAVE_D_TYPE. Fill it in if needed. */
758 if (direntry->d_type != DT_UNKNOWN
759 && __builtin_expect (lstat64 (real_file_name, &lstat_buf),
762 error (0, errno, _("Cannot lstat %s"), file_name);
763 free (new_entry->path);
764 free (new_entry);
765 continue;
767 #endif
769 new_entry->ino = lstat_buf.st_ino;
770 new_entry->dev = lstat_buf.st_dev;
772 add_single_dir (new_entry, 0);
773 continue;
775 else if (!S_ISREG (lstat_buf.st_mode) && !is_link)
776 continue;
778 if (opt_chroot && is_link)
780 real_name = chroot_canon (opt_chroot, file_name);
781 if (real_name == NULL)
783 if (strstr (file_name, ".so") == NULL)
784 error (0, 0, _("Input file %s not found.\n"), file_name);
785 continue;
788 else
789 real_name = real_file_name;
791 if (process_file (real_name, file_name, direntry->d_name, &flag,
792 &osversion, &soname, is_link))
794 if (real_name != real_file_name)
795 free (real_name);
796 continue;
800 /* A link may just point to itself. */
801 if (is_link)
803 /* If the path the link points to isn't its soname and it is not
804 .so symlink for ld(1) only, we treat it as a normal file. */
805 const char *real_base_name = basename (real_file_name);
807 if (strcmp (real_base_name, soname) != 0)
809 len = strlen (real_base_name);
810 if (len < strlen (".so")
811 || strcmp (real_base_name + len - strlen (".so"), ".so") != 0
812 || strncmp (real_base_name, soname, len) != 0)
813 is_link = 0;
817 if (real_name != real_file_name)
818 free (real_name);
820 if (is_link)
822 free (soname);
823 soname = xstrdup (direntry->d_name);
826 if (flag == FLAG_ELF
827 && (entry->flag == FLAG_ELF_LIBC5
828 || entry->flag == FLAG_ELF_LIBC6))
829 flag = entry->flag;
830 /* Some sanity checks to print warnings. */
831 if (opt_verbose)
833 if (flag == FLAG_ELF_LIBC5 && entry->flag != FLAG_ELF_LIBC5
834 && entry->flag != FLAG_ANY)
835 error (0, 0, _("libc5 library %s in wrong directory"), file_name);
836 if (flag == FLAG_ELF_LIBC6 && entry->flag != FLAG_ELF_LIBC6
837 && entry->flag != FLAG_ANY)
838 error (0, 0, _("libc6 library %s in wrong directory"), file_name);
839 if (flag == FLAG_LIBC4 && entry->flag != FLAG_LIBC4
840 && entry->flag != FLAG_ANY)
841 error (0, 0, _("libc4 library %s in wrong directory"), file_name);
844 /* Add library to list. */
845 for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
847 /* Is soname already in list? */
848 if (strcmp (dlib_ptr->soname, soname) == 0)
850 /* Prefer a file to a link, otherwise check which one
851 is newer. */
852 if ((!is_link && dlib_ptr->is_link)
853 || (is_link == dlib_ptr->is_link
854 && _dl_cache_libcmp (dlib_ptr->name, direntry->d_name) < 0))
856 /* It's newer - add it. */
857 /* Flag should be the same - sanity check. */
858 if (dlib_ptr->flag != flag)
860 if (dlib_ptr->flag == FLAG_ELF
861 && (flag == FLAG_ELF_LIBC5 || flag == FLAG_ELF_LIBC6))
862 dlib_ptr->flag = flag;
863 else if ((dlib_ptr->flag == FLAG_ELF_LIBC5
864 || dlib_ptr->flag == FLAG_ELF_LIBC6)
865 && flag == FLAG_ELF)
866 dlib_ptr->flag = flag;
867 else
868 error (0, 0, _("libraries %s and %s in directory %s have same soname but different type."),
869 dlib_ptr->name, direntry->d_name, entry->path);
871 free (dlib_ptr->name);
872 dlib_ptr->osversion = osversion;
873 dlib_ptr->name = xstrdup (direntry->d_name);
874 dlib_ptr->is_link = is_link;
876 /* Don't add this library, abort loop. */
877 /* Also free soname, since it's dynamically allocated. */
878 free (soname);
879 break;
882 /* Add the library if it's not already in. */
883 if (dlib_ptr == NULL)
885 dlib_ptr = (struct dlib_entry *)xmalloc (sizeof (struct dlib_entry));
886 dlib_ptr->name = xstrdup (direntry->d_name);
887 dlib_ptr->flag = flag;
888 dlib_ptr->osversion = osversion;
889 dlib_ptr->soname = soname;
890 dlib_ptr->is_link = is_link;
891 /* Add at head of list. */
892 dlib_ptr->next = dlibs;
893 dlibs = dlib_ptr;
897 closedir (dir);
899 /* Now dlibs contains a list of all libs - add those to the cache
900 and created all symbolic links. */
901 for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
903 /* Don't create links to links. */
904 if (dlib_ptr->is_link == 0)
905 create_links (dir_name, entry->path, dlib_ptr->name,
906 dlib_ptr->soname);
907 if (opt_build_cache)
908 add_to_cache (entry->path, dlib_ptr->soname, dlib_ptr->flag,
909 dlib_ptr->osversion, hwcap);
912 /* Free all resources. */
913 while (dlibs)
915 dlib_ptr = dlibs;
916 free (dlib_ptr->soname);
917 free (dlib_ptr->name);
918 dlibs = dlibs->next;
919 free (dlib_ptr);
922 if (opt_chroot && dir_name)
923 free (dir_name);
926 /* Search through all libraries. */
927 static void
928 search_dirs (void)
930 struct dir_entry *entry;
932 for (entry = dir_entries; entry != NULL; entry = entry->next)
933 search_dir (entry);
935 /* Free all allocated memory. */
936 while (dir_entries)
938 entry = dir_entries;
939 dir_entries = dir_entries->next;
940 free (entry->path);
941 free (entry);
946 static void parse_conf_include (const char *config_file, unsigned int lineno,
947 bool do_chroot, const char *pattern);
949 /* Parse configuration file. */
950 static void
951 parse_conf (const char *filename, bool do_chroot)
953 FILE *file = NULL;
954 char *line = NULL;
955 const char *canon;
956 size_t len = 0;
957 unsigned int lineno;
959 if (do_chroot && opt_chroot)
961 canon = chroot_canon (opt_chroot, filename);
962 if (canon)
963 file = fopen (canon, "r");
964 else
965 canon = filename;
967 else
969 canon = filename;
970 file = fopen (filename, "r");
973 if (file == NULL)
975 error (0, errno, _("Can't open configuration file %s"), canon);
976 if (canon != filename)
977 free ((char *) canon);
978 return;
981 /* No threads use this stream. */
982 __fsetlocking (file, FSETLOCKING_BYCALLER);
984 if (canon != filename)
985 free ((char *) canon);
987 lineno = 0;
990 ssize_t n = getline (&line, &len, file);
991 if (n < 0)
992 break;
994 ++lineno;
995 if (line[n - 1] == '\n')
996 line[n - 1] = '\0';
998 /* Because the file format does not know any form of quoting we
999 can search forward for the next '#' character and if found
1000 make it terminating the line. */
1001 *strchrnul (line, '#') = '\0';
1003 /* Remove leading whitespace. NUL is no whitespace character. */
1004 char *cp = line;
1005 while (isspace (*cp))
1006 ++cp;
1008 /* If the line is blank it is ignored. */
1009 if (cp[0] == '\0')
1010 continue;
1012 if (!strncmp (cp, "include", 7) && isblank (cp[7]))
1014 char *dir;
1015 cp += 8;
1016 while ((dir = strsep (&cp, " \t")) != NULL)
1017 if (dir[0] != '\0')
1018 parse_conf_include (filename, lineno, do_chroot, dir);
1020 else
1021 add_dir (cp);
1023 while (!feof_unlocked (file));
1025 /* Free buffer and close file. */
1026 free (line);
1027 fclose (file);
1030 /* Handle one word in an `include' line, a glob pattern of additional
1031 config files to read. */
1032 static void
1033 parse_conf_include (const char *config_file, unsigned int lineno,
1034 bool do_chroot, const char *pattern)
1036 if (opt_chroot && pattern[0] != '/')
1037 error (EXIT_FAILURE, 0,
1038 _("need absolute file name for configuration file when using -r"));
1040 char *copy = NULL;
1041 if (pattern[0] != '/' && strchr (config_file, '/') != NULL)
1043 if (asprintf (&copy, "%s/%s", dirname (strdupa (config_file)),
1044 pattern) < 0)
1045 error (EXIT_FAILURE, 0, _("memory exhausted"));
1046 pattern = copy;
1049 glob64_t gl;
1050 int result;
1051 if (do_chroot && opt_chroot)
1053 char *canon = chroot_canon (opt_chroot, pattern);
1054 result = glob64 (canon ?: pattern, 0, NULL, &gl);
1055 free (canon);
1057 else
1058 result = glob64 (pattern, 0, NULL, &gl);
1060 switch (result)
1062 case 0:
1063 for (size_t i = 0; i < gl.gl_pathc; ++i)
1064 parse_conf (gl.gl_pathv[i], false);
1065 globfree64 (&gl);
1066 break;
1068 case GLOB_NOMATCH:
1069 break;
1071 case GLOB_NOSPACE:
1072 errno = ENOMEM;
1073 case GLOB_ABORTED:
1074 if (opt_verbose)
1075 error (0, errno, _("%s:%u: cannot read directory %s"),
1076 config_file, lineno, pattern);
1077 break;
1079 default:
1080 abort ();
1081 break;
1084 if (copy)
1085 free (copy);
1088 /* Honour LD_HWCAP_MASK. */
1089 static void
1090 set_hwcap (void)
1092 char *mask = getenv ("LD_HWCAP_MASK");
1094 if (mask)
1095 hwcap_mask = strtoul (mask, NULL, 0);
1100 main (int argc, char **argv)
1102 int remaining;
1104 /* Parse and process arguments. */
1105 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
1107 /* Remaining arguments are additional directories if opt_manual_link
1108 is not set. */
1109 if (remaining != argc && !opt_manual_link)
1111 int i;
1112 for (i = remaining; i < argc; ++i)
1113 if (opt_build_cache && argv[i][0] != '/')
1114 error (EXIT_FAILURE, 0,
1115 _("relative path `%s' used to build cache"),
1116 argv[i]);
1117 else
1118 add_dir (argv[i]);
1121 set_hwcap ();
1123 if (opt_chroot)
1125 /* Normalize the path a bit, we might need it for printing later. */
1126 char *endp = strchr (opt_chroot, '\0');
1127 while (endp > opt_chroot && endp[-1] == '/')
1128 --endp;
1129 *endp = '\0';
1130 if (endp == opt_chroot)
1131 opt_chroot = NULL;
1133 if (opt_chroot)
1135 /* It is faster to use chroot if we can. */
1136 if (!chroot (opt_chroot))
1138 if (chdir ("/"))
1139 error (EXIT_FAILURE, errno, _("Can't chdir to /"));
1140 opt_chroot = NULL;
1145 if (cache_file == NULL)
1147 cache_file = alloca (strlen (LD_SO_CACHE) + 1);
1148 strcpy (cache_file, LD_SO_CACHE);
1151 if (config_file == NULL)
1152 config_file = LD_SO_CONF;
1154 if (opt_print_cache)
1156 if (opt_chroot)
1158 char *p = chroot_canon (opt_chroot, cache_file);
1159 if (p == NULL)
1160 error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"),
1161 cache_file);
1162 cache_file = p;
1164 print_cache (cache_file);
1165 if (opt_chroot)
1166 free (cache_file);
1167 exit (0);
1170 if (opt_chroot)
1172 /* Canonicalize the directory name of cache_file, not cache_file,
1173 because we'll rename a temporary cache file to it. */
1174 char *p = strrchr (cache_file, '/');
1175 char *canon = chroot_canon (opt_chroot,
1176 p ? (*p = '\0', cache_file) : "/");
1178 if (canon == NULL)
1180 error (EXIT_FAILURE, errno,
1181 _("Can't open cache file directory %s\n"),
1182 p ? cache_file : "/");
1185 if (p)
1186 ++p;
1187 else
1188 p = cache_file;
1190 cache_file = alloca (strlen (canon) + strlen (p) + 2);
1191 sprintf (cache_file, "%s/%s", canon, p);
1192 free (canon);
1195 if (opt_manual_link)
1197 /* Link all given libraries manually. */
1198 int i;
1200 for (i = remaining; i < argc; ++i)
1201 manual_link (argv[i]);
1203 exit (0);
1207 if (opt_build_cache)
1208 init_cache ();
1210 if (!opt_only_cline)
1212 parse_conf (config_file, true);
1214 /* Always add the standard search paths. */
1215 add_system_dir (SLIBDIR);
1216 if (strcmp (SLIBDIR, LIBDIR))
1217 add_system_dir (LIBDIR);
1220 search_dirs ();
1222 if (opt_build_cache)
1223 save_cache (cache_file);
1225 return 0;