~vcs-imports/debconf/svn

« back to all changes in this revision

Viewing changes to src/debconf/dpkg-preconfigure

  • Committer: joeyh
  • Date: 2011-02-02 00:33:44 UTC
  • Revision ID: svn-v4:a4a2c43b-8ac3-0310-8836-e0e880c912e2:trunk:2516
moved to git

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/perl -w
2
 
 
3
 
=head1 NAME
4
 
 
5
 
dpkg-preconfigure - let packages ask questions prior to their installation
6
 
 
7
 
=head1 SYNOPSIS
8
 
 
9
 
 dpkg-preconfigure [options] package.deb
10
 
 
11
 
 dpkg-preconfigure --apt
12
 
 
13
 
=head1 DESCRIPTION
14
 
 
15
 
B<dpkg-preconfigure> lets packages ask questions before they are installed.
16
 
It operates on a set of debian packages, and all packages that use debconf
17
 
will have their config script run so they can examine the system and ask
18
 
questions.
19
 
 
20
 
=head1 OPTIONS
21
 
 
22
 
=over 4
23
 
 
24
 
=item B<-f>I<type>, B<--frontend=>I<type>
25
 
 
26
 
Select the frontend to use.
27
 
 
28
 
=item B<-p>I<value>, B<--priority=>I<value>
29
 
 
30
 
Set the lowest priority of questions you are interested in. Any questions
31
 
with a priority below the selected priority will be ignored and their
32
 
default answers will be used.
33
 
 
34
 
=item B<--terse>
35
 
 
36
 
Enables terse output mode. This affects only some frontends.
37
 
 
38
 
=item B<--apt>
39
 
 
40
 
Run in apt mode. It will expect to read a set of package filenames from
41
 
stdin, rather than getting them as parameters. Typically this is used to
42
 
make apt run dpkg-preconfigure on all packages before they are installed.
43
 
To do this, add something like this to /etc/apt/apt.conf:
44
 
 
45
 
 // Pre-configure all packages before
46
 
 // they are installed.
47
 
 DPkg::Pre-Install-Pkgs {
48
 
        "dpkg-preconfigure --apt --priority=low";
49
 
 };
50
 
 
51
 
=item B<-h>, B<--help>
52
 
 
53
 
Display usage help.
54
 
 
55
 
=back
56
 
 
57
 
=cut
58
 
 
59
 
=head1 SEE ALSO
60
 
 
61
 
L<debconf(7)>
62
 
 
63
 
=cut
64
 
 
65
 
# This program may be running from apt. If so, if it fails, apt is going to
66
 
# fail as well, which will make it hard for people to fix whatever the failure
67
 
# was. One thing someone encountered was perl failing to install. Apt then
68
 
# was re-run with perl unpacked and not configured, and modules weren't
69
 
# able to be loaded. As a sanity check, detect that case. If found, exit with
70
 
# an error message, but a return code of 0 so apt continues.
71
 
BEGIN {
72
 
        eval qq{
73
 
                use strict;
74
 
                use FileHandle;
75
 
                use Debconf::Log qw(:all);
76
 
                use Debconf::Db;
77
 
                use Debconf::Template;
78
 
                use Debconf::Config;
79
 
                use Debconf::AutoSelect qw(:all);
80
 
                use Debconf::Gettext;
81
 
        };
82
 
        if ($@) {
83
 
                # Don't use gettext() on this because it may have failed to
84
 
                # load!
85
 
                print STDERR "debconf: Perl may be unconfigured ($@) -- aborting\n";
86
 
                exit 0;
87
 
        }
88
 
}
89
 
 
90
 
Debconf::Db->load;
91
 
 
92
 
my $apt=0;
93
 
Debconf::Config->getopt(
94
 
qq{Usage: dpkg-preconfigure [options] [debs]
95
 
       --apt                    Apt mode.},
96
 
        "apt"                   => \$apt,
97
 
);
98
 
 
99
 
# In apt mode, need unbuffered output. Let's just enable it.
100
 
$|=1;
101
 
 
102
 
my @debs=@ARGV;
103
 
@ARGV=();
104
 
 
105
 
my $have_tty=1;
106
 
 
107
 
# If running from apt, read package filenames on stdin.
108
 
if ($apt) {
109
 
        while (<>) {
110
 
                chomp;
111
 
                push @debs, $_ if length $_;
112
 
        }
113
 
        
114
 
        exit unless @debs;
115
 
        
116
 
        # We have now reached the end of the first file on stdin.
117
 
        # Future reads from stdin should get input from the user, so re-open.
118
 
        $have_tty=0 unless open (STDIN, "/dev/tty");
119
 
}
120
 
elsif (! @debs) {
121
 
        print STDERR sprintf("dpkg-preconfigure: ".gettext("must specify some debs to preconfigure")), "\n";
122
 
        exit(1);
123
 
}
124
 
 
125
 
if (! -x "/usr/bin/apt-extracttemplates") {
126
 
        warn gettext("delaying package configuration, since apt-utils is not installed");
127
 
        exit;
128
 
}
129
 
 
130
 
my $frontend=make_frontend();
131
 
 
132
 
