OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [linux/] [uClibc/] [utils/] [ldconfig.c] - Blame information for rev 1765

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
/*
2
 * ldconfig - update shared library symlinks
3
 *
4
 * usage: ldconfig [-DvqnNX] [-f conf] [-C cache] [-r root] dir ...
5
 *        ldconfig -l [-Dv] lib ...
6
 *        ldconfig -p
7
 *        -D: debug mode, don't update links
8
 *        -v: verbose mode, print things as we go
9
 *        -q: quiet mode, don't print warnings
10
 *        -n: don't process standard directories
11
 *        -N: don't update the library cache
12
 *        -X: don't update the library links
13
 *        -l: library mode, manually link libraries
14
 *        -p: print the current library cache
15
 *        -f conf: use conf instead of /etc/ld.so.conf
16
 *        -C cache: use cache instead of /etc/ld.so.cache
17
 *        -r root: first, do a chroot to the indicated directory
18
 *        dir ...: directories to process
19
 *        lib ...: libraries to link
20
 *
21
 * Copyright 1994-2000 David Engel and Mitch D'Souza
22
 *
23
 * This program may be used for any purpose as long as this
24
 * copyright notice is kept.
25
 */
26
 
27
#include <stdio.h>
28
#include <stdlib.h>
29
#include <stdarg.h>
30
#include <string.h>
31
#include <ctype.h>
32
#include <getopt.h>
33
#include <dirent.h>
34
#include <unistd.h>
35
#include <link.h>
36
#include <fcntl.h>
37
#include <errno.h>
38
#include <sys/stat.h>
39
#include <sys/mman.h>
40
#include <ld_elf.h>
41
#include "readsoname.h"
42
 
43
struct exec
44
{
45
  unsigned long a_info;         /* Use macros N_MAGIC, etc for access */
46
  unsigned a_text;              /* length of text, in bytes */
47
  unsigned a_data;              /* length of data, in bytes */
48
  unsigned a_bss;               /* length of uninitialized data area for file, in bytes */
49
  unsigned a_syms;              /* length of symbol table data in file, in bytes */
50
  unsigned a_entry;             /* start address */
51
  unsigned a_trsize;            /* length of relocation info for text, in bytes */
52
  unsigned a_drsize;            /* length of relocation info for data, in bytes */
53
};
54
 
55
#if !defined (N_MAGIC)
56
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
57
#endif
58
/* Code indicating object file or impure executable.  */
59
#define OMAGIC 0407
60
/* Code indicating pure executable.  */
61
#define NMAGIC 0410
62
/* Code indicating demand-paged executable.  */
63
#define ZMAGIC 0413
64
/* This indicates a demand-paged executable with the header in the text.
65
   The first page is unmapped to help trap NULL pointer references */
66
#define QMAGIC 0314
67
/* Code indicating core file.  */
68
#define CMAGIC 0421
69
 
70
char *___strtok = NULL;
71
 
72
/* For SunOS */
73
#ifndef PATH_MAX
74
#include <limits.h>
75
#define PATH_MAX _POSIX_PATH_MAX
76
#endif
77
 
78
/* For SunOS */
79
#ifndef N_MAGIC
80
#define N_MAGIC(exec) ((exec).a_magic & 0xffff)
81
#endif
82
 
83
#define EXIT_OK    0
84
#define EXIT_FATAL 128
85
 
86
char *prog = NULL;
87
int debug = 0;                   /* debug mode */
88
int verbose = 0;         /* verbose mode */
89
int libmode = 0;         /* library mode */
90
int nocache = 0;         /* don't build cache */
91
int nolinks = 0;         /* don't update links */
92
 
93
char *conffile = LDSO_CONF;     /* default conf file */
94
char *cachefile = LDSO_CACHE;   /* default cache file */
95
void cache_print(void);
96
void cache_dolib(const char *dir, const char *so, int libtype);
97
void cache_write(void);
98
 
