This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
blead is upstream for Math-BigInt
[perl5.git] / cpan / Digest-SHA / shasum
CommitLineData
6bc89f92
SP
1#!perl -w
2
84c0b84e 3 # shasum: filter for computing SHA digests (analogous to sha1sum)
6bc89f92 4 #
dfe1edcb 5 # Copyright (C) 2003-2010 Mark Shelor, All Rights Reserved
6bc89f92 6 #
dfe1edcb
CBW
7 # Version: 5.48
8 # Mon Jan 4 16:32:52 MST 2010
6bc89f92
SP
9
10=head1 NAME
11
12shasum - Print or Check SHA Checksums
13
14=head1 SYNOPSIS
15
16 Usage: shasum [OPTION] [FILE]...
17 or: shasum [OPTION] --check [FILE]
18 Print or check SHA checksums.
19 With no FILE, or when FILE is -, read standard input.
20
21 -a, --algorithm 1 (default), 224, 256, 384, 512
22 -b, --binary read files in binary mode (default on DOS/Windows)
23 -c, --check check SHA sums against given list
128cbdba 24 -p, --portable read files in portable mode
cccd5831 25 produces same digest on Windows/Unix/Mac
6bc89f92
SP
26 -t, --text read files in text mode (default)
27
28 The following two options are useful only when verifying checksums:
29
128cbdba 30 -s, --status don't output anything, status code shows success
6bc89f92
SP
31 -w, --warn warn about improperly formatted SHA checksum lines
32
128cbdba
SP
33 -h, --help display this help and exit
34 -v, --version output version information and exit
6bc89f92 35
128cbdba
SP
36 The sums are computed as described in FIPS PUB 180-2. When checking,
37 the input should be a former output of this program. The default mode
38 is to print a line with checksum, a character indicating type (`*'
39 for binary, `?' for portable, ` ' for text), and name for each FILE.
6bc89f92 40
747da336
RGS
41=head1 DESCRIPTION
42
43The I<shasum> script provides the easiest and most convenient way to
44compute SHA message digests. Rather than writing a program, the user
45simply feeds data to the script via the command line, and waits for
46the results to be printed on standard output. Data can be fed to
47I<shasum> through files, standard input, or both.
48
49The following command shows how easy it is to compute digests for typical
50inputs such as the NIST test vector "abc":
51
dfe1edcb 52 perl -e "print qq(abc)" | shasum
747da336
RGS
53
54Or, if you want to use SHA-256 instead of the default SHA-1, simply say:
55
dfe1edcb 56 perl -e "print qq(abc)" | shasum -a 256
747da336
RGS
57
58Since I<shasum> uses the same interface employed by the familiar
59I<sha1sum> program (and its somewhat outmoded anscestor I<md5sum>),
60you can install this script as a convenient drop-in replacement.
61
6bc89f92
SP
62=head1 AUTHOR
63
dfe1edcb 64Copyright (c) 2003-2010 Mark Shelor <mshelor@cpan.org>.
6bc89f92
SP
65
66=head1 SEE ALSO
67
128cbdba 68shasum is implemented using the Perl module L<Digest::SHA> or
6bc89f92
SP
69L<Digest::SHA::PurePerl>.
70
71=cut
72
73use strict;
747da336 74use FileHandle;
6bc89f92
SP
75use Getopt::Long;
76
dfe1edcb 77my $VERSION = "5.48";
6bc89f92
SP
78
79
80 # Try to use Digest::SHA, since it's faster. If not installed,
81 # use Digest::SHA::PurePerl instead.
82
83my $MOD_PREFER = "Digest::SHA";
84my $MOD_SECOND = "Digest::SHA::PurePerl";
85
86my $module = $MOD_PREFER;
747da336 87eval "require $module";
6bc89f92
SP
88if ($@) {
89 $module = $MOD_SECOND;
747da336 90 eval "require $module";
6bc89f92
SP
91 die "Unable to find $MOD_PREFER or $MOD_SECOND\n" if $@;
92}
93
94
95 # Usage statement adapted from Ulrich Drepper's md5sum.
128cbdba
SP
96 # Include an "-a" option for algorithm selection,
97 # and a "-p" option for portable digest computation.
6bc89f92
SP
98
99sub usage {
128cbdba 100 my($err, $msg) = @_;
6bc89f92 101
128cbdba
SP
102 $msg = "" unless defined $msg;
103 if ($err) {
c7e5c266 104 warn($msg . "Type shasum -h for help\n");
128cbdba
SP
105 exit($err);
106 }
c7e5c266 107 print <<'END_OF_USAGE';
6bc89f92
SP
108Usage: shasum [OPTION] [FILE]...
109 or: shasum [OPTION] --check [FILE]
110Print or check SHA checksums.
111With no FILE, or when FILE is -, read standard input.
112
113 -a, --algorithm 1 (default), 224, 256, 384, 512
114 -b, --binary read files in binary mode (default on DOS/Windows)
115 -c, --check check SHA sums against given list
128cbdba 116 -p, --portable read files in portable mode
cccd5831 117 produces same digest on Windows/Unix/Mac
6bc89f92
SP
118 -t, --text read files in text mode (default)
119
120The following two options are useful only when verifying checksums:
128cbdba 121 -s, --status don't output anything, status code shows success
6bc89f92
SP
122 -w, --warn warn about improperly formatted SHA checksum lines
123
128cbdba
SP
124 -h, --help display this help and exit
125 -v, --version output version information and exit
6bc89f92 126
128cbdba
SP
127The sums are computed as described in FIPS PUB 180-2. When checking, the
128input should be a former output of this program. The default mode is to
129print a line with checksum, a character indicating type (`*' for binary,
130`?' for portable, ` ' for text), and name for each FILE.
6bc89f92
SP
131
132Report bugs to <mshelor@cpan.org>.
133END_OF_USAGE
134 exit($err);
135}
136
137
138 # Collect options from command line
139
140my ($alg, $binary, $check, $text, $status, $warn, $help, $version);
128cbdba 141my ($portable);
6bc89f92 142
747da336 143eval { Getopt::Long::Configure ("bundling") };
6bc89f92 144GetOptions(
128cbdba
SP
145 'b|binary' => \$binary, 'c|check' => \$check,
146 't|text' => \$text, 'a|algorithm=i' => \$alg,
147 's|status' => \$status, 'w|warn' => \$warn,
148 'h|help' => \$help, 'v|version' => \$version,
149 'p|portable' => \$portable
150) or usage(1, "");
6bc89f92
SP
151
152
153 # Deal with help requests and incorrect uses
154
128cbdba
SP
155usage(0)
156 if $help;
84c0b84e 157usage(1, "shasum: Ambiguous file mode\n")
128cbdba 158 if scalar(grep { defined $_ } ($binary, $portable, $text)) > 1;
c7e5c266 159usage(1, "shasum: --warn option used only when verifying checksums\n")
128cbdba 160 if $warn && !$check;
c7e5c266 161usage(1, "shasum: --status option used only when verifying checksums\n")
128cbdba 162 if $status && !$check;
6bc89f92
SP
163
164
165 # Default to SHA-1 unless overriden by command line option
166
dfe1edcb 167$alg = 1 unless defined $alg;
128cbdba 168grep { $_ == $alg } (1, 224, 256, 384, 512)
84c0b84e 169 or usage(1, "shasum: Unrecognized algorithm\n");
6bc89f92
SP
170
171
172 # Display version information if requested
173
174if ($version) {
175 print "$VERSION\n";
176 exit(0);
177}
178
179
180 # Try to figure out if the OS is DOS-like. If it is,
181 # default to binary mode when reading files, unless
c7e5c266
SP
182 # explicitly overriden by command line "--text" or
183 # "--portable" options.
6bc89f92
SP
184
185my $isDOSish = ($^O =~ /^(MSWin\d\d|os2|dos|mint|cygwin)$/);
128cbdba
SP
186if ($isDOSish) { $binary = 1 unless $text || $portable }
187
c7e5c266 188my $modesym = $binary ? '*' : ($portable ? '?' : ' ');
6bc89f92
SP
189
190
191 # Read from STDIN (-) if no files listed on command line
192
193@ARGV = ("-") unless @ARGV;
194
195
196 # sumfile($file): computes SHA digest of $file
197
198sub sumfile {
dcbcf62d 199 my $file = shift;
6bc89f92 200
84c0b84e
SP
201 my $mode = $portable ? 'p' : ($binary ? 'b' : '');
202 my $digest = eval { $module->new($alg)->addfile($file, $mode) };
203 if ($@) {
204 warn "shasum: $file: $!\n";
c7e5c266
SP
205 return;
206 }
c7e5c266 207
84c0b84e 208 $digest->hexdigest;
6bc89f92
SP
209}
210
211
212 # %len2alg: maps hex digest length to SHA algorithm
213
214my %len2alg = (40 => 1, 56 => 224, 64 => 256, 96 => 384, 128 => 512);
215
216
217 # Verify checksums if requested
218
219if ($check) {
220 my $checkfile = shift(@ARGV);
c7e5c266
SP
221 my ($err, $read_errs, $match_errs) = (0, 0, 0);
222 my ($num_files, $num_checksums) = (0, 0);
747da336 223 my ($fh, $sum, $fname, $rsp, $digest);
6bc89f92 224
84c0b84e 225 die "shasum: $checkfile: $!\n"
747da336 226 unless $fh = FileHandle->new($checkfile, "r");
6bc89f92
SP
227 while (<$fh>) {
228 s/\s+$//;
c7e5c266 229 ($sum, $modesym, $fname) = /^(\S+) (.)(.*)$/;
128cbdba 230 ($binary, $portable, $text) =
c7e5c266 231 map { $_ eq $modesym } ('*', '?', ' ');
6bc89f92 232 unless ($alg = $len2alg{length($sum)}) {
dcbcf62d
SP
233 warn("shasum: $checkfile: $.: improperly " .
234 "formatted SHA checksum line\n") if $warn;
6bc89f92
SP
235 next;
236 }
c7e5c266 237 $rsp = "$fname: "; $num_files++;
747da336 238 unless ($digest = sumfile($fname)) {
dcbcf62d 239 $rsp .= "FAILED open or read\n";
c7e5c266 240 $err = 1; $read_errs++;
dcbcf62d
SP
241 }
242 else {
c7e5c266 243 $num_checksums++;
dcbcf62d 244 if (lc($sum) eq $digest) { $rsp .= "OK\n" }
c7e5c266 245 else { $rsp .= "FAILED\n"; $err = 1; $match_errs++ }
dcbcf62d 246 }
6bc89f92
SP
247 print $rsp unless $status;
248 }
747da336 249 $fh->close;
c7e5c266
SP
250 unless ($status) {
251 warn("shasum: WARNING: $read_errs of $num_files listed " .
252 "files could not be read\n") if $read_errs;
253 warn("shasum: WARNING: $match_errs of $num_checksums " .
254 "computed checksums did NOT match\n") if $match_errs;
255 }
6bc89f92
SP
256 exit($err);
257}
258
259
260 # Compute and display SHA checksums of requested files
261
747da336
RGS
262my($file, $digest);
263
264for $file (@ARGV) {
265 if ($digest = sumfile($file)) {
84c0b84e 266 print "$digest $modesym", "$file\n";
6bc89f92 267 }
6bc89f92 268}