| Chess | Tools | Data | Blog | Poetry | Why? | Wiki | Admin | Logout |

Download


#!/usr/bin/perl -w
# $Revision: 1.4 $
# Luis Mondesi < lemsx1@hotmail.com >
# Last modified: 2003-Sep-25
#
# DESCRIPTION: simple script to check md5sum of all
#               debian installed files. If a --binary
#               flag is given, it will check only binaries.
#               If --md5sum="" is given, it will use that
#               binary to check md5sum's.
#               Output will be printed to STDOUT unless
#               --log="/path/to/file.log" is given.
#
#               Note that if you don't have read access to
#               files/binaries then you might need to run
#               this with a different user who has permission
#               to read those binaries or files. (root?)
#
# NOTE: later discovered "debsums" perl script which essentially
#       does the same in a simpler and nicer way... use that instead.
#       Unless you want a different type of report when seeing what got
#       changed.
# USAGE: $0 [--binary] [--md5sum="/usr/local/bin/md5sum"] [--log="/tmp/log"]
# LICENSE: GPL
 

use File::Find 'find';     # find();
use File::Basename 'basename'; # basename();
use FileHandle;

use strict;
$|++;

use Getopt::Long;
Getopt::Long::Configure('bundling');

# vars #

my $DEBUG = 0;

my $USAGE=" check-md5sum-debian.pl [-h|--help] [-b|--binary] [-l|--log] [-m|--md5sum] [-d|--debug]
";

# list of files we should not check for
# note that only .md5sum files are checked anyway

my $EXCEPTION_LIST = "\.txt\$|\.rtf\$";

my $DEBIAN_INFO = "/var/lib/dpkg/info";
my $BIN_FLAG = 0; # search for binaries only

my $OUTPUT="STDOUT"; # output to, unless LOG is passed
my $LOG = ""; # log file (command line)

my ($tmp_md5sum, $tmp_file) = "";

my $MD5SUM = ""; 

my $HELP = 0;

# end vars #

# get opts #

GetOptions(
    # flags
    'b|binary'      =>  \$BIN_FLAG,
    'm|md5sum=s'    =>  \$MD5SUM,
    'l|log'         =>  \$LOG,
    'h|help'        =>  \$HELP,
    'd|debug'       =>  \$DEBUG
);

# end get opts #

# code #

if ( $HELP > 0 )
{
    print $USAGE;
    exit(0);
}

eval "use Digest::md5sum";
if ($@)
{
    print STDERR "
 ERROR: Digest::Md5sum was not found
".
    "           Trying to find a valid 'md5sum' binary

" if $DEBUG;
    
#    if ( -x "/sbin/md5sum" ) 
#    {
#        $MD5SUM = "/sbin/md5sum";
#    } elsif ( -x "/usr/sbin/md5sum" ) {
#        $MD5SUM = "/usr/sbin/md5sum";
#    } elsif ( -x "/usr/bin/md5sum" ) {
#        $MD5SUM = "/usr/bin/md5sum";
#    } elsif ( -x "/bin/md5sum" ) {
#        $MD5SUM = "/bin/md5sum";
#    } elsif ( -x "/usr/local/sbin/md5sum" ) {
#        $MD5SUM = "/usr/local/sbin/md5sum";
#    } elsif ( -x "/usr/local/bin/md5sum" ) {
#        $MD5SUM = "/usr/local/bin/md5sum";
#    }

    foreach my $md5bin ( split(/:/,$ENV{"PATH"}))
    {
        # FIXME
        # assuming that a PATH var exists might lead to problems... but
        # 
        print STDERR "Checking PATH: ". $md5bin."
" if $DEBUG;

        if ( -x $md5bin."/md5sum" )
        {
            $md5bin =~ s,//+,/,g; # just in case
                                  # removes extra /
            $MD5SUM = "$md5bin/md5sum";
        }
    }
    # sanity check
    if ( $MD5SUM ne "" ) 
    {
        print STDERR "
 WARN: Using $MD5SUM
" if $DEBUG;
    } else {
        print STDERR "
 ERROR: no suitable 'md5sum' found." if $DEBUG;
        exit(1);
    }
}

