* catgets/gencat.c: Use GPL, not LGPL.
[platform/upstream/glibc.git] / elf / ldconfig.c
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.
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License version 2 as
7    published by the Free Software Foundation.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 #define PROCINFO_CLASS static
19 #include <alloca.h>
20 #include <argp.h>
21 #include <dirent.h>
22 #include <elf.h>
23 #include <error.h>
24 #include <errno.h>
25 #include <inttypes.h>
26 #include <libintl.h>
27 #include <stdbool.h>
28 #include <stdio.h>
29 #include <stdio_ext.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <sys/fcntl.h>
34 #include <sys/mman.h>
35 #include <sys/stat.h>
36 #include <sys/types.h>
37 #include <glob.h>
38 #include <libgen.h>
39
40 #include "ldconfig.h"
41 #include "dl-cache.h"
42
43 #include "dl-procinfo.h"
44
45 #ifdef _DL_FIRST_PLATFORM
46 # define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT)
47 #else
48 # define _DL_FIRST_EXTRA _DL_HWCAP_COUNT
49 #endif
50
51 #ifndef LD_SO_CONF
52 # define LD_SO_CONF SYSCONFDIR "/ld.so.conf"
53 #endif
54
55 /* Get libc version number.  */
56 #include <version.h>
57
58 #define PACKAGE _libc_intl_domainname
59
60 static const struct
61 {
62   const char *name;
63   int flag;
64 } lib_types[] =
65 {
66   {"libc4", FLAG_LIBC4},
67   {"libc5", FLAG_ELF_LIBC5},
68   {"libc6", FLAG_ELF_LIBC6},
69   {"glibc2", FLAG_ELF_LIBC6}
70 };
71
72
73 /* List of directories to handle.  */
74 struct dir_entry
75 {
76   char *path;
77   int flag;
78   ino64_t ino;
79   dev_t dev;
80   struct dir_entry *next;
81 };
82
83 /* The list is unsorted, contains no duplicates.  Entries are added at
84    the end.  */
85 static struct dir_entry *dir_entries;
86
87 /* Flags for different options.  */
88 /* Print Cache.  */
89 static int opt_print_cache;
90
91 /* Be verbose.  */
92 int opt_verbose;
93
94 /* Format to support.  */
95 /* 0: only libc5/glibc2; 1: both; 2: only glibc 2.2.  */
96 int opt_format = 1;
97
98 /* Build cache.  */
99 static int opt_build_cache = 1;
100
101 /* Generate links.  */
102 static int opt_link = 1;
103
104 /* Only process directories specified on the command line.  */
105 static int opt_only_cline;
106
107 /* Path to root for chroot.  */
108 static char *opt_chroot;
109
110 /* Manually link given shared libraries.  */
111 static int opt_manual_link;
112
113 /* Cache file to use.  */
114 static char *cache_file;
115
116 /* Configuration file.  */
117 static const char *config_file;
118
119 /* Mask to use for important hardware capabilities.  */
120 static unsigned long int hwcap_mask = HWCAP_IMPORTANT;
121
122 /* Configuration-defined capabilities defined in kernel vDSOs.  */
123 static const char *hwcap_extra[64 - _DL_FIRST_EXTRA];
124
125 /* Name and version of program.  */
126 static void print_version (FILE *stream, struct argp_state *state);
127 void (*argp_program_version_hook) (FILE *, struct argp_state *)
128      = print_version;
129
130 /* Definitions of arguments for argp functions.  */
131 static const struct argp_option options[] =
132 {
133   { "print-cache", 'p', NULL, 0, N_("Print cache"), 0},
134   { "verbose", 'v', NULL, 0, N_("Generate verbose messages"), 0},
135   { NULL, 'N', NULL, 0, N_("Don't build cache"), 0},
136   { NULL, 'X', NULL, 0, N_("Don't generate links"), 0},
137   { NULL, 'r', N_("ROOT"), 0, N_("Change to and use ROOT as root directory"), 0},
138   { NULL, 'C', N_("CACHE"), 0, N_("Use CACHE as cache file"), 0},
139   { NULL, 'f', N_("CONF"), 0, N_("Use CONF as configuration file"), 0},
140   { NULL, 'n', NULL, 0, N_("Only process directories specified on the command line.  Don't build cache."), 0},
141   { NULL, 'l', NULL, 0, N_("Manually link individual libraries."), 0},
142   { "format", 'c', N_("FORMAT"), 0, N_("Format to use: new, old or compat (default)"), 0},
143   { NULL, 0, NULL, 0, NULL, 0 }
144 };
145
146 #define PROCINFO_CLASS static
147 #include <dl-procinfo.c>
148
149 /* Short description of program.  */
150 static const char doc[] = N_("Configure Dynamic Linker Run Time Bindings.");
151
152 /* Prototype for option handler.  */
153 static error_t parse_opt (int key, char *arg, struct argp_state *state);
154
155 /* Data structure to communicate with argp functions.  */
156 static struct argp argp =
157 {
158   options, parse_opt, NULL, doc, NULL, NULL, NULL
159 };
160
161 /* Check if string corresponds to an important hardware capability or
162    a platform.  */
163 static int
164 is_hwcap_platform (const char *name)
165 {
166   int hwcap_idx = _dl_string_hwcap (name);
167
168   if (hwcap_idx != -1 && ((1 << hwcap_idx) & hwcap_mask))
169     return 1;
170
171   hwcap_idx = _dl_string_platform (name);
172   if (hwcap_idx != -1)
173     return 1;
174
175   for (hwcap_idx = _DL_FIRST_EXTRA; hwcap_idx < 64; ++hwcap_idx)
176     if (hwcap_extra[hwcap_idx - _DL_FIRST_EXTRA] != NULL
177         && !strcmp (name, hwcap_extra[hwcap_idx - _DL_FIRST_EXTRA]))
178       return 1;
179
180   return 0;
181 }
182
183 /* Get hwcap (including platform) encoding of path.  */
184 static uint64_t
185 path_hwcap (const char *path)
186 {
187   char *str = xstrdup (path);
188   char *ptr;
189   uint64_t hwcap = 0;
190   uint64_t h;
191
192   size_t len;
193
194   len = strlen (str);
195   if (str[len] == '/')
196     str[len] = '\0';
197
198   /* Search pathname from the end and check for hwcap strings.  */
199   for (;;)
200     {
201       ptr = strrchr (str, '/');
202
203       if (ptr == NULL)
204         break;
205
206       h = _dl_string_hwcap (ptr + 1);
207
208       if (h == (uint64_t) -1)
209         {
210           h = _dl_string_platform (ptr + 1);
211           if (h == (uint64_t) -1)
212             {
213               for (h = _DL_FIRST_EXTRA; h < 64; ++h)
214                 if (hwcap_extra[h - _DL_FIRST_EXTRA] != NULL
215                     && !strcmp (ptr + 1, hwcap_extra[h - _DL_FIRST_EXTRA]))
216                   break;
217               if (h == 64)
218                 break;
219             }
220         }
221       hwcap += 1ULL << h;
222
223       /* Search the next part of the path.  */
224       *ptr = '\0';
225     }
226
227   free (str);
228   return hwcap;
229 }
230
231 /* Handle program arguments.  */
232 static error_t
233 parse_opt (int key, char *arg, struct argp_state *state)
234 {
235   switch (key)
236     {
237     case 'C':
238       cache_file = arg;
239       break;
240     case 'f':
241       config_file = arg;
242       break;
243     case 'l':
244       opt_manual_link = 1;
245       break;
246     case 'N':
247       opt_build_cache = 0;
248       break;
249     case 'n':
250       opt_build_cache = 0;
251       opt_only_cline = 1;
252       break;
253     case 'p':
254       opt_print_cache = 1;
255       break;
256     case 'r':
257       opt_chroot = arg;
258       break;
259     case 'v':
260       opt_verbose = 1;
261       break;
262     case 'X':
263       opt_link = 0;
264       break;
265     case 'c':
266       if (strcmp (arg, "old") == 0)
267         opt_format = 0;
268       else if (strcmp (arg, "compat") == 0)
269         opt_format = 1;
270       else if (strcmp (arg, "new") == 0)
271         opt_format = 2;
272       break;
273     default:
274       return ARGP_ERR_UNKNOWN;
275     }
276
277   return 0;
278 }
279
280 /* Print the version information.  */
281 static void
282 print_version (FILE *stream, struct argp_state *state)
283 {
284   fprintf (stream, "ldconfig (GNU %s) %s\n", PACKAGE, VERSION);
285   fprintf (stream, gettext ("\
286 Copyright (C) %s Free Software Foundation, Inc.\n\
287 This is free software; see the source for copying conditions.  There is NO\n\
288 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
289 "), "2005");
290   fprintf (stream, gettext ("Written by %s.\n"),
291            "Andreas Jaeger");
292 }
293
294 /* Add a single directory entry.  */
295 static void
296 add_single_dir (struct dir_entry *entry, int verbose)
297 {
298   struct dir_entry *ptr, *prev;
299
300   ptr = dir_entries;
301   prev = ptr;
302   while (ptr != NULL)
303     {
304       /* Check for duplicates.  */
305       if (ptr->ino == entry->ino && ptr->dev == entry->dev)
306         {
307           if (opt_verbose && verbose)
308             error (0, 0, _("Path `%s' given more than once"), entry->path);
309           /* Use the newer information.  */
310           ptr->flag = entry->flag;
311           free (entry->path);
312           free (entry);
313           break;
314         }
315       prev = ptr;
316       ptr = ptr->next;
317     }
318   /* Is this the first entry?  */
319   if (ptr == NULL && dir_entries == NULL)
320     dir_entries = entry;
321   else if (ptr == NULL)
322     prev->next = entry;
323 }
324
325 /* Add one directory to the list of directories to process.  */
326 static void
327 add_dir (const char *line)
328 {
329   unsigned int i;
330   struct dir_entry *entry = xmalloc (sizeof (struct dir_entry));
331   entry->next = NULL;
332
333   /* Search for an '=' sign.  */
334   entry->path = xstrdup (line);
335   char *equal_sign = strchr (entry->path, '=');
336   if (equal_sign)
337     {
338       *equal_sign = '\0';
339       ++equal_sign;
340       entry->flag = FLAG_ANY;
341       for (i = 0; i < sizeof (lib_types) / sizeof (lib_types[0]); ++i)
342         if (strcmp (equal_sign, lib_types[i].name) == 0)
343           {
344             entry->flag = lib_types[i].flag;
345             break;
346           }
347       if (entry->flag == FLAG_ANY)
348         error (0, 0, _("%s is not a known library type"), equal_sign);
349     }
350   else
351     {
352       entry->flag = FLAG_ANY;
353     }
354
355   /* Canonify path: for now only remove leading and trailing
356      whitespace and the trailing slashes slashes.  */
357   i = strlen (entry->path) - 1;
358
359   while (isspace (entry->path[i]) && i > 0)
360     entry->path[i--] = '\0';
361
362   while (entry->path[i] == '/' && i > 0)
363     entry->path[i--] = '\0';
364
365   char *path = entry->path;
366   if (opt_chroot)
367     path = chroot_canon (opt_chroot, path);
368
369   struct stat64 stat_buf;
370   if (path == NULL || stat64 (path, &stat_buf))
371     {
372       if (opt_verbose)
373         error (0, errno, _("Can't stat %s"), entry->path);
374       free (entry->path);
375       free (entry);
376     }
377   else
378     {
379       entry->ino = stat_buf.st_ino;
380       entry->dev = stat_buf.st_dev;
381
382       add_single_dir (entry, 1);
383     }
384
385   if (opt_chroot)
386     free (path);
387 }
388
389
390 static int
391 chroot_stat (const char *real_path, const char *path, struct stat64 *st)
392 {
393   int ret;
394   char *canon_path;
395
396   if (!opt_chroot)
397     return stat64 (real_path, st);
398
399   ret = lstat64 (real_path, st);
400   if (ret || !S_ISLNK (st->st_mode))
401     return ret;
402
403   canon_path = chroot_canon (opt_chroot, path);
404   if (canon_path == NULL)
405     return -1;
406
407   ret = stat64 (canon_path, st);
408   free (canon_path);
409   return ret;
410 }
411
412 /* Create a symbolic link from soname to libname in directory path.  */
413 static void
414 create_links (const char *real_path, const char *path, const char *libname,
415               const char *soname)
416 {
417   char *full_libname, *full_soname;
418   char *real_full_libname, *real_full_soname;
419   struct stat64 stat_lib, stat_so, lstat_so;
420   int do_link = 1;
421   int do_remove = 1;
422   /* XXX: The logics in this function should be simplified.  */
423
424   /* Get complete path.  */
425   full_libname = alloca (strlen (path) + strlen (libname) + 2);
426   full_soname = alloca (strlen (path) + strlen (soname) + 2);
427   sprintf (full_libname, "%s/%s", path, libname);
428   sprintf (full_soname, "%s/%s", path, soname);
429   if (opt_chroot)
430     {
431       real_full_libname = alloca (strlen (real_path) + strlen (libname) + 2);
432       real_full_soname = alloca (strlen (real_path) + strlen (soname) + 2);
433       sprintf (real_full_libname, "%s/%s", real_path, libname);
434       sprintf (real_full_soname, "%s/%s", real_path, soname);
435     }
436   else
437     {
438       real_full_libname = full_libname;
439       real_full_soname = full_soname;
440     }
441
442   /* Does soname already exist and point to the right library?  */
443   if (chroot_stat (real_full_soname, full_soname, &stat_so) == 0)
444     {
445       if (chroot_stat (real_full_libname, full_libname, &stat_lib))
446         {
447           error (0, 0, _("Can't stat %s\n"), full_libname);
448           return;
449         }
450       if (stat_lib.st_dev == stat_so.st_dev
451           && stat_lib.st_ino == stat_so.st_ino)
452         /* Link is already correct.  */
453         do_link = 0;
454       else if (lstat64 (full_soname, &lstat_so) == 0
455                && !S_ISLNK (lstat_so.st_mode))
456         {
457           error (0, 0, _("%s is not a symbolic link\n"), full_soname);
458           do_link = 0;
459           do_remove = 0;
460         }
461     }
462   else if (lstat64 (real_full_soname, &lstat_so) != 0
463            || !S_ISLNK (lstat_so.st_mode))
464     /* Unless it is a stale symlink, there is no need to remove.  */
465     do_remove = 0;
466
467   if (opt_verbose)
468     printf ("\t%s -> %s", soname, libname);
469
470   if (do_link && opt_link)
471     {
472       /* Remove old link.  */
473       if (do_remove)
474         if (unlink (real_full_soname))
475           {
476             error (0, 0, _("Can't unlink %s"), full_soname);
477             do_link = 0;
478           }
479       /* Create symbolic link.  */
480       if (do_link && symlink (libname, real_full_soname))
481         {
482           error (0, 0, _("Can't link %s to %s"), full_soname, libname);
483           do_link = 0;
484         }
485       if (opt_verbose)
486         {
487           if (do_link)
488             fputs (_(" (changed)\n"), stdout);
489           else
490             fputs (_(" (SKIPPED)\n"), stdout);
491         }
492     }
493   else if (opt_verbose)
494     fputs ("\n", stdout);
495 }
496
497 /* Manually link the given library.  */
498 static void
499 manual_link (char *library)
500 {
501   char *path;
502   char *real_path;
503   char *real_library;
504   char *libname;
505   char *soname;
506   struct stat64 stat_buf;
507   int flag;
508   unsigned int osversion;
509
510   /* Prepare arguments for create_links call.  Split library name in
511      directory and filename first.  Since path is allocated, we've got
512      to be careful to free at the end.  */
513   path = xstrdup (library);
514   libname = strrchr (path, '/');
515
516   if (libname)
517     {
518       /* Successfully split names.  Check if path is just "/" to avoid
519          an empty path.  */
520       if (libname == path)
521         {
522           libname = library + 1;
523           path = xrealloc (path, 2);
524           strcpy (path, "/");
525         }
526       else
527         {
528           *libname = '\0';
529           ++libname;
530         }
531     }
532   else
533     {
534       /* There's no path, construct one. */
535       libname = library;
536       path = xrealloc (path, 2);
537       strcpy (path, ".");
538     }
539
540   if (opt_chroot)
541     {
542       real_path = chroot_canon (opt_chroot, path);
543       if (real_path == NULL)
544         {
545           error (0, errno, _("Can't find %s"), path);
546           free (path);
547           return;
548         }
549       real_library = alloca (strlen (real_path) + strlen (libname) + 2);
550       sprintf (real_library, "%s/%s", real_path, libname);
551     }
552   else
553     {
554       real_path = path;
555       real_library = library;
556     }
557
558   /* Do some sanity checks first.  */
559   if (lstat64 (real_library, &stat_buf))
560     {
561       error (0, errno, _("Can't lstat %s"), library);
562       free (path);
563       return;
564     }
565   /* We don't want links here!  */
566   else if (!S_ISREG (stat_buf.st_mode))
567     {
568       error (0, 0, _("Ignored file %s since it is not a regular file."),
569              library);
570       free (path);
571       return;
572     }
573   if (process_file (real_library, library, libname, &flag, &osversion,
574                     &soname, 0))
575     {
576       error (0, 0, _("No link created since soname could not be found for %s"),
577              library);
578       free (path);
579       return;
580     }
581   create_links (real_path, path, libname, soname);
582   free (soname);
583   free (path);
584 }
585
586
587 /* Read a whole directory and search for libraries.
588    The purpose is two-fold:
589    - search for libraries which will be added to the cache
590    - create symbolic links to the soname for each library
591
592    This has to be done separatly for each directory.
593
594    To keep track of which libraries to add to the cache and which
595    links to create, we save a list of all libraries.
596
597    The algorithm is basically:
598    for all libraries in the directory do
599      get soname of library
600      if soname is already in list
601        if new library is newer, replace entry
602        otherwise ignore this library
603      otherwise add library to list
604
605    For example, if the two libraries libxy.so.1.1 and libxy.so.1.2
606    exist and both have the same soname, e.g. libxy.so, a symbolic link
607    is created from libxy.so.1.2 (the newer one) to libxy.so.
608    libxy.so.1.2 and libxy.so are added to the cache - but not
609    libxy.so.1.1.  */
610
611 /* Information for one library.  */
612 struct dlib_entry
613 {
614   char *name;
615   char *soname;
616   int flag;
617   int is_link;
618   unsigned int osversion;
619   struct dlib_entry *next;
620 };
621
622
623 static void
624 search_dir (const struct dir_entry *entry)
625 {
626   DIR *dir;
627   struct dirent64 *direntry;
628   char *file_name, *dir_name, *real_file_name, *real_name;
629   int file_name_len, real_file_name_len, len;
630   char *soname;
631   struct dlib_entry *dlibs;
632   struct dlib_entry *dlib_ptr;
633   struct stat64 lstat_buf, stat_buf;
634   int is_link, is_dir;
635   uint64_t hwcap = path_hwcap (entry->path);
636   unsigned int osversion;
637
638   file_name_len = PATH_MAX;
639   file_name = alloca (file_name_len);
640
641   dlibs = NULL;
642
643   if (opt_verbose)
644     {
645       if (hwcap != 0)
646         printf ("%s: (hwcap: %#.16" PRIx64 ")\n", entry->path, hwcap);
647       else
648         printf ("%s:\n", entry->path);
649     }
650
651   if (opt_chroot)
652     {
653       dir_name = chroot_canon (opt_chroot, entry->path);
654       real_file_name_len = PATH_MAX;
655       real_file_name = alloca (real_file_name_len);
656     }
657   else
658     {
659       dir_name = entry->path;
660       real_file_name_len = 0;
661       real_file_name = file_name;
662     }
663
664   if (dir_name == NULL || (dir = opendir (dir_name)) == NULL)
665     {
666       if (opt_verbose)
667         error (0, errno, _("Can't open directory %s"), entry->path);
668       if (opt_chroot && dir_name)
669         free (dir_name);
670       return;
671     }
672
673   while ((direntry = readdir64 (dir)) != NULL)
674     {
675       int flag;
676 #ifdef _DIRENT_HAVE_D_TYPE
677       /* We only look at links and regular files.  */
678       if (direntry->d_type != DT_UNKNOWN
679           && direntry->d_type != DT_LNK
680           && direntry->d_type != DT_REG
681           && direntry->d_type != DT_DIR)
682         continue;
683 #endif /* _DIRENT_HAVE_D_TYPE  */
684       /* Does this file look like a shared library or is it a hwcap
685          subdirectory?  The dynamic linker is also considered as
686          shared library.  */
687       if (((strncmp (direntry->d_name, "lib", 3) != 0
688             && strncmp (direntry->d_name, "ld-", 3) != 0)
689            || strstr (direntry->d_name, ".so") == NULL)
690           && (
691 #ifdef _DIRENT_HAVE_D_TYPE
692               direntry->d_type == DT_REG ||
693 #endif
694               !is_hwcap_platform (direntry->d_name)))
695         continue;
696       len = strlen (entry->path) + strlen (direntry->d_name);
697       if (len > file_name_len)
698         {
699           file_name_len = len + 1;
700           file_name = alloca (file_name_len);
701           if (!opt_chroot)
702             real_file_name = file_name;
703         }
704       sprintf (file_name, "%s/%s", entry->path, direntry->d_name);
705       if (opt_chroot)
706         {
707           len = strlen (dir_name) + strlen (direntry->d_name);
708           if (len > real_file_name_len)
709             {
710               real_file_name_len = len + 1;
711               real_file_name = alloca (real_file_name_len);
712             }
713           sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name);
714         }
715 #ifdef _DIRENT_HAVE_D_TYPE
716       if (direntry->d_type != DT_UNKNOWN)
717         lstat_buf.st_mode = DTTOIF (direntry->d_type);
718       else
719 #endif
720         if (__builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
721           {
722             error (0, errno, _("Cannot lstat %s"), file_name);
723             continue;
724           }
725
726       is_link = S_ISLNK (lstat_buf.st_mode);
727       if (is_link)
728         {
729           /* In case of symlink, we check if the symlink refers to
730              a directory. */
731           if (__builtin_expect (stat64 (real_file_name, &stat_buf), 0))
732             {
733               if (opt_verbose)
734                 error (0, errno, _("Cannot stat %s"), file_name);
735
736               /* Remove stale symlinks.  */
737               if (strstr (direntry->d_name, ".so."))
738                 unlink (real_file_name);
739               continue;
740             }
741           is_dir = S_ISDIR (stat_buf.st_mode);
742         }
743       else
744         is_dir = S_ISDIR (lstat_buf.st_mode);
745
746       if (is_dir && is_hwcap_platform (direntry->d_name))
747         {
748           /* Handle subdirectory later.  */
749           struct dir_entry *new_entry;
750
751           new_entry = xmalloc (sizeof (struct dir_entry));
752           new_entry->path = xstrdup (file_name);
753           new_entry->flag = entry->flag;
754           new_entry->next = NULL;
755           if (is_link)
756             {
757               new_entry->ino = stat_buf.st_ino;
758               new_entry->dev = stat_buf.st_dev;
759             }
760           else
761             {
762 #ifdef _DIRENT_HAVE_D_TYPE
763               /* We have filled in lstat only #ifndef
764                  _DIRENT_HAVE_D_TYPE.  Fill it in if needed.  */
765               if (direntry->d_type != DT_UNKNOWN
766                   && __builtin_expect (lstat64 (real_file_name, &lstat_buf),
767                                        0))
768                 {
769                   error (0, errno, _("Cannot lstat %s"), file_name);
770                   free (new_entry->path);
771                   free (new_entry);
772                   continue;
773                 }
774 #endif
775
776               new_entry->ino = lstat_buf.st_ino;
777               new_entry->dev = lstat_buf.st_dev;
778             }
779           add_single_dir (new_entry, 0);
780           continue;
781         }
782       else if (!S_ISREG (lstat_buf.st_mode) && !is_link)
783         continue;
784
785       if (opt_chroot && is_link)
786         {
787           real_name = chroot_canon (opt_chroot, file_name);
788           if (real_name == NULL)
789             {
790               if (strstr (file_name, ".so") == NULL)
791                 error (0, 0, _("Input file %s not found.\n"), file_name);
792               continue;
793             }
794         }
795       else
796         real_name = real_file_name;
797
798       if (process_file (real_name, file_name, direntry->d_name, &flag,
799                         &osversion, &soname, is_link))
800         {
801           if (real_name != real_file_name)
802             free (real_name);
803           continue;
804         }
805
806
807       /* A link may just point to itself.  */
808       if (is_link)
809         {
810           /* If the path the link points to isn't its soname and it is not
811              .so symlink for ld(1) only, we treat it as a normal file.  */
812           const char *real_base_name = basename (real_file_name);
813
814           if (strcmp (real_base_name, soname) != 0)
815             {
816               len = strlen (real_base_name);
817               if (len < strlen (".so")
818                   || strcmp (real_base_name + len - strlen (".so"), ".so") != 0
819                   || strncmp (real_base_name, soname, len) != 0)
820                 is_link = 0;
821             }
822         }
823
824       if (real_name != real_file_name)
825         free (real_name);
826
827       if (is_link)
828         {
829           free (soname);
830           soname = xstrdup (direntry->d_name);
831         }
832
833       if (flag == FLAG_ELF
834           && (entry->flag == FLAG_ELF_LIBC5
835               || entry->flag == FLAG_ELF_LIBC6))
836         flag = entry->flag;
837       /* Some sanity checks to print warnings.  */
838       if (opt_verbose)
839         {
840           if (flag == FLAG_ELF_LIBC5 && entry->flag != FLAG_ELF_LIBC5
841               && entry->flag != FLAG_ANY)
842             error (0, 0, _("libc5 library %s in wrong directory"), file_name);
843           if (flag == FLAG_ELF_LIBC6 && entry->flag != FLAG_ELF_LIBC6
844               && entry->flag != FLAG_ANY)
845             error (0, 0, _("libc6 library %s in wrong directory"), file_name);
846           if (flag == FLAG_LIBC4 && entry->flag != FLAG_LIBC4
847               && entry->flag != FLAG_ANY)
848             error (0, 0, _("libc4 library %s in wrong directory"), file_name);
849         }
850
851       /* Add library to list.  */
852       for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
853         {
854           /* Is soname already in list?  */
855           if (strcmp (dlib_ptr->soname, soname) == 0)
856             {
857               /* Prefer a file to a link, otherwise check which one
858                  is newer.  */
859               if ((!is_link && dlib_ptr->is_link)
860                   || (is_link == dlib_ptr->is_link
861                       && _dl_cache_libcmp (dlib_ptr->name, direntry->d_name) < 0))
862                 {
863                   /* It's newer - add it.  */
864                   /* Flag should be the same - sanity check.  */
865                   if (dlib_ptr->flag != flag)
866                     {
867                       if (dlib_ptr->flag == FLAG_ELF
868                           && (flag == FLAG_ELF_LIBC5 || flag == FLAG_ELF_LIBC6))
869                         dlib_ptr->flag = flag;
870                       else if ((dlib_ptr->flag == FLAG_ELF_LIBC5
871                                 || dlib_ptr->flag == FLAG_ELF_LIBC6)
872                                && flag == FLAG_ELF)
873                         dlib_ptr->flag = flag;
874                       else
875                         error (0, 0, _("libraries %s and %s in directory %s have same soname but different type."),
876                                dlib_ptr->name, direntry->d_name, entry->path);
877                     }
878                   free (dlib_ptr->name);
879                   dlib_ptr->osversion = osversion;
880                   dlib_ptr->name = xstrdup (direntry->d_name);
881                   dlib_ptr->is_link = is_link;
882                 }
883               /* Don't add this library, abort loop.  */
884               /* Also free soname, since it's dynamically allocated.  */
885               free (soname);
886               break;
887             }
888         }
889       /* Add the library if it's not already in.  */
890       if (dlib_ptr == NULL)
891         {
892           dlib_ptr = (struct dlib_entry *)xmalloc (sizeof (struct dlib_entry));
893           dlib_ptr->name = xstrdup (direntry->d_name);
894           dlib_ptr->flag = flag;
895           dlib_ptr->osversion = osversion;
896           dlib_ptr->soname = soname;
897           dlib_ptr->is_link = is_link;
898           /* Add at head of list.  */
899           dlib_ptr->next = dlibs;
900           dlibs = dlib_ptr;
901         }
902     }
903
904   closedir (dir);
905
906   /* Now dlibs contains a list of all libs - add those to the cache
907      and created all symbolic links.  */
908   for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
909     {
910       /* Don't create links to links.  */
911       if (dlib_ptr->is_link == 0)
912         create_links (dir_name, entry->path, dlib_ptr->name,
913                       dlib_ptr->soname);
914       if (opt_build_cache)
915         add_to_cache (entry->path, dlib_ptr->soname, dlib_ptr->flag,
916                       dlib_ptr->osversion, hwcap);
917     }
918
919   /* Free all resources.  */
920   while (dlibs)
921     {
922       dlib_ptr = dlibs;
923       free (dlib_ptr->soname);
924       free (dlib_ptr->name);
925       dlibs = dlibs->next;
926       free (dlib_ptr);
927     }
928
929   if (opt_chroot && dir_name)
930     free (dir_name);
931 }
932
933 /* Search through all libraries.  */
934 static void
935 search_dirs (void)
936 {
937   struct dir_entry *entry;
938
939   for (entry = dir_entries; entry != NULL; entry = entry->next)
940     search_dir (entry);
941
942   /* Free all allocated memory.  */
943   while (dir_entries)
944     {
945       entry = dir_entries;
946       dir_entries = dir_entries->next;
947       free (entry->path);
948       free (entry);
949     }
950 }
951
952
953 static void parse_conf_include (const char *config_file, unsigned int lineno,
954                                 bool do_chroot, const char *pattern);
955
956 /* Parse configuration file.  */
957 static void
958 parse_conf (const char *filename, bool do_chroot)
959 {
960   FILE *file = NULL;
961   char *line = NULL;
962   const char *canon;
963   size_t len = 0;
964   unsigned int lineno;
965
966   if (do_chroot && opt_chroot)
967     {
968       canon = chroot_canon (opt_chroot, filename);
969       if (canon)
970         file = fopen (canon, "r");
971       else
972         canon = filename;
973     }
974   else
975     {
976       canon = filename;
977       file = fopen (filename, "r");
978     }
979
980   if (file == NULL)
981     {
982       error (0, errno, _("Can't open configuration file %s"), canon);
983       if (canon != filename)
984         free ((char *) canon);
985       return;
986     }
987
988   /* No threads use this stream.  */
989   __fsetlocking (file, FSETLOCKING_BYCALLER);
990
991   if (canon != filename)
992     free ((char *) canon);
993
994   lineno = 0;
995   do
996     {
997       ssize_t n = getline (&line, &len, file);
998       if (n < 0)
999         break;
1000
1001       ++lineno;
1002       if (line[n - 1] == '\n')
1003         line[n - 1] = '\0';
1004
1005       /* Because the file format does not know any form of quoting we
1006          can search forward for the next '#' character and if found
1007          make it terminating the line.  */
1008       *strchrnul (line, '#') = '\0';
1009
1010       /* Remove leading whitespace.  NUL is no whitespace character.  */
1011       char *cp = line;
1012       while (isspace (*cp))
1013         ++cp;
1014
1015       /* If the line is blank it is ignored.  */
1016       if (cp[0] == '\0')
1017         continue;
1018
1019       if (!strncmp (cp, "include", 7) && isblank (cp[7]))
1020         {
1021           char *dir;
1022           cp += 8;
1023           while ((dir = strsep (&cp, " \t")) != NULL)
1024             if (dir[0] != '\0')
1025               parse_conf_include (filename, lineno, do_chroot, dir);
1026         }
1027       else if (!strncasecmp (cp, "hwcap", 5) && isblank (cp[5]))
1028         {
1029           cp += 6;
1030           char *p, *name = NULL;
1031           unsigned long int n = strtoul (cp, &cp, 0);
1032           if (cp != NULL && isblank (*cp))
1033             while ((p = strsep (&cp, " \t")) != NULL)
1034               if (p[0] != '\0')
1035                 {
1036                   if (name == NULL)
1037                     name = p;
1038                   else
1039                     {
1040                       name = NULL;
1041                       break;
1042                     }
1043                 }
1044           if (name == NULL)
1045             {
1046               error (EXIT_FAILURE, 0, _("%s:%u: bad syntax in hwcap line"),
1047                      filename, lineno);
1048               break;
1049             }
1050           if (n >= (64 - _DL_FIRST_EXTRA))
1051             error (EXIT_FAILURE, 0,
1052                    _("%s:%u: hwcap index %lu above maximum %u"),
1053                    filename, lineno, n, 64 - _DL_FIRST_EXTRA - 1);
1054           if (hwcap_extra[n] == NULL)
1055             {
1056               for (unsigned long int h = 0; h < (64 - _DL_FIRST_EXTRA); ++h)
1057                 if (hwcap_extra[h] != NULL && !strcmp (name, hwcap_extra[h]))
1058                   error (EXIT_FAILURE, 0,
1059                          _("%s:%u: hwcap index %lu already defined as %s"),
1060                          filename, lineno, h, name);
1061               hwcap_extra[n] = xstrdup (name);
1062             }
1063           else
1064             {
1065               if (strcmp (name, hwcap_extra[n]))
1066                 error (EXIT_FAILURE, 0,
1067                        _("%s:%u: hwcap index %lu already defined as %s"),
1068                        filename, lineno, n, hwcap_extra[n]);
1069               if (opt_verbose)
1070                 error (0, 0, _("%s:%u: duplicate hwcap %lu %s"),
1071                        filename, lineno, n, name);
1072             }
1073         }
1074       else
1075         add_dir (cp);
1076     }
1077   while (!feof_unlocked (file));
1078
1079   /* Free buffer and close file.  */
1080   free (line);
1081   fclose (file);
1082 }
1083
1084 /* Handle one word in an `include' line, a glob pattern of additional
1085    config files to read.  */
1086 static void
1087 parse_conf_include (const char *config_file, unsigned int lineno,
1088                     bool do_chroot, const char *pattern)
1089 {
1090   if (opt_chroot && pattern[0] != '/')
1091     error (EXIT_FAILURE, 0,
1092            _("need absolute file name for configuration file when using -r"));
1093
1094   char *copy = NULL;
1095   if (pattern[0] != '/' && strchr (config_file, '/') != NULL)
1096     {
1097       if (asprintf (&copy, "%s/%s", dirname (strdupa (config_file)),
1098                     pattern) < 0)
1099         error (EXIT_FAILURE, 0, _("memory exhausted"));
1100       pattern = copy;
1101     }
1102
1103   glob64_t gl;
1104   int result;
1105   if (do_chroot && opt_chroot)
1106     {
1107       char *canon = chroot_canon (opt_chroot, pattern);
1108       result = glob64 (canon ?: pattern, 0, NULL, &gl);
1109       free (canon);
1110     }
1111   else
1112     result = glob64 (pattern, 0, NULL, &gl);
1113
1114   switch (result)
1115     {
1116     case 0:
1117       for (size_t i = 0; i < gl.gl_pathc; ++i)
1118         parse_conf (gl.gl_pathv[i], false);
1119       globfree64 (&gl);
1120       break;
1121
1122     case GLOB_NOMATCH:
1123       break;
1124
1125     case GLOB_NOSPACE:
1126       errno = ENOMEM;
1127     case GLOB_ABORTED:
1128       if (opt_verbose)
1129         error (0, errno, _("%s:%u: cannot read directory %s"),
1130                config_file, lineno, pattern);
1131       break;
1132
1133     default:
1134       abort ();
1135       break;
1136     }
1137
1138   if (copy)
1139     free (copy);
1140 }
1141
1142 /* Honour LD_HWCAP_MASK.  */
1143 static void
1144 set_hwcap (void)
1145 {
1146   char *mask = getenv ("LD_HWCAP_MASK");
1147
1148   if (mask)
1149     hwcap_mask = strtoul (mask, NULL, 0);
1150 }
1151
1152
1153 int
1154 main (int argc, char **argv)
1155 {
1156   int remaining;
1157
1158   /* Parse and process arguments.  */
1159   argp_parse (&argp, argc, argv, 0, &remaining, NULL);
1160
1161   /* Remaining arguments are additional directories if opt_manual_link
1162      is not set.  */
1163   if (remaining != argc && !opt_manual_link)
1164     {
1165       int i;
1166       for (i = remaining; i < argc; ++i)
1167         if (opt_build_cache && argv[i][0] != '/')
1168           error (EXIT_FAILURE, 0,
1169                  _("relative path `%s' used to build cache"),
1170                  argv[i]);
1171         else
1172           add_dir (argv[i]);
1173     }
1174
1175 #ifdef USE_TLS
1176   hwcap_extra[63 - _DL_FIRST_EXTRA] = "tls";
1177 #endif
1178
1179   set_hwcap ();
1180
1181   if (opt_chroot)
1182     {
1183       /* Normalize the path a bit, we might need it for printing later.  */
1184       char *endp = strchr (opt_chroot, '\0');
1185       while (endp > opt_chroot && endp[-1] == '/')
1186         --endp;
1187       *endp = '\0';
1188       if (endp == opt_chroot)
1189         opt_chroot = NULL;
1190
1191       if (opt_chroot)
1192         {
1193           /* It is faster to use chroot if we can.  */
1194           if (!chroot (opt_chroot))
1195             {
1196               if (chdir ("/"))
1197                 error (EXIT_FAILURE, errno, _("Can't chdir to /"));
1198               opt_chroot = NULL;
1199             }
1200         }
1201     }
1202
1203   if (cache_file == NULL)
1204     {
1205       cache_file = alloca (strlen (LD_SO_CACHE) + 1);
1206       strcpy (cache_file, LD_SO_CACHE);
1207     }
1208
1209   if (config_file == NULL)
1210     config_file = LD_SO_CONF;
1211
1212   if (opt_print_cache)
1213     {
1214       if (opt_chroot)
1215         {
1216           char *p = chroot_canon (opt_chroot, cache_file);
1217           if (p == NULL)
1218             error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"),
1219                    cache_file);
1220           cache_file = p;
1221         }
1222       print_cache (cache_file);
1223       if (opt_chroot)
1224         free (cache_file);
1225       exit (0);
1226     }
1227
1228   if (opt_chroot)
1229     {
1230       /* Canonicalize the directory name of cache_file, not cache_file,
1231          because we'll rename a temporary cache file to it.  */
1232       char *p = strrchr (cache_file, '/');
1233       char *canon = chroot_canon (opt_chroot,
1234                                   p ? (*p = '\0', cache_file) : "/");
1235
1236       if (canon == NULL)
1237         {
1238           error (EXIT_FAILURE, errno,
1239                  _("Can't open cache file directory %s\n"),
1240                  p ? cache_file : "/");
1241         }
1242
1243       if (p)
1244         ++p;
1245       else
1246         p = cache_file;
1247
1248       cache_file = alloca (strlen (canon) + strlen (p) + 2);
1249       sprintf (cache_file, "%s/%s", canon, p);
1250       free (canon);
1251     }
1252
1253   if (opt_manual_link)
1254     {
1255       /* Link all given libraries manually.  */
1256       int i;
1257
1258       for (i = remaining; i < argc; ++i)
1259         manual_link (argv[i]);
1260
1261       exit (0);
1262     }
1263
1264
1265   if (opt_build_cache)
1266     init_cache ();
1267
1268   if (!opt_only_cline)
1269     {
1270       parse_conf (config_file, true);
1271
1272       /* Always add the standard search paths.  */
1273       add_system_dir (SLIBDIR);
1274       if (strcmp (SLIBDIR, LIBDIR))
1275         add_system_dir (LIBDIR);
1276     }
1277
1278   search_dirs ();
1279
1280   if (opt_build_cache)
1281     save_cache (cache_file);
1282
1283   return 0;
1284 }