99
/* These two are used internally -- you shouldn't need to use them */
100
static void verror_msg(const char *s, va_list p)
101
{
102
        fflush(stdout);
103
        fprintf(stderr, "%s: ", prog);
104
        vfprintf(stderr, s, p);
105
}
106
 
107
extern void warnx(const char *s, ...)
108
{
109
        va_list p;
110
 
111
        va_start(p, s);
112
        verror_msg(s, p);
113
        va_end(p);
114
        fprintf(stderr, "\n");
115
}
116
 
117
extern void err(int errnum, const char *s, ...)
118
{
119
        va_list p;
120
 
121
        va_start(p, s);
122
        verror_msg(s, p);
123
        va_end(p);
124
        fprintf(stderr, "\n");
125
        exit(errnum);
126
}
127
 
128
static void vperror_msg(const char *s, va_list p)
129
{
130
        int err = errno;
131
 
132
        if (s == 0)
133
                s = "";
134
        verror_msg(s, p);
135
        if (*s)
136
                s = ": ";
137
        fprintf(stderr, "%s%s\n", s, strerror(err));
138
}
139
 
140
extern void warn(const char *s, ...)
141
{
142
        va_list p;
143
 
144
        va_start(p, s);
145
        vperror_msg(s, p);
146
        va_end(p);
147
}
148
 
149
void *xmalloc(size_t size)
150
{
151
    void *ptr;
152
    if ((ptr = malloc(size)) == NULL)
153
        err(EXIT_FATAL,"out of memory");
154
    return ptr;
155
}
156
 
157
char *xstrdup(const char *str)
158
{
159
    char *ptr;
160
    if ((ptr = strdup(str)) == NULL)
161
        err(EXIT_FATAL,"out of memory");
162
    return ptr;
163
}
164
 
165
/* If shared library, return a malloced copy of the soname and set the
166
   type, else return NULL.
167
 
168
   expected_type should be either LIB_ANY or one of the following:-
169
   LIB_DLL
170
   LIB_ELF
171
   LIB_ELF_LIBC5
172
   LIB_ELF_LIBC6
173
 
174
   If the lib is ELF and we can not deduce the type the type will
175
   be set based on expected_type.
176
 
177
   If the expected, actual/deduced types missmatch we display a warning
178
   and use the actual/deduced type.
179
*/
180
char *is_shlib(const char *dir, const char *name, int *type,
181
        int *islink, int expected_type)
