Pod::Html should not convert "foo" in `foo''
[p5sagit/p5-mst-13.2.git] / ext / Digest / SHA / bin / shasum
CommitLineData
6bc89f92 1#!perl -w
2
3 # shasum: filter for computing SHA digests (analogous to md5sum)
4 #
77d2a621 5 # Copyright (C) 2003-2006 Mark Shelor, All Rights Reserved
6bc89f92 6 #
dcbcf62d 7 # Version: 5.37
8 # Mon May 8 04:30:09 MST 2006
6bc89f92 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
25 produces same digest on Windows/Unix/MacOS
6bc89f92 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 31 -w, --warn warn about improperly formatted SHA checksum lines
32
128cbdba 33 -h, --help display this help and exit
34 -v, --version output version information and exit
6bc89f92 35
128cbdba 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
41=head1 AUTHOR
42
77d2a621 43Copyright (c) 2003-2006 Mark Shelor <mshelor@cpan.org>.
6bc89f92 44
45=head1 SEE ALSO
46
128cbdba 47shasum is implemented using the Perl module L<Digest::SHA> or
6bc89f92 48L<Digest::SHA::PurePerl>.
49
50=cut
51
52use strict;
53use Getopt::Long;
54
dcbcf62d 55my $VERSION = "5.37";
6bc89f92 56
57
58 # Try to use Digest::SHA, since it's faster. If not installed,
59 # use Digest::SHA::PurePerl instead.
60
61my $MOD_PREFER = "Digest::SHA";
62my $MOD_SECOND = "Digest::SHA::PurePerl";
63
64my $module = $MOD_PREFER;
65eval "require $module";
66if ($@) {
67 $module = $MOD_SECOND;
68 eval "require $module";
69 die "Unable to find $MOD_PREFER or $MOD_SECOND\n" if $@;
70}
71
72
73 # Usage statement adapted from Ulrich Drepper's md5sum.
128cbdba 74 # Include an "-a" option for algorithm selection,
75 # and a "-p" option for portable digest computation.
6bc89f92 76
77sub usage {
128cbdba 78 my($err, $msg) = @_;
6bc89f92 79
128cbdba 80 $msg = "" unless defined $msg;
81 if ($err) {
82 print STDERR "$msg", "Type shasum -h for help\n";
83 exit($err);
84 }
85 print STDOUT <<'END_OF_USAGE';
6bc89f92 86Usage: shasum [OPTION] [FILE]...
87 or: shasum [OPTION] --check [FILE]
88Print or check SHA checksums.
89With no FILE, or when FILE is -, read standard input.
90
91 -a, --algorithm 1 (default), 224, 256, 384, 512
92 -b, --binary read files in binary mode (default on DOS/Windows)
93 -c, --check check SHA sums against given list
128cbdba 94 -p, --portable read files in portable mode
95 produces same digest on Windows/Unix/MacOS
6bc89f92 96 -t, --text read files in text mode (default)
97
98The following two options are useful only when verifying checksums:
128cbdba 99 -s, --status don't output anything, status code shows success
6bc89f92 100 -w, --warn warn about improperly formatted SHA checksum lines
101
128cbdba 102 -h, --help display this help and exit
103 -v, --version output version information and exit
6bc89f92 104
128cbdba 105The sums are computed as described in FIPS PUB 180-2. When checking, the
106input should be a former output of this program. The default mode is to
107print a line with checksum, a character indicating type (`*' for binary,
108`?' for portable, ` ' for text), and name for each FILE.
6bc89f92 109
110Report bugs to <mshelor@cpan.org>.
111END_OF_USAGE
112 exit($err);
113}
114
115
116 # Collect options from command line
117
118my ($alg, $binary, $check, $text, $status, $warn, $help, $version);
128cbdba 119my ($portable);
6bc89f92 120
128cbdba 121Getopt::Long::Configure ("bundling");
6bc89f92 122GetOptions(
128cbdba 123 'b|binary' => \$binary, 'c|check' => \$check,
124 't|text' => \$text, 'a|algorithm=i' => \$alg,
125 's|status' => \$status, 'w|warn' => \$warn,
126 'h|help' => \$help, 'v|version' => \$version,
127 'p|portable' => \$portable
128) or usage(1, "");
6bc89f92 129
130
131 # Deal with help requests and incorrect uses
132
128cbdba 133usage(0)
134 if $help;
135usage(1, "ambiguous file mode\n")
136 if scalar(grep { defined $_ } ($binary, $portable, $text)) > 1;
137usage(1, "warn option used only when verifying checksums\n")
138 if $warn && !$check;
139usage(1, "status option used only when verifying checksums\n")
140 if $status && !$check;
6bc89f92 141
142
143 # Default to SHA-1 unless overriden by command line option
144
145$alg = 1 unless $alg;
128cbdba 146grep { $_ == $alg } (1, 224, 256, 384, 512)
147 or usage(1, "unrecognized algorithm\n");
6bc89f92 148
149
150 # Display version information if requested
151
152if ($version) {
153 print "$VERSION\n";
154 exit(0);
155}
156
157
158 # Try to figure out if the OS is DOS-like. If it is,
159 # default to binary mode when reading files, unless
128cbdba 160 # explicitly overriden by command line "text" or
161 # "portable" options.
6bc89f92 162
163my $isDOSish = ($^O =~ /^(MSWin\d\d|os2|dos|mint|cygwin)$/);
128cbdba 164if ($isDOSish) { $binary = 1 unless $text || $portable }
165
166my $mode = $binary ? '*' : ($portable ? '?' : ' ');
6bc89f92 167
168
169 # Read from STDIN (-) if no files listed on command line
170
171@ARGV = ("-") unless @ARGV;
172
173
174 # sumfile($file): computes SHA digest of $file
175
176sub sumfile {
dcbcf62d 177 my $file = shift;
6bc89f92 178
dcbcf62d 179 local *F;
180 return unless open(F, "<$file");
181 binmode(F) if $binary || $portable;
128cbdba 182
dcbcf62d 183 my $digest = $module->new($alg);
128cbdba 184 if ($portable && -T $file) {
dcbcf62d 185 local $/ = \4096;
186 while (defined (my $rec = <F>)) {
187 while (substr($rec, -1) eq "\015") {
188 defined (my $extra = <F>) or last;
189 $rec .= $extra;
190 }
191 $rec =~ s/\015+\012/\012/g;
192 $rec =~ s/\015/\012/g;
193 $digest->add($rec);
194 }
128cbdba 195 }
dcbcf62d 196 else { $digest->addfile(*F) }
197 close(F);
128cbdba 198
dcbcf62d 199 $digest->hexdigest;
6bc89f92 200}
201
202
203 # %len2alg: maps hex digest length to SHA algorithm
204
205my %len2alg = (40 => 1, 56 => 224, 64 => 256, 96 => 384, 128 => 512);
206
207
208 # Verify checksums if requested
209
210if ($check) {
211 my $checkfile = shift(@ARGV);
212 my $err = 0;
213 my ($fh, $sum, $fname, $rsp);
214
215 die "shasum: $checkfile: No such file or directory\n"
216 unless open($fh, "<$checkfile");
217 while (<$fh>) {
218 s/\s+$//;
128cbdba 219 ($sum, $mode, $fname) = /^(\S+) (.)(.*)$/;
dcbcf62d 220 unless (-e $fname) {
221 warn "shasum: $fname: No such file or directory\n";
222 next;
223 }
128cbdba 224 ($binary, $portable, $text) =
225 map { $_ eq $mode } ('*', '?', ' ');
6bc89f92 226 unless ($alg = $len2alg{length($sum)}) {
dcbcf62d 227 warn("shasum: $checkfile: $.: improperly " .
228 "formatted SHA checksum line\n") if $warn;
6bc89f92 229 next;
230 }
231 $rsp = "$fname: ";
dcbcf62d 232 unless (my $digest = sumfile($fname)) {
233 $rsp .= "FAILED open or read\n";
234 $err = 1;
235 }
236 else {
237 if (lc($sum) eq $digest) { $rsp .= "OK\n" }
238 else { $rsp .= "FAILED\n"; $err = 1 }
239 }
6bc89f92 240 print $rsp unless $status;
241 }
242 close($fh);
243 exit($err);
244}
245
246
247 # Compute and display SHA checksums of requested files
248
dcbcf62d 249for my $arg (@ARGV) {
250 if (-d $arg) {
251 print STDERR "shasum: $arg: Is a directory\n";
6bc89f92 252 next;
253 }
dcbcf62d 254 next unless my $digest = sumfile($arg);
255 print "$digest $mode", "$arg\n";
6bc89f92 256}