echeck-stat-brokeness - gentoo-tools - Some Gentoo helper tools
 (HTM) git clone git://r-36.net/gentoo-tools
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) 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 }