182
{
183
    char *good = NULL;
184
    char *cp, *cp2;
185
    FILE *file;
186
    struct exec exec;
187
    ElfW(Ehdr) *elf_hdr;
188
    struct stat statbuf;
189
    char buff[4096];
190
 
191
    /* see if name is of the form *.so* */
192
    if (name[strlen(name)-1] != '~' && (cp = strstr(name, ".so")))
193
    {
194
        /* find the start of the Vminor part, if any */
195
        if (cp[3] == '.' && (cp2 = strchr(cp + 4, '.')))
196
            cp = cp2;
197
        else
198
            cp = cp + strlen(cp);
199
 
200
        /* construct the full path name */
201
        sprintf(buff, "%s%s%s", dir, (*dir && strcmp(dir, "/")) ?
202
                "/" : "", name);
203
 
204
        /* first, make sure it's a regular file */
205
        if (lstat(buff, &statbuf))
206
            warn("skipping %s", buff);
207
        else if (!S_ISREG(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode))
208
            warnx("%s is not a regular file or symlink, skipping", buff);
209
        else
210
        {
211
            /* is it a regular file or a symlink */
212
            *islink = S_ISLNK(statbuf.st_mode);
213
 
214
            /* then try opening it */
215
            if (!(file = fopen(buff, "rb")))
216
                warn("skipping %s", buff);
217
            else
218
            {
219
                /* now make sure it's a shared library */
220
                if (fread(&exec, sizeof exec, 1, file) < 1)
221
                    warnx("can't read header from %s, skipping", buff);
222
                else if (N_MAGIC(exec) != ZMAGIC && N_MAGIC(exec) != QMAGIC)
223
                {
224
                    elf_hdr = (ElfW(Ehdr) *) &exec;
225
                    if (elf_hdr->e_ident[0] != 0x7f ||
226
                            strncmp(&elf_hdr->e_ident[1], "ELF",3) != 0)
227
                    {
228
                        /* silently ignore linker scripts */
229
                        if (strncmp((char *)&exec, "/* GNU ld", 9) != 0)
230
                            warnx("%s is not a shared library, skipping", buff);
231
                    }
232
                    else
233
                    {
234
                        /* always call readsoname to update type */
235
                        if(expected_type == LIB_DLL) {
236
                            warnx("%s is not an a.out library, its ELF!\n", buff);
237
                            expected_type=LIB_ANY;
238
                        }
239
                        *type = LIB_ELF;
240
                        good = readsoname(buff, file, expected_type, type,
241
                                elf_hdr->e_ident[EI_CLASS]);
242
                        if (good == NULL || *islink)
243
                        {
244
                            if (good != NULL)
245
                                free(good);
246
                            good = xstrdup(name);
247
                        }
248
                        else
249
                        {
250
                            /* if the soname does not match the filename,
251
                               issue a warning, but only in debug mode. */
252
                            int len = strlen(good);
253
                            if (debug && (strncmp(good, name, len) != 0 ||
254
                                        (name[len] != '\0' && name[len] != '.')))
255
                                warnx("%s has inconsistent soname (%s)", buff, good);
256
                        }
257
                    }
258
                }
259
                else
260
                {
261
                    if (*islink)
262
                        good = xstrdup(name);
263
                    else
264
                    {
265
                        good = xmalloc(cp - name + 1);
266
                        strncpy(good, name, cp - name);
267
                        good[cp - name] = '\0';
268
                    }
269
                    if(expected_type != LIB_ANY && expected_type != LIB_DLL)
270
                    {
271
                        warnx("%s is not an ELF library, its an a.out DLL!", buff);
272
                        expected_type=LIB_ANY;
273
                    }
274
 
275
                    *type = LIB_DLL;
276
                }
277
                fclose(file);
278
            }
279
        }
280
    }
281
 
282
    return good;
283
}
284
 
285
/* update the symlink to new library */
286
void link_shlib(const char *dir, const char *file, const char *so)
287
{
288
    int change = 1;
289
    char libname[4096];
290
    char linkname[4096];
291
    struct stat libstat;
292
    struct stat linkstat;
293
 
294
    /* construct the full path names */
295
    sprintf(libname, "%s/%s", dir, file);
296
    sprintf(linkname, "%s/%s", dir, so);
297
 
298
    /* see if a link already exists */
299
    if (!stat(linkname, &linkstat))
300
    {
301
        /* now see if it's the one we want */
302
        if (stat(libname, &libstat))
303
            warn("can't stat %s", libname);
304
        else if (libstat.st_dev == linkstat.st_dev &&
305
                libstat.st_ino == linkstat.st_ino)
306
            change = 0;
307
    }
308
 
309
    /* then update the link, if required */
310
    if (change > 0 && !nolinks)
311
    {
312
        if (!lstat(linkname, &linkstat))
313
        {
314
            if (!S_ISLNK(linkstat.st_mode))
315
            {
316
                warnx("%s is not a symlink", linkname);
317
                change = -1;
318
            }
319
            else if (remove(linkname))
320
            {
321
                warn("can't unlink %s", linkname);
322
                change = -1;
323
            }
324
        }
325
        if (change > 0)
326
        {
327
            if (symlink(file, linkname))
328
            {
329
                warn("can't link %s to %s", linkname, file);
330
                change = -1;
331
            }
332
        }
333
    }
334
 
335
    /* some people like to know what we're doing */
336
    if (verbose > 0)
337
        printf("\t%s => %s%s\n", so, file,
338
                change < 0 ? " (SKIPPED)" :
339
                (change > 0 ? " (changed)" : ""));
340
 
341
    return;
342
}
343
 