if (! $have_tty && $frontend->need_tty) {
133
 
        print STDERR sprintf("dpkg-preconfigure: ".gettext("unable to re-open stdin: %s"), $!)."\n";
134
 
        exit 0;
135
 
}
136
 
 
137
 
# Use the external package scanner for speed. It takes a list of debs
138
 
# and outputs to stdout a table with these fields separated by spaces:
139
 
my ($package, $version, $template, $config);
140
 
# Note that it also handles making sure the current version of debconf can
141
 
# deal with the package, because apt-extracttemplates skips over any
142
 
# package that depends on a version of debconf newer than what is
143
 
# installed.
144
 
unless (open(INFO, "-|")) {
145
 
        # The kernel can accept command lines up to 20k worth of
146
 
        # characters. It has happened that the list of packages to
147
 
        # configure is more than that, which requires splitting it up into
148
 
        # multiple apt-extracttemplates runs.
149
 
        my $command_max=20000; # LINUX SPECIFIC!!
150
 
                # I could use POSIX::ARG_MAX, but that would be slow.
151
 
        my $static_len=length("apt-extracttemplates");
152
 
        my $len=$static_len;
153
 
        my @collect;
154
 
        if ($apt && @debs > 30) {
155
 
                STDERR->autoflush(1);
156
 
        }
157
 
        foreach my $deb (@debs) {
158
 
                $len += length($deb) + 1;
159
 
                if ($len < $command_max && @collect < 30) {
160
 
                        push @collect, $deb;
161
 
                }
162
 
                else {
163
 
                        if (system("apt-extracttemplates", @collect) != 0) {
164
 
                                print STDERR sprintf("debconf: ".gettext("apt-extracttemplates failed: %s")."\n",$!);
165
 
                        }
166
 
                        if ($apt && @debs > 30) {
167
 
                                $progress += @collect;
168
 
                                printf STDERR "\r".gettext("Extracting templates from packages: %d%%"), $progress * 100 / @debs;
169
 
                        }
170
 
                                
171
 
                        @collect=($deb);
172
 
                        $len=$static_len + length($deb) + 1;
173
 
                }
174
 
        }
175
 
        if (system("apt-extracttemplates", @collect) != 0) {
176
 
                print STDERR sprintf("debconf: ".gettext("apt-extracttemplates failed: %s")."\n",$!);
177
 
        }
178
 
        if ($apt && @debs > 30) {
179
 
                $progress += @collect;
180
 
                printf STDERR "\r".gettext("Extracting templates from packages: %d%%")."\n", $progress * 100 / @debs;
181
 
        }
182
 
        exit;
183
 
}
184
 
# Why buffer here? Well, suppose 300 packages are being installed, and
185
 
# only the first and last use debconf. The first is preconfigured. Then
186
 
# the user watches their UI lock up until it scans all the way to the last..
187
 
# Blowing a bit of memory on a buffer seems like a saner approach.
188
 
my @buffer=<INFO>;
189
 
if ($apt && @buffer) {
190
 
        print gettext("Preconfiguring packages ...\n");
191
 
}
192
 
foreach my $line (@buffer) {
193
 
        ($package, $version, $template, $config)=split /\s/, $line;
194
 
        
195
 
        # Load templates if any.
196
 
        if (defined $template && length $template) {
197
 
                eval q{
198
 
                        Debconf::Template->load($template, $package)
199
 
                };
200
 
                unlink $template;
201
 
                if ($@) {
202
 
                        print STDERR "$package ".sprintf(gettext("template parse error: %s"), $@)."\n";
203
 
                        unlink $config;
204
 
                        next;
205
 
                }
206
 
        }
207
 
}
208
 
 
209
 
foreach my $line (@buffer) {
210
 
        ($package, $version, $template, $config)=split /\s/, $line;
211
 
 
212
 
        # Run config script if any.
213
 
        if (defined $config && length $config && -e $config) {
214
 
                debug user => sprintf("preconfiguring %s (%s)",$package,$version);
215
 
                chmod(0755, $config) or
216
 
                        die sprintf(gettext("debconf: can't chmod: %s"), $!);
217
 
                $frontend->default_title($package);
218
 
                $frontend->info(undef);
219
 
                my $confmodule=make_confmodule($config, 'configure', $version);
220
 
                # Make sure any questions created are owned by the correct package.
221
 
                $confmodule->owner($package);
222
 
                1 while ($confmodule->communicate);
223
 
                # I could just exit, but it's good to be robust so
224
 
                # other packages can still be configured and installed.
225
 
                if ($confmodule->exitcode > 0) {
226
 
                        print STDERR sprintf(
227
 
                                gettext("%s failed to preconfigure, with exit status %s"),
228
 
                                $package, $confmodule->exitcode)."\n";
229
 
                }
230
 
                unlink $config;
231
 
        }
232
 
}
233
 
 
234
 
$frontend->shutdown;
235
 
 
236
 
# Save state.
237
 
Debconf::Db->save;
238
 
 
239
 
=head1 AUTHOR
240
 
 
241
 
Joey Hess <joeyh@debian.org>
242
 
 
243
 
=cut
244