| Dicop-Base documentation | Contained in the Dicop-Base distribution. |
Dicop::Hash -- manage hashes over files
use Dicop::Hash;
my $hash = Dicop::Hash->new('worker/linux/test');
$hash->update(); # to see whether file has changed
print $hash->as_hex();
my $hash2 = Dicop::Hash->new(\'Some static text');
$hash2->update(); # no-op
print $hash2->as_hex();
print $hash->compare($hash2) ? 'equal' : 'not equal';
perl5.005, Exporter
Exports nothing per default.
This module manages all the file hashes for the server. It currently uses MD5 as hashing algorithmn.
Create a new hash object. The only parameter is a filename to read in and calculate the hash over, or alternatively a ref to a scalar to hash.
Read in a file and then hash the file data, store hash along with time stamp.
When the file has changed, recalculate hash. Otherwise do nothing. Called by
as_hex() automatically.
Return hash value as hexified string. Does update the hash value if neccessary
before returning it, so there is no need to call update() manually.
If an error occured while hashing the file, will return a reference to the error message.
Returns a potential error message or the empty string for no error.
$hash->compare($other_hash);
Compares the both hashes and returns true if they are equal. Use this
over a plain eq because this can also work when different hash
algorithmns are in use.
(c) Bundesamt fuer Sicherheit in der Informationstechnik 1998-2008
DiCoP is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation.
See http://www.bsi.bund.de/ for more information.
| Dicop-Base documentation | Contained in the Dicop-Base distribution. |
############################################################################# # Dicop::Hash - manage hashes (MD5 etc) for files # # (c) Bundesamt fuer Sicherheit in der Informationstechnik 1998-2008 # # DiCoP is free software; you can redistribute it and/or modify it under the # terms of the GNU General Public License version 2 as published by the Free # Software Foundation. # # See the file LICENSE or L<http://www.bsi.de/> for more information. ############################################################################# package Dicop::Hash; $VERSION = 1.06; # Current version of this package require 5.004; # requires this Perl version or later use strict; use Dicop::Event qw/crumble/; use Digest::MD5; sub new { # create a new hash, parameter is file to read in (or ref to scalar to hash) my $class = shift; $class = ref($class) || $class || __PACKAGE__; my $self = {}; bless $self, $class; $self->{_hash} = ''; $self->{_error} = ''; $self->{_modified} = time; $self->{_size} = 0; $self->read(@_); $self; } sub read { # read file, hash it and store hash value my ($self,$file) = @_; $self->{_hash} = ''; $self->{_error} = ''; # reset error my $md5 = Digest::MD5->new(); if (ref($file)) { $self->{_file} = \'SCALAR'; # for update() $self->{_size} = length($$file); $md5->add($$file); } else { $self->{_file} = $file; $self->{_error} = "Cannot hash '$file': $!" and return unless -f $self->{_file}; # no regular file? my @stat = stat($self->{_file}); $self->{_size} = $stat[7]; # store size $self->{_modified} = $stat[9]; # store mtime open (SOMEFILE, $file) or (($self->{_error} = $!) and return); binmode SOMEFILE; # for non-unix $md5->addfile(*SOMEFILE); close (SOMEFILE) or ($self->{_error} = "Cannot close '$file': $!"); } $self->{_hash} = $md5->hexdigest(); $self; } sub as_hex { my $self = shift; $self->update(); return \"$self->{_error}" if $self->{_error}; return \"Unknown error - hash is empty" if $self->{_hash} eq ''; $self->{_hash}; } sub error { my $self = shift; $self->{_error}; } sub update { my $self = shift; return $self if ref($self->{_file}); # in memory file $self->{_error} = "Cannot hash '$self->{_file}': $!" and return $self unless -f $self->{_file}; # file does not exist? my @stat = stat($self->{_file}); if ( $self->{_error} || # in case of error, try again ($stat[9] != $self->{_modified}) || # or if file modified ($stat[7] != $self->{_size})) # or if size changed { $self->read($self->{_file}); # rehash } $self; } sub compare { my ($self,$other) = @_; # as_hex() calls update() for us # XXX TODO: md5=1234 vs. 1234 $self->as_hex() eq $other->as_hex(); } 1; __END__ #############################################################################