line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package MDV::Distribconf; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# $Id$ |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
our $VERSION = '4.101'; |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 NAME |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
MDV::Distribconf - Read and write config of a distribution tree |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 SYNOPSIS |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
use MDV::Distribconf; |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
my $d = MDV::Distribconf->new("/path/to/the/distribution/root"); |
16
|
|
|
|
|
|
|
$d->load() |
17
|
|
|
|
|
|
|
or die "This doesn't seem to be a distribution tree\n"; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
print $d->getpath(undef, "root") ."\n"; |
20
|
|
|
|
|
|
|
foreach ($d->listmedia) { |
21
|
|
|
|
|
|
|
printf "%s -> %s\n", $d->getpath($_, "hdlist"), $d->getpath($_, path); |
22
|
|
|
|
|
|
|
} |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
=head1 DESCRIPTION |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
MDV::Distribconf is a module to get or write the configuration of a Mageia |
27
|
|
|
|
|
|
|
distribution tree. This configuration is stored in a file called |
28
|
|
|
|
|
|
|
F, aimed at replacing the old-style F file. |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
The format of the F file is limited and doesn't allow to add new |
31
|
|
|
|
|
|
|
values without breaking compatibility, while F is designed for |
32
|
|
|
|
|
|
|
extensibility. To keep compatibility with old tools, this module is able |
33
|
|
|
|
|
|
|
to generate an F file based on F. |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
This module is able to manage both configuration of old-style trees |
36
|
|
|
|
|
|
|
(F for OS versions 10.0 and older) and of new-style ones |
37
|
|
|
|
|
|
|
(F for 10.1 and newer). |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=head1 media.cfg |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
The F is structured like a classical F<.ini> file. All |
42
|
|
|
|
|
|
|
parameters are optional; this means that a readable empty file is ok, if |
43
|
|
|
|
|
|
|
this is what you want :) |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
F contains sections, each section corresponding to a media, |
46
|
|
|
|
|
|
|
except the C<[media_info]> section wich is used to store global info. The |
47
|
|
|
|
|
|
|
section name is the (relative) path where the rpms are located. It is |
48
|
|
|
|
|
|
|
sufficient to uniquely identify a media. |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
Some values have specific signification: |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
=over 4 |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=item media specific values: |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=over 4 |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
=item B |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
The path or basename of the hdlist. By default, this is |
61
|
|
|
|
|
|
|
C, with slashes and spaces being replaced by '_'. |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=item B |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
The path or basename of the synthesis. By default, this is the hdlist |
66
|
|
|
|
|
|
|
name prefixed by C. |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
=item B |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
The path or basename of the gpg public key file. By default, this is |
71
|
|
|
|
|
|
|
the media name prefixed by C. |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=item B |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
A human-readable name for the media. By default this is the media path |
76
|
|
|
|
|
|
|
(that is, the section name), where slashes have been replaced by |
77
|
|
|
|
|
|
|
underscores. |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=item B |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
The xml file containing rpm informations. |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=item B |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
The xml file containing rpm changelogs. |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
=item B |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
The xml file containing rpm files list. |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
=back |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=item global specific values: |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=over 4 |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
=item B |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
OS version. |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=item B |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
OS branch (cauldron, etc.) |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
=item B |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
Media target architecture. |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=item B |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
The root path of the distribution tree. This value is not set in |
112
|
|
|
|
|
|
|
F, can't be owerwritten, and is only used internally. |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=item B |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
The default path relative to the 'root' path where media are |
117
|
|
|
|
|
|
|
located. MDV::Distribconf is supposed to configure this automatically |
118
|
|
|
|
|
|
|
to C or to C, depending on the OS version. |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
=item B |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
The default path relative to the 'root' path where distrib metadata |
123
|
|
|
|
|
|
|
are located. MDV::Distribconf is supposed to configure this automatically |
124
|
|
|
|
|
|
|
to C or to C, depending on the OS |
125
|
|
|
|
|
|
|
version. |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
=back |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=back |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
For the paths of the hdlist and synthesis files, if only a basename is |
132
|
|
|
|
|
|
|
provided, the path is assumed to be relative to the mediadir or infodir. |
133
|
|
|
|
|
|
|
(hdlist and synthesis are created in both directories.) If it's a complete |
134
|
|
|
|
|
|
|
path, it's assumed to be relative to the 'root'. For example, |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
hdlist.cz -> //hdlist.cz |
137
|
|
|
|
|
|
|
./hdlist.cz -> /./hdlist.cz |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
Here's a complete example of a F file: |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
# Comment |
142
|
|
|
|
|
|
|
[media_info] |
143
|
|
|
|
|
|
|
# some tools can use those values |
144
|
|
|
|
|
|
|
version=2006.0 |
145
|
|
|
|
|
|
|
branch=cauldron |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
[core] |
148
|
|
|
|
|
|
|
hdlist=hdlist_core.cz |
149
|
|
|
|
|
|
|
name=Core |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
[../SRPMS/core] |
152
|
|
|
|
|
|
|
hdlist=hdlist_core.src.cz |
153
|
|
|
|
|
|
|
name=Core Sources |
154
|
|
|
|
|
|
|
noauto=1 |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
[contrib] |
157
|
|
|
|
|
|
|
hdlist=hdlist_contrib.cz |
158
|
|
|
|
|
|
|
name=Contrib |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
[../SRPMS/contrib] |
161
|
|
|
|
|
|
|
hdlist=hdlist_contrib.src.cz |
162
|
|
|
|
|
|
|
name=Contrib Sources |
163
|
|
|
|
|
|
|
noauto=1 |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
=head1 METHODS |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=cut |
168
|
|
|
|
|
|
|
|
169
|
5
|
|
|
5
|
|
72039
|
use strict; |
|
5
|
|
|
|
|
25
|
|
|
5
|
|
|
|
|
150
|
|
170
|
5
|
|
|
5
|
|
27
|
use warnings; |
|
5
|
|
|
|
|
8
|
|
|
5
|
|
|
|
|
126
|
|
171
|
5
|
|
|
5
|
|
3964
|
use Config::IniFiles; |
|
5
|
|
|
|
|
115784
|
|
|
5
|
|
|
|
|
17160
|
|
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
sub mymediacfg_version { |
174
|
91
|
|
|
91
|
0
|
453
|
$VERSION =~ /^(\d+)\./; |
175
|
91
|
|
|
|
|
453
|
$1 |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
=head2 MDV::Distribconf->new($root) |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
Returns a new MDV::Distribconf object, C<$root> being the top level |
181
|
|
|
|
|
|
|
directory of the tree. |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
=cut |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
sub new { |
186
|
50
|
|
|
50
|
1
|
30253
|
my ($class, $path, $mediacfg_version) = @_; |
187
|
50
|
|
|
|
|
302
|
my $distrib = { |
188
|
|
|
|
|
|
|
root => $path, |
189
|
|
|
|
|
|
|
infodir => '', |
190
|
|
|
|
|
|
|
mediadir => '', |
191
|
|
|
|
|
|
|
type => '', # mdk vs mdv |
192
|
|
|
|
|
|
|
mediainfodir => '', |
193
|
|
|
|
|
|
|
cfg => new Config::IniFiles(-default => 'media_info', -allowcontinue => 1), |
194
|
|
|
|
|
|
|
}; |
195
|
|
|
|
|
|
|
|
196
|
50
|
100
|
|
|
|
5665
|
if (!defined($mediacfg_version)) { |
197
|
47
|
|
|
|
|
150
|
$distrib->{cfg}->newval('media_info', 'mediacfg_version', mymediacfg_version()); |
198
|
|
|
|
|
|
|
} |
199
|
|
|
|
|
|
|
|
200
|
50
|
|
|
|
|
7000
|
bless($distrib, $class) |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=head2 $distrib->load() |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
Finds and loads the configuration of the distrib: locate the path where |
206
|
|
|
|
|
|
|
information is found; if available loads F, if available loads |
207
|
|
|
|
|
|
|
F. |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
Returns 1 on success, 0 error (that is, if no directory containing media |
210
|
|
|
|
|
|
|
information is found, or if no F, neither F files are |
211
|
|
|
|
|
|
|
found). |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
See also L, L and L. |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
=cut |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
sub load { |
218
|
45
|
|
|
45
|
1
|
114
|
my ($distrib) = @_; |
219
|
45
|
100
|
|
|
|
113
|
$distrib->loadtree() or return 0; |
220
|
44
|
50
|
66
|
|
|
142
|
$distrib->parse_mediacfg() || $distrib->parse_hdlists() or return 0; |
221
|
44
|
|
|
|
|
233
|
return 1; |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
=head2 $distrib->loadtree() |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
Tries to find a valid media information directory, and set infodir and |
227
|
|
|
|
|
|
|
mediadir. Returns 1 on success, 0 if no media information directory was |
228
|
|
|
|
|
|
|
found. |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
=cut |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
sub loadtree { |
233
|
45
|
|
|
45
|
1
|
87
|
my ($distrib) = @_; |
234
|
|
|
|
|
|
|
|
235
|
45
|
100
|
|
|
|
1459
|
if (-d "$distrib->{root}/media/media_info") { |
|
|
100
|
|
|
|
|
|
236
|
30
|
|
|
|
|
112
|
$distrib->{infodir} = 'media/media_info'; |
237
|
30
|
|
|
|
|
59
|
$distrib->{mediadir} = 'media'; |
238
|
30
|
|
|
|
|
56
|
$distrib->{mediainfodir} = '/media_info'; |
239
|
30
|
|
|
|
|
54
|
$distrib->{type} = 'mandriva'; |
240
|
|
|
|
|
|
|
} elsif (-d "$distrib->{root}/Mandrake/base") { |
241
|
14
|
|
|
|
|
55
|
$distrib->{infodir} = 'Mandrake/base'; |
242
|
14
|
|
|
|
|
28
|
$distrib->{mediadir} = 'Mandrake'; |
243
|
14
|
|
|
|
|
25
|
$distrib->{mediainfodir} = ''; |
244
|
14
|
|
|
|
|
25
|
$distrib->{type} = 'mandrake'; |
245
|
|
|
|
|
|
|
} else { |
246
|
1
|
|
|
|
|
9
|
return 0; |
247
|
|
|
|
|
|
|
} |
248
|
44
|
|
|
|
|
155
|
return 1; |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
=head2 check_mediacfg_version($wanted_version) |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
Check that the current distrib uses this version or lesser, which means it is |
254
|
|
|
|
|
|
|
supported. |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
=cut |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
sub check_mediacfg_version { |
259
|
22
|
|
|
22
|
1
|
68
|
my ($distrib, $wanted_version) = @_; |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
# Check wanted version is <= than the module |
262
|
|
|
|
|
|
|
# Otherwise the module can't properly handle it |
263
|
22
|
50
|
|
|
|
49
|
return 0 if (mymediacfg_version() < $wanted_version); |
264
|
|
|
|
|
|
|
|
265
|
22
|
50
|
|
|
|
100
|
return 0 if ($wanted_version < $distrib->getvalue(undef, 'mediacfg_version')); |
266
|
|
|
|
|
|
|
|
267
|
22
|
|
|
|
|
794
|
return 1 |
268
|
|
|
|
|
|
|
} |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=head2 $distrib->settree($spec) |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
Virtual set the internal structure of the distrib. |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
$spec can be 'mandrake' or 'mandriva' to automatically load a know structure |
275
|
|
|
|
|
|
|
(old and new fascion, or a hashref: |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
mediadir => 'media', |
278
|
|
|
|
|
|
|
infodir => 'media/media_info', |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
=cut |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
sub settree { |
283
|
4
|
|
|
4
|
1
|
13
|
my ($distrib, $spec) = @_; |
284
|
|
|
|
|
|
|
|
285
|
4
|
100
|
100
|
|
|
29
|
if (ref($spec) eq 'HASH') { |
|
|
100
|
|
|
|
|
|
286
|
1
|
|
|
|
|
3
|
foreach (qw(infodir mediadir mediainfodir)) { |
287
|
3
|
|
100
|
|
|
13
|
$distrib->{$_} = $spec->{$_} || ''; |
288
|
|
|
|
|
|
|
} |
289
|
|
|
|
|
|
|
} elsif ($spec && $spec =~ /mandrake/i) { |
290
|
1
|
|
|
|
|
3
|
$distrib->{infodir} = 'Mandrake/base'; |
291
|
1
|
|
|
|
|
4
|
$distrib->{mediadir} = 'Mandrake'; |
292
|
1
|
|
|
|
|
3
|
$distrib->{type} = 'mandrake'; |
293
|
1
|
|
|
|
|
4
|
$distrib->{mediainfodir} = ''; |
294
|
|
|
|
|
|
|
} else { # finally it can be everything, we do not care |
295
|
2
|
|
|
|
|
7
|
$distrib->{infodir} = 'media/media_info'; |
296
|
2
|
|
|
|
|
5
|
$distrib->{mediadir} = 'media'; |
297
|
2
|
|
|
|
|
25
|
$distrib->{mediainfodir} = '/media_info'; |
298
|
2
|
|
|
|
|
26
|
$distrib->{type} = 'mandriva'; |
299
|
|
|
|
|
|
|
} |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
=head2 $distrib->parse_hdlists($hdlists) |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
Reads the F file whose path is given by the parameter $hdlist, |
306
|
|
|
|
|
|
|
or, if no parameter is specified, the F file found in the media |
307
|
|
|
|
|
|
|
information directory of the distribution. Returns 1 on success, 0 if no |
308
|
|
|
|
|
|
|
F can be found or parsed. |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=cut |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
sub parse_hdlists { |
313
|
23
|
|
|
23
|
1
|
76
|
my ($distrib, $hdlists) = @_; |
314
|
23
|
|
33
|
|
|
132
|
$hdlists ||= "$distrib->{root}/$distrib->{infodir}/hdlists"; |
315
|
|
|
|
|
|
|
|
316
|
23
|
50
|
|
|
|
1043
|
open my $h_hdlists, "<", $hdlists |
317
|
|
|
|
|
|
|
or return 0; |
318
|
23
|
|
|
|
|
237
|
$distrib->{cfg} = new Config::IniFiles( -default => 'media_info', -allowcontinue => 1); |
319
|
23
|
|
|
|
|
2605
|
my $i = 0; |
320
|
23
|
|
|
|
|
654
|
foreach (<$h_hdlists>) { |
321
|
56
|
|
|
|
|
3073
|
s/#.*//; s/^\s*//; |
|
56
|
|
|
|
|
210
|
|
322
|
56
|
|
|
|
|
111
|
chomp; |
323
|
56
|
50
|
|
|
|
127
|
length or next; |
324
|
56
|
|
|
|
|
87
|
my ($options, %media); |
325
|
56
|
|
|
|
|
494
|
($options, @media{qw(hdlist path name size)}) = /^\s*(?:(.*):)?(\S+)\s+(\S+)\s+([^(]*)(?:\s+\((\w+)\))?$/; |
326
|
56
|
100
|
|
|
|
160
|
if (!$media{hdlist}) { # Hack because hdlists format really sucks |
327
|
3
|
|
|
|
|
22
|
($options, @media{qw(hdlist path name size)}) = /^\s*(?:(.*):)?(\S+)\s+(\S+)\s+(.*)$/; |
328
|
|
|
|
|
|
|
} |
329
|
56
|
50
|
|
|
|
115
|
if ($options) { |
330
|
0
|
|
|
|
|
0
|
$media{$_} = 1 foreach split /:/, $options; |
331
|
|
|
|
|
|
|
} |
332
|
56
|
|
|
|
|
293
|
$media{name} =~ s/\s*$//; |
333
|
56
|
|
|
|
|
433
|
$media{path} =~ s!^$distrib->{mediadir}/+!!; |
334
|
56
|
50
|
|
|
|
167
|
foreach (qw(hdlist name size), $options ? split(/:/, $options) : ()) { |
335
|
168
|
50
|
|
|
|
12672
|
$distrib->{cfg}->newval($media{path}, $_, $media{$_}) |
336
|
|
|
|
|
|
|
or die "Can't set value [$_]\n"; |
337
|
|
|
|
|
|
|
} |
338
|
|
|
|
|
|
|
} |
339
|
23
|
|
|
|
|
2274
|
close($h_hdlists); |
340
|
|
|
|
|
|
|
|
341
|
23
|
|
|
|
|
190
|
return 1; |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
=head2 $distrib->parse_version($fversion) |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
Reads the F file whose path is given by the parameter $fversion, |
347
|
|
|
|
|
|
|
or, if no parameter is specified, the F file found in the media |
348
|
|
|
|
|
|
|
information directory of the distribution. Returns 1 on success, 0 if no |
349
|
|
|
|
|
|
|
F can be found or parsed. |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
=cut |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
sub parse_version { |
354
|
0
|
|
|
0
|
1
|
0
|
my ($distrib, $fversion) = @_; |
355
|
0
|
|
0
|
|
|
0
|
$fversion ||= $distrib->getfullpath(undef, 'VERSION'); |
356
|
0
|
0
|
|
|
|
0
|
open my $h_ver, "<", $fversion |
357
|
|
|
|
|
|
|
or return 0; |
358
|
0
|
|
|
|
|
0
|
my $l = <$h_ver>; |
359
|
0
|
|
|
|
|
0
|
close $h_ver; |
360
|
0
|
|
|
|
|
0
|
chomp $l; |
361
|
|
|
|
|
|
|
# XXX heuristics ahead. This breaks regularly. |
362
|
0
|
|
|
|
|
0
|
my ($version, $branch, $product, $arch) = $l =~ /^(?:mandrake|mandriva) ?linux\s+(\w+)\s+([^- ]*)-([^- ]*)-([^- ]*)/i; |
363
|
0
|
|
|
|
|
0
|
$distrib->{cfg}->newval('media_info', 'version', $version); |
364
|
0
|
|
|
|
|
0
|
$distrib->{cfg}->newval('media_info', 'branch', $branch); |
365
|
0
|
|
|
|
|
0
|
$distrib->{cfg}->newval('media_info', 'product', $product); |
366
|
0
|
|
|
|
|
0
|
$distrib->{cfg}->newval('media_info', 'arch', $arch); |
367
|
0
|
|
|
|
|
0
|
return 1; |
368
|
|
|
|
|
|
|
} |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
=head2 $distrib->parse_mediacfg($mediacfg) |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
Reads the F file whose path is given by the parameter |
373
|
|
|
|
|
|
|
$mediacfg, or, if no parameter is specified, the F file found |
374
|
|
|
|
|
|
|
in the media information directory of the distribution. Returns 1 on |
375
|
|
|
|
|
|
|
success, 0 if no F can be found or parsed. |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
=cut |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
sub parse_mediacfg { |
380
|
45
|
|
|
45
|
1
|
102
|
my ($distrib, $mediacfg) = @_; |
381
|
45
|
|
66
|
|
|
285
|
$mediacfg ||= "$distrib->{root}/$distrib->{infodir}/media.cfg"; |
382
|
|
|
|
|
|
|
(-f $mediacfg && -r _) && |
383
|
45
|
50
|
66
|
|
|
1241
|
($distrib->{cfg} = new Config::IniFiles( -file => $mediacfg, -default => 'media_info', -allowcontinue => 1)) |
|
|
|
66
|
|
|
|
|
384
|
|
|
|
|
|
|
or return 0; |
385
|
|
|
|
|
|
|
|
386
|
22
|
|
|
|
|
288384
|
return $distrib->check_mediacfg_version(mymediacfg_version()); |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
=head2 $distrib->listmedia() |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
Returns an array of existing media in the configuration |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
=cut |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
sub listmedia { |
396
|
89
|
|
|
89
|
1
|
27877
|
my ($distrib) = @_; |
397
|
89
|
|
|
|
|
268
|
return grep { $_ ne 'media_info' } $distrib->{cfg}->Sections; |
|
488
|
|
|
|
|
1946
|
|
398
|
|
|
|
|
|
|
} |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
=head2 $distrib->mediaexists($media) |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
Return true if $media exists |
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
=cut |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
sub mediaexists { |
407
|
4246
|
|
|
4246
|
1
|
6335
|
my ($distrib, $media) = @_; |
408
|
4246
|
|
100
|
|
|
7754
|
$media ||= 'media_info'; |
409
|
4246
|
|
66
|
|
|
11615
|
return ($media eq 'media_info' || $distrib->{cfg}->SectionExists($media)); |
410
|
|
|
|
|
|
|
} |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
sub _expand { |
413
|
1255
|
|
|
1255
|
|
33805
|
my ($self, $media, $value, $level) = @_; |
414
|
1255
|
100
|
|
|
|
3004
|
$value or return $value; # being lazy |
415
|
|
|
|
|
|
|
# unsupported if < 3 |
416
|
1009
|
100
|
|
|
|
1862
|
$self->getvalue(undef, 'mediacfg_version') < 3 and return $value; |
417
|
49
|
|
100
|
|
|
1255
|
$media ||= 'media_info'; |
418
|
49
|
|
100
|
|
|
179
|
$level ||= 0; # avoid infinite loop |
419
|
49
|
50
|
|
|
|
91
|
++$level >= 15 and return $value; |
420
|
|
|
|
|
|
|
|
421
|
49
|
|
|
|
|
101
|
$value =~ s@\%\{(\w+)\}@ |
422
|
3
|
100
|
|
|
|
10
|
$self->getvalue($media, $1) || '%{' . $1 . '}'; |
423
|
|
|
|
|
|
|
@eg; |
424
|
49
|
|
|
|
|
87
|
$value =~ s@\$\{(\w+)\}@ |
425
|
2
|
50
|
|
|
|
6
|
$self->getvalue('media_info', $1, $level) || '${' . $1 . '}'; |
426
|
|
|
|
|
|
|
@eg; |
427
|
|
|
|
|
|
|
|
428
|
49
|
|
|
|
|
234
|
$value |
429
|
|
|
|
|
|
|
} |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
=head2 $distrib->getvalue($media, $var) |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
Returns the $var value for $media, or C if the value is not set. |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
If $var is "name", "hdlist" or "synthesis", and if the value is not explicitly |
436
|
|
|
|
|
|
|
defined, the return value is expanded from $media. |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
If $media is "media_info" or C, you'll get the global value. |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
This function doesn't cares about path, see L for that. |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
=cut |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
sub getvalue { |
445
|
3721
|
|
|
3721
|
1
|
33985
|
my ($distrib, $media, $var, $level) = @_; |
446
|
3721
|
|
100
|
|
|
11254
|
$media ||= 'media_info'; |
447
|
|
|
|
|
|
|
|
448
|
3721
|
50
|
|
|
|
6226
|
$distrib->mediaexists($media) or return; |
449
|
|
|
|
|
|
|
|
450
|
3721
|
|
|
|
|
16213
|
my $default = ""; |
451
|
3721
|
|
|
|
|
5888
|
for ($var) { |
452
|
3721
|
100
|
|
|
|
7541
|
/^path$/ and return $media; |
453
|
3529
|
100
|
|
|
|
6440
|
/^root$/ and return $distrib->{root}; |
454
|
3284
|
100
|
|
|
|
7331
|
/^(info|files|changelog)$/ and |
455
|
|
|
|
|
|
|
return "$var." . lc($distrib->getvalue($media, 'name', $level)) . '.xml' . $distrib->getvalue(undef, 'xml-info-suffix'); |
456
|
3281
|
100
|
|
|
|
5929
|
/^synthesis$/ and do { |
457
|
2
|
|
|
|
|
6
|
$default = 'synthesis.' . lc($distrib->getvalue($media, 'hdlist', $level)); |
458
|
|
|
|
|
|
|
# If compression (suffix) chosen differs from default .cz (gzip), be sure to use corresponding suffix |
459
|
2
|
50
|
33
|
|
|
81
|
if ($default =~ /.*\.cz$/ and !($distrib->getvalue(undef, 'synthesis-suffix') eq ".cz")) { |
460
|
0
|
|
|
|
|
0
|
$default =~ s/\.cz$//g; |
461
|
0
|
|
|
|
|
0
|
$default .= $distrib->getvalue(undef, 'synthesis-suffix'); |
462
|
|
|
|
|
|
|
} |
463
|
|
|
|
|
|
|
}; |
464
|
3281
|
100
|
|
|
|
5812
|
/^synthesis-filter$/ and $default = ".cz:gzip -9"; |
465
|
3281
|
100
|
|
|
|
5903
|
/^synthesis-suffix$/ and return (split ':', $distrib->getvalue(undef, 'synthesis-filter'))[0]; |
466
|
3097
|
100
|
|
|
|
5510
|
/^xml-info-filter$/ and $default = ".lzma:lzma -5"; |
467
|
3097
|
100
|
|
|
|
6376
|
/^xml-info-suffix$/ and return (split ':', $distrib->getvalue(undef, 'xml-info-filter'))[0]; |
468
|
2548
|
100
|
|
|
|
4598
|
/^hdlist$/ and $default = 'hdlist_' . lc($distrib->getvalue($media, 'name', $level)) . '.cz'; |
469
|
2548
|
100
|
|
|
|
5857
|
/^pubkey$/ and $default = 'pubkey_' . lc($distrib->getvalue($media, 'name', $level)); |
470
|
2548
|
100
|
|
|
|
5472
|
/^(pubkey|hdlist|synthesis)$/ and do { |
471
|
55
|
|
|
|
|
241
|
$default =~ s![/ ]+!_!g; |
472
|
|
|
|
|
|
|
}; |
473
|
2548
|
100
|
|
|
|
5093
|
/^name$/ and do { |
474
|
66
|
|
|
|
|
117
|
$default = $media; |
475
|
66
|
|
|
|
|
224
|
$default =~ s![/ ]+!_!g; |
476
|
66
|
|
|
|
|
153
|
last; |
477
|
|
|
|
|
|
|
}; |
478
|
2482
|
50
|
|
|
|
4298
|
/^productid$/ and do { |
479
|
0
|
|
0
|
|
|
0
|
return join(',', map { "$_=" . ($distrib->getvalue(undef, $_) || '') } |
|
0
|
|
|
|
|
0
|
|
480
|
|
|
|
|
|
|
qw(vendor distribution type version branch release arch product)); |
481
|
|
|
|
|
|
|
}; |
482
|
|
|
|
|
|
|
/^mediacfg_version$/ and |
483
|
2482
|
100
|
100
|
|
|
6493
|
return $distrib->{cfg}->val('media_info', 'mediacfg_version') || 1; |
484
|
1185
|
100
|
|
|
|
2163
|
/^VERSION$/ and do { $default = 'VERSION'; last }; |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
7
|
|
485
|
1181
|
50
|
|
|
|
2058
|
/^product.id$/ and do { $default = 'product.id'; last }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
486
|
1181
|
50
|
|
|
|
2057
|
/^product$/ and do { $default = 'Download'; last }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
487
|
|
|
|
|
|
|
/^(MD5SUM|depslist.ordered|compss|provides)$/ |
488
|
1181
|
50
|
|
|
|
2514
|
and do { $default = $_; last }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
489
|
1181
|
50
|
|
|
|
2500
|
/^(?:tag|branch)$/ and do { $default = ''; last }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
490
|
1181
|
100
|
|
|
|
2256
|
/^(?:media|info)dir$/ and do { $default = $distrib->{$var}; last }; |
|
8
|
|
|
|
|
17
|
|
|
8
|
|
|
|
|
16
|
|
491
|
1173
|
100
|
|
|
|
2147
|
/^os$/ and do { $default = 'linux'; last; }; |
|
19
|
|
|
|
|
31
|
|
|
19
|
|
|
|
|
32
|
|
492
|
1154
|
100
|
|
|
|
2105
|
/^gnu$/ and do { $default = 1; last; }; |
|
19
|
|
|
|
|
37
|
|
|
19
|
|
|
|
|
31
|
|
493
|
1135
|
100
|
|
|
|
1960
|
/^vendor$/ and do { $default = $distrib->{type}; last; }; |
|
19
|
|
|
|
|
44
|
|
|
19
|
|
|
|
|
35
|
|
494
|
1116
|
100
|
|
|
|
2108
|
/^arch$/ and do { $default = undef; last; }; |
|
57
|
|
|
|
|
99
|
|
|
57
|
|
|
|
|
89
|
|
495
|
1059
|
100
|
|
|
|
1889
|
/^platform$/ and do { |
496
|
19
|
|
|
|
|
56
|
my $arch = $distrib->getvalue($media, 'arch'); |
497
|
19
|
50
|
|
|
|
601
|
$default = defined($arch) ? sprintf('%s-%s-%s%s', |
|
|
50
|
|
|
|
|
|
498
|
|
|
|
|
|
|
$arch, |
499
|
|
|
|
|
|
|
$distrib->getvalue($media, 'vendor'), |
500
|
|
|
|
|
|
|
$distrib->getvalue($media, 'os'), |
501
|
|
|
|
|
|
|
$distrib->getvalue($media, 'gnu') ? '-gnu' : '', |
502
|
|
|
|
|
|
|
) : undef; |
503
|
19
|
|
|
|
|
543
|
last; |
504
|
|
|
|
|
|
|
}; |
505
|
1040
|
50
|
|
|
|
1867
|
/^rpmsrate$/ and do { $default = 'rpmsrate'; last; }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
506
|
1040
|
100
|
|
|
|
1739
|
/^description$/ and do { $default = 'description'; last; }; |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
8
|
|
507
|
1036
|
50
|
|
|
|
1771
|
/^provide$/ and do { $default = 'description'; last; }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
508
|
1036
|
50
|
|
|
|
2134
|
/^depslist.ordered$/ and do { $default = 'description'; last; }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
509
|
|
|
|
|
|
|
} |
510
|
1251
|
|
|
|
|
3299
|
return $distrib->_expand($media, $distrib->{cfg}->val($media, $var, $default), $level); |
511
|
|
|
|
|
|
|
} |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
=head2 $distrib->getpath($media, $var) |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
Gives relative path of $var from the root of the distrib. This function is |
516
|
|
|
|
|
|
|
useful to know where files are actually located. It takes care of location |
517
|
|
|
|
|
|
|
of media, location of index files, and paths set in the configuration. |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
=cut |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
sub getpath { |
522
|
523
|
|
|
523
|
1
|
1941
|
my ($distrib, $media, $var) = @_; |
523
|
523
|
50
|
|
|
|
966
|
$distrib->mediaexists($media) or return; |
524
|
523
|
|
50
|
|
|
5418
|
$var ||= ""; # Avoid undef value |
525
|
523
|
100
|
|
|
|
1451
|
if ($var =~ /^(info|files|changelog)$/) { |
526
|
3
|
50
|
|
|
|
8
|
$distrib->getvalue($media, 'xml-info') or return; |
527
|
3
|
50
|
|
|
|
83
|
$distrib->getvalue($media, 'cdmode') or return; |
528
|
|
|
|
|
|
|
} |
529
|
523
|
|
|
|
|
1109
|
my $val = $distrib->getvalue($media, $var); |
530
|
523
|
100
|
|
|
|
8622
|
$var =~ /^(?:root|VERSION|product\.id|(?:media|info)dir)$/ and return $val; |
531
|
266
|
100
|
|
|
|
653
|
my $thispath = $var eq 'path' ? $distrib->{mediadir} : $distrib->{infodir}; |
532
|
266
|
100
|
|
|
|
509
|
if ($distrib->getvalue(undef, 'mediacfg_version') >= 2) { |
533
|
135
|
|
|
|
|
3949
|
return $thispath . '/' . $val; |
534
|
|
|
|
|
|
|
} else { |
535
|
|
|
|
|
|
|
return ($val =~ m!/! ? "" : |
536
|
|
|
|
|
|
|
($var eq 'path' ? $distrib->{mediadir} : $distrib->{infodir} ) |
537
|
131
|
100
|
|
|
|
4160
|
. "/") . $val; |
|
|
100
|
|
|
|
|
|
538
|
|
|
|
|
|
|
} |
539
|
|
|
|
|
|
|
} |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
=head2 $distrib->getmediapath($media, $var) |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
This function does the same than getpath except it return the path proper |
544
|
|
|
|
|
|
|
to the media for files having doble location (index for example). |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
=cut |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
sub getmediapath { |
549
|
182
|
|
|
182
|
1
|
335
|
my ($distrib, $media, $var) = @_; |
550
|
182
|
|
|
|
|
400
|
my %files = ( |
551
|
|
|
|
|
|
|
pubkey => 'pubkey', |
552
|
|
|
|
|
|
|
hdlist => 'hdlist.cz', |
553
|
|
|
|
|
|
|
synthesis => 'synthesis.hdlist' . $distrib->getvalue(undef, 'synthesis-suffix'), |
554
|
|
|
|
|
|
|
MD5SUM => 'MD5SUM', |
555
|
|
|
|
|
|
|
infodir => '', |
556
|
|
|
|
|
|
|
info => 'info.xml' . $distrib->getvalue(undef, 'xml-info-suffix'), |
557
|
|
|
|
|
|
|
files => 'files.xml' . $distrib->getvalue(undef, 'xml-info-suffix'), |
558
|
|
|
|
|
|
|
changelog => 'changelog.xml' . $distrib->getvalue(undef, 'xml-info-suffix'), |
559
|
|
|
|
|
|
|
); |
560
|
182
|
50
|
|
|
|
5813
|
$var eq 'path' and return $distrib->getpath($media, 'path'); |
561
|
182
|
100
|
|
|
|
535
|
if ($var =~ /^(info|files|changelog)$/) { |
562
|
3
|
50
|
|
|
|
9
|
$distrib->getvalue($media, 'xml-info') or return; |
563
|
3
|
50
|
|
|
|
90
|
$distrib->getvalue($media, 'cdmode') and return; |
564
|
|
|
|
|
|
|
} |
565
|
182
|
|
|
|
|
438
|
return $distrib->getpath($media, 'path') . $distrib->{mediainfodir} . "/$files{$var}"; |
566
|
|
|
|
|
|
|
} |
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
=head2 $distrib->getfullpath($media, $var) |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
Does the same thing than getpath(), but the return value will be |
571
|
|
|
|
|
|
|
prefixed by the 'root' path. This is a shortcut for: |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
$distrib->getpath(undef, 'root') . '/' . $distrib->getpath($media, $var). |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
=cut |
576
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
sub getfullpath { |
578
|
22
|
|
|
22
|
1
|
45
|
my $distrib = shift; |
579
|
22
|
50
|
|
|
|
60
|
my $path = $distrib->getpath(@_) or return; |
580
|
22
|
50
|
50
|
|
|
75
|
return $distrib->getpath(undef, 'root') if (($_[1] || '') eq 'root'); |
581
|
22
|
|
|
|
|
45
|
return $distrib->getpath(undef, 'root') . '/' . $path; |
582
|
|
|
|
|
|
|
} |
583
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
=head2 $distrib->getfullmediapath($media, $var) |
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
This function does the same than getpath except it return the path proper |
587
|
|
|
|
|
|
|
to the media for files having doble location (index for example). |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
=cut |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
sub getfullmediapath { |
592
|
10
|
|
|
10
|
1
|
20
|
my $distrib = shift; |
593
|
10
|
50
|
|
|
|
27
|
my $path = $distrib->getmediapath(@_) or return; |
594
|
10
|
|
|
|
|
25
|
return $distrib->getpath(undef, 'root') . '/' . $path; |
595
|
|
|
|
|
|
|
} |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
=head2 $distrib->getdpath($media, $var) |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
Does the same thing than getpath(), but the return always return the best for |
600
|
|
|
|
|
|
|
file having twice location (index). |
601
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
You may want to use this function to ensure you allways the good value. |
603
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
=cut |
605
|
|
|
|
|
|
|
|
606
|
|
|
|
|
|
|
sub getdpath { |
607
|
221
|
|
|
221
|
1
|
468
|
my ($distrib, $media, $var) = @_; |
608
|
|
|
|
|
|
|
|
609
|
221
|
100
|
|
|
|
1046
|
if ($var =~ /^(hdlist|synthesis|pubkey|MD5SUM|info|files|changelog)$/) { |
610
|
205
|
100
|
100
|
|
|
447
|
if ($distrib->getvalue($media, 'cdmode') |
611
|
|
|
|
|
|
|
|| $distrib->{type} eq 'mandrake') { |
612
|
38
|
|
|
|
|
193
|
return $distrib->getpath($media, $var); |
613
|
|
|
|
|
|
|
} else { |
614
|
167
|
|
|
|
|
387
|
return $distrib->getmediapath($media, $var); |
615
|
|
|
|
|
|
|
} |
616
|
|
|
|
|
|
|
} else { |
617
|
16
|
|
|
|
|
43
|
return $distrib->getpath($media, $var); |
618
|
|
|
|
|
|
|
} |
619
|
|
|
|
|
|
|
} |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
=head2 $distrib->getfulldpath($media, $var) |
622
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
Does the same thing than getfullpath(), but the return always return the best |
624
|
|
|
|
|
|
|
for file having twice location (index). |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
You may want to use this function to ensure you allways the good value. |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
=cut |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
sub getfulldpath { |
631
|
197
|
|
|
197
|
1
|
1545
|
my $distrib = shift; |
632
|
197
|
50
|
|
|
|
404
|
my $path = $distrib->getdpath(@_) or return; |
633
|
197
|
|
|
|
|
420
|
return $distrib->getpath(undef, 'root') . '/' . $path; |
634
|
|
|
|
|
|
|
} |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
1; |
638
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
__END__ |