my_md5sum 2.34 KB
Newer Older
unknown's avatar
unknown committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
#!/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;
use Digest::MD5;
use Getopt::Long;

my $VER= "1.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 (<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
		# Print an error message if they don't match
		print "$0: MD5 check failed for '$checkfile'\n" if $digest ne $checksum;
	}
}
# Else generate the MD5 digest to STDOUT
else
{
	foreach my $file (@files)
	{
		my $digest= &mkmd5($file);

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


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