home *** CD-ROM | disk | FTP | other *** search
/ H4CK3R 4 / hacker04 / 04_HACK04.ISO / darwin / darwinx86.iso / usr / bin / dpkg-shlibdeps < prev    next >
Encoding:
Text File  |  2001-09-18  |  7.8 KB  |  239 lines

  1. #! /usr/bin/perl
  2.  
  3. my $dpkglibdir, $version;
  4.  
  5. BEGIN { 
  6.     $dpkglibdir="/usr/share/dpkg";
  7.     $version=""; # This line modified by Makefile
  8.     push (@INC, $dpkglibdir); 
  9. }
  10.  
  11. use POSIX;
  12. use POSIX qw(:errno_h :signal_h);
  13.  
  14. require 'controllib.pl';
  15.  
  16. $shlibsoverride= '/etc/dpkg/shlibs.override';
  17. $shlibsdefault= '/etc/dpkg/shlibs.default';
  18. $shlibslocal= 'debian/shlibs.local';
  19. $shlibsppdir= '/var/lib/dpkg/info';
  20. $shlibsppext= '.shlibs';
  21. $varnameprefix= 'shlibs';
  22. $dependencyfield= 'Depends';
  23. $varlistfile= 'debian/substvars';
  24.  
  25. @depfields= qw(Suggests Recommends Depends Pre-Depends);
  26.  
  27. sub usageversion {
  28.     print STDERR
  29. "Debian GNU/Linux dpkg-shlibdeps $version.  Copyright (C) 1996
  30. Ian Jackson.  This is free software; see the GNU General Public Licence
  31. version 2 or later for copying conditions.  There is NO warranty.
  32.  
  33. Usage:
  34.   dpkg-shlibdeps [<option> ...] <executable>|-e<executable> [<option>] ...
  35. Positional arguments/options (order is significant):
  36.        <executable>           } include dependencies for <executable>
  37.        -e<executable>         }  (use -e if <executable> starts with \`-')
  38.        -d<dependencyfield>    next executable(s) set shlibs:<dependencyfield>
  39. Overall options (have global effect no matter where placed):
  40.        -p<varnameprefix>      set <varnameprefix>:* instead of shlibs:*.
  41.        -O                     print variable settings to stdout
  42.        -L<localshlibsfile>    shlibs override file, not debian/shlibs.local
  43.        -T<varlistfile>        update variables here, not debian/substvars
  44. Dependency fields recognised are ".join("/",@depfields)."
  45. ";
  46. }
  47.  
  48. $i=0; grep($depstrength{$_}= ++$i, @depfields);
  49.  
  50. while (@ARGV) {
  51.     $_=shift(@ARGV);
  52.     if (m/^-T/) {
  53.         $varlistfile= $';
  54.     } elsif (m/^-p(\w[-:0-9A-Za-z]*)$/) {
  55.         $varnameprefix= $1;
  56.     } elsif (m/^-L/) {
  57.         $shlibslocal= $';
  58.     } elsif (m/^-O$/) {
  59.         $stdout= 1;
  60.     } elsif (m/^-h$/) {
  61.         usageversion; exit(0);
  62.     } elsif (m/^-d/) {
  63.         $dependencyfield= capit($');
  64.         defined($depstrength{$dependencyfield}) ||
  65.             &warn("unrecognised dependency field \`$dependencyfield'");
  66.     } elsif (m/^-e/) {
  67.         push(@exec,$'); push(@execf,$dependencyfield);
  68.     } elsif (m/^-/) {
  69.         usageerr("unknown option \`$_'");
  70.     } else {
  71.         push(@exec,$_); push(@execf,$dependencyfield);
  72.     }
  73. }
  74.  
  75. @exec || usageerr("need at least one executable");
  76.  
  77. sub isbin {
  78.     open (F, $_[0]) || die("unable to open '$_[0]' for test");
  79.     if (read (F, $d, 4) != 4) {
  80.        die ("unable to read first four bytes of '$_[0]' as magic number");
  81.     }
  82.     if ($d =~ /^\177ELF$/) { # ELF binary
  83.        return 1;
  84.     } elsif (unpack ('N', $d) == 0xfeedface) { # NeXTstep binary
  85.        return 0;
  86.     } elsif ($d =~ /^\#\!..$/) { # shell script
  87.        return 0;
  88.     } elsif (unpack ('N', $d) == 0xcafebabe) { # JAVA binary
  89.        return 0;
  90.     } else {
  91.        die("unrecognized file type for '$_[0]'");
  92.     }
  93. }
  94.  
  95. for ($i=0;$i<=$#exec;$i++) {
  96.     if (!isbin ($exec[$i])) { next; }
  97.     defined($c= open(P,"-|")) || syserr("cannot fork for ldd");
  98.     if (!$c) { exec("ldd","--",$exec[$i]); syserr("cannot exec ldd"); }
  99.     $nthisldd=0;
  100.     while (<P>) {
  101.         chomp;
  102.     if (m,^\s+(\S+)\s+\=\>\s+\1$,) {
  103.         # shared libraries depend on themselves (unsure why)
  104.         # Only under old ld.so
  105.         $nthisldd++;
  106.     } elsif (m,\s+statically linked(\s+\(ELF\))?$,) {
  107.         $nthisldd++;
  108.     } elsif (m,^\s+(\S+)\.so\.(\S+)\s+=>\s+(/\S+)(\s+\(0x.+\))?$,) {
  109.         push(@libname,$1); push(@libsoname,$2); push(@libpath,$3);
  110.         push(@libf,$execf[$i]);
  111.         push(@libpaths,$3) if !$libpathadded{$3}++;
  112.         $nthisldd++;
  113.     } else {
  114.         &warn("unknown output from ldd on \`$exec[$i]': \`$_'");
  115.     }
  116.     }
  117.     close(P); $? && subprocerr("ldd on \`$exec[$i]'");
  118.     $nthisldd || &warn("ldd on \`$exec[$i]' gave nothing on standard output");
  119. }
  120.  
  121. if ($#libpaths >= 0) {
  122.     grep(s/\[\?\*/\\$&/g, @libpaths);
  123.     defined($c= open(P,"-|")) || syserr("cannot fork for dpkg --search");
  124.     if (!$c) { exec("dpkg","--search","--",@libpaths); syserr("cannot exec dpkg"); }
  125.     while (<P>) {
  126.        s/\n$//;
  127.        if (m/^local diversion |^diversion by/) {
  128.            &warn("diversions involved - output may be incorrect");
  129.            print(STDERR " $_\n") || syserr("write diversion info to stderr");
  130.        } elsif (m=^(\S+(, \S+)*): (/.+)$=) {
  131.            $pathpackages{$+}= $1;
  132.        } else {
  133.            &warn("unknown output from dpkg --search: \`$_'");
  134.        }
  135.     }
  136.     close(P); $? && subprocerr("dpkg --search");
  137. }
  138.  
  139. LIB: for ($i=0;$i<=$#libname;$i++) {
  140.     scanshlibsfile($shlibslocal,$libname[$i],$libsoname[$i],$libf[$i]) && next;
  141.     scanshlibsfile($shlibsoverride,$libname[$i],$libsoname[$i],$libf[$i]) && next;
  142.     if (!defined($pathpackages{$libpath[$i]})) {
  143.         &warn("could not find any packages for $libpath[$i]".
  144.               " ($libname[$i].so.$libsoname[$i])");
  145.     } else {
  146.         @packages= split(/, /,$pathpackages{$libpath[$i]});
  147.         for $p (@packages) {
  148.             scanshlibsfile("$shlibsppdir/$p$shlibsppext",
  149.                            $libname[$i],$libsoname[$i],$libf[$i])
  150.                 && next LIB;
  151.         }
  152.     }
  153.     scanshlibsfile($shlibsdefault,$libname[$i],$libsoname[$i],$libf[$i]) && next;
  154.     &warn("unable to find dependency information for ".
  155.           "shared library $libname[$i] (soname $libsoname[$i], path $libpath[$i], ".
  156.           "dependency field $libf[$i])");
  157. }
  158.  
  159. sub scanshlibsfile {
  160.     my ($fn,$ln,$lsn,$lf) = @_;
  161.     my ($da,$dv,$dk);
  162.     $fn= "./$fn" if $fn =~ m/^\s/;
  163.     if (!open(SLF,"< $fn")) {
  164.         $! == ENOENT || syserr("unable to open shared libs info file \`$fn'");
  165. #print STDERR "scanshlibsfile($fn,$ln,$lsn,$lf) ... ENOENT\n";
  166.         return 0;
  167.     }
  168. #print STDERR "scanshlibsfile($fn,$ln,$lsn,$lf) ...\n";
  169.     while (<SLF>) {
  170.         s/\s*\n$//; next if m/^\#/;
  171.         if (!m/^\s*(\S+)\s+(\S+)/) {
  172.             &warn("shared libs info file \`$fn' line $.: bad line \`$_'");
  173.             next;
  174.         }
  175.         next if $1 ne $ln || $2 ne $lsn;
  176.         $da= $';
  177.         for $dv (split(/,/,$da)) {
  178.             $dv =~ s/^\s+//; $dv =~ s/\s+$//;
  179.             if (defined($depstrength{$lf})) {
  180.                 if (!defined($predefdepfdep{$dv}) ||
  181.                     $depstrength{$predefdepfdep{$dv}} < $depstrength{$lf}) {
  182.                     $predefdepfdep{$dv}= $lf;
  183.                 }
  184.             } else {
  185.                 $dk= "$lf: $dv";
  186.                 if (!defined($unkdepfdone{$dk})) {
  187.                     $unkdepfdone{$dk}= 1;
  188.                     $unkdepf{$lf}.= ', ' if length($unkdepf{$lf});
  189.                     $unkdepf{$lf}.= $dv;
  190.                 }
  191.             }
  192.         }
  193.         return 1;
  194.     }
  195.     close(SLF);
  196.     return 0;
  197. }
  198.  
  199. if (!$stdout) {
  200.     $varlistfile="./$varlistfile" if $fileslistfile =~ m/^\s/;
  201.     open(Y,"> $varlistfile.new") ||
  202.         syserr("open new substvars file \`$varlistfile.new'");
  203.     my (@fowner) = &getfowner ();
  204.     chown (@fowner, "$varlistfile.new") ||
  205.     syserr ("chown of \`$varlistfile.new'");
  206.     if (open(X,"< $varlistfile")) {
  207.         while (<X>) {
  208.             s/\n$//;
  209.             next if m/^(\w[-:0-9A-Za-z]*):/ && $1 eq $varnameprefix;
  210.             print(Y "$_\n") ||
  211.                 syserr("copy old entry to new varlist file \`$varlistfile.new'");
  212.         }
  213.     } elsif ($! != ENOENT) {
  214.         syserr("open old varlist file \`$varlistfile' for reading");
  215.     }
  216.     $fh= 'Y';
  217. } else {
  218.     $fh= 'STDOUT';
  219. }
  220. for $dv (sort keys %predefdepfdep) {
  221.     $lf= $predefdepfdep{$dv};
  222.     $defdepf{$lf}.= ', ' if length($defdepf{$lf});
  223.     $defdepf{$lf}.= $dv;
  224. }
  225. for $lf (reverse @depfields) {
  226.     next unless defined($defdepf{$lf});
  227.     print($fh "$varnameprefix:$lf=$defdepf{$lf}\n")
  228.         || syserr("write output entry");
  229. }
  230. for $lf (sort keys %unkdepf) {
  231.     print($fh "$varnameprefix:$lf=$unkdepf{$lf}\n")
  232.         || syserr("write userdef output entry");
  233. }
  234. close($fh) || syserr("close output");
  235. if (!$stdout) {
  236.     rename("$varlistfile.new",$varlistfile) ||
  237.         syserr("install new varlist file \`$varlistfile'");
  238. }
  239.