#!/usr/bin/perl
# $RedRiver$
use strict;
use warnings;
# find www/ -name *.so* | xargs find_depends | sort -u | xargs -I {} cp {} /home/andrew/www{}
#use OpenBSD::PackageInfo;
#use OpenBSD::PackingList;
#use OpenBSD::SharedLibs;
#use Data::Dumper;
#my $dir = '/var/db/pkg';
#my $pkg = 'p5-DBD-mysql-3.0002';
#my $pkg = 'p5-DBD-mysql';
#my $file = shift || '/usr/local/libdata/perl5/site_perl/i386-openbsd/auto/DBD/mysql/mysql.so';
die unless @ARGV;
my %libs;
foreach my $file (@ARGV) {
my $libs = find_libs($file);
#print Dumper $libs;
foreach (keys %{ $libs }) {
$libs{ $_ } = $libs->{$_};
}
}
foreach (keys %libs) {
print $libs{$_}, "\n";
}
exit;
#OpenBSD::SharedLibs::add_system_libs('/');
#print installed_packages();
#print installed_name($pkg);
#print info_names();
#exit;
#my $plist = OpenBSD::PackingList->from_installation($pkg) || die $!;
#print Dumper $plist->{wantlib};
#print Dumper $OpenBSD::SharedLibs::registered_libs;
#foreach (@{ $plist->{wantlib} }) {
# print Dumper $_->{name}, find_library($_->{name});
#}
#sub find_library
#{
# my $spec = shift;
# my @r;
# OpenBSD::SharedLibs::add_system_libs('/');
#
# my $lib = '/usr';
# @r = OpenBSD::SharedLibs::lookup_libspec('/usr', $spec);
# unless (@r) {
# $lib = '/usr/X11R6';
# @r = OpenBSD::SharedLibs::lookup_libspec('/usr/X11R6', $spec);
# }
# unless (@r) {
# for my $pkg (installed_packages()) {
# OpenBSD::SharedLibs::add_package_libs($pkg, 1);
# }
# $lib = '/usr/local';
# @r = OpenBSD::SharedLibs::lookup_libspec('/usr/local', $spec);
# }
# return $lib, @r;
#}
sub find_libs
{
my $file = shift;
my $ld = shift || get_ldconfig();
my $locs = shift || {};
print STDERR "Finding libs for '$file'\n";
my @libs = search_file($file);
foreach (@libs) {
my ($name, $maj, $min) = $_ =~ /^([^\.]+)\.so\.(\d+)\.(\d+)$/;
my $spec = 'l' . $name . '.' . $maj . '.' . $min;
if (exists $ld->{$spec}) {
next if exists $locs->{$spec};
$locs->{$spec} = $ld->{$spec};
$locs = find_libs($locs->{$spec}, $ld, $locs);
} else {
warn "Couldn't find location for lib '$_'";
}
}
return $locs;
}
sub search_file
{
my $file = shift;
my @libs;
open my $libs, '<', $file or die;
local $/ = chr(0);
while (<$libs>) {
if (m|^(/[^\w\/]+/)?lib(\S+)\.(\d+)\.(\d+)|) {
my ($path, $name, $major, $minor) = ($1, $2, $3, $4);
my $spec="$name.$major.$minor";
if (defined $path && $path ne '/usr/local/lib') {
$spec="$path/$spec";
}
push @libs, $spec;
}
}
close $libs;
return @libs;
}
sub get_ldconfig
{
my $ldconfig = '/sbin/ldconfig';
my (%paths, %libs);
open my $ld, '-|', $ldconfig, '-r' or die;
while (<$ld>) {
chomp;
if (/search directories:\s+(.*)/) {
#search directories: /usr/lib:/usr/local/lib
my @p = split /:/, $1;
@paths{@p} = 1;
} elsif (/\d+:-(\S+)\s+=>\s+(\S+)/) {
#0:-ldes.9.0 => /usr/lib/libdes.so.9.0
my $lib = $1;
my $loc = $2;
#my ($name, $maj, $min) = $lib =~ /l([^\.]+)\.(\d+)\.(\d+)/;
#my $spec = 'lib' . $name . '.so.' . $maj . '.' . $min;
$libs{$lib} = $loc;
} else {
#print $_, "\n";
}
}
close $ld;
$libs{_paths} = [ keys %paths ];
return \%libs;
}