1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
#!/usr/bin/perl
# perl script originally by hallon@debian.org, much faster than sed & sh.
#
# modified by cas to pipe its output through frcode and then > to the
# db file.
#
# caching of .list timestamps and re-use of old locatedb data added by
# Pawel Chmielowski <prefiks@prefiks.org>, see Bug #457572
# 2009-05-30 Craig Sanders <cas@taz.net.au>
# - rewrote script to output a plain text listing rather than use frcode
#
# 2009-06-03 # Craig Sanders <cas@taz.net.au>
# - added optional support for compressing /var/lib/dlocatedb
use strict;
use warnings;
use File::Basename;
my $program = basename($0);
my $dbfile = '/var/lib/dlocate/dlocatedb';
my $stampsfile = '/var/lib/dlocate/dlocatedb.stamps';
#my $dbfile = '/tmp/dlocate';
#my $stampsfile = '/tmp/dlocate.stamps';
my $infodir = '/var/lib/dpkg/info';
my $compress = 0;
my $defaults = '/etc/default/dlocate';
if (open my $defaults_fh, '<', $defaults) {
while (<$defaults_fh>) {
chomp;
s/#.*|^\s*|\s*$//g;
next if (/^$/);
s/\s|"//g;
my ($key, $val) = split /=/;
if ($key eq 'COMPRESS_DLOCATE') {
$compress = $val;
}
}
close $defaults_fh;
}
my (%old_stamps, %stamps);
if (open my $stamps_fh, '<', $stampsfile) {
while (<$stamps_fh>) {
chomp;
my ($stamp, $file) = split /:/, $_, 2;
$old_stamps{$file} = $stamp;
}
close $stamps_fh;
}
open my $dbnew_fh, '>', "$dbfile.new"
or die "$program: couldn't open $dbfile.new for write: $!\n";
opendir my $dir_dh, $infodir
or die "$program: can't open directory $infodir: $!\n";
while (defined(my $pkg = readdir $dir_dh)) {
next unless $pkg =~ s/\.list$// and -s "$infodir/$pkg.list";
$stamps{$pkg} = (stat(_))[10]; # ctime
}
closedir $dir_dh;
my @new_pkgs;
my %processed;
chdir $infodir;
if (%old_stamps and open my $db_fh, '<', $dbfile) {
while (<$db_fh>) {
my ($pkg) = /^(\S+?):/;
if (not defined $pkg) {
# Skip diversion lines.
next;
} elsif (not exists $stamps{$pkg}) {
# skip packages which are no longer installed
} elsif (exists $old_stamps{$pkg} and
$stamps{$pkg} == $old_stamps{$pkg}) {
print { $dbnew_fh } $_;
} elsif (not exists $processed{$pkg}) {
open my $files_fh, '<', "$pkg.list"
or die "$program: can't open file $pkg.list: $!\n";
while (<$files_fh>) {
print { $dbnew_fh } "$pkg: $_";
}
close $files_fh;
}
$processed{$pkg} = 1;
}
close $db_fh;
my %tmp = %stamps;
delete $tmp{$_} for keys %processed;
@new_pkgs = keys %tmp;
} else {
@new_pkgs = keys %stamps;
}
foreach my $pkg (@new_pkgs) {
open my $files_fh, '<', "$pkg.list"
or die "$program: can't open new $pkg.list for read: $!\n";
while (<$files_fh>) {
print { $dbnew_fh } $pkg, ': ', $_;
}
close $files_fh;
}
# append diversions info to dlocatedb
my $divpipe = 'dpkg-divert --list \*';
open my $diversion_fh, "-|", $divpipe
or die "$program: can't open pipe from '$divpipe': $!\n";
while (<$diversion_fh>) {
print { $dbnew_fh } $_;
}
close $diversion_fh;
close $dbnew_fh;
# Create a backup to the database before replacing it with the new database.
# This is effectively two rename's done atomically.
if (-e $dbfile) {
unlink("$dbfile.old") if (-e "$dbfile.old");
link($dbfile, "$dbfile.old") if (-e $dbfile);
}
rename("$dbfile.new", $dbfile);
# optionally compress dlocatedb
if ($compress eq "1") {
system('gzip', '--quiet', '--force', $dbfile);
rename("$dbfile.gz", $dbfile);
}
open my $stamps_fh, '>', "$stampsfile.new"
or die "$program: can't create stamps file $stampsfile.new: $!\n";
print { $stamps_fh } "$stamps{$_}:$_\n" for keys %stamps;
close $stamps_fh;
if (-e $stampsfile) {
unlink($stampsfile);
}
rename("$stampsfile.new", $stampsfile);
|