168 lines
3.5 KiB
Perl
Executable File
168 lines
3.5 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
|
|
use File::Basename;
|
|
use Getopt::Long;
|
|
|
|
# this dependency analysis program is the only one which need to know
|
|
# the RPM buildroot to do its work.
|
|
|
|
# Figuring out what files are really executables via magic numbers is
|
|
# hard. Not only is every '#!' an executable of some type (with a
|
|
# potentially infinite supply of interpreters) but there are thousands
|
|
# of valid binary magic numbers for old OS's and old CPU types.
|
|
|
|
# Permissions do not always help discriminate binaries from the rest
|
|
# of the files, on Solaris the shared libraries are marked as
|
|
# 'executable'.
|
|
|
|
# -rwxr-xr-x 1 bin bin 1013248 Jul 1 1998 /lib/libc.so.1
|
|
|
|
# I would like to let the 'file' command take care of the magic
|
|
# numbers for us. Alas! under linux file prints different kind of
|
|
# messages for each interpreter, there is no common word 'script' to
|
|
# look for.
|
|
|
|
# ' perl commands text'
|
|
# ' Bourne shell script text'
|
|
# ' a /usr/bin/wish -f script text'
|
|
|
|
# WORSE on solaris there are entries which say:
|
|
|
|
# ' current ar archive, not a dynamic executable or shared object'
|
|
|
|
# how do I grep for 'executable' when people put a 'not executable' in
|
|
# there? I trim off everything after the first comma (if there is
|
|
# one) and if the result has the string 'executable' in it then it may
|
|
# be one.
|
|
|
|
|
|
# so we must also do some magic number processing ourselves, and be
|
|
# satisfied with 'good enough'.
|
|
|
|
# I look for files which have atleast one of the executable bits set
|
|
# and are either labled 'executable' by the file command (see above
|
|
# restriction) OR have a '#!' as their first two characters.
|
|
|
|
|
|
$is_mode_executable=oct(111);
|
|
|
|
# set a known path
|
|
|
|
$ENV{'PATH'}= (
|
|
':/usr/bin'.
|
|
':/bin'.
|
|
'');
|
|
|
|
# taint perl requires we clean up these bad environmental variables.
|
|
|
|
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
|
|
|
|
$BUILDROOT = '';
|
|
%option_linkage = (
|
|
"buildroot" => \$BUILDROOT,
|
|
);
|
|
|
|
if( !GetOptions (\%option_linkage, "buildroot=s") ) {
|
|
die("Illegal options in \@ARGV: '@ARGV'\n");
|
|
|
|
}
|
|
|
|
if ($BUILDROOT == '/') {
|
|
$BUILDROOT = '';
|
|
}
|
|
|
|
if ("@ARGV") {
|
|
foreach (@ARGV) {
|
|
process_file($_);
|
|
}
|
|
} else {
|
|
|
|
# notice we are passed a list of filenames NOT as common in unix the
|
|
# contents of the file.
|
|
|
|
foreach (<>) {
|
|
process_file($_);
|
|
}
|
|
}
|
|
|
|
|
|
foreach $module (sort keys %provides) {
|
|
print "executable($module)\n";
|
|
}
|
|
|
|
exit 0;
|
|
|
|
|
|
|
|
|
|
sub is_file_script {
|
|
|
|
my ($file) = @_;
|
|
chomp $file;
|
|
|
|
my $out = 0;
|
|
open(FILE, "<$file")||
|
|
die("$0: Could not open file: '$file' : $!\n");
|
|
|
|
my $rc = sysread(FILE,$line,2);
|
|
|
|
if ( ($rc > 1) && ($line =~ m/^\#\!/) ) {
|
|
$out = 1;
|
|
}
|
|
|
|
close(FILE) ||
|
|
die("$0: Could not close file: '$file' : $!\n");
|
|
|
|
return $out;
|
|
}
|
|
|
|
|
|
|
|
sub is_file_binary_executable {
|
|
my ($file) = @_;
|
|
|
|
$file_out=`file $file`;
|
|
# trim off any extra descriptions.
|
|
$file_out =~ s/\,.*$//;
|
|
|
|
my $out = 0;
|
|
if ($file_out =~ m/executable/ ) {
|
|
$out = 1;
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
|
|
sub process_file {
|
|
my ($file) = @_;
|
|
chomp $file;
|
|
|
|
my $prov_name = $file;
|
|
$prov_name =~ s!^$BUILDROOT!!;
|
|
|
|
# If its a link find the file it points to. Dead links do not
|
|
# provide anything.
|
|
|
|
while (-l $file) {
|
|
my $newfile = readlink($file);
|
|
if ($newfile !~ m!^/!) {
|
|
$newfile = dirname($file).'/'.$newfile;
|
|
} else {
|
|
$newfile = $BUILDROOT.$newfile;
|
|
}
|
|
$file = $newfile;
|
|
}
|
|
|
|
(-f $file) || return ;
|
|
( (stat($file))[2] & $is_mode_executable ) || return ;
|
|
|
|
is_file_script($file) ||
|
|
is_file_binary_executable($file) ||
|
|
return ;
|
|
|
|
$provides{$prov_name}=1;
|
|
$provides{basename($prov_name)}=1;
|
|
|
|
return ;
|
|
}
|