[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

verify script for Debian packages



Having gotten nervous after almost losing my file system last week, I wrote a
little perl script to go through the file lists in /var/lib/dpkg/info and
check to see that the files are where they're supposed to be.  Given the
current way of doing things in the packaging system, I think this is about as
close to a real package verifier as one can get without adding a lot of
complicated new stuff.  Anyway, this script works for me, and has turned up a
number of inconsistencies in my installation, some of which appear to be bugs
in the packages involved (developers take note).  The "mark" feature, which
would have automatically marked packages for resintallation, was not
implemented partly because it's hard, and partly because it's dangerous: it
can't tell the difference between something broken and something you might
have tweaked by hand, like a custom kernel.

To use: move everything from the #!/usr/bin/perl line to the end to a file
named "dpkg-verify", in whatever directory you like--/usr/sbin is where I put
this on my system.  Run without arguments, it gives a usage message that
should be pretty self-explanatory.

My correct email address is not given in the headers for anti-spam purposes
only--I welcome mail from friendly humans who aren't trying to sell me
anything.  Unsolicited commercial messages of any sort will be dealt with
negatively and severely.  My username is gobbel, at the host named
cogsci.ucsd.edu.

-Randy Gobbel
-- 
http://cogsci.ucsd.edu/~gobbel/

#!/usr/bin/perl --
#
# $Id: dpkg-verify,v 1.4 1996-10-31 13:35:25-08 gobbel Exp $
#
# dpkg-verify: Given a list of packages, check to see if any of their files
# are missing.  If so, optionally mark the associated package as requiring
# reinstallation, and produce a report listing the missing files.  Currently
# no way to check that the files are actually correct, only that they exist.
# NOTE: the "mark" option is currently unimplemented, and may be a bad idea.

sub usage {
    print STDERR <<END;
Usage: dpkg-verify <opts> <package name> ...

Options:  -v|--verbose   Output package names as they are processed.
          -m|--mark-bad  Mark packages with files missing as requiring
                         reinstallation (unimplemented, dangerous).
          -l|--list      List missing files to stdout.
          -a|--all       Check all installed packages.
END
}

sub badusage {
    print STDERR $_[0];
    &usage;
    exit 1;
}

sub error {
    print STDERR "***ERROR: ", @_;
    exit 1;
}

sub debug {
    if ($debug_flg) {
	print $_[0];
    }
}

sub mark_bad {
    print STDERR "Mark option is not implemented.\n";
}

$verbose = 0;
$mark = 0;
$doall = 0;
$listfiles = 0;

while ($ARGV[0] =~ m/^-/) {
    $_= shift(@ARGV);
    $noptsdone++;
    if (m/^--$/) {
        $noptsdone--; last;
    } elsif (m/^--verbose$/) {
	$verbose = 1;
    } elsif (m/^--list$/) {
	$listfiles = 1;
    } elsif (m/^--mark-bad$/) {
	$mark = 1;
    } elsif (m/^--all$/) {
	$doall = 1;
    } elsif (m/^--/) {
        &badusage("Unknown option \`$_'\n");
    }else {
        s/^-//; $noptsdone--;
        while (s/^.//) {
	    if ($& eq 'v') {
		$verbose = 1;
	    } elsif ($& eq 'l') {
		$listfiles = 1;
	    } elsif ($& eq 'a') {
		$doall = 1;
	    } elsif ($& eq 'm') {
		$mark = 1;
	    } else {
		&badusage("Unknown option \`-$&'\n");
	    }
	}
    }
}

&debug("options parsed");

if ($doall) {
    open(ALLPKG, "dpkg --get-selections |");
    while (<ALLPKG>) {
	split(' ',$_);
	push(@allpkg,$_[0]);
    }
}

$packages = 0;
$somebad = 0;

foreach $package ($doall ? @allpkg : @ARGV) {
    $badpkg = 0;
    $packages++;
    # if no list file -> error, doesn't exist
    # loop through <package>.list file in /var/lib/dpkg/info
    #    for each file, if doesn't exist:
    #       if not already done, send package name to stdout (mark as done)
    #       if mark, mark package as needing reinstall
    #       if verbose, send file name to stdout
    if (! -e '/var/lib/dpkg/info/' . $package . '.list') {
	&error("Package $package not found.\n");
	next;
    }
    open(PKGLIST,'/var/lib/dpkg/info/' . $package . '.list');
    while (chop($thisone = <PKGLIST>)) {
	#print "file = $thisone\n";
	if (! -e $thisone) {
	    if (!$badpkg) {
		print "***Broken package: $package\n";
		print "Missing files:\n" if $verbose;
		$badpkg = 1;
		$somebad = 1;
	    }
	    if ($verbose || $listfiles) {
		print $thisone, "\n";
	    }
	    if ($mark) {
		&mark_bad($package);
	    }
	}
    }
   if ($verbose && !$badpkg) {
       print "Ok: $package\n";
   }
    close(PKGLIST);
}

if (!$packages) {
    &badusage("No packages specified.\n");
}

if ($somebad) {
    exit 2;
}

# $Log: dpkg-verify,v $
# Revision 1.4  1996-10-31 13:35:25-08  gobbel
# minor tweak in usage message format.
#
# Revision 1.3  1996-10-31 13:33:09-08  gobbel
# now outputs "Missing files" message and file list if verbose (list option no
# longer required in addition to verbose).
#
# Revision 1.2  1996-10-31 13:27:54-08  gobbel
# various bug fixes and tweaks.
#
# Revision 1.1  1996-10-30 22:57:45-08  gobbel
# Initial revision
#

--
TO UNSUBSCRIBE FROM THIS MAILING LIST: e-mail the word "unsubscribe" to
debian-user-REQUEST@lists.debian.org . Trouble? e-mail to Bruce@Pixar.com


Reply to: