Annotation of openbsd/fill_chroot/find_depends, Revision 1.11
1.1 andrew 1: #!/usr/bin/perl
1.11 ! andrew 2: # $RedRiver: find_depends,v 1.10 2008/09/16 22:15:03 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:
! 71: if (/\/ld\.so$/) {
! 72: $spec = $_;
! 73: }
! 74: else {
! 75: if ( my ($name, $maj, $min) = $_ =~ /lib([^\/]+)\.so\.(\d+)\.(\d+)$/ ) {
! 76: $spec = 'l' . $name . '.' . $maj . '.' . $min;
! 77: }
! 78: }
! 79:
! 80: next if ! $spec;
! 81: next if exists $locs->{$spec};
! 82:
1.10 andrew 83: print " Found spec '$spec'\n" if $opts{v};
1.1 andrew 84:
1.11 ! andrew 85: if (-e $spec) {
! 86: $locs->{$spec} = $spec;
! 87: }
! 88: else {
! 89: $locs->{$spec} = $ld->{$spec};
! 90: }
! 91:
! 92: if (! $locs->{$spec}) {
! 93: print STDERR "Couldn't find location for '$_' (file '$file')\n";
! 94: next;
! 95: }
1.1 andrew 96:
1.11 ! andrew 97: $locs = find_libs($locs->{$spec}, $ld, $locs);
1.1 andrew 98:
99: }
100:
101: return $locs;
102: }
103:
104: sub search_file
105: {
106: my $file = shift;
107: my @libs;
1.7 andrew 108:
109: open my $libs, '-|', '/usr/bin/ldd', $file or die "Couldn't open ldd '$file': $!";
1.1 andrew 110: while (<$libs>) {
1.7 andrew 111: chomp;
1.9 andrew 112: my ($spec) = (split(/\s+/, $_))[7];
113: next if ! $spec;
1.7 andrew 114: next if $spec !~ m{^/}xms;
115: push @libs, $spec;
1.1 andrew 116: }
117: close $libs;
118:
119: return @libs;
120: }
121:
122: sub get_ldconfig
123: {
124: my $ldconfig = '/sbin/ldconfig';
125: my (%paths, %libs);
126:
1.4 andrew 127: open my $ld, '-|', $ldconfig, '-r'
128: or die "Couldn't open pipe to ldconfig: $!";
1.1 andrew 129: while (<$ld>) {
130: chomp;
131: if (/search directories:\s+(.*)/) {
132: #search directories: /usr/lib:/usr/local/lib
133: my @p = split /:/, $1;
134: @paths{@p} = 1;
135: } elsif (/\d+:-(\S+)\s+=>\s+(\S+)/) {
136: #0:-ldes.9.0 => /usr/lib/libdes.so.9.0
137: my $lib = $1;
138: my $loc = $2;
139: #my ($name, $maj, $min) = $lib =~ /l([^\.]+)\.(\d+)\.(\d+)/;
140: #my $spec = 'lib' . $name . '.so.' . $maj . '.' . $min;
141: $libs{$lib} = $loc;
142: } else {
143: #print $_, "\n";
144: }
145: }
146: close $ld;
147:
148: $libs{_paths} = [ keys %paths ];
149: return \%libs;
150: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>