#!/usr/bin/perl -w

#
#
# Author: Edwin Groothuis <edwin@FreeBSD.org>
#

#
# Small tool to find distinfo with missing RMD160/SHA256/SIZE statements,
# based on the assumption that if there is one of the RMD160/SHA256/SIZE
# statements, then there should be all of them (except for SIZE
# when RMD160/SHA256 is set to IGNORE).
#
# Usage: distinfochecker [-v] [-d directory]
# -v	- verbose (print)
# -d	- use directory instead of /usr/mports
#

use Getopt::Std;
use strict;
use Data::Dumper;

my $UP="/usr/mports";
my $verbose=0;

my %opts=();
getopt('d:v',\%opts);

$UP=$opts{d} if (defined $opts{d});
$verbose=1 if (defined $opts{v});

my $errors=0;
my $checked=0;

opendir(DHUP,$UP);
while (my $c=readdir(DHUP)) {

    next if ($c=~/^\./);
    next if ($c=~/^[A-Z]/);
    next if ($c=~/^distfiles/);

    opendir(DHUPC,"$UP/$c");
    while (my $p=readdir(DHUPC)) {
	next if ($p=~/^\./);
	next if ($p=~/^Makefile/);

	if (!-f "$UP/$c/$p/distinfo") {
	    print "$c/$p - No distinfo found\n" if ($verbose);
	    next;
	}
	open(FIN,"$UP/$c/$p/distinfo");
	my @lines=<FIN>;
	chomp(@lines);
	close(FIN);

	my %RMD160=();
	my %SHA256=();
	my %SIZE=();

	foreach my $line (@lines) {
	    if ($line=~/^RMD160 \((.+?)\) = (.+?)$/) {
		if (defined $RMD160{$1}) {
		    print "$c/$p - Duplicate RMD160 for $1\n";
		    $errors++;
		}
		$RMD160{$1}=$2;
	    }
	    if ($line=~/^SHA256 \((.+?)\) = (.+?)$/) {
		if (defined $SHA256{$1}) {
		    print "$c/$p - Duplicate SHA256 for $1\n";
		    $errors++;
		}
		$SHA256{$1}=$2;
	    }
	    if ($line=~/^SIZE \((.+?)\) = (.+?)$/) {
		if (defined $SIZE{$1}) {
		    print "$c/$p - Duplicate SIZE for $1\n";
		    $errors++;
		}
		$SIZE{$1}=$2;
	    }
	}

	foreach my $f (sort(keys(%RMD160))) {
	    if (!defined ($SHA256{$f})) {
		print "$c/$p - Missing SHA256 for $f\n";
		$SHA256{$f}="missing";
		$errors++;
	    }
	    if ($RMD160{$f} ne "IGNORE") {
		if (!defined ($SIZE{$f})) {
		    print "$c/$p - Missing SIZE for $f\n";
		    $SIZE{$f}="missing";
		    $errors++;
		}
	    }
	    $checked++;
	}

	foreach my $f (sort(keys(%SHA256))) {
	    if (!defined ($RMD160{$f})) {
		print "$c/$p - Missing RMD160 for $f\n";
		$RMD160{$f}="missing";
		$errors++;
	    }
	    if ($SHA256{$f} ne "IGNORE") {
		if (!defined ($SIZE{$f})) {
		    print "$c/$p - Missing SIZE for $f\n";
		    $SIZE{$f}="missing";
		    $errors++;
		}
	    }
	}

	foreach my $f (sort(keys(%SIZE))) {
	    if (!defined ($RMD160{$f})) {
		print "$c/$p - Missing RMD160 for $f\n";
		$RMD160{$f}="missing";
		$errors++;
	    }
	    if (!defined ($SHA256{$f})) {
		print "$c/$p - Missing SHA256 for $f\n";
		$SHA256{$f}="missing";
		$errors++;
	    }
	}


    }
    closedir(DHUPC);
}
closedir(DHUP);

print "Errors: $errors\nChecked: $checked\n";
