-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathfix_db.pl
executable file
·97 lines (89 loc) · 3 KB
/
fix_db.pl
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
#!/usr/bin/perl -w
use strict;
use Debconf::Db;
use Debconf::Log q{warn};
Debconf::Db->load;
if (! @ARGV || $ARGV[0] ne 'end') {
# These actions need to be repeated until the db is consistent.
my $fix=0;
my $ok;
my $counter=0;
do {
$ok=1;
# There is no iterator method in the templates object, so I will do
# some nasty hacking to get them all. Oh well. Nothing else needs to
# iterate templates..
my %templates=();
my $ti=$Debconf::Db::templates->iterator;
while (my $t=$ti->iterate) {
$templates{$t}=Debconf::Template->get($t);
}
my %questions=();
my $qi=Debconf::Question->iterator;
while (my $q=$qi->iterate) {
# I have seen instances where a question would have no associated
# template field. Always a bug.
if (! defined $q->template) {
warn "question \"".$q->name."\" has no template field; removing it.";
$q->addowner("killme",""); # make sure it has one owner at least, so removal is triggered
foreach my $owner (split(/, /, $q->owners)) {
$q->removeowner($owner);
}
$ok=0;
$fix=1;
}
elsif (! exists $templates{$q->template->template}) {
warn "question \"".$q->name."\" uses nonexistant template ".$q->template->template."; removing it.";
foreach my $owner (split(/, /, $q->owners)) {
$q->removeowner($owner);
}
$ok=0;
$fix=1;
}
else {
$questions{$q->name}=$q;
}
}
# I had a report of a templates db that had templates that claimed to
# be owned by their matching questions -- but the questions didn't exist!
# Check for such a thing.
foreach my $t (keys %templates) {
# Object has no owners method (not otherwise needed), so I'll do
# some nasty grubbing.
my @owners=$Debconf::Db::templates->owners($t);
if (! @owners) {
warn "template \"$t\" has no owners; removing it.";
$Debconf::Db::templates->addowner($t, "killme","");
$Debconf::Db::templates->removeowner($t, "killme");
$fix=1;
}
foreach my $q (@owners) {
if (! exists $questions{$q}) {
warn "template \"$t\" claims to be used by nonexistant question \"$q\"; removing that.";
$Debconf::Db::templates->removeowner($t, $q);
$ok=0;
$fix=1;
}
}
}
$counter++;
} until ($ok || $counter > 20);
# If some fixes were done, save them and then fork a new process
# to do the final fixes. Seems to be necessary to do this is the db was
# really screwed up.
if ($fix) {
Debconf::Db->save;
exec($0, "end");
die "exec of self failed";
}
}
# A bug in debconf between 0.5.x and 0.9.79 caused some shared templates
# owners to not be registered. The fix is nasty; we have to load up all
# templates belonging to all installed packages all over again.
# This also means that if any of the stuff above resulted in a necessary
# question and template being deleted, it will be reinstated now.
foreach my $templatefile (glob("/var/lib/dpkg/info/*.templates")) {
my ($package) = $templatefile =~ m:/var/lib/dpkg/info/(.*?).templates:;
Debconf::Template->load($templatefile, $package);
}
Debconf::Db->save;