344
/* figure out which library is greater */
345
int libcmp(char *p1, char *p2)
346
{
347
    while (*p1)
348
    {
349
        if (isdigit(*p1) && isdigit(*p2))
350
        {
351
            /* must compare this numerically */
352
            int v1, v2;
353
            v1 = strtoul(p1, &p1, 10);
354
            v2 = strtoul(p2, &p2, 10);
355
            if (v1 != v2)
356
                return v1 - v2;
357
        }
358
        else if (isdigit(*p1) && !isdigit(*p2))
359
            return 1;
360
        else if (!isdigit(*p1) && isdigit(*p2))
361
            return -1;
362
        else if (*p1 != *p2)
363
            return *p1 - *p2;
364
        else
365
            p1++, p2++;
366
    }
367
 
368
    return *p1 - *p2;
369
}
370
 
371
struct lib
372
{
373
    char *so;                   /* soname of a library */
374
    char *name;                 /* name of a library */
375
    int libtype;                /* type of a library */
376
    int islink;                 /* is it a symlink */
377
    struct lib *next;           /* next library in list */
378
};
379
 
380
/* update all shared library links in a directory */
381
void scan_dir(const char *rawname)
382
{
383
    DIR *dir;
384
    const char *name;
385
    struct dirent *ent;
386
    char *so, *path, *path_n;
387
    struct lib *lp, *libs = NULL;
388
    int i, libtype, islink, expected_type = LIB_ANY;
389
 
390
    /* We need a writable copy of this string */
391
    path = strdup(rawname);
392
    if (!path) {
393
        err(EXIT_FATAL, "Out of memory!\n");
394
    }
395
    /* Eliminate all double //s */
396
    path_n=path;
397
    while((path_n=strstr(path_n, "//"))) {
398
        i = strlen(path_n);
399
        memmove(path_n, path_n+1, i-1);
400
        *(path_n + i - 1)='\0';
401
    }
402
    name = path;
403
 
404
#if 0
405
    char *t;
406
    /* Check for an embedded expected type */
407
    t=strrchr(name, '=');
408
    if( t )
409
    {
410
        *t++ = '\0'; /* Skip = char */
411
        if(strcasecmp(t, "libc4") == 0)
412
        {
413
            expected_type = LIB_DLL;
414
        }
415
        else
416
        {
417
            if(strcasecmp(t, "libc5") == 0)
418
            {
419
                expected_type = LIB_ELF_LIBC5;
420
            }
421
            else
422
            {
423
                if(strcasecmp(t, "libc6") == 0)
424
                {
425
                    expected_type = LIB_ELF_LIBC6;
426
                }
427
                else
428
                {
429
                    if(strcasecmp(t, "libc0") == 0)
430
                    {
431
                        expected_type = LIB_ELF_LIBC0;
432
                    }
433
                    else
434
                    {
435
                        warnx("Unknown type field '%s' for dir '%s' - ignored\n", t, name);
436
                        expected_type = LIB_ANY;
437
                    }
438
                }
439
            }
440
        }
441
    }
442
#endif
443
 
444
    /* let 'em know what's going on */
445
    if (verbose > 0)
446
        printf("%s:\n", name);
447
 
448
    /* if we can't open it, we can't do anything */
449
    if ((dir = opendir(name)) == NULL)
450
    {
451
        warn("skipping %s", name);
452
        free(path);
453
        return;
454
    }
455
 
456
    /* yes, we have to look at every single file */
457
    while ((ent = readdir(dir)) != NULL)
458
    {
459
        /* if it's not a shared library, don't bother */
460
        if ((so = is_shlib(name, ent->d_name, &libtype, &islink, expected_type)) == NULL)
461
            continue;
462
 
463
        /* have we already seen one with the same so name? */
464
        for (lp = libs; lp; lp = lp->next)
465
        {
466
            if (strcmp(so, lp->so) == 0)
467
            {
468
                /* we have, which one do we want to use? */
469
                if ((!islink && lp->islink) ||
470
                        (islink == lp->islink &&
471
                         libcmp(ent->d_name, lp->name) > 0))
472
                {
473
                    /* let's use the new one */
474
                    free(lp->name);
475
                    lp->name = xstrdup(ent->d_name);
476
                    lp->libtype = libtype;
477
                    lp->islink = islink;
478
                }
479
                break;
480
            }
481
        }
482
 
483
        /* congratulations, you're the first one we've seen */
484
        if (!lp)
485
        {
486
            lp = xmalloc(sizeof *lp);
487
            lp->so = xstrdup(so);
488
            lp->name = xstrdup(ent->d_name);
489
            lp->libtype = libtype;
490
            lp->islink = islink;
491
            lp->next = libs;
492
            libs = lp;
493
        }
494
 
495
        free(so);
496
    }
497
 
498
    /* don't need this any more */
499
    closedir(dir);
500
 
501
    /* now we have all the latest libs, update the links */
502
    for (lp = libs; lp; lp = lp->next)
503
    {
504
        if (!lp->islink)
505
            link_shlib(name, lp->name, lp->so);
506
#ifdef USE_CACHE
507
        if (!nocache)
508
            cache_dolib(name, lp->so, lp->libtype);
509
#endif
510
    }
511
 
512
    /* always try to clean up after ourselves */
513
    while (libs)
514
    {
515
        lp = libs->next;
516
        free(libs->so);
517
        free(libs->name);
518
        free(libs);
519
        libs = lp;
520
    }
521
 
522
    free(path);
523
    return;
524
}
525
 
