my_md5sum 2.76 KB
Newer Older
unknown's avatar
unknown committed
1 2 3 4 5 6 7 8 9 10 11 12
#!/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 <matt@mysql.com>
#
use strict;
unknown's avatar
unknown committed
13 14 15 16 17 18 19 20 21 22 23

#
# 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");
}

unknown's avatar
unknown committed
24 25 26
use Digest::MD5;
use Getopt::Long;

unknown's avatar
unknown committed
27 28
my $VER= "1.3";
my $EXIT= 0;
unknown's avatar
unknown committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78

#
# 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 (<CHECKFILE>)
	{
		#
		# 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
unknown's avatar
unknown committed
79 80 81
		# 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;
unknown's avatar
unknown committed
82 83 84

                # Set the exit() status to non-zero if FAILED
                $EXIT= 1 if $digest ne $checksum;
unknown's avatar
unknown committed
85 86 87 88 89 90 91 92 93 94 95 96 97
	}
}
# Else generate the MD5 digest to STDOUT
else
{
	foreach my $file (@files)
	{
		my $digest= &mkmd5($file);

		print "$digest  $file\n";
	}
}

unknown's avatar
unknown committed
98 99
exit($EXIT);

unknown's avatar
unknown committed
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141

#
# 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 <<EOF;

$0 version $VER by Matt Wagner <matt\@mysql.com>

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);
}