On Thursday 27 November 2003, at 13 h 25, the keyboard of Stan Pinte 
<[EMAIL PROTECTED]> wrote:

> savez-vous comment on peut d�tecter tous les fichiers qui ne sont pas 
> g�r�s par des packets debian sur son syst�me?

Lire status pour trouver la liste des paquetages, faire un "dpkg -L" pour la 
liste des fichiers, un find pour avoir *tous* les fichiers et comparer les deux 
listes ?

Je joins le source de mon programme gorets qui fait presque cela (il fait les 
deux premi�re �tapes, pour trouver quels paquetages prennent le plus de place).

"Resistance is futile. You will be packaged."

#!/usr/bin/perl

# $Id: gorets,v 1.5 2000/11/20 20:51:13 bortz Exp $

use Getopt::Long;

$VERSION = 1.2;
$statusfile = '/var/lib/dpkg/status';
$max = 15;
$verbose = 0;
$debug = 0;
$filter = "";

%optctl = ("maximum" => \$max, 
           "verbose" => \$verbose, "debug" => \$debug,
           "filter" => \$filter);
GetOptions(\%optctl, "maximum=i", "verbose!", "debug:i", "filter=s") or 
    die "$0 syntax error";

if ($verbose) {
  print "$0: (gorets), version $VERSION, CVS ", '$Revision: 1.5 $', "\n";
}

$filesystem = shift (@ARGV);

if (! $filesystem) {
    die "Usage: $0 filesystem";
}

($ref_dev,$ref_ino,$ref_mode,$ref_nlink,$ref_uid,$ref_gid,
 $ref_rdev,$ref_size,
 $ref_atime,$ref_mtime,$ref_ctime,
 $ref_blksize,$ref_blocks) = stat($filesystem);

if (! $ref_dev) {
    die "$0: unknown (or unreadable) filesystem $filesystem";
}

if (-e $statusfile) {
        open (PKG_SOURCE, "< $statusfile") or
            die "Cannot open $statusfile - $!\n";
        $/ = "";  # Snarf a paragraph at a time
      PACKAGE:
        while (<PKG_SOURCE>) {
            $clump = $_;
            (@pkglines) = split(/\n/, $clump);
            if($#pkglines > 3) {
                foreach(@pkglines) {
                    $index++;
                    if(/^Package:/) {
                        ($label, $pkg) =  split(/:\s+/,$_,2);
                        if ($filter and ($pkg !~ /$filter/o)) {
                            next PACKAGE;
                        }
                        #if ($pkg_count >= 20) {
                        #    last PACKAGE;
                        #}
                        $pkg_count++;
                    }
                    if (/^Status:/) {
                        ($label,  $pkgstatus) = split(/:\s+/,$_,2);
                        $pkg_status{$pkg} = $pkgstatus;
                        ($plan, $state, $status) = split(/\s+/,$pkgstatus);
                        if ($status eq "installed") {
                            $packages{$pkg} = 1;
                        }
                        next PACKAGE;
                    }
                }
            }
        }
    }
else {
    die "No status file $statusfile??? Is it a Debian machine?";
}

$/ = "\n";
foreach $pkg (keys (%packages)) {
    $pkg_size = 0;
    open (DPKG, "dpkg --listfiles $pkg |") or
        die "Cannot run dpkg: $!";
    while (<DPKG>) {
        $clump = $_;
        chomp $clump;
        $file = $clump;
        if ($file eq '/.') {
            next;
        }
        if (! $file) {
            next;
        }
        if (-l $file) {
            next;
        }
        if (! -f $file) {
            next;
        }
        ($file_dev,$file_ino,$file_mode,$file_nlink,
         $file_uid,$file_gid,$file_rdev,$file_size,
         $file_atime,$file_mtime,$file_ctime,
         $file_blksize,$file_blocks) = stat ($file);
        if (! $file_dev) {
            print STDERR "$0: cannot find $file (of $pkg)\n";
        }
        if ($file_dev == $ref_dev) {
            if ($debug >= 3) {
                print "$file (of $pkg) is on the filesystem (size 
$file_size)\n";
            }
            $pkg_size += $file_size;
            $total_size += $file_size;
        }
    }
    close (DPKG);
    $packages {$pkg} = $pkg_size;
}

if ($verbose) {
    print "Total packages: $pkg_count\n";
    print "Total size on $filesystem: ", int($total_size/1024), " kilobytes\n";
}

$pkg_count = 0;
foreach $pkg (reverse sort by_size keys (%packages)) {
    print $pkg, ": ", int ($packages{$pkg}/1024), " kilobytes\n";
    $pkg_count++;
    if ($pkg_count > $max) {
        last;
    }
}

sub by_size {
    $packages{$a} <=> $packages{$b};
}

__END__

=head1 NAME

gorets - utility to find the Debian packages who eat disk space

=head1 SYNOPSIS

B<gorets> [I<options>] filesystem

=head1 DESCRIPTION

B<gorets> (BTW, it means something like "greedy pigs" in French) is
here to help the system administrator of a Debian machine to find
B<which> packages are eating disk space on a B<given filesystem>.

B<gorets> finds, for each installed package (you can restrict the list
of packages with the I<--filter> option), which files belongs to the
filesystem you indicated and B<gorets> add their sizes. It
produces a report with (if you use the I<--verbose> option)
the total number of packages, the total size occupied and the list,
ordered by reverse use of disk space, of packages.

=head1 OPTIONS

=over 12

=item B<-v> B<--verbose> 

Add some details to the final listing.

=item B<-m> B<--maximum> I<number>

Limit the list of packages in the final report to the number given 
(default is 15).

=item B<-f> B<--filter> I<regular expression>

Restrict the examination of files to packages which match
the regular expression (in Perl syntax).

=item B<-d> B<--debug> I<level>

Add details (the higher the level, the more details you get) about
    what it does. Useful only for the developer.

=back

=head1 BUGS

Files with hard links are counted several times. I hope hard links are
uncommon in Debian packages.

The (small) size of directories and symbolic links is not counted at all.

=head1 AUTHOR/COPYRIGHT

Copyright 2000 Stephane Bortzmeyer <[EMAIL PROTECTED]>
Free software; see the GNU General Public Licence version 2. 
No warranty.




Répondre à