526
/* return the list of system-specific directories */
527
char *get_extpath(void)
528
{
529
    char *res = NULL, *cp;
530
    FILE *file;
531
    struct stat stat;
532
 
533
    if ((file = fopen(conffile, "r")) != NULL)
534
    {
535
        fstat(fileno(file), &stat);
536
        res = xmalloc(stat.st_size + 1);
537
        fread(res, 1, stat.st_size, file);
538
        fclose(file);
539
        res[stat.st_size] = '\0';
540
 
541
        /* convert comments fo spaces */
542
        for (cp = res; *cp; /*nada*/) {
543
            if (*cp == '#') {
544
                do
545
                    *cp++ = ' ';
546
                while (*cp && *cp != '\n');
547
            } else {
548
                cp++;
549
            }
550
        }
551
    }
552
 
553
    return res;
554
}
555
 
556
#ifdef USE_CACHE
557
typedef struct liblist
558
{
559
    int flags;
560
    int sooffset;
561
    int liboffset;
562
    char *soname;
563
    char *libname;
564
    struct liblist *next;
565
} liblist_t;
566
 
567
static header_t magic = { LDSO_CACHE_MAGIC, LDSO_CACHE_VER, 0 };
568
static liblist_t *lib_head = NULL;
569
 
570
static int liblistcomp(liblist_t *x, liblist_t *y)
571
{
572
    int res;
573
 
574
    if ((res = libcmp(x->soname, y->soname)) == 0)
575
    {
576
        res = libcmp(strrchr(x->libname, '/') + 1,
577
                strrchr(y->libname, '/') + 1);
578
    }
579
 
580
    return res;
581
}
582
 
