--- loncom/build/filecompare.pl 2001/10/26 00:18:54 1.1 +++ loncom/build/filecompare.pl 2001/11/16 20:06:08 1.4 @@ -1,25 +1,34 @@ #!/usr/bin/perl -# Scott Harrison +# The LearningOnline Network witih CAPA +# +# filecompare.pl - script used to help probe and compare file statistics +# # YEAR=2001 -# 9/27, 10/24, 10/25 +# 9/27, 10/24, 10/25, 11/4 Scott Harrison +# 11/14 Guy Albertelli +# 11/16 Scott Harrison +# +# $Id: filecompare.pl,v 1.4 2001/11/16 20:06:08 harris41 Exp $ +### -my $invocation=<( - sub { - print 'existence: '.@_[0]; - return; - } - ), - 'md5sum'=>( - sub { - print 'md5sum: '.@_[0]; - return; - } - ), - 'age'=>( - sub { - print 'age: '.@_[0]; - return; - } - ), - 'size'=>( - sub { - print 'size: '.@_[0]; - return; - } - ), - 'lines'=>( - sub { - print 'lines: '.@_[0]; - return; - } - ), - 'diffs'=>( - sub { - print 'diffs: '.@_[0]; - return; - } - ), + 'existence'=>( sub {print 'existence: '.@_[0]; return;}), + 'md5sum'=>(sub {print 'md5sum: '.@_[0];return;}), + 'cvstime'=>(sub {print 'cvstime: '.@_[0];return;}), + 'age'=>(sub {print 'age: '.@_[0];return;}), + 'size'=>(sub {print 'size: '.@_[0];return;}), + 'lines'=>(sub {print 'lines: '.@_[0];return;}), + 'diffs'=>(sub {print 'diffs: '.@_[0];return;}), ); my %MEASURE=( - 'existence' => ( - sub { - my ($file1,$file2)=@_; + 'existence' => ( sub { my ($file1,$file2)=@_; my $rv1=(-e $file1)?'yes':'no'; my $rv2=(-e $file2)?'yes':'no'; - return ($rv1,$rv2); - } - ), - 'md5sum'=>( - sub { - my ($file1,$file2)=@_; - my $rv1=`md5sum $file1`; chop $rv1; - my $rv2=`md5sum $file2`; chop $rv2; - return ($rv1,$rv2); - } - ), - 'age'=>( - sub { - my ($file1,$file2)=@_; - my @a=stat($file1); my $rv1=$a[10]; - @a=stat($file2); my $rv2=$a[10]; - return ($rv1,$rv2); - } - ), - 'size'=>( - sub { - my ($file1,$file2)=@_; + return ($rv1,$rv2); } ), + 'md5sum'=>( sub { my ($file1,$file2)=@_; + my ($rv1)=split(/ /,`md5sum $file1`); chop $rv1; + my ($rv2)=split(/ /,`md5sum $file2`); chop $rv2; + return ($rv1,$rv2); } ), + 'cvstime'=>( sub { my ($file1,$file2)=@_; + my $rv1=&cvstime($file1); + my @a=stat($file2); my $gmt=gmtime($a[9]); + my $rv2=&utctime($gmt); + return ($rv1,$rv2); } ), + 'age'=>( sub { my ($file1,$file2)=@_; + my @a=stat($file1); my $rv1=$a[9]; + @a=stat($file2); my $rv2=$a[9]; + return ($rv1,$rv2); } ), + 'size'=>( sub { my ($file1,$file2)=@_; my @a=stat($file1); my $rv1=$a[7]; @a=stat($file2); my $rv2=$a[7]; - return ($rv1,$rv2); - } - ), - 'lines'=>( - sub { - my ($file1,$file2)=@_; + return ($rv1,$rv2); } ), + 'lines'=>( sub { my ($file1,$file2)=@_; my $rv1=`wc -l $file1`; chop $rv1; my $rv2=`wc -l $file2`; chop $rv2; - return ($rv1,$rv2); - } - ), - 'diffs'=>( - sub { - my ($file1,$file2)=@_; + return ($rv1,$rv2); } ), + 'diffs'=>( sub { my ($file1,$file2)=@_; 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); - } - ), + return ($rv1,$rv2); } ), ); FLOP: foreach my $file (@files) { @@ -247,25 +219,28 @@ FLOP: foreach my $file (@files) { } my ($existence1,$existence2)=&{$MEASURE{'existence'}}($file1,$file2); my $existence=$existence1.':'.$existence2; - my ($md5sum,$age,$size,$lines,$diffs); + my ($cvstime,$md5sum,$age,$size,$lines,$diffs); if ($existence1 eq 'no' or $existence2 eq 'no') { $md5sum='n/a'; $age='n/a'; + $cvstime='n/a'; $size='n/a'; $lines='n/a'; $diffs='n/a'; } else { + my ($cvstime1,$cvstime2)=&{$MEASURE{'cvstime'}}($file1,$file2); + $cvstime=$cvstime1-$cvstime2; my ($age1,$age2)=&{$MEASURE{'age'}}($file1,$file2); $age=$age1-$age2; my ($md5sum1,$md5sum2)=&{$MEASURE{'md5sum'}}($file1,$file2); - if ($md5sum1 == $md5sum2) { + if ($md5sum1 eq $md5sum2) { $md5sum='same'; $size=0; $lines=0; $diffs=0; } - elsif ($md5sum1 != $md5sum2) { + elsif ($md5sum1 ne $md5sum2) { $md5sum='different'; my ($size1,$size2)=&{$MEASURE{'size'}}($file1,$file2); $size=$size1-$size2; @@ -282,7 +257,7 @@ FLOP: foreach my $file (@files) { if ($show eq 'different') { my @ks=(keys %restrict); unless (@ks) { - @ks=('existence','md5sum','age','size','lines','diffs'); + @ks=('existence','cvstime','md5sum','age','size','lines','diffs'); } FLOP2: for my $key (@ks) { if ($key eq 'existence') { @@ -295,6 +270,11 @@ FLOP: foreach my $file (@files) { $showflag=1; } } + elsif ($key eq 'cvstime') { + if ($cvstime!=0) { + $showflag=1; + } + } elsif ($key eq 'age') { if ($age!=0) { $showflag=1; @@ -323,7 +303,7 @@ FLOP: foreach my $file (@files) { elsif ($show eq 'same') { my @ks=(keys %restrict); unless (@ks) { - @ks=('existence','md5sum','age','size','lines','diffs'); + @ks=('existence','md5sum','cvstime','age','size','lines','diffs'); } my $showcount=length(@ks); FLOP3: for my $key (@ks) { @@ -337,6 +317,11 @@ FLOP: foreach my $file (@files) { $showcount--; } } + elsif ($key eq 'cvstime') { + if ($cvstime!=0) { + $showcount--; + } + } elsif ($key eq 'age') { if ($age!=0) { $showcount--; @@ -362,11 +347,51 @@ FLOP: foreach my $file (@files) { $showflag=1; } } + if ($buildmode==1) { + if ($md5sum eq 'same') { + exit(1); + } + elsif ($cvstime<0) { + exit(2); + } + else { + exit(0); + } + } + elsif ($buildmode==2) { + if ($cvstime<0) { + exit(2); + } + else { + exit(0); + } + } + elsif ($buildmode==3) { + if ($md5sum eq 'same') { + exit(1); + } + elsif ($age<0) { + exit(2); + } + else { + exit(0); + } + } + elsif ($buildmode==4) { + if ($cvstime>0) { + exit(2); + } + else { + exit(0); + } + } print "$file"; if ($verbose==1) { print "\t"; print &{$OUTPUT{'existence'}}($existence); print "\t"; + print &{$OUTPUT{'cvstime'}}($cvstime); + print "\t"; print &{$OUTPUT{'age'}}($age); print "\t"; print &{$OUTPUT{'md5sum'}}($md5sum); @@ -380,5 +405,109 @@ FLOP: foreach my $file (@files) { print "\n"; } +sub cvstime { + my ($f)=@_; + my $path; my $file; + if ($f=~/^(.*\/)(.*?)$/) { + $f=~/^(.*\/)(.*?)$/; + ($path,$file)=($1,$2); + } + else { + $file=$f; $path=''; + } + 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; + } + else { + $cvstime='n/a'; + } + return $cvstime; +} + +sub utctime { + my ($f)=@_; + my $utctime=`date -d '$f UTC' --utc +"%s"`; + chomp $utctime; + return $utctime; +} + +sub dowarn { + my ($msg)=@_; + warn($msg) unless $buildmode; +} + +=head1 NAME + +filecompare.pl - script used to help probe and compare file statistics + +=head1 SYNOPSIS + +filecompare.pl [ options ... ] [FILE1] [FILE2] [ restrictions ... ] + +or + +filecompare.pl [ options ... ] [DIR1] [DIR2] [ restrictions ... ] + +Restrictions: a list of space separated values (after the file/dir names) +can restrict the comparison. +These values can be: existence, cvstime, age, md5sum, size, lines, +and/or diffs. + +Options (before file/dir names): + + -p show all files that have the same comparison + + -n show all files that have different comparisons + + -a show all files (with comparisons) + + -q only show file names (based on first file/dir) + + -v verbose mode (default) + +=head1 DESCRIPTION + +filecompare.pl can work in two modes: file comparison mode, or directory +comparison mode. + +Comparisons can be a function of: +* existence similarity +* cvs time similarity (first argument treated as CVS source) +* age similarity (modification time) +* md5sum similarity +* size similarity (bytes) +* line count difference +* number of different lines + +filecompare.pl integrates smoothly with the LPML installation language +(linux packaging markup language). filecompare.pl is a tool that can +be used for safe CVS source-to-target installations. + +=head1 README + +filecompare.pl integrates smoothly with the LPML installation language +(linux packaging markup language). filecompare.pl is a tool that can +be used for safe CVS source-to-target installations. + +The unique identifier is considered to be the file name(s) independent +of the directory path. + +=head1 PREREQUISITES + +=head1 COREQUISITES + +=head1 OSNAMES + +linux + +=head1 SCRIPT CATEGORIES +Packaging/Administrative +=cut