]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/ldconfig.c
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / elf / ldconfig.c
CommitLineData
2b778ceb 1/* Copyright (C) 1999-2021 Free Software Foundation, Inc.
591e1ffb
UD
2 This file is part of the GNU C Library.
3 Contributed by Andreas Jaeger <aj@suse.de>, 1999.
4
43bc8ac6 5 This program is free software; you can redistribute it and/or modify
2e2efe65
RM
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; version 2 of the License, or
8 (at your option) any later version.
591e1ffb 9
43bc8ac6 10 This program is distributed in the hope that it will be useful,
591e1ffb 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
43bc8ac6
UD
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
591e1ffb 14
43bc8ac6 15 You should have received a copy of the GNU General Public License
5a82c748 16 along with this program; if not, see <https://www.gnu.org/licenses/>. */
591e1ffb 17
ee600e3f 18#define PROCINFO_CLASS static
b44ac4f4 19#include <assert.h>
7b0d235c 20#include <alloca.h>
591e1ffb
UD
21#include <argp.h>
22#include <dirent.h>
9c95d361 23#include <elf.h>
591e1ffb
UD
24#include <error.h>
25#include <errno.h>
5a35dfca 26#include <inttypes.h>
591e1ffb 27#include <libintl.h>
11bf311e 28#include <locale.h>
f57ebe29 29#include <stdbool.h>
591e1ffb 30#include <stdio.h>
c96873d7 31#include <stdio_ext.h>
591e1ffb
UD
32#include <stdlib.h>
33#include <string.h>
34#include <unistd.h>
e054f494 35#include <stdint.h>
591e1ffb
UD
36#include <sys/fcntl.h>
37#include <sys/mman.h>
38#include <sys/stat.h>
39#include <sys/types.h>
8e115d80
RM
40#include <glob.h>
41#include <libgen.h>
591e1ffb 42
8f480b4b
RM
43#include <ldconfig.h>
44#include <dl-cache.h>
b44ac4f4 45#include <dl-hwcaps.h>
591e1ffb 46
8f480b4b 47#include <dl-procinfo.h>
591e1ffb 48
31563b68
FW
49/* This subpath in search path entries is always supported and
50 included in the cache for backwards compatibility. */
51#define TLS_SUBPATH "tls"
52
53/* The MSB of the hwcap field is set for objects in TLS_SUBPATH
54 directories. There is always TLS support in glibc, so the dynamic
55 loader does not check the bit directly. But more hwcap bits make a
56 an object more preferred, so the bit still has meaning. */
57#define TLS_HWCAP_BIT 63
ab1d521d 58
591e1ffb 59#ifndef LD_SO_CONF
8ca91b36 60# define LD_SO_CONF SYSCONFDIR "/ld.so.conf"
591e1ffb
UD
61#endif
62
63/* Get libc version number. */
64#include <version.h>
65
66#define PACKAGE _libc_intl_domainname
67
591e1ffb
UD
68static const struct
69{
70 const char *name;
71 int flag;
a986484f 72} lib_types[] =
591e1ffb
UD
73{
74 {"libc4", FLAG_LIBC4},
75 {"libc5", FLAG_ELF_LIBC5},
76 {"libc6", FLAG_ELF_LIBC6},
77 {"glibc2", FLAG_ELF_LIBC6}
45eca4d1 78};
591e1ffb
UD
79
80
81/* List of directories to handle. */
82struct dir_entry
83{
84 char *path;
85 int flag;
4ceae915
AJ
86 ino64_t ino;
87 dev_t dev;
b7176cc2
DD
88 const char *from_file;
89 int from_line;
b44ac4f4
FW
90
91 /* Non-NULL for subdirectories under a glibc-hwcaps subdirectory. */
92 struct glibc_hwcaps_subdirectory *hwcaps;
93
591e1ffb
UD
94 struct dir_entry *next;
95};
96
97/* The list is unsorted, contains no duplicates. Entries are added at
98 the end. */
99static struct dir_entry *dir_entries;
100
101/* Flags for different options. */
102/* Print Cache. */
c96873d7 103static int opt_print_cache;
591e1ffb
UD
104
105/* Be verbose. */
c96873d7 106int opt_verbose;
591e1ffb 107
45eca4d1 108/* Format to support. */
db07fae8 109enum opt_format opt_format = opt_format_new;
45eca4d1 110
591e1ffb
UD
111/* Build cache. */
112static int opt_build_cache = 1;
113
920b35c9
FW
114/* Enable symbolic link processing. If set, create or update symbolic
115 links, and remove stale symbolic links. */
591e1ffb
UD
116static int opt_link = 1;
117
118/* Only process directories specified on the command line. */
c96873d7 119static int opt_only_cline;
591e1ffb
UD
120
121/* Path to root for chroot. */
122static char *opt_chroot;
123
b85697f6 124/* Manually link given shared libraries. */
c96873d7 125static int opt_manual_link;
b85697f6 126
27d9ffda
UD
127/* Should we ignore an old auxiliary cache file? */
128static int opt_ignore_aux_cache;
129
591e1ffb 130/* Cache file to use. */
b4a555d6 131static char *cache_file;
591e1ffb
UD
132
133/* Configuration file. */
134static const char *config_file;
135
0cfbb8c6
UD
136/* Mask to use for important hardware capabilities. */
137static unsigned long int hwcap_mask = HWCAP_IMPORTANT;
138
591e1ffb
UD
139/* Name and version of program. */
140static void print_version (FILE *stream, struct argp_state *state);
141void (*argp_program_version_hook) (FILE *, struct argp_state *)
142 = print_version;
143
cbbcaf23
UD
144/* Function to print some extra text in the help message. */
145static char *more_help (int key, const char *text, void *input);
146
591e1ffb
UD
147/* Definitions of arguments for argp functions. */
148static const struct argp_option options[] =
149{
150 { "print-cache", 'p', NULL, 0, N_("Print cache"), 0},
151 { "verbose", 'v', NULL, 0, N_("Generate verbose messages"), 0},
152 { NULL, 'N', NULL, 0, N_("Don't build cache"), 0},
920b35c9 153 { NULL, 'X', NULL, 0, N_("Don't update symbolic links"), 0},
7864c09b
UD
154 { NULL, 'r', N_("ROOT"), 0, N_("Change to and use ROOT as root directory"), 0},
155 { NULL, 'C', N_("CACHE"), 0, N_("Use CACHE as cache file"), 0},
156 { NULL, 'f', N_("CONF"), 0, N_("Use CONF as configuration file"), 0},
591e1ffb 157 { NULL, 'n', NULL, 0, N_("Only process directories specified on the command line. Don't build cache."), 0},
b85697f6 158 { NULL, 'l', NULL, 0, N_("Manually link individual libraries."), 0},
cad64f77 159 { "format", 'c', N_("FORMAT"), 0, N_("Format to use: new (default), old, or compat"), 0},
27d9ffda 160 { "ignore-aux-cache", 'i', NULL, 0, N_("Ignore auxiliary cache file"), 0},
591e1ffb
UD
161 { NULL, 0, NULL, 0, NULL, 0 }
162};
163
11bf8ce1
UD
164#define PROCINFO_CLASS static
165#include <dl-procinfo.c>
166
591e1ffb
UD
167/* Short description of program. */
168static const char doc[] = N_("Configure Dynamic Linker Run Time Bindings.");
169
170/* Prototype for option handler. */
171static error_t parse_opt (int key, char *arg, struct argp_state *state);
172
173/* Data structure to communicate with argp functions. */
174static struct argp argp =
175{
cbbcaf23 176 options, parse_opt, NULL, doc, NULL, more_help, NULL
591e1ffb
UD
177};
178
a6c1c03a
AJ
179/* Check if string corresponds to an important hardware capability or
180 a platform. */
45eca4d1 181static int
a6c1c03a 182is_hwcap_platform (const char *name)
45eca4d1
UD
183{
184 int hwcap_idx = _dl_string_hwcap (name);
8ca91b36 185
13e23af7 186 /* Is this a normal hwcap for the machine like "fpu?" */
0cfbb8c6 187 if (hwcap_idx != -1 && ((1 << hwcap_idx) & hwcap_mask))
45eca4d1 188 return 1;
a6c1c03a 189
13e23af7 190 /* Is this a platform pseudo-hwcap like "i686?" */
a6c1c03a
AJ
191 hwcap_idx = _dl_string_platform (name);
192 if (hwcap_idx != -1)
193 return 1;
194
31563b68
FW
195 /* Backwards-compatibility for the "tls" subdirectory. */
196 if (strcmp (name, TLS_SUBPATH) == 0)
197 return 1;
676fde70 198
45eca4d1
UD
199 return 0;
200}
201
a6c1c03a
AJ
202/* Get hwcap (including platform) encoding of path. */
203static uint64_t
45eca4d1
UD
204path_hwcap (const char *path)
205{
206 char *str = xstrdup (path);
207 char *ptr;
a6c1c03a
AJ
208 uint64_t hwcap = 0;
209 uint64_t h;
45eca4d1
UD
210
211 size_t len;
212
213 len = strlen (str);
214 if (str[len] == '/')
215 str[len] = '\0';
216
217 /* Search pathname from the end and check for hwcap strings. */
218 for (;;)
219 {
220 ptr = strrchr (str, '/');
221
222 if (ptr == NULL)
223 break;
224
a6c1c03a 225 h = _dl_string_hwcap (ptr + 1);
45eca4d1 226
59553897
UD
227 if (h == (uint64_t) -1)
228 {
229 h = _dl_string_platform (ptr + 1);
230 if (h == (uint64_t) -1)
676fde70 231 {
31563b68
FW
232 if (strcmp (ptr + 1, TLS_SUBPATH) == 0)
233 h = TLS_HWCAP_BIT;
234 else
676fde70
UD
235 break;
236 }
59553897 237 }
a6c1c03a 238 hwcap += 1ULL << h;
591e1ffb 239
45eca4d1
UD
240 /* Search the next part of the path. */
241 *ptr = '\0';
242 }
243
244 free (str);
245 return hwcap;
246}
591e1ffb
UD
247
248/* Handle program arguments. */
249static error_t
250parse_opt (int key, char *arg, struct argp_state *state)
251{
252 switch (key)
253 {
254 case 'C':
255 cache_file = arg;
27d9ffda
UD
256 /* Ignore auxiliary cache since we use non-standard cache. */
257 opt_ignore_aux_cache = 1;
591e1ffb
UD
258 break;
259 case 'f':
260 config_file = arg;
261 break;
27d9ffda
UD
262 case 'i':
263 opt_ignore_aux_cache = 1;
264 break;
b85697f6
UD
265 case 'l':
266 opt_manual_link = 1;
267 break;
591e1ffb
UD
268 case 'N':
269 opt_build_cache = 0;
270 break;
271 case 'n':
272 opt_build_cache = 0;
273 opt_only_cline = 1;
274 break;
275 case 'p':
276 opt_print_cache = 1;
277 break;
278 case 'r':
279 opt_chroot = arg;
280 break;
281 case 'v':
282 opt_verbose = 1;
283 break;
284 case 'X':
285 opt_link = 0;
286 break;
45eca4d1
UD
287 case 'c':
288 if (strcmp (arg, "old") == 0)
db07fae8 289 opt_format = opt_format_old;
45eca4d1 290 else if (strcmp (arg, "compat") == 0)
db07fae8 291 opt_format = opt_format_compat;
45eca4d1 292 else if (strcmp (arg, "new") == 0)
db07fae8 293 opt_format = opt_format_new;
45eca4d1 294 break;
591e1ffb
UD
295 default:
296 return ARGP_ERR_UNKNOWN;
297 }
298
299 return 0;
300}
301
cbbcaf23
UD
302/* Print bug-reporting information in the help message. */
303static char *
304more_help (int key, const char *text, void *input)
305{
8b748aed 306 char *tp = NULL;
cbbcaf23
UD
307 switch (key)
308 {
309 case ARGP_KEY_HELP_EXTRA:
310 /* We print some extra information. */
8b748aed 311 if (asprintf (&tp, gettext ("\
cbbcaf23 312For bug reporting instructions, please see:\n\
8b748aed
JM
313%s.\n"), REPORT_BUGS_TO) < 0)
314 return NULL;
315 return tp;
cbbcaf23
UD
316 default:
317 break;
318 }
319 return (char *) text;
320}
321
591e1ffb
UD
322/* Print the version information. */
323static void
324print_version (FILE *stream, struct argp_state *state)
325{
8b748aed 326 fprintf (stream, "ldconfig %s%s\n", PKGVERSION, VERSION);
591e1ffb
UD
327 fprintf (stream, gettext ("\
328Copyright (C) %s Free Software Foundation, Inc.\n\
329This is free software; see the source for copying conditions. There is NO\n\
330warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
5f72f980 331"), "2020");
591e1ffb
UD
332 fprintf (stream, gettext ("Written by %s.\n"),
333 "Andreas Jaeger");
334}
335
5e598c2b
FW
336/* Allocate a new subdirectory with full path PATH under ENTRY, using
337 inode data from *ST. */
338static struct dir_entry *
339new_sub_entry (const struct dir_entry *entry, const char *path,
340 const struct stat64 *st)
341{
342 struct dir_entry *new_entry = xmalloc (sizeof (struct dir_entry));
343 new_entry->from_file = entry->from_file;
344 new_entry->from_line = entry->from_line;
345 new_entry->path = xstrdup (path);
346 new_entry->flag = entry->flag;
b44ac4f4 347 new_entry->hwcaps = NULL;
5e598c2b
FW
348 new_entry->next = NULL;
349 new_entry->ino = st->st_ino;
350 new_entry->dev = st->st_dev;
351 return new_entry;
352}
353
b44ac4f4
FW
354/* Add a single directory entry. Return true if the directory is
355 actually added (because it is not a duplicate). */
356static bool
a8fd59b0
AJ
357add_single_dir (struct dir_entry *entry, int verbose)
358{
359 struct dir_entry *ptr, *prev;
b44ac4f4 360 bool added = true;
a8fd59b0
AJ
361
362 ptr = dir_entries;
363 prev = ptr;
364 while (ptr != NULL)
365 {
366 /* Check for duplicates. */
4ceae915 367 if (ptr->ino == entry->ino && ptr->dev == entry->dev)
a8fd59b0
AJ
368 {
369 if (opt_verbose && verbose)
b7176cc2
DD
370 {
371 error (0, 0, _("Path `%s' given more than once"), entry->path);
372 fprintf (stderr, _("(from %s:%d and %s:%d)\n"),
373 entry->from_file, entry->from_line,
374 ptr->from_file, ptr->from_line);
375 }
a8fd59b0
AJ
376 /* Use the newer information. */
377 ptr->flag = entry->flag;
4ceae915 378 free (entry->path);
a8fd59b0 379 free (entry);
b44ac4f4 380 added = false;
a8fd59b0
AJ
381 break;
382 }
383 prev = ptr;
384 ptr = ptr->next;
385 }
386 /* Is this the first entry? */
387 if (ptr == NULL && dir_entries == NULL)
388 dir_entries = entry;
389 else if (ptr == NULL)
390 prev->next = entry;
b44ac4f4
FW
391 return added;
392}
393
394/* Check if PATH contains a "glibc-hwcaps" subdirectory. If so, queue
395 its subdirectories for glibc-hwcaps processing. */
396static void
397add_glibc_hwcaps_subdirectories (struct dir_entry *entry, const char *path)
398{
399 /* glibc-hwcaps subdirectories do not nest. */
400 assert (entry->hwcaps == NULL);
401
402 char *glibc_hwcaps;
403 if (asprintf (&glibc_hwcaps, "%s/" GLIBC_HWCAPS_SUBDIRECTORY, path) < 0)
404 error (EXIT_FAILURE, errno, _("Could not form glibc-hwcaps path"));
405
406 DIR *dir = opendir (glibc_hwcaps);
407 if (dir != NULL)
408 {
409 while (true)
410 {
411 errno = 0;
412 struct dirent64 *e = readdir64 (dir);
413 if (e == NULL)
414 {
415 if (errno == 0)
416 break;
417 else
418 error (EXIT_FAILURE, errno, _("Listing directory %s"), path);
419 }
420
421 /* Ignore hidden subdirectories, including "." and "..", and
422 regular files. File names containing a ':' cannot be
423 looked up by the dynamic loader, so skip those as
424 well. */
425 if (e->d_name[0] == '.' || e->d_type == DT_REG
426 || strchr (e->d_name, ':') != NULL)
427 continue;
428
429 /* See if this entry eventually resolves to a directory. */
430 struct stat64 st;
431 if (fstatat64 (dirfd (dir), e->d_name, &st, 0) < 0)
432 /* Ignore unreadable entries. */
433 continue;
434
435 if (S_ISDIR (st.st_mode))
436 {
437 /* This is a directory, so it needs to be scanned for
438 libraries, associated with the hwcaps implied by the
439 subdirectory name. */
440 char *new_path;
441 if (asprintf (&new_path, "%s/" GLIBC_HWCAPS_SUBDIRECTORY "/%s",
442 /* Use non-canonicalized path here. */
443 entry->path, e->d_name) < 0)
444 error (EXIT_FAILURE, errno,
445 _("Could not form glibc-hwcaps path"));
446 struct dir_entry *new_entry = new_sub_entry (entry, new_path,
447 &st);
448 free (new_path);
449 new_entry->hwcaps = new_glibc_hwcaps_subdirectory (e->d_name);
450 add_single_dir (new_entry, 0);
451 }
452 }
453
454 closedir (dir);
455 }
456
457 free (glibc_hwcaps);
a8fd59b0
AJ
458}
459
591e1ffb
UD
460/* Add one directory to the list of directories to process. */
461static void
b7176cc2 462add_dir_1 (const char *line, const char *from_file, int from_line)
591e1ffb 463{
591e1ffb 464 unsigned int i;
539842a4 465 struct dir_entry *entry = xmalloc (sizeof (struct dir_entry));
b44ac4f4 466 entry->hwcaps = NULL;
591e1ffb 467 entry->next = NULL;
45eca4d1 468
b7176cc2
DD
469 entry->from_file = strdup (from_file);
470 entry->from_line = from_line;
471
591e1ffb
UD
472 /* Search for an '=' sign. */
473 entry->path = xstrdup (line);
539842a4 474 char *equal_sign = strchr (entry->path, '=');
591e1ffb
UD
475 if (equal_sign)
476 {
477 *equal_sign = '\0';
478 ++equal_sign;
479 entry->flag = FLAG_ANY;
a986484f 480 for (i = 0; i < sizeof (lib_types) / sizeof (lib_types[0]); ++i)
591e1ffb
UD
481 if (strcmp (equal_sign, lib_types[i].name) == 0)
482 {
483 entry->flag = lib_types[i].flag;
484 break;
485 }
486 if (entry->flag == FLAG_ANY)
487 error (0, 0, _("%s is not a known library type"), equal_sign);
488 }
489 else
490 {
491 entry->flag = FLAG_ANY;
492 }
493
69acbe9f 494 /* Canonify path: for now only remove leading and trailing
00ee369c
AS
495 whitespace and the trailing slashes. */
496 i = strlen (entry->path);
69acbe9f 497
00ee369c
AS
498 while (i > 0 && isspace (entry->path[i - 1]))
499 entry->path[--i] = '\0';
69acbe9f 500
00ee369c
AS
501 while (i > 0 && entry->path[i - 1] == '/')
502 entry->path[--i] = '\0';
503
504 if (i == 0)
505 return;
45eca4d1 506
539842a4
UD
507 char *path = entry->path;
508 if (opt_chroot)
509 path = chroot_canon (opt_chroot, path);
510
511 struct stat64 stat_buf;
512 if (path == NULL || stat64 (path, &stat_buf))
4ceae915 513 {
8645ad47
AJ
514 if (opt_verbose)
515 error (0, errno, _("Can't stat %s"), entry->path);
4ceae915
AJ
516 free (entry->path);
517 free (entry);
4ceae915 518 }
539842a4
UD
519 else
520 {
521 entry->ino = stat_buf.st_ino;
522 entry->dev = stat_buf.st_dev;
4ceae915 523
b44ac4f4
FW
524 if (add_single_dir (entry, 1))
525 /* Add glibc-hwcaps subdirectories if present. */
526 add_glibc_hwcaps_subdirectories (entry, path);
539842a4 527 }
4ceae915 528
539842a4
UD
529 if (opt_chroot)
530 free (path);
591e1ffb
UD
531}
532
b7176cc2
DD
533static void
534add_dir (const char *line)
535{
536 add_dir_1 (line, "<builtin>", 0);
537}
591e1ffb 538
b4a555d6
UD
539static int
540chroot_stat (const char *real_path, const char *path, struct stat64 *st)
541{
542 int ret;
543 char *canon_path;
544
545 if (!opt_chroot)
546 return stat64 (real_path, st);
547
548 ret = lstat64 (real_path, st);
549 if (ret || !S_ISLNK (st->st_mode))
550 return ret;
551
552 canon_path = chroot_canon (opt_chroot, path);
553 if (canon_path == NULL)
554 return -1;
555
556 ret = stat64 (canon_path, st);
557 free (canon_path);
558 return ret;
559}
560
591e1ffb
UD
561/* Create a symbolic link from soname to libname in directory path. */
562static void
b4a555d6
UD
563create_links (const char *real_path, const char *path, const char *libname,
564 const char *soname)
591e1ffb 565{
7b0d235c 566 char *full_libname, *full_soname;
b4a555d6
UD
567 char *real_full_libname, *real_full_soname;
568 struct stat64 stat_lib, stat_so, lstat_so;
591e1ffb
UD
569 int do_link = 1;
570 int do_remove = 1;
571 /* XXX: The logics in this function should be simplified. */
45eca4d1 572
591e1ffb 573 /* Get complete path. */
7b0d235c 574 full_libname = alloca (strlen (path) + strlen (libname) + 2);
7c545dbe 575 full_soname = alloca (strlen (path) + strlen (soname) + 2);
7b0d235c
AJ
576 sprintf (full_libname, "%s/%s", path, libname);
577 sprintf (full_soname, "%s/%s", path, soname);
b4a555d6
UD
578 if (opt_chroot)
579 {
580 real_full_libname = alloca (strlen (real_path) + strlen (libname) + 2);
7c545dbe 581 real_full_soname = alloca (strlen (real_path) + strlen (soname) + 2);
b4a555d6
UD
582 sprintf (real_full_libname, "%s/%s", real_path, libname);
583 sprintf (real_full_soname, "%s/%s", real_path, soname);
584 }
585 else
586 {
587 real_full_libname = full_libname;
588 real_full_soname = full_soname;
589 }
591e1ffb
UD
590
591 /* Does soname already exist and point to the right library? */
b4a555d6 592 if (chroot_stat (real_full_soname, full_soname, &stat_so) == 0)
591e1ffb 593 {
b4a555d6 594 if (chroot_stat (real_full_libname, full_libname, &stat_lib))
591e1ffb
UD
595 {
596 error (0, 0, _("Can't stat %s\n"), full_libname);
597 return;
598 }
599 if (stat_lib.st_dev == stat_so.st_dev
600 && stat_lib.st_ino == stat_so.st_ino)
601 /* Link is already correct. */
602 do_link = 0;
b4a555d6 603 else if (lstat64 (full_soname, &lstat_so) == 0
591e1ffb
UD
604 && !S_ISLNK (lstat_so.st_mode))
605 {
606 error (0, 0, _("%s is not a symbolic link\n"), full_soname);
607 do_link = 0;
608 do_remove = 0;
609 }
610 }
b4a555d6 611 else if (lstat64 (real_full_soname, &lstat_so) != 0
591e1ffb
UD
612 || !S_ISLNK (lstat_so.st_mode))
613 /* Unless it is a stale symlink, there is no need to remove. */
614 do_remove = 0;
615
616 if (opt_verbose)
617 printf ("\t%s -> %s", soname, libname);
618
619 if (do_link && opt_link)
620 {
621 /* Remove old link. */
622 if (do_remove)
b4a555d6 623 if (unlink (real_full_soname))
591e1ffb
UD
624 {
625 error (0, 0, _("Can't unlink %s"), full_soname);
626 do_link = 0;
627 }
628 /* Create symbolic link. */
b4a555d6 629 if (do_link && symlink (libname, real_full_soname))
591e1ffb
UD
630 {
631 error (0, 0, _("Can't link %s to %s"), full_soname, libname);
632 do_link = 0;
633 }
634 if (opt_verbose)
635 {
636 if (do_link)
637 fputs (_(" (changed)\n"), stdout);
638 else
639 fputs (_(" (SKIPPED)\n"), stdout);
640 }
641 }
642 else if (opt_verbose)
643 fputs ("\n", stdout);
644}
645
b85697f6
UD
646/* Manually link the given library. */
647static void
648manual_link (char *library)
649{
650 char *path;
b4a555d6
UD
651 char *real_path;
652 char *real_library;
b85697f6
UD
653 char *libname;
654 char *soname;
b4a555d6 655 struct stat64 stat_buf;
b85697f6 656 int flag;
a986484f 657 unsigned int osversion;
b85697f6
UD
658
659 /* Prepare arguments for create_links call. Split library name in
660 directory and filename first. Since path is allocated, we've got
661 to be careful to free at the end. */
662 path = xstrdup (library);
663 libname = strrchr (path, '/');
664
665 if (libname)
666 {
667 /* Successfully split names. Check if path is just "/" to avoid
27d9ffda 668 an empty path. */
b85697f6
UD
669 if (libname == path)
670 {
671 libname = library + 1;
672 path = xrealloc (path, 2);
673 strcpy (path, "/");
674 }
675 else
676 {
677 *libname = '\0';
678 ++libname;
679 }
680 }
681 else
682 {
683 /* There's no path, construct one. */
684 libname = library;
685 path = xrealloc (path, 2);
686 strcpy (path, ".");
687 }
688
b4a555d6
UD
689 if (opt_chroot)
690 {
691 real_path = chroot_canon (opt_chroot, path);
692 if (real_path == NULL)
693 {
694 error (0, errno, _("Can't find %s"), path);
695 free (path);
696 return;
697 }
698 real_library = alloca (strlen (real_path) + strlen (libname) + 2);
699 sprintf (real_library, "%s/%s", real_path, libname);
700 }
701 else
702 {
703 real_path = path;
704 real_library = library;
705 }
706
b85697f6 707 /* Do some sanity checks first. */
b4a555d6 708 if (lstat64 (real_library, &stat_buf))
b85697f6 709 {
11bf311e 710 error (0, errno, _("Cannot lstat %s"), library);
b85697f6
UD
711 free (path);
712 return;
713 }
714 /* We don't want links here! */
715 else if (!S_ISREG (stat_buf.st_mode))
716 {
717 error (0, 0, _("Ignored file %s since it is not a regular file."),
718 library);
719 free (path);
720 return;
721 }
27d9ffda 722
a986484f 723 if (process_file (real_library, library, libname, &flag, &osversion,
27d9ffda 724 &soname, 0, &stat_buf))
b85697f6
UD
725 {
726 error (0, 0, _("No link created since soname could not be found for %s"),
727 library);
728 free (path);
729 return;
730 }
27d9ffda
UD
731 if (soname == NULL)
732 soname = implicit_soname (libname, flag);
b4a555d6 733 create_links (real_path, path, libname, soname);
b85697f6
UD
734 free (soname);
735 free (path);
736}
737
738
591e1ffb
UD
739/* Read a whole directory and search for libraries.
740 The purpose is two-fold:
741 - search for libraries which will be added to the cache
742 - create symbolic links to the soname for each library
743
744 This has to be done separatly for each directory.
45eca4d1 745
591e1ffb
UD
746 To keep track of which libraries to add to the cache and which
747 links to create, we save a list of all libraries.
748
749 The algorithm is basically:
750 for all libraries in the directory do
751 get soname of library
752 if soname is already in list
753 if new library is newer, replace entry
754 otherwise ignore this library
755 otherwise add library to list
45eca4d1 756
591e1ffb
UD
757 For example, if the two libraries libxy.so.1.1 and libxy.so.1.2
758 exist and both have the same soname, e.g. libxy.so, a symbolic link
759 is created from libxy.so.1.2 (the newer one) to libxy.so.
760 libxy.so.1.2 and libxy.so are added to the cache - but not
761 libxy.so.1.1. */
762
763/* Information for one library. */
45eca4d1 764struct dlib_entry
591e1ffb
UD
765{
766 char *name;
767 char *soname;
768 int flag;
769 int is_link;
a986484f 770 unsigned int osversion;
591e1ffb
UD
771 struct dlib_entry *next;
772};
773
774
775static void
776search_dir (const struct dir_entry *entry)
777{
b44ac4f4
FW
778 uint64_t hwcap;
779 if (entry->hwcaps == NULL)
45eca4d1 780 {
b44ac4f4
FW
781 hwcap = path_hwcap (entry->path);
782 if (opt_verbose)
783 {
784 if (hwcap != 0)
785 printf ("%s: (hwcap: %#.16" PRIx64 ")", entry->path, hwcap);
786 else
787 printf ("%s:", entry->path);
788 }
45eca4d1 789 }
b44ac4f4
FW
790 else
791 {
792 hwcap = 0;
793 if (opt_verbose)
794 printf ("%s: (hwcap: \"%s\")", entry->path,
795 glibc_hwcaps_subdirectory_name (entry->hwcaps));
796 }
797 if (opt_verbose)
798 printf (_(" (from %s:%d)\n"), entry->from_file, entry->from_line);
45eca4d1 799
27d9ffda
UD
800 char *dir_name;
801 char *real_file_name;
802 size_t real_file_name_len;
803 size_t file_name_len = PATH_MAX;
804 char *file_name = alloca (file_name_len);
b4a555d6
UD
805 if (opt_chroot)
806 {
807 dir_name = chroot_canon (opt_chroot, entry->path);
808 real_file_name_len = PATH_MAX;
809 real_file_name = alloca (real_file_name_len);
810 }
811 else
812 {
813 dir_name = entry->path;
814 real_file_name_len = 0;
815 real_file_name = file_name;
816 }
817
27d9ffda 818 DIR *dir;
b4a555d6 819 if (dir_name == NULL || (dir = opendir (dir_name)) == NULL)
591e1ffb
UD
820 {
821 if (opt_verbose)
822 error (0, errno, _("Can't open directory %s"), entry->path);
b4a555d6
UD
823 if (opt_chroot && dir_name)
824 free (dir_name);
591e1ffb
UD
825 return;
826 }
45eca4d1 827
27d9ffda
UD
828 struct dirent64 *direntry;
829 struct dlib_entry *dlibs = NULL;
2b510e91 830 while ((direntry = readdir64 (dir)) != NULL)
591e1ffb
UD
831 {
832 int flag;
591e1ffb
UD
833 /* We only look at links and regular files. */
834 if (direntry->d_type != DT_UNKNOWN
835 && direntry->d_type != DT_LNK
45eca4d1
UD
836 && direntry->d_type != DT_REG
837 && direntry->d_type != DT_DIR)
591e1ffb 838 continue;
45eca4d1 839 /* Does this file look like a shared library or is it a hwcap
b44ac4f4
FW
840 subdirectory (if not already processing a glibc-hwcaps
841 subdirectory)? The dynamic linker is also considered as
45eca4d1
UD
842 shared library. */
843 if (((strncmp (direntry->d_name, "lib", 3) != 0
844 && strncmp (direntry->d_name, "ld-", 3) != 0)
845 || strstr (direntry->d_name, ".so") == NULL)
4484b9e2 846 && (direntry->d_type == DT_REG
b44ac4f4
FW
847 || (entry->hwcaps == NULL
848 && !is_hwcap_platform (direntry->d_name))))
591e1ffb 849 continue;
27d9ffda
UD
850
851 size_t len = strlen (direntry->d_name);
3858bf28
RM
852 /* Skip temporary files created by the prelink program. Files with
853 names like these are never really DSOs we want to look at. */
854 if (len >= sizeof (".#prelink#") - 1)
855 {
856 if (strcmp (direntry->d_name + len - sizeof (".#prelink#") + 1,
857 ".#prelink#") == 0)
858 continue;
859 if (len >= sizeof (".#prelink#.XXXXXX") - 1
860 && memcmp (direntry->d_name + len - sizeof (".#prelink#.XXXXXX")
861 + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0)
862 continue;
863 }
30a3aa75 864 len += strlen (entry->path) + 2;
7b0d235c 865 if (len > file_name_len)
591e1ffb 866 {
30a3aa75 867 file_name_len = len;
7b0d235c 868 file_name = alloca (file_name_len);
b4a555d6
UD
869 if (!opt_chroot)
870 real_file_name = file_name;
871 }
872 sprintf (file_name, "%s/%s", entry->path, direntry->d_name);
873 if (opt_chroot)
874 {
30a3aa75 875 len = strlen (dir_name) + strlen (direntry->d_name) + 2;
b4a555d6
UD
876 if (len > real_file_name_len)
877 {
30a3aa75 878 real_file_name_len = len;
b4a555d6
UD
879 real_file_name = alloca (real_file_name_len);
880 }
881 sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name);
591e1ffb 882 }
27d9ffda
UD
883
884 struct stat64 lstat_buf;
27d9ffda 885 /* We optimize and try to do the lstat call only if needed. */
7c3002f0 886 if (direntry->d_type != DT_UNKNOWN)
4ceae915 887 lstat_buf.st_mode = DTTOIF (direntry->d_type);
7c3002f0 888 else
a1ffb40e 889 if (__glibc_unlikely (lstat64 (real_file_name, &lstat_buf)))
7c3002f0 890 {
95ce33a5 891 error (0, errno, _("Cannot lstat %s"), file_name);
7c3002f0
UD
892 continue;
893 }
894
27d9ffda 895 struct stat64 stat_buf;
b44ac4f4 896 bool is_dir;
27d9ffda 897 int is_link = S_ISLNK (lstat_buf.st_mode);
4ceae915 898 if (is_link)
27d9ffda 899 {
4ceae915
AJ
900 /* In case of symlink, we check if the symlink refers to
901 a directory. */
7dee2660
UD
902 char *target_name = real_file_name;
903 if (opt_chroot)
904 {
905 target_name = chroot_canon (opt_chroot, file_name);
906 if (target_name == NULL)
907 {
908 if (strstr (file_name, ".so") == NULL)
909 error (0, 0, _("Input file %s not found.\n"), file_name);
910 continue;
911 }
912 }
a1ffb40e 913 if (__glibc_unlikely (stat64 (target_name, &stat_buf)))
4ceae915 914 {
8645ad47 915 if (opt_verbose)
95ce33a5 916 error (0, errno, _("Cannot stat %s"), file_name);
647eb037
UD
917
918 /* Remove stale symlinks. */
920b35c9 919 if (opt_link && strstr (direntry->d_name, ".so."))
647eb037 920 unlink (real_file_name);
4ceae915
AJ
921 continue;
922 }
923 is_dir = S_ISDIR (stat_buf.st_mode);
27d9ffda
UD
924
925 /* lstat_buf is later stored, update contents. */
926 lstat_buf.st_dev = stat_buf.st_dev;
927 lstat_buf.st_ino = stat_buf.st_ino;
928 lstat_buf.st_size = stat_buf.st_size;
929 lstat_buf.st_ctime = stat_buf.st_ctime;
4ceae915
AJ
930 }
931 else
932 is_dir = S_ISDIR (lstat_buf.st_mode);
933
b44ac4f4
FW
934 /* No descending into subdirectories if this directory is a
935 glibc-hwcaps subdirectory (which are not recursive). */
936 if (entry->hwcaps == NULL
937 && is_dir && is_hwcap_platform (direntry->d_name))
45eca4d1 938 {
27d9ffda
UD
939 if (!is_link
940 && direntry->d_type != DT_UNKNOWN
941 && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
4ceae915 942 {
27d9ffda 943 error (0, errno, _("Cannot lstat %s"), file_name);
27d9ffda 944 continue;
4ceae915 945 }
5e598c2b
FW
946
947 /* Handle subdirectory later. */
948 struct dir_entry *new_entry = new_sub_entry (entry, file_name,
949 &lstat_buf);
a8fd59b0 950 add_single_dir (new_entry, 0);
45eca4d1
UD
951 continue;
952 }
0f843f89 953 else if (!S_ISREG (lstat_buf.st_mode) && !is_link)
591e1ffb
UD
954 continue;
955
27d9ffda 956 char *real_name;
b4a555d6
UD
957 if (opt_chroot && is_link)
958 {
959 real_name = chroot_canon (opt_chroot, file_name);
960 if (real_name == NULL)
961 {
962 if (strstr (file_name, ".so") == NULL)
963 error (0, 0, _("Input file %s not found.\n"), file_name);
964 continue;
965 }
966 }
967 else
968 real_name = real_file_name;
591e1ffb 969
27d9ffda
UD
970 /* Call lstat64 if not done yet. */
971 if (!is_link
972 && direntry->d_type != DT_UNKNOWN
973 && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
b4a555d6 974 {
27d9ffda 975 error (0, errno, _("Cannot lstat %s"), file_name);
b4a555d6
UD
976 continue;
977 }
27d9ffda
UD
978
979 /* First search whether the auxiliary cache contains this
980 library already and it's not changed. */
981 char *soname;
982 unsigned int osversion;
983 if (!search_aux_cache (&lstat_buf, &flag, &osversion, &soname))
984 {
985 if (process_file (real_name, file_name, direntry->d_name, &flag,
986 &osversion, &soname, is_link, &lstat_buf))
987 {
988 if (real_name != real_file_name)
989 free (real_name);
990 continue;
991 }
992 else if (opt_build_cache)
993 add_to_aux_cache (&lstat_buf, flag, osversion, soname);
994 }
b4a555d6 995
27d9ffda
UD
996 if (soname == NULL)
997 soname = implicit_soname (direntry->d_name, flag);
82d8607d
UD
998
999 /* A link may just point to itself. */
591e1ffb
UD
1000 if (is_link)
1001 {
97114a38
CD
1002 /* If the path the link points to isn't its soname or it is not
1003 the .so symlink for ld(1), we treat it as a normal file.
1004
1005 You should always do this:
1006
1007 libfoo.so -> SONAME -> Arbitrary package-chosen name.
1008
1009 e.g. libfoo.so -> libfoo.so.1 -> libfooimp.so.9.99.
1010 Given a SONAME of libfoo.so.1.
1011
1012 You should *never* do this:
1013
1014 libfoo.so -> libfooimp.so.9.99
1015
1016 If you do, and your SONAME is libfoo.so.1, then libfoo.so
1017 fails to point at the SONAME. In that case ldconfig may consider
1018 libfoo.so as another implementation of SONAME and will create
1019 symlinks against it causing problems when you try to upgrade
1020 or downgrade. The problems will arise because ldconfig will,
1021 depending on directory ordering, creat symlinks against libfoo.so
1022 e.g. libfoo.so.1.2 -> libfoo.so, but when libfoo.so is removed
1023 (typically by the removal of a development pacakge not required
1024 for the runtime) it will break the libfoo.so.1.2 symlink and the
1025 application will fail to start. */
2fe98a4a 1026 const char *real_base_name = basename (real_file_name);
82d8607d
UD
1027
1028 if (strcmp (real_base_name, soname) != 0)
1029 {
1030 len = strlen (real_base_name);
1031 if (len < strlen (".so")
1032 || strcmp (real_base_name + len - strlen (".so"), ".so") != 0
1033 || strncmp (real_base_name, soname, len) != 0)
1034 is_link = 0;
1035 }
27d9ffda 1036 }
45eca4d1 1037
395412a0
UD
1038 if (real_name != real_file_name)
1039 free (real_name);
1040
82d8607d
UD
1041 if (is_link)
1042 {
1043 free (soname);
1044 soname = xstrdup (direntry->d_name);
1045 }
1046
591e1ffb
UD
1047 if (flag == FLAG_ELF
1048 && (entry->flag == FLAG_ELF_LIBC5
1049 || entry->flag == FLAG_ELF_LIBC6))
1050 flag = entry->flag;
27d9ffda 1051
591e1ffb
UD
1052 /* Some sanity checks to print warnings. */
1053 if (opt_verbose)
1054 {
1055 if (flag == FLAG_ELF_LIBC5 && entry->flag != FLAG_ELF_LIBC5
1056 && entry->flag != FLAG_ANY)
7b0d235c 1057 error (0, 0, _("libc5 library %s in wrong directory"), file_name);
591e1ffb
UD
1058 if (flag == FLAG_ELF_LIBC6 && entry->flag != FLAG_ELF_LIBC6
1059 && entry->flag != FLAG_ANY)
7b0d235c 1060 error (0, 0, _("libc6 library %s in wrong directory"), file_name);
591e1ffb
UD
1061 if (flag == FLAG_LIBC4 && entry->flag != FLAG_LIBC4
1062 && entry->flag != FLAG_ANY)
7b0d235c 1063 error (0, 0, _("libc4 library %s in wrong directory"), file_name);
591e1ffb 1064 }
45eca4d1 1065
591e1ffb 1066 /* Add library to list. */
27d9ffda 1067 struct dlib_entry *dlib_ptr;
591e1ffb
UD
1068 for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
1069 {
1070 /* Is soname already in list? */
1071 if (strcmp (dlib_ptr->soname, soname) == 0)
1072 {
1073 /* Prefer a file to a link, otherwise check which one
1074 is newer. */
1075 if ((!is_link && dlib_ptr->is_link)
1076 || (is_link == dlib_ptr->is_link
45eca4d1 1077 && _dl_cache_libcmp (dlib_ptr->name, direntry->d_name) < 0))
591e1ffb
UD
1078 {
1079 /* It's newer - add it. */
1080 /* Flag should be the same - sanity check. */
1081 if (dlib_ptr->flag != flag)
1082 {
1083 if (dlib_ptr->flag == FLAG_ELF
1084 && (flag == FLAG_ELF_LIBC5 || flag == FLAG_ELF_LIBC6))
1085 dlib_ptr->flag = flag;
1086 else if ((dlib_ptr->flag == FLAG_ELF_LIBC5
1087 || dlib_ptr->flag == FLAG_ELF_LIBC6)
1088 && flag == FLAG_ELF)
1089 dlib_ptr->flag = flag;
1090 else
1091 error (0, 0, _("libraries %s and %s in directory %s have same soname but different type."),
27d9ffda
UD
1092 dlib_ptr->name, direntry->d_name,
1093 entry->path);
591e1ffb
UD
1094 }
1095 free (dlib_ptr->name);
1096 dlib_ptr->name = xstrdup (direntry->d_name);
1097 dlib_ptr->is_link = is_link;
27d9ffda 1098 dlib_ptr->osversion = osversion;
591e1ffb
UD
1099 }
1100 /* Don't add this library, abort loop. */
1101 /* Also free soname, since it's dynamically allocated. */
1102 free (soname);
1103 break;
1104 }
1105 }
1106 /* Add the library if it's not already in. */
1107 if (dlib_ptr == NULL)
1108 {
1109 dlib_ptr = (struct dlib_entry *)xmalloc (sizeof (struct dlib_entry));
1110 dlib_ptr->name = xstrdup (direntry->d_name);
591e1ffb 1111 dlib_ptr->soname = soname;
27d9ffda 1112 dlib_ptr->flag = flag;
591e1ffb 1113 dlib_ptr->is_link = is_link;
27d9ffda 1114 dlib_ptr->osversion = osversion;
591e1ffb
UD
1115 /* Add at head of list. */
1116 dlib_ptr->next = dlibs;
1117 dlibs = dlib_ptr;
1118 }
1119 }
1120
1121 closedir (dir);
1122
1123 /* Now dlibs contains a list of all libs - add those to the cache
1124 and created all symbolic links. */
27d9ffda 1125 struct dlib_entry *dlib_ptr;
591e1ffb
UD
1126 for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
1127 {
b44ac4f4
FW
1128 /* The cached file name is the soname for non-glibc-hwcaps
1129 subdirectories (relying on symbolic links; this helps with
1130 library updates that change the file name), and the actual
1131 file for glibc-hwcaps subdirectories. */
1132 const char *filename;
1133 if (entry->hwcaps == NULL)
1134 {
1135 /* Don't create links to links. */
1136 if (dlib_ptr->is_link == 0)
1137 create_links (dir_name, entry->path, dlib_ptr->name,
1138 dlib_ptr->soname);
1139 filename = dlib_ptr->soname;
1140 }
1141 else
1142 {
1143 /* Do not create links in glibc-hwcaps subdirectories, but
1144 still log the cache addition. */
1145 if (opt_verbose)
1146 printf ("\t%s -> %s\n", dlib_ptr->soname, dlib_ptr->name);
1147 filename = dlib_ptr->name;
1148 }
591e1ffb 1149 if (opt_build_cache)
b44ac4f4
FW
1150 add_to_cache (entry->path, filename, dlib_ptr->soname,
1151 dlib_ptr->flag, dlib_ptr->osversion,
1152 hwcap, entry->hwcaps);
591e1ffb
UD
1153 }
1154
1155 /* Free all resources. */
45eca4d1 1156 while (dlibs)
591e1ffb
UD
1157 {
1158 dlib_ptr = dlibs;
1159 free (dlib_ptr->soname);
1160 free (dlib_ptr->name);
1161 dlibs = dlibs->next;
1162 free (dlib_ptr);
1163 }
b4a555d6
UD
1164
1165 if (opt_chroot && dir_name)
1166 free (dir_name);
591e1ffb
UD
1167}
1168
1169/* Search through all libraries. */
1170static void
1171search_dirs (void)
1172{
1173 struct dir_entry *entry;
1174
1175 for (entry = dir_entries; entry != NULL; entry = entry->next)
1176 search_dir (entry);
1177
1178 /* Free all allocated memory. */
1179 while (dir_entries)
1180 {
1181 entry = dir_entries;
1182 dir_entries = dir_entries->next;
1183 free (entry->path);
1184 free (entry);
1185 }
1186}
1187
1188
8e115d80 1189static void parse_conf_include (const char *config_file, unsigned int lineno,
a334319f 1190 bool do_chroot, const char *pattern);
8e115d80 1191
591e1ffb
UD
1192/* Parse configuration file. */
1193static void
a334319f 1194parse_conf (const char *filename, bool do_chroot)
591e1ffb 1195{
b4a555d6 1196 FILE *file = NULL;
591e1ffb 1197 char *line = NULL;
b4a555d6 1198 const char *canon;
591e1ffb 1199 size_t len = 0;
8e115d80 1200 unsigned int lineno;
45eca4d1 1201
8e115d80 1202 if (do_chroot && opt_chroot)
b4a555d6
UD
1203 {
1204 canon = chroot_canon (opt_chroot, filename);
1205 if (canon)
1206 file = fopen (canon, "r");
1207 else
1208 canon = filename;
1209 }
1210 else
1211 {
1212 canon = filename;
1213 file = fopen (filename, "r");
1214 }
591e1ffb
UD
1215
1216 if (file == NULL)
1217 {
b5a1271c
FW
1218 if (errno != ENOENT)
1219 error (0, errno, _("\
1db86e88 1220Warning: ignoring configuration file that cannot be opened: %s"),
b5a1271c 1221 canon);
b4a555d6
UD
1222 if (canon != filename)
1223 free ((char *) canon);
591e1ffb
UD
1224 return;
1225 }
1226
c96873d7
UD
1227 /* No threads use this stream. */
1228 __fsetlocking (file, FSETLOCKING_BYCALLER);
1229
b4a555d6
UD
1230 if (canon != filename)
1231 free ((char *) canon);
1232
8e115d80 1233 lineno = 0;
591e1ffb
UD
1234 do
1235 {
1236 ssize_t n = getline (&line, &len, file);
1237 if (n < 0)
1238 break;
1239
8e115d80 1240 ++lineno;
591e1ffb
UD
1241 if (line[n - 1] == '\n')
1242 line[n - 1] = '\0';
1243
1244 /* Because the file format does not know any form of quoting we
1245 can search forward for the next '#' character and if found
1246 make it terminating the line. */
1247 *strchrnul (line, '#') = '\0';
1248
69acbe9f
UD
1249 /* Remove leading whitespace. NUL is no whitespace character. */
1250 char *cp = line;
1251 while (isspace (*cp))
1252 ++cp;
1253
591e1ffb 1254 /* If the line is blank it is ignored. */
69acbe9f 1255 if (cp[0] == '\0')
591e1ffb
UD
1256 continue;
1257
8e115d80
RM
1258 if (!strncmp (cp, "include", 7) && isblank (cp[7]))
1259 {
1260 char *dir;
1261 cp += 8;
1262 while ((dir = strsep (&cp, " \t")) != NULL)
1263 if (dir[0] != '\0')
a334319f 1264 parse_conf_include (filename, lineno, do_chroot, dir);
8e115d80 1265 }
ab1d521d 1266 else if (!strncasecmp (cp, "hwcap", 5) && isblank (cp[5]))
31563b68 1267 error (0, 0, _("%s:%u: hwcap directive ignored"), filename, lineno);
8e115d80 1268 else
b7176cc2 1269 add_dir_1 (cp, filename, lineno);
69acbe9f
UD
1270 }
1271 while (!feof_unlocked (file));
591e1ffb
UD
1272
1273 /* Free buffer and close file. */
1274 free (line);
1275 fclose (file);
1276}
1277
8e115d80
RM
1278/* Handle one word in an `include' line, a glob pattern of additional
1279 config files to read. */
1280static void
1281parse_conf_include (const char *config_file, unsigned int lineno,
a334319f 1282 bool do_chroot, const char *pattern)
8e115d80
RM
1283{
1284 if (opt_chroot && pattern[0] != '/')
1285 error (EXIT_FAILURE, 0,
1286 _("need absolute file name for configuration file when using -r"));
1287
1288 char *copy = NULL;
1289 if (pattern[0] != '/' && strchr (config_file, '/') != NULL)
1290 {
322861e8
UD
1291 if (asprintf (&copy, "%s/%s", dirname (strdupa (config_file)),
1292 pattern) < 0)
1293 error (EXIT_FAILURE, 0, _("memory exhausted"));
8e115d80
RM
1294 pattern = copy;
1295 }
1296
1297 glob64_t gl;
1298 int result;
1299 if (do_chroot && opt_chroot)
1300 {
1301 char *canon = chroot_canon (opt_chroot, pattern);
49bd556d
UD
1302 if (canon == NULL)
1303 return;
1304 result = glob64 (canon, 0, NULL, &gl);
8e115d80
RM
1305 free (canon);
1306 }
1307 else
1308 result = glob64 (pattern, 0, NULL, &gl);
1309
1310 switch (result)
1311 {
1312 case 0:
1313 for (size_t i = 0; i < gl.gl_pathc; ++i)
a334319f 1314 parse_conf (gl.gl_pathv[i], false);
8e115d80
RM
1315 globfree64 (&gl);
1316 break;
1317
1318 case GLOB_NOMATCH:
1319 break;
1320
1321 case GLOB_NOSPACE:
1322 errno = ENOMEM;
32db86d5 1323 /* Fall through. */
8e115d80
RM
1324 case GLOB_ABORTED:
1325 if (opt_verbose)
1326 error (0, errno, _("%s:%u: cannot read directory %s"),
1327 config_file, lineno, pattern);
1328 break;
1329
1330 default:
1331 abort ();
1332 break;
1333 }
1334
72e6cdfa 1335 free (copy);
8e115d80
RM
1336}
1337
0cfbb8c6
UD
1338/* Honour LD_HWCAP_MASK. */
1339static void
1340set_hwcap (void)
1341{
1342 char *mask = getenv ("LD_HWCAP_MASK");
1343
1344 if (mask)
1345 hwcap_mask = strtoul (mask, NULL, 0);
1346}
1347
591e1ffb
UD
1348
1349int
1350main (int argc, char **argv)
1351{
11bf311e
UD
1352 /* Set locale via LC_ALL. */
1353 setlocale (LC_ALL, "");
1354
7d38eb38
AJ
1355 /* But keep the C collation. That way `include' directives using
1356 globbing patterns are processed in a locale-independent order. */
1357 setlocale (LC_COLLATE, "C");
1358
11bf311e
UD
1359 /* Set the text message domain. */
1360 textdomain (_libc_intl_domainname);
45eca4d1 1361
591e1ffb 1362 /* Parse and process arguments. */
11bf311e 1363 int remaining;
591e1ffb
UD
1364 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
1365
11bf8ce1 1366 /* Remaining arguments are additional directories if opt_manual_link
b85697f6
UD
1367 is not set. */
1368 if (remaining != argc && !opt_manual_link)
591e1ffb
UD
1369 {
1370 int i;
1371 for (i = remaining; i < argc; ++i)
11bf8ce1
UD
1372 if (opt_build_cache && argv[i][0] != '/')
1373 error (EXIT_FAILURE, 0,
1374 _("relative path `%s' used to build cache"),
1375 argv[i]);
1376 else
b7176cc2 1377 add_dir_1 (argv[i], "<cmdline>", 0);
591e1ffb
UD
1378 }
1379
0cfbb8c6
UD
1380 set_hwcap ();
1381
591e1ffb
UD
1382 if (opt_chroot)
1383 {
f0189a54 1384 /* Normalize the path a bit, we might need it for printing later. */
616d9133 1385 char *endp = rawmemchr (opt_chroot, '\0');
b4a555d6 1386 while (endp > opt_chroot && endp[-1] == '/')
f0189a54
UD
1387 --endp;
1388 *endp = '\0';
b4a555d6
UD
1389 if (endp == opt_chroot)
1390 opt_chroot = NULL;
f0189a54 1391
b4a555d6
UD
1392 if (opt_chroot)
1393 {
1394 /* It is faster to use chroot if we can. */
1395 if (!chroot (opt_chroot))
1396 {
1397 if (chdir ("/"))
1398 error (EXIT_FAILURE, errno, _("Can't chdir to /"));
1399 opt_chroot = NULL;
1400 }
1401 }
1402 }
1403
1404 if (cache_file == NULL)
1405 {
1406 cache_file = alloca (strlen (LD_SO_CACHE) + 1);
1407 strcpy (cache_file, LD_SO_CACHE);
591e1ffb
UD
1408 }
1409
b4a555d6
UD
1410 if (config_file == NULL)
1411 config_file = LD_SO_CONF;
1412
591e1ffb
UD
1413 if (opt_print_cache)
1414 {
b4a555d6
UD
1415 if (opt_chroot)
1416 {
1417 char *p = chroot_canon (opt_chroot, cache_file);
1418 if (p == NULL)
1419 error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"),
1420 cache_file);
1421 cache_file = p;
1422 }
591e1ffb 1423 print_cache (cache_file);
b4a555d6
UD
1424 if (opt_chroot)
1425 free (cache_file);
591e1ffb
UD
1426 exit (0);
1427 }
1428
b4a555d6
UD
1429 if (opt_chroot)
1430 {
1431 /* Canonicalize the directory name of cache_file, not cache_file,
27d9ffda 1432 because we'll rename a temporary cache file to it. */
b4a555d6
UD
1433 char *p = strrchr (cache_file, '/');
1434 char *canon = chroot_canon (opt_chroot,
1435 p ? (*p = '\0', cache_file) : "/");
1436
1437 if (canon == NULL)
4bc2bcba
UD
1438 error (EXIT_FAILURE, errno,
1439 _("Can't open cache file directory %s\n"),
1440 p ? cache_file : "/");
b4a555d6
UD
1441
1442 if (p)
1443 ++p;
1444 else
1445 p = cache_file;
1446
1447 cache_file = alloca (strlen (canon) + strlen (p) + 2);
1448 sprintf (cache_file, "%s/%s", canon, p);
1449 free (canon);
1450 }
1451
b85697f6
UD
1452 if (opt_manual_link)
1453 {
1454 /* Link all given libraries manually. */
1455 int i;
1456
1457 for (i = remaining; i < argc; ++i)
a986484f 1458 manual_link (argv[i]);
b85697f6
UD
1459
1460 exit (0);
1461 }
45eca4d1
UD
1462
1463
591e1ffb
UD
1464 if (opt_build_cache)
1465 init_cache ();
1466
1467 if (!opt_only_cline)
1468 {
a334319f 1469 parse_conf (config_file, true);
334fcf2a 1470
591e1ffb 1471 /* Always add the standard search paths. */
bd89c0b5 1472 add_system_dir (SLIBDIR);
8ca91b36 1473 if (strcmp (SLIBDIR, LIBDIR))
bd89c0b5 1474 add_system_dir (LIBDIR);
591e1ffb 1475 }
45eca4d1 1476
3f7dcb2b 1477 const char *aux_cache_file = _PATH_LDCONFIG_AUX_CACHE;
4bc2bcba 1478 if (opt_chroot)
6db52fbb 1479 aux_cache_file = chroot_canon (opt_chroot, aux_cache_file);
4bc2bcba 1480
6db52fbb 1481 if (! opt_ignore_aux_cache && aux_cache_file)
4bc2bcba 1482 load_aux_cache (aux_cache_file);
27d9ffda
UD
1483 else
1484 init_aux_cache ();
1485
591e1ffb
UD
1486 search_dirs ();
1487
1488 if (opt_build_cache)
27d9ffda
UD
1489 {
1490 save_cache (cache_file);
6db52fbb 1491 if (aux_cache_file)
c0dafcf1 1492 save_aux_cache (aux_cache_file);
27d9ffda 1493 }
591e1ffb
UD
1494
1495 return 0;
1496}