583
void cache_dolib(const char *dir, const char *so, int libtype)
584
{
585
    char fullpath[PATH_MAX];
586
    liblist_t *new_lib, *cur_lib;
587
 
588
    magic.nlibs++;
589
    sprintf(fullpath, "%s/%s", dir, so);
590
    new_lib = xmalloc(sizeof (liblist_t));
591
    new_lib->flags = libtype;
592
    new_lib->soname = xstrdup(so);
593
    new_lib->libname = xstrdup(fullpath);
594
 
595
    if (lib_head == NULL || liblistcomp(new_lib, lib_head) > 0)
596
    {
597
        new_lib->next = lib_head;
598
        lib_head = new_lib;
599
    }
600
    else
601
    {
602
        for (cur_lib = lib_head; cur_lib->next != NULL &&
603
                liblistcomp(new_lib, cur_lib->next) <= 0;
604
                cur_lib = cur_lib->next)
605
            /* nothing */;
606
        new_lib->next = cur_lib->next;
607
        cur_lib->next = new_lib;
608
    }
609
}
610
 
611
void cache_write(void)
612
{
613
    int cachefd;
614
    int stroffset = 0;
615
    char tempfile[4096];
616
    liblist_t *cur_lib;
617
 
618
    if (!magic.nlibs)
619
        return;
620
 
621
    sprintf(tempfile, "%s~", cachefile);
622
 
623
    if (unlink(tempfile) && errno != ENOENT)
624
        err(EXIT_FATAL,"can't unlink %s (%s)", tempfile, strerror(errno));
625
 
626
    if ((cachefd = creat(tempfile, 0644)) < 0)
627
        err(EXIT_FATAL,"can't create %s (%s)", tempfile, strerror(errno));
628
 
629
    if (write(cachefd, &magic, sizeof (header_t)) != sizeof (header_t))
630
        err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno));
631
 
632
    for (cur_lib = lib_head; cur_lib != NULL; cur_lib = cur_lib->next)
633
    {
634
        cur_lib->sooffset = stroffset;
635
        stroffset += strlen(cur_lib->soname) + 1;
636
        cur_lib->liboffset = stroffset;
637
        stroffset += strlen(cur_lib->libname) + 1;
638
        if (write(cachefd, cur_lib, sizeof (libentry_t)) !=
639
                sizeof (libentry_t))
640
            err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno));
641
    }
642
 
643
    for (cur_lib = lib_head; cur_lib != NULL; cur_lib = cur_lib->next)
644
    {
645
        if (write(cachefd, cur_lib->soname, strlen(cur_lib->soname) + 1)
646
                != strlen(cur_lib->soname) + 1)
647
            err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno));
648
        if (write(cachefd, cur_lib->libname, strlen(cur_lib->libname) + 1)
649
                != strlen(cur_lib->libname) + 1)
650
            err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno));
651
    }
652
 
653
    if (close(cachefd))
654
        err(EXIT_FATAL,"can't close %s (%s)", tempfile, strerror(errno));
655
 
656
    if (chmod(tempfile, 0644))
657
        err(EXIT_FATAL,"can't chmod %s (%s)", tempfile, strerror(errno));
658
 
659
    if (rename(tempfile, cachefile))
660
        err(EXIT_FATAL,"can't rename %s (%s)", tempfile, strerror(errno));
661
}
662
 
