3 # shasum: filter for computing SHA digests (analogous to md5sum)
5 # Copyright (C) 2003-2005 Mark Shelor, All Rights Reserved
8 # Fri Dec 2 02:32:20 MST 2005
12 shasum - Print or Check SHA Checksums
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.
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)
26 The following two options are useful only when verifying checksums:
28 --status don't output anything, status code shows success
29 -w, --warn warn about improperly formatted SHA checksum lines
31 --help display this help and exit
32 --version output version information and exit
34 The sums are computed as described in FIPS PUB 180-2. When checking,
35 the input should be a former output of this program. The default
36 mode is to print a line with checksum, a character indicating type
37 (`*' for binary, ` ' for text), and name for each FILE.
41 Copyright (c) 2003-2005 Mark Shelor <mshelor@cpan.org>.
45 Shasum is implemented using the Perl module L<Digest::SHA> or
46 L<Digest::SHA::PurePerl>.
56 # Try to use Digest::SHA, since it's faster. If not installed,
57 # use Digest::SHA::PurePerl instead.
59 my $MOD_PREFER = "Digest::SHA";
60 my $MOD_SECOND = "Digest::SHA::PurePerl";
62 my $module = $MOD_PREFER;
63 eval "require $module";
65 $module = $MOD_SECOND;
66 eval "require $module";
67 die "Unable to find $MOD_PREFER or $MOD_SECOND\n" if $@;
71 # Usage statement adapted from Ulrich Drepper's md5sum.
72 # Include an "-a" option for algorithm selection.
77 my $stream = $err ? *STDERR : *STDOUT;
78 print $stream <<'END_OF_USAGE';
79 Usage: shasum [OPTION] [FILE]...
80 or: shasum [OPTION] --check [FILE]
81 Print or check SHA checksums.
82 With no FILE, or when FILE is -, read standard input.
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)
89 The 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
93 --help display this help and exit
94 --version output version information and exit
96 The sums are computed as described in FIPS PUB 180-2. When checking,
97 the input should be a former output of this program. The default
98 mode is to print a line with checksum, a character indicating type
99 (`*' for binary, ` ' for text), and name for each FILE.
101 Report bugs to <mshelor@cpan.org>.
107 # Collect options from command line
109 my ($alg, $binary, $check, $text, $status, $warn, $help, $version);
112 'binary' => \$binary, 'check' => \$check,
113 'text' => \$text, 'algorithm=i' => \$alg,
114 'status' => \$status, 'warn' => \$warn,
115 'help' => \$help, 'version' => \$version
119 # Deal with help requests and incorrect uses
122 usage(1) if $binary and $text;
123 usage(1) if $warn and not $check;
124 usage(1) if $status and not $check;
127 # Default to SHA-1 unless overriden by command line option
129 $alg = 1 unless $alg;
130 grep { $_ == $alg } (1, 224, 256, 384, 512) or usage(1);
133 # Display version information if requested
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.
145 my $isDOSish = ($^O =~ /^(MSWin\d\d|os2|dos|mint|cygwin)$/);
146 if ($isDOSish) { $binary = 1 unless $text }
149 # Read from STDIN (-) if no files listed on command line
151 @ARGV = ("-") unless @ARGV;
154 # sumfile($file): computes SHA digest of $file
160 unless (open($fh, "<$file")) {
161 print STDERR "shasum: $file: No such file or directory\n";
164 binmode($fh) if $binary;
165 $digest = $module->new($alg)->addfile($fh)->hexdigest;
171 # %len2alg: maps hex digest length to SHA algorithm
173 my %len2alg = (40 => 1, 56 => 224, 64 => 256, 96 => 384, 128 => 512);
176 # Verify checksums if requested
179 my $checkfile = shift(@ARGV);
181 my ($fh, $sum, $fname, $rsp);
183 die "shasum: $checkfile: No such file or directory\n"
184 unless open($fh, "<$checkfile");
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;
194 if (lc($sum) eq sumfile($fname)) { $rsp .= "OK\n" }
195 else { $rsp .= "FAILED\n"; $err = 1 }
196 print $rsp unless $status;
203 # Compute and display SHA checksums of requested files
207 print STDERR "shasum: $_: Is a directory\n";
210 next unless my $digest = sumfile($_);
211 print "$digest ", $binary ? "\*" : " ", "$_\n";