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