gentoo-tools

Some Gentoo helper tools
git clone git://r-36.net/gentoo-tools
Log | Files | Refs | LICENSE

echeck-stat-brokeness (4788B)


      1 #!/usr/bin/perl
      2 #
      3 # This script was taken from the source below and is licenses under different
      4 # terms. It is renamed to fit the naming convention of all other tools.
      5 # -- Christoph Lohmann <20h@r-36.net>, 2015-09-09
      6 #
      7 # A Perl script for evaluating and summarising which executables in
      8 # the given directories depend on the old 32-bit stat() family APIs.
      9 #
     10 # Usage: summarise_stat.pl directory [...]
     11 #
     12 # Copyright (c) 2007,2013 Silicon Graphics, Inc.  All Rights Reserved.
     13 # By Greg Banks <gnb@melbourne.sgi.com>
     14 #
     15 # Updated 20130511 to correctly diagnose 64b executables
     16 #
     17 # This program is free software; you can redistribute it and/or modify
     18 # it under the terms of the GNU General Public License as published by
     19 # the Free Software Foundation; either version 2 of the License, or
     20 # (at your option) any later version.
     21 #
     22 # This program is distributed in the hope that it will be useful,
     23 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     24 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     25 # GNU General Public License for more details.
     26 #
     27 # You should have received a copy of the GNU General Public License
     28 # along with this program; if not, write to the Free Software
     29 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     30 #
     31 
     32 use strict;
     33 use warnings;
     34 
     35 my @pathnames;		# file and directories to read, from the commandline
     36 my @summ;
     37 my $nbroken = 0;
     38 my $total = 0;
     39 my $debug = 0;
     40 my @broken_by_status;
     41 
     42 # Parse arguments
     43 @pathnames = @ARGV;
     44 if ( scalar @pathnames == 0 )
     45 {
     46 	my $baseargv0 = (split /\//, $0)[-1];
     47 	die "usage: $baseargv0 path0 [path1 ...]\n"
     48 }
     49 
     50 my @status_strings =
     51 (
     52 	"cannot be read (permission denied)",
     53 	"are scripts (shell, perl, whatever)",
     54 	"are 64-bit executables",
     55 	"don't use any stat() family calls at all",
     56 	"use 32-bit stat() family interfaces only",
     57 	"use 64-bit stat64() family interfaces only",
     58 	"use both 32-bit and 64-bit stat() family interfaces",
     59 );
     60 my @status_broken = (
     61 	0,
     62 	0,
     63 	0,
     64 	0,
     65 	1,
     66 	0,
     67 	1
     68 );
     69 
     70 sub MAX_STATUS { return 6 };
     71 sub status
     72 {
     73 	my ($r) = @_;
     74 	return 0 if ($r->{no_perm});
     75 	return 1 if ($r->{not_exe});
     76 	return 2 if ($r->{elf64b});
     77 	return 3 + ($r->{used64} ? 2 : 0) + ($r->{used32} ? 1 : 0);
     78 }
     79 
     80 map { $summ[$_] = 0 } (0..MAX_STATUS);
     81 map { $broken_by_status[$_] = [] } (0..MAX_STATUS);
     82 
     83 # Function to scan a file
     84 sub scan_file
     85 {
     86 	my ($path) = @_;
     87 	my $fh;
     88 
     89 	my %res =
     90 	(
     91 		elf64b => 0,
     92 		used32 => 0,
     93 		used64 => 0,
     94 		not_exe => 0,
     95 		no_perm => 0,
     96 	);
     97 
     98 	open $fh,'-|', "file -L \"$path\" 2>&1"
     99 		or return;
    100 	$_ = readline $fh;
    101 	chomp;
    102 	if (m/ELF 64-bit/)
    103 	{
    104 		$res{elf64b} = 1;
    105 	}
    106 	close $fh;
    107 	$fh = undef;
    108 
    109 	open $fh,'-|', "nm -uD \"$path\" 2>&1"
    110 		or return;
    111 	while (<$fh>)
    112 	{
    113 		chomp;
    114 
    115 		if (m/File format not recogni[sz]ed/)
    116 		{
    117 			$res{not_exe} = 1;
    118 		}
    119 		elsif (m/Permission denied/)
    120 		{
    121 			$res{no_perm} = 1;
    122 		}
    123 		elsif (m/^\s+U __(|l|f)xstat$/)
    124 		{
    125 			$res{used32}++;
    126 		}
    127 		elsif (m/^\s+U __(|l|f)xstat64$/)
    128 		{
    129 			$res{used64}++;
    130 		}
    131 	}
    132 	close $fh;
    133 
    134 	print "$res{used32} $res{used64} $res{not_exe} $res{no_perm} $res{elf64b} $path\n" if $debug;
    135 
    136 	my $s = status(\%res);
    137 	if ($status_broken[$s])
    138 	{
    139 	    push(@{$broken_by_status[$s]}, $path);
    140 	    $nbroken++;
    141 	}
    142 	$summ[$s]++;
    143 	$total++;
    144 }
    145 
    146 # Function to scan a directory
    147 sub scan_directory
    148 {
    149 	my ($path) = @_;
    150 	my $dh;
    151 	return unless opendir($dh,$path);
    152 	while (my $d = readdir $dh)
    153 	{
    154 		next if ($d =~ m/^\./);
    155 		print "$path/$d\n" if $debug;
    156 		scan_path("$path/$d");
    157 	}
    158 	closedir $dh;
    159 }
    160 
    161 # Function to scan something that might be a file or a directory
    162 sub scan_path
    163 {
    164 	my ($path) = @_;
    165 	print "scan_path($path)\n" if $debug;
    166 	if ( -l $path )
    167 	{
    168 	    # Ignore symlinks to files
    169 	    return if ( -f $path );
    170 	    # Follow symlinks to directories, but avoid deep recursion
    171 	    # on silly compatibility symlinks like /usr/bin/X11 -> .
    172 	    return if ( readlink($path) eq "." );
    173 	}
    174 	if ( -d $path )
    175 	{
    176 		scan_directory($path);
    177 	}
    178 	elsif ( -e $path )
    179 	{
    180 		scan_file($path);
    181 	}
    182 }
    183 
    184 # Scan files and directories specified in the commandline
    185 foreach my $path (@pathnames)
    186 {
    187 	scan_path($path);
    188 }
    189 
    190 if ( !$total )
    191 {
    192     printf "No files found.\n";
    193     exit;
    194 }
    195 
    196 # generate a summary
    197 print "Summary by status\n";
    198 print "-----------------\n";
    199 foreach my $s (0..MAX_STATUS)
    200 {
    201 	next if $summ[$s] == 0;
    202 	printf "%7d %4.1f%% %s%s\n",
    203 		$summ[$s], (100.0 * $summ[$s] / $total), $status_strings[$s],
    204 		($status_broken[$s] ? " [BROKEN]" : "");
    205 }
    206 printf "%7d %4.1f%% BROKEN\n",
    207 	$nbroken, (100.0 * $nbroken / $total);
    208 
    209 # list all broken files
    210 if ($nbroken)
    211 {
    212 	print "List of broken files\n";
    213 	print "--------------------\n";
    214 	foreach my $s (0..MAX_STATUS)
    215 	{
    216 		next if !$status_broken[$s];
    217 		next if !scalar(@{$broken_by_status[$s]});
    218 		printf "These %s\n", $status_strings[$s];
    219 		map { printf "    %s\n", $_; } @{$broken_by_status[$s]};
    220 	}
    221 }