#!/usr/bin/perl -wT
#-*-perl-*-
# $rcs = ' $Id: md5sum,v 1.5 2001/04/12 07:12:12 idnopheq Exp idnophe
+q $ ' ;
use strict;
use FileHandle;
use Digest::MD5;
use Getopt::Mixed 1.006, "nextOption";
use vars qw ( %option );
my ($VERSION) = '$Revision: 1.5 $' =~ /([.\d]+)/;
my $warnings = 0;
# Print a usage message on a unknown option.
# Requires abigail's patch to Getopt::Std of 25 Feb 1999.
$SIG {__WARN__} = sub {
if (substr ($_ [0], 0, 14)
eq "Unknown option") {
die "Usage"
};
require File::Basename;
$0 = File::Basename::basename ($0);
$warnings = 1;
warn "$0: @_";
};
$SIG {__DIE__} = sub {
require File::Basename;
$0 = File::Basename::basename ($0);
if (substr ($_ [0], 0, 7) eq "Version") {
die <<VER;
$0 (Perl bin utils) $VERSION
VER
}
elsif (substr ($_ [0], 0, 5) eq "Usage") {
die <<EOF;
$0 (Perl bin utils) $VERSION
$0 [-bBcpqrtwvV] [-s string] [file ...]
EOF
}
elsif (substr ($_ [0], 0, 4) eq "Help") {
die <<HELP;
$0 (Perl bin utils) $VERSION
$0 [-bBcpqrtwvV] [-s string] [file ...]
-b, --binary binary file mode
-B, --bsd FreeBSD, maybe OpenBSD?, format
-c, --check check manifest file
-p, print from stdin. Does nothing, included for FreeBSD
-q, --quiet only the MD5 sum is printed out
-r, --reverse Reverses the format of the output like FSF but no bin
+ary *
-s, --string Print a checksum of the given string
-t, --text text file mode (default)
-v, does nothing, included for Win32
-h, --help display this help and exit
-V, --version output version information and exit
The following two options are useful only when verifying checksums:
--status don't output anything, status code shows success
-w, --warn warn about improperly formated MD5 checksum lines
The sums are computed as described in RFC 1321. When checking, the in
+put
should be a former default output of this program. The default mode i
+s to
print a line with checksum, a character indicating type ('*' for binar
+y, ' '
for text), and name for each FILE.
HELP
}
die "$0: @_";
};
# Get the options.
Getopt::Mixed::init (
"binary", # binary file mode
"b>binary", # -b an alias for --binary
"bsd", # FreeBSD, maybe OpenBSD?, format
"B>bsd", # -B an alias for --bsd
"check", # check manifest file
"c>check", # -c an alias for --check
"help", # more detailed help
"?>help", # -? an alias for --help
"h>help", # -h an alias for --help
"p", # does nothing, included for FreeBSD
"quiet", # only the MD5 sum is printed out
"q>quiet" , # -q an alias for --quiet
"reverse", # Reverses the format of the output
# like FSF but no binary *
"r>reverse", # -r an alias for --reverse
"status", # return 0 on ok, non-0 on badness
# only useful w/ -c or --check
"string=s", # Print a checksum of a given string
"s>string", # -s an alias for --string
"text", # text mode (default)
"t>text", # -t an alias for --text
"v", # does nothing, included for Win32
"version", # print the version number and exit
"V>version", # -V an alias for --version
"warn", # show # of ok and bad checksums
# only useful w/ -c or --check
"w>warn", # -w an alias for --warn
);
# process the options and gently place them in a hash for easy access
while (
my (
$option,
$value,
$asEntered
) = nextOption ()
) {
$option{$option} = $value || 1;
}
# cleanup options
Getopt::Mixed::cleanup();
# *** BEGGING FOR SWITCH CONSTRUCT
die "Version"
if $option{'version'};
die "Help"
if $option{'help'};
# if the 'string' option was presented, $option{'string'} will hold th
+at
# string, so hash it & print & outta here
if ( $option{'string'} ) {
my $inMD5 = Digest::MD5->new;
$inMD5->add ( $option{'string'} );
print outputHash(
$option{'string'},
$inMD5->hexdigest,
' '
);
exit;
}
# if we are checking file from a manifest file, the do it and bye!
if ( $option{'check'} ) {
checkManifest ( $ARGV[0] );
exit;
}
# figure out if we're working binary via OS and a 'text' override
$option{'binary'} ||= $^O =~ /MSWin32/;
undef $option{'binary'}
if $option{'text'};
$ARGV[0] ||= "-";
# here endeth the begging ***
# MAIN, if you will
# parse each remaining option and treat it as a file to hash
foreach my $file ( @ARGV ) {
chomp $file;
my (
$md5Digest,
$binary
) = MD5 ( $file );
print &outputHash (
$file,
$md5Digest,
$binary
);
}
sub MD5 {
my $file = shift;
my $prefix = ' ';
my $inFile = new FileHandle;
my $inMD5 = Digest::MD5->new;
unless (-e $file) {
warn "$file: No such file or directory\n";
return;
}
unless ( $inFile->open ( "<$file" ) ) {
warn "Could not open $file:$!\n";
return;
}
binmode ( $inFile ) && ( $prefix = '*' )
if $option{'binary'};
$inMD5->addfile ( $inFile );
$inFile->close; # being tidy
return $inMD5->hexdigest, $prefix;
}
sub checkManifest {
my $file = shift;
my $inFile = new FileHandle;
unless (-e $file) {
warn "$file: No such file or directory\n";
return;
}
$inFile->open ( "<$file" )
or die "Could not open $file:$!\n";
my $ok = my $failed = 0;
while ( <$inFile> ) {
next
if /^#/; # skip comments
# our manifest file ~should be~ in a fixed format if sane
my (
$md5Hash,
$binary,
$fileName
) = unpack "a32 a2 A*", $_;
warn "$fileName: No such file or directory\n" && next
unless -e $fileName;
my $karma = verifyHash (
$md5Hash,
$fileName
);
KARMA: {
unless ( $karma && -e $fileName ) {
warn "$fileName: No such file or directory\n";
$failed++;
return;
return;
}
unless ( $karma ) {
warn "$fileName: Improperly formatted MD5 checksum line\n";
$failed++;
next;
return;
}
bless $inFile;
}
my $md5 = ( MD5 ( $fileName ) )[0]
or return;
$option{'binary'} = ( $binary =~ /\*/ ) || undef;
if ( $md5Hash eq $md5 ) {
print $fileName , ": OK\n"
unless $option{'status'};
$ok++;
}
else {
print $fileName , ": FAILED\n"
unless $option{'status'};
$failed++;
}
}
if ( $option{'status'} ) {
if ( $failed > 0 ) { return 1; };
return 0;
}
$= = $ok+$failed;
warn "WARNING: $failed of ", $=, " computed checksums did NOT match\
+n"
if ( $failed > 0 && $option{'warn'} );
}
sub verifyHash {
my (
$hash,
$file
) = @_;
if ( length $hash != 32 ) { return }
elsif ( ! -e $file ) { return 2 }
return 1;
}
sub onError {
require File::Basename;
return File::Basename::basename ($0);
}
sub outputHash {
my (
$file,
$md5Hash,
$bin
) = @_;
return
unless $md5Hash;
if ( ( defined $option{'bsd'} )
+ ( defined $option{'quiet'} )
+ ( defined $option{'reverse'} )
> 1 ) {
warn "Too many output options defined. Setting to default (FSF) st
+yle.\n";
undef $option{'bsd'};
undef $option{'quiet'};
undef $option{'reverse'};
}
OUTPUT: {
$option{'bsd'} && do {
return onError() , " ($file) = $md5Hash\n";
last OUTPUT;
};
$option{'quiet'} && do {
return "$md5Hash\n";
last OUTPUT;
};
$option{'reverse'} && do {
return "$md5Hash $file\n";
last OUTPUT;
};
return "$md5Hash $bin$file\n";
}
}
__DATA__
=pod
=head1 NAME
md5sum - Print or check message-digests
=head2 SYNOPSIS
md5sum [option]... [file]...
md5sum [option]... --check [file]
=head2 DESCRIPTION
md5sum computes a 128-bit checksum (or fingerprint or message-digest)
+for each specified file. If a file is specified as `-' or if no files
+ are given md5sum computes the checksum for the standard input. md5su
+m can also determine whether a file and checksum are consistent. Syno
+pses:
For each file, `md5sum' outputs the MD5 checksum, a flag indicating a
+binary or text input file, and the filename. If file is omitted or sp
+ecified as `-', standard input is read.
=head2 OPTIONS
The program accepts the following options.
=item -b --binary Treat all input files as binary.
This option has no effect on Unix systems, since they don't distinguis
+h between binary and text files. This option is useful on systems tha
+t have different internal and external character representations. On
+MS-DOS and MS-Windows, this is the default.
=item -B --bsd Provide FreeBSD default output
Like the md5 command of the BSD-derrivitives. This output will not wo
+rk with the check feature.
=item -c --check
Read filenames and checksum information from the single file (or from
+stdin if no file was specified) and report whether each named file an
+d the corresponding checksum data are consistent.
The input to this mode of md5sum is usually the output of a prior, che
+cksum-generating run of `md5sum'. Each valid line of input consists o
+f an MD5 checksum, a binary/text flag, and then a filename. Binary fi
+les are marked with `*', text with ` '. For each such line, md5sum re
+ads the named file and computes its MD5 checksum. Then, if the comput
+ed message digest does not match the one on the line with the filenam
+e, the file is noted as having failed the test. Otherwise, the file p
+asses the test.
By default, for each valid line, one line is written to standard outpu
+t indicating whether the named file passed the test. After all checks
+ have been performed, if there were any failures, a warning is issued
+ to standard error. Use the `--status' option to inhibit that output.
+ If any listed file cannot be opened or read, if any valid line has a
+n MD5 checksum inconsistent with the associated file, or if no valid
+line is found, md5sum exits with nonzero status. Otherwise, it exits
+successfully.
=item -p Echo stdin to stdout and appends the MD5 sum
+to stdout
(Default w/o options, so ignorred). For *BSD boxen.
=item -q --quiet Quiet mode
Only the MD5 sum is printed out. Overrides the -r option.
=item -r --reverse Reverses the format of the output
This helps with visual diffs, if you're on a *BSD box. Simillar to de
+fault output, but w/o the binary star '*' prepending binary files. T
+his may be important if you're on a Win32 boxen.
=item --status
This option is useful only when verifying checksums. When verifying ch
+ecksums, don't generate the default one-line-per-file diagnostic and
+don't output the warning summarizing any failures. Failures to open o
+r read a file still evoke individual diagnostics to standard error. I
+f all listed files are readable and are consistent with the associate
+d MD5 checksums, exit successfully. Otherwise exit with a status code
+ indicating there was a failure.
=item -s --string Print the MD5 checksum of the string
This option overrides most options, and requires you to provide text a
+s an argument to the option. Based on your shell, you will likely wa
+nt to single quote ' the text on both ends.
=item -t --text Treat all input files as text files
This is the reverse of `--binary'.
=item -v Verbose output
(Default w/o options, so ignorred). For MS-DOS-derrived boxen.
=item -w --warn
This option is useful only when verifying checksums. When verifying ch
+ecksums, warn about improperly formatted MD5 checksum lines. This opt
+ion is useful only if all but a few lines in the checked input are va
+lid.
=head2 SEE ALSO
I dunno? Some man pages, like md5sum and md5?
=head2 ACKNOWLEDGEMENTS
RSA Data Security probably think they get some credit. I'd like to th
+ank the Academy, all those people who I love, and of course the Perl
+Monks, especially abigail.
=head2 LICENSE
# Copyright (c) 2001
# Dexter Coffin. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in t
+he
# documentation and/or other materials provided with the distributi
+on.
#
# THIS SOFTWARE IS PROVIDED BY DEXTER COFFIN AND CONTRIBUTORS ``AS IS'
+' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, TH
+E
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR P
+URPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL DEXTER COFFIN OR CONTRIBUTORS BE
+LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQU
+ENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GO
+ODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION
+)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN AN
+Y WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+OF
# SUCH DAMAGE.
#
=cut
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.