if ( $LOG gt "" )
{
    $OUTPUT = new FileHandle;
    $OUTPUT->open("> $LOG");
    $OUTPUT->autoflush(1);
}  

main();

# functions
sub main {
    # get all md5sum files into @md5sumfiles
    my @files = do_file_ary($DEBIAN_INFO);

    my $this_md5sum=""; # current file md5sum 

    # debug
    #print join(" ",@files);

    foreach my $file (@files) 
    {
        if ( open(FILE,$file) )
        {
            while (<FILE>) 
            {
                chomp;
                ($tmp_md5sum,$tmp_file) = split(/\s+/,$_);

                $tmp_file = "/$tmp_file"; # prepend slash

                if ( $BIN_FLAG > 0 ) {
                    # we only care about binaries here
                    if ( -x "$tmp_file" ) 
                    {
                        $this_md5sum = get_md5sum($tmp_file);
                        #print STDOUT "DEBUG: $tmp_file
 -> $this_md5sum
 -> $tmp_md5sum
";
                        if ($tmp_md5sum ne $this_md5sum)
                        {
                            if ( $OUTPUT eq "STDOUT" )
                            {
                                # is there a simpler way of checking
                                # this?
                                print STDOUT "
WARN: $tmp_file 
NEW: [$this_md5sum] 
OLD: [$tmp_md5sum]";
                            } else {
                                print $OUTPUT "
WARN: $tmp_file 
NEW: [$this_md5sum] 
OLD: [$tmp_md5sum]";
                            }
                        }
                    }
                } else {
                    # check all files
                    $this_md5sum = get_md5sum($tmp_file);
                    if ($tmp_md5sum ne $this_md5sum)
                    {
                        if ( $OUTPUT eq "STDOUT" )
                        {
                            # is there a simpler way of checking
                            # this?
                            print STDOUT "
WARN: $tmp_file 
NEW: [$this_md5sum] 
OLD: [$tmp_md5sum]";
                        } else {
                            print $OUTPUT "
WARN: $tmp_file 
NEW: [$this_md5sum] 
OLD: [$tmp_md5sum]";
                        }
                    }
                } #end if/else bin_flag
            } #end while
        } else {
            print STDERR "
 ERROR: Could not open $file" if $DEBUG;
        } #end if/else open
    } #end foreach
}

sub get_md5sum {
    my $file = shift;
    my ($str,$this_file) = "";

    # prefer to use md5sum binary
    # if one was passed in command line
    # or found after failing to import
    # Digest::Md5sum module
    if ( $MD5SUM gt "" ) {
        if ( -r $file ) {
            # usually first field is md5sum
            ($str,$this_file) = split(/\s+/,qx/$MD5SUM $file/);
        } else {
            # unable to read file, permission?
            $str  = "00000000000000000000000000000000";
        }
    } 
    # try to create a new md5sum object and
    # proceed
    #elsif ( ) {}
    return $str;
}

my @md5sumfiles = ();
sub do_file_ary {
    # uses find() to recur thru directories
    # returns an array of files
    # i.e. in directory "a" with the files:
    # /a/file.txt
    # /a/b/file-b.txt
    # /a/b/c/file-c.txt
    # /a/b2/c2/file-c2.txt
    # 
    # my @ary = &do_file_ary(".");
    # 
    # will yield:
    # a/file.txt
    # a/b/file-b.txt
    # a/b/c/file-c.txt
    # a/b2/c2/file-c2.txt
    # 
    my $ROOT = shift;
    my %opt = (wanted => \&process_file, no_chdir=>1);
    find(\%opt,$ROOT);
    return @md5sumfiles;
} # end do_file_ary

sub process_file {
    my $base_name = basename($_);
    if  ( 
        -f $_ 
        && $base_name !~ m/^($EXCEPTION_LIST)$/
        && $base_name !~ m/^\.[a-zA-Z0-9]+$/ 
        && $_ =~ m/(.*\.md5sums)$/
        ) 
    {
        s/^\.\/*//g;
        push @md5sumfiles,$_;
    }
}

Advertisement