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 }