1 |
#!/usr/bin/perl |
2 |
|
3 |
# $Id: urpmi 271299 2010-11-21 15:54:30Z peroyvind $ |
4 |
|
5 |
#- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 MandrakeSoft SA |
6 |
#- Copyright (C) 2005-2010 Mandriva SA |
7 |
#- |
8 |
#- This program is free software; you can redistribute it and/or modify |
9 |
#- it under the terms of the GNU General Public License as published by |
10 |
#- the Free Software Foundation; either version 2, or (at your option) |
11 |
#- any later version. |
12 |
#- |
13 |
#- This program is distributed in the hope that it will be useful, |
14 |
#- but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 |
#- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 |
#- GNU General Public License for more details. |
17 |
#- |
18 |
#- You should have received a copy of the GNU General Public License |
19 |
#- along with this program; if not, write to the Free Software |
20 |
#- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21 |
|
22 |
use strict; |
23 |
use urpm; |
24 |
use urpm::args; |
25 |
use urpm::msg; |
26 |
use urpm::media; |
27 |
use urpm::select; |
28 |
use urpm::util qw(untaint difference2 member partition cat_); |
29 |
use urpm::main_loop; |
30 |
|
31 |
#- default options. |
32 |
our $update = 0; |
33 |
our $media = ''; |
34 |
our $searchmedia; |
35 |
our $excludemedia = ''; |
36 |
our $sortmedia = ''; |
37 |
our $allow_medium_change = 0; |
38 |
our $auto_select = 0; |
39 |
our $auto_update = 0; |
40 |
our $no_install = 0; |
41 |
our $no_remove = 0; |
42 |
our $install_src = 0; |
43 |
our $clean = 0; |
44 |
our $noclean = 0; |
45 |
our $force = 0; |
46 |
our $parallel = ''; |
47 |
our $env = ''; |
48 |
our $test = 0; |
49 |
our $all = 0; |
50 |
our $use_provides = 1; |
51 |
our $logfile = ''; |
52 |
our $restricted = 0; |
53 |
our $nomd5sum = 0; |
54 |
our $forcekey = 0; |
55 |
our $force_dudf = 0; |
56 |
|
57 |
my @files; |
58 |
my @src_files; |
59 |
my @names; |
60 |
my @src_names; |
61 |
|
62 |
$ENV{PATH} = "/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin"; |
63 |
delete @ENV{qw(ENV BASH_ENV IFS CDPATH)}; |
64 |
$ENV{HOME} ||= "/root"; |
65 |
$ENV{USER} ||= "root"; |
66 |
|
67 |
sub dudf_invoke { |
68 |
my ($dudf, $methodname, @args) = @_; |
69 |
|
70 |
if ($dudf) { |
71 |
$dudf->$methodname(@args); |
72 |
} |
73 |
} |
74 |
|
75 |
sub usage () { |
76 |
print N("urpmi version %s |
77 |
Copyright (C) 1999-2010 Mandriva. |
78 |
This is free software and may be redistributed under the terms of the GNU GPL. |
79 |
|
80 |
usage: |
81 |
", $urpm::VERSION) . N(" --help - print this help message. |
82 |
") . N(" --media - use only the given media, separated by comma. |
83 |
") . N(" --excludemedia - do not use the given media, separated by comma. |
84 |
") . N(" --update - use only update media. |
85 |
") . N(" --searchmedia - use only the given media to search requested packages. |
86 |
") . N(" --sortmedia - sort media according to substrings separated by comma. |
87 |
") . N(" --synthesis - use the given synthesis instead of urpmi db. |
88 |
") . N(" --auto - non-interactive mode, assume default answers to questions. |
89 |
") . N(" --auto-select - automatically select packages to upgrade the system. |
90 |
") . N(" --auto-update - update media then upgrade the system. |
91 |
") . N(" --no-md5sum - disable MD5SUM file checking. |
92 |
") . N(" --force-key - force update of gpg key. |
93 |
") . N(" --auto-orphans - remove orphans without asking |
94 |
") . N(" --no-suggests - do not auto select \"suggested\" packages. |
95 |
") . N(" --no-uninstall - never ask to uninstall a package, abort the installation. |
96 |
") . N(" --no-install - don't install packages (only download) |
97 |
") . N(" --keep - keep existing packages if possible, reject requested |
98 |
packages that lead to removals. |
99 |
") . N(" --split-level - split in small transaction if more than given packages |
100 |
are going to be installed or upgraded, |
101 |
default is %d. |
102 |
", urpm::default_options()->{'split-level'}) |
103 |
. N(" --split-length - small transaction length, default is %d. |
104 |
", urpm::default_options()->{'split-length'}) |
105 |
. N(" --fuzzy, -y - impose fuzzy search. |
106 |
") . N(" --buildrequires - install the buildrequires of the packages |
107 |
") . N(" --install-src - install only source package (no binaries). |
108 |
") . N(" --clean - remove rpm from cache before anything else. |
109 |
") . N(" --noclean - don't clean rpms from cache. |
110 |
") . N(" --justdb - update only the rpm db, not the filesystem. |
111 |
") . N(" --replacepkgs - force installing packages which are already installed. |
112 |
") . N(" --force - force invocation even if some packages do not exist. |
113 |
") . N(" --allow-nodeps - allow asking user to install packages without |
114 |
dependencies checking. |
115 |
") . N(" --allow-force - allow asking user to install packages without |
116 |
dependencies checking and integrity. |
117 |
") . N(" --allow-suggests - auto select \"suggested\" packages. |
118 |
") . N(" --parallel - distributed urpmi across machines of alias. |
119 |
") . N(" --root - use another root for rpm installation. |
120 |
") . N(" --urpmi-root - use another root for urpmi db & rpm installation. |
121 |
") . N(" --use-distrib - configure urpmi on the fly from a distrib tree, useful |
122 |
to install a chroot with --root option. |
123 |
") . N(" --metalink - generate and use a local metalink. |
124 |
") . N(" --download-all - download all needed packages before trying to install them |
125 |
") . N(" --downloader - program to use to retrieve distant files. |
126 |
known programs: %s |
127 |
", join(', ', urpm::download::ftp_http_downloaders())) |
128 |
. N(" --curl-options - additional options to pass to curl |
129 |
") . N(" --rsync-options- additional options to pass to rsync |
130 |
") . N(" --wget-options - additional options to pass to wget |
131 |
") . N(" --prozilla-options - additional options to pass to prozilla |
132 |
") . N(" --aria2-options - additional options to pass to aria2 |
133 |
") . N(" --limit-rate - limit the download speed. |
134 |
") . N(" --resume - resume transfer of partially-downloaded files |
135 |
(--no-resume disables it, default is disabled). |
136 |
") . N(" --proxy - use specified HTTP proxy, the port number is assumed |
137 |
to be 1080 by default (format is <proxyhost[:port]>). |
138 |
") . N(" --proxy-user - specify user and password to use for proxy |
139 |
authentication (format is <user:password>). |
140 |
") . N(" --bug - output a bug report in directory indicated by |
141 |
next arg. |
142 |
") . N(" --env - use specific environment (typically a bug report). |
143 |
") . N(" --verify-rpm - verify rpm signature before installation |
144 |
(--no-verify-rpm disables it, default is enabled). |
145 |
") . N(" --test - only verify if the installation can be achieved correctly. |
146 |
") . N(" --excludepath - exclude path separated by comma. |
147 |
") . N(" --excludedocs - exclude doc files. |
148 |
") . N(" --ignoresize - don't verify disk space before installation. |
149 |
") . N(" --ignorearch - allow to install rpms for unmatched architectures. |
150 |
") . N(" --noscripts - do not execute package scriptlet(s) |
151 |
") . N(" --replacefiles - ignore file conflicts |
152 |
") . N(" --repackage - Re-package the files before erasing |
153 |
") . N(" --skip - packages which installation should be skipped |
154 |
") . N(" --prefer - packages which should be preferred |
155 |
") . N(" --more-choices - when several packages are found, propose more choices |
156 |
than the default. |
157 |
") . N(" --nolock - don't lock rpm db. |
158 |
") . N(" --strict-arch - upgrade only packages with the same architecture. |
159 |
") . N(" -a - select all matches on command line. |
160 |
") . N(" -p - allow search in provides to find package. |
161 |
") . N(" -P - do not search in provides to find package. |
162 |
") . N(" --quiet, -q - quiet mode. |
163 |
") . N(" --verbose, -v - verbose mode. |
164 |
") . N(" --debug - very verbose mode. |
165 |
") . "\n" . N(" names or rpm files given on command line will be installed. |
166 |
"); |
167 |
exit(1); |
168 |
} |
169 |
|
170 |
# Parse command line |
171 |
my $command_line = join " ", @ARGV; |
172 |
my @ARGVcopy; # keep a copy, in case we have to restart |
173 |
|
174 |
# Expand *.urpmi arguments |
175 |
if (member('--restricted', @ARGV)) { |
176 |
@ARGVcopy = @ARGV; |
177 |
} else { |
178 |
foreach my $a (@ARGV) { |
179 |
if ($a =~ /\.urpmi$/) { |
180 |
open my $fh, '<', $a or do { warn "Can't open $a: $!\n"; next }; |
181 |
push @ARGVcopy, map { chomp; $_ } <$fh>; |
182 |
close $fh; |
183 |
} else { |
184 |
push @ARGVcopy, $a; |
185 |
} |
186 |
} |
187 |
@ARGV = @ARGVcopy; |
188 |
} |
189 |
|
190 |
my $urpm = urpm->new_parse_cmdline or exit(1); |
191 |
my $dudf; |
192 |
|
193 |
eval { |
194 |
require urpm::dudf; |
195 |
$dudf = new urpm::dudf(\$urpm, $command_line, $force_dudf); |
196 |
}; |
197 |
|
198 |
if (@ARGV && $auto_select) { |
199 |
print STDERR N("Error: can't use --auto-select along with package list.\n"); |
200 |
exit 1; |
201 |
} |
202 |
|
203 |
# Verify that arguments were given |
204 |
unless (@ARGV || $auto_select || $clean) { |
205 |
if ($options{bug}) { |
206 |
print STDERR N("Error: To generate a bug report, specify the usual command-line arguments |
207 |
along with --bug.\n"); |
208 |
exit 1; |
209 |
} |
210 |
usage(); |
211 |
} |
212 |
|
213 |
my @spec_files; |
214 |
# Process the rest of the arguments |
215 |
foreach (@ARGV) { |
216 |
if (/\.(?:rpm|spec)$/) { |
217 |
if (/\.src\.rpm$/) { |
218 |
push @src_files, $_; |
219 |
} elsif (/\.spec$/) { |
220 |
push @spec_files, $_; |
221 |
} else { |
222 |
push @files, untaint($_); |
223 |
} |
224 |
next; |
225 |
} |
226 |
push @names, $_; |
227 |
} |
228 |
|
229 |
if ($options{buildrequires}) { |
230 |
push @src_names, @names; |
231 |
@names = (); |
232 |
} |
233 |
|
234 |
#- use install_src to promote all names as src package. |
235 |
if ($install_src) { |
236 |
@files and $urpm->{fatal}(1, N("You can't install binary rpm files when using --install-src")); |
237 |
@spec_files and $urpm->{fatal}(1, N("You can't install spec files")); |
238 |
push @src_names, @names; |
239 |
@names = (); |
240 |
#- allow to use --install-src as a non-root user |
241 |
$options{nolock} = 1; |
242 |
} elsif (@spec_files) { |
243 |
if (!$options{buildrequires}) { |
244 |
$urpm->{error}(N("defaulting to --buildrequires")); |
245 |
$options{buildrequires} = 1; |
246 |
} |
247 |
push @src_files, @spec_files; |
248 |
} elsif (@src_files && !$options{buildrequires}) { |
249 |
$urpm->{error}(N("please use --buildrequires or --install-src, defaulting to --buildrequires")); |
250 |
$options{buildrequires} = 1; |
251 |
} |
252 |
|
253 |
#- rurpmi checks |
254 |
if ($restricted) { |
255 |
urpm::error_restricted($urpm) if @files; |
256 |
#- force some options |
257 |
foreach (qw(keep verify-rpm)) { $urpm->{options}{$_} = 1 } |
258 |
#- forbid some other options |
259 |
urpm::error_restricted($urpm) if $urpm->{root} || $options{usedistrib} || $force || $env || $parallel || $options{synthesis} || $auto_update || $options{auto_orphans}; |
260 |
foreach (qw(allow-nodeps allow-force curl-options rsync-options wget-options prozilla-options noscripts)) { |
261 |
urpm::error_restricted($urpm) if $urpm->{options}{$_}; |
262 |
} |
263 |
} |
264 |
|
265 |
#- prepare bug report. |
266 |
my $bug = $options{bug}; |
267 |
if ($bug) { |
268 |
mkdir $bug or $urpm->{fatal}(8, (-d $bug |
269 |
? N("Directory [%s] already exists, please use another directory for bug report or delete it", $bug) |
270 |
: N("Unable to create directory [%s] for bug report", $bug))); |
271 |
#- copy all synthesis file used, along with configuration of urpmi |
272 |
my @list_files = grep { -e $_ } $urpm->{skiplist}, $urpm->{instlist}, |
273 |
$urpm->{prefer_list}, $urpm->{prefer_vendor_list}, '/root/.rpmdrake'; |
274 |
system("cp", "-af", @list_files, $urpm->{config}, $bug) |
275 |
and die N("Copying failed"); |
276 |
#- log everything for bug report. |
277 |
$logfile = "$bug/urpmi.log"; |
278 |
} |
279 |
|
280 |
if ($env) { |
281 |
urpm::set_env($urpm, $env); |
282 |
} else { |
283 |
if ($< != 0 && !$options{debug__do_not_install}) { |
284 |
#- need to be root if binary rpms are to be installed |
285 |
$auto_select || @names || @files and $urpm->{fatal}(1, N("Only superuser is allowed to install packages")); |
286 |
} |
287 |
} |
288 |
|
289 |
unless ($bug || $install_src || $env || $urpm->{options}{'allow-force'} || $urpm->{root}) { |
290 |
require urpm::sys; |
291 |
urpm::sys::check_fs_writable() or $urpm->{fatal}(1, N("Error: %s appears to be mounted read-only. |
292 |
Use --allow-force to force operation.", $urpm::sys::mountpoint)); |
293 |
} |
294 |
|
295 |
unless ($bug || $env || $test) { |
296 |
sys_log("called with: $command_line"); |
297 |
} |
298 |
|
299 |
my ($pid_out, $pid_err); |
300 |
if ($logfile && !$INC{"Devel/Trace.pm"}) { |
301 |
bug_log(scalar localtime(), " urpmi called with $command_line\n"); |
302 |
|
303 |
open(my $SAVEOUT, ">&STDOUT"); select $SAVEOUT; $| = 1; |
304 |
open(my $SAVEERR, ">&STDERR"); select $SAVEERR; $| = 1; |
305 |
|
306 |
#- fork twice to copy stdout and stderr to $logfile |
307 |
unless ($pid_out = open STDOUT, "|-") { |
308 |
select $SAVEOUT; $| = 1; |
309 |
$/ = \1; |
310 |
binmode STDIN, ':raw'; #- since we read character by character, perl must not try to recognise utf8 strings since it really can't |
311 |
while (my $s = <STDIN>) { |
312 |
open my $fh, ">>$logfile"; |
313 |
print $SAVEOUT $s; |
314 |
print $fh $s; |
315 |
} |
316 |
exit 0; |
317 |
} |
318 |
unless ($pid_err = open STDERR, "|-") { |
319 |
select $SAVEERR; $| = 1; |
320 |
$/ = \1; |
321 |
binmode STDIN, ':raw'; #- since we read character by character, perl must not try to recognise utf8 strings since it really can't |
322 |
while (my $s = <STDIN>) { |
323 |
open my $fh, ">>$logfile"; |
324 |
print $SAVEERR $s; |
325 |
print $fh $s; |
326 |
} |
327 |
exit 0; |
328 |
} |
329 |
|
330 |
#- log to SAVEERR instead of STDERR |
331 |
unless ($bug) { |
332 |
$urpm->{fatal} = sub { printf $SAVEERR "%s\n", $_[1]; exit($_[0]) }; |
333 |
$urpm->{error} = sub { printf $SAVEERR "%s\n", $_[0] }; |
334 |
$urpm->{log} = sub { printf $SAVEOUT "%s\n", $_[0] }; |
335 |
} |
336 |
} |
337 |
|
338 |
#- make unbuffered |
339 |
select STDERR; $| = 1; |
340 |
select STDOUT; $| = 1; |
341 |
|
342 |
if ($options{previous_priority_upgrade}) { |
343 |
# we were just restarted |
344 |
# so, no need to update the media again |
345 |
$auto_update = 0; |
346 |
# temporary hack : if we were using an old version of URPM (eg: when |
347 |
# upgrading from 2006), file handles might have leaked, so close them (with |
348 |
# some heuristics.) |
349 |
require urpm::sys; |
350 |
urpm::sys::fix_fd_leak(); |
351 |
# also, clean up rpm db log files, because rpm might have been upgraded |
352 |
urpm::sys::clean_rpmdb_shared_regions('') if !$urpm->{root}; |
353 |
} |
354 |
|
355 |
my $urpmi_lock = !$env && !$options{nolock} && urpm::lock::urpmi_db($urpm, '', wait => $options{wait_lock}); |
356 |
|
357 |
#- should we ignore arch compatibility |
358 |
if ($urpm->{options}{ignorearch}) { urpm::shunt_ignorearch() } |
359 |
|
360 |
if ($urpm->{root}) { |
361 |
$urpm->{options}{'priority-upgrade'} = '' if !$ENV{TESTING_priority_upgrade}; |
362 |
} |
363 |
if ($auto_update && !$bug && !$env) { |
364 |
$urpm->{options}{'auto-update'} = 1; |
365 |
} |
366 |
|
367 |
urpm::media::configure($urpm, |
368 |
excludemedia => $excludemedia, |
369 |
media => $media, |
370 |
parallel => $parallel, |
371 |
searchmedia => $searchmedia, |
372 |
cmdline_skiplist => $options{skip}, |
373 |
sortmedia => $sortmedia, |
374 |
synthesis => $options{synthesis}, |
375 |
update => $update, |
376 |
usedistrib => $options{usedistrib}, |
377 |
probe_with => $options{probe_with}, |
378 |
download_callback => \&urpm::download::sync_logger, |
379 |
); |
380 |
|
381 |
if ($bug) { |
382 |
require urpm::bug_report; |
383 |
urpm::bug_report::rpmdb_to_synthesis($urpm, "$bug/rpmdb.cz"); |
384 |
} |
385 |
|
386 |
urpm::select::set_priority_upgrade_option($urpm, $options{previous_priority_upgrade}); |
387 |
|
388 |
my $state = {}; |
389 |
my %requested = $urpm->register_rpms(@files, @src_files); |
390 |
|
391 |
#- finish bug environment creation. |
392 |
if ($bug) { |
393 |
urpm::bug_report::write_urpmdb($urpm, $bug); |
394 |
urpm::bug_report::copy_requested($urpm, $bug, \%requested); |
395 |
} |
396 |
|
397 |
my $rpm_lock = !$env && !$options{nolock} && urpm::lock::rpm_db($urpm, 'exclusive', wait => $options{wait_lock}); |
398 |
|
399 |
dudf_invoke($dudf, "store_userpkgs", @names); |
400 |
|
401 |
#- search the packages according to the selection given by the user. |
402 |
my $search_result = ''; |
403 |
if (@names) { |
404 |
$search_result = urpm::select::search_packages($urpm, |
405 |
\%requested, [ @names ], |
406 |
all => $all, |
407 |
use_provides => $use_provides, |
408 |
fuzzy => $urpm->{options}{fuzzy}, |
409 |
no_substring => $urpm->{options}{auto}, # do not allow substring match if we can't prompt the user |
410 |
) || $force or exit 1; |
411 |
|
412 |
if (%requested) { |
413 |
$urpm->{log}("found package(s): " . join(" ", map { scalar $urpm->{depslist}[$_]->fullname } |
414 |
map { split /\|/ } keys %requested)); |
415 |
} |
416 |
} |
417 |
if (@src_names) { |
418 |
$search_result = urpm::select::search_packages($urpm, \%requested, [ @src_names ], |
419 |
all => $all, |
420 |
use_provides => $use_provides, |
421 |
fuzzy => $urpm->{options}{fuzzy}, |
422 |
src => 1, |
423 |
) || $force or exit 1; |
424 |
} |
425 |
|
426 |
# callback called to ask user to choose between virtual packages |
427 |
# - $choices is the sorted list of choices |
428 |
# - $prefered is a subset of @$choices (it can be empty) |
429 |
sub ask_choice { |
430 |
my ($urpm, $_db, $_state, $choices, $virtual_pkg_name, $prefered) = @_; |
431 |
|
432 |
my @choices; |
433 |
if ($prefered && @$prefered) { |
434 |
@choices = @$choices; |
435 |
} else { |
436 |
($prefered, my $other) = urpm::select::get_preferred($urpm, $choices, $options{prefer}); |
437 |
@choices = (@$prefered, @$other); |
438 |
} |
439 |
my $prefer = @$prefered && join(',', grep { member($choices[$_-1], @$prefered) } 1 .. @choices); |
440 |
|
441 |
my (@l) = map { |
442 |
my ($name, $summary) = (scalar($_->fullname), translate($_->summary)); |
443 |
$_->flag_installed ? |
444 |
($_->summary ? |
445 |
#-PO: here format is "<package_name>: <summary> (to upgrade)" |
446 |
N("%s: %s (to upgrade)", $name, $summary) : |
447 |
#-PO: here format is "<package_name> (to upgrade)" |
448 |
N("%s (to upgrade)", $name)) : |
449 |
|
450 |
$_->flag_upgrade ? ($_->summary ? |
451 |
#-PO: here format is "<package_name>: <summary> (to install)" |
452 |
N("%s: %s (to install)", $name, $summary) : |
453 |
#-PO: here format is "<package_name> (to install)" |
454 |
N("%s (to install)", $name)) : $name; |
455 |
} @choices; |
456 |
|
457 |
my $n = 1; #- default value. |
458 |
|
459 |
if (@l > 1 && !$urpm->{options}{auto}) { |
460 |
print N("In order to satisfy the '%s' dependency, one of the following packages is needed:", $virtual_pkg_name), "\n"; |
461 |
my $i = 0; |
462 |
foreach (@l) { print " " . ++$i . "- $_\n" } |
463 |
$n = message_input_(N("What is your choice? (1-%d) ", $i), default => $prefer, range_min => 0, range => $i); |
464 |
defined($n) && $n ne "0" or exit 1; # abort. |
465 |
if ($n =~ /\D/) { |
466 |
my @nn = map { $choices[$_ - 1] } grep { !/\D/ } split /[, \t]+/, $n; |
467 |
@nn or exit 1; |
468 |
return @nn; |
469 |
} |
470 |
} |
471 |
$choices[$n - 1]; |
472 |
} |
473 |
|
474 |
#- do the resolution of dependencies between requested package (and auto selection if any). |
475 |
#- handle parallel option if any. |
476 |
#- return value is true if program should be restarted (in order to take care of important |
477 |
#- packages being upgraded (problably urpmi and perl-URPM, but maybe rpm too, and glibc also ?). |
478 |
my $restart_itself; |
479 |
if ($options{replacepkgs}) { |
480 |
urpm::select::select_replacepkgs($urpm, $state, \%requested); |
481 |
} else { |
482 |
$restart_itself = urpm::select::resolve_dependencies($urpm, |
483 |
$state, |
484 |
\%requested, |
485 |
rpmdb => $env && "$env/rpmdb.cz", |
486 |
auto_select => $auto_select, |
487 |
callback_choices => \&ask_choice, |
488 |
install_src => $install_src, |
489 |
keep => $urpm->{options}{keep}, |
490 |
nodeps => $urpm->{options}{'allow-nodeps'} || $urpm->{options}{'allow-force'}, |
491 |
no_suggests => $urpm->{options}{'no-suggests'}, |
492 |
priority_upgrade => $test || $env ? '' : $urpm->{options}{'priority-upgrade'}, |
493 |
); |
494 |
} |
495 |
|
496 |
{ |
497 |
my $msg = urpm::select::translate_already_installed($state); |
498 |
$msg and print "$msg\n"; |
499 |
} |
500 |
|
501 |
my @unselected_uninstalled = @{$state->{unselected_uninstalled} || []}; |
502 |
if (@unselected_uninstalled) { |
503 |
my $list = join "\n", map { $_->name . '-' . $_->version . '-' . $_->release } @unselected_uninstalled; |
504 |
my $msg = @unselected_uninstalled == 1 ? |
505 |
N("The following package cannot be installed because it depends on packages |
506 |
that are older than the installed ones:\n%s",$list) |
507 |
: N("The following packages can't be installed because they depend on packages |
508 |
that are older than the installed ones:\n%s", $list); |
509 |
if ($urpm->{options}{auto}) { |
510 |
print "$msg\n"; |
511 |
} else { |
512 |
my $noexpr = N("Nn"); |
513 |
dudf_invoke($dudf, "dudf_exit", 17, $msg); |
514 |
$msg .= N("\nContinue installation anyway?"); |
515 |
$force || message_input_($msg . N(" (Y/n) "), boolean => 1) !~ /[$noexpr]/ or exit 17; |
516 |
} |
517 |
} |
518 |
|
519 |
my @ask_unselect = urpm::select::unselected_packages($urpm, $state); |
520 |
if (@ask_unselect) { |
521 |
my $list = urpm::select::translate_why_unselected($urpm, $state, @ask_unselect); |
522 |
my $msg = @ask_unselect == 1 ? |
523 |
N("A requested package cannot be installed:\n%s",$list) |
524 |
: N("Some requested packages cannot be installed:\n%s", $list); |
525 |
if ($urpm->{options}{auto}) { |
526 |
print "$msg\n"; |
527 |
} else { |
528 |
my $noexpr = N("Nn"); |
529 |
dudf_invoke($dudf, "dudf_exit", 17, $msg); |
530 |
$msg .= N("\nContinue installation anyway?"); |
531 |
$force || message_input_($msg . N(" (Y/n) "), boolean => 1) !~ /[$noexpr]/ or exit 17; |
532 |
} |
533 |
} |
534 |
|
535 |
if (my @conflicting_pkgs_msgs = |
536 |
$urpm->{options}{'allow-force'} ? () : urpm::select::removed_packages_msgs($urpm, $state)) { |
537 |
{ |
538 |
my $db = urpm::db_open_or_die_($urpm); |
539 |
urpm::select::find_removed_from_basesystem($urpm, $db, $state, sub { |
540 |
my ($urpm, @pkgs) = @_; |
541 |
foreach (@pkgs) { |
542 |
$urpm->{error}(N("removing package %s will break your system", $_)); |
543 |
} |
544 |
@pkgs and $no_remove = 1; |
545 |
}); |
546 |
} |
547 |
if ($no_remove && !$force) { |
548 |
my $list = join("\n", @conflicting_pkgs_msgs); |
549 |
my $msg = @conflicting_pkgs_msgs == 1 ? |
550 |
N("The installation cannot continue because the following package |
551 |
has to be removed for others to be upgraded:\n%s\n", $list) |
552 |
: N("The installation cannot continue because the following packages |
553 |
have to be removed for others to be upgraded:\n%s\n", $list); |
554 |
print "$msg\n"; |
555 |
dudf_invoke($dudf, "dudf_exit", 0, $msg); |
556 |
exit 0; |
557 |
} |
558 |
|
559 |
my $msg = urpm::select::conflicting_packages_msg_($urpm, $state, \@conflicting_pkgs_msgs); |
560 |
if ($test) { |
561 |
$msg = "$msg\n" . N("(test only, removal will not be actually done)"); |
562 |
} |
563 |
if ($urpm->{options}{auto}) { |
564 |
print "$msg\n"; |
565 |
} else { |
566 |
my $yesexpr = N("Yy"); |
567 |
$force || urpm::msg::ask_yes_or_no($msg) or exit 0; |
568 |
} |
569 |
} |
570 |
|
571 |
#- check if there is at least one package to install that |
572 |
#- has not been given by the user. |
573 |
my $ask_user = $env || $search_result eq 'substring'; |
574 |
|
575 |
my @to_install = @{$urpm->{depslist}}[sort { $a <=> $b } keys %{$state->{selected}}]; # sorted by medium for format_selected_packages |
576 |
{ |
577 |
my @binary = grep { $_->arch ne 'src' } @to_install; |
578 |
if ($install_src) { |
579 |
if (@binary && $install_src && !$env) { |
580 |
my $list = join(' ', sort map { $_->name } @binary); |
581 |
$urpm->{fatal}(1, N("You must first call urpmi with --buildrequires to install the following dependencies:\n%s\n", $list)); |
582 |
} |
583 |
} else { |
584 |
@to_install = @binary; |
585 |
} |
586 |
} |
587 |
|
588 |
if (@to_install && $options{auto_orphans}) { |
589 |
urpm::orphans::compute_future_unrequested_orphans($urpm, $state); |
590 |
if (my @orphans = map { scalar $_->fullname } @{$state->{orphans_to_remove}}) { |
591 |
print P("The following orphan package will be removed.", |
592 |
"The following orphan packages will be removed.", scalar(@orphans)) |
593 |
. "\n" . urpm::orphans::add_leading_spaces(join("\n", @orphans) . "\n"); |
594 |
} |
595 |
} |
596 |
|
597 |
#- this cleans up the list of potential orphan packages: |
598 |
#- - if a package is explicitly requested on the command line, then |
599 |
#- we assume the user doesn't want this package to be auto orphaned |
600 |
#- so we remove it from installed-through-deps |
601 |
#- - this also takes care of removing packages from |
602 |
#- installed-through-deps if the package was first installed as a |
603 |
#- dep of another package, then removed and then explicitly installed |
604 |
urpm::orphans::mark_as_requested($urpm, $state, $test); |
605 |
|
606 |
foreach my $pkg (@to_install) { |
607 |
#- reflect change in flag usage, now requested is set whatever a package is selected or not, |
608 |
#- but required is always set (so a required but not requested is a pure dependency). |
609 |
$ask_user ||= !$pkg->flag_requested || $auto_select || $parallel; |
610 |
} |
611 |
$urpm->{nb_install} = @to_install; |
612 |
|
613 |
dudf_invoke($dudf, "store_toinstall", @to_install); |
614 |
|
615 |
if (!$urpm->{options}{auto} && $ask_user && $urpm->{nb_install} || $env && !$options{debug__do_not_install}) { |
616 |
my $msg = $urpm->{nb_install} == 1 ? N("To satisfy dependencies, the following package is going to be installed:") |
617 |
: N("To satisfy dependencies, the following packages are going to be installed:"); |
618 |
if ($test) { |
619 |
$msg = "$msg\n" . N("(test only, installation will not be actually done)"); |
620 |
} |
621 |
my ($size, $filesize) = $urpm->selected_size_filesize($state); |
622 |
|
623 |
my @to_install_formatted = urpm::msg::format_line_selected_packages($urpm, $state, \@to_install); |
624 |
my $msg2 = $size >= 0 ? |
625 |
N("%s of additional disk space will be used.", formatXiB($size)) : |
626 |
N("%s of disk space will be freed.", formatXiB(-$size)); |
627 |
my $msg2_ = $filesize ? N("%s of packages will be retrieved.", formatXiB($filesize)) . "\n" : ''; |
628 |
my $msg3 = P("Proceed with the installation of one package?", |
629 |
"Proceed with the installation of the %d packages?", |
630 |
$urpm->{nb_install}, $urpm->{nb_install}); |
631 |
my $p = join("\n", $msg, @to_install_formatted, $msg2, $msg2_ . $msg3); |
632 |
if ($env && !$options{debug__do_not_install}) { |
633 |
print "$p\n"; |
634 |
exit 0; #- exit now for specific environment. |
635 |
} |
636 |
my $noexpr = N("Nn"); |
637 |
$force || message_input_($p . N(" (Y/n) "), boolean => 1) !~ /[$noexpr]/ or exit 0; |
638 |
} |
639 |
|
640 |
dudf_invoke($dudf, "check_removed_upgraded", $state); |
641 |
|
642 |
my $exit_code = urpm::main_loop::run($urpm, $state, |
643 |
int(@names || @src_names || @files || @src_files), |
644 |
\@ask_unselect, \%requested, { |
645 |
(!$urpm->{options}{auto} || $allow_medium_change ? (copy_removable => sub { |
646 |
my $msg = N("Please insert the medium named \"%s\"", $_[0]); |
647 |
if ($ENV{DISPLAY} && $::gui) { |
648 |
#- probably run from a drak tool |
649 |
(my $gmessage) = grep { -x $_ } '/usr/X11R6/bin/gmessage', '/usr/bin/gmessage'; |
650 |
if ($gmessage) { |
651 |
return system($gmessage, '-buttons', N("Ok") . ':1,' . N("Cancel") . ':0', "\n$msg\n"); |
652 |
} |
653 |
} |
654 |
if (eval { require Hal::Cdroms; 1 }) { |
655 |
print "$msg\n"; |
656 |
Hal::Cdroms->new->wait_for_insert; |
657 |
1; |
658 |
} else { |
659 |
my $msg2 = N("Press Enter when mounted..."); |
660 |
defined message_input_("$msg\n$msg2 "); |
661 |
} |
662 |
}) : ()), |
663 |
trans_log => sub { |
664 |
# my ($mode, $file, $percent, $total, $eta, $speed) = @_; |
665 |
goto &urpm::download::sync_logger; |
666 |
}, |
667 |
bad_signature => sub { |
668 |
my ($msg, $msg2) = @_; |
669 |
#- rurpmi always abort here |
670 |
if ($urpm->{options}{auto} || $restricted) { |
671 |
print "$msg\n"; |
672 |
0; |
673 |
} else { |
674 |
my $yesexpr = N("Yy"); |
675 |
$force || urpm::msg::ask_yes_or_no("$msg$msg2"); |
676 |
} |
677 |
}, |
678 |
trans_error_summary => sub { |
679 |
my ($_nok, $errors) = @_; |
680 |
dudf_invoke($dudf, "set_error_msg", join("\n", map { "\t$_" } @$errors)); |
681 |
}, |
682 |
ask_yes_or_no => sub { |
683 |
my ($_title, $msg) = @_; # graphical title |
684 |
my $yesexpr = N("Yy"); |
685 |
$force || urpm::msg::ask_yes_or_no($msg); |
686 |
}, |
687 |
need_restart => sub { |
688 |
my ($need_restart_formatted) = @_; |
689 |
print "$_\n" foreach values %$need_restart_formatted; |
690 |
}, |
691 |
message => sub { |
692 |
my ($_title, $msg) = @_; # graphical title |
693 |
print $msg; |
694 |
} |
695 |
}); |
696 |
|
697 |
if ($exit_code == 0 && $auto_select && !$options{auto_orphans}) { |
698 |
if (urpm::orphans::check_unrequested_orphans_after_auto_select($urpm)) { |
699 |
if (my $msg = urpm::orphans::get_now_orphans_msg($urpm)) { |
700 |
print "\n", $msg; |
701 |
} |
702 |
} |
703 |
} |
704 |
|
705 |
unless ($env || $options{nolock}) { |
706 |
$urpmi_lock->unlock; |
707 |
$rpm_lock->unlock if $rpm_lock; |
708 |
} |
709 |
|
710 |
unless ($env) { |
711 |
#- try to umount removable device which may have been mounted. |
712 |
urpm::removable::try_umounting_removables($urpm); |
713 |
} |
714 |
|
715 |
#- restart urpmi if needed, keep command line for that. |
716 |
if ($restart_itself && !$exit_code) { |
717 |
print N("restarting urpmi"), "\n"; |
718 |
#- it seems to work correctly with exec instead of system, provided |
719 |
#- STDOUT or STDERR are not closed before (else no output at all). |
720 |
#- added --previous-priority-upgrade to allow checking if yet if |
721 |
#- priority-upgrade list has changed. and make sure we don't uselessly restart |
722 |
#- renamed bug report dir as /restarted to avoid exit because it already exists |
723 |
#- This permits to have in a same dir bug reports before and after the restart |
724 |
@ARGV = @ARGVcopy; |
725 |
my @arg = ($ARGV[0], map { |
726 |
$ARGV[$_] . ($ARGV[$_ - 1] eq '--bug' ? "/restarted" : ""); |
727 |
} (1 .. $#ARGV)); |
728 |
@arg = ('--previous-priority-upgrade=' . $urpm->{options}{'priority-upgrade'}, |
729 |
grep { !/^--no-priority-upgrade$|--previous-priority-upgrade=/ } @arg); |
730 |
exec $0, @arg; |
731 |
} |
732 |
|
733 |
#- this help flushing correctly by closing this file before (piped on tee). |
734 |
#- but killing them is generally better. |
735 |
if ($pid_err || $pid_out) { |
736 |
kill 15, $pid_err, $pid_out; |
737 |
close STDERR; |
738 |
close STDOUT; |
739 |
} |
740 |
|
741 |
dudf_invoke($dudf, "dudf_exit", $exit_code); |
742 |
|
743 |
exit($exit_code); |