#!/usr/bin/perl use strict; use warnings; use v5.21; use Data::Dumper; my $files = {}; # key = filename get_all_files($files); get_rpm_files($files); verify_rpm_files($files); #changed rpm for my $key (sort keys %{$files}) { if ($files->{$key}->{'rpm_verify'}->{'flags'}) { say $key; } } # not rpm for my $key (sort keys %{$files}) { if ($files->{$key}->{'rpm'}) { next } if ($files->{$key}->{'directory'}) { next } say $key; } #say Dumper $files; ############################################################################### # # # ################################################################################ sub get_all_files { my $all_files = shift; #hashref, key = filename #my $command = q{/usr/bin/find / -type f 2>/dev/null}; my $command = q{/usr/bin/find / -type f -o -type d}; my @list = qx{$command}; foreach my $filename (@list) { next if ($filename =~ /^\/proc\//); # kernel structures next if ($filename =~ /^\/run\//); # runtime data next if ($filename =~ /^\/sys\//); # kernel structures chomp $filename; $all_files->{$filename}->{'all'} = 1; $all_files->{$filename}->{'directory'} = 0; if (-d $filename) { $all_files->{$filename}->{'directory'} = 1 } } return; } # sub get_all_files ################################################################################ # # # ################################################################################ sub get_rpm_files { my $all_files = shift; #hashref, key = filename my $command = q{/usr/bin/rpm -qal}; my @list = qx{$command}; foreach my $filename (@list) { chomp $filename; # filter non-files next if $filename =~ /(contains no files)/; $all_files->{$filename}->{'rpm'} = 1; } return; } # sub get_rpm_files ################################################################################ # # # .M....... # 123456789 # ################################################################################ sub verify_rpm_files { my $all_files = shift; #hashref, key = filename my $command = q{/usr/bin/rpm -Va}; my @list = qx{$command}; foreach my $line (@list) { chomp $line; my @pieces = split /\s+/, $line; my $flags = shift @pieces; my @rev = reverse @pieces; my $filename = shift @rev; my $attribute = shift @rev; if (0) { say "line $line"; #say "pieces: " . Dumper @pieces; say "filename $filename"; say "flags: $flags"; say parse_flags($flags); say "attribute: $attribute"; say parse_attr_code($attribute); } $all_files->{$filename}->{'rpm_verify'}->{'flags'} = $flags; $all_files->{$filename}->{'rpm_verify'}->{'attr'} = $attribute; } return; } # sub verify_rpm_files ################################################################################ # # # ################################################################################ sub parse_flags { my $flags = shift; my $output = q{}; if ($flags) { if ($flags =~ /^S/) { $output .= "File Size Differs\n"}; if ($flags =~ /^.M/) { $output .= "File Mode Differs\n"}; if ($flags =~ /^..5/) { $output .= "MD5 Checksum Differs\n"}; if ($flags =~ /^...D/) { $output .= "Device File Major/Minor Ver Nbrs Differ\n"}; if ($flags =~ /^....L/) { $output .= "A Mismatch Occurs In Link\n"; }; if ($flags =~ /^.....U/) { $output .= "File Ownership Differs\n"; }; if ($flags =~ /^......G/) { $output .= "File Group Differs\n"; }; if ($flags =~ /^.......T/) { $output .= "File Time (mtime) Differs\n"; }; } return $output; } # sub parse_flags ################################################################################ # # # ################################################################################ sub parse_attr_code { my $attribute = shift; my $output = q{}; if ($attribute) { if ($attribute eq "c") {$output = "Configuration File" }; if ($attribute eq "d") {$output = "Documentation File" }; if ($attribute eq "g") {$output = "Ghost File" }; if ($attribute eq "l") {$output = "License File" }; if ($attribute eq "r") {$output = "Readme File" }; } return $output; } # sub parse_attr_code __END__