File Coverage

blib/lib/RPMVerify.pm
Criterion Covered Total %
statement 21 62 33.8
branch 0 28 0.0
condition 0 9 0.0
subroutine 7 11 63.6
pod n/a
total 28 110 25.4


line stmt bran cond sub pod time code
1             package RPM::Verify 1.000;
2              
3             # PODNAME: RPM::Verify
4             # ABSTRACT: Run rpm -v on every installed rpm, and give you a descriptive hash of the relevant changes.
5              
6 1     1   198288 use strict;
  1         3  
  1         43  
7 1     1   6 use warnings;
  1         2  
  1         79  
8              
9 1     1   5 no warnings qw{experimental};
  1         2  
  1         73  
10 1     1   7 use feature qw{signatures};
  1         2  
  1         159  
11              
12 1     1   689 use Ref::Util qw{is_arrayref};
  1         3352  
  1         104  
13 1     1   9 use List::Util qw{any};
  1         2  
  1         140  
14 1     1   606 use File::Which qw{which};
  1         1667  
  1         1094  
15              
16              
17 0     0     sub alterations(%options) {
  0            
  0            
18 0 0         die "Cannot find rpm binary!" unless which('rpm');
19 0 0         die "Cannot find xargs binary!" unless which('xargs');
20              
21 0           my (@skipfiles, @skiptypes);
22 0 0         @skiptypes = @{$options{skip_types}} if is_arrayref($options{skip_types});
  0            
23 0 0         @skipfiles = @{$options{skip_files}} if is_arrayref($options{skip_files});
  0            
24              
25 0           my @skipext;
26 0 0   0     if (any { 'config' eq $_ } @skiptypes) {
  0            
27 0           push(@skipext, qr/\.conf$/, qr/\.cfg$/);
28             }
29              
30 0 0         open(my $list, "-|", qq{rpm -qa | xargs -P 32 -- rpm -V}) or die "Could not acquire list of RPM changes!";
31              
32             #SM5DLUGT c
33 0           my @mapper = qw{size mode md5 fileno linkloc owner group mtime capabilities NOP NOP ftype NOP file};
34 0           my %ftmap = (
35             c => 'config',
36             d => 'documentation',
37             g => 'ghost',
38             l => 'license',
39             r => 'readme',
40             );
41              
42 0           my %files;
43 0           LINE: foreach my $line ( readline($list) ) {
44 0           chomp $line;
45             # Not an rpm -V row
46 0 0         next unless ( $line =~ m/^(\S{8,9}|missing\s+[cdg]|missing)\s+(\S.*)$/ );
47 0           my @parse = unpack("AAAAAAAAAAAAAA*", $line);
48 0           my %parsed;
49 0           for (my $pos=0; $pos < scalar(@parse); $pos++) {
50             # Ignore . and space
51 0 0         next if index('.', $parse[$pos]) == 0;
52 0 0         next if index(' ', $parse[$pos]) == 0;
53             # File type is a special case
54 0           my $key = $mapper[$pos];
55 0 0         $key = $ftmap{$parse[$pos]} if $pos == 11;
56              
57             # Don't bother with things we want to skip.
58 0 0 0 0     next LINE if @skiptypes && any { $_ eq $key } @skiptypes;
  0            
59              
60 0           my $value = $parse[$pos];
61 0 0         $value = !!$value unless $pos == 13;
62              
63             #XXX Some authors of RPMs don't list configuration as...you know, configuration.
64 0 0 0 0     next LINE if @skipext && $pos == 13 && any { $value =~ $_ } @skipext;
  0   0        
65              
66 0           $parsed{$key} = $value;
67             }
68             # Anything that's not an absolute path is just a broken RPM with a jacked FILES list
69 0 0         next unless index( $parsed{file}, '/') == 0;
70              
71 0           $files{$parsed{file}} = \%parsed;
72 0           $files{$parsed{file}}{provider} = qx[yum whatprovides -q $parsed{file} | head -n1];
73 0           ($files{$parsed{file}}{provider}) = $files{$parsed{file}}{provider} =~ m/^(\S+) .*/;
74             }
75 0           close $list;
76              
77 0           return %files;
78             }
79              
80             1;
81              
82             __END__