#!/usr/bin/perl # # my_md5sum # # Script to clone the 'md5sum' command found on modern systems, since that # command is not always found on all systems. # # Use the "--help" option for more info! # # Written by Matt Wagner # use strict; # # Use local perl libraries first. 'unshift' adds to the front of @INC # The local perl library dir hidden is $HOME/.perllibs on each build host # BEGIN { my $homedir= $ENV{HOME}; unshift (@INC, "$homedir/.perllibs"); } use Digest::MD5; use Getopt::Long; my $VER= "1.3"; my $EXIT= 0; # # Strip the leading path info off the program name ($0). We want 'my_md5sum' # not './my_md5sum'. # $0=~ s/^.*\/(.+)$/$1/; my ($opt_check, $opt_help)= undef; GetOptions( "check|c" => \$opt_check, "help|h" => \$opt_help, ) || usage(); # # Put all the [file1 file2 file3 ...]'s into an array # my @files = @ARGV; # # Give the "--help" text if: # - "--help|-h" was specified # - The number of files given as arguments is nil # - The "--check|-c" option is used with more than one [file] argument # usage() if $opt_help || $#files == -1 || ($opt_check && $#files > 0); # If "--check|-c", then go into checking if ($opt_check) { open (CHECKFILE, $files[0]) or die "$files[0]: $!"; while () { # # Goto the next line in the file if it does not match a typical # digest line like: # # f1007efa2c72daa693981ec764cdeaca Bootstrap # next if $_!~ m/^([a-z0-9]{32})\s+(.+)$/; # Collect the trappings from the above regex my $checksum= $1; my $checkfile= $2; # Generate a fresh MD5 for the file in question my $digest= &mkmd5($checkfile); # Check the fresh MD5 against what is recorded in the file # Print an error message if they don't match, else print OK print "$checkfile: FAILED\n" if $digest ne $checksum; print "$checkfile: OK\n" if $digest eq $checksum; # Set the exit() status to non-zero if FAILED $EXIT= 1 if $digest ne $checksum; } } # Else generate the MD5 digest to STDOUT else { foreach my $file (@files) { my $digest= &mkmd5($file); print "$digest $file\n"; } } exit($EXIT); # # This routine generates the MD5 digest of a file # sub mkmd5 { my $file= shift; open (FILE, $file) or die "$file: $!"; binmode(FILE); my $digest= Digest::MD5->new->addfile(*FILE)->hexdigest; close FILE; return $digest; } # # Print the help text # sub usage { print < Usage: $0 [-c [file]] | [file1...] Generates or checks MD5 message digests. Options: -c, --check Check message digests (default is generate) -h, --help Display this text and exit The input for -c should be the list of message digests and file names that is printed on STDOUT by this program when it generates digests. EOF exit(0); }