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