--- loncom/build/filecompare.pl 2001/12/06 00:23:16 1.9 +++ loncom/build/filecompare.pl 2014/06/09 05:14:12 1.15 @@ -1,16 +1,38 @@ #!/usr/bin/perl # The LearningOnline Network with CAPA -# # filecompare.pl - script used to help probe and compare file statistics # +# $Id: filecompare.pl,v 1.15 2014/06/09 05:14:12 raeburn Exp $ +# +# Copyright Michigan State University Board of Trustees +# +# This file is part of the LearningOnline Network with CAPA (LON-CAPA). +# +# LON-CAPA is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# LON-CAPA is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LON-CAPA; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# /home/httpd/html/adm/gpl.txt +# +# http://www.lon-capa.org/ +# # YEAR=2001 # 9/27, 10/24, 10/25, 11/4 Scott Harrison # 11/14 Guy Albertelli # 11/16,11/17 Scott Harrison # 12/3,12/5 Scott Harrison # -# $Id: filecompare.pl,v 1.9 2001/12/06 00:23:16 harris41 Exp $ ### ############################################################################### @@ -50,11 +72,13 @@ Options (before file/dir names): -a show all files (with comparisons) -q only show file names (based on first file/dir) -v verbose mode (default) --bN buildmode (controls exit code of this script; 0 unless...) +-bN buildmode (controls EXIT code of this script; 0 unless...) N=1: md5sum=same --> 1; cvstime<0 --> 2 N=2: same as N=1 except without md5sum N=3: md5sum=same --> 1; age<0 --> 2 N=4: cvstime>0 --> 2 + N=5: md5sum=same --> 1; cvstime<0 and sha1sum from dns_checksums=different --> 2; + N=6: md5sum=same --> 1; age<0 and sha1sum from dns_checksums=different --> 2; The third way to pass arguments is set by the -s flag. filecompare.pl -s SOURCE=[source] TARGET=[target] MODE=[mode] LOC1 LOC2 @@ -81,6 +105,7 @@ unless (@ARGV) { # size similarity (bytes) # line count difference # number of different lines +# sha1sum similarity to checksum for same file in installed version # # Quantities of comparison: # existence (no,yes); other values become 'n/a' @@ -90,10 +115,11 @@ unless (@ARGV) { # size similarity (byte difference) # line count difference (integer) # number of different lines (integer) +# sha1sum ("same" or "different") # ---------------------------------------------------------------- Dependencies # implementing from unix command line (assuming bash) -# md5sum, diff, wc -l +# md5sum, diff, wc -l, sha1sum # ---------------------------------------------- Process command line arguments # Flags (before file/dir names): @@ -140,6 +166,7 @@ dowarn('Show: '.$show."\n"); my @files; my $loc1; my $loc2; +my $dirmode='directories'; # ----------------------------------------- If status checking mode for lpml my ($sourceroot,$targetroot,$mode,$sourceglob,$targetglob); my ($source,$target); @@ -153,7 +180,16 @@ if ($statusmode==1) { # print "SOURCE: $source\n"; # print "TARGET: $target\n"; if ($mode eq 'MODE=fileglob') { - @files=glob($source); + $loc1=$source;$loc1=~s/\/[^\/]*$// if length($loc1)>2; + $loc2=$target;$loc2=~s/\/[^\/]*$// if length($loc2)>2; + @files=map {s/^$loc1\///;$_} glob($source); + $dirmode='directories'; + } + elsif ($mode eq 'MODE=file') { + $loc1=$source; + $loc2=$target; + $dirmode='files'; + @files=($loc1); } } else { @@ -162,7 +198,6 @@ else { # FILE1 FILE2 or DIR1 DIR2 $loc1=shift @ARGV; $loc2=shift @ARGV; -my $dirmode='directories'; unless ($loc1 and $loc2) { print "LOC1: $loc1\nLOC2: $loc2\n"; print($invocation), exit(1); @@ -209,6 +244,7 @@ my %OUTPUT=( 'size'=>(sub {print 'size: '.@_[0];return;}), 'lines'=>(sub {print 'lines: '.@_[0];return;}), 'diffs'=>(sub {print 'diffs: '.@_[0];return;}), + 'sha1sum'=>(sub {print 'sha1sum: '.@_[0];return;}), ); my %MEASURE=( @@ -238,11 +274,37 @@ my %MEASURE=( my $rv2=`wc -l $file2`; chop $rv2; return ($rv1,$rv2); } ), 'diffs'=>( sub { my ($file1,$file2)=@_; + return (0,0); my $rv1=`diff $file1 $file2 | grep '^<' | wc -l`; chop $rv1; $rv1=~s/^\s+//; $rv1=~s/\s+$//; my $rv2=`diff $file1 $file2 | grep '^>' | wc -l`; chop $rv2; $rv2=~s/^\s+//; $rv2=~s/\s+$//; return ($rv1,$rv2); } ), + 'sha1sum'=>( sub { my ($file1,$file2)=@_; + if (open(my $fh,"; + close($fh); + chomp($loncaparev); + $loncaparev =~ s/^\QLON-CAPA release \E//; + $loncaparev =~ s/\-\d{8}$//; + my ($rv1)=split(/ /,`sha1sum $file2`); chomp $rv1; + my $checksum; + if ($loncaparev eq 'CVS_HEAD') { + return ($rv1,$checksum); + } + elsif (open(my $fh,"<../../loncom/dns_checksums/$loncaparev.tab")) { + while (<$fh>) { + chomp(); + if (/^\Q$file2\E,[\d\.]+,(\w+)$/) { + $checksum = $1; + last; + } + } + close($fh); + return ($rv1,$checksum); + } + } + return('n/a','n/a'); }), ); FLOOP: foreach my $file (@files) { @@ -258,7 +320,7 @@ FLOOP: foreach my $file (@files) { } my ($existence1,$existence2)=&{$MEASURE{'existence'}}($file1,$file2); my $existence=$existence1.':'.$existence2; - my ($cvstime,$md5sum,$age,$size,$lines,$diffs); + my ($cvstime,$md5sum,$age,$size,$lines,$diffs,$sha1sum); if ($existence1 eq 'no' or $existence2 eq 'no') { $md5sum='n/a'; $age='n/a'; @@ -266,14 +328,28 @@ FLOOP: foreach my $file (@files) { $size='n/a'; $lines='n/a'; $diffs='n/a'; + $sha1sum='n/a'; } else { if ($buildmode) { my ($cvstime1,$cvstime2)=&{$MEASURE{'cvstime'}}($file1,$file2); $cvstime=$cvstime1-$cvstime2; - } + my ($sha1sumfile,$checksum) = &{$MEASURE{'sha1sum'}}($file1,$file2); + $sha1sum='n/a'; + unless ($checksum eq 'n/a') { + if ($sha1sumfile && $checksum) { + if ($sha1sumfile eq $checksum) { + $sha1sum='same'; + } + else { + $sha1sum='different'; + } + } + } + } else { $cvstime='n/a'; + $sha1sum='n/a'; } my ($age1,$age2)=&{$MEASURE{'age'}}($file1,$file2); $age=$age1-$age2; @@ -392,7 +468,7 @@ FLOOP: foreach my $file (@files) { $showflag=1; } } - if ($buildmode==1) { + if ($buildmode==1) { # -b1 if ($md5sum eq 'same') { exit(1); } @@ -403,7 +479,7 @@ FLOOP: foreach my $file (@files) { exit(0); } } - elsif ($buildmode==2) { + elsif ($buildmode==2) { # -b2 if ($cvstime<0) { exit(2); } @@ -411,7 +487,7 @@ FLOOP: foreach my $file (@files) { exit(0); } } - elsif ($buildmode==3) { + elsif ($buildmode==3) { # -b3 if ($md5sum eq 'same') { exit(1); } @@ -422,7 +498,7 @@ FLOOP: foreach my $file (@files) { exit(0); } } - elsif ($buildmode==4) { + elsif ($buildmode==4) { # -b4 if ($existence=~/no$/) { exit(3); } @@ -436,6 +512,39 @@ FLOOP: foreach my $file (@files) { exit(0); } } + elsif ($buildmode==5) { # -b5 + if ($md5sum eq 'same') { + exit(1); + } + elsif ($cvstime<0) { + if ($sha1sum eq 'same') { + exit(0); + } + else { + exit(2); + } + } + else { + exit(0); + } + } + elsif ($buildmode==6) { # -b6 + if ($md5sum eq 'same') { + exit(1); + } + elsif ($age<0) { + if ($sha1sum eq 'same') { + exit(0); + } + else { + exit(2); + } + } + else { + exit(0); + } + } + if ($showflag) { print "$file"; if ($verbose==1) { @@ -447,12 +556,15 @@ FLOOP: foreach my $file (@files) { print &{$OUTPUT{'age'}}($age); print "\t"; print &{$OUTPUT{'md5sum'}}($md5sum); + print "\t"; + print &{$OUTPUT{'sha1sum'}}($sha1sum); print "\t"; print &{$OUTPUT{'size'}}($size); print "\t"; print &{$OUTPUT{'lines'}}($lines); print "\t"; print &{$OUTPUT{'diffs'}}($diffs); + } print "\n"; } @@ -472,12 +584,18 @@ sub cvstime { } my $cvstime; if ($buildmode!=3) { - my $entry=`grep '^/$file/' ${path}CVS/Entries` or - die('*** ERROR *** cannot grep against '.${path}. - 'CVS/Entries for ' .$file . "\n"); - my @fields=split(/\//,$entry); - $cvstime=`date -d '$fields[3] UTC' --utc +"%s"`; - chomp $cvstime; + my $entry=`grep '^/$file/' ${path}CVS/Entries 2>/dev/null`; +# or +# die('*** WARNING *** cannot grep against '.${path}. +# 'CVS/Entries for ' .$file . "\n"); + if ($entry) { + my @fields=split(/\//,$entry); + $cvstime=`date -d '$fields[3] UTC' --utc +"%s"`; + chomp $cvstime; + } + else { + $cvstime='n/a'; + } } else { $cvstime='n/a';