ldconfig.c (d5453ba5c4971fa25ab694501c39ad634315c9fc) ldconfig.c (f606c848fa4c2b07aff750b92c803d61f11d5e07)
1/*
2 * Copyright (c) 1993 Paul Kranenburg
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
1/*
2 * Copyright (c) 1993 Paul Kranenburg
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * $Id: ldconfig.c,v 1.8 1994/12/23 22:31:24 nate Exp $
30 * $Id: ldconfig.c,v 1.8 1994/06/16 13:38:32 pk Exp $
31 */
32
33#include <sys/param.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <sys/file.h>
37#include <sys/time.h>
38#include <sys/mman.h>

--- 15 unchanged lines hidden (view full) ---

54#undef major
55#undef minor
56
57extern char *__progname;
58
59static int verbose;
60static int nostd;
61static int justread;
31 */
32
33#include <sys/param.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <sys/file.h>
37#include <sys/time.h>
38#include <sys/mman.h>

--- 15 unchanged lines hidden (view full) ---

54#undef major
55#undef minor
56
57extern char *__progname;
58
59static int verbose;
60static int nostd;
61static int justread;
62static int merge;
62
63struct shlib_list {
64 /* Internal list of shared libraries found */
65 char *name;
66 char *path;
67 int dewey[MAXDEWEY];
68 int ndewey;
69#define major dewey[0]
70#define minor dewey[1]
71 struct shlib_list *next;
72};
73
74static struct shlib_list *shlib_head = NULL, **shlib_tail = &shlib_head;
75
76static void enter __P((char *, char *, char *, int *, int));
77static int dodir __P((char *, int));
63
64struct shlib_list {
65 /* Internal list of shared libraries found */
66 char *name;
67 char *path;
68 int dewey[MAXDEWEY];
69 int ndewey;
70#define major dewey[0]
71#define minor dewey[1]
72 struct shlib_list *next;
73};
74
75static struct shlib_list *shlib_head = NULL, **shlib_tail = &shlib_head;
76
77static void enter __P((char *, char *, char *, int *, int));
78static int dodir __P((char *, int));
78static int build_hints __P((void));
79static int listhints __P((void));
79static int buildhints __P((void));
80static int readhints __P((void));
81static void listhints __P((void));
80
81int
82main(argc, argv)
83int argc;
84char *argv[];
85{
86 int i, c;
87 int rval = 0;
88
82
83int
84main(argc, argv)
85int argc;
86char *argv[];
87{
88 int i, c;
89 int rval = 0;
90
89 while ((c = getopt(argc, argv, "rsv")) != EOF) {
91 while ((c = getopt(argc, argv, "mrsv")) != EOF) {
90 switch (c) {
92 switch (c) {
91 case 'v':
92 verbose = 1;
93 case 'm':
94 merge = 1;
93 break;
95 break;
96 case 'r':
97 justread = 1;
98 break;
94 case 's':
95 nostd = 1;
96 break;
99 case 's':
100 nostd = 1;
101 break;
97 case 'r':
98 justread = 1;
102 case 'v':
103 verbose = 1;
99 break;
100 default:
104 break;
105 default:
101 fprintf(stderr, "Usage: %s [-r][-s][-v][dir ...]\n",
106 errx(1, "Usage: %s [-m][-r][-s][-v][dir ...]",
102 __progname);
107 __progname);
103 exit(1);
104 break;
105 }
106 }
107
108 break;
109 }
110 }
111
108 if (justread)
109 return listhints();
112 if (justread || merge) {
113 if ((rval = readhints()) != 0)
114 return rval;
115 if (justread) {
116 listhints();
117 return;
118 }
119 }
110
111 if (!nostd)
112 std_search_path();
113
114 for (i = 0; i < n_search_dirs; i++)
115 rval |= dodir(search_dirs[i], 1);
116
117 for (i = optind; i < argc; i++)
118 rval |= dodir(argv[i], 0);
119
120
121 if (!nostd)
122 std_search_path();
123
124 for (i = 0; i < n_search_dirs; i++)
125 rval |= dodir(search_dirs[i], 1);
126
127 for (i = optind; i < argc; i++)
128 rval |= dodir(argv[i], 0);
129
120 rval |= build_hints();
130 rval |= buildhints();
121
122 return rval;
123}
124
125int
126dodir(dir, silent)
127char *dir;
128int silent;
129{
130 DIR *dd;
131 struct dirent *dp;
132 char name[MAXPATHLEN], rest[MAXPATHLEN];
133 int dewey[MAXDEWEY], ndewey;
134
135 if ((dd = opendir(dir)) == NULL) {
136 if (!silent || errno != ENOENT)
131
132 return rval;
133}
134
135int
136dodir(dir, silent)
137char *dir;
138int silent;
139{
140 DIR *dd;
141 struct dirent *dp;
142 char name[MAXPATHLEN], rest[MAXPATHLEN];
143 int dewey[MAXDEWEY], ndewey;
144
145 if ((dd = opendir(dir)) == NULL) {
146 if (!silent || errno != ENOENT)
137 perror(dir);
147 warn("%s", dir);
138 return -1;
139 }
140
141 while ((dp = readdir(dd)) != NULL) {
142 int n;
143
144 name[0] = rest[0] = '\0';
145

--- 77 unchanged lines hidden (view full) ---

223 k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
224
225 k = (((k << 1) + (k >> 14)) ^ (vmajor*257)) & 0x3fff;
226
227 return k;
228}
229
230int
148 return -1;
149 }
150
151 while ((dp = readdir(dd)) != NULL) {
152 int n;
153
154 name[0] = rest[0] = '\0';
155

--- 77 unchanged lines hidden (view full) ---

233 k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
234
235 k = (((k << 1) + (k >> 14)) ^ (vmajor*257)) & 0x3fff;
236
237 return k;
238}
239
240int
231build_hints()
241buildhints()
232{
233 struct hints_header hdr;
234 struct hints_bucket *blist;
235 struct shlib_list *shp;
236 char *strtab;
237 int i, n, str_index = 0;
238 int strtab_sz = 0; /* Total length of strings */
239 int nhints = 0; /* Total number of hints */

--- 39 unchanged lines hidden (view full) ---

279 if (bp->hi_pathx) {
280 int i;
281
282 for (i = 0; i < hdr.hh_nbucket; i++) {
283 if (blist[i].hi_pathx == 0)
284 break;
285 }
286 if (i == hdr.hh_nbucket) {
242{
243 struct hints_header hdr;
244 struct hints_bucket *blist;
245 struct shlib_list *shp;
246 char *strtab;
247 int i, n, str_index = 0;
248 int strtab_sz = 0; /* Total length of strings */
249 int nhints = 0; /* Total number of hints */

--- 39 unchanged lines hidden (view full) ---

289 if (bp->hi_pathx) {
290 int i;
291
292 for (i = 0; i < hdr.hh_nbucket; i++) {
293 if (blist[i].hi_pathx == 0)
294 break;
295 }
296 if (i == hdr.hh_nbucket) {
287 fprintf(stderr, "Bummer!\n");
297 warnx("Bummer!");
288 return -1;
289 }
290 while (bp->hi_next != -1)
291 bp = &blist[bp->hi_next];
292 bp->hi_next = i;
293 bp = blist + i;
294 }
295

--- 8 unchanged lines hidden (view full) ---

304
305 /* Copy versions */
306 bcopy(shp->dewey, bp->hi_dewey, sizeof(bp->hi_dewey));
307 bp->hi_ndewey = shp->ndewey;
308 }
309
310 tmpfile = concat(_PATH_LD_HINTS, "+", "");
311 if ((fd = open(tmpfile, O_RDWR|O_CREAT|O_TRUNC, 0444)) == -1) {
298 return -1;
299 }
300 while (bp->hi_next != -1)
301 bp = &blist[bp->hi_next];
302 bp->hi_next = i;
303 bp = blist + i;
304 }
305

--- 8 unchanged lines hidden (view full) ---

314
315 /* Copy versions */
316 bcopy(shp->dewey, bp->hi_dewey, sizeof(bp->hi_dewey));
317 bp->hi_ndewey = shp->ndewey;
318 }
319
320 tmpfile = concat(_PATH_LD_HINTS, "+", "");
321 if ((fd = open(tmpfile, O_RDWR|O_CREAT|O_TRUNC, 0444)) == -1) {
312 perror(_PATH_LD_HINTS);
322 warn("%s", _PATH_LD_HINTS);
313 return -1;
314 }
315
316 if (write(fd, &hdr, sizeof(struct hints_header)) !=
317 sizeof(struct hints_header)) {
323 return -1;
324 }
325
326 if (write(fd, &hdr, sizeof(struct hints_header)) !=
327 sizeof(struct hints_header)) {
318 perror(_PATH_LD_HINTS);
328 warn("%s", _PATH_LD_HINTS);
319 return -1;
320 }
321 if (write(fd, blist, hdr.hh_nbucket * sizeof(struct hints_bucket)) !=
322 hdr.hh_nbucket * sizeof(struct hints_bucket)) {
329 return -1;
330 }
331 if (write(fd, blist, hdr.hh_nbucket * sizeof(struct hints_bucket)) !=
332 hdr.hh_nbucket * sizeof(struct hints_bucket)) {
323 perror(_PATH_LD_HINTS);
333 warn("%s", _PATH_LD_HINTS);
324 return -1;
325 }
326 if (write(fd, strtab, strtab_sz) != strtab_sz) {
334 return -1;
335 }
336 if (write(fd, strtab, strtab_sz) != strtab_sz) {
327 perror(_PATH_LD_HINTS);
337 warn("%s", _PATH_LD_HINTS);
328 return -1;
329 }
330 if (close(fd) != 0) {
338 return -1;
339 }
340 if (close(fd) != 0) {
331 perror(_PATH_LD_HINTS);
341 warn("%s", _PATH_LD_HINTS);
332 return -1;
333 }
334
335 /* Install it */
336 if (unlink(_PATH_LD_HINTS) != 0 && errno != ENOENT) {
342 return -1;
343 }
344
345 /* Install it */
346 if (unlink(_PATH_LD_HINTS) != 0 && errno != ENOENT) {
337 perror(_PATH_LD_HINTS);
347 warn("%s", _PATH_LD_HINTS);
338 return -1;
339 }
340
341 if (rename(tmpfile, _PATH_LD_HINTS) != 0) {
348 return -1;
349 }
350
351 if (rename(tmpfile, _PATH_LD_HINTS) != 0) {
342 perror(_PATH_LD_HINTS);
352 warn("%s", _PATH_LD_HINTS);
343 return -1;
344 }
345
346 return 0;
347}
348
349static int
353 return -1;
354 }
355
356 return 0;
357}
358
359static int
350listhints()
360readhints()
351{
352 int fd;
353 caddr_t addr;
354 long msize;
355 struct hints_header *hdr;
356 struct hints_bucket *blist;
357 char *strtab;
361{
362 int fd;
363 caddr_t addr;
364 long msize;
365 struct hints_header *hdr;
366 struct hints_bucket *blist;
367 char *strtab;
368 struct shlib_list *shp;
358 int i;
359
360 if ((fd = open(_PATH_LD_HINTS, O_RDONLY, 0)) == -1) {
369 int i;
370
371 if ((fd = open(_PATH_LD_HINTS, O_RDONLY, 0)) == -1) {
361 perror(_PATH_LD_HINTS);
372 warn("%s", _PATH_LD_HINTS);
362 return -1;
363 }
364
365 msize = PAGSIZ;
366 addr = mmap(0, msize, PROT_READ, MAP_COPY, fd, 0);
367
368 if (addr == (caddr_t)-1) {
373 return -1;
374 }
375
376 msize = PAGSIZ;
377 addr = mmap(0, msize, PROT_READ, MAP_COPY, fd, 0);
378
379 if (addr == (caddr_t)-1) {
369 perror(_PATH_LD_HINTS);
380 warn("%s", _PATH_LD_HINTS);
370 return -1;
371 }
372
373 hdr = (struct hints_header *)addr;
374 if (HH_BADMAG(*hdr)) {
381 return -1;
382 }
383
384 hdr = (struct hints_header *)addr;
385 if (HH_BADMAG(*hdr)) {
375 fprintf(stderr, "%s: Bad magic: %o\n",
386 warnx("%s: Bad magic: %o",
376 _PATH_LD_HINTS, hdr->hh_magic);
377 return -1;
378 }
379
380 if (hdr->hh_version != LD_HINTS_VERSION_1) {
387 _PATH_LD_HINTS, hdr->hh_magic);
388 return -1;
389 }
390
391 if (hdr->hh_version != LD_HINTS_VERSION_1) {
381 fprintf(stderr, "Unsupported version: %d\n", hdr->hh_version);
392 warnx("Unsupported version: %d", hdr->hh_version);
382 return -1;
383 }
384
385 if (hdr->hh_ehints > msize) {
386 if (mmap(addr+msize, hdr->hh_ehints - msize,
387 PROT_READ, MAP_COPY|MAP_FIXED,
388 fd, msize) != (caddr_t)(addr+msize)) {
389
393 return -1;
394 }
395
396 if (hdr->hh_ehints > msize) {
397 if (mmap(addr+msize, hdr->hh_ehints - msize,
398 PROT_READ, MAP_COPY|MAP_FIXED,
399 fd, msize) != (caddr_t)(addr+msize)) {
400
390 perror(_PATH_LD_HINTS);
401 warn("%s", _PATH_LD_HINTS);
391 return -1;
392 }
393 }
394 close(fd);
395
396 blist = (struct hints_bucket *)(addr + hdr->hh_hashtab);
397 strtab = (char *)(addr + hdr->hh_strtab);
398
402 return -1;
403 }
404 }
405 close(fd);
406
407 blist = (struct hints_bucket *)(addr + hdr->hh_hashtab);
408 strtab = (char *)(addr + hdr->hh_strtab);
409
399 printf("%s:\n", _PATH_LD_HINTS);
400 for (i = 0; i < hdr->hh_nbucket; i++) {
401 struct hints_bucket *bp = &blist[i];
402
403 /* Sanity check */
404 if (bp->hi_namex >= hdr->hh_strtab_sz) {
410 for (i = 0; i < hdr->hh_nbucket; i++) {
411 struct hints_bucket *bp = &blist[i];
412
413 /* Sanity check */
414 if (bp->hi_namex >= hdr->hh_strtab_sz) {
405 fprintf(stderr, "Bad name index: %#x\n", bp->hi_namex);
415 warnx("Bad name index: %#x", bp->hi_namex);
406 return -1;
407 }
408 if (bp->hi_pathx >= hdr->hh_strtab_sz) {
416 return -1;
417 }
418 if (bp->hi_pathx >= hdr->hh_strtab_sz) {
409 fprintf(stderr, "Bad path index: %#x\n", bp->hi_pathx);
419 warnx("Bad path index: %#x", bp->hi_pathx);
410 return -1;
411 }
412
420 return -1;
421 }
422
413 printf("\t%d:-l%s.%d.%d => %s (%d -> %d)\n",
414 i,
415 strtab + bp->hi_namex, bp->hi_major, bp->hi_minor,
416 strtab + bp->hi_pathx,
417 hinthash(strtab+bp->hi_namex, bp->hi_major)
418 % hdr->hh_nbucket,
419 bp->hi_next);
423 /* Allocate new list element */
424 shp = (struct shlib_list *)xmalloc(sizeof *shp);
425 shp->name = strdup(strtab + bp->hi_namex);
426 shp->path = strdup(strtab + bp->hi_pathx);
427 bcopy(bp->hi_dewey, shp->dewey, sizeof(shp->dewey));
428 shp->ndewey = bp->hi_ndewey;
429 shp->next = NULL;
430
431 *shlib_tail = shp;
432 shlib_tail = &shp->next;
420 }
421
422 return 0;
423}
424
433 }
434
435 return 0;
436}
437
438static void
439listhints()
440{
441 struct shlib_list *shp;
442 int i;
443
444 printf("%s:\n", _PATH_LD_HINTS);
445
446 for (i = 0, shp = shlib_head; shp; i++, shp = shp->next)
447 printf("\t%d:-l%s.%d.%d => %s\n",
448 i, shp->name, shp->major, shp->minor, shp->path);
449
450 return;
451}
452