Tie::RefHash is now dual life, maintained by Yuval Kogman.
[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 #
77d2a621 7 # Version: 5.34
8 # Thu Feb 2 18:55:40 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
24 -t, --text read files in text mode (default)
25
26 The following two options are useful only when verifying checksums:
27
28 --status don't output anything, status code shows success
29 -w, --warn warn about improperly formatted SHA checksum lines
30
31 --help display this help and exit
32 --version output version information and exit
33
34The sums are computed as described in FIPS PUB 180-2. When checking,
35the input should be a former output of this program. The default
36mode is to print a line with checksum, a character indicating type
37(`*' for binary, ` ' for text), and name for each FILE.
38
39=head1 AUTHOR
40
77d2a621 41Copyright (c) 2003-2006 Mark Shelor <mshelor@cpan.org>.
6bc89f92 42
43=head1 SEE ALSO
44
45Shasum is implemented using the Perl module L<Digest::SHA> or
46L<Digest::SHA::PurePerl>.
47
48=cut
49
50use strict;
51use Getopt::Long;
52
77d2a621 53my $VERSION = "5.34";
6bc89f92 54
55
56 # Try to use Digest::SHA, since it's faster. If not installed,
57 # use Digest::SHA::PurePerl instead.
58
59my $MOD_PREFER = "Digest::SHA";
60my $MOD_SECOND = "Digest::SHA::PurePerl";
61
62my $module = $MOD_PREFER;
63eval "require $module";
64if ($@) {
65 $module = $MOD_SECOND;
66 eval "require $module";
67 die "Unable to find $MOD_PREFER or $MOD_SECOND\n" if $@;
68}
69
70
71 # Usage statement adapted from Ulrich Drepper's md5sum.
72 # Include an "-a" option for algorithm selection.
73
74sub usage {
75 my($err) = @_;
76
77 my $stream = $err ? *STDERR : *STDOUT;
78 print $stream <<'END_OF_USAGE';
79Usage: shasum [OPTION] [FILE]...
80 or: shasum [OPTION] --check [FILE]
81Print or check SHA checksums.
82With no FILE, or when FILE is -, read standard input.
83
84 -a, --algorithm 1 (default), 224, 256, 384, 512
85 -b, --binary read files in binary mode (default on DOS/Windows)
86 -c, --check check SHA sums against given list
87 -t, --text read files in text mode (default)
88
89The following two options are useful only when verifying checksums:
90 --status don't output anything, status code shows success
91 -w, --warn warn about improperly formatted SHA checksum lines
92
93 --help display this help and exit
94 --version output version information and exit
95
96The sums are computed as described in FIPS PUB 180-2. When checking,
97the input should be a former output of this program. The default
98mode is to print a line with checksum, a character indicating type
99(`*' for binary, ` ' for text), and name for each FILE.
100
101Report bugs to <mshelor@cpan.org>.
102END_OF_USAGE
103 exit($err);
104}
105
106
107 # Collect options from command line
108
109my ($alg, $binary, $check, $text, $status, $warn, $help, $version);
110
111GetOptions(
112 'binary' => \$binary, 'check' => \$check,
113 'text' => \$text, 'algorithm=i' => \$alg,
114 'status' => \$status, 'warn' => \$warn,
115 'help' => \$help, 'version' => \$version
116) or usage(1);
117
118
119 # Deal with help requests and incorrect uses
120
121usage(0) if $help;
122usage(1) if $binary and $text;
123usage(1) if $warn and not $check;
124usage(1) if $status and not $check;
125
126
127 # Default to SHA-1 unless overriden by command line option
128
129$alg = 1 unless $alg;
130grep { $_ == $alg } (1, 224, 256, 384, 512) or usage(1);
131
132
133 # Display version information if requested
134
135if ($version) {
136 print "$VERSION\n";
137 exit(0);
138}
139
140
141 # Try to figure out if the OS is DOS-like. If it is,
142 # default to binary mode when reading files, unless
143 # explicitly overriden by command line "text" option.
144
145my $isDOSish = ($^O =~ /^(MSWin\d\d|os2|dos|mint|cygwin)$/);
146if ($isDOSish) { $binary = 1 unless $text }
147
148
149 # Read from STDIN (-) if no files listed on command line
150
151@ARGV = ("-") unless @ARGV;
152
153
154 # sumfile($file): computes SHA digest of $file
155
156sub sumfile {
157 my($file) = @_;
158 my($fh, $digest);
159
160 unless (open($fh, "<$file")) {
161 print STDERR "shasum: $file: No such file or directory\n";
162 return;
163 }
164 binmode($fh) if $binary;
165 $digest = $module->new($alg)->addfile($fh)->hexdigest;
166 close($fh);
167 return($digest);
168}
169
170
171 # %len2alg: maps hex digest length to SHA algorithm
172
173my %len2alg = (40 => 1, 56 => 224, 64 => 256, 96 => 384, 128 => 512);
174
175
176 # Verify checksums if requested
177
178if ($check) {
179 my $checkfile = shift(@ARGV);
180 my $err = 0;
181 my ($fh, $sum, $fname, $rsp);
182
183 die "shasum: $checkfile: No such file or directory\n"
184 unless open($fh, "<$checkfile");
185 while (<$fh>) {
186 s/\s+$//;
187 ($sum, $binary, $fname) = /^(\S+)\s+(\*?)(.*)$/;
188 unless ($alg = $len2alg{length($sum)}) {
189 print STDERR "shasum: $checkfile: $.: improperly ",
190 "formatted SHA checksum line\n" if $warn;
191 next;
192 }
193 $rsp = "$fname: ";
194 if (lc($sum) eq sumfile($fname)) { $rsp .= "OK\n" }
195 else { $rsp .= "FAILED\n"; $err = 1 }
196 print $rsp unless $status;
197 }
198 close($fh);
199 exit($err);
200}
201
202
203 # Compute and display SHA checksums of requested files
204
205for (@ARGV) {
206 if (-d $_) {
207 print STDERR "shasum: $_: Is a directory\n";
208 next;
209 }
210 next unless my $digest = sumfile($_);
211 print "$digest ", $binary ? "\*" : " ", "$_\n";
212}