#!/usr/bin/perl

$dbfile=shift;

$|=1;

if(length($dbfile)==0) {
  print STDERR "Usage: md5sumcache.pl <dbfile>\n";
  exit(1);
}

$total=0;
if(open(F,$dbfile)) {
  while(<F>) {
    chop;
    ($size,$time,$md5,$file)=split("\t");
    $md5{$file}=join("\t",$size,$time,$md5);
    $total++;
  }
  close(F);
}

$count=0;
while($file=<STDIN>) {
  chop($file);
  if(($count % 100)==0) {
    if($total==0 || $count>$total) { $p=$count; }
    else {
      $p=sprintf("%.1f%%",$count*100/$total);
    }
    if(length($file)>50) {
      $filecut=substr($file,0,50)."[]...";
    }
    else {
      $filecut=$file . "..." . (" " x (52-length($file)));
    }
    print STDERR "[$p] $filecut\r";
  }
  @s=stat($file);
  undef($md5);
  if(defined($cache=$md5{$file})) {
    ($size,$time,$md5)=split("\t",$cache);
    if($size!=$s[7] || $time!=$s[9]) {
      #print STDERR "SIZE ($size $s[7]) or TIME ($time $s[9]) not match $file\n";
      undef($md5);
    }
  }
  $size=$s[7];
  $time=$s[9];
  $md5[$count]=join("\t",$size,$time,$md5);
  $file[$count]=$file;
  $file{$file}=$count;
  if(length($md5)==0) {
    push(@tomd5,$file);
  }
  $count++;
}
$tomd5=$#tomd5+1;
$total=$tomd5;

print STDERR "Found ".($tomd5)." files which need md5 to be computed...                 \n";

if($tomd5>0) {
  $TMP=$ENV{TMP};
  if(length($TMP)==0) { $TMP="/tmp"; }
  $tmp="$TMP/md5.$$";

  open(M,">$tmp");
  foreach(@tomd5) { print M "$_\n"; }
  close(M);

  $count=0;
  open(M,"cat $tmp|xargs md5sum|");
  while(<M>) {
    chop;
    ($md5,$file)=m/(\S+)\s+(.*)/;
    if(($count % 100)==0 || 1) {
      if($total==0 || $count>$total) { $p=$count; }
      else {
	$p=sprintf("%.1f%%",$count*100/$total);
      }
      if(length($file)>50) {
	$filecut=substr($file,0,50)."[]...";
      }
      else {
	$filecut=$file . "..." . (" " x (52-length($file)));
      }
      print STDERR "[$p] $filecut\r";
    }
    if(!defined($i=$file{$file})) {
      print STDERR "** ERROR: $file not found in hash (should not happen)\n";
    }
    else {
      ($size,$time)=split("\t",$md5[$i]);
      $md5[$i]=join("\t",$size,$time,$md5);
    }
    $count++;
  }
  close(M);
  unlink("$tmp");
}

open(F,">$dbfile");
print F "SIZE     \tTIME      \tMD5                             \t--FILENAME--\n";
for($i=0;$i<=$#md5;$i++) {
  ($size,$time,$md5)=split("\t",$md5[$i]);
  print F "".$size.(" " x (9-length($size)))."\t$time\t$md5\t$file[$i]\n";
  print "$md5  $file[$i]\n";
}
close(F);
print STDERR "$i md5[s] written.".(" "x50)."\n";
