line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package urpm::util; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
|
4
|
22
|
|
|
22
|
|
1003456
|
use strict; |
|
22
|
|
|
|
|
387
|
|
|
22
|
|
|
|
|
869
|
|
5
|
22
|
|
|
22
|
|
152
|
use Exporter; |
|
22
|
|
|
|
|
62
|
|
|
22
|
|
|
|
|
45127
|
|
6
|
|
|
|
|
|
|
our @ISA = 'Exporter'; |
7
|
|
|
|
|
|
|
our @EXPORT = qw(add2hash_ |
8
|
|
|
|
|
|
|
any |
9
|
|
|
|
|
|
|
append_to_file |
10
|
|
|
|
|
|
|
basename |
11
|
|
|
|
|
|
|
begins_with |
12
|
|
|
|
|
|
|
cat_ |
13
|
|
|
|
|
|
|
cat_utf8 |
14
|
|
|
|
|
|
|
copy_and_own |
15
|
|
|
|
|
|
|
difference2 |
16
|
|
|
|
|
|
|
dirname |
17
|
|
|
|
|
|
|
file2absolute_file |
18
|
|
|
|
|
|
|
file_size |
19
|
|
|
|
|
|
|
find |
20
|
|
|
|
|
|
|
formatList |
21
|
|
|
|
|
|
|
intersection |
22
|
|
|
|
|
|
|
max |
23
|
|
|
|
|
|
|
member |
24
|
|
|
|
|
|
|
min |
25
|
|
|
|
|
|
|
offset_pathname |
26
|
|
|
|
|
|
|
output_safe |
27
|
|
|
|
|
|
|
partition |
28
|
|
|
|
|
|
|
put_in_hash |
29
|
|
|
|
|
|
|
quotespace |
30
|
|
|
|
|
|
|
reduce_pathname |
31
|
|
|
|
|
|
|
remove_internal_name |
32
|
|
|
|
|
|
|
same_size_and_mtime |
33
|
|
|
|
|
|
|
uniq |
34
|
|
|
|
|
|
|
uniq_ |
35
|
|
|
|
|
|
|
unquotespace |
36
|
|
|
|
|
|
|
untaint |
37
|
|
|
|
|
|
|
wc_l |
38
|
|
|
|
|
|
|
); |
39
|
|
|
|
|
|
|
|
40
|
0
|
|
0
|
0
|
0
|
0
|
sub min { my $n = shift; $_ < $n and $n = $_ foreach @_; $n } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
41
|
0
|
|
0
|
0
|
0
|
0
|
sub max { my $n = shift; $_ > $n and $n = $_ foreach @_; $n } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
#- quoting/unquoting a string that may be containing space chars. |
44
|
0
|
|
0
|
0
|
0
|
0
|
sub quotespace { my $x = $_[0] || ''; $x =~ s/(\s)/\\$1/g; $x } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
45
|
0
|
|
0
|
0
|
0
|
0
|
sub unquotespace { my $x = $_[0] || ''; $x =~ s/\\(\s)/$1/g; $x } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
46
|
0
|
|
0
|
0
|
0
|
0
|
sub remove_internal_name { my $x = $_[0] || ''; $x =~ s/\(\S+\)$/$1/g; $x } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
47
|
|
|
|
|
|
|
|
48
|
10
|
50
|
|
10
|
0
|
271262
|
sub dirname { local $_ = shift; s|[^/]*/*\s*$||; s|(.)/*$|$1|; $_ || '.' } |
|
10
|
|
|
|
|
183
|
|
|
10
|
|
|
|
|
38
|
|
|
10
|
|
|
|
|
194
|
|
49
|
0
|
|
|
0
|
0
|
0
|
sub basename { local $_ = shift; s|/*\s*$||; s|.*/||; $_ } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
sub file2absolute_file { |
52
|
0
|
|
|
0
|
0
|
0
|
my ($f) = @_; |
53
|
|
|
|
|
|
|
|
54
|
0
|
0
|
|
|
|
0
|
if ($f !~ m!^/!) { |
55
|
0
|
|
|
|
|
0
|
require File::Spec; |
56
|
0
|
|
|
|
|
0
|
$f = File::Spec->rel2abs($f); |
57
|
|
|
|
|
|
|
} |
58
|
0
|
|
|
|
|
0
|
$f; |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
#- reduce pathname by removing /.. each time it appears (or . too). |
62
|
|
|
|
|
|
|
sub reduce_pathname { |
63
|
0
|
|
|
0
|
0
|
0
|
my ($url) = @_; |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
#- clean url to remove any macro (which cannot be solved now). |
66
|
|
|
|
|
|
|
#- take care if this is a true url and not a simple pathname. |
67
|
0
|
|
|
|
|
0
|
my ($host, $dir) = $url =~ m|([^:/]*://[^/]*/)?(.*)|; |
68
|
0
|
|
0
|
|
|
0
|
$host //= ''; |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
#- remove any multiple /s or trailing /. |
71
|
|
|
|
|
|
|
#- then split all components of pathname. |
72
|
0
|
|
|
|
|
0
|
$dir =~ s|/+|/|g; $dir =~ s|/$||; |
|
0
|
|
|
|
|
0
|
|
73
|
0
|
|
|
|
|
0
|
my @paths = split '/', $dir; |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
#- reset $dir, recompose it, and clean trailing / added by algorithm. |
76
|
0
|
|
|
|
|
0
|
$dir = ''; |
77
|
0
|
|
|
|
|
0
|
foreach (@paths) { |
78
|
0
|
0
|
|
|
|
0
|
if ($_ eq '..') { |
|
|
0
|
|
|
|
|
|
79
|
0
|
0
|
|
|
|
0
|
if ($dir =~ s|([^/]+)/$||) { |
80
|
0
|
0
|
|
|
|
0
|
if ($1 eq '..') { |
81
|
0
|
|
|
|
|
0
|
$dir .= "../../"; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
} else { |
84
|
0
|
|
|
|
|
0
|
$dir .= "../"; |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
} elsif ($_ ne '.') { |
87
|
0
|
|
|
|
|
0
|
$dir .= "$_/"; |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
} |
90
|
0
|
|
|
|
|
0
|
$dir =~ s|/$||; |
91
|
0
|
|
0
|
|
|
0
|
$dir ||= '/'; |
92
|
|
|
|
|
|
|
|
93
|
0
|
|
|
|
|
0
|
$host . $dir; |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
#- offset pathname by returning the right things to add to a relative directory |
97
|
|
|
|
|
|
|
#- to make no change. url is needed to resolve going before to top base. |
98
|
|
|
|
|
|
|
sub offset_pathname { |
99
|
0
|
|
|
0
|
0
|
0
|
my ($url, $offset) = map { reduce_pathname($_) } @_; |
|
0
|
|
|
|
|
0
|
|
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
#- clean url to remove any macro (which cannot be solved now). |
102
|
|
|
|
|
|
|
#- take care if this is a true url and not a simple pathname. |
103
|
0
|
|
|
|
|
0
|
my (undef, $dir) = $url =~ m|([^:/]*://[^/]*/)?(.*)|; |
104
|
0
|
|
|
|
|
0
|
my @paths = split '/', $dir; |
105
|
0
|
|
|
|
|
0
|
my @offpaths = reverse split '/', $offset; |
106
|
0
|
|
|
|
|
0
|
my @corrections; |
107
|
0
|
|
|
|
|
0
|
my $result = ''; |
108
|
|
|
|
|
|
|
|
109
|
0
|
|
|
|
|
0
|
foreach (@offpaths) { |
110
|
0
|
0
|
|
|
|
0
|
if ($_ eq '..') { |
111
|
0
|
|
|
|
|
0
|
push @corrections, pop @paths; |
112
|
|
|
|
|
|
|
} else { |
113
|
0
|
|
|
|
|
0
|
$result .= '../'; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
} |
116
|
0
|
|
|
|
|
0
|
$result . join('/', reverse @corrections); |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
sub untaint { |
120
|
0
|
|
|
0
|
0
|
0
|
my @r = map { /(.*)/ } @_; |
|
0
|
|
|
|
|
0
|
|
121
|
0
|
0
|
|
|
|
0
|
@r == 1 ? $r[0] : @r; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
sub copy { |
125
|
0
|
|
|
0
|
0
|
0
|
my ($file, $dest) = @_; |
126
|
0
|
|
|
|
|
0
|
!system("/bin/cp", "-p", "-L", "-R", $file, $dest); |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
sub copy_and_own { |
129
|
0
|
|
|
0
|
0
|
0
|
my ($file, $dest_file) = @_; |
130
|
0
|
0
|
|
|
|
0
|
copy($file, $dest_file) && chown(0, 0, $dest_file) == 1; |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub move { |
134
|
0
|
|
|
0
|
0
|
0
|
my ($file, $dest) = @_; |
135
|
0
|
0
|
|
|
|
0
|
rename($file, $dest) || !system("/bin/mv", "-f", $file, $dest); |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
#- file_size is useful to write file_size(...) > 32 without having warnings if file doesn't exist |
139
|
|
|
|
|
|
|
sub file_size { |
140
|
0
|
|
|
0
|
0
|
0
|
my ($file) = @_; |
141
|
0
|
0
|
|
|
|
0
|
-s $file || 0; |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
sub same_size_and_mtime { |
145
|
0
|
|
|
0
|
0
|
0
|
my ($f1, $f2) = @_; |
146
|
|
|
|
|
|
|
|
147
|
0
|
|
|
|
|
0
|
my @sstat = stat $f1; |
148
|
0
|
|
|
|
|
0
|
my @lstat = stat $f2; |
149
|
0
|
0
|
|
|
|
0
|
$sstat[7] == $lstat[7] && $sstat[9] == $lstat[9]; |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
sub partition(&@) { |
153
|
0
|
|
|
0
|
0
|
0
|
my $f = shift; |
154
|
0
|
|
|
|
|
0
|
my (@a, @b); |
155
|
0
|
|
|
|
|
0
|
foreach (@_) { |
156
|
0
|
0
|
|
|
|
0
|
$f->($_) ? push(@a, $_) : push(@b, $_); |
157
|
|
|
|
|
|
|
} |
158
|
0
|
|
|
|
|
0
|
\@a, \@b; |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
sub begins_with { |
162
|
0
|
|
|
0
|
0
|
0
|
my ($s, $prefix) = @_; |
163
|
0
|
|
|
|
|
0
|
index($s, $prefix) == 0; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
sub formatList { |
166
|
0
|
|
|
0
|
0
|
0
|
my $nb = shift; |
167
|
0
|
0
|
|
|
|
0
|
join(", ", @_ <= $nb ? @_ : (@_[0..$nb-1], '...')); |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
0
|
0
|
|
0
|
0
|
0
|
sub add2hash_ { my ($a, $b) = @_; while (my ($k, $v) = each %{$b || {}}) { exists $a->{$k} or $a->{$k} = $v } $a } |
|
0
|
0
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
171
|
0
|
0
|
|
0
|
0
|
0
|
sub put_in_hash { my ($a, $b) = @_; while (my ($k, $v) = each %{$b || {}}) { $a->{$k} = $v } $a } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
172
|
0
|
|
|
0
|
0
|
0
|
sub uniq { my %l; $l{$_} = 1 foreach @_; grep { delete $l{$_} } @_ } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
173
|
0
|
|
|
0
|
0
|
0
|
sub difference2 { my %l; @l{@{$_[1]}} = (); grep { !exists $l{$_} } @{$_[0]} } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
174
|
0
|
|
|
0
|
0
|
0
|
sub intersection { my (%l, @m); @l{@{shift @_}} = (); foreach (@_) { @m = grep { exists $l{$_} } @$_; %l = (); @l{@m} = () } keys %l } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
175
|
1
|
50
|
|
1
|
0
|
58346
|
sub member { my $e = shift; foreach (@_) { $e eq $_ and return 1 } 0 } |
|
1
|
|
|
|
|
19
|
|
|
6
|
|
|
|
|
31
|
|
|
1
|
|
|
|
|
20
|
|
176
|
0
|
0
|
|
0
|
0
|
|
sub cat_ { my @l = map { my $F; open($F, '<', $_) ? <$F> : () } @_; wantarray() ? @l : join '', @l } |
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
177
|
0
|
0
|
|
0
|
0
|
|
sub cat_utf8 { my @l = map { my $F; open($F, '<:utf8', $_) ? <$F> : () } @_; wantarray() ? @l : join '', @l } |
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
178
|
0
|
0
|
|
0
|
0
|
|
sub wc_l { my $F; open($F, '<', $_[0]) or return; my $count = 0; while (<$F>) { $count++ } $count } |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
sub uniq_(&@) { |
181
|
0
|
|
|
0
|
0
|
|
my $f = shift; |
182
|
0
|
|
|
|
|
|
my %l; |
183
|
0
|
|
|
|
|
|
$l{$f->($_)} = 1 foreach @_; |
184
|
0
|
|
|
|
|
|
grep { delete $l{$f->($_)} } @_; |
|
0
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
} |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
sub output_safe { |
188
|
0
|
|
|
0
|
0
|
|
my ($file, $content, $o_backup_ext) = @_; |
189
|
|
|
|
|
|
|
|
190
|
0
|
0
|
|
|
|
|
open(my $f, '>', "$file.new") or return; |
191
|
0
|
0
|
|
|
|
|
print $f $content or return; |
192
|
0
|
0
|
|
|
|
|
close $f or return; |
193
|
|
|
|
|
|
|
|
194
|
0
|
0
|
0
|
|
|
|
rename($file, "$file$o_backup_ext") or return if $o_backup_ext; |
195
|
0
|
0
|
|
|
|
|
rename("$file.new", $file) or return; |
196
|
0
|
|
|
|
|
|
1; |
197
|
|
|
|
|
|
|
} |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
sub find(&@) { |
200
|
0
|
|
|
0
|
0
|
|
my $f = shift; |
201
|
0
|
|
0
|
|
|
|
$f->($_) and return $_ foreach @_; |
202
|
0
|
|
|
|
|
|
undef; |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
sub any(&@) { |
206
|
0
|
|
|
0
|
0
|
|
my $f = shift; |
207
|
0
|
|
0
|
|
|
|
$f->($_) and return 1 foreach @_; |
208
|
0
|
|
|
|
|
|
0; |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
sub append_to_file { |
212
|
0
|
|
|
0
|
0
|
|
my $f = shift; |
213
|
0
|
0
|
|
|
|
|
open(my $F, '>>', $f) or die "writing to file $f failed: $!\n"; |
214
|
0
|
|
|
|
|
|
print $F $_ foreach @_; |
215
|
0
|
|
|
|
|
|
1; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
1; |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=head1 NAME |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
urpm::util - Misc. utilities subs for urpmi |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
Mostly a subset of L |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=head1 SYNOPSIS |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
=head1 DESCRIPTION |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
=head1 COPYRIGHT |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
Copyright (C) 2005 MandrakeSoft SA |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
Copyright (C) 2005-2010 Mandriva SA |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
Copyright (C) 2011-2017 Mageia |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
=cut |