source: soft/build_system/build_system/mkcd/tags/V4_1_6_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.6 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];
757
758#
759# clone
760#
761$functions{clone} =
762    [
763    # 0
764        [ "", "clone", 1, "<disc to clone>", "Clone the given disc",
765            sub {   my ($cd, $fn, $disc) = @_;
766                    my @a = ('clone', { disc => $disc });
767                    $config->{disc}[$cd]{function}{list}[$fn] = \@a;
768                    push @{$config->{disc}[$cd]{function}{data}{clone}}, \@a;
769                    push @{$config->{disc}[$cd]{steps}}, \@a;
770                    1
771          }, "Setting clone parameters"
772        ],
773          # 1
774        [ "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",
775            sub {   my ($cd, $fn, @dir) = @_;
776                    my $list = @{$config->{list}};
777                    while (@dir) {
778                        my $rpmdir = shift @dir;
779                        my $path = shift @dir or last;
780                        $config->{disc}[$cd]{function}{data}{dir}{$rpmdir} = [ "clone_dir", { reploc => $path } ];
781                        $config->{disc}[$cd]{function}{list}[$fn][1]{rpmsdir} = $path;
782                        log_("clone: disc $cd adding list $list for virtual rep $rpmdir path $path\n", $config->{verbose}, $config->{LOG},3);
783                        $config->{list}[$list]{virtual} = [ { disc => $cd, repname => $rpmdir } ];
784                        push @{$config->{disc}[$cd]{fastgeneric}}, [ '', { repname => $rpmdir, lists => [ $list ] } ];
785                    }
786                    $config->{list}[$list]{done} = 1;
787                    1
788            }, "Setting directory name and path parameters"
789        ]
790#       [ "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",
791#           sub {   my ($cd, $fn,@to_del) = @_;
792#                   $config->{disc}[$cd]{function}{list}[$fn][1]{to_del} = \@to_del;
793#                   1
794#           }, "Setting delete parametes"
795#       ]
796];
797
798#
799# rm
800#
801$functions{rm} =
802    [
803     # 0
804        [ "", "rm", -1, "<disc to rm>", "Delete the given file or directory on the disc image",
805            sub {   my ($cd, $fn, @files) = @_;
806                    my @a = ('rm', { files => \@files });
807                    $config->{disc}[$cd]{function}{list}[$fn] = \@a;
808                    push @{$config->{disc}[$cd]{function}{data}{files}}, \@a;
809                    push @{$config->{disc}[$cd]{steps}}, \@a;
810                    1
811          }, "Setting rm parameters"
812        ],
813     # 1
814        [ "", "first", 0, "", "Remove files in the files copied with first option",
815            sub {
816                my ($cd, $fn) = @_;
817                $config->{disc}[$cd]{function}{list}[$fn][1]{first} = 1;
818                1
819            }, "Setting first flag"
820        ],
821];
822
823sub new {
824    my ($class, $conf) = @_;
825    $config = $conf;
826    bless {
827        config       => $conf,
828        functions    => \%functions
829    }, $class;
830}
831
832sub get_rpmsdir {
833    my ($type, $cd, $fn, $rpms, $opts) = @_;
834    my $options = '(?:(noauto):)?';
835    # FIXME taken from Tools.pm
836    my $match_val2 = q(((?:[^"\s]*(?:[^"\s]+|"[^\"]+")[^"\s]*)+));
837    foreach (@$rpms)  {
838        log_("get_rpmsdir: $_\n", $config->{verbose}, $config->{LOG}, 3);
839        my %options;
840        foreach (keys %$opts)  { $options{$_} = $opts->{$_} }
841        if (my ($opt, $hdlist, $hdlist_path, $hdlist_name, $pubkey) = m/${options}hdlist:([^,]+),([^,]+),$match_val2(?:,(.*))?/) {
842            if (!$config->{disc}[$cd]{function}{list}[$fn][1]{fixed}) {
843                $config->{disc}[$cd]{function}{list}[$fn][1]{fixed} = 1;
844                log_("WARNING get_rpmsdir: hdlist rpmsdir could only be fixed, forcing fixed flag\n", $config->{verbose}, $config->{LOG}, 0);
845            }
846            my $list = add_list($cd, "hdlist_rpm", $hdlist, $pubkey);
847            my $new_cd = @{$config->{disc}};
848            log_("get_rpmsdir: adding virtual disc $new_cd for hdlist $hdlist (path $hdlist_path disc_name $hdlist_name)\n", $config->{verbose}, $config->{LOG}, 3);
849            push @{$config->{virtual_disc}}, $new_cd;
850            $functions{disc}[0][5]->($new_cd, $hdlist_name, 0, 0, $hdlist_name, 0);
851            $functions{dir}[0][5]->($new_cd, 1, "rpms", $hdlist_path);
852            $functions{generic}[0][5]->($new_cd, 2, "rpms", $list);
853            $options{hdlist} = $hdlist;
854            foreach (split ',', $opt)  { $options{$_} = 1 }
855            push @{$config->{disc}[$cd]{function}{list}[$fn][1]{$type}}, [ $list, $new_cd, 'rpms', \%options ]
856        } elsif (my ($opt, $cdrep, $repname, $list) = m,$options(\d+)/([^/]+)(?:/(\d+))?,) {
857            foreach (split ',', $opt)  { $options{$_} = 1 }
858            push @{$config->{disc}[$cd]{function}{list}[$fn][1]{$type}}, [ $list, $cdrep, $repname, \%options ]
859        } else {
860            log_("ERROR get_rpmsdir: could not parse rpmsdir value $_\n", $config->{verbose}, $config->{LOG}, 0);
861        }
862    }
863}
864
865sub add_list {
866    my ($cd, $type, $pkg_list, $pubkey) = @_;
867    my $list = @{$config->{list}};
868    log_("add_list: disc $cd adding list $list for $type $pkg_list\n", $config->{verbose}, $config->{LOG}, 3);
869    $config->{list}[$list]{packages} = [ { $type => [ $pkg_list ] } ];
870    $config->{list}[$list]{done} = 1;
871    $config->{list}[$list]{nosize} = 1;
872    if ($pubkey) {
873        log_("add_list: adding pubkey file $pubkey for list $list\n", $config->{verbose}, $config->{LOG}, 3);
874        push @{$config->{list}[$list]{keyfiles}}, $pubkey;
875    }
876    $list
877}
878
879sub template {
880    my ($class, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discsFiles) = @_;
881    if (!$fixed) {
882        my $size;
883        if ($nolive) {
884            return $size
885        } else {
886
887        }
888    } elsif ($fixed == 1) {
889        my $mkiso;
890        if ($nolive) {
891        } else {
892           
893        }
894    } elsif ($fixed == 2) {
895        my $mkiso;
896        if ($nolive) {
897        } else {
898           
899        }
900    }   
901}
902
903sub clone {
904    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discsFiles) = @_;
905    my $graft = $totgraft->{$cdnum};
906    my $disc_src = $fct->[1]{disc};
907    if ($fixed == 0) {
908        if ($nolive) {
909            if ($fct->[1]{full_copy}) {
910                log_("clone: full copy of disc $disc_src nolive mode\n", $config->{verbose}, $config->{LOG},2);
911                if ($totgraft->{$disc_src}) {
912                    log_("clone: getting disc from current build\n", $config->{verbose}, $config->{LOG},3);
913                    $graft = $totgraft->{$disc_src}
914                } elsif (-d "$dir/$disc_src") {
915                    log_("clone: getting disc from filesystem\n", $config->{verbose}, $config->{LOG},3);
916                    $graft->{"/"}{"$dir/$disc_src"} = 1
917                } else {
918                    log_("ERROR clone: source disc not available\n", $config->{verbose}, $config->{LOG},3);
919                }
920            }
921        } else {
922            if ($fct->[1]{full_copy}) {
923                log_("clone: full copy of disc $disc_src\n", $config->{verbose}, $config->{LOG},2);
924                if (-d "$dir/$disc_src") {
925                    log_("clone: getting disc from filesystem\n", $config->{verbose}, $config->{LOG},3);
926                    $graft->{"/"}{"$dir/$disc_src"} = undef;
927                    cpal("$dir/$disc_src/", "$dir/$cdnum");
928                } else {
929                    log_("ERROR clone: source disc not available\n", $config->{verbose}, $config->{LOG},3);
930                }
931            }
932        }
933    }
934    1
935}
936
937sub rm {
938    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discsFiles) = @_;
939    my $graft = $totgraft->{$cdnum};
940    my $files = $fct->[1]{files};
941#    use File::Find;
942    if ($fixed == 0) {
943        if ($nolive) {
944            # FIXME this does not really works in no live mode (exclude files does not work with mkisofs properly)
945            my $size;
946            foreach my $r (@$files) {
947                log_("rm: trying $r\n", $config->{verbose}, $config->{LOG},2);
948                $r = "/$r" if $r !~ m,^/,;
949                #$graft->{$r} = 3;
950                $r =~ s/\*/.+/;
951                foreach my $g (keys %$graft) {
952                    ref $graft->{$g} or next;
953                    log_("rm: graft $g ($r)\n", $config->{verbose}, $config->{LOG},3);
954                    if ($g =~ m,^/?$r/?$,) {
955                        foreach my $f (keys %{$graft->{$g}}) {
956                             $size -= du $f
957                        }
958                        $g =~ m,^/, and $g = "/$g";
959                        $graft->{$g} = 0;
960                        log_("rm: deleting $g (size $size)\n", $config->{verbose}, $config->{LOG},4);
961                    }
962                }
963                my @up = grep { $_ } split '/', $r;
964                my $last = pop @up;
965                while (@up) {
966                    my $uppath = join '/', @up;
967                    $uppath = "/$uppath";
968                    log_("rm: testing $uppath\n", $config->{verbose}, $config->{LOG},4);
969                    $uppath = $graft->{$uppath} ? $uppath : $graft->{"/$uppath"} ? "/$uppath" : $graft->{"$uppath/"} ? "$uppath/" : "/$uppath/";
970                    log_("rm: graft $graft->{$uppath}\n", $config->{verbose}, $config->{LOG},4);
971                    if (ref $graft->{$uppath}) {
972                        foreach (keys %{$graft->{$uppath}}) {
973                            log_("rm: testing $uppath ($_)\n", $config->{verbose}, $config->{LOG},4);
974                            if (-d $_) {
975                                log_("rm: opening $_\n", $config->{verbose}, $config->{LOG},4);
976                                opendir my $dir, $_ or next;
977                                foreach my $first (readdir $dir) {
978                                    $first =~ /^\.{1,2}$/ and next;
979                                    log_("rm: FIRST 2 $first in $uppath$first ($r) " . $graft->{"$uppath$first"} . "\n", $config->{verbose}, $config->{LOG},4);
980                                    if ("$uppath$first" ne $r) {
981                                        log_("rm: adding $_/$first in $uppath\n", $config->{verbose}, $config->{LOG},4);
982                                        $graft->{"$uppath$first"} ||= {};
983                                        $graft->{"$uppath$first"}{"$_/$first"} = 1;
984                                    }
985                                }
986                                delete $graft->{$uppath}{$_}
987                            }
988                        }
989                        last
990                    }
991                    $last = pop @up;
992                }
993            }
994#           my @find;
995#           foreach my $k (keys %$graft){
996#               ref $graft->{$k} or next;
997#               foreach my $f (keys %{$graft->{$k}}){
998#                   $f =~ s|/{2,}|/|g;
999#                   find({ wanted => sub { s,/?\Q$f,,; $_ = "$k/$_"; s|/{2,}|/|g; push @find, [ $f, $_ ] }, no_chdir => 1 }, $f);
1000#               }
1001#           }
1002#           foreach (@$files) { s|/{2,}|/|g }
1003#           foreach my $t (@find){
1004#               my ($k, $f) = @$t;
1005#               foreach my $r (@$files){
1006#                   next if $f =~ m,^/?$r/[^/]+,;
1007#                   if ($f =~ m,^/?$r/?$,){
1008#                       log_("rm: deleting $f (path $k regexp $r)\n", $config->{verbose}, $config->{LOG});
1009#                       $graft->{$f} = 0;
1010#                       $size -= du $k;
1011#                       $size -= du "$k/$f";
1012#                   }
1013#               }
1014#           }
1015            return $size
1016        } else {
1017            my $first = "first/" if $fct->[1]{first};
1018            foreach (@$files) {
1019                my @file = glob "$dir/$first$cdnum/$_";
1020                foreach my $f (@file) {
1021                    if (-d $f) {
1022                        log_("rm: deleting directory $f\n", $config->{verbose}, $config->{LOG}, 2);
1023                        my $err = rmtree $f;
1024                        if (!$err) { log_("ERROR rm: deleting $f failed: $!,\n", $config->{verbose}, $config->{LOG}) }
1025                    } else {
1026                        log_("rm: deleting file $f\n", $config->{verbose}, $config->{LOG},2);
1027                        my $err = unlink $f;
1028                        if (!$err) { log_("ERROR rm: deleting $f failed: $!,\n", $config->{verbose}, $config->{LOG}) }
1029                    }
1030                }
1031            }
1032            return 
1033        }
1034    }
1035    1
1036}
1037
1038sub cp {
1039    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discsFiles, $sort) = @_;
1040    my $graft = $totgraft->{$cdnum};
1041    if (!$fixed) {
1042        my $size;
1043        my $source = $fct->[1]{src};
1044        my $dest = $fct->[1]{dest};
1045        if ($nolive) {
1046            $size += du($source, $inode);
1047            log_("cp: copying $source => $dest (size $size)\n", $config->{verbose}, $config->{LOG},1);
1048            $graft->{"/$dest"}{$source} = 1;
1049            return $size
1050        } else {
1051            my $first = "first/" if $fct->[1]{first};
1052            cpal($source, "$dir/$first$cdnum/$dest");
1053            $graft->{"$dir/$cdnum/$dest"}{$source} = 1;
1054            push @{$sort->{$cdnum}}, [ "$dir/$first$cdnum/$dest" ] if $fct->[1]{first};
1055            return
1056        }
1057    }
1058}
1059
1060sub fixed {
1061    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discs_file, $sort, $cdsize) = @_;
1062    my $graft = $totgraft->{$cdnum};
1063    my $destination = $fct->[1]{dest};
1064    my ($fdest, $nocopy);
1065    my $rep = $fct->[1]{dir}; 
1066    my $list = $fct->[1]{list};
1067    my $dest_dir = $cd->{function}{data}{dir}{$rep}[1];
1068    my $reploc = $dest_dir->{reploc};
1069    my $reploc_full = "$dir/$cdnum/$reploc/";
1070    if ($destination) {
1071        $fdest = "$dir/$cdnum/$destination";
1072    } else {
1073        $fdest = "$dir/$cdnum/$reploc";
1074        $nocopy = 1
1075    }
1076    my $size;
1077    if (!$fixed) {
1078        my $source = $fct->[1]{source_dir};
1079        my $uppath = $destination;
1080        $uppath =~ s,([^/]+),../,g;
1081        $uppath =~ s,/+,/,g;
1082        log_("DEST: $destination uppath $uppath dest $reploc_full\n", $config->{verbose}, $config->{LOG},3);
1083        -d $fdest or mkpath $fdest;
1084        if ($nolive) {
1085            -d $reploc_full or mkpath $reploc_full;
1086            opendir my $A, $source;
1087            log_("fixed: $source\n", $config->{verbose}, $config->{LOG},3);
1088            my $struct_v = $config->{struct_version};
1089            my $media = $config->{struct}{$struct_v}{media};
1090            my $install_dir = $config->{struct}{$struct_v}{install};
1091            foreach (readdir $A) {
1092                /^\.{1,2}$/ and next;
1093                if (! /^$install_dir$/) {
1094                    $size += du("$source/$_", $inode);
1095                    log_("fixed: adding $_ (size $size)\n", $config->{verbose}, $config->{LOG},4);
1096                    $graft->{"/$destination/$_/"}{"$source/$_"} = 1
1097                } else {
1098                    $graft->{"/$reploc/"}{"$source/$media/"} = 1
1099                }
1100            }
1101            log_("fixed: creating symlink $uppath$reploc => $fdest/RPMS\n", $config->{verbose}, $config->{LOG}, 4);
1102            my $err = symlink "$uppath$reploc", "$fdest/RPMS";                                           
1103            !$err and log_("ERROR fixed: $!\n", $config->{verbose}, $config->{LOG});
1104            $graft->{"/"}{"$fdest/RPMS"} = 1;
1105            $cdsize->{real}{rep}{$cdnum}{$rep}{$list} = $size
1106        } else {
1107            log_("fixed: copying $source to $fdest\n", $config->{verbose}, $config->{LOG});
1108            cpal($source, $fdest);
1109            if (!$nocopy) {
1110                log_("fixed: creating symlink $uppath$reploc => $fdest/RPMS\n", $config->{verbose}, $config->{LOG});
1111                my $err = symlink "$uppath$reploc", "$fdest/RPMS";                                           
1112                !$err and log_("ERROR fixed: $!\n", $config->{verbose}, $config->{LOG});
1113            }
1114            $cdsize->{real}{rep}{$cdnum}{$rep}{$list} = du($source)
1115        }
1116        log_("fixed: real rep cd $cdnum rep $rep list $list size $cdsize->{real}{rep}{$cdnum}{$rep}{$list}\n", $config->{verbose}, $config->{LOG}, 8);
1117        return $size
1118    } else {
1119        # there is only one (virtual) list for fixed
1120        my $list = $fct->[1]{list};
1121        log_("fixed: list $list\n", $config->{verbose}, $config->{LOG});
1122        my $rep = $fct->[1]{dir}; 
1123        my $sep_arch = $dest_dir->{sep_arch};
1124        my $nolive_rep = $reploc;
1125        if ($nolive) {
1126            if (!$nocopy) {
1127                foreach my $src (keys %{$cdfile->[$cdnum]{$rep}{$list}}) {
1128                    log_("fixed: src $src\n", $config->{verbose}, $config->{LOG});
1129                    foreach (@{$cdfile->[$cdnum]{$rep}{$list}{$src}}) {
1130                        $graft->{"$nolive_rep/$_->[1]"}{"$src/$_->[1]"} = 1
1131                    }
1132                }
1133            }
1134        } else {
1135            if (!$nocopy) {
1136                foreach my $src (keys %{$cdfile->[$cdnum]{$rep}{$list}}) {
1137                    log_("fixed: src $src\n", $config->{verbose}, $config->{LOG});
1138                    foreach (@{$cdfile->[$cdnum]{$rep}{$list}{$src}}) {
1139                        link("$fdest/$_->[1]", "$reploc_full/$_->[1]") 
1140                    }
1141                }
1142            }
1143        }
1144        $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);
1145        $size
1146    }
1147}
1148
1149sub cdcom {
1150    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discs_file) = @_;
1151    my $graft = $totgraft->{$cdnum};
1152    if (!$fixed) {
1153        my $size;
1154        my $source = $fct->[1]{source_dir};
1155        my $dest = $config->{disc}[$cdnum]{function}{data}{dir}{$fct->[1]{dir}}[1]{reploc};
1156        my $destination = $fct->[1]{dest};
1157        my $uppath = $destination;
1158        $uppath =~ s,([^/]+),../,g;
1159        $uppath =~ s,/+,/,g;
1160        log_("DEST: $destination uppath $uppath dest $dest\n", $config->{verbose}, $config->{LOG},3);
1161        my $fdest = "$dir/$cdnum/$destination";
1162        my $struct_v = $config->{struct_version};
1163        my $media = $config->{struct}{$struct_v}{media};
1164        my $install_dir = $config->{struct}{$struct_v}{install};
1165        if ($nolive) {
1166            my $path = "$dir/$cdnum/$dest";
1167            -d $path or mkpath $path;
1168            opendir my $A, $source;
1169            log_("cdcom: $source\n", $config->{verbose}, $config->{LOG},3);
1170            foreach (readdir $A) {
1171                /^\.{1,2}$/ and next;
1172                if (! /^$install_dir$/) {
1173                    $size += du("$source/$_", $inode);
1174                    log_("cdcom: adding $_ (size $size)\n", $config->{verbose}, $config->{LOG},4);
1175                    $graft->{"/$destination/$_/"}{"$source/$_"} = 1
1176                } else {
1177                    $graft->{"/$dest/"}{"$source/$media/"} = 1
1178                }
1179            }
1180            #local *A; opendir A, "$source/Mandrake/RPMS";
1181            #foreach (readdir A){
1182            #    /^\.{1,2}$/ and next;
1183            #    my $newdest = readlink "$source/Mandrake/RPMS/$_";
1184            #    $newdest =~ s,((?:../))*(.*), $1/$destination/$2,;
1185            #    log_("cdcom: creating symlink $dest/$_ => $newdest\n", $config->{verbose}, $config->{LOG});
1186            #    my $err = symlink $newdest, "$dir/$cdnum/$dest/$_";
1187            #    !$err and log_("ERROR cdcom: $!\n", $config->{verbose}, $config->{LOG}) and next;
1188            #    $graft->{"/$dest/"}{"$dir/$cdnum/$dest/$_"} = 1
1189            #}
1190            #$graft->{"/$dest/"}{"$source/Mandrake/RPMS"} = 1;
1191            log_("cdcom: creating symlink $uppath$dest => $fdest/RPMS\n", $config->{verbose}, $config->{LOG}, 4);
1192            -d $fdest or mkpath $fdest;
1193            my $err = symlink "$uppath$dest", "$fdest/RPMS";                                           
1194            !$err and log_("ERROR cdcom: $!\n", $config->{verbose}, $config->{LOG});
1195            $graft->{"/"}{"$fdest/RPMS"} = 1;
1196            return $size
1197        } else {
1198            -f $fdest or mkpath $fdest;
1199            cpal($source, $fdest, $media);
1200            local *A; opendir A, "$source/$media";
1201            foreach (readdir A) {
1202                /^\.{1,2}$/ and next;
1203                my $newdest = readlink "$source/$media/$_";
1204                $newdest =~ s,((?:../)*)(.*),$1$destination/$2,;
1205                log_("cdcom: creating symlink $dir/$cdnum/$dest/$_ => $dir/$cdnum/$dest/$newdest\n", $config->{verbose}, $config->{LOG},2);
1206                my $err = link "$dir/$cdnum/$dest/$newdest", "$dir/$cdnum/$dest/$_";
1207                # should be OK with new du with inode checking
1208                #$size -= du("$dir/$cdnum/$dest/$newdest");
1209                !$err and log_("ERROR cdcom: $!\n", $config->{verbose}, $config->{LOG})
1210            }
1211            log_("cdcom: creating symlink $uppath$dest => $fdest/RPMS\n", $config->{verbose}, $config->{LOG});
1212            my $err = symlink "$uppath$dest", "$fdest/RPMS";                                           
1213            !$err and log_("ERROR cdcom: $!\n", $config->{verbose}, $config->{LOG});
1214               
1215            return $size
1216        }
1217        my $rep = $fct->[1]{dir}; 
1218        my $lists = $fct->[1]{lists};
1219        my $dest_dir = $cd->{function}{data}{dir}{$rep}[1];
1220        my $reploc = "$dir/$cdnum/$dest_dir->{reploc}/";
1221        my $sep_arch = $dest_dir->{sep_arch};
1222        foreach my $list (@$lists) {
1223            $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});
1224        }
1225        return $size
1226    }
1227}
1228
1229sub process_hdlist_flags {
1230    my ($nolive, $synthesis, $hdlist, $discs_files, $dir, $cdnum, $fct, $rep, $reploc, $sep_arch, $graft, $list, $nolive_rep) = @_;
1231    my $size;
1232    log_("process_hdlist_flags: synthesis $synthesis hdlist $hdlist disc $cdnum reploc $reploc\n", $config->{verbose}, $config->{LOG});
1233    my $media_hdlist = $config->{struct}{$config->{struct_version}}{media_hdlist};
1234    if ($nolive) {
1235        if ($synthesis || $hdlist) {
1236            if (ref $discs_files) {
1237                my (undef, $path) = buildGenericHdlist($dir, $cdnum, $fct, $rep, "$reploc/$media_hdlist", $discs_files, $sep_arch);
1238                if ($fct->[1]{hdlist})  {
1239                    $size += du("$reploc/$media_hdlist/hdlist.cz");
1240                    $graft->{"$nolive_rep/$media_hdlist/hdlist.cz"}{"$reploc/$media_hdlist/hdlist.cz"} = 1
1241                }
1242                if ($fct->[1]{synthesis}) {
1243                    $size += du("$reploc/$media_hdlist/synthesis.hdlist.cz");
1244                    $graft->{"$nolive_rep/$media_hdlist/synthesis.hdlist.cz"}{"$reploc/$media_hdlist/synthesis.hdlist.cz"} = 1
1245                }
1246            } else {
1247                log_("WARNING process_hdlist_flags: disc $cdnum rep $rep list $list is empty, no hdlist or synthesis created\n", $config->{verbose}, $config->{LOG});
1248            }
1249        }
1250    } else {
1251        if ($synthesis || $hdlist) {
1252            if (ref $discs_files) {
1253                buildGenericHdlist($dir, $cdnum, $fct, $rep, "$reploc/$media_hdlist", $discs_files, $sep_arch);
1254            } else {
1255                log_("WARNING process_hdlist_flags: disc $cdnum rep $rep list $list is empty, no hdlist or synthesis created\n", $config->{verbose}, $config->{LOG});
1256            }
1257        }
1258    }
1259    $size
1260}
1261
1262sub printSize {
1263    my ($img, $file) = @_;
1264    local *A; open A, ">$file";
1265    my $size = imageSize($img);
1266    log_("printSize: creating $file for $img\n", $config->{verbose}, $config->{LOG});
1267    if ($size) {
1268        print A <<EOF
1269#!/usr/bin/perl
1270
1271\$width = $size->[0];
1272\$height = $size->[1];
1273\@data = ()
1274EOF
1275    } else {
1276        print "ERROR advertising: $size/n";
1277        return 0
1278    }
1279}
1280
1281sub advertising {
1282    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode) = @_;
1283    my $graft = $totgraft->{$cdnum};
1284    if (!$fixed) {
1285        my $size;
1286        my $struct_v = $config->{struct_version};
1287        my $extra = $config->{struct}{$struct_v}{extra};
1288        if ($nolive) {
1289            log_("Getting advertising images size\n", $config->{verbose}, $config->{LOG});
1290            my $addir = "$extra/advertising" . ($fct->[1]{lang} ? ".$fct->[1]{lang}" : "");
1291            my $rep = "$dir/$cdnum/$addir";
1292            -d $rep or mkpath $rep;
1293            local *L; open L, ">$rep/list";
1294            foreach (@{$fct->[1]{img}}) {
1295                s/\.png$//;
1296                my ($name) = m,([^/]*)$,;
1297                $size += du($_, $inode);
1298                print L "$name\n";
1299                if (-f "$_.png") { $graft->{"$addir/$name.png"}{"$_.png"} = 1 } else { next }
1300                if (-f "$_.pl") { $graft->{"$addir/$name.pl"}{"$_.pl"} = 1
1301                } else {
1302                    printSize("$_.png", "$rep/$name.pl");
1303                    $graft->{"$addir/$name.pl"}{"$_.pl"} = 1
1304                }
1305                -f "${_}_icon.png" and $graft->{"$addir/$name-icon.png"}{"${_}_icon.png"} = 1
1306            } 
1307            close L;
1308            $graft->{"$addir/list"}{"$rep/list"} = 1;
1309            $size += du("$rep/list");
1310            return $size
1311        } else {
1312            my $rep = "$dir/$cdnum/$extra/advertising" . ($fct->[1]{lang} ? ".$fct->[1]{lang}" : "");
1313            log_("Creating advertising images directory ($rep)\n", $config->{verbose}, $config->{LOG});
1314            -d $rep or mkpath $rep;
1315            local *L; open L, ">$rep/list";
1316            foreach (@{$fct->[1]{img}}) {
1317                s/\.png$//;
1318                my ($name) = m,([^/]*)$,;
1319                if (-f "$_.png") { cpal("$_.png", "$rep/$name.png") } else { next }
1320                if (-f "$_.pl") { cpal("$_.pl", "$rep/$name.pl") } else { printSize("$_.png", "$rep/$name.pl") }
1321                -f "${_}_icon.png" and cpal("${_}_icon.png", "$rep/${name}_icon.png");
1322                print L "$name.png\n"
1323            }
1324            close L;
1325            return
1326        }
1327    }
1328}
1329
1330sub dir {
1331    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd) = @_;
1332    if (!$fixed) {
1333        if ($nolive) {
1334            return 0
1335        } else {
1336            my $reploc = "$dir/$cdnum/$fct->[1]{reploc}";
1337            log_("dir: creating $reploc\n", $config->{verbose}, $config->{LOG});
1338            -d $reploc or mkpath $reploc;
1339            return 0   
1340        }
1341    }
1342}
1343
1344sub generic {
1345    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discsFile) = @_;
1346    my $graft = $totgraft->{$cdnum};
1347    my $size;
1348    my $rep = $fct->[1]{repname};
1349    my $dest_dir = $cd->{function}{data}{dir}{$rep}[1];
1350    my $nolive_rep = $dest_dir->{reploc};
1351    if ($fixed) {
1352        my $lists = $fct->[1]{lists};
1353        log_("generic: rep $rep\n", $config->{verbose}, $config->{LOG});
1354        my $reploc = "$dir/$cdnum/$dest_dir->{reploc}/";
1355        my $sep_arch = $dest_dir->{sep_arch};
1356        my %list;
1357        if ($sep_arch) {
1358            if (-f "$reploc/list") {
1359                open my $list_file, "$reploc/list";
1360                while (<$list_file>) {
1361                    chomp;
1362                    $list{$_} = 1
1363                }
1364            }
1365        }
1366        if ($nolive) {
1367            if ($fixed > 0) {
1368                foreach my $list (@$lists) {
1369                    log_("generic: list $list\n", $config->{verbose}, $config->{LOG});
1370                    foreach my $src (keys %{$cdfile->[$cdnum]{$rep}{$list}}) {
1371                        log_("generic: src $src\n", $config->{verbose}, $config->{LOG});
1372                        foreach (@{$cdfile->[$cdnum]{$rep}{$list}{$src}}) {
1373                            if ($_->[0] == 1) {
1374                                my $d = $nolive_rep;
1375                                if ($sep_arch) {
1376                                    $_->[1] =~ /([^.]+)\.rpm$/  or log_("WARNING generic: could not find arch of $_\n", $config->{verbose}, $config->{LOG});
1377                                    $d .= "/$1"
1378                                }
1379                                $graft->{"$d/$_->[1]"}{"$src/$_->[1]"} = 1
1380                            } elsif ($_->[0] == 2) {
1381                                my $d = $nolive_rep;
1382                                if ($sep_arch) {
1383                                    $_->[1] =~ /([^.]+)\.rpm$/  or log_("WARNING generic: could not find arch of $_\n", $config->{verbose}, $config->{LOG});
1384                                    $d .= "/$1"
1385                                }
1386                                delete $graft->{"$d/$_->[1]"}{"$src/$_->[1]"} 
1387                            }
1388                        }
1389                    }
1390                    $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);
1391                }
1392            }
1393            if ($sep_arch) {
1394                open my $list_file, ">$reploc/list";
1395                foreach (sort keys %list) { print $list_file "$_\n" if $list{$_} }
1396                close $list_file;
1397                $size += du("$dir/$cdnum/$reploc/list");
1398                $graft->{"$nolive_rep/list"}{"$reploc/list"} = 1
1399            }
1400            return $size
1401        } else {
1402            foreach my $list (@$lists) {
1403                log_("generic: list $list\n", $config->{verbose}, $config->{LOG});
1404                foreach my $src (keys %{$cdfile->[$cdnum]{$rep}{$list}}) {
1405                    log_("generic: src $src\n", $config->{verbose}, $config->{LOG});
1406                    foreach (@{$cdfile->[$cdnum]{$rep}{$list}{$src}}) {
1407                        if ($_->[0] == 1) {
1408                            my $d = $reploc;
1409                            if ($sep_arch) {
1410                                $_->[1] =~ /([^.]+)\.rpm$/ or log_("WARNING generic: could not find arch of $_\n", $config->{verbose}, $config->{LOG});
1411                                $d .= "/$1";
1412                                $list{"$1/$_->[1]"} = 1;
1413                                -d $d or mkdir $d;
1414                            }
1415                            cpal("$src/$_->[1]", $d)   
1416                        }  elsif ($_->[0] == 2) {
1417                            log_("generic: deleting $reploc/$_->[1]\n", $config->{verbose}, $config->{LOG});
1418                            my $d = $reploc;
1419                            if ($sep_arch) {
1420                                $_->[1] =~ /([^.]+)\.rpm$/ or log_("WARNING generic: could not find arch of $_\n", $config->{verbose}, $config->{LOG});
1421                                $list{"$1/$_->[1]"} = 0;
1422                                $d = "$reploc/$1";
1423                            }
1424                            unlink "$d/$_->[1]";
1425                        }
1426                    }
1427                }
1428                $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);
1429            }
1430            if ($sep_arch) {
1431                open my $list_file, ">$reploc/list";
1432                foreach (sort keys %list) { print $list_file "$_\n" if $list{$_} }
1433                close $list_file;
1434            }
1435            return 0
1436        }
1437       
1438    }
1439}
1440
1441sub printVERSION {
1442    my ($name, $file, $rel_info, $prefix) = @_;
1443    open my $VERSION, ">$file";
1444    my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = gmtime(time());
1445    $year += 1900;
1446    my $tag;
1447    foreach (qw(branch product arch)) {
1448        $tag .= "$rel_info->{$_}-" if $rel_info->{branch}
1449    }
1450    $tag .= $rel_info->{tag} if $rel_info->{tag};
1451    printf $VERSION "${prefix}Mandriva Linux $name $tag %04d%02d%02d $hour:%02d\n", $year, $mon+1, $mday, $min;
1452}
1453
1454sub buildGenericHdlist {
1455    my ($dir, $cdnum, $fct, $rep, $reploc, $discsFilescdrep, $sep_arch) = @_;
1456    my @rpm = map { "$discsFilescdrep->{$_}/$_.rpm" } keys %$discsFilescdrep;
1457   
1458    if ($fct->[1]{synthesis}) {
1459        -d $reploc or mkpath $reploc;
1460    }
1461    # $hdlist = "$reploc/hdlist$cdnum$rep.cz" if $fct->[1]{hdlist};
1462    # my $synthesis = "$reploc/synthesis.hdlist$cdnum$rep.cz" if $fct->[1]{synthesis};
1463    my ($hdlist, $synthesis, @md5files);
1464    my $struct_v = $config->{struct_version};
1465    if ($fct->[1]{hdlist}) {
1466        $hdlist = "$reploc/hdlist.cz";
1467        -d $reploc or mkdir $reploc;
1468        push @md5files, $hdlist
1469    }
1470    if ($fct->[1]{synthesis}) {
1471        $synthesis = "$reploc/synthesis.hdlist.cz";
1472        -d $reploc or mkdir $reploc;
1473        push @md5files, $synthesis
1474    }
1475    my $urpm = mkcd_build_hdlist(1, [ 0, { hdlist => $hdlist, rpms => \@rpm , synthesis => $synthesis } ], "$config->{tmp}/.mkcd_build_hdlist");
1476    compute_files_md5("$reploc/MD5SUM", \@md5files);
1477    $urpm, $reploc
1478}
1479
1480sub buildInstallHdlist {
1481    my ($dir, $cdnum, $inst, $list, $discsFiles, $sort, $nolive, $cdsize) = @_;
1482    my (@hdlist, @hdlist_list);
1483    my $struct_v = $config->{struct_version};
1484    my $media_info = $config->{struct}{$struct_v}{media_info};
1485    my $media_base = $config->{struct}{$struct_v}{media_base};
1486    -d "$dir/$cdnum/$media_info" or mkpath "$dir/$cdnum/$media_info";
1487    open my $HDLISTS, ">$dir/$cdnum/$media_info/hdlists";
1488    my $media_cfg = "$dir/$cdnum/$media_info/media.cfg";
1489    my $rel_info = $inst->[1]; 
1490    unlink $media_cfg;
1491    printVERSION($config->{name}, $media_cfg, $rel_info, '# ');
1492    open my $MEDIACFG, ">>$media_cfg";
1493    if ($rel_info->{version} || $rel_info->{branch} || $rel_info->{arch}) {
1494        print $MEDIACFG "\n[media_info]\n";
1495        foreach (qw(version branch arch product minor subversion)) {
1496            print $MEDIACFG "$_=$rel_info->{$_}\n" if $_;
1497        }
1498        print $MEDIACFG "\n";
1499    }
1500    if ($inst->[1]{suppl}) {
1501        print $HDLISTS "suppl\n";
1502        print $MEDIACFG "suppl=1\n"
1503    }
1504    if ($inst->[1]{askmedia}) {
1505        print $HDLISTS "askmedia\n";
1506        print $MEDIACFG "askmedia=1\n"
1507    }
1508    my (%rpmdone, %cd_rep);
1509    my %kerneldone;
1510    my $repnum = 1;
1511    my (@thisInstallRep, @check, @md5files);
1512    my $headers_dir = "$config->{tmp}/.mkcd_build_hdlist";
1513    my $path = "$dir/$cdnum/$media_info";
1514    my $suppl_cd = $inst->[1]{suppl_cd};
1515    my $suppl_postfix = 's' if $suppl_cd;
1516    log_("buildInstallHdlist: suppl_postfix is '$suppl_postfix' ($suppl_cd && $struct_v)\n", $config->{verbose}, $config->{LOG});
1517    foreach my $rd (@{$inst->[1]{tmp_rpmsdir}}) {
1518        my ($ls, $cdrep, $repname, $opts) = @$rd;
1519        log_("buildInstallHdlist: suppl_cd $suppl_cd cd $cdrep repname $repname fixed $opts->{fixed}\n", $config->{verbose}, $config->{LOG});
1520        next if $suppl_cd && $opts->{fixed};
1521        if (!$list->{$cdrep}) { log_("WARNING buildInstallHdlist: disc $cdrep not in list, ignoring\n", $config->{verbose}, $config->{LOG}); next }
1522        my $a = $discsFiles->[$cdrep]{$repname};
1523        if (!(ref($a) && %$a)) { log_("WARNING buildInstallHdlist: $cdrep/$repname is empty\n", $config->{verbose}, $config->{LOG}); next }
1524        my $realcd = $config->{disc}[$cdrep]{name};
1525        my $rpmdir = $config->{disc}[$cdrep]{function}{data}{dir}{$repname}[1]{reploc};
1526        $rpmdir .= "/%{ARCH}" if $config->{disc}[$cdrep]{function}{data}{dir}{$repname}[1]{sep_arch};
1527        if (!$rpmdir) { log_("ERROR buildInstallHdlist: disc $cdrep: $repname not defined\n", $config->{verbose}, $config->{LOG}); next }
1528        $hdlist[$repnum]{rpms} = [];
1529        if ($opts->{oem}) {
1530            log_("buildInstallHdlist: oem mode for $cdrep/$repname ($rpmdir)\n", $config->{verbose}, $config->{LOG});
1531            foreach (@{$inst->[1]{oem}{hdlist}}) {
1532                my ($oemdir, $hl, $rep, $name) = @$_;
1533                print $HDLISTS "noauto:" if $opts->{noauto};
1534                print $HDLISTS "$hl $rep $name\n";
1535                my $hdlist = "$path/$hl";
1536                log_("buildInstallHdlist: adding oem hdlist $hdlist from $dir\n", $config->{verbose}, $config->{LOG});
1537                if ($inst->[1]{oem}{norebuild}) {
1538                    cpal("$oemdir/$hl", $hdlist)
1539                }
1540                $hdlist[$repnum]{hdlist} = $hdlist;
1541                $hdlist_list[$repnum] = $hdlist;
1542                $hdlist[$repnum]{synthesis} = "$path/synthesis.$hl";
1543                push @md5files, ($hdlist, "$path/synthesis.$hl");
1544                $repnum++
1545            }
1546        } else {
1547            #
1548            # even for live sources rpm are taken, this may lead to errors in some special case, where
1549            # the sources change after the live is created, but this could help in combined live/nolive
1550            # situation
1551            #
1552            log_("installation: $cdrep - $repname - list $ls\n", $config->{verbose}, $config->{LOG});
1553            my $size;
1554            foreach my $list (keys %{$discsFiles->[$cdrep]{$repname}}) {
1555                next if $ls && $ls != $list;
1556                $thisInstallRep[$cdrep]{$repname}{$list} = $discsFiles->[$cdrep]{$repname}{$list};
1557                push @{$check[$repnum]}, [$cdrep, $repname, $list];
1558                log_("installation: list $list\n", $config->{verbose}, $config->{LOG});
1559                my $cdsfilesrpms = $discsFiles->[$cdrep]{$repname}{$list};
1560                my %localdone;
1561                my %localkerneldone;
1562                # FIXME taken from tools
1563                my $kernel_like = "((?:(?:NVIDIA_)?kernel.*)|NVIDIA_nforce.*|cm2020.*)";
1564                #
1565               
1566                $size += $cdsize->{rep}{$cdrep}{$repname}{$list} || $cdsize->{real}{rep}{$cdrep}{$repname}{$list};
1567                log_("buildInstallHdlist: update ($opts->{update}) nodupkernel ($opts->{nodupkernel}) mode for $cdrep/$repname list $list\n", $config->{verbose}, $config->{LOG}, 3);
1568                push @{$hdlist[$repnum]{rpms}}, map {
1569                    if (/$kernel_like-[^.]+(?:\.[^.]+){3,5}mdk-[^-]+-[^-]+\.[^.]+$/) {
1570                        $kerneldone{$1} = 1;
1571                    }
1572                    if (/(.*)-[^-]+-[^-]+\.[^.]+$/) {
1573                        $rpmdone{$_} = 1;
1574                        $rpmdone{$1} = 1;
1575                        "$cdsfilesrpms->{$_}/$_.rpm" }
1576                    } grep {
1577                        if ($opts->{nodupkernel} && /($kernel_like-[^.]+(?:\.[^.]+){3,5}mdk)-[^-]+-[^-]+\.[^.]+$/) {
1578                            if ($localdone{$1} || $localkerneldone{$2}) { 0 }
1579                            else {
1580                                $localkerneldone{$2} = 1;
1581                                $localdone{$1} = 1;
1582                                ! ($kerneldone{$2} || $rpmdone{$_} || !$opts->{update} && $rpmdone{$1})
1583                            }
1584                        } elsif (/(.*)-[^-]+-[^-]+\.[^.]+$/) {
1585                            if ($localdone{$1}) { $inst->[1]{dup} }
1586                            else {
1587                                $localdone{$1} = 1;
1588                                $inst->[1]{dup} || ! ($rpmdone{$_} || !$opts->{update} && $rpmdone{$1})
1589                            } } } keys %$cdsfilesrpms;
1590                $hdlist[$repnum]{callback} = sub {
1591                       my ($urpm, $id) = @_;
1592                       my $pkg = $urpm->{depslist}[$id];
1593                       my $filename = $pkg->filename;
1594                       $urpm->{id}{$filename} = $id;
1595                       $pkg->pack_header
1596                   }
1597            }
1598            if (@{$hdlist[$repnum]{rpms}}) {
1599                if (!($opts->{fixed} && $opts->{nohdlist})) {
1600                    print $HDLISTS "noauto:" if $opts->{noauto};
1601                    my $size = int ($size/(1024*1024));
1602                    if ($realcd) {
1603                        print $HDLISTS "hdlist$repnum$suppl_postfix.cz $rpmdir disc $realcd $config->{disc}[$cdrep]{longname} (${size}m)\n"
1604                    } else {
1605                        print $HDLISTS "hdlist$repnum$suppl_postfix.cz $rpmdir $config->{disc}[$cdrep]{longname} (${size}m)\n"
1606                    }
1607                    my $media_dir = $rpmdir;
1608                    $media_dir =~ s/^$media_base\///;
1609                    print $MEDIACFG "[$media_dir]\nhdlist=media_info/hdlist$repnum$suppl_postfix.cz\nsize=${size}m\n";
1610                    print $MEDIACFG "noauto" if $opts->{noauto};
1611                    $cd_rep{$repnum} = [ $cdrep, $rpmdir ];
1612                    my %keys;
1613                    my $text;
1614                    foreach my $list (keys %{$discsFiles->[$cdrep]{$repname}}) {
1615                        foreach my $keyfile (@{$config->{list}[$list]{keyfiles}}) {
1616                            if (-f $keyfile) {
1617                                log_("buildInstallHdlist: dumping $keyfile in $dir/$cdnum/$media_info/pubkey$repnum$suppl_postfix\n", $config->{verbose}, $config->{LOG}, 3);
1618                                open my $KF, $keyfile;
1619                                my $key;
1620                                while (<$KF>) {
1621                                    $key .= $_;
1622                                    if (/^-----END PGP PUBLIC KEY BLOCK-----/) {
1623                                        if (! $keys{$key}) {
1624                                            $keys{$key} = 1;
1625                                            $text .= $key
1626                                        }
1627                                        $key = ''
1628                                    }
1629                                }
1630                                close $KF
1631                            } else { 
1632                                log_("ERROR buildInstallHdlist: $keyfile file does not exist\n", $config->{verbose}, $config->{LOG}, 0);
1633                            }
1634                        }
1635                    }
1636                    if ($text) {
1637                        open my $KEY, ">$dir/$cdnum/$media_info/pubkey$repnum$suppl_postfix";
1638                        print $KEY $text;
1639                        close $KEY;
1640                    }
1641                    $hdlist_list[$repnum] = "$path/hdlist$repnum$suppl_postfix.cz";
1642                    $hdlist[$repnum]{hdlist} = $hdlist_list[$repnum];
1643                    push @md5files, $hdlist_list[$repnum];
1644                    if ($inst->[1]{synthesis}) { 
1645                        $hdlist[$repnum]{synthesis} = "$path/synthesis.hdlist$repnum$suppl_postfix.cz";
1646                        push @md5files, $hdlist[$repnum]{synthesis}
1647                    }
1648                } else {
1649                    my $tmpdir = "$config->{tmp}/build/virtual_hdlist/$config->{name}/$cdnum/";
1650                    -d $tmpdir or mkpath $tmpdir;
1651                    $hdlist[$repnum]{hdlist} = "$tmpdir/hdlist$repnum.cz";
1652                    $hdlist_list[$repnum] = $hdlist[$repnum]{hdlist}
1653                }
1654                $repnum++
1655            } else {
1656                log_("WARNING installation: $cdrep $repname is empty, ignoring\n", $config->{verbose}, $config->{LOG});
1657            }
1658        }
1659    }
1660    # FIXME OEM mode not tested, moreover this norebuild test is wrong, new URPM need to rebuild hdlist.
1661    if (!$inst->[1]{oem}{norebuild}) {
1662        my $urpm = mkcd_build_hdlist($repnum - 1, \@hdlist, $headers_dir, "$path/depslist.ordered", "$path/provides", "$path/compss");
1663        get_sorted_packages($urpm, \@hdlist, $sort, \%cd_rep, "$dir/$cdnum", $nolive, $config->{verbose}, $config->{LOG});
1664    }
1665    log_("installation: compute_files_md5 @md5files\n", $config->{verbose}, $config->{LOG});
1666    compute_files_md5("$dir/$cdnum/$media_info/MD5SUM", \@md5files);
1667
1668    log_("installation: oem ($inst->[1]{oem})\n", $config->{verbose}, $config->{LOG});
1669    if (!$inst->[1]{oem}{oem}) {
1670        log_("installation: checkDiscs\n", $config->{verbose}, $config->{LOG});
1671        checkDiscs(\@hdlist_list, "$path/depslist.ordered", \@thisInstallRep, \@check, $config->{LOG}) or die "depslist.ordered, hdlists and RPMS mismatch\n";
1672    }
1673# Add sources
1674    foreach my $rd (@{$inst->[1]{srpmsdir}}) {
1675        my ($ls, $cdrep, $repname, $opts) = @$rd;
1676        if (!$list->{$cdrep}) { log_("WARNING buildInstallHdlist: disc $cdrep not in list, ignoring\n", $config->{verbose}, $config->{LOG}); next }
1677        foreach my $list (keys %{$discsFiles->[$cdrep]{$repname}}) {
1678            next if $ls && $ls == $list;
1679            $thisInstallRep[$cdrep]{$repname}{$list} = $discsFiles->[$cdrep]{$repname}{$list};
1680        }
1681    }
1682   
1683    my $pfile = "$dir/$cdnum/pkg-$config->{name}" . ($inst->[1]{tag} ? "-$inst->[1]{tag}" : "") . ".idx";
1684    printDiscsFile($config, \@thisInstallRep, $pfile);
1685    return $repnum, $path, $pfile, $suppl_postfix
1686}
1687
1688sub switch_theme {
1689    my ($dir, $theme) = @_;
1690
1691    opendir my $DIR, $dir or die "FATAL switch_theme: unable to open $dir\n";
1692    log_("switch_theme: checking main dir $dir\n", $config->{verbose}, $config->{LOG});
1693    foreach my $f (readdir $DIR){
1694        $f =~ /^\.{1,2}$/ and next;
1695        -d "$dir/$f" or next;
1696        log_("switch_theme: checking $dir/$f\n", $config->{verbose}, $config->{LOG});
1697        opendir my $ALT, "$dir/$f" or die "FATAL switch_theme: unable to open $dir/$f\n";
1698        foreach my $i (readdir $ALT) {
1699            $i =~ /all.rdz/ or next;
1700            log_("switch_theme: updating $i\n", $config->{verbose}, $config->{LOG});
1701            my $initrd = "$dir/$f/$i";
1702
1703            open my $NEW_INITRD, ">$initrd.new";
1704            open my $INITRD, $initrd;
1705
1706            binmode $NEW_INITRD;
1707            binmode $INITRD;
1708
1709            my $buf;
1710            while (1) {
1711                my $c = read $INITRD, $buf, 2048;
1712                $c or last;
1713                if ($buf =~ s/BOOTSPL//) {
1714                    print $NEW_INITRD $buf;
1715                    last
1716                }
1717                print $NEW_INITRD $buf
1718            }
1719            close $NEW_INITRD;
1720            close $INITRD;
1721
1722            my $cfg = "/etc/bootsplash/themes/$theme/config/bootsplash-800x600.cfg";
1723            -f $cfg or die "FATAL switch_theme: $cfg does not exist\n";
1724            log_("switch_theme: /sbin/splash -s -f $cfg >> $initrd.new\n", $config->{verbose}, $config->{LOG});
1725            system("/sbin/splash -s -f $cfg >> $initrd.new");
1726            unlink $initrd;
1727            link "$initrd.new", $initrd;
1728            unlink "$initrd.new"
1729        }
1730        closedir $ALT
1731    }
1732    closedir $DIR;
1733    # syslinux
1734    copy "/usr/share/bootsplash/themes/$theme/lilo/syslinux", "$dir/boot.msg";
1735}
1736
1737sub boot {
1738    my ($class, $fct, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discsFiles, $sort) = @_;
1739    my $graft = $totgraft->{$cdnum};
1740    my $isolinux = $fct->[1]{isolinux};
1741    my $bootimg = $fct->[1]{bootimg};
1742    log_("Boot: $fixed nolive $nolive\n", $config->{verbose}, $config->{LOG});
1743    my $struct_v = $config->{struct_version};
1744    my $isolinux_dir = $fct->[1]{isolinux_dir} || $config->{struct}{$struct_v}{isolinux};
1745    if (!$fixed) {
1746        my $size;
1747        my (@chunk_first, @chunk);
1748       
1749        if ($nolive) {
1750            my $mkiso;
1751            my $img;
1752            my $dir;
1753            my $path; 
1754            if ($isolinux) {
1755                log_("boot: isolinux mode (bootimg $bootimg)\n", $config->{verbose}, $config->{LOG});
1756                my $img = $bootimg ? $bootimg->[0] : "$isolinux_dir/isolinux.bin"; 
1757                $mkiso = qq( -udf -b $img -c $isolinux_dir/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table);
1758                push @chunk_first, $img;
1759                $graft->{"$isolinux_dir/boot.cat"} = 0;
1760            } elsif ($bootimg) {
1761                log_("boot: el torito mode (bootimg $bootimg->[0])\n", $config->{verbose}, $config->{LOG});
1762                $img = $bootimg->[0];
1763                $dir = $bootimg->[1]{dir};
1764                $img =~ s,(.*)/([^/]+)$,$2,;
1765                $dir or ($dir) = $1;
1766                $mkiso = qq( -udf -b $dir/$img -c ${dir}/boot.cat);
1767                $graft->{"$dir/boot.cat"} = 0;
1768            }
1769            foreach (@{$fct->[1]{files}}) {
1770                my ($files, $opt) = @$_;
1771                my $dest = $opt->{dest};
1772                $size += du($files);
1773                my ($dirname) = $files =~ m,([^/]*)$,;
1774                log_("boot: files $files dest $dest dirname $dirname\n", $config->{verbose}, $config->{LOG});
1775                if ($img) { 
1776                    my $bimg = $bootimg->[0];
1777                    $bimg =~ s/$dirname//;
1778                    log_("boot: boot image $files/$bimg ($bimg) in $dir/$img (" . (stat "$files/$bimg")[7] . ")\n", $config->{verbose}, $config->{LOG});
1779                    if (-f "$files/$bimg") { 
1780                        if ((stat "$files/$bimg")[7] > 3000000) { 
1781                            $mkiso .= qq( -no-emul-boot)
1782                        }
1783                        # $mkiso .= qq( $dir/$img=$files/$bimg)
1784                        push @chunk_first, "$files/$bimg";
1785                        $graft->{"$dir/$img"}{"$files/$bimg"} = 1
1786                    }
1787                    if ($dir =~ /isolinux$/ && $isolinux->[0]{theme}) {
1788                        switch_theme($dir, $isolinux->[0]{theme})
1789                    }
1790                }
1791
1792                # if (-d "$files") { $mkiso .= " $dest/$dirname/=$files"; next }
1793                # $mkiso .= " $dest/=$files";
1794                log_("boot: graft $dest/$dirname/ from $files\n", $config->{verbose}, $config->{LOG});
1795                if (-d $files) { 
1796                    $graft->{"$dest/$dirname/"}{$files} = 1 
1797                } else { 
1798                    $graft->{"$dest/"}{$files} = 1 
1799                }
1800                $dest =~ s,/+,/,g;
1801                if ($opt->{first}) {
1802                    push @chunk_first, $dest
1803                } else {
1804                    unshift @chunk, $dest 
1805                }
1806                push @chunk_first, "$dir/boot.cat"
1807            }
1808            # it is = and not .= because mkcdisos->[$cdnum] has been added already at the beginning
1809            $mkisos->[$cdnum] = "$mkiso $mkisos->[$cdnum]";
1810        } else {
1811            log_("FILES $fct->[1]{files}\n", $config->{verbose}, $config->{LOG});
1812            foreach (@{$fct->[1]{files}}) {
1813                my ($files, $opt) = @$_;
1814                my $dest = "$config->{topdir}/build/$config->{name}/" . ($opt->{first} ? "first/" : "") . "$cdnum/";
1815                # FIXME first should ne obsolete, however it appears in several place, and the removal must be done with care
1816                -d $dest or mkpath $dest;
1817                my $odest = $opt->{dest};
1818                log_("boot: file $files (first $opt->{first} to $dest odest $odest)\n", $config->{verbose}, $config->{LOG});
1819                if ($odest) {
1820                    $dest .= "/$odest";
1821                    if ($odest =~ m,/$,) { mkpath $dest }
1822                } else {
1823                    my ($dirname) = $files =~ m,([^/]*)$,;
1824                    $dest .= "/$dirname"
1825                }
1826                $dest =~ s,/+,/,g;
1827                log_("boot: file $files (to $dest odest $odest)\n", $config->{verbose}, $config->{LOG});
1828                cpal($files, $dest, "(rr_moved|boot.cat)");
1829                if ($dest =~ /isolinux$/ && $isolinux->[0]{theme}) {
1830                    switch_theme($dest, $isolinux->[0]{theme})
1831                }
1832                if ($opt->{first}) {
1833                    push @chunk_first, $dest
1834                } else {
1835                    unshift @chunk, $dest 
1836                }
1837                push @chunk_first, "$dir/boot.cat"
1838            }
1839            if ($fct->[1]{oem}) {
1840                log_("boot: setting default boot to oem\n", $config->{verbose}, $config->{LOG});
1841                my $dest = "$config->{topdir}/build/$config->{name}/first/$cdnum/$isolinux_dir";
1842                -d $dest or mkpath $dest;
1843                my $old = "$dest/isolinux.cfg";
1844                my $new = "$dest/isolinux.cfg.new";
1845                copy $old, $new;
1846                unlink $old;
1847                link $new, $old;
1848                unlink $new;
1849                substInFile { s/default linux/default oem/ } $old
1850            }
1851            $graft->{"/"}{"$dir/first/$cdnum/"} = 1;
1852            $size = du("$dir/first/$cdnum/", $inode);
1853        }
1854        push @{$sort->{$cdnum}}, \@chunk_first;
1855        unshift @{$sort->{$cdnum}}, \@chunk;
1856        return $size
1857    } elsif ($fixed == 1) {
1858        if (!$nolive) {
1859            if ($isolinux) {
1860                my $img = $bootimg ? $bootimg->[0] : "$isolinux_dir/isolinux.bin"; 
1861                $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");
1862                if (-f "$dir/$cdnum/$img") {
1863                    push @{$sort->{$cdnum}}, [ "$dir/$cdnum/$img" ];
1864                } elsif (-f "$dir/first/$cdnum/$img") {
1865                    push @{$sort->{$cdnum}}, [ "$dir/first/$cdnum/$img" ];
1866                }
1867                $graft->{"$isolinux_dir/boot.cat"} = 0
1868            } elsif ($bootimg) {
1869                my $img = $bootimg->[0];
1870                my $sdir = $bootimg->[1]{dir};
1871                $img =~ s,(.*/)([^/]+)$,$2,;
1872                $sdir or ($sdir) = $1;
1873                $sdir =~ s,//+,/,g;
1874                $sdir =~ s,/$,,g;
1875                log_("boot: boot image $sdir/$img\n", $config->{verbose}, $config->{LOG});
1876                $mkisos->[$cdnum] .= qq( -udf -b $sdir/$img);
1877                my $Bootdir;
1878                my $cdimages;
1879                log_("boot: try to find boot image in $cdimages/$bootimg->[0] and $dir/first/$cdnum/$bootimg->[0]\n", $config->{verbose}, $config->{LOG});
1880                if (-f "$cdimages/$bootimg->[0]") {
1881                    $cdimages = "$dir/$cdnum";
1882                    $Bootdir = "$dir/$cdnum/$sdir/";
1883                } elsif (-f "$dir/first/$cdnum/$bootimg->[0]") {
1884                    $cdimages = "$dir/first/$cdnum";
1885                    $Bootdir = "$dir/first/$cdnum/$sdir/";
1886                } else {
1887                    die "FATAL boot: could not find boot image\n";
1888                }
1889                if ((stat "$cdimages/$bootimg->[0]")[7] > 3000000) { 
1890                    $mkisos->[$cdnum] .= qq( -no-emul-boot)
1891                }
1892                push @{$sort->{$cdnum}}, [ "$cdimages/$bootimg->[0]" ];
1893                $Bootdir =~ s,//+,/,g;
1894                $Bootdir =~ s,/$,,g;
1895                if (! -f "$Bootdir/$img") {
1896                    if (! -d $Bootdir) { mkpath $Bootdir or die "cannot create $Bootdir\n" }
1897                    my $err = link "$cdimages/$bootimg->[0]", "$Bootdir/$img";
1898                    if (!$err) { log_("Linking failed $cdimages/$bootimg->[0]: $!\n", $config->{verbose}, $config->{LOG}) };
1899                }
1900                $mkisos->[$cdnum] .= qq( -c $sdir/boot.cat $dir/first/$cdnum);
1901                $graft->{"$sdir/boot.cat"} = 0;
1902                log_("BOOT $mkisos->[$cdnum]\n", $config->{verbose}, $config->{LOG});
1903            }
1904        }
1905    }
1906}
1907
1908sub installation {
1909    my ($class, $inst, $dir, $fixed, $nolive, $cdnum, $cd, $cdfile, $list, $mkisos, $totgraft, $inode, $discsFiles, $sort, $cdsize) = @_;
1910    my $graft = $totgraft->{$cdnum};
1911    my $install = $inst->[1]{install};
1912    my $struct_v = $config->{struct_version};
1913    my $struct = $config->{struct}{$struct_v};
1914    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});
1915
1916    my $name = $config->{name};
1917    my $topdir = $config->{topdir};
1918    my $isodir = $config->{isodir} ? $config->{isodir} : "$topdir/iso/$name";
1919    my ($compss, $rpmsrate);
1920    if (defined $cd->{function}{data}{installation}[1]{compssUsers}) {
1921        $compss = $cd->{function}{data}{installation}[1]{compssUsers}
1922    } elsif ($install) {
1923        $compss = "$install/$media_info/$compss_name"
1924    }
1925    if (defined $cd->{function}{data}{installation}[1]{rpmsrate}) {
1926        $rpmsrate = $cd->{function}{data}{installation}[1]{rpmsrate}
1927    } elsif ($install) {
1928        $rpmsrate = "$install/$media_info/base/rpmsrate";
1929    }   
1930    if (!$fixed) {
1931        my $size;
1932        my $media_dir = $struct->{media};
1933
1934        if ($nolive) {
1935            if ($install) {
1936                opendir my $A, $install;
1937                foreach (readdir $A) {
1938                    /~$/ and next;
1939                    /^(\.{1,2}|$install_dir|LICENSE-APPS\.txt|$isolinux_dir|$images_dir|VERSION|boot\.cat|rr_moved|$media_base)$/ and next;
1940                    $size += du("$install/$_");
1941                    if (-d "$install/$_") { $graft->{"/$_/"}{"$install/$_"} = 1; next }
1942                    $graft->{"/"}{"$install/$_"} = 1
1943                }
1944
1945                local *A; opendir A, "$install/$install_dir";
1946                foreach (readdir A) {
1947                    log_("$install_dir -- $_\n", $config->{verbose}, $config->{LOG}, 3);
1948                    /~$/ and next;
1949                    # FIXME both old and new structure detailed
1950                    "$install_dir/$_" =~ m{^($install_dir/(\.{1,2}|$media_base))$|$media_dir|$media_info|$extra_dir|$images_dir|$isolinux_dir} and next;
1951                    $size += du("$install/$install_dir/$_");
1952                    # if (-d "$install/Mandrake/$_") { $mkiso .= " Mandrake/$_/=$install/Mandrake/$_"; next }
1953                    # $graft->{"Mandrake/"}{"$install/Mandrake/$_"} = 1;
1954                    if (-d "$install/$install_dir/$_") { $graft->{"$install_dir/$_/"}{"$install/$install_dir/$_"} = 1; next }
1955                    $graft->{"$install_dir/"}{"$install/$install_dir/$_"} = 1;
1956                }
1957
1958                local *A; opendir A, "$install/$media_info";
1959                foreach (readdir A) {
1960                    /~$/ and next; 
1961                    /(^(\.{1,2}|compss|provides|depslist.ordered|MD5SUM|pubkey.*|synthesis|$compss_name|rpmsrate|rpmslist|filelist|Serial|hashfile)|hdlist|cooker)/ and next;
1962                    $size += du("$install/$media_info/$_");
1963                    # if (-d "$install/Mandrake/base/$_") { $mkiso .= " Mandrake/base/$_/=$install/Mandrake/base/$_"; next}
1964                    # $mkiso .= " Mandrake/base/=$install/Mandrake/base/$_";
1965                    if (-d "$install/$media_info/$_") { $graft->{"$media_info/$_/"}{"$install/$media_info/$_"} = 1; next }
1966                    $graft->{"$media_info/"}{"$install/$media_info/$_"} = 1
1967                }
1968            }
1969            if ($compss) {
1970                if (-f $compss) { 
1971                    log_("installation: $compss_name $compss\n", $config->{verbose}, $config->{LOG}, 2);
1972                    $size += du($compss);
1973                    $graft->{"$media_info/$compss_name"}{$compss} = 1
1974                } else { log_("ERROR installation: $compss file does not exist", $config->{verbose}, $config->{LOG}, 0) } 
1975            }
1976        } else {
1977            if ($install) {
1978                cpal("$install/$install_dir","$dir/$cdnum/$install_dir","$install/*($extra_dir|$images_dir|($install_dir/*)?$isolinux_dir|$media_dir|$media_info)");
1979                cpal("$install/","$dir/$cdnum/","$install/*($install_dir|$images_dir|$isolinux_dir|$media_base|tutorial|misc|doc|LICENSE-APPS.txt|boot.cat|rr_moved)");
1980                cpal("$install/$media_info","$dir/$cdnum/$media_info","$install/*$media_info/*(hdlist|MD5SUM|pubkey|depslist|synthesis|rpmslist|filelist|Serial|hashfile|$compss_name|rpmsrate)");
1981
1982                #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))");
1983                if (!$inst->[1]{oem}) {
1984                    cpal("$install/tutorial", "$dir/$cdnum/tutorial") if -d "$install/tutorial";
1985                    cpal("$install/misc", "$dir/$cdnum/misc") if -d "$install/misc";
1986                    cpal("$install/doc", "$dir/$cdnum/doc") if -d "$install/doc";
1987                }
1988
1989            }
1990            if ($compss) {
1991                if (-f $compss) {
1992                    my $path = "$dir/$cdnum/$media_info";
1993                    -d $path or mkpath $path;
1994                    log_("installation: $compss_name $compss\n", $config->{verbose}, $config->{LOG}, 2);
1995                    cpal($compss, "$path/$compss_name");
1996                } else { log_("ERROR installation: $compss file does not exist", $config->{verbose}, $config->{LOG}, 0) }
1997            }
1998        }
1999        return $size
2000    } else {
2001        my $patch_dir = $struct->{patch};
2002        my $stage2 = $struct->{stage2};
2003        if ($nolive) {
2004            my $size;
2005            if ($inst->[1]{boot_medium}) {
2006                -d "$dir/$cdnum/$patch_dir" or mkpath "$dir/$cdnum/$patch_dir";
2007                my $file = "$dir/$cdnum/$patch_dir/patch-oem.pl";
2008                my $A;
2009                if (-f "$install/$patch_dir/patch-oem.pl") {
2010                    copy "$install/$patch_dir/patch-oem.pl", $file;
2011                    open $A, ">>$file" or print "ERROR installation: could not open $file for writing\n";
2012                } else {
2013                    open $A, ">$file" or print "ERROR installation: could not open $file for writing\n";
2014                }
2015                print $A "use install_any;
2016package install_any;
2017
2018\$current_medium = $inst->[1]{boot_medium};
2019\$asked_medium = $inst->[1]{boot_medium};
2020                ";
2021                $graft->{"$patch_dir/"}{$file} = 1;
2022                $size += du($file, $inode)
2023            }
2024            my ($repnum, $path, $pfile, $suppl_postfix) = buildInstallHdlist($dir, $cdnum, $inst, $list, $discsFiles, $sort, $nolive, $cdsize);
2025            my $err = copy $pfile, "$isodir/$cdnum-$name.idx";
2026            !$err and log_("ERROR installation: link $pfile to $isodir/$cdnum-$name.idx ($!)\n", $config->{verbose}, $config->{LOG});
2027            if ($install && $fixed == 1) {
2028               
2029                # $mkiso = " Mandrake/base/=$path/compss Mandrake/base/=$path/depslist.ordered Mandrake/base/=$path/provides Mandrake/base/=$path/hdlists /=$pfile";
2030                $graft->{"$media_info/"}{"$path/compss"} = 1;
2031                $graft->{"$media_info/"}{"$path/depslist.ordered"} = 1; 
2032                $graft->{"$media_info/"}{"$path/provides"} = 1;
2033                $graft->{"$media_info/"}{"$path/hdlists"} = 1;
2034                $graft->{"$media_info/"}{"$path/MD5SUM"} = 1;
2035                $graft->{"/"}{$pfile} = 1;
2036                if ($rpmsrate) {
2037                    if (-f $rpmsrate) {
2038                        $size += du($rpmsrate);
2039                        # $mkiso .= " Mandrake/base/rpmsrate=$rpmsrate"
2040                        $graft->{"$media_info/rpmsrate"}{$rpmsrate} = 1
2041                    } else { log_("ERROR installation: $rpmsrate file does not exist", $config->{verbose}, $config->{LOG}, 0); return 0 }
2042                }
2043                $size += du("$path/compss", $inode);
2044                $size += du("$path/depslist.ordered");
2045                $size += du("$path/provides");
2046                $size += du($pfile, $inode);
2047                unshift @{$sort->{$cdnum}}, [ "$path/", "$install/$stage2" ]
2048            }
2049            my $version = "$dir/$cdnum/VERSION";
2050            $size += du("$path/hdlists");
2051            printVERSION($config->{name}, $version, $inst->[1]);
2052            $graft->{VERSION}{$version} = 1;
2053            $size += du($version);     
2054            foreach my $n (1 .. $repnum - 1) {
2055                # $mkiso .= " Mandrake/base/=$path/hdlist$n.cz";
2056                $graft->{"$media_info/"}{"$path/hdlist$n$suppl_postfix.cz"} = 1;
2057                # FIXME This is wrong, previous hdlist size must be deduced in iterative rebuild mode
2058                $size += du("$path/hdlist$n$suppl_postfix.cz");
2059                if (-f "$path/pubkey$n") { 
2060                    $graft->{"$media_info/"}{"$path/pubkey$n$suppl_postfix"} = 1;
2061                    $size += du("$path/pubkey$n$suppl_postfix");
2062                }
2063                if ($inst->[1]{synthesis}) {
2064                    # $mkiso .= " Mandrake/base/=$path/synthesis.hdlist$n.cz";
2065                    $graft->{"$media_info/"}{"$path/synthesis.hdlist$n$suppl_postfix.cz"} = 1;
2066                    $size += du("$path/synthesys.hdlist$n$suppl_postfix.cz")
2067                }
2068            }
2069            return $size;
2070        } else {
2071            if (!$install) { mkpath "$dir/$cdnum/$media_info/" ; mkpath "$dir/$cdnum/$install_dir" }
2072            if ($inst->[1]{boot_medium}) {
2073                log_("installation: boot_medium defined to $inst->[1]{boot_medium}\n", $config->{verbose}, $config->{LOG}, 2);
2074                my $file = "$dir/$cdnum/$patch_dir/patch-oem.pl";
2075                my $A;
2076                if (-f $file) {
2077                    unlink $file;
2078                    copy "$install/$patch_dir/patch-oem.pl", $file;
2079                    open $A, ">>$file" or print "ERROR installation: could not open $file for writing\n";
2080                } else {
2081                    open $A, ">$file" or print "ERROR installation: could not open $file for writing\n";
2082                }
2083                print $A "use install_any;
2084package install_any;
2085
2086\$current_medium = $inst->[1]{boot_medium};
2087\$asked_medium = $inst->[1]{boot_medium};
2088";
2089            } 
2090            unlink "$dir/$cdnum/$media_info/hdlists";
2091            (undef, undef, my $pfile) = buildInstallHdlist($dir, $cdnum, $inst, $list, $discsFiles, $sort, 0, $cdsize);
2092            my $err = copy $pfile, "$isodir/$cdnum-$name.idx";
2093            !$err and log_("ERROR installation: link $pfile to $isodir/$cdnum-$name.idx ($!)\n", $config->{verbose}, $config->{LOG});
2094            if ($fixed == 1) {
2095                if ($rpmsrate) {
2096                    if (-f $rpmsrate) {
2097                        log_("installation: rpmsrate: $rpmsrate\n", $config->{verbose}, $config->{LOG}, 2);
2098                        cpal($rpmsrate, "$dir/$cdnum/$media_info/rpmsrate");
2099                    } else { 
2100                        log_("ERROR installation: $rpmsrate file does not exist", $config->{verbose}, $config->{LOG}, 0); 
2101                        return 0 
2102                    }
2103                }
2104                if ($install) {
2105                    unshift @{$sort->{$cdnum}}, [ "$dir/$cdnum/$media_info/", "$dir/$cdnum/$stage2" ]
2106                }
2107            }
2108            my $version = "$dir/$cdnum/VERSION";
2109            unlink $version;
2110            printVERSION($config->{name}, $version, $inst->[1]);
2111        }
2112    }
2113}
2114
21151
2116
2117#
2118# Changeloh
2119#
2120# 2002 03 15
2121# new sources handling in installation
2122#
2123# 2002 03 19
2124# cdcom are now build as normal ones not to force deps, use standard list
2125#
2126# 2002 03 29
2127# fix a bug in nolive mode that prevent rpmsrate to be put on discs
2128#
2129# 2002 05 13
2130# finish md5 check
2131# fix commented du in sub installation
2132#
2133# 2002 08 01
2134# add noauto options for rpmsdir
2135#
2136# 2002 08 14
2137# fix little bug in buildGenericHdlists
2138#
2139# 2002 10 02
2140# allow glob in rm function for live mode (need to do it for nolive mode)
2141#
2142# 20030401
2143# get_rpmsdir now manages hdlist dir
Note: See TracBrowser for help on using the repository browser.