# RPM Package Management System
# Copyright (C) 1995 Red Hat, Inc
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

# -*-perl-*-

require "dbrecord.pl";
require "dbmisc.pl";
require "misc.pl";

sub verifyspec {
    local (*spec) = @_;
    local (@filelist, @md5sum_array, $diskinfo, $info, $file);
    local ( @di, @i, $x, $a, $b, $name, $isbad );

    local ( @text ) = ("size", "mtime", "MD5 checksum", "file mode and/or permissions", "user id", "group id", "isconf", "isdoc", "device number", "symbolic link");
		       
    $name = $spec{name};
    if ($spec{subname}) {
	$name .= "-" . $spec{subname};
    }
    $name .= "-" . $spec{version} . "-" . $spec{release};
    &verbose("verifying $name...");

    foreach (0 .. ($spec{"subpackage:0:fileC"} - 1)) {
	$filelist[$_] = $spec{"subpackage:0:file:$_:path"};
	&debug("verifysub: $_ == $filelist[$_]");
    }

    &md5sum_array(*filelist, *md5sum_array, 0);

    foreach (0 .. ($spec{"subpackage:0:fileC"} - 1)) {
	$isbad = 0;
	$file = $filelist[$_];
	$diskinfo = &stat_info_array($file, 0, 0, *md5sum_array);
	if ($diskinfo eq "missing") {
	    print "$file ($name) is missing\n";
	    next;
	}
	$info = $spec{"subpackage:0:file:$_:info"};
	@di = split(/[ \t\n]+/, $diskinfo);
	@i = split(/[ \t\n]+/, $info);
	foreach $x (0,2..5,8,9) {
	    next if (&is_directory($info) && ($x == 0));
	    $a = $di[$x];
	    $b = $i[$x];
	    if ($a ne $b) {
		if (&isverbose) {
		    print "$file ($name) $text[$x] has changed\n";
		    print "$file ($name) $a != $b\n";
		} else {
		    $isbad = 1;
		}
	    }
	}
	if ($isbad) {
	    print "$file ($name) is bad\n";
	}
    }    
}

sub verifydbpackages {
    local (@packages) = @_;
    local ($package, $str, %spec);

    &debug("verify packages in list @packages\n");

    if (!@packages) {
	warning("no matches");
	return 1;
    }

    foreach $package (@packages) {
	if ($package eq "--version--") { next }
	$str = $Packages{$package};
	if (!defined $str) {
	    &error("RPM database corrupt -- use --rebuild to rebuilt it");
	}

	%spec = &strtorec($str, "all");

	&verifyspec($spec);
    }
}

sub verifyrpmpackages {
    local (@list) = @_;
    local ($file, %header, %spec, %pspec);

    require "build.pl";
    require "spec.pl";
    require "header.pl";

    foreach $file (@list) {
	&debug("reading spec file from $file");

	&readheader("", $file, *header, *spec, *pspec);

	&verifyspec(*spec);
    }
}

sub doverify {
    local($what, @args) = @_;

    &opendatabase("ro");

    &debug("Doing $what verify (@args)");

    $what =~ /^all$/ && &verifydbpackages(sort(keys(%Packages)));
    $what =~ /^whence$/ && &verifydbpackages(whence(@args));
    $what =~ /^Whence$/ && &verifydbpackages(whence(&stdinlist()));
    $what =~ /^package$/ && &verifyrpmpackages(@args);
    $what =~ /^Package$/ && &verifyrpmpackages(&stdinlist());
    $what =~ /^$/ && &verifydbpackages(&getmultmatches(@args));

    &closedatabase();
}

1;
