Annotation of openbsd/fill_chroot/find_depends, Revision 1.12
1.1 andrew 1: #!/usr/bin/perl
1.12 ! andrew 2: # $RedRiver: find_depends,v 1.11 2008/09/16 22:28:53 andrew Exp $
1.1 andrew 3: use strict;
4: use warnings;
5:
1.4 andrew 6: my %opts;
1.3 andrew 7: my @Files;
8:
9: foreach (@ARGV) {
1.4 andrew 10: if (/^-+(\w+)$/) {
1.3 andrew 11: $opts{$1} = 1;
12: } else {
13: push @Files, $_;
14: }
15: }
16:
1.4 andrew 17: Help() if $opts{h} || $opts{help};
18: Usage() unless @Files;
1.1 andrew 19:
20: my %libs;
1.2 andrew 21:
1.3 andrew 22: foreach my $file (@Files) {
1.2 andrew 23: my $l = find_libs($file);
24:
25: foreach (keys %{ $l }) {
26: $libs{$_} = $l->{$_};
1.1 andrew 27: }
28: }
29:
30: foreach (keys %libs) {
31: print $libs{$_}, "\n";
32: }
33:
34: exit;
35:
1.4 andrew 36: sub Usage
37: {
38: print "Usage: $0 [-v] file [file2 [file3 [...]]]\n";
39: exit;
40: }
41:
42: sub Help
43: {
44: print <<EOL;
45: Hopefully finds all libraries that are required by an executable
46: or shared library.
47:
48: Usage:
49: $0 [-v] file [file2 [file3 [...]]]
50:
51: Example:
52: find /var/www/ -name *.so* | xargs find_depends | \\
53: sort -u | xargs -I {} cp {} /var/www{}
54: EOL
55:
56: exit;
57: }
58:
1.1 andrew 59: sub find_libs
60: {
61: my $file = shift;
62: my $ld = shift || get_ldconfig();
63: my $locs = shift || {};
64:
1.4 andrew 65: print STDERR "Finding libs for '$file'\n" if $opts{v};
1.1 andrew 66:
67: my @libs = search_file($file);
68: foreach (@libs) {
1.11 andrew 69: my $spec;
70:
1.12 ! andrew 71: if ($_ eq $file) {
! 72: # We don't want to include the file we are looking in
! 73: next;
1.11 andrew 74: }
1.12 ! andrew 75: elsif ( my ($name, $maj, $min) = $_ =~ /lib([^\/]+)\.so\.(\d+)\.(\d+)$/ ) {
! 76: $spec = 'l' . $name . '.' . $maj . '.' . $min;
! 77: if ($ld->{$spec}) {
! 78: $locs->{$spec} = $ld->{$spec};
1.11 andrew 79: }
80: }
1.12 ! andrew 81: elsif (-e $_) {
! 82: $spec = $_;
! 83: $locs->{$spec} = $spec;
1.11 andrew 84: }
85: else {
1.12 ! andrew 86: next;
1.11 andrew 87: }
88:
89: if (! $locs->{$spec}) {
90: print STDERR "Couldn't find location for '$_' (file '$file')\n";
91: next;
92: }
1.12 ! andrew 93:
! 94: print " Found '$spec' => '$locs->{$spec}'\n" if $opts{v};
1.1 andrew 95:
1.11 andrew 96: $locs = find_libs($locs->{$spec}, $ld, $locs);
1.1 andrew 97:
98: }
99:
100: return $locs;
101: }
102:
103: sub search_file
104: {
105: my $file = shift;
106: my @libs;
1.7 andrew 107:
108: open my $libs, '-|', '/usr/bin/ldd', $file or die "Couldn't open ldd '$file': $!";
1.1 andrew 109: while (<$libs>) {
1.7 andrew 110: chomp;
1.9 andrew 111: my ($spec) = (split(/\s+/, $_))[7];
112: next if ! $spec;
1.7 andrew 113: next if $spec !~ m{^/}xms;
114: push @libs, $spec;
1.1 andrew 115: }
116: close $libs;
117:
118: return @libs;
119: }
120:
121: sub get_ldconfig
122: {
123: my $ldconfig = '/sbin/ldconfig';
124: my (%paths, %libs);
125:
1.4 andrew 126: open my $ld, '-|', $ldconfig, '-r'
127: or die "Couldn't open pipe to ldconfig: $!";
1.1 andrew 128: while (<$ld>) {
129: chomp;
130: if (/search directories:\s+(.*)/) {
131: #search directories: /usr/lib:/usr/local/lib
132: my @p = split /:/, $1;
133: @paths{@p} = 1;
134: } elsif (/\d+:-(\S+)\s+=>\s+(\S+)/) {
135: #0:-ldes.9.0 => /usr/lib/libdes.so.9.0
136: my $lib = $1;
137: my $loc = $2;
138: #my ($name, $maj, $min) = $lib =~ /l([^\.]+)\.(\d+)\.(\d+)/;
139: #my $spec = 'lib' . $name . '.so.' . $maj . '.' . $min;
140: $libs{$lib} = $loc;
141: } else {
142: #print $_, "\n";
143: }
144: }
145: close $ld;
146:
147: $libs{_paths} = [ keys %paths ];
148: return \%libs;
149: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>