NAME

File::Signature - Detect changes to a file's content or attributes.

SYNOPSIS

use File::Signature;
my $sig = File::Signature->new('/some/file');

# If you have a stringified signature stored in $string 
# you can create a File::Signature object from it.
my $sig = File::Signature->new_from_string($string);

if (my $err = $sig->error) { 
    warn $err, "\n";
}
# You can use a signature object to re-check the same file.
if ( $sig->is_same() ) { print "Ok. The signature is the same.\n" }
if ( $sig->changed() ) { print "Uh Oh! The signature has changed.\n" }

my @digests = $sig->old_and_new('digest');
my @inodes  = $sig->old_and_new('ino'); 
my @modes   = $sig->old_and_new('mode');
my @uid     = $sig->old_and_new('uid');
my @gid     = $sig->old_and_new('gid'); 
my @mtime   = $sig->old_and_new('mtime'); 

# A slightly more worthwhile use...
my @fields = $sig->changed(); 
for my $field (@fields) { 
    printf "$field was: %s but changed to %s.\n", 
               $sig->old_and_new($field);
}

ABSTRACT

This perl library uses perl5 objects to assist in determining whether a file's contents or attributes have changed. It maintains several pieces of information about the file: a digest (currently only MD5 is supported), its inode number, its mode, the uid of its owner, the gid of its group owner, and its last modification time. A File::Signature object is closely associated with a single pathname. It provides a way to compare the state of a file over different points in time; it isn't useful for comparing different files.

DESCRIPTION

This module provides a way to monitor files for changes. It implements an object oriented interface to file "signatures." In the case of this module, a signature includes an MD5 digest (other digests may be added later), the file's size, its inode number, its mode, its owner's uid, its group's gid, and its mtime. This information is associated with a file by the file's "pathname." The pathname is considered to be the file's unique identifier. In reality, a file may have more than one pathname, but this module doesn't recognize that. It will simply treat two differing pathnames as two different files, even if they refer to the same file.

As this module checks whether a file changes over time, a minimal use of it would include the time when the signature was created and a different time when the signature is regenerated and compared with the previous one. The amount of time between these checks is arbitrary. This module makes it easy to save a signature object and then load it and check for consistency at a later time, whether seconds or years have passed.

CONSTRUCTORS

new()

This constructor requires a pathname argument. If one is not provided, it will throw an exception (i.e. croak.) If the pathname cannot be stat()'d or if it cannot be read, the object returned will hold an error accessible via the error() instance method. The pathname should be absolute and, if it isn't it well be resolved to an absolute pathname unless the "allow_relative_paths" configure option is provided. See "configure()" below.

new_from_string()

This constructor takes a single argument, a previously stringified signature object, and returns a new signature object created from the string.

INSTANCE METHODS

error()

If there was a non-fatal error when the object was constructed or when the last check was performed, a signature error object is returned instead. This method determines whether the object is an error object. It returns false if it isn't and a true value if it is. The true value in that case will be a human readable error message in scalar context or, in list context, list containing a "failure" message, the pathname, and an optional system error message.

is_same()

Updates the signature and checks whether it is the same. It returns true if it is and false if it isn't. It will throw an exception (i.e. croak) if the current signature object reports an error.

changed()

Updates the signature and checks whether it is has changed. It returns true if it has and false if it hasn't. It will throw an exception (i.e. croak) if the current signature object reports an error.

old_and_new()

This method requires a fieldname to be passes as a string. It returns a two-element list consisting of the previous and current value for the field with the supplied fieldname. If the fieldname is not recognized, it will return undef. This is used primarily to determine what has changed once a change has been detected with is_same() or changed(). The currently accepted fieldnames are any of qw( digest ino mode uid gid size mtime pathname ). Note that the old and new pathname fields should always be the same.

OTHER CLASS METHODS

configure()

This is used to configure special behavior for all instances. The options are passes as hash where the keys are option names and the values are the desired settings. The following keys are recognized:

use_digest_format

This key may be either 'bin', 'hex', or 'b64' and will determine whether the digest will be stored as a binary string, a string of hexadecimals, or a base64 encoded string. The default is 'hex', but that should not be relied upon as it may change in the future. An unrecognized value will result in a binary string representation just as if 'bin' had been the value. If a binary string is used, the "stringify_separator" should not be changed from "\0"!

allow_relative_paths

A true value for this key will result in relative paths being permitted as the pathname for signature objects. Usually, when a relative pathname is given in a call to the new() constructor, the absolute path is determined. This option disables that behavior. Changing this option is NOT RECOMMENDED.

stringify_separator

This option changes the field separator that is used when a signature object is stringified. By default this separator is a null ("\0"). It can be changed to any string but the string used must never appear in any of the fields. This includes the fields of signature error objects which sometimes contain system generated error messages. For example, colons and forward slashes are bad choices. Changing this option is NOT RECOMMENDED.

EXCEPTIONS

This is a list of all exceptions that thrown by File::Signature:

"argument required"

Thrown by configure() and new_from_string() when called with no arguments.

"odd argument list (not a hash?)"

Thrown by configure() when called with an odd number of arguments. (It is to be called with a hash.)

"argument was null"

Thrown by new_from_string() when called with an empty string.

"bad errobj string"

Thrown by new_from_string() when something that looks like a stringified error object results in the wrong number of fields.

"bad object string"

Thrown by new_from_string() when something that looks like a stringified signature object results in the wrong number of fields.

"pathname required"

Thrown by new() when called without an argument.

"pathname was null"

Thrown by new() when called without a null string as an argument.

"bad method call"

Thrown by is_same(), changed(), and old_and_new() when called on an error object.

EXPORT

None.

CHANGES

$Log: Signature.pm,v $
Revision 1.9  2003/08/12 19:53:03  jeremy
Fixups to tests.

Revision 1.8  2003/08/11 16:53:41  jeremy
Fixed bad POD.

Revision 1.7  2003/06/13 03:58:32  jeremy
Bug fixes, doc updates, minor changes.

Revision 1.6  2003/06/12 02:49:37  jeremy
_throw_exception() fixed. Additional error states handled in 
constructors.

Revision 1.5  2003/06/10 22:03:11  jeremy
POD updates.

Revision 1.4  2003/06/08 12:59:25  jeremy
POD changes.

Revision 1.3  2003/06/08 12:36:24  jeremy
More minor prepping for RCS.

Revision 1.2  2003/06/08 12:33:38  jeremy
Minor touch-ups for RCS prepping.

SEE ALSO

"stat" in perlfunc, MD5::Digest, stat(2)

Mention other useful documentation such as the documentation of related modules or operating system documentation (such as man pages in UNIX), or any relevant external documentation such as RFCs or standards.

AUTHOR

Jeremy Madea, <jdm@pobox.com>

COPYRIGHT AND LICENSE

Copyright (C) 2003 by Jeremy Madea. All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.