summaryrefslogtreecommitdiff
path: root/Build-tools/my_md5sum
blob: f4ac2f7d674a5f1edc236762e96b63124a7abbb7 (plain)
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/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 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 (<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, 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 <<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);
}