1 |
#!/usr/bin/perl |
2 |
|
3 |
# $Id: urpme 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::install; |
27 |
use urpm::media; |
28 |
use urpm::select; |
29 |
use urpm::orphans; |
30 |
|
31 |
|
32 |
$ENV{PATH} = "/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin"; |
33 |
delete @ENV{qw(ENV BASH_ENV IFS CDPATH)}; |
34 |
|
35 |
our ($test, $parallel, $force, $env); |
36 |
my $yesexpr = |
37 |
#-PO: Add here the keys which might be pressed in the "Yes"-case. |
38 |
N("Yy"); |
39 |
|
40 |
sub usage() { |
41 |
print N("urpme version %s |
42 |
Copyright (C) 1999-2010 Mandriva. |
43 |
This is free software and may be redistributed under the terms of the GNU GPL. |
44 |
|
45 |
usage: |
46 |
", $urpm::VERSION) . N(" --help - print this help message. |
47 |
") . N(" --auto - automatically select a package in choices. |
48 |
") . N(" --auto-orphans - remove orphans |
49 |
") . N(" --test - verify if the removal can be achieved correctly. |
50 |
") . N(" --force - force invocation even if some packages do not exist. |
51 |
") . N(" --parallel - distributed urpmi across machines of alias. |
52 |
") . N(" --repackage - Re-package the files before erasing |
53 |
") . N(" --root - use another root for rpm removal. |
54 |
") . N(" --urpmi-root - use another root for urpmi db & rpm installation. |
55 |
") . N(" --justdb - update only the rpm db, not the filesystem. |
56 |
") . N(" --noscripts - do not execute package scriptlet(s). |
57 |
") . N(" --use-distrib - configure urpme on the fly from a distrib tree, useful |
58 |
to (un)install a chroot with --root option. |
59 |
") . N(" --verbose, -v - verbose mode. |
60 |
") . N(" -a - select all packages matching expression. |
61 |
"); |
62 |
exit(1); |
63 |
} |
64 |
|
65 |
my @origARGV = @ARGV; |
66 |
my $urpm = urpm->new_parse_cmdline or exit(1); |
67 |
my @cmdline_pkgs_to_remove = @ARGV; |
68 |
@cmdline_pkgs_to_remove || $options{matches} || $options{auto_orphans} or usage(); |
69 |
|
70 |
my $state = {}; |
71 |
|
72 |
if ($env) { |
73 |
urpm::set_env($urpm, $env); |
74 |
} elsif ($< && !$test) { |
75 |
$urpm->{fatal}(1, N("Only superuser is allowed to remove packages")); |
76 |
} |
77 |
|
78 |
#- rurpme checks |
79 |
if ($options{restricted}) { |
80 |
urpm::error_restricted($urpm) if $urpm->{root} || $options{usedistrib} || $urpm->{options}{noscripts} || $parallel; |
81 |
} |
82 |
|
83 |
unless ($test) { |
84 |
sys_log("called with: @origARGV"); |
85 |
} |
86 |
|
87 |
#- just configure parallel mode if available. |
88 |
my $_urpmi_lock = !$env && urpm::lock::urpmi_db($urpm, '', wait => $options{wait_lock}); |
89 |
urpm::media::configure($urpm, |
90 |
synthesis => ($parallel ? 'none' : ''), |
91 |
parallel => $parallel, |
92 |
probe_with => $options{probe_with}, |
93 |
usedistrib => $options{usedistrib}, |
94 |
); |
95 |
|
96 |
#- examine packages... |
97 |
my @toremove; |
98 |
if (@cmdline_pkgs_to_remove || $options{matches}) { |
99 |
@toremove = urpm::select::find_packages_to_remove( |
100 |
$urpm, |
101 |
$state, |
102 |
\@cmdline_pkgs_to_remove, |
103 |
matches => $options{matches}, |
104 |
force => $force, |
105 |
callback_notfound => sub { |
106 |
my $urpm = shift @_; |
107 |
#- Warning : the following message is parsed in urpm::parallel_* |
108 |
$urpm->{fatal}(1, (@_ > 1 ? N("unknown packages") : N("unknown package")) . |
109 |
': ' . join(', ', @_)); |
110 |
0; |
111 |
}, |
112 |
callback_fuzzy => sub { |
113 |
my $urpm = shift @_; |
114 |
my $match = shift @_; |
115 |
my $pkgs = $urpm::msg::no_translation ? join(' ', @_) : join('', map { "\n$_" } sort @_); |
116 |
#- Warning : the following message is parsed in urpm::parallel_* |
117 |
$urpm->{fatal}(1, N("The following packages contain %s: %s", $match, $pkgs)); |
118 |
0; |
119 |
}, |
120 |
callback_base => sub { |
121 |
my ($urpm, @l) = @_; |
122 |
#- Warning : the following message is parsed in urpm::parallel_* |
123 |
$urpm->{fatal}(1, P("Removing the following package will break your system:", |
124 |
"Removing the following packages will break your system:", int(@l)) |
125 |
. "\n" . add_leading_spaces(urpm::select::translate_why_removed($urpm, $state, @l))); |
126 |
0; |
127 |
}, |
128 |
) or $urpm->{fatal}(0, N("Nothing to remove")); |
129 |
} |
130 |
|
131 |
my $may_be_orphans = 1; |
132 |
if (@toremove && !$urpm->{options}{auto}) { |
133 |
urpm::orphans::unrequested_orphans_after_remove($urpm, \@toremove) |
134 |
or $may_be_orphans = 0; |
135 |
} |
136 |
|
137 |
my @toremove_no_orphans = @toremove; |
138 |
my @orphans; |
139 |
if ($options{auto_orphans} && $may_be_orphans) { |
140 |
urpm::orphans::compute_future_unrequested_orphans($urpm, $state); |
141 |
@orphans = map { scalar $_->fullname } @{$state->{orphans_to_remove}}; |
142 |
|
143 |
push @toremove, @orphans; |
144 |
if (!@toremove) { |
145 |
print N("No orphans to remove"), "\n"; |
146 |
exit 0; |
147 |
} |
148 |
} |
149 |
|
150 |
my $msg = |
151 |
P("To satisfy dependencies, the following package will be removed", |
152 |
"To satisfy dependencies, the following %d packages will be removed", |
153 |
scalar(@toremove), scalar(@toremove)) |
154 |
. sprintf(" (%s)", formatXiB(-$urpm->selected_size($state))) . ":\n" |
155 |
. add_leading_spaces(urpm::select::translate_why_removed($urpm, $state, @toremove_no_orphans)) . "\n" |
156 |
. (@orphans ? P("(orphan package)", "(orphan packages)", scalar(@orphans)) . "\n" . |
157 |
add_leading_spaces(join("\n", sort @orphans) . "\n") : ()); |
158 |
|
159 |
if ($urpm->{options}{auto} || $env) { |
160 |
$test and print STDOUT $msg; |
161 |
} elsif ($parallel || @toremove > @cmdline_pkgs_to_remove) { |
162 |
print STDOUT $msg; |
163 |
$force || message_input_(P("Remove %d package?", "Remove %d packages?", scalar(@toremove), scalar(@toremove)) . N(" (y/N) "), boolean => 1) =~ /[$yesexpr]/ or exit 0; |
164 |
} |
165 |
|
166 |
print($test ? |
167 |
#- Warning : the following message is parsed in urpm::parallel_* |
168 |
N("testing removal of %s", join(' ', sort @toremove)) : |
169 |
N("removing %s", join(' ', sort @toremove)), "\n"); |
170 |
|
171 |
exit 0 if $env; |
172 |
|
173 |
my %remove_options = ( |
174 |
test => $test, |
175 |
force => $force, |
176 |
justdb => $options{justdb}, |
177 |
urpm::install::options($urpm), |
178 |
); |
179 |
my @errors = $parallel |
180 |
? urpm::parallel::remove($urpm, \@toremove, %remove_options) |
181 |
: urpm::install::install($urpm, \@toremove, {}, {}, %remove_options); |
182 |
|
183 |
if (@errors) { |
184 |
#- Warning : the following message is parsed in urpm::parallel_* |
185 |
$urpm->{fatal}(2, N("Removal failed") . ":\n" . join("\n", map { "\t$_" } @errors)); |
186 |
} elsif ($test) { |
187 |
print N("Removal is possible"), "\n"; |
188 |
} elsif ($may_be_orphans && !$options{auto_orphans}) { |
189 |
if (my $msg = urpm::orphans::get_now_orphans_msg($urpm)) { |
190 |
print "\n", $msg; |
191 |
} |
192 |
} |
193 |
|
194 |
sub add_leading_spaces { |
195 |
my ($s) = @_; |
196 |
$s =~ s/^/ /gm; |
197 |
$s; |
198 |
} |