1 #*************************************************************************
3 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 # Copyright 2008 by Sun Microsystems, Inc.
7 # OpenOffice.org - a multi-platform office productivity suite
9 # $RCSfile: msiglobal.pm,v $
11 # This file is part of OpenOffice.org.
13 # OpenOffice.org is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU Lesser General Public License version 3
15 # only, as published by the Free Software Foundation.
17 # OpenOffice.org is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU Lesser General Public License version 3 for more details
21 # (a copy is included in the LICENSE file that accompanied this code).
23 # You should have received a copy of the GNU Lesser General Public License
24 # version 3 along with OpenOffice.org. If not, see
25 # <http://www.openoffice.org/license.html>
26 # for a copy of the LGPLv3 License.
28 #*************************************************************************
30 package installer
::windows
::msiglobal
;
34 use installer
::converter
;
35 use installer
::exiter
;
37 use installer
::globals
;
38 use installer
::logger
;
39 use installer
::pathanalyzer
;
40 use installer
::remover
;
41 use installer
::scriptitems
;
42 use installer
::systemactions
;
43 use installer
::worker
;
44 use installer
::windows
::idtglobal
;
45 use installer
::windows
::language
;
47 ###########################################################################
48 # Generating the header of the ddf file.
49 # The usage of ddf files is needed, because makecab.exe can only include
50 # one sourcefile into a cab file
51 ###########################################################################
53 sub write_ddf_file_header
55 my ($ddffileref, $cabinetfile, $installdir) = @_;
59 $oneline = ".Set CabinetName1=" . $cabinetfile . "\n";
60 push(@
{$ddffileref} ,$oneline);
61 $oneline = ".Set ReservePerCabinetSize=128\n"; # This reserves space for a digital signature.
62 push(@
{$ddffileref} ,$oneline);
63 $oneline = ".Set MaxDiskSize=CDROM\n"; # This allows the .cab file to be as large as needed.
64 push(@
{$ddffileref} ,$oneline);
65 $oneline = ".Set CompressionType=LZX\n";
66 push(@
{$ddffileref} ,$oneline);
67 $oneline = ".Set Compress=ON\n";
68 push(@
{$ddffileref} ,$oneline);
69 $oneline = ".Set CompressionLevel=$installer::globals::cabfilecompressionlevel\n";
70 push(@
{$ddffileref} ,$oneline);
71 $oneline = ".Set Cabinet=ON\n";
72 push(@
{$ddffileref} ,$oneline);
73 $oneline = ".Set DiskDirectoryTemplate=" . $installdir . "\n";
74 push(@
{$ddffileref} ,$oneline);
77 ##########################################################################
78 # Lines in ddf files must not contain more than 256 characters
79 ##########################################################################
83 my ( $ddffile, $ddffilename ) = @_;
90 for ( my $i = 0; $i <= $#{$ddffile}; $i++ )
92 my $oneline = ${$ddffile}[$i];
94 $linelength = length($oneline);
97 if ( $linelength > 256 )
99 installer
::exiter
::exit_program
("ERROR \"$ddffilename\" line $linenumber: Lines in ddf files must not contain more than 256 characters!", "check_ddf_file");
102 if ( $linelength > $maxlength )
104 $maxlength = $linelength;
105 $maxline = $linenumber;
109 my $infoline = "Check of ddf file \"$ddffilename\": Maximum length \"$maxlength\" in line \"$maxline\" (allowed line length: 256 characters)\n";
110 push(@installer::globals
::logfileinfo
, $infoline);
113 ##########################################################################
114 # Lines in ddf files must not be longer than 256 characters.
115 # Therefore it can be useful to use relative pathes. Then it is
116 # necessary to change into temp directory before calling
118 ##########################################################################
120 sub make_relative_ddf_path
122 my ( $sourcepath ) = @_;
124 my $windowstemppath = $installer::globals
::temppath
;
126 if ( $^O
=~ /cygwin/i )
128 $windowstemppath = $installer::globals
::cyg_temppath
;
131 $sourcepath =~ s/\Q$windowstemppath\E//;
132 $sourcepath =~ s/^\\//;
137 ##########################################################################
138 # Returning the order of the sequences in the files array.
139 ##########################################################################
141 sub get_sequenceorder
147 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
149 my $onefile = ${$filesref}[$i];
150 if ( ! $onefile->{'assignedsequencenumber'} ) { installer
::exiter
::exit_program
("ERROR: No sequence number assigned to $onefile->{'gid'} ($onefile->{'uniquename'})!", "get_sequenceorder"); }
151 $order{$onefile->{'assignedsequencenumber'}} = $i;
157 ##########################################################################
158 # Generation the list, in which the source of the files is connected
159 # with the cabinet destination file. Because more than one file needs
160 # to be included into a cab file, this has to be done via ddf files.
161 ##########################################################################
163 sub generate_cab_file_list
165 my ($filesref, $installdir, $ddfdir, $allvariables) = @_;
167 my @cabfilelist = ();
169 installer
::logger
::include_header_into_logfile
("Generating ddf files");
171 installer
::logger
::include_timestamp_into_logfile
("Performance Info: ddf file generation start");
173 if ( $^O
=~ /cygwin/i ) { installer
::worker
::generate_cygwin_pathes
($filesref); }
175 if ( $installer::globals
::use_packages_for_cabs
)
177 my $sequenceorder = get_sequenceorder
($filesref);
180 my $currentcabfile = "";
182 while ( ( exists($sequenceorder->{$counter}) ) || ( exists($installer::globals
::allmergemodulefilesequences
{$counter}) ) ) # Taking care of files from merge modules
184 if ( exists($installer::globals
::allmergemodulefilesequences
{$counter}) )
186 # Skipping this sequence, it is not included in $filesref, because it is assigned to a file from a merge module.\n";
191 # Files with increasing sequencerorder are included in one cab file
192 my $onefile = ${$filesref}[$sequenceorder->{$counter}];
193 my $cabinetfile = $onefile->{'assignedcabinetfile'};
194 my $sourcepath = $onefile->{'sourcepath'};
195 if ( $^O
=~ /cygwin/i ) { $sourcepath = $onefile->{'cyg_sourcepath'}; }
196 my $uniquename = $onefile->{'uniquename'};
200 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; };
201 if ( $styles =~ /\bDONT_PACK\b/ ) { $doinclude = 0; }
203 # to avoid lines with more than 256 characters, it can be useful to use relative pathes
204 if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path
($sourcepath); }
206 # all files with the same cabinetfile have increasing sequencenumbers
210 write_ddf_file_header
(\
@ddffile, $cabinetfile, $installdir);
212 my $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
213 if ( $doinclude ) { push(@ddffile, $ddfline); }
215 $counter++; # increasing the counter
217 my $nextcabinetfile = "";
218 if ( exists($sequenceorder->{$counter}) ) { $nextfile = ${$filesref}[$sequenceorder->{$counter}]; }
219 if ( $nextfile->{'assignedcabinetfile'} ) { $nextcabinetfile = $nextfile->{'assignedcabinetfile'}; }
221 while ( $nextcabinetfile eq $cabinetfile )
223 $sourcepath = $nextfile->{'sourcepath'};
224 if ( $^O
=~ /cygwin/i ) { $sourcepath = $nextfile->{'cyg_sourcepath'}; }
225 # to avoid lines with more than 256 characters, it can be useful to use relative pathes
226 if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path
($sourcepath); }
227 $uniquename = $nextfile->{'uniquename'};
228 my $localdoinclude = 1;
229 my $nextfilestyles = "";
230 if ( $nextfile->{'Styles'} ) { $nextfilestyles = $nextfile->{'Styles'}; }
231 if ( $nextfilestyles =~ /\bDONT_PACK\b/ ) { $localdoinclude = 0; }
232 $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
233 if ( $localdoinclude ) { push(@ddffile, $ddfline); }
235 $counter++; # increasing the counter!
236 $nextcabinetfile = "_lastfile_";
237 if ( exists($sequenceorder->{$counter}) )
239 $nextfile = ${$filesref}[$sequenceorder->{$counter}];
240 $nextcabinetfile = $nextfile->{'assignedcabinetfile'};
244 # creating the DDF file
246 my $ddffilename = $cabinetfile;
247 $ddffilename =~ s/.cab/.ddf/;
248 $ddfdir =~ s/\Q$installer::globals::separator\E\s*$//;
249 $ddffilename = $ddfdir . $installer::globals
::separator
. $ddffilename;
251 installer
::files
::save_file
($ddffilename ,\
@ddffile);
252 my $infoline = "Created ddf file: $ddffilename\n";
253 push(@installer::globals
::logfileinfo
, $infoline);
255 # lines in ddf files must not be longer than 256 characters
256 check_ddf_file
(\
@ddffile, $ddffilename);
258 # Writing the makecab system call
260 my $oneline = "makecab.exe /V3 /F " . $ddffilename . " 2\>\&1 |" . "\n";
262 push(@cabfilelist, $oneline);
264 # collecting all ddf files
265 push(@installer::globals
::allddffiles
, $ddffilename);
268 elsif ((( $installer::globals
::cab_file_per_component
) || ( $installer::globals
::fix_number_of_cab_files
)) && ( $installer::globals
::updatedatabase
))
270 my $sequenceorder = get_sequenceorder
($filesref);
273 my $currentcabfile = "";
275 while ( ( exists($sequenceorder->{$counter}) ) || ( exists($installer::globals
::allmergemodulefilesequences
{$counter}) ) ) # Taking care of files from merge modules
277 # if ( exists($installer::globals::allmergemodulefilesequences{$counter}) )
279 # # Skipping this sequence, it is not included in $filesref, because it is assigned to a file from a merge module.\n";
284 my $onefile = ${$filesref}[$sequenceorder->{$counter}];
287 my $cabinetfile = $onefile->{'cabinet'};
288 my $sourcepath = $onefile->{'sourcepath'};
289 if ( $^O
=~ /cygwin/i ) { $sourcepath = $onefile->{'cyg_sourcepath'}; }
290 my $uniquename = $onefile->{'uniquename'};
294 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; };
295 if ( $styles =~ /\bDONT_PACK\b/ ) { $doinclude = 0; }
297 # to avoid lines with more than 256 characters, it can be useful to use relative pathes
298 if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path
($sourcepath); }
302 write_ddf_file_header
(\
@ddffile, $cabinetfile, $installdir);
304 my $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
305 if ( $doinclude ) { push(@ddffile, $ddfline); }
308 if ( ${$filesref}[$sequenceorder->{$counter}] ) { $nextfile = ${$filesref}[$sequenceorder->{$counter}]; }
310 my $nextcabinetfile = "";
312 if ( $nextfile->{'cabinet'} ) { $nextcabinetfile = $nextfile->{'cabinet'}; }
314 while ( $nextcabinetfile eq $cabinetfile )
316 $sourcepath = $nextfile->{'sourcepath'};
317 if ( $^O
=~ /cygwin/i ) { $sourcepath = $nextfile->{'cyg_sourcepath'}; }
318 # to avoid lines with more than 256 characters, it can be useful to use relative pathes
319 if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path
($sourcepath); }
320 $uniquename = $nextfile->{'uniquename'};
321 my $localdoinclude = 1;
322 my $nextfilestyles = "";
323 if ( $nextfile->{'Styles'} ) { $nextfilestyles = $nextfile->{'Styles'}; }
324 if ( $nextfilestyles =~ /\bDONT_PACK\b/ ) { $localdoinclude = 0; }
325 $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
326 if ( $localdoinclude ) { push(@ddffile, $ddfline); }
327 $counter++; # increasing the counter!
329 $nextcabinetfile = "_lastfile_";
330 if (( exists($sequenceorder->{$counter}) ) && ( ${$filesref}[$sequenceorder->{$counter}] ))
332 $nextfile = ${$filesref}[$sequenceorder->{$counter}];
333 $nextcabinetfile = $nextfile->{'cabinet'};
337 # creating the DDF file
339 my $ddffilename = $cabinetfile;
340 $ddffilename =~ s/.cab/.ddf/;
341 $ddfdir =~ s/\Q$installer::globals::separator\E\s*$//;
342 $ddffilename = $ddfdir . $installer::globals
::separator
. $ddffilename;
344 installer
::files
::save_file
($ddffilename ,\
@ddffile);
345 my $infoline = "Created ddf file: $ddffilename\n";
346 push(@installer::globals
::logfileinfo
, $infoline);
348 # lines in ddf files must not be longer than 256 characters
349 check_ddf_file
(\
@ddffile, $ddffilename);
351 # Writing the makecab system call
353 my $oneline = "makecab.exe /V3 /F " . $ddffilename . " 2\>\&1 |" . "\n";
355 push(@cabfilelist, $oneline);
357 # collecting all ddf files
358 push(@installer::globals
::allddffiles
, $ddffilename);
361 elsif (( $installer::globals
::cab_file_per_component
) || ( $installer::globals
::fix_number_of_cab_files
))
363 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
365 my $onefile = ${$filesref}[$i];
366 my $cabinetfile = $onefile->{'cabinet'};
367 my $sourcepath = $onefile->{'sourcepath'};
368 if ( $^O
=~ /cygwin/i ) { $sourcepath = $onefile->{'cyg_sourcepath'}; }
369 my $uniquename = $onefile->{'uniquename'};
373 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; };
374 if ( $styles =~ /\bDONT_PACK\b/ ) { $doinclude = 0; }
377 # to avoid lines with more than 256 characters, it can be useful to use relative pathes
378 if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path
($sourcepath); }
380 # all files with the same cabinetfile are directly behind each other in the files collector
384 write_ddf_file_header
(\
@ddffile, $cabinetfile, $installdir);
386 my $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
387 if ( $doinclude ) { push(@ddffile, $ddfline); }
389 my $nextfile = ${$filesref}[$i+1];
390 my $nextcabinetfile = "";
392 if ( $nextfile->{'cabinet'} ) { $nextcabinetfile = $nextfile->{'cabinet'}; }
394 while ( $nextcabinetfile eq $cabinetfile )
396 $sourcepath = $nextfile->{'sourcepath'};
397 if ( $^O
=~ /cygwin/i ) { $sourcepath = $nextfile->{'cyg_sourcepath'}; }
398 # to avoid lines with more than 256 characters, it can be useful to use relative pathes
399 if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path
($sourcepath); }
400 $uniquename = $nextfile->{'uniquename'};
401 my $localdoinclude = 1;
402 my $nextfilestyles = "";
403 if ( $nextfile->{'Styles'} ) { $nextfilestyles = $nextfile->{'Styles'}; }
404 if ( $nextfilestyles =~ /\bDONT_PACK\b/ ) { $localdoinclude = 0; }
405 $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
406 if ( $localdoinclude ) { push(@ddffile, $ddfline); }
407 $i++; # increasing the counter!
408 $nextfile = ${$filesref}[$i+1];
409 if ( $nextfile ) { $nextcabinetfile = $nextfile->{'cabinet'}; }
410 else { $nextcabinetfile = "_lastfile_"; }
413 # creating the DDF file
415 my $ddffilename = $cabinetfile;
416 $ddffilename =~ s/.cab/.ddf/;
417 $ddfdir =~ s/\Q$installer::globals::separator\E\s*$//;
418 $ddffilename = $ddfdir . $installer::globals
::separator
. $ddffilename;
420 installer
::files
::save_file
($ddffilename ,\
@ddffile);
421 my $infoline = "Created ddf file: $ddffilename\n";
422 push(@installer::globals
::logfileinfo
, $infoline);
424 # lines in ddf files must not be longer than 256 characters
425 check_ddf_file
(\
@ddffile, $ddffilename);
427 # Writing the makecab system call
429 my $oneline = "makecab.exe /V3 /F " . $ddffilename . " 2\>\&1 |" . "\n";
431 push(@cabfilelist, $oneline);
433 # collecting all ddf files
434 push(@installer::globals
::allddffiles
, $ddffilename);
437 elsif (( $installer::globals
::one_cab_file
) && ( $installer::globals
::updatedatabase
))
439 my $sequenceorder = get_sequenceorder
($filesref);
442 my $currentcabfile = "";
444 while ( ( exists($sequenceorder->{$counter}) ) || ( exists($installer::globals
::allmergemodulefilesequences
{$counter}) ) ) # Taking care of files from merge modules
446 if ( exists($installer::globals
::allmergemodulefilesequences
{$counter}) )
448 # Skipping this sequence, it is not included in $filesref, because it is assigned to a file from a merge module.\n";
453 my $onefile = ${$filesref}[$sequenceorder->{$counter}];
455 $cabinetfile = $onefile->{'cabinet'};
456 my $sourcepath = $onefile->{'sourcepath'};
457 if ( $^O
=~ /cygwin/i ) { $sourcepath = $onefile->{'cyg_sourcepath'}; }
458 my $uniquename = $onefile->{'uniquename'};
460 # to avoid lines with more than 256 characters, it can be useful to use relative pathes
461 if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path
($sourcepath); }
463 if ( $counter == 1 ) { write_ddf_file_header
(\
@ddffile, $cabinetfile, $installdir); }
467 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; };
468 if ( $styles =~ /\bDONT_PACK\b/ ) { $doinclude = 0; }
470 my $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
471 if ( $doinclude ) { push(@ddffile, $ddfline); }
473 $counter++; # increasing the counter
476 # creating the DDF file
478 my $ddffilename = $cabinetfile;
479 $ddffilename =~ s/.cab/.ddf/;
480 $ddfdir =~ s/[\/\\]\s*$//;
481 $ddffilename = $ddfdir . $installer::globals
::separator
. $ddffilename;
483 installer
::files
::save_file
($ddffilename ,\
@ddffile);
484 my $infoline = "Created ddf file: $ddffilename\n";
485 push(@installer::globals
::logfileinfo
, $infoline);
487 # lines in ddf files must not be longer than 256 characters
488 check_ddf_file
(\
@ddffile, $ddffilename);
490 # Writing the makecab system call
492 # my $oneline = "makecab.exe /F " . $ddffilename . "\n";
493 my $oneline = "makecab.exe /V3 /F " . $ddffilename . " 2\>\&1 |" . "\n";
495 push(@cabfilelist, $oneline);
497 # collecting all ddf files
498 push(@installer::globals
::allddffiles
, $ddffilename);
500 elsif ( $installer::globals
::one_cab_file
)
504 my $cabinetfile = "";
506 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
508 my $onefile = ${$filesref}[$i];
509 $cabinetfile = $onefile->{'cabinet'};
510 my $sourcepath = $onefile->{'sourcepath'};
511 if ( $^O
=~ /cygwin/i ) { $sourcepath = $onefile->{'cyg_sourcepath'}; }
512 my $uniquename = $onefile->{'uniquename'};
514 # to avoid lines with more than 256 characters, it can be useful to use relative pathes
515 if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path
($sourcepath); }
517 if ( $i == 0 ) { write_ddf_file_header
(\
@ddffile, $cabinetfile, $installdir); }
521 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; };
522 if ( $styles =~ /\bDONT_PACK\b/ ) { $doinclude = 0; }
524 my $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
525 if ( $doinclude ) { push(@ddffile, $ddfline); }
528 # creating the DDF file
530 my $ddffilename = $cabinetfile;
531 $ddffilename =~ s/.cab/.ddf/;
532 $ddfdir =~ s/[\/\\]\s*$//;
533 $ddffilename = $ddfdir . $installer::globals
::separator
. $ddffilename;
535 installer
::files
::save_file
($ddffilename ,\
@ddffile);
536 my $infoline = "Created ddf file: $ddffilename\n";
537 push(@installer::globals
::logfileinfo
, $infoline);
539 # lines in ddf files must not be longer than 256 characters
540 check_ddf_file
(\
@ddffile, $ddffilename);
542 # Writing the makecab system call
544 my $oneline = "makecab.exe /F " . $ddffilename . "\n";
546 push(@cabfilelist, $oneline);
548 # collecting all ddf files
549 push(@installer::globals
::allddffiles
, $ddffilename);
553 installer
::exiter
::exit_program
("ERROR: No cab file specification in globals.pm !", "create_media_table");
556 installer
::logger
::include_timestamp_into_logfile
("Performance Info: ddf file generation end");
558 return \
@cabfilelist; # contains all system calls for packaging process
561 ########################################################################
562 # Returning the file sequence of a specified file.
563 ########################################################################
565 sub get_file_sequence
567 my ($filesref, $uniquefilename) = @_;
570 my $found_sequence = 0;
572 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
574 my $onefile = ${$filesref}[$i];
575 my $uniquename = $onefile->{'uniquename'};
577 if ( $uniquename eq $uniquefilename )
579 $sequence = $onefile->{'sequencenumber'};
585 if ( ! $found_sequence ) { installer
::exiter
::exit_program
("ERROR: No sequence found for $uniquefilename !", "get_file_sequence"); }
590 ########################################################################
591 # For update and patch reasons the pack order needs to be saved.
592 # The pack order is saved in the ddf files; the names and locations
593 # of the ddf files are saved in @installer::globals::allddffiles.
594 # The outputfile "packorder.txt" can be saved in
595 # $installer::globals::infodirectory .
596 ########################################################################
600 installer
::logger
::include_header_into_logfile
("Saving pack order");
602 installer
::logger
::include_timestamp_into_logfile
("Performance Info: saving pack order start");
604 my $packorderfilename = "packorder.txt";
605 $packorderfilename = $installer::globals
::infodirectory
. $installer::globals
::separator
. $packorderfilename;
609 my $headerline = "\# Syntax\: Filetable_Sequence Cabinetfilename Physical_FileName Unique_FileName\n\n";
610 push(@packorder, $headerline);
612 for ( my $i = 0; $i <= $#installer::globals
::allddffiles
; $i++ )
614 my $ddffilename = $installer::globals
::allddffiles
[$i];
615 my $ddffile = installer
::files
::read_file
($ddffilename);
616 my $cabinetfile = "";
618 for ( my $j = 0; $j <= $#{$ddffile}; $j++ )
620 my $oneline = ${$ddffile}[$j];
622 # Getting the Cabinet file name
624 if ( $oneline =~ /^\s*\.Set\s+CabinetName.*\=(.*?)\s*$/ ) { $cabinetfile = $1; }
625 if ( $oneline =~ /^\s*\.Set\s+/ ) { next; }
627 if ( $oneline =~ /^\s*\"(.*?)\"\s+(.*?)\s*$/ )
630 my $uniquefilename = $2;
632 installer
::pathanalyzer
::make_absolute_filename_to_relative_filename
(\
$sourcefile);
634 # Using the hash created in create_files_table for performance reasons to get the sequence number
635 my $filesequence = "";
636 if ( exists($installer::globals
::uniquefilenamesequence
{$uniquefilename}) ) { $filesequence = $installer::globals
::uniquefilenamesequence
{$uniquefilename}; }
637 else { installer
::exiter
::exit_program
("ERROR: No sequence number value for $uniquefilename !", "save_packorder"); }
639 my $line = $filesequence . "\t" . $cabinetfile . "\t" . $sourcefile . "\t" . $uniquefilename . "\n";
640 push(@packorder, $line);
645 installer
::files
::save_file
($packorderfilename ,\
@packorder);
647 installer
::logger
::include_timestamp_into_logfile
("Performance Info: saving pack order end");
650 #################################################################
651 # Returning the name of the msi database
652 #################################################################
654 sub get_msidatabasename
656 my ($allvariableshashref, $language) = @_;
658 my $databasename = $allvariableshashref->{'PRODUCTNAME'} . $allvariableshashref->{'PRODUCTVERSION'};
659 $databasename = lc($databasename);
660 $databasename =~ s/\.//g;
661 $databasename =~ s/\-//g;
662 $databasename =~ s/\s//g;
664 # possibility to overwrite the name with variable DATABASENAME
665 if ( $allvariableshashref->{'DATABASENAME'} )
667 $databasename = $allvariableshashref->{'DATABASENAME'};
672 if (!($language eq ""))
674 $databasename .= "_$language";
678 $databasename .= ".msi";
680 return $databasename;
683 #################################################################
684 # Creating the msi database
685 # This works only on Windows
686 #################################################################
688 sub create_msi_database
690 my ($idtdirbase ,$msifilename) = @_;
692 # -f : path containing the idt files
693 # -d : msi database, including path
694 # -c : create database
695 # -i : include the following tables ("*" includes all available tables)
697 my $msidb = "msidb.exe"; # Has to be in the path
698 my $extraslash = ""; # Has to be set for non-ActiveState perl
700 installer
::logger
::include_header_into_logfile
("Creating msi database");
702 $idtdirbase = installer
::converter
::make_path_conform
($idtdirbase);
704 $msifilename = installer
::converter
::make_path_conform
($msifilename);
706 if ( $^O
=~ /cygwin/i ) {
707 # msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
708 $idtdirbase =~ s/\//\\\\/g
;
709 $msifilename =~ s/\//\\\\/g
;
712 my $systemcall = $msidb . " -f " . $idtdirbase . " -d " . $msifilename . " -c " . "-i " . $extraslash . "*";
714 my $returnvalue = system($systemcall);
716 my $infoline = "Systemcall: $systemcall\n";
717 push( @installer::globals
::logfileinfo
, $infoline);
721 $infoline = "ERROR: Could not execute $msidb!\n";
722 push( @installer::globals
::logfileinfo
, $infoline);
726 $infoline = "Success: Executed $msidb successfully!\n";
727 push( @installer::globals
::logfileinfo
, $infoline);
731 #####################################################################
732 # Returning the value from sis.mlf for Summary Information Stream
733 #####################################################################
735 sub get_value_from_sis_lng
737 my ($language, $languagefile, $searchstring) = @_;
739 my $language_block = installer
::windows
::idtglobal
::get_language_block_from_language_file
($searchstring, $languagefile);
740 my $newstring = installer
::windows
::idtglobal
::get_language_string_from_language_block
($language_block, $language, $searchstring);
741 $newstring = "\"" . $newstring . "\"";
746 #################################################################
747 # Returning the msi version for the Summary Information Stream
748 #################################################################
750 sub get_msiversion_for_sis
752 my $msiversion = "200";
756 #################################################################
757 # Returning the word count for the Summary Information Stream
758 #################################################################
760 sub get_wordcount_for_sis
766 #################################################################
767 # Returning the codepage for the Summary Information Stream
768 #################################################################
770 sub get_codepage_for_sis
772 my ( $language ) = @_;
774 my $codepage = installer
::windows
::language
::get_windows_encoding
($language);
776 # Codepage 65001 does not work in Summary Information Stream
777 if ( $codepage == 65001 ) { $codepage = 0; }
779 # my $codepage = "1252"; # determine dynamically in a function
780 # my $codepage = "65001"; # UTF-8
784 #################################################################
785 # Returning the template for the Summary Information Stream
786 #################################################################
788 sub get_template_for_sis
790 my ( $language ) = @_;
792 my $windowslanguage = installer
::windows
::language
::get_windows_language
($language);
794 my $value = "\"Intel;" . $windowslanguage; # adding the Windows language
796 $value = $value . "\""; # adding ending '"'
801 #################################################################
802 # Returning the PackageCode for the Summary Information Stream
803 #################################################################
805 sub get_packagecode_for_sis
807 # always generating a new package code for each package
809 my $guidref = get_guid_list
(1, 1); # only one GUID shall be generated
811 ${$guidref}[0] =~ s/\s*$//; # removing ending spaces
813 my $guid = "\{" . ${$guidref}[0] . "\}";
815 my $infoline = "PackageCode: $guid\n";
816 push( @installer::globals
::logfileinfo
, $infoline);
821 #################################################################
822 # Returning the title for the Summary Information Stream
823 #################################################################
825 sub get_title_for_sis
827 my ( $language, $languagefile, $searchstring ) = @_;
829 my $title = get_value_from_sis_lng
($language, $languagefile, $searchstring );
834 #################################################################
835 # Returning the author for the Summary Information Stream
836 #################################################################
838 sub get_author_for_sis
840 my $author = $installer::globals
::longmanufacturer
;
842 $author = "\"" . $author . "\"";
847 #################################################################
848 # Returning the subject for the Summary Information Stream
849 #################################################################
851 sub get_subject_for_sis
853 my ( $allvariableshashref ) = @_;
855 my $subject = $allvariableshashref->{'PRODUCTNAME'} . " " . $allvariableshashref->{'PRODUCTVERSION'};
857 $subject = "\"" . $subject . "\"";
862 #################################################################
863 # Returning the comment for the Summary Information Stream
864 #################################################################
866 sub get_comment_for_sis
868 my ( $language, $languagefile, $searchstring ) = @_;
870 my $comment = get_value_from_sis_lng
($language, $languagefile, $searchstring );
875 #################################################################
876 # Returning the keywords for the Summary Information Stream
877 #################################################################
879 sub get_keywords_for_sis
881 my ( $language, $languagefile, $searchstring ) = @_;
883 my $keywords = get_value_from_sis_lng
($language, $languagefile, $searchstring );
888 ######################################################################
889 # Returning the application name for the Summary Information Stream
890 ######################################################################
892 sub get_appname_for_sis
894 my ( $language, $languagefile, $searchstring ) = @_;
896 my $appname = get_value_from_sis_lng
($language, $languagefile, $searchstring );
901 ######################################################################
902 # Returning the security for the Summary Information Stream
903 ######################################################################
905 sub get_security_for_sis
911 #################################################################
912 # Writing the Summary information stream into the msi database
913 # This works only on Windows
914 #################################################################
916 sub write_summary_into_msi_database
918 my ($msifilename, $language, $languagefile, $allvariableshashref) = @_;
920 # -g : requrired msi version
924 installer
::logger
::include_header_into_logfile
("Writing summary information stream");
926 my $msiinfo = "msiinfo.exe"; # Has to be in the path
928 my $sislanguage = "en-US"; # title, comment, keyword and appname alway in english
930 my $msiversion = get_msiversion_for_sis
();
931 my $codepage = get_codepage_for_sis
($language);
932 my $template = get_template_for_sis
($language);
933 my $guid = get_packagecode_for_sis
();
934 my $title = get_title_for_sis
($sislanguage,$languagefile, "OOO_SIS_TITLE");
935 my $author = get_author_for_sis
();
936 my $subject = get_subject_for_sis
($allvariableshashref);
937 my $comment = get_comment_for_sis
($sislanguage,$languagefile, "OOO_SIS_COMMENT");
938 my $keywords = get_keywords_for_sis
($sislanguage,$languagefile, "OOO_SIS_KEYWORDS");
939 my $appname = get_appname_for_sis
($sislanguage,$languagefile, "OOO_SIS_APPNAME");
940 my $security = get_security_for_sis
();
941 my $wordcount = get_wordcount_for_sis
();
943 $msifilename = installer
::converter
::make_path_conform
($msifilename);
945 my $systemcall = $msiinfo . " " . $msifilename . " -g " . $msiversion . " -c " . $codepage
946 . " -p " . $template . " -v " . $guid . " -t " . $title . " -a " . $author
947 . " -j " . $subject . " -o " . $comment . " -k " . $keywords . " -n " . $appname
948 . " -u " . $security . " -w " . $wordcount;
950 my $returnvalue = system($systemcall);
952 my $infoline = "Systemcall: $systemcall\n";
953 push( @installer::globals
::logfileinfo
, $infoline);
957 $infoline = "ERROR: Could not execute $msiinfo!\n";
958 push( @installer::globals
::logfileinfo
, $infoline);
962 $infoline = "Success: Executed $msiinfo successfully!\n";
963 push( @installer::globals
::logfileinfo
, $infoline);
967 #########################################################################
968 # For more than one language in the installation set:
969 # Use one database and create Transformations for all other languages
970 #########################################################################
972 sub create_transforms
974 my ($languagesarray, $defaultlanguage, $installdir, $allvariableshashref) = @_;
976 installer
::logger
::include_header_into_logfile
("Creating Transforms");
978 my $msitran = "msitran.exe"; # Has to be in the path
980 $installdir = installer
::converter
::make_path_conform
($installdir);
982 # Syntax for creating a transformation
983 # msitran.exe -g <baseDB> <referenceDB> <transformfile> [<errorhandling>}
985 my $basedbname = get_msidatabasename
($allvariableshashref, $defaultlanguage);
986 $basedbname = $installdir . $installer::globals
::separator
. $basedbname;
988 my $errorhandling = "f"; # Suppress "change codepage" error
990 # Iterating over all files
992 foreach ( @
{$languagesarray} )
994 my $onelanguage = $_;
996 if ( $onelanguage eq $defaultlanguage ) { next; }
998 my $referencedbname = get_msidatabasename
($allvariableshashref, $onelanguage);
999 $referencedbname = $installdir . $installer::globals
::separator
. $referencedbname;
1001 my $transformfile = $installdir . $installer::globals
::separator
. "trans_" . $onelanguage . ".mst";
1003 my $systemcall = $msitran . " " . " -g " . $basedbname . " " . $referencedbname . " " . $transformfile . " " . $errorhandling;
1005 my $returnvalue = system($systemcall);
1007 my $infoline = "Systemcall: $systemcall\n";
1008 push( @installer::globals
::logfileinfo
, $infoline);
1010 # Problem: msitran.exe in version 4.0 always returns "1", even if no failure occured.
1011 # Therefore it has to be checked, if this is version 4.0. If yes, if the mst file
1012 # exists and if it is larger than 0 bytes. If this is true, then no error occured.
1013 # File Version of msitran.exe: 4.0.6000.16384 has checksum: "b66190a70145a57773ec769e16777b29".
1014 # Same for msitran.exe from wntmsci12: "aa25d3445b94ffde8ef0c1efb77a56b8"
1018 $infoline = "WARNING: Returnvalue of $msitran is not 0. Checking version of $msitran!\n";
1019 push( @installer::globals
::logfileinfo
, $infoline);
1021 open(FILE
, "<$installer::globals::msitranpath") or die "ERROR: Can't open $installer::globals::msitranpath for creating file hash";
1023 my $digest = Digest
::MD5
->new->addfile(*FILE
)->hexdigest;
1026 my @problemchecksums = ("b66190a70145a57773ec769e16777b29", "aa25d3445b94ffde8ef0c1efb77a56b8");
1027 my $isproblemchecksum = 0;
1029 foreach my $problemchecksum ( @problemchecksums )
1031 $infoline = "Checksum of problematic MsiTran.exe: $problemchecksum\n";
1032 push( @installer::globals
::logfileinfo
, $infoline);
1033 $infoline = "Checksum of used MsiTran.exe: $digest\n";
1034 push( @installer::globals
::logfileinfo
, $infoline);
1035 if ( $digest eq $problemchecksum ) { $isproblemchecksum = 1; }
1038 if ( $isproblemchecksum )
1040 # Check existence of mst
1041 if ( -f
$transformfile )
1043 $infoline = "File $transformfile exists.\n";
1044 push( @installer::globals
::logfileinfo
, $infoline);
1045 my $filesize = ( -s
$transformfile );
1046 $infoline = "Size of $transformfile: $filesize\n";
1047 push( @installer::globals
::logfileinfo
, $infoline);
1049 if ( $filesize > 0 )
1051 $infoline = "Info: Returnvalue $returnvalue of $msitran is no problem :-) .\n";
1052 push( @installer::globals
::logfileinfo
, $infoline);
1053 $returnvalue = 0; # reset the error
1057 $infoline = "Filesize indicates that an error occured.\n";
1058 push( @installer::globals
::logfileinfo
, $infoline);
1063 $infoline = "File $transformfile does not exist -> An error occured.\n";
1064 push( @installer::globals
::logfileinfo
, $infoline);
1069 $infoline = "This is not a problematic version of msitran.exe. Therefore the error is not caused by problematic msitran.exe.\n";
1070 push( @installer::globals
::logfileinfo
, $infoline);
1076 $infoline = "ERROR: Could not execute $msitran!\n";
1077 push( @installer::globals
::logfileinfo
, $infoline);
1081 $infoline = "Success: Executed $msitran successfully!\n";
1082 push( @installer::globals
::logfileinfo
, $infoline);
1085 # The reference database can be deleted
1087 my $result = unlink($referencedbname);
1088 # $result contains the number of deleted files
1092 $infoline = "ERROR: Could not remove file $$referencedbname !\n";
1093 push( @installer::globals
::logfileinfo
, $infoline);
1094 installer
::exiter
::exit_program
($infoline, "create_transforms");
1099 #########################################################################
1100 # The default language msi database does not need to contain
1101 # the language in the database name. Therefore the file
1102 # is renamed. Example: "openofficeorg20_01.msi" to "openofficeorg20.msi"
1103 #########################################################################
1105 sub rename_msi_database_in_installset
1107 my ($defaultlanguage, $installdir, $allvariableshashref) = @_;
1109 installer
::logger
::include_header_into_logfile
("Renaming msi database");
1111 my $olddatabasename = get_msidatabasename
($allvariableshashref, $defaultlanguage);
1112 $olddatabasename = $installdir . $installer::globals
::separator
. $olddatabasename;
1114 my $newdatabasename = get_msidatabasename
($allvariableshashref);
1116 $installer::globals
::shortmsidatabasename
= $newdatabasename;
1118 $newdatabasename = $installdir . $installer::globals
::separator
. $newdatabasename;
1120 installer
::systemactions
::rename_one_file
($olddatabasename, $newdatabasename);
1122 $installer::globals
::msidatabasename
= $newdatabasename;
1125 #########################################################################
1126 # Adding the language to the name of the msi databasename,
1127 # if this is required (ADDLANGUAGEINDATABASENAME)
1128 #########################################################################
1130 sub add_language_to_msi_database
1132 my ($defaultlanguage, $installdir, $allvariables) = @_;
1134 my $languagestring = $defaultlanguage;
1135 if ( $allvariables->{'USELANGUAGECODE'} ) { $languagestring = installer
::windows
::language
::get_windows_language
($defaultlanguage); }
1136 my $newdatabasename = $installer::globals
::shortmsidatabasename
;
1137 $newdatabasename =~ s/\.msi\s*$/_$languagestring\.msi/;
1138 $installer::globals
::shortmsidatabasename
= $newdatabasename;
1139 $newdatabasename = $installdir . $installer::globals
::separator
. $newdatabasename;
1141 my $olddatabasename = $installer::globals
::msidatabasename
;
1143 installer
::systemactions
::rename_one_file
($olddatabasename, $newdatabasename);
1145 $installer::globals
::msidatabasename
= $newdatabasename;
1148 ##########################################################################
1149 # Writing the databasename into the setup.ini.
1150 ##########################################################################
1152 sub put_databasename_into_setupini
1154 my ($setupinifile, $allvariableshashref) = @_;
1156 my $databasename = get_msidatabasename
($allvariableshashref);
1157 my $line = "database=" . $databasename . "\n";
1159 push(@
{$setupinifile}, $line);
1162 ##########################################################################
1163 # Writing the required msi version into setup.ini
1164 ##########################################################################
1166 sub put_msiversion_into_setupini
1168 my ($setupinifile) = @_;
1170 my $msiversion = "2.0";
1171 my $line = "msiversion=" . $msiversion . "\n";
1173 push(@
{$setupinifile}, $line);
1176 ##########################################################################
1177 # Writing the productname into setup.ini
1178 ##########################################################################
1180 sub put_productname_into_setupini
1182 my ($setupinifile, $allvariableshashref) = @_;
1184 my $productname = $allvariableshashref->{'PRODUCTNAME'};
1185 my $line = "productname=" . $productname . "\n";
1187 push(@
{$setupinifile}, $line);
1190 ##########################################################################
1191 # Writing the productcode into setup.ini
1192 ##########################################################################
1194 sub put_productcode_into_setupini
1196 my ($setupinifile) = @_;
1198 my $productcode = $installer::globals
::productcode
;
1199 my $line = "productcode=" . $productcode . "\n";
1201 push(@
{$setupinifile}, $line);
1204 ##########################################################################
1205 # Writing the ProductVersion from Property table into setup.ini
1206 ##########################################################################
1208 sub put_productversion_into_setupini
1210 my ($setupinifile) = @_;
1212 my $line = "productversion=" . $installer::globals
::msiproductversion
. "\n";
1213 push(@
{$setupinifile}, $line);
1216 ##########################################################################
1217 # Writing the key for Minor Upgrades into setup.ini
1218 ##########################################################################
1220 sub put_upgradekey_into_setupini
1222 my ($setupinifile) = @_;
1224 if ( $installer::globals
::minorupgradekey
ne "" )
1226 my $line = "upgradekey=" . $installer::globals
::minorupgradekey
. "\n";
1227 push(@
{$setupinifile}, $line);
1231 ##########################################################################
1232 # Writing the number of languages into setup.ini
1233 ##########################################################################
1235 sub put_languagecount_into_setupini
1237 my ($setupinifile, $languagesarray) = @_;
1239 my $languagecount = $#{$languagesarray} + 1;
1240 my $line = "count=" . $languagecount . "\n";
1242 push(@
{$setupinifile}, $line);
1245 ##########################################################################
1246 # Writing the defaultlanguage into setup.ini
1247 ##########################################################################
1249 sub put_defaultlanguage_into_setupini
1251 my ($setupinifile, $defaultlanguage) = @_;
1253 my $windowslanguage = installer
::windows
::language
::get_windows_language
($defaultlanguage);
1254 my $line = "default=" . $windowslanguage . "\n";
1255 push(@
{$setupinifile}, $line);
1258 ##########################################################################
1259 # Writing the information about transformations into setup.ini
1260 ##########################################################################
1262 sub put_transforms_into_setupini
1264 my ($setupinifile, $onelanguage, $counter) = @_;
1266 my $windowslanguage = installer
::windows
::language
::get_windows_language
($onelanguage);
1267 my $transformfilename = "trans_" . $onelanguage . ".mst";
1269 my $line = "lang" . $counter . "=" . $windowslanguage . "," . $transformfilename . "\n";
1271 push(@
{$setupinifile}, $line);
1274 ###################################################
1275 # Including Windows line ends in ini files
1276 # Profiles on Windows shall have \r\n line ends
1277 ###################################################
1279 sub include_windows_lineends
1283 for ( my $i = 0; $i <= $#{$onefile}; $i++ )
1285 ${$onefile}[$i] =~ s/\r?\n$/\r\n/;
1289 ##########################################################################
1290 # Generation the file setup.ini, that is used by the loader setup.exe.
1291 ##########################################################################
1293 sub create_setup_ini
1295 my ($languagesarray, $defaultlanguage, $installdir, $allvariableshashref) = @_;
1297 installer
::logger
::include_header_into_logfile
("Creating setup.ini");
1299 my $setupinifilename = $installdir . $installer::globals
::separator
. "setup.ini";
1301 my @setupinifile = ();
1302 my $setupinifile = \
@setupinifile;
1304 my $line = "\[setup\]\n";
1305 push(@setupinifile, $line);
1307 put_databasename_into_setupini
($setupinifile, $allvariableshashref);
1308 put_msiversion_into_setupini
($setupinifile);
1309 put_productname_into_setupini
($setupinifile, $allvariableshashref);
1310 put_productcode_into_setupini
($setupinifile);
1311 put_productversion_into_setupini
($setupinifile);
1312 put_upgradekey_into_setupini
($setupinifile);
1314 $line = "\[languages\]\n";
1315 push(@setupinifile, $line);
1317 put_languagecount_into_setupini
($setupinifile, $languagesarray);
1318 put_defaultlanguage_into_setupini
($setupinifile, $defaultlanguage);
1320 if ( $#{$languagesarray} > 0 ) # writing the transforms information
1324 for ( my $i = 0; $i <= $#{$languagesarray}; $i++ )
1326 if ( ${$languagesarray}[$i] eq $defaultlanguage ) { next; }
1328 put_transforms_into_setupini
($setupinifile, ${$languagesarray}[$i], $counter);
1333 if ( $installer::globals
::iswin
&& $installer::globals
::plat
=~ /cygwin/i) # Windows line ends only for Cygwin
1335 include_windows_lineends
($setupinifile);
1338 installer
::files
::save_file
($setupinifilename, $setupinifile);
1340 $infoline = "Generated file $setupinifilename !\n";
1341 push( @installer::globals
::logfileinfo
, $infoline);
1344 #################################################################
1345 # Copying the files defined as ScpActions into the
1347 #################################################################
1349 sub copy_scpactions_into_installset
1351 my ($defaultlanguage, $installdir, $allscpactions) = @_;
1353 installer
::logger
::include_header_into_logfile
("Copying ScpAction files into installation set");
1355 for ( my $i = 0; $i <= $#{$allscpactions}; $i++ )
1357 my $onescpaction = ${$allscpactions}[$i];
1359 if ( $onescpaction->{'Name'} eq "loader.exe" ) { next; } # do not copy this ScpAction loader
1361 # only copying language independent files or files with the correct language (the defaultlanguage)
1363 my $filelanguage = $onescpaction->{'specificlanguage'};
1365 if ( ($filelanguage eq $defaultlanguage) || ($filelanguage eq "") )
1367 my $sourcefile = $onescpaction->{'sourcepath'};
1368 my $destfile = $installdir . $installer::globals
::separator
. $onescpaction->{'DestinationName'};
1370 installer
::systemactions
::copy_one_file
($sourcefile, $destfile);
1375 #################################################################
1376 # Copying the files for the Windows installer into the
1377 # installation set (setup.exe).
1378 #################################################################
1380 sub copy_windows_installer_files_into_installset
1382 my ($installdir, $includepatharrayref, $allvariables) = @_;
1384 installer
::logger
::include_header_into_logfile
("Copying Windows installer files into installation set");
1387 push(@copyfile, "loader2.exe");
1389 if ( $allvariables->{'NOLOADERREQUIRED'} ) { @copyfile = (); }
1391 for ( my $i = 0; $i <= $#copyfile; $i++ )
1393 my $filename = $copyfile[$i];
1394 my $sourcefileref = installer
::scriptitems
::get_sourcepath_from_filename_and_includepath
(\
$filename, $includepatharrayref, 1);
1396 if ( ! -f
$$sourcefileref ) { installer
::exiter
::exit_program
("ERROR: msi file not found: $$sourcefileref !", "copy_windows_installer_files_into_installset"); }
1399 if ( $copyfile[$i] eq "loader2.exe" ) { $destfile = "setup.exe"; } # renaming the loader
1400 else { $destfile = $copyfile[$i]; }
1402 $destfile = $installdir . $installer::globals
::separator
. $destfile;
1404 installer
::systemactions
::copy_one_file
($$sourcefileref, $destfile);
1408 #################################################################
1409 # Copying MergeModules for the Windows installer into the
1410 # installation set. The list of MergeModules is located
1411 # in %installer::globals::copy_msm_files
1412 #################################################################
1414 sub copy_merge_modules_into_installset
1416 my ($installdir) = @_;
1418 installer
::logger
::include_header_into_logfile
("Copying Merge files into installation set");
1421 foreach $cabfile ( keys %installer::globals
::copy_msm_files
)
1423 my $sourcefile = $installer::globals
::copy_msm_files
{$cabfile};
1424 my $destfile = $installdir . $installer::globals
::separator
. $cabfile;
1426 installer
::systemactions
::copy_one_file
($sourcefile, $destfile);
1430 #################################################################
1431 # Copying the child projects into the
1433 #################################################################
1435 sub copy_child_projects_into_installset
1437 my ($installdir, $allvariables) = @_;
1439 my $sourcefile = "";
1444 if ( $allvariables->{'JAVAPRODUCT'} )
1446 $sourcefile = $installer::globals
::javafile
->{'sourcepath'};
1447 $destdir = $installdir . $installer::globals
::separator
. $installer::globals
::javafile
->{'Subdir'};
1448 if ( ! -d
$destdir) { installer
::systemactions
::create_directory
($destdir); }
1449 installer
::systemactions
::copy_one_file
($sourcefile, $destdir);
1452 if ( $allvariables->{'UREPRODUCT'} )
1454 $sourcefile = $installer::globals
::urefile
->{'sourcepath'};
1455 $destdir = $installdir . $installer::globals
::separator
. $installer::globals
::urefile
->{'Subdir'};
1456 if ( ! -d
$destdir) { installer
::systemactions
::create_directory
($destdir); }
1457 installer
::systemactions
::copy_one_file
($sourcefile, $destdir);
1461 #################################################################
1462 # Getting a list of GUID using uuidgen.exe.
1463 # This works only on Windows
1464 #################################################################
1468 my ($number, $log) = @_;
1470 if ( $log ) { installer
::logger
::include_header_into_logfile
("Generating $number GUID"); }
1472 my $uuidgen = "uuidgen.exe"; # Has to be in the path
1474 # "-c" for uppercase output
1476 # my $systemcall = "$uuidgen -n$number -c |";
1477 my $systemcall = "$uuidgen -n$number |";
1478 open (UUIDGEN
, "$systemcall" ) or die("uuidgen is missing.");
1479 my @uuidlist = <UUIDGEN
>;
1482 my $infoline = "Systemcall: $systemcall\n";
1483 if ( $log ) { push( @installer::globals
::logfileinfo
, $infoline); }
1485 my $comparenumber = $#uuidlist + 1;
1487 if ( $comparenumber == $number )
1489 $infoline = "Success: Executed $uuidgen successfully!\n";
1490 if ( $log ) { push( @installer::globals
::logfileinfo
, $infoline); }
1494 $infoline = "ERROR: Could not execute $uuidgen successfully!\n";
1495 if ( $log ) { push( @installer::globals
::logfileinfo
, $infoline); }
1498 # uppercase, no longer "-c", because this is only supported in uuidgen.exe v.1.01
1499 for ( my $i = 0; $i <= $#uuidlist; $i++ ) { $uuidlist[$i] = uc($uuidlist[$i]); }
1504 #################################################################
1505 # Calculating a GUID with a string using md5.
1506 #################################################################
1510 my ( $string ) = @_;
1514 my $md5 = Digest
::MD5
->new;
1516 my $digest = $md5->hexdigest;
1517 $digest = uc($digest);
1519 # my $id = pack("A32", $digest);
1520 my ($first, $second, $third, $fourth, $fifth) = unpack ('A8 A4 A4 A4 A12', $digest);
1521 $guid = "$first-$second-$third-$fourth-$fifth";
1526 #################################################################
1527 # Filling the component hash with the values of the
1529 #################################################################
1531 sub fill_component_hash
1533 my ($componentfile) = @_;
1535 my %components = ();
1537 for ( my $i = 0; $i <= $#{$componentfile}; $i++ )
1539 my $line = ${$componentfile}[$i];
1541 if ( $line =~ /^\s*(.*?)\t(.*?)\s*$/ )
1546 $components{$key} = $value;
1550 return \
%components;
1553 #################################################################
1554 # Creating a new component file, if new guids were generated.
1555 #################################################################
1557 sub create_new_component_file
1559 my ($componenthash) = @_;
1561 my @componentfile = ();
1565 foreach $key (keys %{$componenthash})
1567 my $value = $componenthash->{$key};
1568 my $input = "$key\t$value\n";
1569 push(@componentfile ,$input);
1572 return \
@componentfile;
1575 #################################################################
1576 # Filling real component GUID into the component table.
1577 # This works only on Windows
1578 #################################################################
1580 sub set_uuid_into_component_table
1582 my ($idtdirbase, $allvariables) = @_;
1584 my $componenttablename = $idtdirbase . $installer::globals
::separator
. "Componen.idt";
1586 my $componenttable = installer
::files
::read_file
($componenttablename);
1588 # For update and patch reasons (small update) the GUID of an existing component must not change!
1589 # The collection of component GUIDs is saved in the directory $installer::globals::idttemplatepath in the file "components.txt"
1593 # my $componentfile = installer::files::read_file($installer::globals::componentfilename);
1594 # my $componenthash = fill_component_hash($componentfile);
1596 for ( my $i = 3; $i <= $#{$componenttable}; $i++ ) # ignoring the first three lines
1598 my $oneline = ${$componenttable}[$i];
1599 my $componentname = "";
1600 if ( $oneline =~ /^\s*(\S+?)\t/ ) { $componentname = $1; }
1604 # if ( $componenthash->{$componentname} )
1606 # $uuid = $componenthash->{$componentname};
1611 if ( exists($installer::globals
::calculated_component_guids
{$componentname}))
1613 $uuid = $installer::globals
::calculated_component_guids
{$componentname};
1617 # Calculating new GUID with the help of the component name.
1618 my $useooobaseversion = 1;
1619 if ( exists($installer::globals
::base_independent_components
{$componentname})) { $useooobaseversion = 0; }
1620 my $sourcestring = $componentname;
1622 if ( $useooobaseversion )
1624 if ( ! exists($allvariables->{'OOOBASEVERSION'}) ) { installer
::exiter
::exit_program
("ERROR: Could not find variable \"OOOBASEVERSION\" (required value for GUID creation)!", "set_uuid_into_component_table"); }
1625 $sourcestring = $sourcestring . "_" . $allvariables->{'OOOBASEVERSION'};
1627 $uuid = calculate_guid
($sourcestring);
1630 # checking, if there is a conflict with an already created guid
1631 if ( exists($installer::globals
::allcalculated_guids
{$uuid}) ) { installer
::exiter
::exit_program
("ERROR: \"$uuid\" was already created before!", "set_uuid_into_component_table"); }
1632 $installer::globals
::allcalculated_guids
{$uuid} = 1;
1633 $installer::globals
::calculated_component_guids
{$componentname} = $uuid;
1636 # $componenthash->{$componentname} = $uuid;
1639 # $installer::globals::created_new_component_guid = 1; # this is very important!
1643 ${$componenttable}[$i] =~ s/COMPONENTGUID/$uuid/;
1646 installer
::files
::save_file
($componenttablename, $componenttable);
1648 # if ( $installer::globals::created_new_component_guid )
1650 # # create new component file!
1651 # $componentfile = create_new_component_file($componenthash);
1652 # installer::worker::sort_array($componentfile);
1654 # # To avoid conflict the components file cannot be saved at the same place
1655 # # All important data have to be saved in the directory: $installer::globals::infodirectory
1656 # my $localcomponentfilename = $installer::globals::componentfilename;
1657 # installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$localcomponentfilename);
1658 # $localcomponentfilename = $installer::globals::infodirectory . $installer::globals::separator . $localcomponentfilename;
1659 # installer::files::save_file($localcomponentfilename, $componentfile);
1661 # # installer::files::save_file($installer::globals::componentfilename, $componentfile); # version using new file in solver
1663 # $infoline = "COMPONENTCODES: Created $counter new GUIDs for components ! \n";
1664 # push( @installer::globals::logfileinfo, $infoline);
1668 # $infoline = "SUCCESS COMPONENTCODES: All component codes exist! \n";
1669 # push( @installer::globals::logfileinfo, $infoline);
1674 #################################################################
1675 # Include all cab files into the msi database.
1676 # This works only on Windows
1677 #################################################################
1679 sub include_cabs_into_msi
1681 my ($installdir) = @_;
1683 installer
::logger
::include_header_into_logfile
("Including cabs into msi database");
1686 my $to = $installdir;
1690 my $infoline = "Changing into directory: $to";
1691 push( @installer::globals
::logfileinfo
, $infoline);
1693 my $msidb = "msidb.exe"; # Has to be in the path
1694 my $extraslash = ""; # Has to be set for non-ActiveState perl
1696 my $msifilename = $installer::globals
::msidatabasename
;
1698 $msifilename = installer
::converter
::make_path_conform
($msifilename);
1700 # msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
1701 $idtdirbase =~ s/\//\\\\/g
;
1702 $msifilename =~ s/\//\\\\/g
;
1705 my $allcabfiles = installer
::systemactions
::find_file_with_file_extension
("cab", $installdir);
1707 for ( my $i = 0; $i <= $#{$allcabfiles}; $i++ )
1709 my $systemcall = $msidb . " -d " . $msifilename . " -a " . ${$allcabfiles}[$i];
1711 my $returnvalue = system($systemcall);
1713 $infoline = "Systemcall: $systemcall\n";
1714 push( @installer::globals
::logfileinfo
, $infoline);
1718 $infoline = "ERROR: Could not execute $systemcall !\n";
1719 push( @installer::globals
::logfileinfo
, $infoline);
1723 $infoline = "Success: Executed $systemcall successfully!\n";
1724 push( @installer::globals
::logfileinfo
, $infoline);
1727 # deleting the cab file
1729 unlink(${$allcabfiles}[$i]);
1731 $infoline = "Deleted cab file: ${$allcabfiles}[$i]\n";
1732 push( @installer::globals
::logfileinfo
, $infoline);
1735 $infoline = "Changing back into directory: $from";
1736 push( @installer::globals
::logfileinfo
, $infoline);
1741 #################################################################
1742 # Executing the created batch file to pack all files.
1743 # This works only on Windows
1744 #################################################################
1746 sub execute_packaging
1748 my ($localpackjobref, $loggingdir, $allvariables) = @_;
1750 installer
::logger
::include_header_into_logfile
("Packaging process");
1752 installer
::logger
::include_timestamp_into_logfile
("Performance Info: Execute packaging start");
1756 my $to = $loggingdir;
1759 $infoline = "chdir: $to \n";
1760 push( @installer::globals
::logfileinfo
, $infoline);
1762 # if the ddf file contains relative pathes, it is necessary to change into the temp directory
1763 if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} )
1765 $to = $installer::globals
::temppath
;
1767 $infoline = "chdir: $to \n";
1768 push( @installer::globals
::logfileinfo
, $infoline);
1771 # changing the tmp directory, because makecab.exe generates temporary cab files
1772 my $origtemppath = "";
1773 if ( $ENV{'TMP'} ) { $origtemppath = $ENV{'TMP'}; }
1774 $ENV{'TMP'} = $installer::globals
::temppath
; # setting TMP to the new unique directory!
1776 my $maxmakecabcalls = 3;
1777 my $allmakecabcalls = $#{$localpackjobref} + 1;
1779 for ( my $i = 0; $i <= $#{$localpackjobref}; $i++ )
1781 my $systemcall = ${$localpackjobref}[$i];
1783 my $callscounter = $i + 1;
1785 installer
::logger
::print_message
( "... makecab.exe ($callscounter/$allmakecabcalls) ... \n" );
1787 # my $returnvalue = system($systemcall);
1789 for ( my $n = 1; $n <= $maxmakecabcalls; $n++ )
1793 $infoline = "Systemcall: $systemcall";
1794 push( @installer::globals
::logfileinfo
, $infoline);
1796 open (DDF
, "$systemcall");
1797 while (<DDF
>) {push(@ddfoutput, $_); }
1800 my $returnvalue = $?
; # $? contains the return value of the systemcall
1804 if ( $n < $maxmakecabcalls )
1806 installer
::logger
::print_message
( "makecab_error (Try $n): Trying again \n" );
1807 $infoline = "makecab_error (Try $n): $systemcall !";
1811 installer
::logger
::print_message
( "ERROR (Try $n): Abort packing \n" );
1812 $infoline = "ERROR (Try $n): $systemcall !";
1815 push( @installer::globals
::logfileinfo
, $infoline);
1816 # for ( my $j = 0; $j <= $#ddfoutput; $j++ ) { push( @installer::globals::logfileinfo, "$ddfoutput[$j]"); }
1818 for ( my $m = 0; $m <= $#ddfoutput; $m++ )
1820 if ( $ddfoutput[$m] =~ /(ERROR\:.*?)\s*$/ )
1822 $infoline = $1 . "\n";
1823 if ( $n < $maxmakecabcalls ) { $infoline =~ s/ERROR\:/makecab_error\:/i; }
1824 installer
::logger
::print_message
( $infoline );
1825 push( @installer::globals
::logfileinfo
, $infoline);
1829 if ( $n == $maxmakecabcalls ) { installer
::exiter
::exit_program
("ERROR: \"$systemcall\"!", "execute_packaging"); }
1833 # installer::logger::print_message( "Success (Try $n): \"$systemcall\"\n" );
1834 $infoline = "Success (Try $n): $systemcall";
1835 push( @installer::globals
::logfileinfo
, $infoline);
1841 installer
::logger
::include_timestamp_into_logfile
("Performance Info: Execute packaging end");
1843 # setting back to the original tmp directory
1844 $ENV{'TMP'} = $origtemppath;
1847 $infoline = "chdir: $from \n";
1848 push( @installer::globals
::logfileinfo
, $infoline);
1851 ###############################################################
1852 # Setting the global variables ProductCode and the UpgradeCode
1853 ###############################################################
1855 sub set_global_code_variables
1857 my ( $languagesref, $languagestringref, $allvariableshashref, $alloldproperties ) = @_;
1859 # In the msi template directory a files "codes.txt" has to exist, in which the ProductCode
1860 # and the UpgradeCode for the product are defined.
1861 # The name "codes.txt" can be overwritten in Product definition with CODEFILENAME .
1862 # Default $installer::globals::codefilename is defined in parameter.pm.
1864 if ( $allvariableshashref->{'CODEFILENAME'} )
1866 $installer::globals
::codefilename
= $installer::globals
::idttemplatepath
. $installer::globals
::separator
. $allvariableshashref->{'CODEFILENAME'};
1867 installer
::files
::check_file
($installer::globals
::codefilename
);
1870 my $infoline = "Using Codes file: $installer::globals::codefilename \n";
1871 push( @installer::globals
::logfileinfo
, $infoline);
1873 my $codefile = installer
::files
::read_file
($installer::globals
::codefilename
);
1875 my $isopensource = 0;
1876 if ( $allvariableshashref->{'OPENSOURCE'} ) { $isopensource = $allvariableshashref->{'OPENSOURCE'}; }
1878 my $onelanguage = "";
1880 if ( $#{$languagesref} > 0 ) # more than one language
1882 if (( ${$languagesref}[1] =~ /jp/ ) ||
1883 ( ${$languagesref}[1] =~ /ko/ ) ||
1884 ( ${$languagesref}[1] =~ /zh/ ))
1886 $onelanguage = "multiasia";
1890 $onelanguage = "multiwestern";
1893 else # only one language
1895 $onelanguage = ${$languagesref}[0];
1898 # ProductCode must not change, if Windows patches shall be applied
1899 if ( $installer::globals
::updatedatabase
)
1901 $installer::globals
::productcode
= $alloldproperties->{'ProductCode'};
1903 elsif ( $installer::globals
::prepare_winpatch
)
1905 # ProductCode has to be specified in each language
1906 my $searchstring = "PRODUCTCODE";
1907 my $codeblock = installer
::windows
::idtglobal
::get_language_block_from_language_file
($searchstring, $codefile);
1908 $installer::globals
::productcode
= installer
::windows
::idtglobal
::get_code_from_code_block
($codeblock, $onelanguage);
1910 my $guidref = get_guid_list
(1, 1); # only one GUID shall be generated
1911 ${$guidref}[0] =~ s/\s*$//; # removing ending spaces
1912 $installer::globals
::productcode
= "\{" . ${$guidref}[0] . "\}";
1915 if ( $installer::globals
::patch
) # patch upgrade codes are defined in soffice.lst
1917 if ( $allvariableshashref->{'PATCHUPGRADECODE'} ) { $installer::globals
::upgradecode
= $allvariableshashref->{'PATCHUPGRADECODE'}; }
1918 else { installer
::exiter
::exit_program
("ERROR: PATCHUPGRADECODE not defined in list file!", "set_global_code_variables"); }
1922 # UpgradeCode can take english as default, if not defined in specified language
1924 $searchstring = "UPGRADECODE"; # searching in the codes.txt file
1925 $codeblock = installer
::windows
::idtglobal
::get_language_block_from_language_file
($searchstring, $codefile);
1926 $installer::globals
::upgradecode
= installer
::windows
::idtglobal
::get_language_string_from_language_block
($codeblock, $onelanguage, "");
1929 # if (( $installer::globals::productcode eq "" ) && ( ! $isopensource )) { installer::exiter::exit_program("ERROR: ProductCode for language $onelanguage not defined in $installer::globals::codefilename !", "set_global_code_variables"); }
1930 if ( $installer::globals
::upgradecode
eq "" ) { installer
::exiter
::exit_program
("ERROR: UpgradeCode not defined in $installer::globals::codefilename !", "set_global_code_variables"); }
1932 $infoline = "Setting ProductCode to: $installer::globals::productcode \n";
1933 push( @installer::globals
::logfileinfo
, $infoline);
1934 $infoline = "Setting UpgradeCode to: $installer::globals::upgradecode \n";
1935 push( @installer::globals
::logfileinfo
, $infoline);
1937 # Adding both variables into the variables array
1939 $allvariableshashref->{'PRODUCTCODE'} = $installer::globals
::productcode
;
1940 $allvariableshashref->{'UPGRADECODE'} = $installer::globals
::upgradecode
;
1942 $infoline = "Defined variable PRODUCTCODE: $installer::globals::productcode \n";
1943 push( @installer::globals
::logfileinfo
, $infoline);
1945 $infoline = "Defined variable UPGRADECODE: $installer::globals::upgradecode \n";
1946 push( @installer::globals
::logfileinfo
, $infoline);
1950 ###############################################################
1951 # Setting the product version used in property table and
1952 # upgrade table. Saving in global variable $msiproductversion
1953 ###############################################################
1955 sub set_msiproductversion
1957 my ( $allvariables ) = @_;
1959 my $productversion = $allvariables->{'PRODUCTVERSION'};
1961 if (( $productversion =~ /^\s*\d+\s*$/ ) && ( $productversion > 255 )) { $productversion = $productversion%256; }
1963 if ( $productversion =~ /^\s*(\d+)\.(\d+)\.(\d+)\s*$/ )
1965 $productversion = $1 . "\." . $2 . $3 . "\." . $installer::globals
::buildid
;
1967 elsif ( $productversion =~ /^\s*(\d+)\.(\d+)\s*$/ )
1969 $productversion = $1 . "\." . $2 . "\." . $installer::globals
::buildid
;
1973 my $productminor = "00";
1974 if (( $allvariables->{'PACKAGEVERSION'} ) && ( $allvariables->{'PACKAGEVERSION'} ne "" ))
1976 if ( $allvariables->{'PACKAGEVERSION'} =~ /^\s*(\d+)\.(\d+)\.(\d+)\s*$/ ) { $productminor = $2; }
1979 $productversion = $productversion . "\." . $productminor . "\." . $installer::globals
::buildid
;
1982 $installer::globals
::msiproductversion
= $productversion;
1984 # Setting $installer::globals::msimajorproductversion, to differ between old version in upgrade table
1986 if ( $installer::globals
::msiproductversion
=~ /^\s*(\d+)\./ )
1989 $installer::globals
::msimajorproductversion
= $major . "\.0\.0";
1993 #################################################################################
1994 # Including the msi product version into the bootstrap.ini, Windows only
1995 #################################################################################
1997 sub put_msiproductversion_into_bootstrapfile
1999 my ($filesref) = @_;
2001 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
2003 my $onefile = ${$filesref}[$i];
2005 if ( $onefile->{'gid'} eq "gid_Profile_Version_Ini" )
2007 my $file = installer
::files
::read_file
($onefile->{'sourcepath'});
2009 for ( my $j = 0; $j <= $#{$file}; $j++ )
2011 ${$file}[$j] =~ s/\<msiproductversion\>/$installer::globals::msiproductversion/;
2014 installer
::files
::save_file
($onefile->{'sourcepath'}, $file);
2021 ####################################################################################
2022 # Updating the file Property.idt dynamically
2025 ####################################################################################
2027 sub update_reglocat_table
2029 my ($basedir, $allvariables) = @_;
2031 my $reglocatfilename = $basedir . $installer::globals
::separator
. "RegLocat.idt";
2033 # Only do something, if this file exists
2035 if ( -f
$reglocatfilename )
2037 my $reglocatfile = installer
::files
::read_file
($reglocatfilename);
2040 if ( $allvariables->{'REGISTRYLAYERNAME'} )
2042 $layername = $allvariables->{'REGISTRYLAYERNAME'};
2046 for ( my $i = 0; $i <= $#{$reglocatfile}; $i++ )
2048 if ( ${$reglocatfile}[$i] =~ /\bLAYERNAMETEMPLATE\b/ )
2050 installer
::exiter
::exit_program
("ERROR: Variable \"REGISTRYLAYERNAME\" has to be defined", "update_reglocat_table");
2055 if ( $layername ne "" )
2057 # Updating the layername in
2059 for ( my $i = 0; $i <= $#{$reglocatfile}; $i++ )
2061 ${$reglocatfile}[$i] =~ s/\bLAYERNAMETEMPLATE\b/$layername/;
2065 installer
::files
::save_file
($reglocatfilename ,$reglocatfile);
2066 my $infoline = "Updated idt file: $reglocatfilename\n";
2067 push(@installer::globals
::logfileinfo
, $infoline);
2074 ####################################################################################
2075 # Updating the file RemoveRe.idt dynamically (RemoveRegistry.idt)
2076 # The name of the component has to be replaced.
2077 ####################################################################################
2079 sub update_removere_table
2083 my $removeregistryfilename = $basedir . $installer::globals
::separator
. "RemoveRe.idt";
2085 # Only do something, if this file exists
2087 if ( -f
$removeregistryfilename )
2089 my $removeregistryfile = installer
::files
::read_file
($removeregistryfilename);
2091 for ( my $i = 0; $i <= $#{$removeregistryfile}; $i++ )
2093 for ( my $i = 0; $i <= $#{$removeregistryfile}; $i++ )
2095 ${$removeregistryfile}[$i] =~ s/\bREGISTRYROOTCOMPONENT\b/$installer::globals::registryrootcomponent/;
2100 installer
::files
::save_file
($removeregistryfilename ,$removeregistryfile);
2101 my $infoline = "Updated idt file: $removeregistryfilename \n";
2102 push(@installer::globals
::logfileinfo
, $infoline);
2106 ##########################################################################
2107 # Reading saved mappings in Files.idt and Director.idt.
2108 # This is required, if installation sets shall be created,
2109 # that can be used for creation of msp files.
2110 ##########################################################################
2112 sub read_saved_mappings
2114 installer
::logger
::include_header_into_logfile
("Reading saved mappings from older installation sets:");
2116 installer
::logger
::include_timestamp_into_logfile
("Performance Info: Reading saved mappings start");
2118 if ( $installer::globals
::previous_idt_dir
)
2120 my @errorlines = ();
2121 my $errorstring = "";
2122 my $error_occured = 0;
2123 my $file_error_occured = 0;
2126 my $idtdir = $installer::globals
::previous_idt_dir
;
2127 $idtdir =~ s/\Q$installer::globals::separator\E\s*$//;
2131 my $idtfile = $idtdir . $installer::globals
::separator
. "File.idt";
2132 push( @installer::globals
::globallogfileinfo
, "\nAnalyzing file: $idtfile\n" );
2133 if ( ! -f
$idtfile ) { push( @installer::globals
::globallogfileinfo
, "Warning: File $idtfile does not exist!\n" ); }
2136 open (F
, "<$idtfile") || installer
::exiter
::exit_program
("ERROR: Cannot open file $idtfile for reading", "read_saved_mappings");
2140 m/^([^\t]+)\t([^\t]+)\t((.*)\|)?([^\t]*)/;
2141 print "OUT1: \$1: $1, \$2: $2, \$3: $3, \$4: $4, \$5: $5\n";
2142 next if ("$1" eq "$5") && (!defined($3));
2145 if ( exists($installer::globals
::savedmapping
{"$2/$5"}))
2147 if ( ! $file_error_occured )
2149 $errorstring = "\nErrors in $idtfile: \n";
2150 push(@errorlines, $errorstring);
2152 $errorstring = "Duplicate savedmapping{" . "$2/$5}\n";
2153 push(@errorlines, $errorstring);
2155 $file_error_occured = 1;
2158 if ( exists($installer::globals
::savedrevmapping
{$lc1}))
2160 if ( ! $file_error_occured )
2162 $errorstring = "\nErrors in $idtfile: \n";
2163 push(@errorlines, $errorstring);
2165 $errorstring = "Duplicate savedrevmapping{" . "$lc1}\n";
2166 push(@errorlines, $errorstring);
2168 $file_error_occured = 1;
2171 my $shortname = $4 || '';
2173 # Don't reuse illegal 8.3 mappings that we used to generate in 2.0.4
2174 if (index($shortname, '.') > 8 ||
2175 (index($shortname, '.') == -1 && length($shortname) > 8))
2180 if (( $shortname ne '' ) && ( index($shortname, '~') > 0 ) && ( exists($installer::globals
::savedrev83mapping
{$shortname}) ))
2182 if ( ! $file_error_occured )
2184 $errorstring = "\nErrors in $idtfile: \n";
2185 push(@errorlines, $errorstring);
2187 $errorstring = "Duplicate savedrev83mapping{" . "$shortname}\n";
2188 push(@errorlines, $errorstring);
2190 $file_error_occured = 1;
2193 $installer::globals
::savedmapping
{"$2/$5"} = "$1;$shortname";
2194 $installer::globals
::savedrevmapping
{lc($1)} = "$2/$5";
2195 $installer::globals
::savedrev83mapping
{$shortname} = "$2/$5" if $shortname ne '';
2201 push( @installer::globals
::globallogfileinfo
, "Read $n old file table key or 8.3 name mappings from $idtfile\n" );
2203 # Reading Director.idt
2205 $idtfile = $idtdir . $installer::globals
::separator
. "Director.idt";
2206 push( @installer::globals
::globallogfileinfo
, "\nAnalyzing file $idtfile\n" );
2207 if ( ! -f
$idtfile ) { push( @installer::globals
::globallogfileinfo
, "Warning: File $idtfile does not exist!\n" ); }
2210 open (F
, "<$idtfile") || installer
::exiter
::exit_program
("ERROR: Cannot open file $idtfile for reading", "read_saved_mappings");
2214 m/^([^\t]+)\t([^\t]+)\t(([^~]+~\d.*)\|)?([^\t]*)/;
2215 next if (!defined($3));
2218 print "OUT2: \$1: $1, \$2: $2, \$3: $3\n";
2220 if ( exists($installer::globals
::saved83dirmapping
{$1}) )
2222 if ( ! $dir_error_occured )
2224 $errorstring = "\nErrors in $idtfile: \n";
2225 push(@errorlines, $errorstring);
2227 $errorstring = "Duplicate saved83dirmapping{" . "$1}\n";
2228 push(@errorlines, $errorstring);
2230 $dir_error_occured = 1;
2233 $installer::globals
::saved83dirmapping
{$1} = $4;
2238 push( @installer::globals
::globallogfileinfo
, "Read $n old directory 8.3 name mappings from $idtfile\n" );
2242 if ( $error_occured )
2244 for ( my $i = 0; $i <= $#errorlines; $i++ )
2246 print "$errorlines[$i]";
2247 push( @installer::globals
::globallogfileinfo
, "$errorlines[$i]");
2249 installer
::exiter
::exit_program
("ERROR: Duplicate entries in saved mappings!", "read_saved_mappings");
2252 # push( @installer::globals::globallogfileinfo, "WARNING: Windows patch shall be prepared, but PREVIOUS_IDT_DIR is not set!\n" );
2253 installer
::exiter
::exit_program
("ERROR: Windows patch shall be prepared, but environment variable PREVIOUS_IDT_DIR is not set!", "read_saved_mappings");
2256 installer
::logger
::include_timestamp_into_logfile
("Performance Info: Reading saved mappings end");