line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package urpm; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
|
4
|
1
|
|
|
1
|
|
5
|
no warnings 'utf8'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
29
|
|
5
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
14
|
|
6
|
1
|
|
|
1
|
|
4
|
use File::Find (); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
10
|
|
7
|
1
|
|
|
1
|
|
34
|
use urpm::msg; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
use urpm::download; |
9
|
|
|
|
|
|
|
use urpm::util qw(basename begins_with cat_ cat_utf8 dirname file2absolute_file member); |
10
|
|
|
|
|
|
|
use urpm::sys; |
11
|
|
|
|
|
|
|
use urpm::cfg; |
12
|
|
|
|
|
|
|
use urpm::md5sum; |
13
|
|
|
|
|
|
|
# perl_checker: require urpm::args |
14
|
|
|
|
|
|
|
# perl_checker: require urpm::media |
15
|
|
|
|
|
|
|
# perl_checker: require urpm::parallel |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
our $VERSION = '8.109'; |
18
|
|
|
|
|
|
|
our @ISA = qw(URPM Exporter); |
19
|
|
|
|
|
|
|
our @EXPORT_OK = ('file_from_local_url', 'file_from_local_medium', 'is_local_medium'); |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# Prepare exit code. If you change this, the exiting with a failure and the message given will be postponed to the end of the overall processing. |
22
|
|
|
|
|
|
|
our $postponed_msg = N("While some packages may have been installed, there were failures.\n"); |
23
|
|
|
|
|
|
|
our $postponed_code = 0; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
use URPM; |
26
|
|
|
|
|
|
|
use URPM::Resolve; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=head1 NAME |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
urpm - Mageia perl tools to handle the urpmi database |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=head1 DESCRIPTION |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
C is used by urpmi executables to manipulate packages and media |
36
|
|
|
|
|
|
|
on a Mageia Linux distribution. |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
=head2 The urpm class |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
=over 4 |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=cut |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
#- this violently overrides is_arch_compat() to always return true. |
45
|
|
|
|
|
|
|
sub shunt_ignorearch { |
46
|
|
|
|
|
|
|
eval q( sub URPM::Package::is_arch_compat { 1 } ); |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
sub xml_info_policies() { qw(never on-demand update-only always) } |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
sub default_options { |
52
|
|
|
|
|
|
|
{ |
53
|
|
|
|
|
|
|
'split-level' => 1, |
54
|
|
|
|
|
|
|
'split-length' => 50, |
55
|
|
|
|
|
|
|
'verify-rpm' => 1, |
56
|
|
|
|
|
|
|
'post-clean' => 1, |
57
|
|
|
|
|
|
|
'xml-info' => 'on-demand', |
58
|
|
|
|
|
|
|
'max-round-robin-tries' => 5, |
59
|
|
|
|
|
|
|
'max-round-robin-probes' => 2, |
60
|
|
|
|
|
|
|
'days-between-mirrorlist-update' => 5, |
61
|
|
|
|
|
|
|
'nb-of-new-unrequested-pkgs-between-auto-select-orphans-check' => 10, |
62
|
|
|
|
|
|
|
}; |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=item urpm->new() |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
The constructor creates a new urpm object. It's a blessed hash that |
68
|
|
|
|
|
|
|
contains fields from L, and also the following fields: |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
B |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
B: [ { |
73
|
|
|
|
|
|
|
start => int, end => int, name => string, url => string, |
74
|
|
|
|
|
|
|
virtual => bool, media_info_dir => string, with_synthesis => string, |
75
|
|
|
|
|
|
|
no-media-info => bool, |
76
|
|
|
|
|
|
|
iso => string, downloader => string, |
77
|
|
|
|
|
|
|
ignore => bool, update => bool, modified => bool, really_modified => bool, |
78
|
|
|
|
|
|
|
unknown_media_info => bool, |
79
|
|
|
|
|
|
|
} ], |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
B: hashref of urpm options |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
several paths: |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
=over |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
B: path of urpmi.cfg (/etc/urpmi/urpmi.cfg) |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
B: path of mediacfg.d (/etc/urpmi/mediacfg.d) |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
B: path of skip.list (/etc/urpmi/skip.list), |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
B: path of inst.list (/etc/urpmi/inst.list), |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
B: path of prefer.list (/etc/urpmi/prefer.list), |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
B: path of prefer.vendor.list (/etc/urpmi/prefer.vendor.list), |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
B: path of netrc (/etc/urpmi/netrc), |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
B: state directory (/var/lib/urpmi), |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
B: cache directory (/var/cache/urpmi), |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
B: path of the rooted system (when using global urpmi config), |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
B: path of the rooted system (when both urpmi & rpmdb are chrooted) |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=back |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
Several subs: |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=over |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
B: sub for relaying fatal errors (should popup in GUIes) |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
B: sub for relaying other errors |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
B: sub for relaying messages if --verbose |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
B: sub for always displayed messages, enable to redirect output for eg: installer |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
B: sub for messages displayed unless --quiet |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=back |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
All C methods are available on an urpm object. |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=cut |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub new { |
132
|
|
|
|
|
|
|
my ($class) = @_; |
133
|
|
|
|
|
|
|
my $self; |
134
|
|
|
|
|
|
|
$self = bless { |
135
|
|
|
|
|
|
|
# from URPM |
136
|
|
|
|
|
|
|
depslist => [], |
137
|
|
|
|
|
|
|
provides => {}, |
138
|
|
|
|
|
|
|
obsoletes => {}, |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
media => undef, |
141
|
|
|
|
|
|
|
options => {}, |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
fatal => sub { printf STDERR "%s\n", $_[1]; exit($_[0]) }, |
144
|
|
|
|
|
|
|
error => sub { printf STDERR "%s\n", $_[0] }, |
145
|
|
|
|
|
|
|
info => sub { printf "%s\n", $_[0] }, #- displayed unless --quiet |
146
|
|
|
|
|
|
|
log => sub { printf "%s\n", $_[0] }, #- displayed if --verbose |
147
|
|
|
|
|
|
|
print => sub { printf "%s\n", $_[0] }, #- always displayed, enable to redirect output for eg: installer |
148
|
|
|
|
|
|
|
}, $class; |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
set_files($self, ''); |
151
|
|
|
|
|
|
|
$self->set_nofatal(1); |
152
|
|
|
|
|
|
|
$self; |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
=item urpm->new_parse_cmdline() |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
Like urpm->new but also parse the command line and parse the configuration file. |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
=cut |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
sub new_parse_cmdline { |
162
|
|
|
|
|
|
|
my ($class) = @_; |
163
|
|
|
|
|
|
|
my $urpm = $class->new; |
164
|
|
|
|
|
|
|
urpm::args::parse_cmdline(urpm => $urpm); |
165
|
|
|
|
|
|
|
get_global_options($urpm); |
166
|
|
|
|
|
|
|
$urpm; |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
sub _add2hash { my ($a, $b) = @_; while (my ($k, $v) = each %{$b || {}}) { defined $a->{$k} or $a->{$k} = $v } $a } |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
sub get_global_options { |
172
|
|
|
|
|
|
|
my ($urpm) = @_; |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
my $config = urpm::cfg::load_config($urpm->{config}) |
175
|
|
|
|
|
|
|
or $urpm->{fatal}(6, $urpm::cfg::err); |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
if (my $global = $config->{global}) { |
178
|
|
|
|
|
|
|
_add2hash($urpm->{options}, $global); |
179
|
|
|
|
|
|
|
} |
180
|
|
|
|
|
|
|
#- remember global options for write_config |
181
|
|
|
|
|
|
|
$urpm->{global_config} = $config->{global}; |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
_add2hash($urpm->{options}, default_options()); |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub prefer_rooted { |
187
|
|
|
|
|
|
|
my ($root, $file) = @_; |
188
|
|
|
|
|
|
|
-e "$root$file" ? "$root$file" : $file; |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
sub check_dir { |
192
|
|
|
|
|
|
|
my ($urpm, $dir) = @_; |
193
|
|
|
|
|
|
|
-d $dir && ! -l $dir or $urpm->{fatal}(1, N("fail to create directory %s", $dir)); |
194
|
|
|
|
|
|
|
-o $dir && -w $dir or $urpm->{fatal}(1, N("invalid owner for directory %s", $dir)); |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
sub init_dir { |
198
|
|
|
|
|
|
|
my ($urpm, $dir) = @_; |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
mkdir $dir, 0755; # try to create it |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
check_dir($urpm, $dir); |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
mkdir "$dir/partial"; |
205
|
|
|
|
|
|
|
mkdir "$dir/rpms"; |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
$dir; |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
sub userdir_prefix { |
211
|
|
|
|
|
|
|
my ($_urpm) = @_; |
212
|
|
|
|
|
|
|
'/tmp/.urpmi-'; |
213
|
|
|
|
|
|
|
} |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
sub valid_statedir { |
216
|
|
|
|
|
|
|
my ($urpm) = @_; |
217
|
|
|
|
|
|
|
$< or return; |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
my $dir = ($urpm->{urpmi_root} || '') . userdir_prefix($urpm) . $< . "/lib"; |
220
|
|
|
|
|
|
|
init_dir($urpm, $dir); |
221
|
|
|
|
|
|
|
} |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
sub userdir { |
224
|
|
|
|
|
|
|
#mdkonline uses userdir because it runs as user |
225
|
|
|
|
|
|
|
my ($urpm) = @_; |
226
|
|
|
|
|
|
|
$< or return; |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
my $dir = ($urpm->{urpmi_root} || '') . userdir_prefix($urpm) . $<; |
229
|
|
|
|
|
|
|
init_dir($urpm, $dir); |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
sub ensure_valid_cachedir { |
233
|
|
|
|
|
|
|
my ($urpm) = @_; |
234
|
|
|
|
|
|
|
if (my $dir = userdir($urpm)) { |
235
|
|
|
|
|
|
|
$urpm->{cachedir} = $dir; |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
-w "$urpm->{cachedir}/partial" or $urpm->{fatal}(1, N("Can not download packages into %s", "$urpm->{cachedir}/partial")); |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
sub valid_cachedir { |
241
|
|
|
|
|
|
|
my ($urpm) = @_; |
242
|
|
|
|
|
|
|
userdir($urpm) || $urpm->{cachedir}; |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
sub is_temporary_file { |
246
|
|
|
|
|
|
|
my ($urpm, $f) = @_; |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
begins_with($f, $urpm->{cachedir}); |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub set_env { |
252
|
|
|
|
|
|
|
my ($urpm, $env) = @_; |
253
|
|
|
|
|
|
|
-d $env or $urpm->{fatal}(8, N("Environment directory %s does not exist", $env)); |
254
|
|
|
|
|
|
|
print N("using specific environment on %s\n", $env); |
255
|
|
|
|
|
|
|
#- setting new environment. |
256
|
|
|
|
|
|
|
$urpm->{config} = "$env/urpmi.cfg"; |
257
|
|
|
|
|
|
|
if (cat_($urpm->{config}) =~ /^\s*virtual\s*$/m) { |
258
|
|
|
|
|
|
|
print "dropping virtual from $urpm->{config}\n"; |
259
|
|
|
|
|
|
|
system(q(perl -pi -e 's/^\s*virtual\s*$//' ) . $urpm->{config}); |
260
|
|
|
|
|
|
|
} |
261
|
|
|
|
|
|
|
$urpm->{mediacfgdir} = "$env/mediacfg.d"; |
262
|
|
|
|
|
|
|
$urpm->{skiplist} = "$env/skip.list"; |
263
|
|
|
|
|
|
|
$urpm->{instlist} = "$env/inst.list"; |
264
|
|
|
|
|
|
|
$urpm->{prefer_list} = "$env/prefer.list"; |
265
|
|
|
|
|
|
|
$urpm->{prefer_vendor_list} = "$env/prefer.vendor.list"; |
266
|
|
|
|
|
|
|
$urpm->{statedir} = $env; |
267
|
|
|
|
|
|
|
$urpm->{env_rpmdb} = "$env/rpmdb.cz"; |
268
|
|
|
|
|
|
|
$urpm->{env_dir} = $env; |
269
|
|
|
|
|
|
|
} |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
sub set_files { |
272
|
|
|
|
|
|
|
my ($urpm, $urpmi_root) = @_; |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
$urpmi_root and $urpmi_root = file2absolute_file($urpmi_root); |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
my %h = ( |
277
|
|
|
|
|
|
|
config => "$urpmi_root/etc/urpmi/urpmi.cfg", |
278
|
|
|
|
|
|
|
mediacfgdir => "$urpmi_root/etc/urpmi/mediacfg.d", |
279
|
|
|
|
|
|
|
skiplist => prefer_rooted($urpmi_root, '/etc/urpmi/skip.list'), |
280
|
|
|
|
|
|
|
instlist => prefer_rooted($urpmi_root, '/etc/urpmi/inst.list'), |
281
|
|
|
|
|
|
|
prefer_list => prefer_rooted($urpmi_root, '/etc/urpmi/prefer.list'), |
282
|
|
|
|
|
|
|
prefer_vendor_list => |
283
|
|
|
|
|
|
|
prefer_rooted($urpmi_root, '/etc/urpmi/prefer.vendor.list'), |
284
|
|
|
|
|
|
|
private_netrc => "$urpmi_root/etc/urpmi/netrc", |
285
|
|
|
|
|
|
|
statedir => "$urpmi_root/var/lib/urpmi", |
286
|
|
|
|
|
|
|
cachedir => "$urpmi_root/var/cache/urpmi", |
287
|
|
|
|
|
|
|
root => $urpmi_root, |
288
|
|
|
|
|
|
|
$urpmi_root ? (urpmi_root => $urpmi_root) : @{[]}, |
289
|
|
|
|
|
|
|
); |
290
|
|
|
|
|
|
|
$urpm->{$_} = $h{$_} foreach keys %h; |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
create_var_lib_rpm($urpm, %h); |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
# policy is too use chroot environment only for --urpmi-root, not for --root: |
295
|
|
|
|
|
|
|
if ($urpmi_root && -e "$urpmi_root/etc/rpm/macros") { |
296
|
|
|
|
|
|
|
URPM::loadmacrosfile("$urpmi_root/etc/rpm/macros"); |
297
|
|
|
|
|
|
|
} |
298
|
|
|
|
|
|
|
} |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
sub create_var_lib_rpm { |
301
|
|
|
|
|
|
|
my ($urpm, %h) = @_; |
302
|
|
|
|
|
|
|
require File::Path; |
303
|
|
|
|
|
|
|
File::Path::mkpath([ $h{statedir}, |
304
|
|
|
|
|
|
|
(map { "$h{cachedir}/$_" } qw(partial rpms)), |
305
|
|
|
|
|
|
|
dirname($h{config}), |
306
|
|
|
|
|
|
|
"$urpm->{root}/var/lib/rpm", |
307
|
|
|
|
|
|
|
"$urpm->{root}/var/tmp", |
308
|
|
|
|
|
|
|
]); |
309
|
|
|
|
|
|
|
} |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
sub modify_rpm_macro { |
312
|
|
|
|
|
|
|
my ($name, $to_remove, $to_add) = @_; |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
my $val = URPM::expand('%' . $name); |
315
|
|
|
|
|
|
|
$val =~ s/$to_remove/$to_add/ or $val = join(' ', grep { $_ } $val, $to_add); |
316
|
|
|
|
|
|
|
URPM::add_macro("$name $val"); |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
sub set_tune_rpm { |
320
|
|
|
|
|
|
|
my ($urpm, $para) = @_; |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
my %h = map { $_ => 1 } map { |
323
|
|
|
|
|
|
|
if ($_ eq 'all') { |
324
|
|
|
|
|
|
|
('nofsync', 'private'); |
325
|
|
|
|
|
|
|
} else { |
326
|
|
|
|
|
|
|
$_; |
327
|
|
|
|
|
|
|
} |
328
|
|
|
|
|
|
|
} split(',', $para); |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
$urpm->{tune_rpm} = \%h; |
331
|
|
|
|
|
|
|
} |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
sub tune_rpm { |
334
|
|
|
|
|
|
|
my ($urpm) = @_; |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
if ($urpm->{tune_rpm}{nofsync}) { |
337
|
|
|
|
|
|
|
modify_rpm_macro('__dbi_other', 'fsync', 'nofsync'); |
338
|
|
|
|
|
|
|
} |
339
|
|
|
|
|
|
|
if ($urpm->{tune_rpm}{private}) { |
340
|
|
|
|
|
|
|
urpm::sys::clean_rpmdb_shared_regions($urpm->{root}); |
341
|
|
|
|
|
|
|
modify_rpm_macro('__dbi_other', 'usedbenv', 'private'); |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
sub _blist_pkg_to_urls { |
346
|
|
|
|
|
|
|
my ($blist, @pkgs) = @_; |
347
|
|
|
|
|
|
|
my $base_url = $blist->{medium}{url} . '/'; |
348
|
|
|
|
|
|
|
map { $base_url . $_->filename } @pkgs; |
349
|
|
|
|
|
|
|
} |
350
|
|
|
|
|
|
|
sub blist_pkg_to_url { |
351
|
|
|
|
|
|
|
my ($blist, $pkg) = @_; |
352
|
|
|
|
|
|
|
my ($url) = _blist_pkg_to_urls($blist, $pkg); |
353
|
|
|
|
|
|
|
$url; |
354
|
|
|
|
|
|
|
} |
355
|
|
|
|
|
|
|
sub blist_to_urls { |
356
|
|
|
|
|
|
|
my ($blist) = @_; |
357
|
|
|
|
|
|
|
_blist_pkg_to_urls($blist, values %{$blist->{pkgs}}); |
358
|
|
|
|
|
|
|
} |
359
|
|
|
|
|
|
|
sub blist_to_filenames { |
360
|
|
|
|
|
|
|
my ($blist) = @_; |
361
|
|
|
|
|
|
|
map { $_->filename } values %{$blist->{pkgs}}; |
362
|
|
|
|
|
|
|
} |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
sub protocol_from_url { |
365
|
|
|
|
|
|
|
my ($url) = @_; |
366
|
|
|
|
|
|
|
$url =~ m!^(\w+)(_[^:]*)?:! && $1; |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
sub file_from_local_url { |
369
|
|
|
|
|
|
|
my ($url) = @_; |
370
|
|
|
|
|
|
|
$url =~ m!^(?:removable[^:]*:/|file:/)?(/.*)! && $1; |
371
|
|
|
|
|
|
|
} |
372
|
|
|
|
|
|
|
sub file_from_local_medium { |
373
|
|
|
|
|
|
|
my ($medium, $o_url) = @_; |
374
|
|
|
|
|
|
|
my $url = $o_url || $medium->{url}; |
375
|
|
|
|
|
|
|
if ($url =~ m!^cdrom://(.*)!) { |
376
|
|
|
|
|
|
|
my $rel = $1; |
377
|
|
|
|
|
|
|
$medium->{mntpoint} or do { require Carp; Carp::confess("cdrom is not mounted yet!\n") }; |
378
|
|
|
|
|
|
|
"$medium->{mntpoint}/$rel"; |
379
|
|
|
|
|
|
|
} else { |
380
|
|
|
|
|
|
|
file_from_local_url($url); |
381
|
|
|
|
|
|
|
} |
382
|
|
|
|
|
|
|
} |
383
|
|
|
|
|
|
|
sub is_local_url { |
384
|
|
|
|
|
|
|
my ($url) = @_; |
385
|
|
|
|
|
|
|
file_from_local_url($url) || is_cdrom_url($url); |
386
|
|
|
|
|
|
|
} |
387
|
|
|
|
|
|
|
sub is_local_medium { |
388
|
|
|
|
|
|
|
my ($medium) = @_; |
389
|
|
|
|
|
|
|
is_local_url($medium->{url}); |
390
|
|
|
|
|
|
|
} |
391
|
|
|
|
|
|
|
sub is_cdrom_url { |
392
|
|
|
|
|
|
|
my ($url) = @_; |
393
|
|
|
|
|
|
|
protocol_from_url($url) eq 'cdrom'; |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
=item db_open_or_die($urpm, $b_write_perm) |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
Open RPM database (RW or not) and die if it fails |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
=cut |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
sub db_open_or_die_ { |
403
|
|
|
|
|
|
|
my ($urpm, $b_write_perm) = @_; |
404
|
|
|
|
|
|
|
my $db; |
405
|
|
|
|
|
|
|
if ($urpm->{env_rpmdb}) { |
406
|
|
|
|
|
|
|
#- URPM has same methods as URPM::DB and empty URPM will be seen as empty URPM::DB. |
407
|
|
|
|
|
|
|
$db = URPM->new; |
408
|
|
|
|
|
|
|
$db->parse_synthesis($urpm->{env_rpmdb}); |
409
|
|
|
|
|
|
|
} else { |
410
|
|
|
|
|
|
|
$db = db_open_or_die($urpm, $urpm->{root}, $b_write_perm); |
411
|
|
|
|
|
|
|
} |
412
|
|
|
|
|
|
|
$db; |
413
|
|
|
|
|
|
|
} |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
# please use higher level function db_open_or_die_() |
416
|
|
|
|
|
|
|
sub db_open_or_die { |
417
|
|
|
|
|
|
|
my ($urpm, $root, $b_write_perm) = @_; |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
$urpm->{debug} and $urpm->{debug}("opening rpmdb (root=$root, write=$b_write_perm)"); |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
my $db = URPM::DB::open($root, $b_write_perm || 0) |
422
|
|
|
|
|
|
|
or $urpm->{fatal}(9, N("unable to open rpmdb")); |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
$db; |
425
|
|
|
|
|
|
|
} |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
=item register_rpms($urpm, @files) |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
Register local packages for being installed, keep track of source. |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
=cut |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
sub register_rpms { |
434
|
|
|
|
|
|
|
my ($urpm, @files) = @_; |
435
|
|
|
|
|
|
|
my ($start, $id, $error, %requested); |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
#- examine each rpm and build the depslist for them using current |
438
|
|
|
|
|
|
|
#- depslist and provides environment. |
439
|
|
|
|
|
|
|
$start = @{$urpm->{depslist}}; |
440
|
|
|
|
|
|
|
foreach (@files) { |
441
|
|
|
|
|
|
|
/\.(?:rpm|spec)$/ or $error = 1, $urpm->{error}(N("invalid rpm file name [%s]", $_)), next; |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
#- if that's an URL, download. |
444
|
|
|
|
|
|
|
if (protocol_from_url($_)) { |
445
|
|
|
|
|
|
|
my $basename = basename($_); |
446
|
|
|
|
|
|
|
unlink "$urpm->{cachedir}/partial/$basename"; |
447
|
|
|
|
|
|
|
$urpm->{log}(N("retrieving rpm file [%s] ...", $_)); |
448
|
|
|
|
|
|
|
if (urpm::download::sync_url($urpm, $_, quiet => 1)) { |
449
|
|
|
|
|
|
|
$urpm->{log}(N("...retrieving done")); |
450
|
|
|
|
|
|
|
$_ = "$urpm->{cachedir}/partial/$basename"; |
451
|
|
|
|
|
|
|
} else { |
452
|
|
|
|
|
|
|
$urpm->{error}(N("...retrieving failed: %s", $@)); |
453
|
|
|
|
|
|
|
unlink "$urpm->{cachedir}/partial/$basename"; |
454
|
|
|
|
|
|
|
next; |
455
|
|
|
|
|
|
|
} |
456
|
|
|
|
|
|
|
} else { |
457
|
|
|
|
|
|
|
-r $_ or $error = 1, $urpm->{error}(N("unable to access rpm file [%s]", $_)), next; |
458
|
|
|
|
|
|
|
} |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
if (/\.spec$/) { |
461
|
|
|
|
|
|
|
my $pkg = URPM::spec2srcheader($_) |
462
|
|
|
|
|
|
|
or $error = 1, $urpm->{error}(N("unable to parse spec file %s [%s]", $_, $!)), next; |
463
|
|
|
|
|
|
|
$id = @{$urpm->{depslist}}; |
464
|
|
|
|
|
|
|
$urpm->{depslist}[$id] = $pkg; |
465
|
|
|
|
|
|
|
$pkg->set_id($id); #- sets internal id to the depslist id. |
466
|
|
|
|
|
|
|
$urpm->{source}{$id} = $_; |
467
|
|
|
|
|
|
|
} else { |
468
|
|
|
|
|
|
|
($id) = $urpm->parse_rpm($_); |
469
|
|
|
|
|
|
|
my $pkg = defined $id && $urpm->{depslist}[$id]; |
470
|
|
|
|
|
|
|
$pkg or $error = 1, $urpm->{error}(N("unable to register rpm file")), next; |
471
|
|
|
|
|
|
|
$pkg->arch eq 'src' || $pkg->is_arch_compat |
472
|
|
|
|
|
|
|
or $error = 1, $urpm->{error}(N("Incompatible architecture for rpm [%s]", $_)), next; |
473
|
|
|
|
|
|
|
$urpm->{source}{$id} = $_; |
474
|
|
|
|
|
|
|
} |
475
|
|
|
|
|
|
|
} |
476
|
|
|
|
|
|
|
$error and $urpm->{fatal}(2, N("error registering local packages")); |
477
|
|
|
|
|
|
|
defined $id && $start <= $id and @requested{($start .. $id)} = (1) x ($id-$start+1); |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
#- distribute local packages to distant nodes directly in cache of each machine. |
480
|
|
|
|
|
|
|
if (@files && $urpm->{parallel_handler}) { |
481
|
|
|
|
|
|
|
$urpm->{parallel_handler}->parallel_register_rpms($urpm, @files); |
482
|
|
|
|
|
|
|
} |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
%requested; |
485
|
|
|
|
|
|
|
} |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
=item is_delta_installable($urpm, $pkg, $root) |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
checks whether the delta RPM represented by $pkg is installable wrt the |
490
|
|
|
|
|
|
|
RPM DB on $root. For this, it extracts the rpm version to which the |
491
|
|
|
|
|
|
|
delta applies from the delta rpm filename itself. So naming conventions |
492
|
|
|
|
|
|
|
do matter :) |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
=cut |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
sub is_delta_installable { |
497
|
|
|
|
|
|
|
my ($urpm, $pkg, $root) = @_; |
498
|
|
|
|
|
|
|
$pkg->flag_installed or return 0; |
499
|
|
|
|
|
|
|
my $f = $pkg->filename; |
500
|
|
|
|
|
|
|
my $n = $pkg->name; |
501
|
|
|
|
|
|
|
my ($v_match) = $f =~ /^\Q$n\E-(.*)_.+\.delta\.rpm$/; |
502
|
|
|
|
|
|
|
my $db = db_open_or_die($urpm, $root); |
503
|
|
|
|
|
|
|
my $v_installed; |
504
|
|
|
|
|
|
|
$db->traverse(sub { |
505
|
|
|
|
|
|
|
my ($p) = @_; |
506
|
|
|
|
|
|
|
$p->name eq $n and $v_installed = $p->version . '-' . $p->release; |
507
|
|
|
|
|
|
|
}); |
508
|
|
|
|
|
|
|
$v_match eq $v_installed; |
509
|
|
|
|
|
|
|
} |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
=item extract_packages_to_install($urpm, $sources) |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
Extract package that should be installed instead of upgraded, |
515
|
|
|
|
|
|
|
installing instead of upgrading is useful |
516
|
|
|
|
|
|
|
- for inst.list (cf flag disable_obsolete) |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
Sources is a hash of id -> source rpm filename. |
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
=cut |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
sub extract_packages_to_install { |
523
|
|
|
|
|
|
|
my ($urpm, $sources) = @_; |
524
|
|
|
|
|
|
|
my %inst; |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
foreach (keys %$sources) { |
527
|
|
|
|
|
|
|
my $pkg = $urpm->{depslist}[$_] or next; |
528
|
|
|
|
|
|
|
$pkg->flag_disable_obsolete |
529
|
|
|
|
|
|
|
and $inst{$pkg->id} = delete $sources->{$pkg->id}; |
530
|
|
|
|
|
|
|
} |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
\%inst; |
533
|
|
|
|
|
|
|
} |
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
#- deprecated, use find_candidate_packages_() directly |
536
|
|
|
|
|
|
|
#- |
537
|
|
|
|
|
|
|
#- side-effects: none |
538
|
|
|
|
|
|
|
sub find_candidate_packages_ { |
539
|
|
|
|
|
|
|
my ($urpm, $id_prop) = @_; |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
my %packages; |
542
|
|
|
|
|
|
|
foreach ($urpm->find_candidate_packages($id_prop)) { |
543
|
|
|
|
|
|
|
push @{$packages{$_->name}}, $_; |
544
|
|
|
|
|
|
|
} |
545
|
|
|
|
|
|
|
values %packages; |
546
|
|
|
|
|
|
|
} |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
=item get_updates_description($urpm, @update_medias) |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
Get reason of update for packages to be updated. |
551
|
|
|
|
|
|
|
Use all update medias if none given. |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
=cut |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
sub get_updates_description { |
556
|
|
|
|
|
|
|
my ($urpm, @update_medias) = @_; |
557
|
|
|
|
|
|
|
my %update_descr; |
558
|
|
|
|
|
|
|
my ($cur, $section); |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
@update_medias or @update_medias = urpm::media::non_ignored_media($urpm, 'update'); |
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
foreach my $medium (@update_medias) { |
563
|
|
|
|
|
|
|
# fix not taking into account the last %package token of each descrptions file: '%package dummy' |
564
|
|
|
|
|
|
|
foreach (cat_utf8(urpm::media::statedir_descriptions($urpm, $medium)), |
565
|
|
|
|
|
|
|
($::env ? cat_utf8("$::env/descriptions") : ()), '%package dummy') { |
566
|
|
|
|
|
|
|
/^%package +(.+)/ and do { |
567
|
|
|
|
|
|
|
# fixes not parsing descriptions file when MU adds itself the security source: |
568
|
|
|
|
|
|
|
if (exists $cur->{importance} && !member($cur->{importance}, qw(security bugfix))) { |
569
|
|
|
|
|
|
|
$cur->{importance} = 'normal'; |
570
|
|
|
|
|
|
|
} |
571
|
|
|
|
|
|
|
$update_descr{$medium->{name}}{$_} = $cur foreach @{$cur->{pkgs} || []}; |
572
|
|
|
|
|
|
|
$cur = { pkgs => [ split /\s/, $1 ] }; |
573
|
|
|
|
|
|
|
$section = 'pkg'; |
574
|
|
|
|
|
|
|
next; |
575
|
|
|
|
|
|
|
}; |
576
|
|
|
|
|
|
|
/^Updated?: +(.+)/ && $section eq 'pkg' and do { $cur->{updated} = $1; next }; |
577
|
|
|
|
|
|
|
/^Importance: +(.+)/ && $section eq 'pkg' and do { $cur->{importance} = $1; next }; |
578
|
|
|
|
|
|
|
/^(ID|URL): +(.+)/ && $section eq 'pkg' and do { $cur->{$1} = $2; next }; |
579
|
|
|
|
|
|
|
/^%(pre|description)/ and do { $section = $1; next }; |
580
|
|
|
|
|
|
|
$section =~ /^(pre|description)\z/ and $cur->{$1} .= $_; |
581
|
|
|
|
|
|
|
} |
582
|
|
|
|
|
|
|
} |
583
|
|
|
|
|
|
|
\%update_descr; |
584
|
|
|
|
|
|
|
} |
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
sub error_restricted ($) { |
587
|
|
|
|
|
|
|
my ($urpm) = @_; |
588
|
|
|
|
|
|
|
$urpm->{fatal}(2, N("This operation is forbidden while running in restricted mode")); |
589
|
|
|
|
|
|
|
} |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
sub DESTROY {} |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
1; |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
=back |
597
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
=head1 SEE ALSO |
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
The L package is used to manipulate at a lower level synthesis and rpm |
601
|
|
|
|
|
|
|
files. |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
See also submodules: L, L, L, |
604
|
|
|
|
|
|
|
L, L, L, L, |
605
|
|
|
|
|
|
|
L, L, L, L, |
606
|
|
|
|
|
|
|
L, L, L, L, |
607
|
|
|
|
|
|
|
L, L, L, |
608
|
|
|
|
|
|
|
L, L, L, |
609
|
|
|
|
|
|
|
L, L, L, L, |
610
|
|
|
|
|
|
|
L, L |
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
=head1 COPYRIGHT |
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 MandrakeSoft SA |
615
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
Copyright (C) 2005-2010 Mandriva SA |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
Copyright (C) 2011-2017 Mageia |
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify |
621
|
|
|
|
|
|
|
it under the terms of the GNU General Public License as published by |
622
|
|
|
|
|
|
|
the Free Software Foundation; either version 2, or (at your option) |
623
|
|
|
|
|
|
|
any later version. |
624
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful, |
626
|
|
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
627
|
|
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
628
|
|
|
|
|
|
|
GNU General Public License for more details. |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License |
631
|
|
|
|
|
|
|
along with this program; if not, write to the Free Software |
632
|
|
|
|
|
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
633
|
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
=cut |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
# ex: set ts=8 sts=4 sw=4 noet: |