source: soft/build_system/build_system/mkcd/tags/V4_1_1_1mdk/pm/Mkcd/Functions.pm @ 1

Last change on this file since 1 was 1, checked in by fasma, 12 years ago

Initial Import from Mandriva's soft revision 224062 and package revision 45733

File size: 84.5 KB
Line 
1#
2# Copyright (C) 2000,2001,2002,2003,2004 Mandrakesoft
3#
4# Author: Florent Villard <warly@mandraesoft.com>
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2, or (at your option)
9# any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19#
20# to prepare, create and burn iso images
21#
22
23package Mkcd::Functions;
24
25our $VERSION = '1.3.0';
26
27use strict;
28use File::Path;
29use MDK::Common qw(substInFile);
30use File::NCopy qw(copy);       
31use Mkcd::Tools qw(cpal du checkDiscs imageSize printDiscsFile config readBatchFile log_ convert_size compute_files_md5 fix_dir);
32use Mkcd::Package qw(mkcd_build_hdlist get_sorted_packages);
33
34=head1 NAME
35
36Functions - mkcd module
37
38=head1 SYNOPSYS
39
40    require Mkcd::Functions;
41
42=head1 DESCRIPTION
43
44<Mkcd::Functions> include the disc building standard functions.
45
46=head1 SEE ALSO
47
48mkcd
49
50=head1 COPYRIGHT
51
52Copyright (C) 2000,2001,2002,2003,2004 Mandrakesoft <warly@mandrakesoft.com>
53
54This program is free software; you can redistribute it and/or modify
55it under the terms of the GNU General Public License as published by
56the Free Software Foundation; either version 2, or (at your option)
57any later version.
58
59This program is distributed in the hope that it will be useful,
60but WITHOUT ANY WARRANTY; without even the implied warranty of
61MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
62GNU General Public License for more details.
63
64You should have received a copy of the GNU General Public License
65along with this program; if not, write to the Free Software
66Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
67
68=cut
69my (%functions, $config);
70
71# need to do it to have its address
72#my %functions = ();
73# [ function name, matching regexp, [arguments list (same as above)]]
74
75$functions{disc} = [ 
76    [ "", "disc", 5, "[options] <disc config number> <size> <serial> <longname> <label> <volume set>", "disc configuration file parameters", 
77    sub { my ($cd, $name, $size, $serial, $longname, $label) = @_;
78        $size = convert_size($size);
79        log_("disc: disc $cd size $size\n", $config->{verbose}, $config->{LOG},3);
80        $config->{disc}[$cd]{size} = $size;
81        $config->{disc}[$cd]{serial} = substr $serial, 0, 128;
82        $config->{disc}[$cd]{longname} = $longname;
83        $config->{disc}[$cd]{label} = substr $label, 0, 32;
84        if (!$config->{disc}[$cd]{appname}) { $config->{disc}[$cd]{appname} = substr $longname, 0, 128 }
85        1
86    }, "Setting disc configuration" ],
87    [ "d", "discnumber", 1 , "<disc real number>", "Set the real disc number", 
88    sub { my ($cd, $discnb) = @_;
89        log_("disc: disc $cd setting real disc number to $discnb\n", $config->{verbose}, $config->{LOG},3);
90        $config->{disc}[$cd]{name} = $discnb;
91    }, "Setting the real disc number" ],
92    [ "p", "publisher", 1 , "<disc publisher id>", "Set the disc publisher", 
93    sub { my ($cd, $publisher) = @_;
94        log_("disc: disc $cd setting publisher as $publisher\n", $config->{verbose}, $config->{LOG},3);
95        $config->{disc}[$cd]{Publisher} = substr $publisher, 0, 128;
96    }, "Setting the publisher ID flag" ],
97    [ "v", "volset", 1 , "<disc volume set ID>", "Set the disc volume set ID", 
98    sub { my ($cd, $volset) = @_;
99        log_("disc: disc $cd setting volset as $volset\n", $config->{verbose}, $config->{LOG},3);
100        $config->{disc}[$cd]{volset} = substr $volset, 0, 128;
101    }, "Setting the volset ID flag" ]
102];
103
104$functions{list} = [ 
105    [ "", "list", -1, "[options] <list config number> <list config file 1> <list config file 2> ... <list config file n>", "list configuration file parameters", 
106    sub { 
107        my ($list, undef, @list_file) = @_;
108        log_("list: list $list file list @list_file\n", $config->{verbose}, $config->{LOG},3);
109        push @{$config->{list}[$list]{filelist}}, @list_file;
110        1
111    }, "Setting list configuration" ],
112    [ "k", "key", 1 , "<pubkey file>", "Select public key file associated with this list", 
113    sub { my ($list, $keyfile) = @_;
114        log_("list: list $list setting pubkey file $keyfile\n", $config->{verbose}, $config->{LOG},3);
115        push @{$config->{list}[$list]{keyfiles}}, $keyfile;
116        1
117    }, "Setting pubkey file" ],
118];
119
120$functions{rpmlist} = [ 
121   [ "", "rpmlist", 0, "[options]", "rpm list associated with a list", 
122   sub { 
123       my ($list) = @_;
124       push @{$config->{list}[$list]{packages}}, { };
125       log_("rpmlist: main\n", $config->{verbose}, $config->{LOG}, 1);
126       $config->{list}[$list]{arg}{update} = 0;
127       1 
128   }, "Setting rpm list" ],
129   [ "b", "binaries", -1, "<rpm path 1> <rpm path 2> ... <rpm path n>", "rpm list associated with a list", 
130   sub { 
131       my ($list, undef, @rpms) = @_;
132       my $idx = $#{$config->{list}[$list]{packages}};
133       push @{$config->{list}[$list]{packages}[$idx]{rpm}}, @rpms;
134       log_("rpmlist: main (update $config->{list}[$list]{update})\n", $config->{verbose}, $config->{LOG}, 1);
135       if ($config->{list}[$list]{arg}{update}) {
136           foreach my $dir (@rpms) {
137               log_("rpmlist: adding for list $list update rep $dir\n", $config->{verbose}, $config->{LOG}, 1);
138               push @{$config->{list}[$list]{prelist}},  map { s/\.rpm//; [ $_, { regexp => 1 } ] } all $dir
139           }
140           push @{$config->{list}[$list]{prelist}},  [ "basesystem", { regexp => 1 } ]
141       }
142
143       1 
144   }, "Setting rpm list" ],
145   [ "d", "dynamic", -1, "<disc1/dir1> <disc2/dir2> ... <discn/dirn>", "dynamic rpm list based on disc generated by this config file", 
146   sub { 
147       my ($list, undef, @rpms) = @_;
148       foreach my $l (@rpms) {
149           my ($cd, $rep) = $l =~ m,(\d+)/(\S+), or do { log_("ERROR rpmlist: $l is not a valid <disc>/<rep> dynamic list definition\n", $config->{verbose}, $config->{LOG}, 1); next };
150           #$config->{list}[$list]{prelist} = [ [ ".*", { regexp => 1 } ] ];
151           push @{$config->{list}[$list]{virtual}}, { disc => $cd, repname => $rep };
152       }
153       1
154   }, "Setting dynamic rpm list" ],
155   [ "s", "sources", -1, "<source path 1> <source path 2> ... <source path n>", "rpm list associated with a list",
156   sub {
157       my ($list, undef, @srpms) = @_;
158       my $idx = $#{$config->{list}[$list]{packages}};
159       push @{$config->{list}[$list]{packages}[$idx]{srpm}}, @srpms;
160       1
161   }, "Setting source rpm list" ],
162   [ "u", "update", 0, "", "select all the rpm in these directories to be in the filelist",
163   sub {
164       my ($list, undef) = @_;
165       log_("rpmlist: update\n", $config->{verbose}, $config->{LOG}, 1);
166       $config->{list}[$list]{arg}{update} = 1;
167       1
168   }, "Setting update mode" ],
169
170];
171
172$functions{dir} =
173        [
174            #0
175            [ "", "dir",2, "<directory name> <directory location>", "Set directory name",
176            sub {       my ($cd, $fn, $repname, $reploc) = @_;
177                my @a = ("dir", { repname => $repname, reploc => $reploc });
178                $config->{disc}[$cd]{function}{data}{dir}{$repname} and log_("WARNING: disc $cd: duplicate directory $repname ($reploc)\n", $config->{verbose}, $config->{LOG}, 3);
179                $config->{disc}[$cd]{function}{list}[$fn] = \@a;
180                $config->{disc}[$cd]{function}{data}{dir}{$repname} = \@a;
181                log_("dir: disc $cd rep $repname ($reploc)\n", $config->{verbose}, $config->{LOG}, 3);
182                push @{$config->{disc}[$cd]{steps}}, \@a;
183                1
184            }, "Setting directory" ],
185            # 1
186            [ "", "sep_arch", 0, "", "Create separate subdirs for each architecture", sub { my ($cd, $fn) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{sep_arch} = 1 }, "Setting separate architecture flag for this dir" ]
187];
188#
189# generic options
190#
191# source => source dir
192#
193# done  => done
194#
195
196$functions{generic} =
197        [
198            # 0
199            ["", "generic", -2, "<directory name> <list1 name> <list2 name> ... <listn name>", "Copy rpms from one list or several lists to a directory. List is either a predefined list number of the configuration file or an other disc directory (e.g. 13/rpms2)",
200                sub {   
201                    my ($cd, $fn, $repname, @lists) = @_;
202                    $config->{disc}[$cd]{function}{data}{dir}{$repname} or log_("ERROR: disc $cd: $repname not defined\n", $config->{verbose}, $config->{LOG}, 0);
203                    my @a = ("generic", { repname => $repname });
204                    foreach my $list (@lists) {
205                        if ($list =~ /^\d+$/) {
206                            if (!$config->{list}[$list]) { log_("ERROR: lists $list does not exist, ignoring\n", $config->{verbose}, $config->{LOG}, 0); next }
207                            push @{$a[1]{lists}}, $list;
208                        } else {
209                            log_("ERROR generic: $list is not a valid list name for rep $cd/$repname\n", $config->{verbose}, $config->{LOG}, 0);
210                            next
211                        }
212                    }
213                    log_("generic: disc $cd repname $repname lists @lists\n", $config->{verbose}, $config->{LOG}, 3);
214                    if (!ref $a[1]{lists}) { log_("ERROR generic: $cd/$repname has no valid list, ignoring\n", $config->{verbose}, $config->{LOG}, 0); return }
215                    $config->{disc}[$cd]{function}{list}[$fn] = \@a;
216                    push @{$config->{disc}[$cd]{function}{data}{generic}{$repname}}, \@a;
217                    push @{$config->{disc}[$cd]{fastgeneric}}, \@a;
218                    push @{$config->{disc}[$cd]{steps}}, \@a;
219                    1
220                }, "Copying rpms to directory"],
221            # 1
222            ["s", "source", [
223            [ "", "source", 0, "", "Source mode configuration",
224                sub {   my ($tmp) = @_;
225                    $tmp->[0]{source} = 1;
226                }, "Source mode" ],
227# 2002 03 14 deprecated
228#           [ "p", "priority", 1, "<priority>", "Set the repository priority", sub { my ($tmp, $prio) = @_; $tmp->[0]{priority} = $prio}, "Setting source repository priority"]
229            ], "[options]", "Source mode setting",
230                sub { my ($cd, $fn, $options) = @_;
231                    foreach (keys %$options) { $config->{disc}[$cd]{function}{list}[$fn][1]{$_} = $options->{$_} }
232                    1
233                }, "Source mode option configuration"],
234            # 2
235            [ "", "synthesis", 0, "", "Add synthesis file in the repository", sub { my ($cd, $fn) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{synthesis} = 1 }, "Setting synthesis tag" ],
236            # 3
237            [ "", "hdlist", 0, "", "Add hdlist file in the repository", sub { my ($cd, $fn) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{hdlist} = 1 }, "Setting hdlist tag" ],
238            # 4
239            [ "l", "limit", [
240                [ "", "limit", 1, "<limit>", "Limit repository size",
241                    sub {       my ($tmp, $limit) = @_;
242                        $tmp->[0]{limit} = 1;
243                        $tmp->[0]{value} = $limit;
244                        1
245                    }, "Limit mode" ],
246                [ "s", "soft",0, "", "Soft mode, do not limit size if disc is not full", sub { my ($tmp) = @_; $tmp->[0]{soft} = 1 } , "Setting soft limit flag" ]
247           
248            ], "[options] <limit>", "Limit the space of this directory on the disc",
249                sub { my ($cd, $fn, $options) = @_;
250                    $config->{disc}[$cd]{function}{list}[$fn][1]{limit} = $options
251                }, "Setting limit option" ],
252            # 5
253            [ "", "nodeps", 0, "", "Do not include deps", sub { my ($cd, $fn) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{nodeps} = 1 }, "Setting nodeps flag for this generic rep" ],
254            # 6
255            [ "g", "group", 1, "<group name>", "Add this generic repository in an alone group",
256            sub { my ($cd, $fn, $group) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{group} = $group },
257            "Setting an alone group name for this generic rep" ],
258        ];
259           
260           
261#
262# installation data
263#
264$functions{installation} =
265        [
266        # 0
267            [ "", "installation", 0, "", "Preparing the installation directory and dependencies files",
268                sub {   my ($cd, $fn) = @_;
269                    my @a = ('installation', { });
270                    if (ref $config->{disc}[$cd]{function}{data}{installation}) { log_("ERROR: disc $cd: duplicate installation procedure, ignored\n", $config->{verbose}, $config->{LOG}); return 0 };
271                    $config->{disc}[$cd]{function}{list}[$fn] = \@a;
272                    $config->{disc}[$cd]{function}{data}{installation} = \@a;
273                    push @{$config->{disc}[$cd]{steps}}, \@a;
274                    1
275                }, "Setting up installation files" ],
276    # 1
277            [ "b", "bootimg", 1, "<boot image>", "boot image for the cd", sub { my ($cd, $fn, $img) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{bootimg} = $img; 1 }, "Setting boot image" ],
278    # 2
279            [ "c", "compssUsers", 1, "<compsUser file>", "Choose alternative compssUser file", sub { my ($cd, $fn, $compss) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{compssUsers} = $compss; 1 }, "Setting alternative compssUser file" ],
280    # 3
281            [ "f", "fixed", [
282                ["", "fixed", -1, "<repository> <extra RPMS directory 1> <extra RPMS directory 2> ... <extra RPMS directory n>", "Fixed repository option configuration",
283                    sub {       my ($tmp, @arg) = @_;
284                        $tmp->[0]{fixed} = 1;
285                        push @$tmp, @arg;
286                        1
287                    }, "Setting fixed option arguments"],
288                ["d", "dup", 0, "", "Duplicate mode, accept to put package present in already done discs",
289                        sub {
290                            my ($tmp) = @_;
291                            $tmp->[0]{dup} = 1; 1
292                        }, "Setting duplicate mode"],
293                ["", "noprovide", 0, "", "Do not handle other discs dependencies",
294                        sub {
295                            my ($tmp) = @_;
296                            $tmp->[0]{noprovide} = 1; 1
297                        }, "Setting noprovide mode"],
298                ["", "relocatable", 0, "", "Create virtual rep to save as much space as possible on updates discs",
299                        sub {
300                            my ($tmp) = @_;
301                            $tmp->[0]{relocatable} = 1; 1
302                        }, "Setting relocatable mode"],
303                ["", "update", 0, "", "Update mode, update already done packages",
304                        sub {
305                            my ($tmp) = @_;
306                            $tmp->[0]{update} = 1; 1 }, "Setting update mode"],
307                ["", "nodupkernel", 0, "", "Remove old kernel from hdlists",
308                        sub {
309                            my ($tmp) = @_;
310                            $tmp->[0]{nodupkernel} = 1; 1 }, "Setting nodupkernel mode"],
311                ["", "nohdlist", 0, "", "Do not generate hdlist for these media",
312                        sub {
313                            my ($tmp) = @_;
314                            $tmp->[0]{nohdlist} = 1; 1 }, "Setting nohdlist flag"],
315                ], "[options] <fixed dir 1> <fixed dir 2> ... <fixed dir n>", "repositories that must not be computed but integrated in the installation group",
316                    sub { my ($cd, $fn, $options, @fixed) = @_;
317                        get_rpmsdir('rpmsdir', $cd, $fn, \@fixed, $options);
318                        $config->{disc}[$cd]{function}{list}[$fn][1]{fixed} = 1;
319                    1 }, "Setting fixed option" ],
320            # 4 
321            [ "l", "lang", 1, "<languages to include>", "languages that are conisdered by the install", sub { my ($cd, $fn, $lang) = @_; my @l = split ',', $lang; push @{$config->{disc}[$cd]{function}{list}[$fn][1]{lang}},  @l; 1 }, "Setting language supported" ],
322            # 5
323            [ "i", "installdir", 1, "<installation directory source>", "Installation directory source", sub { my ($cd, $fn, $dir) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{install} = $dir; 1 }, "Setting install source directory" ],
324            # 6
325            [ "", "nosources", 0, "", "Do not add source rpm for this installation group", sub { my ($cd, $fn) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{nosources} = 1; 1 }, "Setting nosources tag for this installation group" ],
326            # 7
327            [ "", "nosrcfit", 0, "", "Do not stop if sources discs are full", sub { my ($cd, $fn) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{nosrcfit} = 1; 1 }, "Setting nosourcefit tag for this installation group" ],
328            # 8
329            [ "o", "sortweight", 1, "<list of respective ordering weight (size,dependencies,rpmsrate)>", "Set the weight for automatic sorting rules", sub { my ($cd, $fn, $weight) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{score} = [split ',', $weight]; 1 }, "Setting sorting weights" ],
330            # 9
331            [ "r", "rpmsrate", 1, "<rpmsrate file>", "Choose alternative rpmsrate", sub { my ($cd, $fn, $rpmsrate) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{rpmsrate} = $rpmsrate }, "Setting alternative rpmsrate file" ],
332            # 10
333            [ "t", "tag", 1, "<tag name>", "Tag added to the VERSION file", sub { my ($cd, $fn, $tag) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{tag} = $tag }, "Setting the tag name" ],
334            # 11
335            [ "", "dup", 0, "", "Authorize duplicate version for this install", sub { my ($cd, $fn) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{dup} = 1 }, "Setting the tag name" ],
336            # 12
337            [ "", "nodeps", 0, "", "Do not include deps", sub { my ($cd, $fn) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{nodeps} = 1 }, "Setting nodeps flag for this installation" ],
338            # 13
339            [ "", "isolinux", 0, "", "Isolinux mode", sub { my ($cd, $fn) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{isolinux} = 1 }, "Build an isolinux install" ],
340            # 14
341            [ "", "synthesis", 0, "", "Add synthesis file in the repository", sub { my ($cd, $fn) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{synthesis} = 1 }, "Setting synthesis tag" ],
342            # 15
343            [ "", "sequential", 0, "", "Build disc in a sequential way", sub { my ($cd, $fn) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{sequential} = 1 }, "Setting sequential tag" ],
344            # 16
345            # FIXME oem mode never tested nor debugged
346            [ "", "oem", [
347                ["", "oem", 1, "[options] <rpms dir>", "OEM mode configuration",
348                    sub {       my ($tmp, @arg) = @_;
349                        $tmp->[0]{oem} = 1;
350                        push @$tmp, @arg;
351                        1
352                    }, "Setting oem option arguments"],
353                ["d", "dir", -1, "<installation dir> <root dir 1> ... <root dir n>", "Create OEM disc based on existing directories list",
354                    sub {
355                        my ($tmp, $instdir, @dir) = @_;
356                        if ($tmp->[0]{file}) {
357                            log_("ERROR installation oem: could not use file and dir option in the same time, ignoring dir\n", $config->{verbose}, $config->{LOG});
358                            return 0 }
359                        log_("dir $instdir @dir\n", $config->{verbose}, $config->{LOG}, 3);
360                        $tmp->[0]{instdir} = $instdir;
361                        $tmp->[0]{dir} = \@dir;
362                        1 }, "Selecting directories"],
363                ["h", "hdlists", 1, "<hdlists to include>", "Select hdlists to include (all if omitted)", sub { my ($tmp, $hdlists) = @_; $tmp->[0]{hdlists} = $hdlists; 1 }, "Selecting hdlists to include"],
364                ["f", "file", 2, "<script file> <installation disc>", "Script file describing the discs (generated with printscript)",
365                    sub {
366                        my ($tmp, $file, $instdisc) = @_;
367                        if ($tmp->[0]{dir}) {
368                            log_("ERROR installation oem: could not use file and dir option in the same time, ignoring file\n", $config->{verbose}, $config->{LOG});
369                            return 0 }
370                        $tmp->[0]{file} = $file;
371                        $tmp->[0]{instdisc} = $instdisc; 1
372                    }, "Setting update mode"],
373                ["l", "listfile", 1, "<list of package to choose>", "Choose an alternative method to select package to select in OEM mode (default is to use packages with rate greater than 2 in rpmsrate ", sub { my ($tmp, $file) = @_; $tmp->[0]{file} = $file; 1 }, "Selecting list file"],
374                ["n", "norebuild", 0, "", "Do not rebuild hdlists", sub { my ($tmp, $file) = @_; $tmp->[0]{norebuild} = 1; 1 }, "Setting no rebuilding flag"],
375                ["r", "rpmsrate", 1, "<rpmsrate file>", "Rpmsrate file to use for OEM mode (use the installation one if omitted)", sub { my ($tmp, $rpmsrate) = @_; $tmp->[0]{rpmsrate} = $rpmsrate; 1 }, "Setting rpmsrate file OEM file"]
376                ], "[options] <rpms dir>", "OEM mode",
377                    sub { my ($cd, $fn, $options, $rpmsdir) = @_;
378                    $config->{disc}[$cd]{function}{list}[$fn][1]{oem}{oem} = 1;
379                    $config->{disc}[$cd]{function}{list}[$fn][1]{oem} = $options;
380                    if ($options->{dir}) {
381                        my $list = @{$config->{list}};
382                        $config->{list}[$list]{prelist} = [
383                                [ "INSTALL", { section => 1, force => 1 } ],
384                                [ "SERVER", { section => 1, regexp => 1, exclude => 1 } ],
385                                [ ".*", { section => 4, regexp => 1 } ]
386                                        ];
387                        log_("installation oem: adding list $list for OEM mode\n", $config->{verbose}, $config->{LOG}, 3);
388                        my $struct_v = $config->{struct_version};
389                        my $install_dir = $config->{struct}{$struct_v}{media_info};
390                        my $hdlists = "$options->{instdir}/$install_dir/hdlists";
391                        local *A; open A, $hdlists or die "ERROR oem: could not open hdlists $hdlists file";
392                        my $i;
393                        while (<A>) {
394                            my ($hdlist, $rep, $mname) = /(\S+)\s+(\S+)\s+(.*)/ or next;
395                            log_("$i -- $hdlist -- $rep -- $options->{dir}[$i]\n", $config->{verbose}, $config->{LOG}, 4);
396                            $options->{dir}[$i] or last;
397                            push @{$options->{hdlist}}, [ "$options->{instdir}/$install_dir/", $hdlist, $rep, $mname ];
398                            push @{$config->{list}[$list]{packages}}, [ { rpm => [ "$options->{dir}[$i]/$rep" ] } ];
399                            $i++
400                        }
401                        for ($rpmsdir) {
402                            my ($cdrep, $repname) = m,^(\d+)/([^/]+)$,;
403                            my $gfn = @{$config->{disc}[$cdrep]{function}{list}};
404                            log_("installation oem: adding function $gfn for generic oem packages on cd $cdrep\n", $config->{verbose}, $config->{LOG}, 4);
405                            $functions{generic}[0][5]($cdrep, $gfn, $repname, $list);
406                            if ($cd == $cdrep) {
407                                # FIXME trick to have this generic function done before the installation
408                                my $a = pop @{$config->{disc}[$cdrep]{steps}};
409                                unshift @{$config->{disc}[$cdrep]{steps}}, $a
410                            }
411                            push @{$config->{disc}[$cd]{function}{list}[$fn][1]{rpmsdir}}, [ $list, $cdrep, $repname, { oem => 1 } ];
412                        }
413                    } elsif ($options->{file}) {
414                        my $oemconfig;
415                        config($options->{file}, $oemconfig, \%functions);
416                        my ($discsFiles) = readBatchFile($options->{file}) or do { log_("ERROR installation oem: cannot read script file $options->{file}\n", $config->{verbose}, $config->{LOG}); return 0 };
417                        my $list = @{$config->{list}};
418                        log_("installation oem: adding list $list for OEM mode\n", $config->{verbose}, $config->{LOG}, 3);
419                        foreach (@{$config->{list}}) {
420                            $_ or next;
421                            push @{$config->{list}[$list]{packages}}, @{$_->{packages}}
422                        }
423                        my $gfn = @{$config->{disc}[$cd]{function}{list}};
424                        $config->{list}[$list]{prelist} = [[ ".*", { section => 3, regexp => 1 } ]];
425                        log_("installation oem: adding function $gfn for generic oem packages\n", $config->{verbose}, $config->{LOG}, 3);
426                        $functions{generic}[0][5]($cd, $gfn, "rpms", $list);
427                    } else {
428                        log_("ERROR installation oem: no disc to build OEM on (either file or dir option are needed)\n", $config->{verbose}, $config->{LOG});
429                        $config->{disc}[$cd]{function}{list}[$fn][1]{oem} = 0;
430                        return 0
431                    }
432                    1 }, "Setting oem option" ],
433            # 17
434            [ "s", "sources", -1, "<srpms directory name 1> <srpms directory name 2> ... <srpms directory name n>", "Select the sources list where to put packages",
435                sub { my ($cd, $fn, @sources) = @_;
436                    get_rpmsdir('srpmsdir', $cd, $fn, \@sources);
437                    $config->{disc}[$cd]{function}{list}[$fn][1]{sources} = 1;
438                    1 }, "Setting fixed option" ],
439            # 18
440            [ "d", "rpmsdir", -1, "<rpms directory 1 cd/rpms directory 1 name/rpms directory 1 list> <rpms directory 2 cd/rpms directory 2 name/rpms directory 2 list> ... <rpms directory n cd/rpms directory n name/rpms directory n list>", "Select rpms dir to take into account",
441                sub {   my ($cd, $fn, @rpms) = @_;
442                    get_rpmsdir('rpmsdir', $cd, $fn, \@rpms);
443                    1
444                }, "Setting rpms dir" ],
445            # 19
446            [ "", "boot_medium", 1, "<boot medium number>", "select alternatives boot medium",
447                sub {   my ($cd, $fn, $nb) = @_;
448                    $config->{disc}[$cd]{function}{list}[$fn][1]{boot_medium} = $nb;
449                    1
450                }, "Setting rpms dir" ],
451            # 20
452            [ "", "suppl", 0, "", "ask for new media during installation",
453                sub {   my ($cd, $fn) = @_;
454                    $config->{disc}[$cd]{function}{list}[$fn][1]{suppl} = 1;
455                    1
456                }, "Setting the suppl switch in hdlists" ],
457            # 21
458            [ "", "suppl_cd", 0, "", "to create a extra packages disc",
459                sub {   my ($cd, $fn) = @_;
460                    $config->{disc}[$cd]{function}{list}[$fn][1]{suppl_cd} = 1;
461                    1
462                }, "Setting the suppl_cd for this disk" ],
463            # 22
464            [ "", "askmedia", 0, "", "to ask which media are configured during installation",
465                sub {   my ($cd, $fn) = @_;
466                    $config->{disc}[$cd]{function}{list}[$fn][1]{askmedia} = 1;
467                    1
468                }, "Setting the askmedia for this disk" ],
469            # 23
470            [ "", "version", 1, "<version>", "Product version",
471                sub {   my ($cd, $fn, $version) = @_;
472                    $config->{disc}[$cd]{function}{list}[$fn][1]{version} = $version;
473                    1
474                }, "Setting the version" ],
475            # 24
476            [ "", "branch", 1, "<branch>", "Name of the branch (cooker, community, official, updates",
477                sub {   my ($cd, $fn, $branch) = @_;
478                    $config->{disc}[$cd]{function}{list}[$fn][1]{branch} = $branch;
479                    1
480                }, "Setting the branch name" ],
481            # 25
482            [ "", "arch", 1, "<arch>", "Name of the architecture",
483                sub {   my ($cd, $fn, $arch) = @_;
484                    $config->{disc}[$cd]{function}{list}[$fn][1]{arch} = $arch;
485                    1
486                }, "Setting the branch name" ],
487            # 26
488            [ "", "minor", 1, "<minor>", "Minor number of the version",
489                sub {   my ($cd, $fn, $minor) = @_;
490                    $config->{disc}[$cd]{function}{list}[$fn][1]{minor} = $minor;
491                    1
492                }, "Setting the minor name" ],
493            # 27
494            [ "", "subversion", 1, "<subversion>", "Subversion",
495                sub {   my ($cd, $fn, $subversion) = @_;
496                    $config->{disc}[$cd]{function}{list}[$fn][1]{subversion} = $subversion;
497                    1
498                }, "Setting the subversion name" ],
499            # 28
500            [ "", "product", 1, "<product>", "Product name",
501                sub {   my ($cd, $fn, $product) = @_;
502                    $config->{disc}[$cd]{function}{list}[$fn][1]{product} = $product;
503                    1
504                }, "Setting the product name" ],
505        ];
506#
507#
508# advertising option
509#
510#    img
511#    lang (new advertising mode in 8.2 deprecates this option)
512#   
513
514$functions{advertising} =
515        [
516            [ "", "advertising", -1, "<picture 1> <picture 2> ... <picture n>", "Setting the advertising pictures used by the installation",
517                sub { my ($cd, $fn, @img) = @_;
518                    my @a = ('advertising', { img => \@img }); 
519                    $config->{disc}[$cd]{function}{list}[$fn] = \@a;
520                    push @{$config->{disc}[$cd]{function}{data}{advertising}}, \@a;
521                    push @{$config->{disc}[$cd]{steps}}, \@a
522                }, "Setting the advertising pictures" ],
523         [ "l", "lang", 1, "<language>", "Set the advertising picture language", sub { my ($cd, $fn, $lang) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{lang} = $lang; 1 }, "Setting the picture language" ]
524];
525
526#
527# cdcom data
528#
529#      dir
530#
531#      source
532#
533$functions{cdcom} =
534         [
535         #0
536            [ "", "cdcom", 2, "<directory name> <disc directory location>", "Commercial disc",
537                sub { my ($cd, $fn, $dir, $source, @list_files) = @_;
538                    my @a = ('cdcom', { dir => $dir, source_dir => $source });
539                    $config->{disc}[$cd]{function}{list}[$fn] = \@a;
540                    push @{$config->{disc}[$cd]{function}{data}{cdcom}}, \@a;
541                    my $list = @{$config->{list}};
542                    $a[1]{list} = $list;
543                    my $struct_v = $config->{struct_version};
544                    my $media = $config->{struct}{$struct_v}{media};
545                    log_("cdcom: disc $cd adding list $list for $source/$media\n", $config->{verbose}, $config->{LOG}, 3);
546                    $config->{list}[$list]{packages} = [ { rpm => [ "$source/$media" ] } ];
547                    # $config->{list}[$list]{prelist} = [[ ".*", { regexp => 1 }]];
548                    $config->{list}[$list]{done} = 1;
549                    $config->{list}[$list]{nosize} = 1;
550                    push @{$config->{disc}[$cd]{fastgeneric}}, [ '', { repname => $dir , lists => [ $list ] } ];
551                    push @{$config->{disc}[$cd]{steps}}, \@a;
552                    1
553                }, "Configuring a commercial disc" ],
554        #1
555           [ "d", "dest", 1, "<destination on the disc>", "Select the destination directory on the disc", sub { my ($cd, $fn, $dest) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{dest} = $dest; 1 }, "Selecting destination directory" ],
556        #2
557           [ "k", "key", 1 , "<pubkey file>", "Select public key file associated with this list",
558           sub {
559               my ($cd, $fn, $keyfile) = @_;
560               my $list = $config->{disc}[$cd]{function}{list}[$fn][1]{list};
561               log_("cdcom: list $list setting pubkey file $keyfile\n", $config->{verbose}, $config->{LOG},3);
562               push @{$config->{list}[$list]{keyfiles}}, $keyfile;
563               1
564           }, "Setting pubkey file" ],
565         # 3
566            [ "", "synthesis", 0, "", "Add synthesis file in the repository",
567                sub {
568                    my ($cd, $fn) = @_;
569                    $config->{disc}[$cd]{function}{list}[$fn][1]{synthesis} = 1
570                }, "Setting synthesis tag" ],
571         # 4
572            [ "", "hdlist", 0, "", "Add hdlist file in the repository",
573                sub {
574                    my ($cd, $fn) = @_;
575                    $config->{disc}[$cd]{function}{list}[$fn][1]{hdlist} = 1
576                }, "Setting hdlist tag" ],
577];
578#
579# fixed
580#
581$functions{fixed} =
582         [
583         #0
584            [ "", "fixed", -2, "<directory name> <disc directory location> <filter list 1> <filter list 2> ... <filter list n>", "Commercial disc",
585                sub { my ($cd, $fn, $dir, $source, @list_files) = @_;
586                    my @a = ('fixed', { dir => $dir, source_dir => $source, repname => $dir, fixed => 1});
587                    $config->{disc}[$cd]{function}{list}[$fn] = \@a;
588                    push @{$config->{disc}[$cd]{function}{data}{fixed}}, \@a;
589                    my $list = @{$config->{list}};
590                    # FIXME something must be duplicated here
591                    $a[1]{list} = $list;
592                    $a[1]{lists} = [ $list ];
593                    log_("fixed: disc $cd adding list $list for $source\n", $config->{verbose}, $config->{LOG}, 3);
594                    $config->{list}[$list]{packages} = [ { rpm => [ $source ] } ];
595                    # $config->{list}[$list]{prelist} = [[ ".*", { regexp => 1 }]];
596                    $config->{list}[$list]{pseudo_done} = 1;
597                    $config->{list}[$list]{nosize} = 1;
598                    $config->{list}[$list]{fixed} = 1;
599                    push @{$config->{list}[$list]{filelist}}, @list_files;
600                    push @{$config->{disc}[$cd]{fastgeneric}}, \@a;
601                    push @{$config->{disc}[$cd]{steps}}, \@a;
602                    1
603                }, "Configuring a fixed disc" ],
604        #1
605           [ "d", "dest", 1, "<destination on the disc>", "Select the destination directory on the disc", sub { my ($cd, $fn, $dest) = @_; $config->{disc}[$cd]{function}{list}[$fn][1]{dest} = $dest; 1 }, "Selecting destination directory" ],
606        #2
607           [ "k", "key", 1 , "<pubkey file>", "Select public key file associated with this list",
608           sub {
609               my ($cd, $fn, $keyfile) = @_;
610               my $list = $config->{disc}[$cd]{function}{list}[$fn][1]{list};
611               log_("fixed: list $list setting pubkey file $keyfile\n", $config->{verbose}, $config->{LOG},3);
612               push @{$config->{list}[$list]{keyfiles}}, $keyfile;
613               1
614           }, "Setting pubkey file" ],
615         # 3
616            [ "", "synthesis", 0, "", "Add synthesis file in the repository",
617                sub {
618                    my ($cd, $fn) = @_;
619                    $config->{disc}[$cd]{function}{list}[$fn][1]{synthesis} = 1
620                }, "Setting synthesis tag" ],
621         # 4
622            [ "", "hdlist", 0, "", "Add hdlist file in the repository",
623                sub {
624                    my ($cd, $fn) = @_;
625                    $config->{disc}[$cd]{function}{list}[$fn][1]{hdlist} = 1
626                }, "Setting hdlist tag" ],
627        # 5
628            [ "", "nodeps", 0, "", "Do not include deps",
629                sub {
630                    my ($cd, $fn) = @_;
631                    $config->{disc}[$cd]{function}{list}[$fn][1]{nodeps} = 1
632                }, "Setting nodeps flag for this fixed rep" ],
633];
634#
635# cp
636#
637$functions{cp} =
638        [
639            [ "", "cp", 2, "<file source> <file destination>", "Copy",
640                sub { my ($cd, $fn, $src, $dest) = @_;
641                    my @a = ('cp', { src => $src, dest => $dest });
642                    $config->{disc}[$cd]{function}{list}[$fn] = \@a;
643                    push @{$config->{disc}[$cd]{function}{data}{cp}}, \@a;
644                    push @{$config->{disc}[$cd]{steps}}, \@a;
645                    1
646        }, "Copying files" ],
647     # 1
648        [ "", "first", 0, "", "Remove files in the files copied with first option",
649            sub {
650                my ($cd, $fn) = @_;
651                $config->{disc}[$cd]{function}{list}[$fn][1]{first} = 1;
652                1
653            }, "Setting first flag"
654        ],
655];
656 #
657 # boot
658 #
659$functions{boot} =
660    [
661    # 0
662        [ "", "boot", 0, "<options> <files or dir to copy 1> <files or dir to copy 2> .. <files or dir to copy 3>", "Boot parameters and files",
663            sub {   my ($cd, $fn) = @_;
664                    my @a = ('boot', { });
665                    $config->{disc}[$cd]{function}{list}[$fn] = \@a;
666                    push @{$config->{disc}[$cd]{function}{data}{boot}}, \@a;
667                    push @{$config->{disc}[$cd]{steps}}, \@a;
668                    1
669          }, "Setting boot parameters"
670        ],
671          # 1
672        [ "", "isolinux", [
673                ["", "isolinux", 0, "", "Create an isolinux bootable disc",
674                    sub {       
675                        my ($tmp, @args) = @_;
676                        $tmp->[0]{isolinux} = 1;
677                        push @$tmp, @args
678                    }, "Setting an isolinux boot disc"],
679                ], "<options>", "isolinux boot disc",
680                    sub { my ($cd, $fn, $options) = @_;
681                        foreach (@{ $config->{disc}[$cd]{function}{data}{boot} }) {
682                                if (ref $_->[1]{isolinux}) { log_("ERROR: disc $cd: duplicate isolinux boot image, ignored\n", $config->{verbose}, $config->{LOG}); return 0 }
683                        }
684                        $config->{disc}[$cd]{function}{list}[$fn][1]{isolinux} = [ $options ]
685                    }, "Setting isolinux image"
686        ],
687          #2
688        [ "b", "bootimg", [
689            [ "", "bootimg", 1, "<boot image name>", "set boot image name",
690                    sub { my ($tmp, @args) = @_;
691                        $tmp->[0]{bootimg} = 1;
692                        push @$tmp, @args
693                    }, "setting boot image name"
694            ],
695            [ "d", "dir", 1, "<directory>", "duplicate the boot image in directory and put it first in the ISO",
696               sub { my ($tmp, $dir) = @_; $tmp->[0]{dir} = $dir }, "" 
697            ]
698                ], "<options> <boot image>", "Create a bootable iso with given image",
699                    sub { my ($cd, $fn, $options, $img) = @_;
700                        foreach (@{ $config->{disc}[$cd]{function}{data}{boot} }) {
701                                if (ref $_->[1]{bootimg}) { log_("ERROR: disc $cd: duplicate boot image, ignored\n", $config->{verbose}, $config->{LOG}); return 0 }
702                        }
703                        $config->{disc}[$cd]{function}{list}[$fn][1]{bootimg} = [ $img, $options ]
704                    }, "Setting boot image options"
705        ],
706          #3
707        [ "f", "files", [
708                [ "", "files", -1, "<file 1> <file 2> .. <file n>", "Set options for files copied",
709                    sub {
710                        my ($tmp, @args) = @_;
711                        $tmp->[0] = {};
712                        push @$tmp, @args
713                    }, "Setting files options" ],
714                [ "", "first", 0 , "", "Put this files first in the ISO",
715                        sub {
716                            my ($tmp) = @_;
717                            $tmp->[0]{first} = 1;
718                            1
719                        }, "Setting first flag for files" ],
720                [ "d", "dest", 1 , "<destination on the targe disc>", "Choose where to copy the files",
721                        sub {
722                            my ($tmp, $dest) = @_;
723                            $tmp->[0]{dest} = $dest;
724                            1
725                        }, "Setting destination location for files" ],
726            ], "[options] <files 1> <files 2> .. <files n>", "Setting files to copy",
727                sub { my ($cd, $fn, $options, @files) = @_;
728                    foreach (fix_dir(@files)) {
729                        log_("boot: file $_ (to $options->{dest})\n", $config->{verbose}, $config->{LOG});
730                        push @{$config->{disc}[$cd]{function}{list}[$fn][1]{files}}, [ $_, $options ]
731                    }
732                    1
733                },
734            "Setting files to copy"
735            ],
736        #4
737        [ "", "oem", 0, "", "Set default boot to oem mode",
738            sub { my ($cd, $fn) = @_;
739                $config->{disc}[$cd]{function}{list}[$fn][1]{oem} = 1
740            }, "Setting oem boot mode"
741        ],
742
743];
744
745#
746# clone
747#
748$functions{clone} =
749    [
750    # 0
751        [ "", "clone", 1, "<disc to clone>", "Clone the given disc",
752            sub {   my ($cd, $fn, $disc) = @_;
753                    my @a = ('clone', { disc => $disc });
754                    $config->{disc}[$cd]{function}{list}[$fn] = \@a;
755                    push @{$config->{disc}[$cd]{function}{data}{clone}}, \@a;
756                    push @{$config->{disc}[$cd]{steps}}, \@a;
757                    1
758          }, "Setting clone parameters"
759        ],
760          # 1
761        [ "i", "include", -2, "<directory name 1> <directory path 1> <directory name 2> <directory path 2> ... <directory name n> <directory path n>", "include declaration of copied directory",
762            sub {   my ($cd, $fn, @dir) = @_;
763                    my $list = @{$config->{list}};
764                    while (@dir) {
765                        my $rpmdir = shift @dir;
766                        my $path = shift @dir or last;
767                        $config->{disc}[$cd]{function}{data}{dir}{$rpmdir} = [ "clone_dir", { reploc => $path } ];
768                        $config->{disc}[$cd]{function}{list}[$fn][1]{rpmsdir} = $path;
769                        log_("clone: disc $cd adding list $list for virtual rep $rpmdir path $path\n", $config->{verbose}, $config->{LOG},3);
770                        $config->{list}[$list]{virtual} = [ { disc => $cd, repname => $rpmdir } ];
771                        push @{$config->{disc}[$cd]{fastgeneric}}, [ '', { repname => $rpmdir, lists => [ $list ] } ];
772                    }
773                    $config->{list}[$list]{done} = 1;
774                    1
775            }, "Setting directory name and path parameters"
776        ]
777#       [ "d", "delete", -1, "<function 1 nb to delete> <function 1 nb to delete> ... <function n nb to delete>", "delete these functions in the cloned disc",
778#           sub {   my ($cd, $fn,@to_del) = @_;
779#                   $config->{disc}[$cd]{function}{list}[$fn][1]{to_del} = \@to_del;
780#                   1
781#           }, "Setting delete parametes"
782#       ]
783];
784
785#
786# rm
787#
788$functions{rm} =
789    [
790     # 0
791        [ "", "rm", -1, "<disc to rm>", "Delete the given file or directory on the disc image",
792            sub {   my ($cd, $fn, @files) = @_;
793                    my @a = ('rm', { files => \@files });
794                    $config->{disc}[$cd]{function}{list}[$fn] = \@a;
795                    push @{$config->{disc}[$cd]{function}{data}{files}}, \@a;
796                    push @{$config->{disc}[$cd]{steps}}, \@a;
797                    1
798          }, "Setting rm parameters"
799        ],
800     # 1
801        [ "", "first", 0, "", "Remove files in the files copied with first option",
802            sub {
803                my ($cd, $fn) = @_;
804                $config->{disc}[$cd]{function}{list}[$fn][1]{first} = 1;
805                1
806            }, "Setting first flag"
807        ],
808];
809
810sub new {
811    my ($class, $conf) = @_;
812    $config = $conf;
813    bless {
814        config       => $conf,
815        functions    => \%functions
816    }, $class;
817}
818
819sub get_rpmsdir {
820    my ($type, $cd, $fn, $rpms, $opts) = @_;
821    my $options = '(?:(noauto):)?';
822    # FIXME taken from Tools.pm
823    my $match_val2 = q(((?:[^"\s]*(?:[^"\s]+|"[^\"]+")[^"\s]*)+));
824    foreach (@$rpms)  {
825        log_("get_rpmsdir: $_\n", $config->{verbose}, $config->{LOG}, 3);
826        my %options;
827        foreach (keys %$opts)  { $options{$_} = $opts->{$_} }
828        if (my ($opt, $hdlist, $hdlist_path, $hdlist_name, $pubkey) = m/${options}hdlist:([^,]+),([^,]+),$match_val2(?:,(.*))?/) {
829            if (!$config->{disc}[$cd]{function}{list}[$fn][1]{fixed}) {
830                $config->{disc}[$cd]{function}{list}[$fn][1]{fixed} = 1;
831                log_("WARNING get_rpmsdir: hdlist rpmsdir could only be fixed, forcing fixed flag\n", $config->{verbose}, $config->{LOG}, 0);
832            }
833            my $list = add_list($cd, "hdlist_rpm", $hdlist, $pubkey);
834            my $new_cd = @{$config->{disc}};
835            log_("get_rpmsdir: adding virtual disc $new_cd for hdlist $hdlist (path $hdlist_path disc_name $hdlist_name)\n", $config->{verbose}, $config->{LOG}, 3);
836            push @{$config->{virtual_disc}}, $new_cd;
837            $functions{disc}[0][5]->($new_cd, $hdlist_name, 0, 0, $hdlist_name, 0);
838            $functions{dir}[0][5]->($new_cd, 1, "rpms", $hdlist_path);
839            $functions{generic}[0][5]->($new_cd, 2, "rpms", $list);
840            $options{hdlist} = $hdlist;
841            foreach (split ',', $opt)  { $options{$_} = 1 }
842            push @{$config->{disc}[$cd]{function}{list}[$fn][1]{$type}}, [ $list, $new_cd, 'rpms', \%options ]
843        } elsif (my ($opt, $cdrep, $repname, $list) = m,$options(\d+)/([^/]+)(?:/(\d+))?,) {
844            foreach (split ',', $opt)  { $options{$_} = 1 }
845            push @{$config->{disc}[$cd]{function}{list}[$fn][1]{$type}}, [ $list, $cdrep, $repname, \%options ]
846        } else {
847            log_("ERROR get_rpmsdir: could not parse rpmsdir value $_\n", $config->{verbose}, $config->{LOG}, 0);
848        }
849    }
850}
851
852sub add_list {
853    my ($cd, $type, $pkg_list, $pubkey) = @_;
854    my $list = @{$config->{list}};
855    log_("add_list: disc $cd adding list $list for $type $pkg_list\n", $config->{verbose}, $config->{LOG}, 3);
856    $config->{list}[$list]{packages} = [ { $type => [ $pkg_list ] } ];
857    $config->{list}[$list]{done} = 1;
858    $config->{list}[$list]{nosize} = 1;
859    if ($pubkey) {
860        log_("add_list: adding pubkey file $pubkey for list $list\n", $config->{verbose}, $config->{LOG}, 3);
861        push @{$config->{list}[$list]{keyfiles}}, $pubkey;
862    }
863    $list
864}
865
866sub template {
867    my ($class, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discsFiles) = @_;
868    if (!$fixed) {
869        my $size;
870        if ($nolive) {
871            return $size
872        } else {
873
874        }
875    } elsif ($fixed == 1) {
876        my $mkiso;
877        if ($nolive) {
878        } else {
879           
880        }
881    } elsif ($fixed == 2) {
882        my $mkiso;
883        if ($nolive) {
884        } else {
885           
886        }
887    }   
888}
889
890sub clone {
891    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discsFiles) = @_;
892    my $graft = $totgraft->{$cdnum};
893    my $disc_src = $fct->[1]{disc};
894    if ($fixed == 0) {
895        if ($nolive) {
896            if ($fct->[1]{full_copy}) {
897                log_("clone: full copy of disc $disc_src nolive mode\n", $config->{verbose}, $config->{LOG},2);
898                if ($totgraft->{$disc_src}) {
899                    log_("clone: getting disc from current build\n", $config->{verbose}, $config->{LOG},3);
900                    $graft = $totgraft->{$disc_src}
901                } elsif (-d "$dir/$disc_src") {
902                    log_("clone: getting disc from filesystem\n", $config->{verbose}, $config->{LOG},3);
903                    $graft->{"/"}{"$dir/$disc_src"} = 1
904                } else {
905                    log_("ERROR clone: source disc not available\n", $config->{verbose}, $config->{LOG},3);
906                }
907            }
908        } else {
909            if ($fct->[1]{full_copy}) {
910                log_("clone: full copy of disc $disc_src\n", $config->{verbose}, $config->{LOG},2);
911                if (-d "$dir/$disc_src") {
912                    log_("clone: getting disc from filesystem\n", $config->{verbose}, $config->{LOG},3);
913                    $graft->{"/"}{"$dir/$disc_src"} = undef;
914                    cpal("$dir/$disc_src/", "$dir/$cdnum");
915                } else {
916                    log_("ERROR clone: source disc not available\n", $config->{verbose}, $config->{LOG},3);
917                }
918            }
919        }
920    }
921    1
922}
923
924sub rm {
925    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discsFiles) = @_;
926    my $graft = $totgraft->{$cdnum};
927    my $files = $fct->[1]{files};
928#    use File::Find;
929    if ($fixed == 0) {
930        if ($nolive) {
931            # FIXME this does not really works in no live mode (exclude files does not work with mkisofs properly)
932            my $size;
933            foreach my $r (@$files) {
934                log_("rm: trying $r\n", $config->{verbose}, $config->{LOG},2);
935                $r = "/$r" if $r !~ m,^/,;
936                #$graft->{$r} = 3;
937                $r =~ s/\*/.+/;
938                foreach my $g (keys %$graft) {
939                    ref $graft->{$g} or next;
940                    log_("rm: graft $g ($r)\n", $config->{verbose}, $config->{LOG},3);
941                    if ($g =~ m,^/?$r/?$,) {
942                        foreach my $f (keys %{$graft->{$g}}) {
943                             $size -= du $f
944                        }
945                        $g =~ m,^/, and $g = "/$g";
946                        $graft->{$g} = 0;
947                        log_("rm: deleting $g (size $size)\n", $config->{verbose}, $config->{LOG},4);
948                    }
949                }
950                my @up = grep { $_ } split '/', $r;
951                my $last = pop @up;
952                while (@up) {
953                    my $uppath = join '/', @up;
954                    $uppath = "/$uppath";
955                    log_("rm: testing $uppath\n", $config->{verbose}, $config->{LOG},4);
956                    $uppath = $graft->{$uppath} ? $uppath : $graft->{"/$uppath"} ? "/$uppath" : $graft->{"$uppath/"} ? "$uppath/" : "/$uppath/";
957                    log_("rm: graft $graft->{$uppath}\n", $config->{verbose}, $config->{LOG},4);
958                    if (ref $graft->{$uppath}) {
959                        foreach (keys %{$graft->{$uppath}}) {
960                            log_("rm: testing $uppath ($_)\n", $config->{verbose}, $config->{LOG},4);
961                            if (-d $_) {
962                                log_("rm: opening $_\n", $config->{verbose}, $config->{LOG},4);
963                                opendir my $dir, $_ or next;
964                                foreach my $first (readdir $dir) {
965                                    $first =~ /^\.{1,2}$/ and next;
966                                    log_("rm: FIRST 2 $first in $uppath$first ($r) " . $graft->{"$uppath$first"} . "\n", $config->{verbose}, $config->{LOG},4);
967                                    if ("$uppath$first" ne $r) {
968                                        log_("rm: adding $_/$first in $uppath\n", $config->{verbose}, $config->{LOG},4);
969                                        $graft->{"$uppath$first"} ||= {};
970                                        $graft->{"$uppath$first"}{"$_/$first"} = 1;
971                                    }
972                                }
973                                delete $graft->{$uppath}{$_}
974                            }
975                        }
976                        last
977                    }
978                    $last = pop @up;
979                }
980            }
981#           my @find;
982#           foreach my $k (keys %$graft){
983#               ref $graft->{$k} or next;
984#               foreach my $f (keys %{$graft->{$k}}){
985#                   $f =~ s|/{2,}|/|g;
986#                   find({ wanted => sub { s,/?\Q$f,,; $_ = "$k/$_"; s|/{2,}|/|g; push @find, [ $f, $_ ] }, no_chdir => 1 }, $f);
987#               }
988#           }
989#           foreach (@$files) { s|/{2,}|/|g }
990#           foreach my $t (@find){
991#               my ($k, $f) = @$t;
992#               foreach my $r (@$files){
993#                   next if $f =~ m,^/?$r/[^/]+,;
994#                   if ($f =~ m,^/?$r/?$,){
995#                       log_("rm: deleting $f (path $k regexp $r)\n", $config->{verbose}, $config->{LOG});
996#                       $graft->{$f} = 0;
997#                       $size -= du $k;
998#                       $size -= du "$k/$f";
999#                   }
1000#               }
1001#           }
1002            return $size
1003        } else {
1004            my $first = "first/" if $fct->[1]{first};
1005            foreach (@$files) {
1006                my @file = glob "$dir/$first$cdnum/$_";
1007                foreach my $f (@file) {
1008                    if (-d $f) {
1009                        log_("rm: deleting directory $f\n", $config->{verbose}, $config->{LOG}, 2);
1010                        my $err = rmtree $f;
1011                        if (!$err) { log_("ERROR rm: deleting $f failed: $!,\n", $config->{verbose}, $config->{LOG}) }
1012                    } else {
1013                        log_("rm: deleting file $f\n", $config->{verbose}, $config->{LOG},2);
1014                        my $err = unlink $f;
1015                        if (!$err) { log_("ERROR rm: deleting $f failed: $!,\n", $config->{verbose}, $config->{LOG}) }
1016                    }
1017                }
1018            }
1019            return 
1020        }
1021    }
1022    1
1023}
1024
1025sub cp {
1026    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discsFiles, $sort) = @_;
1027    my $graft = $totgraft->{$cdnum};
1028    if (!$fixed) {
1029        my $size;
1030        my $source = $fct->[1]{src};
1031        my $dest = $fct->[1]{dest};
1032        if ($nolive) {
1033            $size += du($source, $inode);
1034            log_("cp: copying $source => $dest (size $size)\n", $config->{verbose}, $config->{LOG},1);
1035            $graft->{"/$dest"}{$source} = 1;
1036            return $size
1037        } else {
1038            my $first = "first/" if $fct->[1]{first};
1039            cpal($source, "$dir/$first$cdnum/$dest");
1040            $graft->{"$dir/$cdnum/$dest"}{$source} = 1;
1041            push @{$sort->{$cdnum}}, [ "$dir/$first$cdnum/$dest" ] if $fct->[1]{first};
1042            return
1043        }
1044    }
1045}
1046
1047sub fixed {
1048    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discs_file, $sort, $cdsize) = @_;
1049    my $graft = $totgraft->{$cdnum};
1050    my $destination = $fct->[1]{dest};
1051    my ($fdest, $nocopy);
1052    my $rep = $fct->[1]{dir}; 
1053    my $list = $fct->[1]{list};
1054    my $dest_dir = $cd->{function}{data}{dir}{$rep}[1];
1055    my $reploc = $dest_dir->{reploc};
1056    my $reploc_full = "$dir/$cdnum/$reploc/";
1057    if ($destination) {
1058        $fdest = "$dir/$cdnum/$destination";
1059    } else {
1060        $fdest = "$dir/$cdnum/$reploc";
1061        $nocopy = 1
1062    }
1063    my $size;
1064    if (!$fixed) {
1065        my $source = $fct->[1]{source_dir};
1066        my $uppath = $destination;
1067        $uppath =~ s,([^/]+),../,g;
1068        $uppath =~ s,/+,/,g;
1069        log_("DEST: $destination uppath $uppath dest $reploc_full\n", $config->{verbose}, $config->{LOG},3);
1070        -d $fdest or mkpath $fdest;
1071        if ($nolive) {
1072            -d $reploc_full or mkpath $reploc_full;
1073            opendir my $A, $source;
1074            log_("fixed: $source\n", $config->{verbose}, $config->{LOG},3);
1075            my $struct_v = $config->{struct_version};
1076            my $media = $config->{struct}{$struct_v}{media};
1077            my $install_dir = $config->{struct}{$struct_v}{install};
1078            foreach (readdir $A) {
1079                /^\.{1,2}$/ and next;
1080                if (! /^$install_dir$/) {
1081                    $size += du("$source/$_", $inode);
1082                    log_("fixed: adding $_ (size $size)\n", $config->{verbose}, $config->{LOG},4);
1083                    $graft->{"/$destination/$_/"}{"$source/$_"} = 1
1084                } else {
1085                    $graft->{"/$reploc/"}{"$source/$media/"} = 1
1086                }
1087            }
1088            log_("fixed: creating symlink $uppath$reploc => $fdest/RPMS\n", $config->{verbose}, $config->{LOG}, 4);
1089            my $err = symlink "$uppath$reploc", "$fdest/RPMS";                                           
1090            !$err and log_("ERROR fixed: $!\n", $config->{verbose}, $config->{LOG});
1091            $graft->{"/"}{"$fdest/RPMS"} = 1;
1092            $cdsize->{real}{rep}{$cdnum}{$rep}{$list} = $size
1093        } else {
1094            log_("fixed: copying $source to $fdest\n", $config->{verbose}, $config->{LOG});
1095            cpal($source, $fdest);
1096            if (!$nocopy) {
1097                log_("fixed: creating symlink $uppath$reploc => $fdest/RPMS\n", $config->{verbose}, $config->{LOG});
1098                my $err = symlink "$uppath$reploc", "$fdest/RPMS";                                           
1099                !$err and log_("ERROR fixed: $!\n", $config->{verbose}, $config->{LOG});
1100            }
1101            $cdsize->{real}{rep}{$cdnum}{$rep}{$list} = du($source)
1102        }
1103        log_("fixed: real rep cd $cdnum rep $rep list $list size $cdsize->{real}{rep}{$cdnum}{$rep}{$list}\n", $config->{verbose}, $config->{LOG}, 8);
1104        return $size
1105    } else {
1106        # there is only one (virtual) list for fixed
1107        my $list = $fct->[1]{list};
1108        log_("fixed: list $list\n", $config->{verbose}, $config->{LOG});
1109        my $rep = $fct->[1]{dir}; 
1110        my $sep_arch = $dest_dir->{sep_arch};
1111        my $nolive_rep = $reploc;
1112        if ($nolive) {
1113            if (!$nocopy) {
1114                foreach my $src (keys %{$cdfile->[$cdnum]{$rep}{$list}}) {
1115                    log_("fixed: src $src\n", $config->{verbose}, $config->{LOG});
1116                    foreach (@{$cdfile->[$cdnum]{$rep}{$list}{$src}}) {
1117                        $graft->{"$nolive_rep/$_->[1]"}{"$src/$_->[1]"} = 1
1118                    }
1119                }
1120            }
1121        } else {
1122            if (!$nocopy) {
1123                foreach my $src (keys %{$cdfile->[$cdnum]{$rep}{$list}}) {
1124                    log_("fixed: src $src\n", $config->{verbose}, $config->{LOG});
1125                    foreach (@{$cdfile->[$cdnum]{$rep}{$list}{$src}}) {
1126                        link("$fdest/$_->[1]", "$reploc_full/$_->[1]") 
1127                    }
1128                }
1129            }
1130        }
1131        $size += process_hdlist_flags($nolive, $fct->[1]{synthesis}, $fct->[1]{hdlist}, $discs_file->[$cdnum]{$rep}{$list}, $dir, $cdnum, $fct, $rep, $reploc_full, $sep_arch, $graft, $list, $reploc);
1132        $size
1133    }
1134}
1135
1136sub cdcom {
1137    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discs_file) = @_;
1138    my $graft = $totgraft->{$cdnum};
1139    if (!$fixed) {
1140        my $size;
1141        my $source = $fct->[1]{source_dir};
1142        my $dest = $config->{disc}[$cdnum]{function}{data}{dir}{$fct->[1]{dir}}[1]{reploc};
1143        my $destination = $fct->[1]{dest};
1144        my $uppath = $destination;
1145        $uppath =~ s,([^/]+),../,g;
1146        $uppath =~ s,/+,/,g;
1147        log_("DEST: $destination uppath $uppath dest $dest\n", $config->{verbose}, $config->{LOG},3);
1148        my $fdest = "$dir/$cdnum/$destination";
1149        my $struct_v = $config->{struct_version};
1150        my $media = $config->{struct}{$struct_v}{media};
1151        my $install_dir = $config->{struct}{$struct_v}{install};
1152        if ($nolive) {
1153            my $path = "$dir/$cdnum/$dest";
1154            -d $path or mkpath $path;
1155            opendir my $A, $source;
1156            log_("cdcom: $source\n", $config->{verbose}, $config->{LOG},3);
1157            foreach (readdir $A) {
1158                /^\.{1,2}$/ and next;
1159                if (! /^$install_dir$/) {
1160                    $size += du("$source/$_", $inode);
1161                    log_("cdcom: adding $_ (size $size)\n", $config->{verbose}, $config->{LOG},4);
1162                    $graft->{"/$destination/$_/"}{"$source/$_"} = 1
1163                } else {
1164                    $graft->{"/$dest/"}{"$source/$media/"} = 1
1165                }
1166            }
1167            #local *A; opendir A, "$source/Mandrake/RPMS";
1168            #foreach (readdir A){
1169            #    /^\.{1,2}$/ and next;
1170            #    my $newdest = readlink "$source/Mandrake/RPMS/$_";
1171            #    $newdest =~ s,((?:../))*(.*), $1/$destination/$2,;
1172            #    log_("cdcom: creating symlink $dest/$_ => $newdest\n", $config->{verbose}, $config->{LOG});
1173            #    my $err = symlink $newdest, "$dir/$cdnum/$dest/$_";
1174            #    !$err and log_("ERROR cdcom: $!\n", $config->{verbose}, $config->{LOG}) and next;
1175            #    $graft->{"/$dest/"}{"$dir/$cdnum/$dest/$_"} = 1
1176            #}
1177            #$graft->{"/$dest/"}{"$source/Mandrake/RPMS"} = 1;
1178            log_("cdcom: creating symlink $uppath$dest => $fdest/RPMS\n", $config->{verbose}, $config->{LOG}, 4);
1179            -d $fdest or mkpath $fdest;
1180            my $err = symlink "$uppath$dest", "$fdest/RPMS";                                           
1181            !$err and log_("ERROR cdcom: $!\n", $config->{verbose}, $config->{LOG});
1182            $graft->{"/"}{"$fdest/RPMS"} = 1;
1183            return $size
1184        } else {
1185            -f $fdest or mkpath $fdest;
1186            cpal($source, $fdest, $media);
1187            local *A; opendir A, "$source/$media";
1188            foreach (readdir A) {
1189                /^\.{1,2}$/ and next;
1190                my $newdest = readlink "$source/$media/$_";
1191                $newdest =~ s,((?:../)*)(.*),$1$destination/$2,;
1192                log_("cdcom: creating symlink $dir/$cdnum/$dest/$_ => $dir/$cdnum/$dest/$newdest\n", $config->{verbose}, $config->{LOG},2);
1193                my $err = link "$dir/$cdnum/$dest/$newdest", "$dir/$cdnum/$dest/$_";
1194                # should be OK with new du with inode checking
1195                #$size -= du("$dir/$cdnum/$dest/$newdest");
1196                !$err and log_("ERROR cdcom: $!\n", $config->{verbose}, $config->{LOG})
1197            }
1198            log_("cdcom: creating symlink $uppath$dest => $fdest/RPMS\n", $config->{verbose}, $config->{LOG});
1199            my $err = symlink "$uppath$dest", "$fdest/RPMS";                                           
1200            !$err and log_("ERROR cdcom: $!\n", $config->{verbose}, $config->{LOG});
1201               
1202            return $size
1203        }
1204        my $rep = $fct->[1]{dir}; 
1205        my $lists = $fct->[1]{lists};
1206        my $dest_dir = $cd->{function}{data}{dir}{$rep}[1];
1207        my $reploc = "$dir/$cdnum/$dest_dir->{reploc}/";
1208        my $sep_arch = $dest_dir->{sep_arch};
1209        foreach my $list (@$lists) {
1210            $size += process_hdlist_flags($nolive, $fct->[1]{synthesis}, $fct->[1]{hdlist}, $discs_file->[$cdnum]{$rep}{$list}, $dir, $cdnum, $fct, $rep, $reploc, $sep_arch, $graft, $list, $dest_dir->{reploc});
1211        }
1212        return $size
1213    }
1214}
1215
1216sub process_hdlist_flags {
1217    my ($nolive, $synthesis, $hdlist, $discs_files, $dir, $cdnum, $fct, $rep, $reploc, $sep_arch, $graft, $list, $nolive_rep) = @_;
1218    my $size;
1219    log_("process_hdlist_flags: synthesis $synthesis hdlist $hdlist disc $cdnum reploc $reploc\n", $config->{verbose}, $config->{LOG});
1220    my $media_hdlist = $config->{struct}{$config->{struct_version}}{media_hdlist};
1221    if ($nolive) {
1222        if ($synthesis || $hdlist) {
1223            if (ref $discs_files) {
1224                my (undef, $path) = buildGenericHdlist($dir, $cdnum, $fct, $rep, "$reploc/$media_hdlist", $discs_files, $sep_arch);
1225                if ($fct->[1]{hdlist})  {
1226                    $size += du("$reploc/$media_hdlist/hdlist.cz");
1227                    $graft->{"$nolive_rep/$media_hdlist/hdlist.cz"}{"$reploc/$media_hdlist/hdlist.cz"} = 1
1228                }
1229                if ($fct->[1]{synthesis}) {
1230                    $size += du("$reploc/$media_hdlist/synthesis.hdlist.cz");
1231                    $graft->{"$nolive_rep/$media_hdlist/synthesis.hdlist.cz"}{"$reploc/$media_hdlist/synthesis.hdlist.cz"} = 1
1232                }
1233            } else {
1234                log_("WARNING process_hdlist_flags: disc $cdnum rep $rep list $list is empty, no hdlist or synthesis created\n", $config->{verbose}, $config->{LOG});
1235            }
1236        }
1237    } else {
1238        if ($synthesis || $hdlist) {
1239            if (ref $discs_files) {
1240                buildGenericHdlist($dir, $cdnum, $fct, $rep, "$reploc/$media_hdlist", $discs_files, $sep_arch);
1241            } else {
1242                log_("WARNING process_hdlist_flags: disc $cdnum rep $rep list $list is empty, no hdlist or synthesis created\n", $config->{verbose}, $config->{LOG});
1243            }
1244        }
1245    }
1246    $size
1247}
1248
1249sub printSize {
1250    my ($img, $file) = @_;
1251    local *A; open A, ">$file";
1252    my $size = imageSize($img);
1253    log_("printSize: creating $file for $img\n", $config->{verbose}, $config->{LOG});
1254    if ($size) {
1255        print A <<EOF
1256#!/usr/bin/perl
1257
1258\$width = $size->[0];
1259\$height = $size->[1];
1260\@data = ()
1261EOF
1262    } else {
1263        print "ERROR advertising: $size/n";
1264        return 0
1265    }
1266}
1267
1268sub advertising {
1269    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode) = @_;
1270    my $graft = $totgraft->{$cdnum};
1271    if (!$fixed) {
1272        my $size;
1273        my $struct_v = $config->{struct_version};
1274        my $extra = $config->{struct}{$struct_v}{extra};
1275        if ($nolive) {
1276            log_("Getting advertising images size\n", $config->{verbose}, $config->{LOG});
1277            my $addir = "$extra/advertising" . ($fct->[1]{lang} ? ".$fct->[1]{lang}" : "");
1278            my $rep = "$dir/$cdnum/$addir";
1279            -d $rep or mkpath $rep;
1280            local *L; open L, ">$rep/list";
1281            foreach (@{$fct->[1]{img}}) {
1282                s/\.png$//;
1283                my ($name) = m,([^/]*)$,;
1284                $size += du($_, $inode);
1285                print L "$name\n";
1286                if (-f "$_.png") { $graft->{"$addir/$name.png"}{"$_.png"} = 1 } else { next }
1287                if (-f "$_.pl") { $graft->{"$addir/$name.pl"}{"$_.pl"} = 1
1288                } else {
1289                    printSize("$_.png", "$rep/$name.pl");
1290                    $graft->{"$addir/$name.pl"}{"$_.pl"} = 1
1291                }
1292                -f "${_}_icon.png" and $graft->{"$addir/$name-icon.png"}{"${_}_icon.png"} = 1
1293            } 
1294            close L;
1295            $graft->{"$addir/list"}{"$rep/list"} = 1;
1296            $size += du("$rep/list");
1297            return $size
1298        } else {
1299            my $rep = "$dir/$cdnum/$extra/advertising" . ($fct->[1]{lang} ? ".$fct->[1]{lang}" : "");
1300            log_("Creating advertising images directory ($rep)\n", $config->{verbose}, $config->{LOG});
1301            -d $rep or mkpath $rep;
1302            local *L; open L, ">$rep/list";
1303            foreach (@{$fct->[1]{img}}) {
1304                s/\.png$//;
1305                my ($name) = m,([^/]*)$,;
1306                if (-f "$_.png") { cpal("$_.png", "$rep/$name.png") } else { next }
1307                if (-f "$_.pl") { cpal("$_.pl", "$rep/$name.pl") } else { printSize("$_.png", "$rep/$name.pl") }
1308                -f "${_}_icon.png" and cpal("${_}_icon.png", "$rep/${name}_icon.png");
1309                print L "$name.png\n"
1310            }
1311            close L;
1312            return
1313        }
1314    }
1315}
1316
1317sub dir {
1318    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd) = @_;
1319    if (!$fixed) {
1320        if ($nolive) {
1321            return 0
1322        } else {
1323            my $reploc = "$dir/$cdnum/$fct->[1]{reploc}";
1324            log_("dir: creating $reploc\n", $config->{verbose}, $config->{LOG});
1325            -d $reploc or mkpath $reploc;
1326            return 0   
1327        }
1328    }
1329}
1330
1331sub generic {
1332    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discsFile) = @_;
1333    my $graft = $totgraft->{$cdnum};
1334    my $size;
1335    my $rep = $fct->[1]{repname};
1336    my $dest_dir = $cd->{function}{data}{dir}{$rep}[1];
1337    my $nolive_rep = $dest_dir->{reploc};
1338    if ($fixed) {
1339        my $lists = $fct->[1]{lists};
1340        log_("generic: rep $rep\n", $config->{verbose}, $config->{LOG});
1341        my $reploc = "$dir/$cdnum/$dest_dir->{reploc}/";
1342        my $sep_arch = $dest_dir->{sep_arch};
1343        my %list;
1344        if ($sep_arch) {
1345            if (-f "$reploc/list") {
1346                open my $list_file, "$reploc/list";
1347                while (<$list_file>) {
1348                    chomp;
1349                    $list{$_} = 1
1350                }
1351            }
1352        }
1353        if ($nolive) {
1354            if ($fixed > 0) {
1355                foreach my $list (@$lists) {
1356                    log_("generic: list $list\n", $config->{verbose}, $config->{LOG});
1357                    foreach my $src (keys %{$cdfile->[$cdnum]{$rep}{$list}}) {
1358                        log_("generic: src $src\n", $config->{verbose}, $config->{LOG});
1359                        foreach (@{$cdfile->[$cdnum]{$rep}{$list}{$src}}) {
1360                            if ($_->[0] == 1) {
1361                                my $d = $nolive_rep;
1362                                if ($sep_arch) {
1363                                    $_->[1] =~ /([^.]+)\.rpm$/  or log_("WARNING generic: could not find arch of $_\n", $config->{verbose}, $config->{LOG});
1364                                    $d .= "/$1"
1365                                }
1366                                $graft->{"$d/$_->[1]"}{"$src/$_->[1]"} = 1
1367                            } elsif ($_->[0] == 2) {
1368                                my $d = $nolive_rep;
1369                                if ($sep_arch) {
1370                                    $_->[1] =~ /([^.]+)\.rpm$/  or log_("WARNING generic: could not find arch of $_\n", $config->{verbose}, $config->{LOG});
1371                                    $d .= "/$1"
1372                                }
1373                                delete $graft->{"$d/$_->[1]"}{"$src/$_->[1]"} 
1374                            }
1375                        }
1376                    }
1377                    $size += process_hdlist_flags($nolive, $fct->[1]{synthesis}, $fct->[1]{hdlist}, $discsFile->[$cdnum]{$rep}{$list}, $dir, $cdnum, $fct, $rep, $reploc, $sep_arch, $graft, $list, $nolive_rep);
1378                }
1379            }
1380            if ($sep_arch) {
1381                open my $list_file, ">$reploc/list";
1382                foreach (sort keys %list) { print $list_file "$_\n" if $list{$_} }
1383                close $list_file;
1384                $size += du("$dir/$cdnum/$reploc/list");
1385                $graft->{"$nolive_rep/list"}{"$reploc/list"} = 1
1386            }
1387            return $size
1388        } else {
1389            foreach my $list (@$lists) {
1390                log_("generic: list $list\n", $config->{verbose}, $config->{LOG});
1391                foreach my $src (keys %{$cdfile->[$cdnum]{$rep}{$list}}) {
1392                    log_("generic: src $src\n", $config->{verbose}, $config->{LOG});
1393                    foreach (@{$cdfile->[$cdnum]{$rep}{$list}{$src}}) {
1394                        if ($_->[0] == 1) {
1395                            my $d = $reploc;
1396                            if ($sep_arch) {
1397                                $_->[1] =~ /([^.]+)\.rpm$/ or log_("WARNING generic: could not find arch of $_\n", $config->{verbose}, $config->{LOG});
1398                                $d .= "/$1";
1399                                $list{"$1/$_->[1]"} = 1;
1400                                -d $d or mkdir $d;
1401                            }
1402                            cpal("$src/$_->[1]", $d)   
1403                        }  elsif ($_->[0] == 2) {
1404                            log_("generic: deleting $reploc/$_->[1]\n", $config->{verbose}, $config->{LOG});
1405                            my $d = $reploc;
1406                            if ($sep_arch) {
1407                                $_->[1] =~ /([^.]+)\.rpm$/ or log_("WARNING generic: could not find arch of $_\n", $config->{verbose}, $config->{LOG});
1408                                $list{"$1/$_->[1]"} = 0;
1409                                $d = "$reploc/$1";
1410                            }
1411                            unlink "$d/$_->[1]";
1412                        }
1413                    }
1414                }
1415                $size += process_hdlist_flags($nolive, $fct->[1]{synthesis}, $fct->[1]{hdlist}, $discsFile->[$cdnum]{$rep}{$list}, $dir, $cdnum, $fct, $rep, $reploc, $sep_arch, $graft, $list, $nolive_rep);
1416            }
1417            if ($sep_arch) {
1418                open my $list_file, ">$reploc/list";
1419                foreach (sort keys %list) { print $list_file "$_\n" if $list{$_} }
1420                close $list_file;
1421            }
1422            return 0
1423        }
1424       
1425    }
1426}
1427
1428sub printVERSION {
1429    my ($name, $file, $rel_info, $prefix) = @_;
1430    open my $VERSION, ">$file";
1431    my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = gmtime(time());
1432    $year += 1900;
1433    my $tag;
1434    foreach (qw(branch product arch)) {
1435        $tag .= "$rel_info->{$_}-" if $rel_info->{branch}
1436    }
1437    $tag .= $rel_info->{tag} if $rel_info->{tag};
1438    printf $VERSION "${prefix}Mandrakelinux $name $tag %04d%02d%02d $hour:%02d\n", $year, $mon+1, $mday, $min;
1439}
1440
1441sub buildGenericHdlist {
1442    my ($dir, $cdnum, $fct, $rep, $reploc, $discsFilescdrep, $sep_arch) = @_;
1443    my @rpm = map { "$discsFilescdrep->{$_}/$_.rpm" } keys %$discsFilescdrep;
1444   
1445    if ($fct->[1]{synthesis}) {
1446        -d $reploc or mkpath $reploc;
1447    }
1448    # $hdlist = "$reploc/hdlist$cdnum$rep.cz" if $fct->[1]{hdlist};
1449    # my $synthesis = "$reploc/synthesis.hdlist$cdnum$rep.cz" if $fct->[1]{synthesis};
1450    my ($hdlist, $synthesis, @md5files);
1451    my $struct_v = $config->{struct_version};
1452    if ($fct->[1]{hdlist}) {
1453        $hdlist = "$reploc/hdlist.cz";
1454        -d $reploc or mkdir $reploc;
1455        push @md5files, $hdlist
1456    }
1457    if ($fct->[1]{synthesis}) {
1458        $synthesis = "$reploc/synthesis.hdlist.cz";
1459        -d $reploc or mkdir $reploc;
1460        push @md5files, $synthesis
1461    }
1462    my $urpm = mkcd_build_hdlist(1, [ 0, { hdlist => $hdlist, rpms => \@rpm , synthesis => $synthesis } ], "$config->{tmp}/.mkcd_build_hdlist");
1463    compute_files_md5("$reploc/MD5SUM", \@md5files);
1464    $urpm, $reploc
1465}
1466
1467sub buildInstallHdlist {
1468    my ($dir, $cdnum, $inst, $list, $discsFiles, $sort, $nolive, $cdsize) = @_;
1469    my (@hdlist, @hdlist_list);
1470    my $struct_v = $config->{struct_version};
1471    my $media_info = $config->{struct}{$struct_v}{media_info};
1472    my $media_base = $config->{struct}{$struct_v}{media_base};
1473    -d "$dir/$cdnum/$media_info" or mkpath "$dir/$cdnum/$media_info";
1474    open my $HDLISTS, ">$dir/$cdnum/$media_info/hdlists";
1475    my $media_cfg = "$dir/$cdnum/$media_info/media.cfg";
1476    my $rel_info = $inst->[1]; 
1477    unlink $media_cfg;
1478    printVERSION($config->{name}, $media_cfg, $rel_info, '# ');
1479    open my $MEDIACFG, ">>$media_cfg";
1480    if ($rel_info->{version} || $rel_info->{branch} || $rel_info->{arch}) {
1481        print $MEDIACFG "\n[media_info]\n";
1482        foreach (qw(version branch arch product minor subversion)) {
1483            print $MEDIACFG "$_=$rel_info->{$_}\n" if $_;
1484        }
1485        print $MEDIACFG "\n";
1486    }
1487    if ($inst->[1]{suppl}) {
1488        print $HDLISTS "suppl\n";
1489        print $MEDIACFG "suppl=1\n"
1490    }
1491    if ($inst->[1]{askmedia}) {
1492        print $HDLISTS "askmedia\n";
1493        print $MEDIACFG "askmedia=1\n"
1494    }
1495    my (%rpmdone, %cd_rep);
1496    my %kerneldone;
1497    my $repnum = 1;
1498    my (@thisInstallRep, @check, @md5files);
1499    my $headers_dir = "$config->{tmp}/.mkcd_build_hdlist";
1500    my $path = "$dir/$cdnum/$media_info";
1501    my $suppl_cd = $inst->[1]{suppl_cd};
1502    my $suppl_postfix = 's' if $suppl_cd;
1503    log_("buildInstallHdlist: suppl_postfix is '$suppl_postfix' ($suppl_cd && $struct_v)\n", $config->{verbose}, $config->{LOG});
1504    foreach my $rd (@{$inst->[1]{tmp_rpmsdir}}) {
1505        my ($ls, $cdrep, $repname, $opts) = @$rd;
1506        log_("buildInstallHdlist: suppl_cd $suppl_cd cd $cdrep repname $repname fixed $opts->{fixed}\n", $config->{verbose}, $config->{LOG});
1507        next if $suppl_cd && $opts->{fixed};
1508        if (!$list->{$cdrep}) { log_("WARNING buildInstallHdlist: disc $cdrep not in list, ignoring\n", $config->{verbose}, $config->{LOG}); next }
1509        my $a = $discsFiles->[$cdrep]{$repname};
1510        if (!(ref($a) && %$a)) { log_("WARNING buildInstallHdlist: $cdrep/$repname is empty\n", $config->{verbose}, $config->{LOG}); next }
1511        my $realcd = $config->{disc}[$cdrep]{name};
1512        my $rpmdir = $config->{disc}[$cdrep]{function}{data}{dir}{$repname}[1]{reploc};
1513        $rpmdir .= "/%{ARCH}" if $config->{disc}[$cdrep]{function}{data}{dir}{$repname}[1]{sep_arch};
1514        if (!$rpmdir) { log_("ERROR buildInstallHdlist: disc $cdrep: $repname not defined\n", $config->{verbose}, $config->{LOG}); next }
1515        $hdlist[$repnum]{rpms} = [];
1516        if ($opts->{oem}) {
1517            log_("buildInstallHdlist: oem mode for $cdrep/$repname ($rpmdir)\n", $config->{verbose}, $config->{LOG});
1518            foreach (@{$inst->[1]{oem}{hdlist}}) {
1519                my ($oemdir, $hl, $rep, $name) = @$_;
1520                print $HDLISTS "noauto:" if $opts->{noauto};
1521                print $HDLISTS "$hl $rep $name\n";
1522                my $hdlist = "$path/$hl";
1523                log_("buildInstallHdlist: adding oem hdlist $hdlist from $dir\n", $config->{verbose}, $config->{LOG});
1524                if ($inst->[1]{oem}{norebuild}) {
1525                    cpal("$oemdir/$hl", $hdlist)
1526                }
1527                $hdlist[$repnum]{hdlist} = $hdlist;
1528                $hdlist_list[$repnum] = $hdlist;
1529                $hdlist[$repnum]{synthesis} = "$path/synthesis.$hl";
1530                push @md5files, ($hdlist, "$path/synthesis.$hl");
1531                $repnum++
1532            }
1533        } else {
1534            #
1535            # even for live sources rpm are taken, this may lead to errors in some special case, where
1536            # the sources change after the live is created, but this could help in combined live/nolive
1537            # situation
1538            #
1539            log_("installation: $cdrep - $repname - list $ls\n", $config->{verbose}, $config->{LOG});
1540            my $size;
1541            foreach my $list (keys %{$discsFiles->[$cdrep]{$repname}}) {
1542                next if $ls && $ls != $list;
1543                $thisInstallRep[$cdrep]{$repname}{$list} = $discsFiles->[$cdrep]{$repname}{$list};
1544                push @{$check[$repnum]}, [$cdrep, $repname, $list];
1545                log_("installation: list $list\n", $config->{verbose}, $config->{LOG});
1546                my $cdsfilesrpms = $discsFiles->[$cdrep]{$repname}{$list};
1547                my %localdone;
1548                my %localkerneldone;
1549                # FIXME taken from tools
1550                my $kernel_like = "((?:(?:NVIDIA_)?kernel.*)|NVIDIA_nforce.*|cm2020.*)";
1551                #
1552               
1553                $size += $cdsize->{rep}{$cdrep}{$repname}{$list} || $cdsize->{real}{rep}{$cdrep}{$repname}{$list};
1554                log_("buildInstallHdlist: update ($opts->{update}) nodupkernel ($opts->{nodupkernel}) mode for $cdrep/$repname list $list\n", $config->{verbose}, $config->{LOG}, 3);
1555                push @{$hdlist[$repnum]{rpms}}, map {
1556                    if (/$kernel_like-[^.]+(?:\.[^.]+){3,5}mdk-[^-]+-[^-]+\.[^.]+$/) {
1557                        $kerneldone{$1} = 1;
1558                    }
1559                    if (/(.*)-[^-]+-[^-]+\.[^.]+$/) {
1560                        $rpmdone{$_} = 1;
1561                        $rpmdone{$1} = 1;
1562                        "$cdsfilesrpms->{$_}/$_.rpm" }
1563                    } grep {
1564                        if ($opts->{nodupkernel} && /($kernel_like-[^.]+(?:\.[^.]+){3,5}mdk)-[^-]+-[^-]+\.[^.]+$/) {
1565                            if ($localdone{$1} || $localkerneldone{$2}) { 0 }
1566                            else {
1567                                $localkerneldone{$2} = 1;
1568                                $localdone{$1} = 1;
1569                                ! ($kerneldone{$2} || $rpmdone{$_} || !$opts->{update} && $rpmdone{$1})
1570                            }
1571                        } elsif (/(.*)-[^-]+-[^-]+\.[^.]+$/) {
1572                            if ($localdone{$1}) { $inst->[1]{dup} }
1573                            else {
1574                                $localdone{$1} = 1;
1575                                $inst->[1]{dup} || ! ($rpmdone{$_} || !$opts->{update} && $rpmdone{$1})
1576                            } } } keys %$cdsfilesrpms;
1577                $hdlist[$repnum]{callback} = sub {
1578                       my ($urpm, $id) = @_;
1579                       my $pkg = $urpm->{depslist}[$id];
1580                       my $filename = $pkg->filename;
1581                       $urpm->{id}{$filename} = $id;
1582                       $pkg->pack_header
1583                   }
1584            }
1585            if (@{$hdlist[$repnum]{rpms}}) {
1586                if (!($opts->{fixed} && $opts->{nohdlist})) {
1587                    print $HDLISTS "noauto:" if $opts->{noauto};
1588                    my $size = int ($size/(1024*1024));
1589                    if ($realcd) {
1590                        print $HDLISTS "hdlist$repnum$suppl_postfix.cz $rpmdir disc $realcd $config->{disc}[$cdrep]{longname} (${size}m)\n"
1591                    } else {
1592                        print $HDLISTS "hdlist$repnum$suppl_postfix.cz $rpmdir $config->{disc}[$cdrep]{longname} (${size}m)\n"
1593                    }
1594                    my $media_dir = $rpmdir;
1595                    $media_dir =~ s/^$media_base\///;
1596                    print $MEDIACFG "[$media_dir]\nhdlist=media_info/hdlist$repnum$suppl_postfix.cz\nsize=${size}m\n";
1597                    print $MEDIACFG "noauto" if $opts->{noauto};
1598                    $cd_rep{$repnum} = [ $cdrep, $rpmdir ];
1599                    my %keys;
1600                    my $text;
1601                    foreach my $list (keys %{$discsFiles->[$cdrep]{$repname}}) {
1602                        foreach my $keyfile (@{$config->{list}[$list]{keyfiles}}) {
1603                            if (-f $keyfile) {
1604                                log_("buildInstallHdlist: dumping $keyfile in $dir/$cdnum/$media_info/pubkey$repnum$suppl_postfix\n", $config->{verbose}, $config->{LOG}, 3);
1605                                open my $KF, $keyfile;
1606                                my $key;
1607                                while (<$KF>) {
1608                                    $key .= $_;
1609                                    if (/^-----END PGP PUBLIC KEY BLOCK-----/) {
1610                                        if (! $keys{$key}) {
1611                                            $keys{$key} = 1;
1612                                            $text .= $key
1613                                        }
1614                                        $key = ''
1615                                    }
1616                                }
1617                                close $KF
1618                            } else { 
1619                                log_("ERROR buildInstallHdlist: $keyfile file does not exist\n", $config->{verbose}, $config->{LOG}, 0);
1620                            }
1621                        }
1622                    }
1623                    if ($text) {
1624                        open my $KEY, ">$dir/$cdnum/$media_info/pubkey$repnum$suppl_postfix";
1625                        print $KEY $text;
1626                        close $KEY;
1627                    }
1628                    $hdlist_list[$repnum] = "$path/hdlist$repnum$suppl_postfix.cz";
1629                    $hdlist[$repnum]{hdlist} = $hdlist_list[$repnum];
1630                    push @md5files, $hdlist_list[$repnum];
1631                    if ($inst->[1]{synthesis}) { 
1632                        $hdlist[$repnum]{synthesis} = "$path/synthesis.hdlist$repnum$suppl_postfix.cz";
1633                        push @md5files, $hdlist[$repnum]{synthesis}
1634                    }
1635                }
1636                $repnum++
1637            } else {
1638                log_("WARNING installation: $cdrep $repname is empty, ignoring\n", $config->{verbose}, $config->{LOG});
1639            }
1640        }
1641    }
1642    # FIXME OEM mode not tested, moreover this norebuild test is wrong, new URPM need to rebuild hdlist.
1643    if (!$inst->[1]{oem}{norebuild}) {
1644        my $urpm = mkcd_build_hdlist($repnum - 1, \@hdlist, $headers_dir, "$path/depslist.ordered", "$path/provides", "$path/compss");
1645        get_sorted_packages($urpm, \@hdlist, $sort, \%cd_rep, "$dir/$cdnum", $nolive, $config->{verbose}, $config->{LOG});
1646    }
1647    log_("installation: compute_files_md5 @md5files\n", $config->{verbose}, $config->{LOG});
1648    compute_files_md5("$dir/$cdnum/$media_info/MD5SUM", \@md5files);
1649
1650    log_("installation: oem ($inst->[1]{oem})\n", $config->{verbose}, $config->{LOG});
1651    if (!$inst->[1]{oem}{oem}) {
1652        log_("installation: checkDiscs\n", $config->{verbose}, $config->{LOG});
1653        checkDiscs(\@hdlist_list, "$path/depslist.ordered", \@thisInstallRep, \@check, $config->{LOG}) or die "depslist.ordered, hdlists and RPMS mismatch\n";
1654    }
1655# Add sources
1656    foreach my $rd (@{$inst->[1]{srpmsdir}}) {
1657        my ($ls, $cdrep, $repname, $opts) = @$rd;
1658        if (!$list->{$cdrep}) { log_("WARNING buildInstallHdlist: disc $cdrep not in list, ignoring\n", $config->{verbose}, $config->{LOG}); next }
1659        foreach my $list (keys %{$discsFiles->[$cdrep]{$repname}}) {
1660            next if $ls && $ls == $list;
1661            $thisInstallRep[$cdrep]{$repname}{$list} = $discsFiles->[$cdrep]{$repname}{$list};
1662        }
1663    }
1664   
1665    my $pfile = "$dir/$cdnum/pkg-$config->{name}" . ($inst->[1]{tag} ? "-$inst->[1]{tag}" : "") . ".idx";
1666    printDiscsFile($config, \@thisInstallRep, $pfile);
1667    return $repnum, $path, $pfile, $suppl_postfix
1668}
1669
1670sub boot {
1671    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discsFiles, $sort) = @_;
1672    my $graft = $totgraft->{$cdnum};
1673    my $isolinux = $fct->[1]{isolinux};
1674    my $bootimg = $fct->[1]{bootimg};
1675    log_("Boot: $fixed nolive $nolive\n", $config->{verbose}, $config->{LOG});
1676    my $struct_v = $config->{struct_version};
1677    my $isolinux_dir = $fct->[1]{isolinux_dir} || $config->{struct}{$struct_v}{isolinux};
1678    if (!$fixed) {
1679        my $size;
1680        my (@chunk_first, @chunk);
1681        if ($nolive) {
1682            my $mkiso;
1683            my $img;
1684            my $dir;
1685            my $path;
1686            if ($isolinux) {
1687                log_("boot: isolinux mode (bootimg $bootimg)\n", $config->{verbose}, $config->{LOG});
1688                my $img = $bootimg ? $bootimg->[0] : "$isolinux_dir/isolinux.bin"; 
1689                $mkiso = qq( -udf -b $img -c $isolinux_dir/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table);
1690                push @chunk_first, $img;
1691                $graft->{"$isolinux_dir/boot.cat"} = 0;
1692            } elsif ($bootimg) {
1693                log_("boot: el torito mode (bootimg $bootimg->[0])\n", $config->{verbose}, $config->{LOG});
1694                $img = $bootimg->[0];
1695                $dir = $bootimg->[1]{dir};
1696                $img =~ s,(.*)/([^/]+)$,$2,;
1697                $dir or ($dir) = $1;
1698                $mkiso = qq( -udf -b $dir/$img -c ${dir}/boot.cat);
1699                $graft->{"$dir/boot.cat"} = 0;
1700            }
1701            foreach (@{$fct->[1]{files}}) {
1702                my ($files, $opt) = @$_;
1703                my $dest = $opt->{dest};
1704                $size += du($files);
1705                my ($dirname) = $files =~ m,([^/]*)$,;
1706                log_("boot: files $files dest $dest dirname $dirname\n", $config->{verbose}, $config->{LOG});
1707                if ($img) { 
1708                    my $bimg = $bootimg->[0];
1709                    $bimg =~ s/$dirname//;
1710                    log_("boot: boot image $files/$bimg ($bimg) in $dir/$img (" . (stat "$files/$bimg")[7] . ")\n", $config->{verbose}, $config->{LOG});
1711                    if (-f "$files/$bimg") { 
1712                        if ((stat "$files/$bimg")[7] > 3000000) { 
1713                            $mkiso .= qq( -no-emul-boot)
1714                        }
1715                        # $mkiso .= qq( $dir/$img=$files/$bimg)
1716                        push @chunk_first, "$files/$bimg";
1717                        $graft->{"$dir/$img"}{"$files/$bimg"} = 1
1718                    }
1719                }
1720               
1721                # if (-d "$files") { $mkiso .= " $dest/$dirname/=$files"; next }
1722                # $mkiso .= " $dest/=$files";
1723                log_("boot: graft $dest/$dirname/ from $files\n", $config->{verbose}, $config->{LOG});
1724                if (-d $files) { 
1725                    $graft->{"$dest/$dirname/"}{$files} = 1 
1726                } else { 
1727                    $graft->{"$dest/"}{$files} = 1 
1728                }
1729                $dest =~ s,/+,/,g;
1730                if ($opt->{first}) {
1731                    push @chunk_first, $dest
1732                } else {
1733                    unshift @chunk, $dest 
1734                }
1735                push @chunk_first, "$dir/boot.cat"
1736            }
1737            # it is = and not .= because mkcdisos->[$cdnum] has been added already at the beginning
1738            $mkisos->[$cdnum] = "$mkiso $mkisos->[$cdnum]";
1739        } else {
1740            log_("FILES $fct->[1]{files}\n", $config->{verbose}, $config->{LOG});
1741            foreach (@{$fct->[1]{files}}) {
1742                my ($files, $opt) = @$_;
1743                my $dest = "$config->{topdir}/build/$config->{name}/" . ($opt->{first} ? "first/" : "") . "$cdnum/";
1744                # FIXME first should ne obsolete, however it appears in several place, and the removal must be done with care
1745                -d $dest or mkpath $dest;
1746                my $odest = $opt->{dest};
1747                log_("boot: file $files (first $opt->{first} to $dest odest $odest)\n", $config->{verbose}, $config->{LOG});
1748                if ($odest) {
1749                    $dest .= "/$odest";
1750                    if ($odest =~ m,/$,) { mkpath $dest }
1751                } else {
1752                    my ($dirname) = $files =~ m,([^/]*)$,;
1753                    $dest .= "/$dirname"
1754                }
1755                $dest =~ s,/+,/,g;
1756                log_("boot: file $files (to $dest odest $odest)\n", $config->{verbose}, $config->{LOG});
1757                cpal($files, $dest, "(rr_moved|boot.cat)");
1758                if ($opt->{first}) {
1759                    push @chunk_first, $dest
1760                } else {
1761                    unshift @chunk, $dest 
1762                }
1763                push @chunk_first, "$dir/boot.cat"
1764            }
1765            if ($fct->[1]{oem}) {
1766                log_("boot: setting default boot to oem\n", $config->{verbose}, $config->{LOG});
1767                my $dest = "$config->{topdir}/build/$config->{name}/first/$cdnum/$isolinux_dir";
1768                -d $dest or mkpath $dest;
1769                my $old = "$dest/isolinux.cfg";
1770                my $new = "$dest/isolinux.cfg.new";
1771                copy $old, $new;
1772                unlink $old;
1773                link $new, $old;
1774                unlink $new;
1775                substInFile { s/default linux/default oem/ } $old
1776            }
1777            $graft->{"/"}{"$dir/first/$cdnum/"} = 1;
1778            $size = du("$dir/first/$cdnum/", $inode);
1779        }
1780        push @{$sort->{$cdnum}}, \@chunk_first;
1781        unshift @{$sort->{$cdnum}}, \@chunk;
1782        return $size
1783    } elsif ($fixed == 1) {
1784        if (!$nolive) {
1785            if ($isolinux) {
1786                my $img = $bootimg ? $bootimg->[0] : "$isolinux_dir/isolinux.bin"; 
1787                $mkisos->[$cdnum] .= qq( -udf -b $img -c $isolinux_dir/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table "$config->{topdir}/build/$config->{name}/first/$cdnum");
1788                if (-f "$dir/$cdnum/$img") {
1789                    push @{$sort->{$cdnum}}, [ "$dir/$cdnum/$img" ];
1790                } elsif (-f "$dir/first/$cdnum/$img") {
1791                    push @{$sort->{$cdnum}}, [ "$dir/first/$cdnum/$img" ];
1792                }
1793                $graft->{"$isolinux_dir/boot.cat"} = 0
1794            } elsif ($bootimg) {
1795                my $img = $bootimg->[0];
1796                my $sdir = $bootimg->[1]{dir};
1797                $img =~ s,(.*/)([^/]+)$,$2,;
1798                $sdir or ($sdir) = $1;
1799                $sdir =~ s,//+,/,g;
1800                $sdir =~ s,/$,,g;
1801                log_("boot: boot image $sdir/$img\n", $config->{verbose}, $config->{LOG});
1802                $mkisos->[$cdnum] .= qq( -udf -b $sdir/$img);
1803                my $Bootdir;
1804                my $cdimages;
1805                log_("boot: try to find boot image in $cdimages/$bootimg->[0] and $dir/first/$cdnum/$bootimg->[0]\n", $config->{verbose}, $config->{LOG});
1806                if (-f "$cdimages/$bootimg->[0]") {
1807                    $cdimages = "$dir/$cdnum";
1808                    $Bootdir = "$dir/$cdnum/$sdir/";
1809                } elsif (-f "$dir/first/$cdnum/$bootimg->[0]") {
1810                    $cdimages = "$dir/first/$cdnum";
1811                    $Bootdir = "$dir/first/$cdnum/$sdir/";
1812                } else {
1813                    die "FATAL boot: could not find boot image\n";
1814                }
1815                if ((stat "$cdimages/$bootimg->[0]")[7] > 3000000) { 
1816                    $mkisos->[$cdnum] .= qq( -no-emul-boot)
1817                }
1818                push @{$sort->{$cdnum}}, [ "$cdimages/$bootimg->[0]" ];
1819                $Bootdir =~ s,//+,/,g;
1820                $Bootdir =~ s,/$,,g;
1821                if (! -f "$Bootdir/$img") {
1822                    if (! -d $Bootdir) { mkpath $Bootdir or die "cannot create $Bootdir\n" }
1823                    my $err = link "$cdimages/$bootimg->[0]", "$Bootdir/$img";
1824                    if (!$err) { log_("Linking failed $cdimages/$bootimg->[0]: $!\n", $config->{verbose}, $config->{LOG}) };
1825                }
1826                $mkisos->[$cdnum] .= qq( -c $sdir/boot.cat $dir/first/$cdnum);
1827                $graft->{"$sdir/boot.cat"} = 0;
1828                log_("BOOT $mkisos->[$cdnum]\n", $config->{verbose}, $config->{LOG});
1829            }
1830        }
1831    }
1832}
1833
1834sub installation {
1835    my ($class, $inst, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discsFiles, $sort, $cdsize) = @_;
1836    my $graft = $totgraft->{$cdnum};
1837    my $install = $inst->[1]{install};
1838    my $struct_v = $config->{struct_version};
1839    my $struct = $config->{struct}{$struct_v};
1840    my ($isolinux_dir, $images_dir, $media_base, $extra_dir, $media_info, $install_dir, $compss_name) = ($struct->{isolinux}, $struct->{images}, $struct->{media_base}, $struct->{extra}, $struct->{media_info}, $struct->{install}, $struct->{compssUsers});
1841
1842    my ($compss, $rpmsrate);
1843    if (defined $cd->{function}{data}{installation}[1]{compssUsers}) {
1844        $compss = $cd->{function}{data}{installation}[1]{compssUsers}
1845    } elsif ($install) {
1846        $compss = "$install/$media_info/$compss_name"
1847    }
1848    if (defined $cd->{function}{data}{installation}[1]{rpmsrate}) {
1849        $rpmsrate = $cd->{function}{data}{installation}[1]{rpmsrate}
1850    } elsif ($install) {
1851        $rpmsrate = "$install/$media_info/base/rpmsrate";
1852    }   
1853    if (!$fixed) {
1854        my $size;
1855        my $media_dir = $struct->{media};
1856
1857        if ($nolive) {
1858            if ($install) {
1859                opendir my $A, $install;
1860                foreach (readdir $A) {
1861                    /~$/ and next;
1862                    /^(\.{1,2}|$install_dir|LICENSE-APPS\.txt|$isolinux_dir|$images_dir|VERSION|boot\.cat|rr_moved|$media_base)$/ and next;
1863                    $size += du("$install/$_");
1864                    if (-d "$install/$_") { $graft->{"/$_/"}{"$install/$_"} = 1; next }
1865                    $graft->{"/"}{"$install/$_"} = 1
1866                }
1867
1868                local *A; opendir A, "$install/$install_dir";
1869                foreach (readdir A) {
1870                    log_("$install_dir -- $_\n", $config->{verbose}, $config->{LOG}, 3);
1871                    /~$/ and next;
1872                    # FIXME both old and new structure detailed
1873                    "$install_dir/$_" =~ m{^($install_dir/(\.{1,2}|$media_base))$|$media_dir|$media_info|$extra_dir|$images_dir|$isolinux_dir} and next;
1874                    $size += du("$install/$install_dir/$_");
1875                    # if (-d "$install/Mandrake/$_") { $mkiso .= " Mandrake/$_/=$install/Mandrake/$_"; next }
1876                    # $graft->{"Mandrake/"}{"$install/Mandrake/$_"} = 1;
1877                    if (-d "$install/$install_dir/$_") { $graft->{"$install_dir/$_/"}{"$install/$install_dir/$_"} = 1; next }
1878                    $graft->{"$install_dir/"}{"$install/$install_dir/$_"} = 1;
1879                }
1880
1881                local *A; opendir A, "$install/$media_info";
1882                foreach (readdir A) {
1883                    /~$/ and next; 
1884                    /(^(\.{1,2}|compss|provides|depslist.ordered|MD5SUM|pubkey.*|synthesis|$compss_name|rpmsrate|rpmslist|filelist|Serial|hashfile)|hdlist|cooker)/ and next;
1885                    $size += du("$install/$media_info/$_");
1886                    # if (-d "$install/Mandrake/base/$_") { $mkiso .= " Mandrake/base/$_/=$install/Mandrake/base/$_"; next}
1887                    # $mkiso .= " Mandrake/base/=$install/Mandrake/base/$_";
1888                    if (-d "$install/$media_info/$_") { $graft->{"$media_info/$_/"}{"$install/$media_info/$_"} = 1; next }
1889                    $graft->{"$media_info/"}{"$install/$media_info/$_"} = 1
1890                }
1891            }
1892            if ($compss) {
1893                if (-f $compss) { 
1894                    log_("installation: $compss_name $compss\n", $config->{verbose}, $config->{LOG}, 2);
1895                    $size += du($compss);
1896                    $graft->{"$media_info/$compss_name"}{$compss} = 1
1897                } else { log_("ERROR installation: $compss file does not exist", $config->{verbose}, $config->{LOG}, 0) } 
1898            }
1899        } else {
1900            if ($install) {
1901                cpal("$install/$install_dir","$dir/$cdnum/$install_dir","$install/*($extra_dir|$images_dir|($install_dir/*)?$isolinux_dir|$media_dir|$media_info)");
1902                cpal("$install/","$dir/$cdnum/","$install/*($install_dir|$images_dir|$isolinux_dir|$media_base|tutorial|misc|doc|LICENSE-APPS.txt|boot.cat|rr_moved)");
1903                cpal("$install/$media_info","$dir/$cdnum/$media_info","$install/*$media_info/*(hdlist|MD5SUM|pubkey|depslist|synthesis|rpmslist|filelist|Serial|hashfile|$compss_name|rpmsrate)");
1904
1905                #cpal("$install/", "$dir/$cdnum", "($install/+(media/+|install/+(extra|images|isolinux)|(Mandrake/+base|media/+media_info)/+(hdlist|MD5SUM|pubkey|depslist|synthesis|rpmslist|filelist|Serial|hashfile|compssUsers|rpmsrate)|Mandrake/+RPMS|Mandrake/+share|isolinux|images|tutorial|misc|doc|LICENSE-APPS.txt|boot.cat|rr_moved))");
1906                if (!$inst->[1]{oem}) {
1907                    cpal("$install/tutorial", "$dir/$cdnum/tutorial") if -d "$install/tutorial";
1908                    cpal("$install/misc", "$dir/$cdnum/misc") if -d "$install/misc";
1909                    cpal("$install/doc", "$dir/$cdnum/doc") if -d "$install/doc";
1910                }
1911
1912            }
1913            if ($compss) {
1914                if (-f $compss) {
1915                    my $path = "$dir/$cdnum/$media_info";
1916                    -d $path or mkpath $path;
1917                    log_("installation: $compss_name $compss\n", $config->{verbose}, $config->{LOG}, 2);
1918                    cpal($compss, "$path/$compss_name");
1919                } else { log_("ERROR installation: $compss file does not exist", $config->{verbose}, $config->{LOG}, 0) }
1920            }
1921        }
1922        return $size
1923    } else {
1924        my $patch_dir = $struct->{patch};
1925        my $stage2 = $struct->{stage2};
1926        if ($nolive) {
1927            my $size;
1928            if ($inst->[1]{boot_medium}) {
1929                -d "$dir/$cdnum/$patch_dir" or mkpath "$dir/$cdnum/$patch_dir";
1930                my $file = "$dir/$cdnum/$patch_dir/patch-oem.pl";
1931                my $A;
1932                if (-f "$install/$patch_dir/patch-oem.pl") {
1933                    copy "$install/$patch_dir/patch-oem.pl", $file;
1934                    open $A, ">>$file" or print "ERROR installation: could not open $file for writing\n";
1935                } else {
1936                    open $A, ">$file" or print "ERROR installation: could not open $file for writing\n";
1937                }
1938                print $A "use install_any;
1939package install_any;
1940
1941\$current_medium = $inst->[1]{boot_medium};
1942\$asked_medium = $inst->[1]{boot_medium};
1943                ";
1944                $graft->{"$patch_dir/"}{$file} = 1;
1945                $size += du($file, $inode)
1946            }
1947            my ($repnum, $path, $pfile, $suppl_postfix) = buildInstallHdlist($dir, $cdnum, $inst, $list, $discsFiles, $sort, $nolive, $cdsize);
1948            if ($install && $fixed == 1) {
1949               
1950                # $mkiso = " Mandrake/base/=$path/compss Mandrake/base/=$path/depslist.ordered Mandrake/base/=$path/provides Mandrake/base/=$path/hdlists /=$pfile";
1951                $graft->{"$media_info/"}{"$path/compss"} = 1;
1952                $graft->{"$media_info/"}{"$path/depslist.ordered"} = 1; 
1953                $graft->{"$media_info/"}{"$path/provides"} = 1;
1954                $graft->{"$media_info/"}{"$path/hdlists"} = 1;
1955                $graft->{"$media_info/"}{"$path/MD5SUM"} = 1;
1956                $graft->{"/"}{$pfile} = 1;
1957                if ($rpmsrate) {
1958                    if (-f $rpmsrate) {
1959                        $size += du($rpmsrate);
1960                        # $mkiso .= " Mandrake/base/rpmsrate=$rpmsrate"
1961                        $graft->{"$media_info/rpmsrate"}{$rpmsrate} = 1
1962                    } else { log_("ERROR installation: $rpmsrate file does not exist", $config->{verbose}, $config->{LOG}, 0); return 0 }
1963                }
1964                $size += du("$path/compss", $inode);
1965                $size += du("$path/depslist.ordered");
1966                $size += du("$path/provides");
1967                $size += du($pfile, $inode);
1968                unshift @{$sort->{$cdnum}}, [ "$path/", "$install/$stage2" ]
1969            }
1970            my $version = "$dir/$cdnum/VERSION";
1971            $size += du("$path/hdlists");
1972            printVERSION($config->{name}, $version, $inst->[1]);
1973            $graft->{VERSION}{$version} = 1;
1974            $size += du($version);     
1975            foreach my $n (1 .. $repnum - 1) {
1976                # $mkiso .= " Mandrake/base/=$path/hdlist$n.cz";
1977                $graft->{"$media_info/"}{"$path/hdlist$n$suppl_postfix.cz"} = 1;
1978                # FIXME This is wrong, previous hdlist size must be deduced in iterative rebuild mode
1979                $size += du("$path/hdlist$n$suppl_postfix.cz");
1980                if (-f "$path/pubkey$n") { 
1981                    $graft->{"$media_info/"}{"$path/pubkey$n$suppl_postfix"} = 1;
1982                    $size += du("$path/pubkey$n$suppl_postfix");
1983                }
1984                if ($inst->[1]{synthesis}) {
1985                    # $mkiso .= " Mandrake/base/=$path/synthesis.hdlist$n.cz";
1986                    $graft->{"$media_info/"}{"$path/synthesis.hdlist$n$suppl_postfix.cz"} = 1;
1987                    $size += du("$path/synthesys.hdlist$n$suppl_postfix.cz")
1988                }
1989            }
1990            return $size;
1991        } else {
1992            if (!$install) { mkpath "$dir/$cdnum/$media_info/" ; mkpath "$dir/$cdnum/$install_dir" }
1993            if ($inst->[1]{boot_medium}) {
1994                log_("installation: boot_medium defined to $inst->[1]{boot_medium}\n", $config->{verbose}, $config->{LOG}, 2);
1995                my $file = "$dir/$cdnum/$patch_dir/patch-oem.pl";
1996                my $A;
1997                if (-f $file) {
1998                    unlink $file;
1999                    copy "$install/$patch_dir/patch-oem.pl", $file;
2000                    open $A, ">>$file" or print "ERROR installation: could not open $file for writing\n";
2001                } else {
2002                    open $A, ">$file" or print "ERROR installation: could not open $file for writing\n";
2003                }
2004                print $A "use install_any;
2005package install_any;
2006
2007\$current_medium = $inst->[1]{boot_medium};
2008\$asked_medium = $inst->[1]{boot_medium};
2009";
2010            } 
2011            unlink "$dir/$cdnum/$media_info/hdlists";
2012            buildInstallHdlist($dir, $cdnum, $inst, $list, $discsFiles, $sort, 0, $cdsize);
2013            if ($fixed == 1) {
2014                if ($rpmsrate) {
2015                    if (-f $rpmsrate) {
2016                        log_("installation: rpmsrate: $rpmsrate\n", $config->{verbose}, $config->{LOG}, 2);
2017                        cpal($rpmsrate, "$dir/$cdnum/$media_info/rpmsrate");
2018                    } else { 
2019                        log_("ERROR installation: $rpmsrate file does not exist", $config->{verbose}, $config->{LOG}, 0); 
2020                        return 0 
2021                    }
2022                }
2023                if ($install) {
2024                    unshift @{$sort->{$cdnum}}, [ "$dir/$cdnum/$media_info/", "$dir/$cdnum/$stage2" ]
2025                }
2026            }
2027            my $version = "$dir/$cdnum/VERSION";
2028            unlink $version;
2029            printVERSION($config->{name}, $version, $inst->[1]);
2030        }
2031    }
2032}
2033
20341
2035
2036#
2037# Changeloh
2038#
2039# 2002 03 15
2040# new sources handling in installation
2041#
2042# 2002 03 19
2043# cdcom are now build as normal ones not to force deps, use standard list
2044#
2045# 2002 03 29
2046# fix a bug in nolive mode that prevent rpmsrate to be put on discs
2047#
2048# 2002 05 13
2049# finish md5 check
2050# fix commented du in sub installation
2051#
2052# 2002 08 01
2053# add noauto options for rpmsdir
2054#
2055# 2002 08 14
2056# fix little bug in buildGenericHdlists
2057#
2058# 2002 10 02
2059# allow glob in rm function for live mode (need to do it for nolive mode)
2060#
2061# 20030401
2062# get_rpmsdir now manages hdlist dir
Note: See TracBrowser for help on using the repository browser.