663
void cache_print(void)
664
{
665
    caddr_t c;
666
    struct stat st;
667
    int fd = 0;
668
    char *strs;
669
    header_t *header;
670
    libentry_t *libent;
671
 
672
    if (stat(cachefile, &st) || (fd = open(cachefile, O_RDONLY))<0)
673
        err(EXIT_FATAL,"can't read %s (%s)", cachefile, strerror(errno));
674
    if ((c = mmap(0,st.st_size, PROT_READ, MAP_SHARED ,fd, 0)) == (caddr_t)-1)
675
        err(EXIT_FATAL,"can't map %s (%s)", cachefile, strerror(errno));
676
    close(fd);
677
 
678
    if (memcmp(((header_t *)c)->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN))
679
        err(EXIT_FATAL,"%s cache corrupt", cachefile);
680
 
681
    if (memcmp(((header_t *)c)->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN))
682
        err(EXIT_FATAL,"wrong cache version - expected %s", LDSO_CACHE_VER);
683
 
684
    header = (header_t *)c;
685
    libent = (libentry_t *)(c + sizeof (header_t));
686
    strs = (char *)&libent[header->nlibs];
687
 
688
    printf("%d libs found in cache `%s' (version %s)\n",
689
            header->nlibs, cachefile, LDSO_CACHE_VER);
690
 
691
    for (fd = 0; fd < header->nlibs; fd++)
692
    {
693
        printf("\t%s ", strs + libent[fd].sooffset);
694
        switch (libent[fd].flags & ~LIB_ELF64)
695
        {
696
            case LIB_DLL:
697
                printf("(libc4)");
698
                break;
699
            case LIB_ELF:
700
                printf("(ELF%s)", libent[fd].flags & LIB_ELF64 ? "/64" : "");
701
                break;
702
            case LIB_ELF_LIBC5:
703
            case LIB_ELF_LIBC6:
704
                printf("(libc%d%s)", (libent[fd].flags & ~LIB_ELF64) + 3,
705
                        libent[fd].flags & LIB_ELF64 ? "/64" : "");
706
                break;
707
            default:
708
                printf("(unknown)");
709
                break;
710
        }
711
        printf(" => %s\n", strs + libent[fd].liboffset);
712
    }
713
 
714
    munmap (c,st.st_size);
715
}
716
#else
717
void cache_print(void)
718
{
719
    warnx("Cache support disabled\n");
720
}
721
#endif
722
 
723
void usage(void)
724
{
725
    fprintf(stderr,
726
            "ldconfig - updates symlinks for shared libraries\n\n"
727
            "Usage: ldconfig [-DvqnNX] [-f conf] [-C cache] [-r root] dir ...\n"
728
            "       ldconfig -l [-Dv] lib ...\n"
729
            "       ldconfig -p\n\nOptions:\n"
730
            "\t-D:\t\tdebug mode, don't update links\n"
731
            "\t-v:\t\tverbose mode, print things as we go\n"
732
            "\t-q:\t\tquiet mode, don't print warnings\n"
733
            "\t-n:\t\tdon't process standard directories\n"
734
            "\t-N:\t\tdon't update the library cache\n"
735
            "\t-X:\t\tdon't update the library links\n"
736
            "\t-l:\t\tlibrary mode, manually link libraries\n"
737
            "\t-p:\t\tprint the current library cache\n"
738
            "\t-f conf :\tuse conf instead of %s\n"
739
            "\t-C cache:\tuse cache instead of %s\n"
740
            "\t-r root :\tfirst, do a chroot to the indicated directory\n"
741
            "\tdir ... :\tdirectories to process\n"
742
            "\tlib ... :\tlibraries to link\n\n",
743
            LDSO_CONF, LDSO_CACHE
744
           );
745
    exit(EXIT_FATAL);
746
}
747
 
