PERL   58

diff backup

Guest on 22nd September 2022 12:37:15 AM

  1. #!/usr/bin/perl
  2. #H# Diffs 2 rsync backup trees to show what files have changed.
  3. #H# Usage:
  4. #H# diff_backup.pl <dir1> <dir2>
  5. #H#
  6. #H# The output is sort of patterned after RedHat's rpm -y command which I feel has
  7. #H# the perfect format for what it does and I was so happy to see that the Gentoo
  8. #H# people copied it in the epm command.
  9. #H# Output Legend:
  10. #H# + File is new (no further checking is done)
  11. #H# - File is no longer present (no further checking is done)
  12. #H# I Inode number has changed
  13. #H# P File permissions have changed
  14. #H# O File UID has changed
  15. #H# G File GID has changed
  16. #H# S File size has changed
  17. #H# M File mtime has changed
  18. #H# 5 File md5sum has changed (assumed if Size is different)
  19.  
  20. $Me=$0;
  21. if ($ARGV[0] eq "-h" || $ARGV[0] eq "--help") {
  22.   open (SELF, $Me);
  23.   while (<SELF>) {
  24.     if ($_ =~ /^#H# /) {
  25.       $Line=$_;
  26.       $Line =~ s/^#H# //;
  27.       print $Line;
  28.     }
  29.   }
  30.   exit;
  31. }
  32.  
  33. $Dir1=$ARGV[0];
  34. $Dir2=$ARGV[1];
  35. $Dir1 =~ s/\/$//;
  36. $Dir2 =~ s/\/$//;
  37. @Files1=();
  38. @Files2=();
  39. @Stat=();
  40. %Inode1=();
  41. %Inode2=();
  42. %Mode1=();
  43. %Mode2=();
  44. %UID1=();
  45. %GID2=();
  46. %Size1=();
  47. %Size2=();
  48. %Mtime1=();
  49. %Mtime2=();
  50. %Diffs=();
  51.  
  52.  
  53. print "Building file list for $Dir1...\n";
  54. open (FINDDATA, "find $Dir1 -type f -print |");
  55. @Files1=<FINDDATA>;
  56. close (FINDDATA);
  57. chomp @Files1;
  58.  
  59. print "Building file list for $Dir2...\n";
  60. open (FINDDATA, "find $Dir2 -type f -print |");
  61. @Files2=<FINDDATA>;
  62. close (FINDDATA);
  63. chomp @Files2;
  64.  
  65. print "Getting file stats for $Dir1...\n";
  66. foreach $FileName (@Files1) {
  67.   @Stat=(stat("$FileName"));
  68.   $FileName =~ s/^$Dir1\///;
  69.   $Inode1{$FileName}=$Stat[1];
  70.   $Mode1{$FileName}=$Stat[2];
  71.   $UID1{$FileName}=$Stat[4];
  72.   $GID1{$FileName}=$Stat[5];
  73.   $Size1{$FileName}=$Stat[7];
  74.   $Mtime1{$FileName}=$Stat[9];
  75. }
  76. print "Getting file stats for $Dir2...\n";
  77. foreach $FileName (@Files2) {
  78.   @Stat=(stat("$FileName"));
  79.   $FileName =~ s/^$Dir2\///;
  80.   $Inode2{$FileName}=$Stat[1];
  81.   $Mode2{$FileName}=$Stat[2];
  82.   $UID2{$FileName}=$Stat[4];
  83.   $GID2{$FileName}=$Stat[5];
  84.   $Size2{$FileName}=$Stat[7];
  85.   $Mtime2{$FileName}=$Stat[9];
  86. }
  87.  
  88. print "Finding files that have dissapeared...\n";
  89. foreach $FileName (sort(keys(%Inode1))) {
  90.   if ($Inode2{$FileName} == undef) {
  91.     $Diffs{$FileName}="-";
  92.   }
  93. }
  94.  
  95. print "Finding files that have been added...\n";
  96. foreach $FileName (sort(keys(%Inode2))) {
  97.   if ($Inode1{$FileName} == undef) {
  98.     $Diffs{$FileName}="+";
  99.   }
  100. }
  101.  
  102. print "Finding files with changes...\n";
  103. foreach $FileName (sort(keys(%Inode1))) {
  104.   if ($Diffs{$FileName} ne "+") {
  105.     if ($Diffs{$FileName} ne "-") {
  106.       if ($Inode1{$FileName} != $Inode2{$FileName}) { $Diffs{$FileName}="$Diffs{$FileName}" . "I"; }
  107.       if ($Mode1{$FileName} != $Mode2{$FileName}) { $Diffs{$FileName}="$Diffs{$FileName}" . "P"; }
  108.       if ($UID1{$FileName} != $UID2{$FileName}) { $Diffs{$FileName}="$Diffs{$FileName}" . "O"; }
  109.       if ($GID1{$FileName} != $GID2{$FileName}) { $Diffs{$FileName}="$Diffs{$FileName}" . "G"; }
  110.       if ($Size1{$FileName} != $Size2{$FileName}) { $Diffs{$FileName}="$Diffs{$FileName}" . "S"; }
  111.       if ($Mtime1{$FileName} != $Mtime2{$FileName}) { $Diffs{$FileName}="$Diffs{$FileName}" . "M"; }
  112.     }
  113.   }
  114. }
  115.  
  116. print "Finding files that have been modified even though they don't look like it...\n";
  117. foreach $FileName (sort(keys(%Diffs))) {
  118.   if ($Diffs{$FileName} ne "+") {
  119.     if ($Diffs{$FileName} ne "-") {
  120.       if ($Diffs{$FileName} !~ /S/) {
  121.         $SumText1=`md5sum "$Dir1/$FileName"`;
  122.         $SumText2=`md5sum "$Dir2/$FileName"`;
  123.         ($Sum1,$Junk)=split(/ /,$SumText1,2);
  124.         ($Sum2,$Junk)=split(/ /,$SumText2,2);
  125.         if ($Sum1 ne $Sum2) { $Diffs{$FileName}="$Diffs{$FileName}" . "5"; }
  126.       } else { $Diffs{$FileName}="$Diffs{$FileName}" . "5"; }
  127.     }
  128.   }
  129. }
  130.  
  131. foreach $FileName (sort (keys (%Diffs))) {
  132.   print "$Diffs{$FileName}\t$FileName\n";
  133. }

Raw Paste


Login or Register to edit or fork this paste. It's free.