#!/usr/bin/perl -w use lib "/home/username/lib/perl"; use strict; use LWP::Simple; use Env; use Compress::Zlib; ## daudit GPL 2009-01-19 by Brett Hamilton http://simple.be/ ## thanks to Michael Leuchtenburg for his help my($distfile, $boxfile, $line, $wholefile, $version, $name, $number, $desc, $i, $arch, $status, $installed, %pkgstat, %distro, %box, $distURL, $distFILE, @dist, $distGZ, $stat, $package_name, $whichdist, $other); $|=1; #unbuffered IO $version = "1.2"; $whichdist = $ARGV[0]; $arch = $ARGV[1]; if (not (defined $whichdist)) { # print "No distribution specified. Defaulting to \"stable\"\n"; $whichdist = "stable"; } if (not ($whichdist =~ m/^stable$|^testing$|^unstable$/)) { print "Invalid distribution specified. Defaulting to \"stable\"\n"; $whichdist = "stable"; } if (not (defined $arch)) { # print "Architecture \"i386\"\n"; $arch = "i386"; } if (not ($arch =~ m/^alpha$|^amd64$|^arm$|^hppa$|^i386$|^ia64$|^mips$|^mipsel$|^powerpc$|^s390$|^sparc/)) { print "Invalid architecture specified. Defaulting to \"i386\"\n"; $arch = "i386"; } print "daudit $version auditing $arch installed packages versus $whichdist packages\n"; $distURL = "http://packages.debian.org/$whichdist/allpackages.en.txt.gz"; print "Fetching $distURL"; $distGZ = get $distURL; print ".\n"; print "uncompressing distribution text list"; $distFILE = Compress::Zlib::memGunzip($distGZ) ; print ".\n"; print "comparing packages.\n"; @dist = split /\n/, $distFILE; ########################## get distro ################################## foreach $line (@dist) { if ($line =~ m/^(\S+)\s\(([^)]+)\)\s([\S\s]+)$/) { # parse the entire line "name (version) desc" $name = $1; $number = $2; # $version = ''; $version = ExtractVersion ($number, $arch); $version =~ s/ //g; # eliminate white space from version $version =~ s/^\d://g; # trim off funky characger (what is it?) # $desc = $3; $distro{$name} = $version; } } ########################## get current installation ########################### $ENV{'COLUMNS'} .= '200'; open(THATFILE, "dpkg -l \"*\" |") || die "can't open pipe: $!";; while ($line = ) { next if ($line =~ m/^[+D|]/); $line =~ m/^(..)\s\s(\S*)\s*(\S*)\s/; $status = $1; $name = $2; $number = $3; $number =~ s/[\(\)]//g; $number =~ s/^.*://; # remove epoch number $pkgstat{$name}=$status; # make a hash of package installed status if ( $status =~ m/i./) { # if it's installed, put it in the box hash $box{$name} = $number; } # $line = "$name $number"; # print "$name $number\n"; # push @box, $line; } close(THATFILE); ########################## compare the two arrays ######################## my (@mismatches, @nomatches); print "\npackage_name installed $whichdist"; foreach $package_name (sort (keys(%box))) { if (defined ($distro{$package_name})) { if ($box{$package_name} eq $distro{$package_name}) { # print "$box{$package_name} OKAY\n"; } else { push @mismatches, "$package_name $box{$package_name} $distro{$package_name}"; } } else { push @nomatches, "$package_name $box{$package_name}"; } } print "\n--------- MisMatches -------------------\n\n"; foreach $line (@mismatches) { print "$line\n"; } print "\n--------- NoMatches --------------------\n\n"; foreach $line (@nomatches) { print "$line\n"; } print "\n--------- other packages status ---------\n\n"; foreach $package_name (sort (keys(%pkgstat))) { if (not ( ($pkgstat{$package_name} eq "ii") || ($pkgstat{$package_name} eq "un"))) { print "$package_name $pkgstat{$package_name}\n"; } } print "\n------------------------------------------\n\n"; ########################## sub extract version number from version string ############# sub ExtractVersion { my ($vstring, $arch) = @_; my (@versions, @archs, $different, @pair, $cpfoo, $extracted); if ($vstring =~ m/\],/) { # multiple arch/versions $vstring =~ s/\]$//; # remove "]" from the end of the version string @versions = split /\],/, $vstring; # split each different version foreach $different (@versions) { #print "NOTE: $different\n"; @pair = split /\[/, $different; # split pair into "version number" and "arch-names" @archs = split /,/, $pair[1]; # split arch-names into an array # return ($pair[0]); foreach $cpfoo (@archs) { # print "$pair[0]"; # print the version number # print "CPU $cpfoo\n"; $cpfoo =~ s/ //; # remove whitespace from cpfoo if ($cpfoo eq $arch) { # find the current ARCH of this box in the array # return ("123"); $extracted = $pair[0]; # grab the version number that we are in chomp $extracted; $extracted =~ s/ $//; # remove trailing whitespace from $extracted # return ("000"); return ($extracted); # return the version number of the matching arch # return ($vstring); } } } } else { return ($vstring); } }