748
#define DIR_SEP      ":, \t\n"
749
int main(int argc, char **argv)
750
{
751
    int i, c;
752
    int nodefault = 0;
753
    int printcache = 0;
754
    char *cp, *dir, *so;
755
    char *extpath;
756
    int libtype, islink;
757
    char *chroot_dir = NULL;
758
 
759
    prog = argv[0];
760
    opterr = 0;
761
 
762
    while ((c = getopt(argc, argv, "DvqnNXlpf:C:r:")) != EOF)
763
        switch (c)
764
        {
765
            case 'D':
766
                debug = 1;              /* debug mode */
767
                nocache = 1;
768
                nolinks = 1;
769
                verbose = 1;
770
                break;
771
            case 'v':
772
                verbose = 1;    /* verbose mode */
773
                break;
774
            case 'q':
775
                if (verbose <= 0)
776
                    verbose = -1;       /* quiet mode */
777
                break;
778
            case 'n':
779
                nodefault = 1;  /* no default dirs */
780
                nocache = 1;
781
                break;
782
            case 'N':
783
                nocache = 1;    /* don't build cache */
784
                break;
785
            case 'X':
786
                nolinks = 1;    /* don't update links */
787
                break;
788
            case 'l':
789
                libmode = 1;    /* library mode */
790
                break;
791
            case 'p':
792
                printcache = 1; /* print cache */
793
                break;
794
            case 'f':
795
                conffile = optarg;      /* alternate conf file */
796
                break;
797
            case 'C':
798
                cachefile = optarg;     /* alternate cache file */
799
                break;
800
            case 'r':
801
                chroot_dir = optarg;
802
                break;
803
            default:
804
                usage();
805
                break;
806
 
807
                /* THE REST OF THESE ARE UNDOCUMENTED AND MAY BE REMOVED
808
                   IN FUTURE VERSIONS. */
809
        }
810
 
811
    if (chroot_dir && *chroot_dir) {
812
        if (chroot(chroot_dir) < 0)
813
            err(EXIT_FATAL,"couldn't chroot to %s (%s)", chroot_dir, strerror(errno));
814
        if (chdir("/") < 0)
815
            err(EXIT_FATAL,"couldn't chdir to / (%s)", strerror(errno));
816
    }
817
 
818
    /* allow me to introduce myself, hi, my name is ... */
819
    if (verbose > 0)
820
        printf("%s: uClibc version\n", argv[0]);
821
 
822
    if (printcache)
823
    {
824
        /* print the cache -- don't you trust me? */
825
        cache_print();
826
        exit(EXIT_OK);
827
    }
828
    else if (libmode)
829
    {
830
        /* so you want to do things manually, eh? */
831
 
832
        /* ok, if you're so smart, which libraries do we link? */
833
        for (i = optind; i < argc; i++)
834
        {
835
            /* split into directory and file parts */
836
            if (!(cp = strrchr(argv[i], '/')))
837
            {
838
                dir = ".";      /* no dir, only a filename */
839
                cp = argv[i];
840
            }
841
            else
842
            {
843
                if (cp == argv[i])
844
                    dir = "/";  /* file in root directory */
845
                else
846
                    dir = argv[i];
847
                *cp++ = '\0';   /* neither of the above */
848
            }
849
 
850
            /* we'd better do a little bit of checking */
851
            if ((so = is_shlib(dir, cp, &libtype, &islink, LIB_ANY)) == NULL)
852
                err(EXIT_FATAL,"%s%s%s is not a shared library", dir,
853
                        (*dir && strcmp(dir, "/")) ? "/" : "", cp);
854
 
855
            /* so far, so good, maybe he knows what he's doing */
856
            link_shlib(dir, cp, so);
857
        }
858
    }
859
    else
860
    {
861
        /* the lazy bum want's us to do all the work for him */
862
 
863
        /* don't cache dirs on the command line */
864
        int nocache_save = nocache;
865
        nocache = 1;
866
 
867
        /* OK, which directories should we do? */
868
        for (i = optind; i < argc; i++)
869
            scan_dir(argv[i]);
870
 
871
        /* restore the desired caching state */
872
        nocache = nocache_save;
873
 
874
        /* look ma, no defaults */
875
        if (!nodefault)
876
        {
877
            /* I guess the defaults aren't good enough */
878
            if ((extpath = get_extpath()))
879
            {
880
                for (cp = strtok(extpath, DIR_SEP); cp;
881
                        cp = strtok(NULL, DIR_SEP))
882
                    scan_dir(cp);
883
                free(extpath);
884
            }
885
 
886
            scan_dir(UCLIBC_RUNTIME_PREFIX "/usr/X11R6/lib");
887
            scan_dir(UCLIBC_RUNTIME_PREFIX "/usr/lib");
888
            scan_dir(UCLIBC_RUNTIME_PREFIX "/lib");
889
        }
890
 
891
#ifdef USE_CACHE
892
        if (!nocache)
893
            cache_write();
894
#endif
895
    }
896
 
897
    exit(EXIT_OK);
898
}
899
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.