#!/usr/bin/perl -w

use strict;

MAIN: {
	local *PKGDB;
	local *CONTENTS;
	my %filenames;		# filename => package name
	my $name;		# Name of active package
	my $entry;		# Directory entry

	chdir("/var/db/pkg") or
		die "Unable to chdir to /var/db/pkg\n";
	opendir(PKGDB, "/var/db/pkg") or
		die "Unable to read /var/db/pkg\n";
	while ($entry = readdir(PKGDB)) {
		my $cwd;		# cwd inside a particular contents
					# file
		next if $entry eq "." || $entry eq "..";
		unless (-d $entry) {
			print STDERR "Skipping: Non-directory \"$entry\"\n";
			next;
		}
		unless (-f "$entry/+CONTENTS") {
			print STDERR "Skipping: No contents for \"$entry\"\n";
			next;
		}
		unless (open(CONTENTS, "<$entry/+CONTENTS")) {
			print STDERR "Skipping: Unable to open contents for \"$entry\"\n";
			next;
		}
		#
		# Parse a +CONTENTS file
		#
		$cwd = undef;
		$name = $entry;		# Initial name is name of directory
		while (<CONTENTS>) {
			if (/^\@cwd\s+(.*)/) {
				# Parse current directory specs
				$cwd = $1;
				$cwd .= "/" unless $cwd =~ m|/$|;
			} elsif (/^\@name\s+(.*)/) {
				# Replace name if specified inside +CONTENTS
				# and different
				if ($name ne $1) {
					$name = $1;
					print STDERR "Name: $entry -> $name\n";
				}
			} elsif (/^\@/) {
				# Skip all other metadata
				next;
			} else {
				# Handle filenames
				chomp;
				my $filename;
				$filename = $cwd . $_;
				if (exists($filenames{$filename})) {
					print STDERR "Conflict:\n" .
				"\t$filename -> $filenames{$filename}\n" .
				"\t$filename -> $name\n";
				} else {
					$filenames{$filename} = $name;
				}
			}
		}
	}

	my $directory;				# Directory to verify
	my @DIRS = @ARGV;
	while ($directory = shift @DIRS) {
		local *FIND;
		open(FIND, "find $directory -type f -o -type l|") or
			die "Unable to start find process for \"$directory\"\n";
		while (<FIND>) {
			chomp;
			if (exists $filenames{$_}) {
				delete $filenames{$_};
				next;
			}
			if (-f $_) {
				printf("%-65s (extra file)\n", $_);
			} else {
				printf("%-65s (extra link)\n", $_);
			}
		}
	}
	@DIRS = @ARGV;
	while ($directory = shift @DIRS) {
		my $key;
		foreach $key (sort grep {/^$directory/} keys %filenames) {
			printf("%-65s (missing)\n", $key);
		}
	}
}
