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

debaudit.sh + tarchk.pl



If you always wanted a way to compare what's in those .deb files with  
what's really in your filesystem (Are the permissions the same? Did the  
contents get modified?), then here's two simple scripts to do it.

I'm putting these in the public domain. Do with them whatever you want.  
(Maybe including them in dpkg might be an idea?)

The first I called debaudit.sh. You call it with a .deb file as argument.

It's extremely short:

#! /bin/sh
dpkg-deb --fsys-tarfile $1 | tarchk.pl

The second (tarchk.pl) does the actual comparing. It parses the tar file  
(see /usr/include/tar.h - btw, this should handle long file names) and  
checks everything against the file system:

#! /usr/bin/perl -w

use strict;

binmode STDIN;

my ($n, $hdr, $ck, $data, $fluff, $fluffdata, $zeroes, $fn, $f_link, $f_user,
    $f_group, $f_data);
my ($t_name, $t_mode, $t_uid, $t_gid, $t_size, $t_mtime, $t_chksum, $t_typeflag,
    $t_linkname, $t_magic, $t_version, $t_uname, $t_gname, $t_devmajor,
    $t_devminor, $t_prefix);
my ($f_dev, $f_ino, $f_mode, $f_nlink, $f_uid, $f_gid, $f_rdev, $f_size,
    $f_atime, $f_mtime, $f_ctime, $f_blksize, $f_blocks);

$hdr = $data = $fluffdata = $f_data = '';
$zeroes = 0;
while (1) {
	$n = read(STDIN, $hdr, 512);
	last if $n == 0;
	if ($n != 512) {
		print "premature eof: read $n, not 512\n";
		die;
	}
	if (0 == unpack('%32C*', $hdr)) {
		$zeroes++;
		next;
	}
	else {
		$zeroes = 0;
	}
	($t_name, $t_mode, $t_uid, $t_gid, $t_size, $t_mtime, $t_chksum,
	 $t_typeflag, $t_linkname, $t_magic, $t_version, $t_uname, $t_gname,
	 $t_devmajor, $t_devminor, $t_prefix) =
	 unpack('A100A8A8A8A12A12A8a1A100A6A2A32A32A8A155', $hdr);
	$t_mode = oct($t_mode);
	$t_uid = oct($t_uid);
	$t_gid = oct($t_gid);
	$t_size = oct($t_size);
	$t_mtime = oct($t_mtime);
	$t_chksum = oct($t_chksum);
	$t_devmajor = oct($t_devmajor);
	$t_devminor = oct($t_devminor);
	$fn = $t_name;
	$fn = $t_prefix . "/" . $t_name if $t_prefix;
	$fn = "/" . $fn;
	$ck = unpack('%32C*', substr($hdr, 0, 148) . ' 'x8 .
				substr($hdr, 148+8, 512-148-8));
	if ($ck != $t_chksum) {
		print "bad checksum\n";
		die;
	}
	$n = read(STDIN, $data, $t_size);
	if ($n != $t_size) {
		print "premature eof: read $n, not $t_size\n";
		die;
	}
	$fluff = 512 - $t_size % 512;
	$fluff = 0 if $fluff == 512;
	$n = read(STDIN, $fluffdata, $fluff);
	if ($n != $fluff) {
		print "premature eof: read $n, not $fluff\n";
		die;
	}
	($f_dev, $f_ino, $f_mode, $f_nlink, $f_uid, $f_gid, $f_rdev, $f_size,
         $f_atime, $f_mtime, $f_ctime, $f_blksize, $f_blocks) = lstat($fn);
	if (!defined $f_mode) {
		print "$fn: missing\n";
		next;
	}
	printf "$fn: mode is %o, not %o\n", $f_mode, $t_mode
		if $t_mode != $f_mode;
	$f_user = getpwuid($f_uid);
	$f_user = '?' if !defined($f_user);
	printf "$fn: uid is %d (%s), not %d (%s)\n",
		$f_uid, $f_user, $t_uid, $t_uname
		if $t_uname ne $f_user;
	$f_group = getgrgid($f_gid);
	$f_group = '?' if !defined($f_group);
	printf "$fn: gid is %d (%s), not %d (%s)\n",
		$f_gid, $f_group, $t_gid, $t_gname
		if $t_gname ne $f_group;
	if ($t_typeflag le '1') {
		if ($t_size == $f_size) {
			open(F, $fn);
			$n = read(F, $f_data, $f_size);
			close(F);
			if ($n == $f_size) {
				print "$fn: contents differ\n"
					if $data ne $f_data;
			}
			else {
				print "$fn: can't read\n" if $n != $f_size;
			}
		}
		else {
			printf "$fn: size is %d, not %d\n", $f_size, $t_size;
		}
	}
	if ($t_typeflag eq '2') {
		$f_link = readlink($fn);
		if (defined $f_link) {
			print "$fn: points to %s, not %s\n",
				$f_link, $t_linkname
				if $f_link ne $t_linkname;
		}
		else {
			print "$fn: should be a symlink to %s\n", $t_linkname;
		}
	}
	if ($t_typeflag eq '3' || $t_typeflag eq '4') {
		printf "$fn: dev=(%d,%d), not (%d,%d)\n",
			$f_rdev/256, $f_rdev%256, $t_devmajor, $t_devminor
			if $f_rdev != $t_devmajor*256 + $t_devminor;
	}
}

MfG Kai


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


Reply to: