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