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