#!/usr/bin/perl -w # # checksum # # This updates a list of all checksummed files, or it returns # the checksum of a specific file. # ### ### Configuration ### use strict; use vars qw($ChecksumVersion %Data @Exclude @NoChecksums); $ChecksumVersion = 'checksum v0.04 regan@ao.com'; @NoChecksums = ( "/RCS/", '\.tar\.gz', "Config/data", "Temp/", "Config/testsite", "Config/distributionsite", "Config/application.files" ); ### ### Main program ### my($arg, $command, $cs, $size); $command = "--compute"; while (defined($arg = shift(@ARGV))) { if ($arg eq "--update" || $arg eq "--compute") { $command = $arg; } elsif ($arg eq "--exclude") { $arg = shift(@ARGV); push(@Exclude, $arg); } elsif ($command eq "--compute") { $cs = Checksum($arg); if (defined($cs)) { $size = -s $arg; print "$size $cs\n"; } } } if ($command eq "--update") { ReadChecksums(); ComputeNewChecksums(); WriteChecksums(); } exit 0; ### ### Checksum ### ### Compute the checksum of a specific file. Omit many of the ### items which are munged by the localization process. ### sub Checksum { my($fname) = @_; my($cs, $line, $pattern); for $pattern (@NoChecksums) { return undef if ($fname =~ /$pattern/); } if (!open(FILE, "<$fname")) { print "Cannot open $fname\n"; return 0; } $cs = 0; $line = 0; while () { $line++; next if ($line == 1 && /^#!.*perl/); next if (/^\$ApplRoot\s*=/); # The root changes next if (/^AuthUserFile\s/); # The password file changes next if (/^AuthName\s/); # The realm will change next if (/\$WebC\s*=/); $cs += unpack("%32C*", $_); } close FILE; return $cs; } ### ### ComputeNewChecksums ### ### Go through all of the files and build checksums. ### sub ComputeNewChecksums { my($cs, $data, $exclude, $file, @files, $looser, $size, $time); @files = `find . -type f -a -print`; for $file (@files) { chomp($file); $file =~ s#^\./##; $looser = 0; next if ($file eq "Config/checksums"); for $exclude (@Exclude) { $looser = 1 if ($file =~ /$exclude/); } next if ($looser); $cs = Checksum($file); if (defined($cs)) { $size = -s $file; $time = (stat($file))[10]; $Data{$file} = "" if (!defined($Data{$file})); $data = "($time $size $cs)"; $Data{$file} .= $data unless ($Data{$file} =~ /\Q$data/); # print "$file: $time $cs\n"; } } } ### ### ReadChecksums ### sub ReadChecksums { return if (!open(CS, ") { chomp; if (/(.*): (.*)/) { $Data{$1} = $2; } } close CS; } ### ### WriteChecksums ### sub WriteChecksums { my($fname); if (!open(CS, ">Config/checksums")) { print STDERR "Cannot open Config/checksums: $!\n"; exit 1; } for $fname (sort keys(%Data)) { print CS "$fname: $Data{$fname}\n"; } close CS; }