update dev300-m58
[ooovba.git] / solenv / bin / modules / installer / worker.pm
blobd9858f8609ec2148183f26a774a475bda2e95bdc
1 #*************************************************************************
3 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 #
5 # Copyright 2008 by Sun Microsystems, Inc.
7 # OpenOffice.org - a multi-platform office productivity suite
9 # $RCSfile: worker.pm,v $
11 # $Revision: 1.65.56.1 $
13 # This file is part of OpenOffice.org.
15 # OpenOffice.org is free software: you can redistribute it and/or modify
16 # it under the terms of the GNU Lesser General Public License version 3
17 # only, as published by the Free Software Foundation.
19 # OpenOffice.org is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU Lesser General Public License version 3 for more details
23 # (a copy is included in the LICENSE file that accompanied this code).
25 # You should have received a copy of the GNU Lesser General Public License
26 # version 3 along with OpenOffice.org. If not, see
27 # <http://www.openoffice.org/license.html>
28 # for a copy of the LGPLv3 License.
30 #*************************************************************************
32 package installer::worker;
34 use Cwd;
35 use File::Copy;
36 use File::stat;
37 use File::Temp qw(tmpnam);
38 use installer::control;
39 use installer::converter;
40 use installer::existence;
41 use installer::exiter;
42 use installer::files;
43 use installer::globals;
44 use installer::logger;
45 use installer::mail;
46 use installer::pathanalyzer;
47 use installer::scpzipfiles;
48 use installer::scriptitems;
49 use installer::sorter;
50 use installer::systemactions;
51 use installer::windows::language;
53 #####################################################################
54 # Unpacking all files ending with tar.gz in a specified directory
55 #####################################################################
57 sub unpack_all_targzfiles_in_directory
59 my ( $directory ) = @_;
61 installer::logger::include_header_into_logfile("Unpacking tar.gz files:");
63 installer::logger::print_message( "... unpacking tar.gz files ... \n" );
65 my $localdirectory = $directory . $installer::globals::separator . "packages";
66 my $alltargzfiles = installer::systemactions::find_file_with_file_extension("tar.gz", $localdirectory);
68 for ( my $i = 0; $i <= $#{$alltargzfiles}; $i++ )
70 my $onefile = $localdirectory . $installer::globals::separator . ${$alltargzfiles}[$i];
72 my $systemcall = "cd $localdirectory; cat ${$alltargzfiles}[$i] \| gunzip \| tar -xf -";
73 $returnvalue = system($systemcall);
75 my $infoline = "Systemcall: $systemcall\n";
76 push( @installer::globals::logfileinfo, $infoline);
78 if ($returnvalue)
80 $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
81 push( @installer::globals::logfileinfo, $infoline);
83 else
85 $infoline = "Success: Executed \"$systemcall\" successfully!\n";
86 push( @installer::globals::logfileinfo, $infoline);
91 #########################################
92 # Copying installation sets to ship
93 #########################################
95 sub copy_install_sets_to_ship
97 my ( $destdir, $shipinstalldir ) = @_;
99 installer::logger::include_header_into_logfile("Copying installation set to ship:");
101 my $dirname = $destdir;
102 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$dirname);
103 $dirname = $dirname . "_inprogress";
104 my $localshipinstalldir = $shipinstalldir . $installer::globals::separator . $dirname;
105 if ( ! -d $localshipinstalldir ) { installer::systemactions::create_directory_structure($localshipinstalldir); }
107 # copy installation set to /ship ($localshipinstalldir)
108 installer::logger::print_message( "... copy installation set from " . $destdir . " to " . $localshipinstalldir . "\n" );
109 installer::systemactions::copy_complete_directory($destdir, $localshipinstalldir);
111 if (( ! $installer::globals::iswindowsbuild ) && ( $installer::globals::addjavainstaller ))
113 # Setting Unix rights for Java starter ("setup")
114 my $localcall = "chmod 775 $localshipinstalldir/setup \>\/dev\/null 2\>\&1";
115 system($localcall);
118 # unpacking the tar.gz file for Solaris
119 if ( $installer::globals::issolarisbuild ) { unpack_all_targzfiles_in_directory($localshipinstalldir); }
121 $localshipinstalldir = installer::systemactions::rename_string_in_directory($localshipinstalldir, "_inprogress", "");
123 return $localshipinstalldir;
126 #########################################
127 # Copying installation sets to ship
128 #########################################
130 sub link_install_sets_to_ship
132 my ( $destdir, $shipinstalldir ) = @_;
134 installer::logger::include_header_into_logfile("Linking installation set to ship:");
136 my $infoline = "... destination directory: $shipinstalldir ...\n";
137 installer::logger::print_message( $infoline );
138 push( @installer::globals::logfileinfo, $infoline);
140 if ( ! -d $shipinstalldir)
142 $infoline = "Creating directory: $shipinstalldir\n";
143 push( @installer::globals::logfileinfo, $infoline);
144 installer::systemactions::create_directory_structure($shipinstalldir);
145 $infoline = "Created directory: $shipinstalldir\n";
146 push( @installer::globals::logfileinfo, $infoline);
149 my $dirname = $destdir;
150 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$dirname);
152 my $localshipinstalldir = $shipinstalldir . $installer::globals::separator . $dirname;
154 # link installation set to /ship ($localshipinstalldir)
155 installer::logger::print_message( "... linking installation set from " . $destdir . " to " . $localshipinstalldir . "\n" );
157 my $systemcall = "ln -s $destdir $localshipinstalldir";
159 $returnvalue = system($systemcall);
161 $infoline = "Systemcall: $systemcall\n";
162 push( @installer::globals::logfileinfo, $infoline);
164 if ($returnvalue)
166 $infoline = "ERROR: Could not create link \"$localshipinstalldir\"!\n";
167 push( @installer::globals::logfileinfo, $infoline);
169 else
171 $infoline = "Success: Created link \"$localshipinstalldir\"!\n";
172 push( @installer::globals::logfileinfo, $infoline);
175 return $localshipinstalldir;
178 #########################################
179 # Create checksum file
180 #########################################
182 sub make_checksum_file
184 my ( $filesref, $includepatharrayref ) = @_;
186 my @checksum = ();
188 my $checksumfileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$installer::globals::checksumfile, $includepatharrayref, 1);
189 if ( $$checksumfileref eq "" ) { installer::exiter::exit_program("ERROR: Could not find file $installer::globals::checksumfile !", "make_checksum_file"); }
191 # # very slow on Windows
192 # for ( my $i = 0; $i <= $#{$filesref}; $i++ )
194 # my $onefile = ${$filesref}[$i];
195 # my $systemcall = "$$checksumfileref $onefile->{'sourcepath'} |";
196 # open (CHECK, "$systemcall");
197 # my $localchecksum = <CHECK>;
198 # close (CHECK);
199 # push(@checksum, $localchecksum);
202 my $systemcall = "$$checksumfileref";
204 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
206 my $onefile = ${$filesref}[$i];
207 $systemcall = $systemcall . " " . $onefile->{'sourcepath'}; # very very long systemcall
209 if ((( $i > 0 ) && ( $i%100 == 0 )) || ( $i == $#{$filesref} )) # limiting to 100 files
211 $systemcall = $systemcall . " \|";
213 my @localchecksum = ();
214 open (CHECK, "$systemcall");
215 @localchecksum = <CHECK>;
216 close (CHECK);
218 for ( my $j = 0; $j <= $#localchecksum; $j++ ) { push(@checksum, $localchecksum[$j]); }
220 $systemcall = "$$checksumfileref"; # reset the system call
224 return \@checksum;
227 #########################################
228 # Saving the checksum file
229 #########################################
231 sub save_checksum_file
233 my ($current_install_number, $installchecksumdir, $checksumfile) = @_;
235 my $numberedchecksumfilename = $installer::globals::checksumfilename;
236 $numberedchecksumfilename =~ s/\./_$current_install_number\./; # checksum.txt -> checksum_01.txt
237 installer::files::save_file($installchecksumdir . $installer::globals::separator . $numberedchecksumfilename, $checksumfile);
240 #################################################
241 # Writing some global information into
242 # the list of files without flag PATCH
243 #################################################
245 sub write_nopatchlist_header
247 my ( $content ) = @_;
249 my @header = ();
250 my $infoline = "This is a list of files, that are defined in scp-projects without\n";
251 push(@header, $infoline);
252 $infoline = "flag \"PATCH\". Important: This does not mean in any case, that \n";
253 push(@header, $infoline);
254 $infoline = "this files are included into or excluded from a patch. \n\n";
255 push(@header, $infoline);
256 $infoline = "Exception Linux: A patch rpm is a complete rpm. This means that all \n";
257 push(@header, $infoline);
258 $infoline = "files are included into a patch rpm, if only one file of the rpm has the \n";
259 push(@header, $infoline);
260 $infoline = "style \"PATCH\". \n\n";
261 push(@header, $infoline);
263 for ( my $i = 0; $i <= $#header; $i++ ) { push(@{$content},$header[$i]); }
266 #################################################
267 # Creating the content of the list of files
268 # without flag PATCH.
269 # All files are saved in
270 # @{$installer::globals::nopatchfilecollector}
271 #################################################
273 sub create_nopatchlist
275 my @content =();
277 write_nopatchlist_header(\@content);
279 for ( my $i = 0; $i <= $#{$installer::globals::nopatchfilecollector}; $i++ )
281 my $onefile = ${$installer::globals::nopatchfilecollector}[$i];
282 my $oneline = $onefile->{'destination'};
283 if ( $onefile->{'zipfilename'} ) { $oneline = $oneline . " (" . $onefile->{'zipfilename'} . ")"; }
284 $oneline = $oneline . "\n";
285 push(@content, $oneline);
288 return \@content;
291 #########################################
292 # Saving the patchlist file
293 #########################################
295 sub save_patchlist_file
297 my ($installlogdir, $patchlistfilename) = @_;
299 my $installpatchlistdir = installer::systemactions::create_directory_next_to_directory($installlogdir, "patchlist");
300 $patchlistfilename =~ s/log\_/patchfiles\_/;
301 $patchlistfilename =~ s/\.log/\.txt/;
302 installer::files::save_file($installpatchlistdir . $installer::globals::separator . $patchlistfilename, \@installer::globals::patchfilecollector);
303 installer::logger::print_message( "... creating patchlist file $patchlistfilename \n" );
305 if (( $installer::globals::patch ) && ( ! $installer::globals::creating_windows_installer_patch )) # only for non-Windows patches
307 $patchlistfilename =~ s/patchfiles\_/nopatchfiles\_/;
308 my $nopatchlist = create_nopatchlist();
309 installer::files::save_file($installpatchlistdir . $installer::globals::separator . $patchlistfilename, $nopatchlist);
310 installer::logger::print_message( "... creating patch exclusion file $patchlistfilename \n" );
315 ###############################################################
316 # Removing all directories of a special language
317 # in the directory $basedir
318 ###############################################################
320 sub remove_old_installation_sets
322 my ($basedir) = @_;
324 installer::logger::print_message( "... removing old installation directories ...\n" );
326 my $removedir = $basedir;
328 if ( -d $removedir ) { installer::systemactions::remove_complete_directory($removedir, 1); }
330 # looking for non successful old installation sets
332 $removedir = $basedir . "_witherror";
333 if ( -d $removedir ) { installer::systemactions::remove_complete_directory($removedir, 1); }
335 $removedir = $basedir . "_inprogress";
336 if ( -d $removedir ) { installer::systemactions::remove_complete_directory($removedir, 1); }
338 # finally the $basedir can be created empty
340 if ( $installer::globals::localinstalldirset ) { installer::systemactions::create_directory_structure($basedir); }
342 installer::systemactions::create_directory($basedir);
345 ###############################################################
346 # Removing all non successful installation sets on ship
347 ###############################################################
349 sub remove_old_ship_installation_sets
351 my ($fulldir, $counter) = @_;
353 installer::logger::print_message( "... removing old installation directories ...\n" );
355 my $basedir = $fulldir;
356 installer::pathanalyzer::get_path_from_fullqualifiedname(\$basedir);
358 # collecting all directories next to the new installation directory
359 my $alldirs = installer::systemactions::get_all_directories($basedir);
361 if ( $fulldir =~ /^\s*(.*?inprogress\-)(\d+)(.*?)\s*$/ )
363 my $pre_inprogress = $1; # $pre still contains "inprogress"
364 my $number = $2;
365 my $post = $3;
366 my $pre_witherror = $pre_inprogress;
367 $pre_witherror =~ s/inprogress/witherror/;
369 for ( my $i = 0; $i <= $#{$alldirs}; $i++ )
371 if ( ${$alldirs}[$i] eq $fulldir ) { next; } # do not delete the newly created directory
373 if ( ${$alldirs}[$i] =~ /^\s*\Q$pre_inprogress\E\d+\Q$post\E\s*$/ ) # removing old "inprogress" directories
375 installer::systemactions::remove_complete_directory(${$alldirs}[$i], 1);
378 if ( ${$alldirs}[$i] =~ /^\s*\Q$pre_witherror\E\d+\Q$post\E\s*$/ ) # removing old "witherror" directories
380 installer::systemactions::remove_complete_directory(${$alldirs}[$i], 1);
386 ###############################################################
387 # Creating the installation directory structure
388 ###############################################################
390 sub create_installation_directory
392 my ($shipinstalldir, $languagestringref, $current_install_number_ref) = @_;
394 my $installdir = "";
396 my $languageref = $languagestringref;
398 if ( $installer::globals::updatepack )
400 $installdir = $shipinstalldir;
401 installer::systemactions::create_directory_structure($installdir);
402 $$current_install_number_ref = installer::systemactions::determine_maximum_number($installdir, $languageref);
403 $installdir = installer::systemactions::rename_string_in_directory($installdir, "number", $$current_install_number_ref);
404 remove_old_ship_installation_sets($installdir);
406 else
408 $installdir = installer::systemactions::create_directories("install", $languageref);
409 if ( $installer::globals::localinstalldir )
411 $installdir = $installer::globals::localinstalldir;
412 $installer::globals::localinstalldirset = 1;
414 installer::logger::print_message( "... creating installation set in $installdir ...\n" );
415 remove_old_installation_sets($installdir);
416 my $inprogressinstalldir = $installdir . "_inprogress";
417 installer::systemactions::rename_directory($installdir, $inprogressinstalldir);
418 $installdir = $inprogressinstalldir;
421 $installer::globals::saveinstalldir = $installdir; # saving directory globally, in case of exiting
423 return $installdir;
426 ###############################################################
427 # Analyzing and creating the log file
428 ###############################################################
430 sub analyze_and_save_logfile
432 my ($loggingdir, $installdir, $installlogdir, $allsettingsarrayref, $languagestringref, $current_install_number) = @_;
434 my $is_success = 1;
435 my $finalinstalldir = "";
437 installer::logger::print_message( "... checking log file " . $loggingdir . $installer::globals::logfilename . "\n" );
439 my $contains_error = installer::control::check_logfile(\@installer::globals::logfileinfo);
441 # Dependent from the success, the installation directory can be renamed and mails can be send.
443 if ( $contains_error )
445 my $errordir = installer::systemactions::rename_string_in_directory($installdir, "_inprogress", "_witherror");
446 if ( $installer::globals::updatepack ) { installer::mail::send_fail_mail($allsettingsarrayref, $languagestringref, $errordir); }
447 # Error output to STDERR
448 for ( my $j = 0; $j <= $#installer::globals::errorlogfileinfo; $j++ )
450 my $line = $installer::globals::errorlogfileinfo[$j];
451 $line =~ s/\s*$//g;
452 installer::logger::print_error( $line );
454 $is_success = 0;
456 $finalinstalldir = $errordir;
458 else
460 my $destdir = "";
462 if ( $installer::globals::updatepack )
464 if ( $installdir =~ /_download_inprogress/ ) { $destdir = installer::systemactions::rename_string_in_directory($installdir, "_download_inprogress", "_download"); }
465 elsif ( $installdir =~ /_jds_inprogress/ ) { $destdir = installer::systemactions::rename_string_in_directory($installdir, "_jds_inprogress", "_jds"); }
466 elsif ( $installdir =~ /_msp_inprogress/ ) { $destdir = installer::systemactions::rename_string_in_directory($installdir, "_msp_inprogress", "_msp"); }
467 else
469 if ( $installdir =~ /_packed/ ) { $destdir = installer::systemactions::rename_string_in_directory($installdir, "_inprogress", ""); }
470 else { $destdir = installer::systemactions::rename_string_in_directory($installdir, "_inprogress", "_packed"); }
472 installer::mail::send_success_mail($allsettingsarrayref, $languagestringref, $destdir);
474 else
476 $destdir = installer::systemactions::rename_string_in_directory($installdir, "_inprogress", "");
479 $finalinstalldir = $destdir;
482 # Saving the logfile in the log file directory and additionally in a log directory in the install directory
484 my $numberedlogfilename = $installer::globals::logfilename;
485 if ( $installer::globals::updatepack ) { $numberedlogfilename =~ s /log_/log_$current_install_number\_/; }
486 installer::logger::print_message( "... creating log file $numberedlogfilename \n" );
487 installer::files::save_file($loggingdir . $numberedlogfilename, \@installer::globals::logfileinfo);
488 installer::files::save_file($installlogdir . $installer::globals::separator . $numberedlogfilename, \@installer::globals::logfileinfo);
490 # Saving the checksumfile in a checksum directory in the install directory
491 # installer::worker::save_checksum_file($current_install_number, $installchecksumdir, $checksumfile);
493 # Saving the list of patchfiles in a patchlist directory in the install directory
494 if (( $installer::globals::patch ) || ( $installer::globals::creating_windows_installer_patch )) { installer::worker::save_patchlist_file($installlogdir, $numberedlogfilename); }
496 if ( $installer::globals::creating_windows_installer_patch ) { $installer::globals::creating_windows_installer_patch = 0; }
498 return ($is_success, $finalinstalldir);
501 ###############################################################
502 # Analyzing and creating the log file
503 ###############################################################
505 sub save_logfile_after_linking
507 my ($loggingdir, $installlogdir, $current_install_number) = @_;
509 # Saving the logfile in the log file directory and additionally in a log directory in the install directory
510 my $numberedlogfilename = $installer::globals::logfilename;
511 if ( $installer::globals::updatepack ) { $numberedlogfilename =~ s /log_/log_$current_install_number\_/; }
512 installer::logger::print_message( "... creating log file $numberedlogfilename \n" );
513 installer::files::save_file($loggingdir . $numberedlogfilename, \@installer::globals::logfileinfo);
514 installer::files::save_file($installlogdir . $installer::globals::separator . $numberedlogfilename, \@installer::globals::logfileinfo);
517 ###############################################################
518 # Removing all directories that are saved in the
519 # global directory @installer::globals::removedirs
520 ###############################################################
522 sub clean_output_tree
524 installer::logger::print_message( "... cleaning the output tree ...\n" );
526 for ( my $i = 0; $i <= $#installer::globals::removedirs; $i++ )
528 if ( -d $installer::globals::removedirs[$i] )
530 installer::logger::print_message( "... removing directory $installer::globals::removedirs[$i] ...\n" );
531 installer::systemactions::remove_complete_directory($installer::globals::removedirs[$i], 1);
535 # Last try to remove the ship test directory
537 if ( $installer::globals::shiptestdirectory )
539 if ( -d $installer::globals::shiptestdirectory )
541 my $infoline = "Last try to remove $installer::globals::shiptestdirectory . \n";
542 push(@installer::globals::logfileinfo, $infoline);
543 my $systemcall = "rmdir $installer::globals::shiptestdirectory";
544 my $returnvalue = system($systemcall);
549 ###############################################################
550 # Removing all directories that are saved in the
551 # global directory @installer::globals::jdsremovedirs
552 ###############################################################
554 sub clean_jds_temp_dirs
556 installer::logger::print_message( "... cleaning jds directories ...\n" );
558 for ( my $i = 0; $i <= $#installer::globals::jdsremovedirs; $i++ )
560 if ( -d $installer::globals::jdsremovedirs[$i] )
562 installer::logger::print_message( "... removing directory $installer::globals::jdsremovedirs[$i] ...\n" );
563 installer::systemactions::remove_complete_directory($installer::globals::jdsremovedirs[$i], 1);
568 ###########################################################
569 # Copying a reference array
570 ###########################################################
572 sub copy_array_from_references
574 my ( $arrayref ) = @_;
576 my @newarray = ();
578 for ( my $i = 0; $i <= $#{$arrayref}; $i++ )
580 push(@newarray, ${$arrayref}[$i]);
583 return \@newarray;
586 ###########################################################
587 # Copying a reference hash
588 ###########################################################
590 sub copy_hash_from_references
592 my ($hashref) = @_;
594 my %newhash = ();
595 my $key;
597 foreach $key (keys %{$hashref})
599 $newhash{$key} = $hashref->{$key};
602 return \%newhash;
605 ###########################################################
606 # Setting one language in the language independent
607 # array of include pathes with $(LANG)
608 ###########################################################
610 sub get_language_specific_include_pathes
612 my ( $patharrayref, $onelanguage ) = @_;
614 my @patharray = ();
616 for ( my $i = 0; $i <= $#{$patharrayref}; $i++ )
618 my $line = ${$patharrayref}[$i];
619 $line =~ s/\$\(LANG\)/$onelanguage/g;
620 push(@patharray ,$line);
623 return \@patharray;
626 ##############################################################
627 # Returning the first item with a defined flag
628 ##############################################################
630 sub return_first_item_with_special_flag
632 my ($itemsref, $flag) = @_;
634 my $firstitem = "";
636 for ( my $i = 0; $i <= $#{$itemsref}; $i++ )
638 my $oneitem = ${$itemsref}[$i];
639 my $styles = "";
640 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'} };
642 if ( $styles =~ /\b$flag\b/ )
644 $firstitem = $oneitem;
645 last;
649 return $firstitem;
652 ##############################################################
653 # Collecting all items with a defined flag
654 ##############################################################
656 sub collect_all_items_with_special_flag
658 my ($itemsref, $flag) = @_;
660 my @allitems = ();
662 for ( my $i = 0; $i <= $#{$itemsref}; $i++ )
664 my $oneitem = ${$itemsref}[$i];
665 my $styles = "";
666 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'} };
668 if ( $styles =~ /\b$flag\b/ )
670 push( @allitems, $oneitem );
674 return \@allitems;
677 ##############################################################
678 # Collecting all files without patch flag in
679 # $installer::globals::nopatchfilecollector
680 ##############################################################
682 sub collect_all_files_without_patch_flag
684 my ($filesref) = @_;
686 my $newfiles = collect_all_items_without_special_flag($filesref, "PATCH");
688 for ( my $i = 0; $i <= $#{$newfiles}; $i++ ) { push(@{$installer::globals::nopatchfilecollector}, ${$newfiles}[$i]); }
691 ##############################################################
692 # Collecting all items without a defined flag
693 ##############################################################
695 sub collect_all_items_without_special_flag
697 my ($itemsref, $flag) = @_;
699 my @allitems = ();
701 for ( my $i = 0; $i <= $#{$itemsref}; $i++ )
703 my $oneitem = ${$itemsref}[$i];
704 my $styles = "";
705 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'} };
707 if ( !( $styles =~ /\b$flag\b/ ))
709 push( @allitems, $oneitem );
713 return \@allitems;
716 ##############################################################
717 # Removing all items with a defined flag from collector
718 ##############################################################
720 sub remove_all_items_with_special_flag
722 my ($itemsref, $flag) = @_;
724 my @allitems = ();
726 for ( my $i = 0; $i <= $#{$itemsref}; $i++ )
728 my $oneitem = ${$itemsref}[$i];
729 my $styles = "";
730 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'} };
731 if ( $styles =~ /\b$flag\b/ )
733 my $infoline = "Attention: Removing from collector: $oneitem->{'Name'} !\n";
734 push( @installer::globals::logfileinfo, $infoline);
735 if ( $flag eq "BINARYTABLE_ONLY" ) { push(@installer::globals::binarytableonlyfiles, $oneitem); }
736 next;
738 push( @allitems, $oneitem );
741 return \@allitems;
744 ###########################################################
745 # Mechanism for simple installation without packing
746 ###########################################################
748 sub install_simple ($$$$$$)
750 my ($packagename, $languagestring, $directoriesarray, $filesarray, $linksarray, $unixlinksarray) = @_;
752 # locate GNU cp on the system
753 my $gnucp = 'cp';
754 if ( $ENV{'GNUCOPY'} ) { $gnucp = $ENV{'GNUCOPY'}; }
755 my $copyopts = '-af';
756 $copyopts = '-PpRf' unless ( $ENV{'GNUCOPY'} ); # if not gnucopy, assume POSIX copy
758 installer::logger::print_message( "... installing module $packagename ...\n" );
760 my $destdir = $installer::globals::destdir;
761 my @lines = ();
763 installer::logger::print_message( "DestDir: $destdir \n" );
764 installer::logger::print_message( "Rootpath: $installer::globals::rootpath \n" );
766 `mkdir -p $destdir` if $destdir ne "";
767 `mkdir -p $destdir$installer::globals::rootpath`;
769 # Create Directories
770 for ( my $i = 0; $i <= $#{$directoriesarray}; $i++ )
772 my $onedir = ${$directoriesarray}[$i];
773 my $dir = "";
775 if ( $onedir->{'Dir'} ) { $dir = $onedir->{'Dir'}; }
777 if ((!($dir =~ /\bPREDEFINED_/ )) || ( $dir =~ /\bPREDEFINED_PROGDIR\b/ ))
779 my $hostname = $onedir->{'HostName'};
781 # ignore '.' subdirectories
782 next if ( $hostname =~ m/\.$/ );
783 # remove './' from the path
784 $hostname =~ s/\.\///g;
786 # printf "mkdir $destdir$hostname\n";
787 mkdir $destdir . $hostname;
788 push @lines, "%dir " . $hostname . "\n";
792 for ( my $i = 0; $i <= $#{$filesarray}; $i++ )
794 my $onefile = ${$filesarray}[$i];
795 my $unixrights = $onefile->{'UnixRights'};
796 my $destination = $onefile->{'destination'};
797 my $sourcepath = $onefile->{'sourcepath'};
799 # This is necessary to install SDK that includes files with $ in its name
800 # Otherwise, the following shell commands does not work and the file list
801 # is not correct
802 $destination =~ s/\$\$/\$/;
803 $sourcepath =~ s/\$\$/\$/;
805 # remove './' from the path
806 $sourcepath =~ s/\.\///g;
807 $destination =~ s/\.\///g;
809 push @lines, "$destination\n";
810 # printf "cp $sourcepath $destdir$destination\n";
811 copy ("$sourcepath", "$destdir$destination") || die "Can't copy file: $sourcepath -> $destdir$destination $!";
812 my $sourcestat = stat($sourcepath);
813 utime ($sourcestat->atime, $sourcestat->mtime, "$destdir$destination");
814 chmod (oct($unixrights), "$destdir$destination") || die "Can't change permissions: $!";
815 push @lines, "$destination\n";
818 for ( my $i = 0; $i <= $#{$linksarray}; $i++ )
820 my $onelink = ${$linksarray}[$i];
821 my $destination = $onelink->{'destination'};
822 my $destinationfile = $onelink->{'destinationfile'};
824 # print "link $destinationfile -> $destdir$destination\n";
825 symlink ("$destinationfile", "$destdir$destination") || die "Can't create symlink: $!";
826 push @lines, "$destination\n";
829 for ( my $i = 0; $i <= $#{$unixlinksarray}; $i++ )
831 my $onelink = ${$unixlinksarray}[$i];
832 my $target = $onelink->{'Target'};
833 my $destination = $onelink->{'destination'};
835 # print "Unix link $target -> $destdir$destination\n";
836 `ln -sf '$target' '$destdir$destination'`;
837 push @lines, "$destination\n";
840 if ( $destdir ne "" )
842 my $filelist;
843 my $fname = $installer::globals::destdir . "/$packagename";
844 open ($filelist, ">$fname") || die "Can't open $fname: $!";
845 print $filelist @lines;
846 close ($filelist);
851 ###########################################################
852 # Adding shellnew files into files collector for
853 # user installation
854 ###########################################################
856 sub add_shellnewfile_into_filesarray
858 my ($filesref, $onefile, $inffile) = @_;
860 my %shellnewfile = ();
861 my $shellnewfileref = \%shellnewfile;
863 installer::converter::copy_item_object($inffile, $shellnewfileref);
865 $shellnewfileref->{'Name'} = $onefile->{'Name'};
866 $shellnewfileref->{'sourcepath'} = $onefile->{'sourcepath'};
867 $shellnewfileref->{'gid'} = $onefile->{'gid'} . "_Userinstall";
869 # the destination has to be adapted
870 my $destination = $inffile->{'destination'};
871 installer::pathanalyzer::get_path_from_fullqualifiedname(\$destination);
872 $destination = $destination . $onefile->{'Name'};
873 $shellnewfileref->{'destination'} = $destination;
875 # add language specific inffile into filesarray
876 push(@{$filesref}, $shellnewfileref);
879 ###########################################################
880 # Replacing one placehoder in template file
881 ###########################################################
883 sub replace_in_template_file
885 my ($templatefile, $placeholder, $newstring) = @_;
887 for ( my $i = 0; $i <= $#{$templatefile}; $i++ )
889 ${$templatefile}[$i] =~ s/\Q$placeholder\E/$newstring/g;
893 ###########################################################
894 # Replacing one placehoder with an array in template file
895 ###########################################################
897 sub replace_array_in_template_file
899 my ($templatefile, $placeholder, $arrayref) = @_;
901 for ( my $i = 0; $i <= $#{$templatefile}; $i++ )
903 if ( ${$templatefile}[$i] =~ /\Q$placeholder\E/ )
905 my @return = splice(@{$templatefile}, $i, 1, @{$arrayref});
910 ###########################################################
911 # Collecting all modules from registry items
912 ###########################################################
914 sub collect_all_modules
916 my ($registryitemsref) = @_;
918 my @allmodules = ();
920 for ( my $i = 0; $i <= $#{$registryitemsref}; $i++ )
922 $registryitem = ${$registryitemsref}[$i];
923 my $module = $registryitem->{'ModuleID'};
925 if ( ! installer::existence::exists_in_array($module, \@allmodules) )
927 push(@allmodules, $module);
931 return \@allmodules;
934 ###########################################################
935 # Changing the content of the inf file
936 ###########################################################
938 sub write_content_into_inf_file
940 my ($templatefile, $filesref, $registryitemsref, $folderref, $folderitemsref, $modulesref, $onelanguage, $inffile, $firstlanguage, $allvariableshashref) = @_;
942 # First part: Shellnew files
943 # SHELLNEWFILESPLACEHOLDER
945 my $rootmodule = 0;
946 # inf files can be assigned to "gid_Module_Root_Files_2"
947 if ( $inffile->{'modules'} =~ /Module_Root/i ) { $rootmodule = 1; }
949 if ( $rootmodule )
951 my $shellnewstring = "";
953 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
955 my $onefile = ${$filesref}[$i];
956 my $directory = $onefile->{'Dir'};
958 if ( $directory =~ /\bPREDEFINED_OSSHELLNEWDIR\b/ )
960 $shellnewstring = $shellnewstring . $onefile->{'Name'} . "\n";
961 if (( $firstlanguage ) && ( ! $installer::globals::shellnewfilesadded )) { add_shellnewfile_into_filesarray($filesref, $onefile, $inffile); }
965 $shellnewstring =~ s/\s*$//;
966 replace_in_template_file($templatefile, "SHELLNEWFILESPLACEHOLDER", $shellnewstring);
968 $installer::globals::shellnewfilesadded = 1;
971 # Second part: Start menu entries
973 # The OfficeMenuFolder is defined as: $productname . " " . $productversion;
975 my $productname = $allvariableshashref->{'PRODUCTNAME'};
976 my $productversion = $allvariableshashref->{'PRODUCTVERSION'};
977 my $productkey = $productname . " " . $productversion;
979 replace_in_template_file($templatefile, "OFFICEFOLDERPLACEHOLDER", $productkey);
981 # Setting name target and infotip for all applications
983 for ( my $i = 0; $i <= $#{$folderitemsref}; $i++ )
985 my $folderitem = ${$folderitemsref}[$i];
987 my $styles = "";
988 if ( $folderitem->{'Styles'} ) { $styles = $folderitem->{'Styles'}; }
989 if ( $styles =~ /\bNON_ADVERTISED\b/ ) { next; } # no entry for non-advertised shortcuts
991 if (( ! $folderitem->{'ismultilingual'} ) || (( $folderitem->{'ismultilingual'} ) && ( $folderitem->{'specificlanguage'} eq $onelanguage )))
993 my $gid = $folderitem->{'gid'};
994 my $app = $gid;
995 $app =~ s/gid_Folderitem_//;
996 $app = uc($app);
998 my $name = $folderitem->{'Name'};
999 my $placeholder = "PLACEHOLDER_FOLDERITEM_NAME_" . $app;
1000 replace_in_template_file($templatefile, $placeholder, $name);
1002 my $tooltip = $folderitem->{'Tooltip'};
1003 $placeholder = "PLACEHOLDER_FOLDERITEM_TOOLTIP_" . $app;
1004 replace_in_template_file($templatefile, $placeholder, $tooltip);
1006 my $executablegid = $folderitem->{'FileID'};
1007 my $exefile = installer::existence::get_specified_file($filesref, $executablegid);
1008 my $exefilename = $exefile->{'Name'};
1009 $placeholder = "PLACEHOLDER_FOLDERITEM_TARGET_" . $app;
1010 replace_in_template_file($templatefile, $placeholder, $exefilename);
1014 # Third part: Windows registry entries
1016 # collecting all modules
1018 my $allmodules = collect_all_modules($registryitemsref);
1020 my @registryitems = ();
1021 my $allsectionsstring = "";
1023 for ( my $j = 0; $j <= $#{$allmodules}; $j++ )
1025 my $moduleid = ${$allmodules}[$j];
1027 my $inffilemodule = $inffile->{'modules'};
1028 # inf files can be assigned to "gid_Module_Root_Files_2", but RegistryItems to "gid_Module_Root"
1029 if ( $inffilemodule =~ /Module_Root/i ) { $inffilemodule = $installer::globals::rootmodulegid; }
1031 if ( ! ( $moduleid eq $inffilemodule )) { next; }
1033 my $shortmodulename = $moduleid;
1034 $shortmodulename =~ s/gid_Module_//;
1035 my $sectionname = "InstRegKeys." . $shortmodulename;
1036 $allsectionsstring = $allsectionsstring . $sectionname . ",";
1037 my $sectionheader = "\[" . $sectionname . "\]" . "\n";
1038 push(@registryitems, $sectionheader);
1040 for ( my $i = 0; $i <= $#{$registryitemsref}; $i++ )
1042 my $registryitem = ${$registryitemsref}[$i];
1044 if ( ! ( $registryitem->{'ModuleID'} eq $moduleid )) { next; }
1046 if (( ! $registryitem->{'ismultilingual'} ) || (( $registryitem->{'ismultilingual'} ) && ( $registryitem->{'specificlanguage'} eq $onelanguage )))
1048 # Syntax: HKCR,".bau",,,"soffice.StarConfigFile.6"
1050 my $regroot = "";
1051 my $parentid = "";
1052 if ( $registryitem->{'ParentID'} ) { $parentid = $registryitem->{'ParentID'}; }
1053 if ( $parentid eq "PREDEFINED_HKEY_CLASSES_ROOT" ) { $regroot = "HKCR"; }
1054 if ( $parentid eq "PREDEFINED_HKEY_LOCAL_MACHINE" ) { $regroot = "HKCU"; }
1056 my $subkey = "";
1057 if ( $registryitem->{'Subkey'} ) { $subkey = $registryitem->{'Subkey'}; }
1058 if ( $subkey ne "" ) { $subkey = "\"" . $subkey . "\""; }
1060 my $valueentryname = "";
1061 if ( $registryitem->{'Name'} ) { $valueentryname = $registryitem->{'Name'}; }
1062 if ( $valueentryname ne "" ) { $valueentryname = "\"" . $valueentryname . "\""; }
1064 my $flag = "";
1066 my $value = "";
1067 if ( $registryitem->{'Value'} ) { $value = $registryitem->{'Value'}; }
1068 if ( $value =~ /\<progpath\>/ ) { $value =~ s/\\\"/\"\"/g; } # Quoting for INF is done by double ""
1069 $value =~ s/\\\"/\"/g; # no more masquerading of '"'
1070 $value =~ s/\<progpath\>/\%OFFICEINSTALLLOCATION\%/g;
1071 # $value =~ s/\%OFFICEINSTALLLOCATION\%\\/\%OFFICEINSTALLLOCATION\%/g; # removing "\" after "%OFFICEINSTALLLOCATION%"
1072 if ( $value ne "" ) { $value = "\"" . $value . "\""; }
1074 my $oneline = $regroot . "," . $subkey . "," . $valueentryname . "," . $flag . "," . $value . "\n";
1076 push(@registryitems, $oneline);
1080 push(@registryitems, "\n"); # empty line after each section
1083 # replacing the $allsectionsstring
1084 $allsectionsstring =~ s/\,\s*$//;
1085 replace_in_template_file($templatefile, "ALLREGISTRYSECTIONSPLACEHOLDER", $allsectionsstring);
1087 # replacing the placeholder for all registry keys
1088 replace_array_in_template_file($templatefile, "REGISTRYKEYSPLACEHOLDER", \@registryitems);
1092 ###########################################################
1093 # Creating inf files for local user system integration
1094 ###########################################################
1096 sub create_inf_file
1098 my ($filesref, $registryitemsref, $folderref, $folderitemsref, $modulesref, $languagesarrayref, $languagestringref, $allvariableshashref) = @_;
1100 # collecting all files with flag INFFILE
1102 my $inf_files = collect_all_items_with_special_flag($filesref ,"INFFILE");
1104 if ( $#{$inf_files} > -1 )
1106 # create new language specific inffile
1107 installer::logger::include_header_into_logfile("Creating inf files:");
1109 my $infdirname = "inffiles";
1110 my $infdir = installer::systemactions::create_directories($infdirname, $languagestringref);
1112 my $infoline = "Number of inf files: $#{$inf_files} + 1 \n";
1113 push( @installer::globals::logfileinfo, $infoline);
1115 # there are inffiles for all modules
1117 for ( my $i = 0; $i <= $#{$inf_files}; $i++ )
1119 my $inffile = ${$inf_files}[$i];
1120 my $inf_file_name = $inffile->{'Name'};
1122 my $templatefilename = $inffile->{'sourcepath'};
1124 if ( ! -f $templatefilename ) { installer::exiter::exit_program("ERROR: Could not find file $templatefilename !", "create_inf_file"); }
1126 # iterating over all languages
1128 for ( my $j = 0; $j <= $#{$languagesarrayref}; $j++ ) # iterating over all languages
1130 my $firstlanguage = 0;
1131 if ( $j == 0 ) { $firstlanguage = 1; }
1133 my $onelanguage = ${$languagesarrayref}[$j];
1135 $infoline = "Templatefile: $inf_file_name, Language: $onelanguage \n";
1136 push( @installer::globals::logfileinfo, $infoline);
1138 my $templatefile = installer::files::read_file($templatefilename);
1140 my $linesbefore = $#{$templatefile};
1142 write_content_into_inf_file($templatefile, $filesref, $registryitemsref, $folderref, $folderitemsref, $modulesref, $onelanguage, $inffile, $firstlanguage, $allvariableshashref);
1144 $infoline = "Lines change: From $linesbefore to $#{$templatefile}.\n";
1145 push( @installer::globals::logfileinfo, $infoline);
1147 # rename language specific inffile
1148 my $language_inf_file_name = $inf_file_name;
1149 my $windowslanguage = installer::windows::language::get_windows_language($onelanguage);
1150 $language_inf_file_name =~ s/\.inf/_$windowslanguage\.inf/;
1152 my $sourcepath = $infdir . $installer::globals::separator . $language_inf_file_name;
1153 installer::files::save_file($sourcepath, $templatefile);
1155 $infoline = "Saving file: $sourcepath\n";
1156 push( @installer::globals::logfileinfo, $infoline);
1158 # creating new file object
1160 my %languageinffile = ();
1161 my $languageinifileref = \%languageinffile;
1163 if ( $j < $#{$languagesarrayref} ) { installer::converter::copy_item_object($inffile, $languageinifileref); }
1164 else { $languageinifileref = $inffile; }
1166 $languageinifileref->{'Name'} = $language_inf_file_name;
1167 $languageinifileref->{'sourcepath'} = $sourcepath;
1168 # destination and gid also have to be adapted
1169 $languageinifileref->{'gid'} = $languageinifileref->{'gid'} . "_" . $onelanguage;
1170 my $destination = $languageinifileref->{'destination'};
1171 installer::pathanalyzer::get_path_from_fullqualifiedname(\$destination);
1172 $destination = $destination . $language_inf_file_name;
1173 $languageinifileref->{'destination'} = $destination;
1175 # add language specific inffile into filesarray
1176 if ( $j < $#{$languagesarrayref} ) { push(@{$filesref}, $languageinifileref); }
1182 ###########################################################
1183 # Selecting patch items
1184 ###########################################################
1186 sub select_patch_items
1188 my ( $itemsref, $itemname ) = @_;
1190 installer::logger::include_header_into_logfile("Selecting items for patches. Item: $itemname");
1192 my @itemsarray = ();
1194 for ( my $i = 0; $i <= $#{$itemsref}; $i++ )
1196 my $oneitem = ${$itemsref}[$i];
1198 my $name = $oneitem->{'Name'};
1199 if (( $name =~ /\bLICENSE/ ) || ( $name =~ /\bREADME/ ))
1201 push(@itemsarray, $oneitem);
1202 next;
1205 # Items with style "PATCH" have to be included into the patch
1206 my $styles = "";
1207 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; }
1208 if ( $styles =~ /\bPATCH\b/ ) { push(@itemsarray, $oneitem); }
1211 return \@itemsarray;
1214 ###########################################################
1215 # Selecting patch items
1216 ###########################################################
1218 sub select_patch_items_without_name
1220 my ( $itemsref, $itemname ) = @_;
1222 installer::logger::include_header_into_logfile("Selecting RegistryItems for patches");
1224 my @itemsarray = ();
1226 for ( my $i = 0; $i <= $#{$itemsref}; $i++ )
1228 my $oneitem = ${$itemsref}[$i];
1230 # Items with style "PATCH" have to be included into the patch
1231 my $styles = "";
1232 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; }
1233 if ( $styles =~ /\bPATCH\b/ ) { push(@itemsarray, $oneitem); }
1236 return \@itemsarray;
1239 ###########################################################
1240 # Selecting patch items
1241 ###########################################################
1243 sub select_langpack_items
1245 my ( $itemsref, $itemname ) = @_;
1247 installer::logger::include_header_into_logfile("Selecting RegistryItems for Language Packs");
1249 my @itemsarray = ();
1251 for ( my $i = 0; $i <= $#{$itemsref}; $i++ )
1253 my $oneitem = ${$itemsref}[$i];
1255 # Items with style "LANGUAGEPACK" have to be included into the patch
1256 my $styles = "";
1257 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; }
1258 if (( $styles =~ /\bLANGUAGEPACK\b/ ) || ( $styles =~ /\bFORCELANGUAGEPACK\b/ )) { push(@itemsarray, $oneitem); }
1261 return \@itemsarray;
1264 ###########################################################
1265 # Searching if LICENSE and README, which are not removed
1266 # in select_patch_items are really needed for the patch.
1267 # If not, they are removed now.
1268 ###########################################################
1270 sub analyze_patch_files
1272 my ( $filesref ) = @_;
1274 installer::logger::include_header_into_logfile("Analyzing patch files");
1276 my @filesarray = ();
1278 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
1280 my $onefile = ${$filesref}[$i];
1281 my $styles = "";
1282 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; }
1283 if ( !( $styles =~ /\bPATCH\b/) ) { next; } # removing all files without flag PATCH (LICENSE, README, ...)
1285 if ( $installer::globals::iswindowsbuild )
1287 # all files of the Windows patch belong to the root module
1288 $onefile->{'modules'} = $installer::globals::rootmodulegid;
1291 push(@filesarray, $onefile);
1294 return \@filesarray;
1297 ###########################################################
1298 # Sorting an array
1299 ###########################################################
1301 sub sort_array
1303 my ( $arrayref ) = @_;
1305 for ( my $i = 0; $i <= $#{$arrayref}; $i++ )
1307 my $under = ${$arrayref}[$i];
1309 for ( my $j = $i + 1; $j <= $#{$arrayref}; $j++ )
1311 my $over = ${$arrayref}[$j];
1313 if ( $under gt $over)
1315 ${$arrayref}[$i] = $over;
1316 ${$arrayref}[$j] = $under;
1317 $under = $over;
1323 ###########################################################
1324 # Renaming linux files with flag LINUXLINK
1325 ###########################################################
1327 sub prepare_linuxlinkfiles
1329 my ( $filesref ) = @_;
1331 @installer::globals::linuxlinks = (); # empty this array, because it could be already used
1332 @installer::globals::linuxpatchfiles = (); # empty this array, because it could be already used
1333 @installer::globals::allfilessav = (); # empty this array, because it could be already used. Required for forced links
1335 my @filesarray = ();
1337 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
1339 my $onefile = ${$filesref}[$i];
1340 my %linkfilehash = ();
1341 my $linkfile = \%linkfilehash;
1342 installer::converter::copy_item_object($onefile, $linkfile);
1344 my $ispatchfile = 0;
1345 my $styles = "";
1346 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; }
1347 if ( $styles =~ /\bPATCH\b/ ) { $ispatchfile = 1; }
1349 # Collecting all files for the mechanism with forced links
1350 # Saving a copy
1351 my %copyfilehash = ();
1352 my $copyfile = \%copyfilehash;
1353 installer::converter::copy_item_object($onefile, $copyfile);
1354 push( @installer::globals::allfilessav, $copyfile);
1356 my $original_destination = $onefile->{'destination'};
1357 # $onefile->{'destination'} is used in the epm list file. This value can be changed now!
1359 if ( $ispatchfile ) { $onefile->{'destination'} = $onefile->{'destination'} . "\.$installer::globals::linuxlibrarypatchlevel"; }
1360 else { $onefile->{'destination'} = $onefile->{'destination'} . "\.$installer::globals::linuxlibrarybaselevel"; }
1362 my $infoline = "LINUXLINK: Changing file destination from $original_destination to $onefile->{'destination'} !\n";
1363 push( @installer::globals::logfileinfo, $infoline);
1365 # all files without PATCH flag are included into the RPM
1366 if ( ! $ispatchfile ) { push( @filesarray, $onefile); }
1367 else { push( @installer::globals::linuxpatchfiles, $onefile); }
1369 # Preparing the collector for the links
1370 # Setting the new file name as destination of the link
1371 my $linkdestination = $linkfile->{'Name'};
1372 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$linkdestination);
1373 if ( $ispatchfile ) { $linkfile->{'destinationfile'} = $linkdestination . "\.$installer::globals::linuxlibrarypatchlevel"; }
1374 else { $linkfile->{'destinationfile'} = $linkdestination . "\.$installer::globals::linuxlibrarybaselevel"; }
1375 push( @installer::globals::linuxlinks, $linkfile );
1377 $infoline = "LINUXLINK: Created link: $linkfile->{'destination'} pointing to $linkfile->{'destinationfile'} !\n";
1378 push( @installer::globals::logfileinfo, $infoline);
1381 return \@filesarray;
1384 ###########################################################
1385 # Adding links into "u-RPMs", that have the flag
1386 # FORCE_INTO_UPDATE_PACKAGE
1387 # This is only relevant for Linux
1388 ###########################################################
1390 sub prepare_forced_linuxlinkfiles
1392 my ( $linksref ) = @_;
1394 my @linksarray = ();
1396 for ( my $i = 0; $i <= $#{$linksref}; $i++ )
1398 my $onelink = ${$linksref}[$i];
1400 my $isforcedlink = 0;
1401 my $styles = "";
1402 if ( $onelink->{'Styles'} ) { $styles = $onelink->{'Styles'}; }
1403 if ( $styles =~ /\bFORCE_INTO_UPDATE_PACKAGE\b/ ) { $isforcedlink = 1; }
1405 if ( $isforcedlink )
1407 my $fileid = "";
1409 if ( $onelink->{'ShortcutID'} )
1411 $fileid = $onelink->{'ShortcutID'};
1413 my $searchedlinkfile = find_file_by_id($linksref, $fileid);
1415 # making a copy!
1416 my %linkfilehash = ();
1417 my $linkfile = \%linkfilehash;
1418 installer::converter::copy_item_object($searchedlinkfile, $linkfile);
1420 $linkfile->{'Name'} = $onelink->{'Name'};
1421 $linkfile->{'destinationfile'} = $linkfile->{'destination'};
1422 my $linkdestination = $linkfile->{'destinationfile'};
1423 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$linkdestination);
1424 $linkfile->{'destinationfile'} = $linkdestination;
1426 my $localdestination = $linkfile->{'destination'};
1427 # Getting the path
1428 installer::pathanalyzer::get_path_from_fullqualifiedname(\$localdestination);
1429 $localdestination =~ s/\Q$installer::globals::separator\E\s*$//;
1430 $linkfile->{'destination'} = $localdestination . $installer::globals::separator . $onelink->{'Name'};
1432 $infoline = "Forced link into update file: $linkfile->{'destination'} pointing to $linkfile->{'destinationfile'} !\n";
1433 push( @installer::globals::logfileinfo, $infoline);
1435 # The file, defined by the link, has to be included into the
1436 # link array @installer::globals::linuxlinks
1437 push( @installer::globals::linuxlinks, $linkfile );
1440 if ( $onelink->{'FileID'} )
1442 $fileid = $onelink->{'FileID'};
1444 my $searchedlinkfile = find_file_by_id(\@installer::globals::allfilessav, $fileid);
1446 # making a copy!
1447 my %linkfilehash = ();
1448 my $linkfile = \%linkfilehash;
1449 installer::converter::copy_item_object($searchedlinkfile, $linkfile);
1451 $linkfile->{'Name'} = $onelink->{'Name'};
1452 $linkfile->{'destinationfile'} = $linkfile->{'destination'};
1453 my $linkdestination = $linkfile->{'destinationfile'};
1454 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$linkdestination);
1455 $linkfile->{'destinationfile'} = $linkdestination;
1457 my $localdestination = $linkfile->{'destination'};
1458 # Getting the path
1459 installer::pathanalyzer::get_path_from_fullqualifiedname(\$localdestination);
1460 $localdestination =~ s/\Q$installer::globals::separator\E\s*$//;
1461 $linkfile->{'destination'} = $localdestination . $installer::globals::separator . $onelink->{'Name'};
1463 $infoline = "Forced link into update file: $linkfile->{'destination'} pointing to $linkfile->{'destinationfile'} !\n";
1464 push( @installer::globals::logfileinfo, $infoline);
1466 # The file, defined by the link, has to be included into the
1467 # link array @installer::globals::linuxlinks
1468 push( @installer::globals::linuxlinks, $linkfile );
1471 if ( $fileid eq "" ) { installer::exiter::exit_program("ERROR: No FileID assigned to forced link $onelink->{'gid'} !", "prepare_forced_linuxlinkfiles"); }
1474 else
1476 # Links with flag FORCE_INTO_UPDATE_PACKAGE are forced into "u"-RPM. All other
1477 # links are included into the non-"u"-package.
1478 push( @linksarray, $onelink );
1482 return \@linksarray;
1485 ###########################################################
1486 # reorganizing the patchfile content,
1487 # sorting for directory to decrease the file size
1488 ###########################################################
1490 sub reorg_patchfile
1492 my ($patchfiles, $patchfiledirectories) = @_;
1494 my @patchfilesarray = ();
1495 my $line = "";
1496 my $directory = "";
1498 # iterating over all directories, writing content into new patchfiles list
1500 for ( my $i = 0; $i <= $#{$patchfiledirectories}; $i++ )
1502 $directory = ${$patchfiledirectories}[$i];
1503 $line = "[" . $directory . "]" . "\n";
1504 push(@patchfilesarray, $line);
1506 for ( my $j = 0; $j <= $#{$patchfiles}; $j++ )
1508 # "\tXXXXX\t" . $olddestination . "\n";
1509 if ( ${$patchfiles}[$j] =~ /^\s*(.*?)\s*\tXXXXX\t\Q$directory\E\s*$/ )
1511 $line = $1 . "\n";
1512 push(@patchfilesarray, $line);
1517 return \@patchfilesarray;
1520 ###########################################################
1521 # One special file has to be the last in patchfile.txt.
1522 # Controlling this file, guarantees, that all files were
1523 # patch correctly. Using version.ini makes it easy to
1524 # control this by looking into the about box
1525 # -> shifting one section to the end
1526 ###########################################################
1528 sub shift_section_to_end
1530 my ($patchfilelist) = @_;
1532 my @patchfile = ();
1533 my @lastsection = ();
1534 my $lastsection = "program";
1535 my $notlastsection = "Basis\\program";
1536 my $record = 0;
1538 for ( my $i = 0; $i <= $#{$patchfilelist}; $i++ )
1540 my $line = ${$patchfilelist}[$i];
1542 if (( $record ) && ( $line =~ /^\s*\[/ )) { $record = 0; }
1544 if (( $line =~ /^\s*\[\Q$lastsection\E\\\]\s*$/ ) && ( ! ( $line =~ /\Q$notlastsection\E\\\]\s*$/ ))) { $record = 1; }
1546 if ( $record ) { push(@lastsection, $line); }
1547 else { push(@patchfile, $line); }
1550 if ( $#lastsection > -1 )
1552 for ( my $i = 0; $i <= $#lastsection; $i++ )
1554 push(@patchfile, $lastsection[$i]);
1558 return \@patchfile;
1561 ###########################################################
1562 # One special file has to be the last in patchfile.txt.
1563 # Controlling this file, guarantees, that all files were
1564 # patch correctly. Using version.ini makes it easy to
1565 # control this by looking into the about box
1566 # -> shifting one file of the last section to the end
1567 ###########################################################
1569 sub shift_file_to_end
1571 my ($patchfilelist) = @_;
1573 my @patchfile = ();
1574 my $lastfilename = "version.ini";
1575 my $lastfileline = "";
1576 my $foundfile = 0;
1578 # Only searching this file in the last section
1579 my $lastsectionname = "";
1581 for ( my $i = 0; $i <= $#{$patchfilelist}; $i++ )
1583 my $line = ${$patchfilelist}[$i];
1584 if ( $line =~ /^\s*\[(.*?)\]\s*$/ ) { $lastsectionname = $1; }
1587 my $record = 0;
1588 for ( my $i = 0; $i <= $#{$patchfilelist}; $i++ )
1590 my $line = ${$patchfilelist}[$i];
1592 if ( $line =~ /^\s*\[\Q$lastsectionname\E\]\s*$/ ) { $record = 1; }
1594 if (( $line =~ /^\s*\"\Q$lastfilename\E\"\=/ ) && ( $record ))
1596 $lastfileline = $line;
1597 $foundfile = 1;
1598 $record = 0;
1599 next;
1602 push(@patchfile, $line);
1605 if ( $foundfile ) { push(@patchfile, $lastfileline); }
1607 return \@patchfile;
1610 ###########################################################
1611 # Putting hash content into array and sorting it
1612 ###########################################################
1614 sub sort_hash
1616 my ( $hashref ) = @_;
1618 my $item = "";
1619 my @sortedarray = ();
1621 foreach $item (keys %{$hashref}) { push(@sortedarray, $item); }
1622 installer::sorter::sorting_array_of_strings(\@sortedarray);
1624 return \@sortedarray;
1627 ###########################################################
1628 # Renaming Windows files in Patch and creating file
1629 # patchfiles.txt
1630 ###########################################################
1632 sub prepare_windows_patchfiles
1634 my ( $filesref, $languagestringref, $allvariableshashref ) = @_;
1636 my @patchfiles = ();
1637 my %patchfiledirectories = ();
1638 my $patchfilename = "patchlist.txt";
1639 my $patchfilename2 = "patchmsi.dll";
1641 if ( ! $allvariableshashref->{'WINDOWSPATCHLEVEL'} ) { installer::exiter::exit_program("ERROR: No Windows patch level defined in list file (WINDOWSPATCHLEVEL) !", "prepare_windows_patchfiles"); }
1642 # my $windowspatchlevel = $allvariableshashref->{'WINDOWSPATCHLEVEL'};
1643 my $windowspatchlevel = $installer::globals::buildid;
1645 # the environment variable CWS_WORK_STAMP is set only in CWS
1646 if ( $ENV{'CWS_WORK_STAMP'} ) { $windowspatchlevel = $ENV{'CWS_WORK_STAMP'} . $windowspatchlevel; }
1648 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
1650 my $onefile = ${$filesref}[$i];
1652 my $filename = $onefile->{'Name'};
1653 if (( $filename eq $patchfilename ) || ( $filename eq $patchfilename2 )) { next; }
1655 my $styles = "";
1656 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; }
1657 if ( $styles =~ /\bDONTRENAMEINPATCH\b/ ) { next; }
1659 # special handling for files with flag DONTSHOW. This files get the extension ".dontshow" to be filtered by dialogs.
1660 my $localwindowspatchlevel = $windowspatchlevel;
1661 if ( $styles =~ /\bDONTSHOW\b/ ) { $localwindowspatchlevel = $localwindowspatchlevel . "\.dontshow"; }
1663 my $olddestination = $onefile->{'destination'};
1664 my $newdestination = $olddestination . "." . $localwindowspatchlevel;
1665 my $localfilename = $olddestination;
1666 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$localfilename); # file name part
1667 my $line = "\"" . $localfilename . "\"" . "=" . "\"" . "\." . $localwindowspatchlevel . "\"";
1668 $onefile->{'destination'} = $newdestination;
1670 my $newfilename = $onefile->{'Name'} . "." . $localwindowspatchlevel;
1671 $onefile->{'Name'} = $newfilename;
1673 # adding section information (section is the directory)
1674 my $origolddestination = $olddestination;
1675 installer::pathanalyzer::get_path_from_fullqualifiedname(\$olddestination); # directory part
1676 if ( ! $olddestination ) { $olddestination = "_root"; }
1677 if ( ! exists($patchfiledirectories{$olddestination}) ) { $patchfiledirectories{$olddestination} = 1; }
1678 $line = $line . "\tXXXXX\t" . $olddestination . "\n";
1680 push(@patchfiles, $line);
1682 # also collecting all files from patch in @installer::globals::patchfilecollector
1683 my $patchfileline = $origolddestination . "\n";
1684 push(@installer::globals::patchfilecollector, $patchfileline);
1687 my $winpatchdirname = "winpatch";
1688 my $winpatchdir = installer::systemactions::create_directories($winpatchdirname, $languagestringref);
1690 my $patchlistfile = installer::existence::get_specified_file_by_name($filesref, $patchfilename);
1692 # reorganizing the patchfile content, sorting for directory to decrease the file size
1693 my $sorteddirectorylist = sort_hash(\%patchfiledirectories);
1694 my $patchfilelist = reorg_patchfile(\@patchfiles, $sorteddirectorylist);
1696 # shifting version.ini to the end of the list, to guarantee, that all files are patched
1697 # if the correct version is shown in the about box
1698 $patchfilelist = shift_section_to_end($patchfilelist);
1699 $patchfilelist = shift_file_to_end($patchfilelist);
1701 # saving the file
1702 $patchfilename = $winpatchdir . $installer::globals::separator . $patchfilename;
1703 installer::files::save_file($patchfilename, $patchfilelist);
1705 my $infoline = "\nCreated list of patch files: $patchfilename\n";
1706 push( @installer::globals::logfileinfo, $infoline);
1708 # and assigning the new source
1709 $patchlistfile->{'sourcepath'} = $patchfilename;
1711 # and finally checking the file size
1712 if ( -f $patchfilename ) # test of existence
1714 my $filesize = ( -s $patchfilename );
1715 $infoline = "Size of patch file list: $filesize\n\n";
1716 push( @installer::globals::logfileinfo, $infoline);
1717 installer::logger::print_message( "... size of patch list file: $filesize Byte ... \n" );
1719 # Win 98: Maximum size of ini file is 65 kB
1720 # if ( $filesize > 64000 ) { installer::exiter::exit_program("ERROR: Maximum size of patch file list is 65 kB (Win98), now reached: $filesize Byte !", "prepare_windows_patchfiles"); }
1725 ###########################################################
1726 # Replacing %-variables with the content
1727 # of $allvariableshashref
1728 ###########################################################
1730 sub replace_variables_in_string
1732 my ( $string, $variableshashref ) = @_;
1734 if ( $string =~ /^.*\%\w+.*$/ )
1736 my $key;
1738 foreach $key (keys %{$variableshashref})
1740 my $value = $variableshashref->{$key};
1741 $key = "\%" . $key;
1742 $string =~ s/\Q$key\E/$value/g;
1746 return $string;
1749 ###########################################################
1750 # Replacing %-variables with the content
1751 # of $allvariableshashref
1752 ###########################################################
1754 sub replace_dollar_variables_in_string
1756 my ( $string, $variableshashref ) = @_;
1758 if ( $string =~ /^.*\$\{\w+\}.*$/ )
1760 my $key;
1762 foreach $key (keys %{$variableshashref})
1764 my $value = $variableshashref->{$key};
1765 $key = "\$\{" . $key . "\}";
1766 $string =~ s/\Q$key\E/$value/g;
1770 return $string;
1773 ###########################################################
1774 # The list file contains the list of packages/RPMs that
1775 # have to be copied.
1776 ###########################################################
1778 sub get_all_files_from_filelist
1780 my ( $listfile, $section ) = @_;
1782 my @allpackages = ();
1784 for ( my $i = 0; $i <= $#{$listfile}; $i++ )
1786 my $line = ${$listfile}[$i];
1787 if ( $line =~ /^\s*\#/ ) { next; } # this is a comment line
1788 if ( $line =~ /^\s*$/ ) { next; } # empty line
1789 $line =~ s/^\s*//;
1790 $line =~ s/\s*$//;
1791 push(@allpackages, $line);
1794 return \@allpackages;
1797 ###########################################################
1798 # Getting one section from a file. Section begins with
1799 # [xyz] and ends with file end or next [abc].
1800 ###########################################################
1802 sub get_section_from_file
1804 my ($file, $sectionname) = @_;
1806 my @section = ();
1807 my $record = 0;
1809 for ( my $i = 0; $i <= $#{$file}; $i++ )
1811 my $line = ${$file}[$i];
1813 if (( $record ) && ( $line =~ /^\s*\[/ ))
1815 $record = 0;
1816 last;
1819 if ( $line =~ /^\s*\[\Q$sectionname\E\]\s*$/ ) { $record = 1; }
1821 if ( $line =~ /^\s*\[/ ) { next; } # this is a section line
1822 if ( $line =~ /^\s*\#/ ) { next; } # this is a comment line
1823 if ( $line =~ /^\s*$/ ) { next; } # empty line
1824 $line =~ s/^\s*//;
1825 $line =~ s/\s*$//;
1826 if ( $record ) { push(@section, $line); }
1829 return \@section;
1833 #######################################################
1834 # Substituting one variable in the xml file
1835 #######################################################
1837 sub replace_one_dollar_variable
1839 my ($file, $variable, $searchstring) = @_;
1841 for ( my $i = 0; $i <= $#{$file}; $i++ )
1843 ${$file}[$i] =~ s/\$\{$searchstring\}/$variable/g;
1847 #######################################################
1848 # Substituting the variables in the xml file
1849 #######################################################
1851 sub substitute_dollar_variables
1853 my ($file, $variableshashref) = @_;
1855 my $key;
1857 foreach $key (keys %{$variableshashref})
1859 my $value = $variableshashref->{$key};
1860 replace_one_dollar_variable($file, $value, $key);
1864 #############################################################################
1865 # Collecting all packages or rpms located in the installation directory
1866 #############################################################################
1868 sub get_all_packages_in_installdir
1870 my ($directory) = @_;
1872 my $infoline = "";
1874 my @allpackages = ();
1875 my $allpackages = \@allpackages;
1877 if ( $installer::globals::islinuxrpmbuild )
1879 $allpackages = installer::systemactions::find_file_with_file_extension("rpm", $directory);
1882 if ( $installer::globals::issolarisbuild )
1884 $allpackages = installer::systemactions::get_all_directories($directory);
1887 return $allpackages;
1890 ###############################################################
1891 # The list of exclude packages can contain the
1892 # beginning of the package name, not the complete name.
1893 ###############################################################
1895 sub is_matching
1897 my ($onepackage, $allexcludepackages ) = @_;
1899 my $matches = 0;
1901 for ( my $i = 0; $i <= $#{$allexcludepackages}; $i++ )
1903 my $oneexcludepackage = ${$allexcludepackages}[$i];
1905 if ( $onepackage =~ /^\s*$oneexcludepackage/ )
1907 $matches = 1;
1908 last;
1912 return $matches;
1915 ###############################################################
1916 # Copying all Solaris packages or RPMs from installation set
1917 ###############################################################
1919 sub copy_all_packages
1921 my ($allexcludepackages, $sourcedir, $destdir) = @_;
1923 my $infoline = "";
1925 $sourcedir =~ s/\/\s*$//;
1926 $destdir =~ s/\/\s*$//;
1928 # $allexcludepackages is a list of RPMs and packages, that shall NOT be included into jds product
1929 my $allpackages = get_all_packages_in_installdir($sourcedir);
1931 for ( my $i = 0; $i <= $#{$allpackages}; $i++ )
1933 my $onepackage = ${$allpackages}[$i];
1935 my $packagename = $onepackage;
1937 if ( $installer::globals::issolarispkgbuild ) # on Solaris $onepackage contains the complete path
1939 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$packagename);
1942 if ( ! installer::existence::exists_in_array($packagename, $allexcludepackages))
1944 if ( ! is_matching($packagename, $allexcludepackages ) )
1947 if ( $installer::globals::islinuxrpmbuild )
1949 my $sourcepackage = $sourcedir . $installer::globals::separator . $packagename;
1950 my $destfile = $destdir . $installer::globals::separator . $packagename;
1951 if ( ! -f $sourcepackage ) { installer::exiter::exit_program("ERROR: Could not find RPM $sourcepackage!", "copy_all_packages"); }
1952 installer::systemactions::hardlink_one_file($sourcepackage, $destfile);
1955 if ( $installer::globals::issolarispkgbuild )
1957 my $destinationdir = $destdir . $installer::globals::separator . $packagename;
1958 if ( ! -d $onepackage ) { installer::exiter::exit_program("ERROR: Could not find Solaris package $onepackage!", "copy_all_packages"); }
1959 # installer::systemactions::hardlink_complete_directory($onepackage, $destinationdir);
1960 # installer::systemactions::copy_complete_directory($onepackage, $destinationdir);
1962 my $systemcall = "cp -p -R $onepackage $destinationdir";
1963 make_systemcall($systemcall);
1966 else
1968 $infoline = "Excluding package (matching): $onepackage\n";
1969 push( @installer::globals::logfileinfo, $infoline);
1972 else
1974 $infoline = "Excluding package (precise name): $onepackage\n";
1975 push( @installer::globals::logfileinfo, $infoline);
1980 ######################################################
1981 # Making systemcall
1982 ######################################################
1984 sub make_systemcall
1986 my ($systemcall) = @_;
1988 my $returnvalue = system($systemcall);
1990 my $infoline = "Systemcall: $systemcall\n";
1991 push( @installer::globals::logfileinfo, $infoline);
1993 if ($returnvalue)
1995 $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
1996 push( @installer::globals::logfileinfo, $infoline);
1998 else
2000 $infoline = "Success: Executed \"$systemcall\" successfully!\n";
2001 push( @installer::globals::logfileinfo, $infoline);
2005 ###########################################################
2006 # Copying all Solaris packages or RPMs from solver
2007 ###########################################################
2009 sub copy_additional_packages
2011 my ($allcopypackages, $destdir, $includepatharrayref) = @_;
2013 my $infoline = "Copy additional packages into installation set.\n";
2014 push( @installer::globals::logfileinfo, $infoline);
2016 $destdir =~ s/\/\s*$//;
2018 for ( my $i = 0; $i <= $#{$allcopypackages}; $i++ )
2020 my $onepackage = ${$allcopypackages}[$i];
2021 $infoline = "Copy package: $onepackage\n";
2022 push( @installer::globals::logfileinfo, $infoline);
2024 # this package must be delivered into the solver
2026 my $packagesourceref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$onepackage, $includepatharrayref, 0);
2027 if ($$packagesourceref eq "") { installer::exiter::exit_program("ERROR: Could not find jds file $onepackage!", "copy_additional_packages"); }
2029 if ( $onepackage =~ /\.tar\.gz\s*$/ )
2031 my $systemcall = "cd $destdir; cat $$packagesourceref | gunzip | tar -xf -";
2032 make_systemcall($systemcall);
2034 else
2036 my $destfile = $destdir . $installer::globals::separator . $onepackage;
2037 installer::systemactions::copy_one_file($$packagesourceref, $destfile);
2042 ###########################################################
2043 # Creating jds installation sets
2044 ###########################################################
2046 sub create_jds_sets
2048 my ($installationdir, $allvariableshashref, $languagestringref, $languagesarrayref, $includepatharrayref) = @_;
2050 installer::logger::print_message( "\n******************************************\n" );
2051 installer::logger::print_message( "... creating jds installation set ...\n" );
2052 installer::logger::print_message( "******************************************\n" );
2054 installer::logger::include_header_into_logfile("Creating jds installation sets:");
2056 my $firstdir = $installationdir;
2057 installer::pathanalyzer::get_path_from_fullqualifiedname(\$firstdir);
2059 my $lastdir = $installationdir;
2060 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$lastdir);
2062 if ( $lastdir =~ /\./ ) { $lastdir =~ s/\./_jds_inprogress\./ }
2063 else { $lastdir = $lastdir . "_jds_inprogress"; }
2065 # removing existing directory "_native_packed_inprogress" and "_native_packed_witherror" and "_native_packed"
2067 my $jdsdir = $firstdir . $lastdir;
2068 if ( -d $jdsdir ) { installer::systemactions::remove_complete_directory($jdsdir); }
2070 my $olddir = $jdsdir;
2071 $olddir =~ s/_inprogress/_witherror/;
2072 if ( -d $olddir ) { installer::systemactions::remove_complete_directory($olddir); }
2074 $olddir = $jdsdir;
2075 $olddir =~ s/_inprogress//;
2076 if ( -d $olddir ) { installer::systemactions::remove_complete_directory($olddir); }
2078 # creating the new directory
2080 installer::systemactions::create_directory($jdsdir);
2082 $installer::globals::saveinstalldir = $jdsdir;
2084 # find and read jds files list
2085 my $filelistname = $installer::globals::jdsexcludefilename;
2087 my $filelistnameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filelistname, "", 0);
2088 if ($$filelistnameref eq "") { installer::exiter::exit_program("ERROR: Could not find jds list file $filelistname!", "create_jds_sets"); }
2090 my $listfile = installer::files::read_file($$filelistnameref);
2092 my $infoline = "Found jds list file: $$filelistnameref\n";
2093 push( @installer::globals::logfileinfo, $infoline);
2095 # substituting the variables
2096 substitute_dollar_variables($listfile, $allvariableshashref);
2098 # determining the packages/RPMs to copy
2099 my $allexcludepackages = get_section_from_file($listfile, "excludefiles");
2100 my $allcopypackages = get_section_from_file($listfile, "copyfiles");
2102 # determining the source directory
2103 my $alldirs = installer::systemactions::get_all_directories($installationdir);
2104 my $sourcedir = ${$alldirs}[0]; # there is only one directory
2106 if ( $installer::globals::issolarisbuild ) { $sourcedir = $installer::globals::saved_packages_path; }
2108 # copy all packages/RPMs
2109 copy_all_packages($allexcludepackages, $sourcedir, $jdsdir);
2110 copy_additional_packages($allcopypackages, $jdsdir, $includepatharrayref);
2112 return $jdsdir;
2115 #############################################################################
2116 # Checking, whether this installation set contains the correct languages
2117 #############################################################################
2119 sub check_jds_language
2121 my ($allvariableshashref, $languagestringref) = @_;
2123 my $infoline = "";
2125 # languagesarrayref and $allvariableshashref->{'JDSLANG'}
2127 if ( ! $allvariableshashref->{'JDSLANG'} ) { installer::exiter::exit_program("ERROR: For building JDS installation sets \"JDSLANG\" must be defined!", "check_jds_language"); }
2128 my $languagestring = $allvariableshashref->{'JDSLANG'};
2130 my $sortedarray1 = installer::converter::convert_stringlist_into_array(\$languagestring, ",");
2132 installer::sorter::sorting_array_of_strings($sortedarray1);
2134 my $sortedarray2 = installer::converter::convert_stringlist_into_array($languagestringref, "_");
2135 installer::sorter::sorting_array_of_strings($sortedarray2);
2137 my $string1 = installer::converter::convert_array_to_comma_separated_string($sortedarray1);
2138 my $string2 = installer::converter::convert_array_to_comma_separated_string($sortedarray2);
2140 my $arrays_are_equal = compare_arrays($sortedarray1, $sortedarray2);
2142 return $arrays_are_equal;
2145 ###################################################################################
2146 # Comparing two arrays. The arrays are equal, if the complete content is equal.
2147 ###################################################################################
2149 sub compare_arrays
2151 my ($array1, $array2) = @_;
2153 my $arrays_are_equal = 1;
2155 # checking the size
2157 if ( ! ( $#{$array1} == $#{$array2} )) { $arrays_are_equal = 0; } # different size
2159 if ( $arrays_are_equal ) # only make further investigations if size is equal
2161 for ( my $i = 0; $i <= $#{$array1}; $i++ )
2163 # ingnoring whitespaces at end and beginning
2164 ${$array1}[$i] =~ s/^\s*//;
2165 ${$array2}[$i] =~ s/^\s*//;
2166 ${$array1}[$i] =~ s/\s*$//;
2167 ${$array2}[$i] =~ s/\s*$//;
2169 if ( ! ( ${$array1}[$i] eq ${$array2}[$i] ))
2171 $arrays_are_equal = 0;
2172 last;
2177 return $arrays_are_equal;
2180 #################################################################
2181 # Copying the files defined as ScpActions into the
2182 # installation set.
2183 #################################################################
2185 sub put_scpactions_into_installset
2187 my ($installdir) = @_;
2189 installer::logger::include_header_into_logfile("Start: Copying scp action files into installation set");
2191 for ( my $i = 0; $i <= $#installer::globals::allscpactions; $i++ )
2193 my $onescpaction = $installer::globals::allscpactions[$i];
2195 my $subdir = "";
2196 if ( $onescpaction->{'Subdir'} ) { $subdir = $onescpaction->{'Subdir'}; }
2198 if ( $onescpaction->{'Name'} eq "loader.exe" ) { next; } # do not copy this ScpAction loader
2200 my $destdir = $installdir;
2201 $destdir =~ s/\Q$installer::globals::separator\E\s*$//;
2202 if ( $subdir ) { $destdir = $destdir . $installer::globals::separator . $subdir; }
2204 my $sourcefile = $onescpaction->{'sourcepath'};
2205 my $destfile = $destdir . $installer::globals::separator . $onescpaction->{'DestinationName'};
2207 my $styles = "";
2208 if ( $onescpaction->{'Styles'} ) { $styles = $onescpaction->{'Styles'}; }
2209 if (( $styles =~ /\bFILE_CAN_MISS\b/ ) && ( $sourcefile eq "" )) { next; }
2211 if (( $subdir =~ /\// ) || ( $subdir =~ /\\/ ))
2213 installer::systemactions::create_directory_structure($destdir);
2215 else
2217 installer::systemactions::create_directory($destdir);
2220 installer::systemactions::copy_one_file($sourcefile, $destfile);
2222 if ( $onescpaction->{'UnixRights'} )
2224 my $localcall = "chmod $onescpaction->{'UnixRights'} $destfile \>\/dev\/null 2\>\&1";
2225 system($localcall);
2230 installer::logger::include_header_into_logfile("End: Copying scp action files into installation set");
2234 #################################################################
2235 # Collecting scp actions for all languages
2236 #################################################################
2238 sub collect_scpactions
2240 my ($allscpactions) = @_;
2242 for ( my $i = 0; $i <= $#{$allscpactions}; $i++ )
2244 push(@installer::globals::allscpactions, ${$allscpactions}[$i]);
2248 #################################################################
2249 # Setting the platform name for download
2250 #################################################################
2252 sub get_platform_name
2254 my $platformname = "";
2256 if (( $installer::globals::islinuxintelrpmbuild ) || ( $installer::globals::islinuxinteldebbuild ))
2258 $platformname = "LinuxIntel";
2260 elsif (( $installer::globals::islinuxppcrpmbuild ) || ( $installer::globals::islinuxppcdebbuild ))
2262 $platformname = "LinuxPowerPC";
2264 elsif (( $installer::globals::islinuxx86_64rpmbuild ) || ( $installer::globals::islinuxx86_64debbuild ))
2266 $platformname = "LinuxX86-64";
2268 elsif ( $installer::globals::issolarissparcbuild )
2270 $platformname = "SolarisSparc";
2272 elsif ( $installer::globals::issolarisx86build )
2274 $platformname = "Solarisx86";
2276 elsif ( $installer::globals::iswindowsbuild )
2278 $platformname = "Win32Intel";
2280 elsif ( $installer::globals::compiler =~ /^unxmacxi/ )
2282 $platformname = "MacOSXIntel";
2284 elsif ( $installer::globals::compiler =~ /^unxmacxp/ )
2286 $platformname = "MacOSXPowerPC";
2288 else
2290 # $platformname = $installer::globals::packageformat;
2291 $platformname = $installer::globals::compiler;
2294 return $platformname;
2297 ###########################################################
2298 # Adding additional variables into the variableshashref,
2299 # that are defined in include files in the solver. The
2300 # names of the include files are stored in
2301 # ADD_INCLUDE_FILES (comma separated list).
2302 ###########################################################
2304 sub add_variables_from_inc_to_hashref
2306 my ($allvariables, $includepatharrayref) = @_;
2308 my $infoline = "";
2309 my $includefilelist = "";
2310 if ( $allvariables->{'ADD_INCLUDE_FILES'} ) { $includefilelist = $allvariables->{'ADD_INCLUDE_FILES'}; }
2312 my $includefiles = installer::converter::convert_stringlist_into_array_without_linebreak_and_quotes(\$includefilelist, ",");
2314 for ( my $i = 0; $i <= $#{$includefiles}; $i++ )
2316 my $includefilename = ${$includefiles}[$i];
2317 $includefilename =~ s/^\s*//;
2318 $includefilename =~ s/\s*$//;
2319 $includefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$includefilename, $includepatharrayref, 1);
2320 if ( $$includefilenameref eq "" ) { installer::exiter::exit_program("Include file $includefilename not found!\nADD_INCLUDE_FILES = $allvariables->{'ADD_INCLUDE_FILES'}", "add_variables_from_inc_to_hashref"); }
2322 $infoline = "Including inc file: $$includefilenameref \n";
2323 push( @installer::globals::globallogfileinfo, $infoline);
2325 my $includefile = installer::files::read_file($$includefilenameref);
2327 for ( my $j = 0; $j <= $#{$includefile}; $j++ )
2329 # Analyzing all "key=value" lines
2330 my $oneline = ${$includefile}[$j];
2332 if ( $oneline =~ /^\s*(\S+)\s*\=\s*(.*?)\s*$/ ) # no white space allowed in key
2334 my $key = $1;
2335 my $value = $2;
2336 $allvariables->{$key} = $value;
2337 $infoline = "Setting of variable: $key = $value\n";
2338 push( @installer::globals::globallogfileinfo, $infoline);
2343 # Allowing different Java versions for Windows and Unix. Instead of "JAVAVERSION"
2344 # the property "WINDOWSJAVAVERSION" has to be used, if it is set.
2346 if ( $installer::globals::iswindowsbuild )
2348 if (( exists($allvariables->{'WINDOWSJAVAVERSION'})) && ( $allvariables->{'WINDOWSJAVAVERSION'} ne "" ))
2350 $allvariables->{'JAVAVERSION'} = $allvariables->{'WINDOWSJAVAVERSION'};
2351 $infoline = "Changing value of property \"JAVAVERSION\" to $allvariables->{'JAVAVERSION'} (property \"WINDOWSJAVAVERSION\").\n";
2352 push( @installer::globals::globallogfileinfo, $infoline);
2357 ##############################################
2358 # Collecting all files from include pathes
2359 ##############################################
2361 sub collect_all_files_from_includepathes
2363 my ($patharrayref) = @_;
2365 installer::logger::globallog("Reading all directories: Start");
2366 installer::logger::print_message( "... reading include pathes ...\n" );
2367 # empty the global
2369 @installer::globals::allincludepathes =();
2370 my $infoline;
2372 for ( my $i = 0; $i <= $#{$patharrayref}; $i++ )
2374 $includepath = ${$patharrayref}[$i];
2375 installer::remover::remove_leading_and_ending_whitespaces(\$includepath);
2377 if ( ! -d $includepath )
2379 $infoline = "$includepath does not exist. (Can be removed from include path list?)\n";
2380 push( @installer::globals::globallogfileinfo, $infoline);
2381 next;
2384 my @sourcefiles = ();
2385 my $pathstring = "";
2386 # installer::systemactions::read_complete_directory($includepath, $pathstring, \@sourcefiles);
2387 installer::systemactions::read_full_directory($includepath, $pathstring, \@sourcefiles);
2389 if ( ! ( $#sourcefiles > -1 ))
2391 $infoline = "$includepath is empty. (Can be removed from include path list?)\n";
2392 push( @installer::globals::globallogfileinfo, $infoline);
2394 else
2396 my $number = $#sourcefiles + 1;
2397 $infoline = "Directory $includepath contains $number files (including subdirs)\n";
2398 push( @installer::globals::globallogfileinfo, $infoline);
2400 my %allfileshash = ();
2401 $allfileshash{'includepath'} = $includepath;
2403 for ( my $j = 0; $j <= $#sourcefiles; $j++ )
2405 $allfileshash{$sourcefiles[$j]} = 1;
2408 push(@installer::globals::allincludepathes, \%allfileshash);
2412 $installer::globals::include_pathes_read = 1;
2414 installer::logger::globallog("Reading all directories: End");
2415 push( @installer::globals::globallogfileinfo, "\n");
2418 ##############################################
2419 # Searching for a file with the gid
2420 ##############################################
2422 sub find_file_by_id
2424 my ( $filesref, $gid ) = @_;
2426 my $foundfile = 0;
2427 my $onefile;
2429 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
2431 $onefile = ${$filesref}[$i];
2432 my $filegid = $onefile->{'gid'};
2434 if ( $filegid eq $gid )
2436 $foundfile = 1;
2437 last;
2441 # It does not need to exist. For example products that do not contain the libraries.
2442 # if (! $foundfile ) { installer::exiter::exit_program("ERROR: No unique file name found for $filename !", "get_selfreg_file"); }
2444 if (! $foundfile ) { $onefile = ""; }
2446 return $onefile;
2449 ##############################################
2450 # Searching for an item with the gid
2451 ##############################################
2453 sub find_item_by_gid
2455 my ( $itemsref, $gid ) = @_;
2457 my $founditem = 0;
2458 my $oneitem = "";
2460 for ( my $i = 0; $i <= $#{$itemsref}; $i++ )
2462 my $localitem = ${$itemsref}[$i];
2463 my $itemgid = $localitem->{'gid'};
2465 if ( $itemgid eq $gid )
2467 $oneitem = $localitem;
2468 $founditem = 1;
2469 last;
2473 return $oneitem;
2476 #########################################################
2477 # Calling sum
2478 #########################################################
2480 sub call_sum
2482 my ($filename) = @_;
2484 $sumfile = "/usr/bin/sum";
2486 if ( ! -f $sumfile ) { installer::exiter::exit_program("ERROR: No file /usr/bin/sum", "call_sum"); }
2488 my $systemcall = "$sumfile $filename |";
2490 my $sumoutput = "";
2492 open (SUM, "$systemcall");
2493 $sumoutput = <SUM>;
2494 close (SUM);
2496 my $returnvalue = $?; # $? contains the return value of the systemcall
2498 my $infoline = "Systemcall: $systemcall\n";
2499 push( @installer::globals::logfileinfo, $infoline);
2501 if ($returnvalue)
2503 $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
2504 push( @installer::globals::logfileinfo, $infoline);
2506 else
2508 $infoline = "Success: Executed \"$systemcall\" successfully!\n";
2509 push( @installer::globals::logfileinfo, $infoline);
2512 return $sumoutput;
2515 #########################################################
2516 # Calling wc
2517 # wc -c pkginfo | cut -f6 -d' '
2518 #########################################################
2520 sub call_wc
2522 my ($filename) = @_;
2524 $wcfile = "/usr/bin/wc";
2526 if ( ! -f $wcfile ) { installer::exiter::exit_program("ERROR: No file /usr/bin/wc", "call_wc"); }
2528 my $systemcall = "$wcfile -c $filename |";
2530 my $wcoutput = "";
2532 open (WC, "$systemcall");
2533 $wcoutput = <WC>;
2534 close (WC);
2536 my $returnvalue = $?; # $? contains the return value of the systemcall
2538 my $infoline = "Systemcall: $systemcall\n";
2539 push( @installer::globals::logfileinfo, $infoline);
2541 if ($returnvalue)
2543 $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
2544 push( @installer::globals::logfileinfo, $infoline);
2546 else
2548 $infoline = "Success: Executed \"$systemcall\" successfully!\n";
2549 push( @installer::globals::logfileinfo, $infoline);
2552 return $wcoutput;
2555 ##############################################
2556 # Setting architecture ARCH=i86pc
2557 # instead of ARCH=i386.
2558 ##############################################
2560 sub set_old_architecture_string
2562 my ($pkginfofile) = @_;
2564 for ( my $i = 0; $i <= $#{$pkginfofile}; $i++ )
2566 if ( ${$pkginfofile}[$i] =~ /^\s*ARCH=i386\s*$/ )
2568 ${$pkginfofile}[$i] =~ s/i386/i86pc/;
2569 last;
2574 ##############################################
2575 # For the new copied package, it is necessary
2576 # that a value for the key SUNW_REQUIRES
2577 # is set. Otherwise this copied package
2578 # with ARCH=i86pc would be useless.
2579 ##############################################
2581 sub check_requires_setting
2583 my ($pkginfofile) = @_;
2585 my $found = 0;
2586 my $patchid = "";
2588 for ( my $i = 0; $i <= $#{$pkginfofile}; $i++ )
2590 if ( ${$pkginfofile}[$i] =~ /^\s*SUNW_REQUIRES=(\S*?)\s*$/ )
2592 $patchid = $1;
2593 $found = 1;
2594 last;
2598 if (( ! $found ) || ( $patchid eq "" )) { installer::exiter::exit_program("ERROR: No patch id defined for SUNW_REQUIRES in patch pkginfo file!", "check_requires_setting"); }
2601 ##############################################
2602 # Setting checksum and wordcount for changed
2603 # pkginfo file into pkgmap.
2604 ##############################################
2606 sub set_pkginfo_line
2608 my ($pkgmapfile, $pkginfofilename) = @_;
2610 # 1 i pkginfo 442 34577 1166716297
2611 # ->
2612 # 1 i pkginfo 443 34737 1166716297
2614 # wc -c pkginfo | cut -f6 -d' ' -> 442 (variable)
2615 # sum pkginfo | cut -f1 -d' ' -> 34577 (variable)
2616 # grep 'pkginfo' pkgmap | cut -f6 -d' ' -> 1166716297 (fix)
2618 my $checksum = call_sum($pkginfofilename);
2619 if ( $checksum =~ /^\s*(\d+)\s+.*$/ ) { $checksum = $1; }
2621 my $wordcount = call_wc($pkginfofilename);
2622 if ( $wordcount =~ /^\s*(\d+)\s+.*$/ ) { $wordcount = $1; }
2624 for ( my $i = 0; $i <= $#{$pkgmapfile}; $i++ )
2626 if ( ${$pkgmapfile}[$i] =~ /(^.*\bpkginfo\b\s+)(\d+)(\s+)(\d+)(\s+)(\d+)(\s*$)/ )
2628 my $newline = $1 . $wordcount . $3 . $checksum . $5 . $6 . $7;
2629 ${$pkgmapfile}[$i] = $newline;
2630 last;
2635 ##############################################
2636 # Setting time stamp of copied files to avoid
2637 # errors from pkgchk.
2638 ##############################################
2640 sub set_time_stamp
2642 my ($olddir, $newdir, $copyfiles) = @_;
2644 for ( my $i = 0; $i <= $#{$copyfiles}; $i++ )
2646 my $sourcefile = $olddir . $installer::globals::separator . ${$copyfiles}[$i];
2647 my $destfile = $newdir . $installer::globals::separator . ${$copyfiles}[$i];
2649 my $systemcall = "touch -r $sourcefile $destfile";
2651 my $returnvalue = system($systemcall);
2653 my $infoline = "Systemcall: $systemcall\n";
2654 push( @installer::globals::logfileinfo, $infoline);
2656 if ($returnvalue)
2658 $infoline = "ERROR: \"$systemcall\" failed!\n";
2659 push( @installer::globals::logfileinfo, $infoline);
2661 else
2663 $infoline = "Success: \"$systemcall\" !\n";
2664 push( @installer::globals::logfileinfo, $infoline);
2669 ##############################################
2670 # Include only files from install directory
2671 # in pkgmap file.
2672 ##############################################
2673 ########################################
2674 # Generating pathes for cygwin.
2675 ########################################
2677 sub generate_cygwin_pathes
2679 my ($filesref) = @_;
2681 my ($tmpfilehandle, $tmpfilename) = tmpnam();
2682 open SOURCEPATHLIST, ">$tmpfilename" or die "oops...\n";
2683 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
2685 print SOURCEPATHLIST "${$filesref}[$i]->{'sourcepath'}\n";
2687 close SOURCEPATHLIST;
2688 my @cyg_sourcepathlist = qx{cygpath -w -f "$tmpfilename"};
2689 chomp @cyg_sourcepathlist;
2690 unlink "$tmpfilename" or die "oops\n";
2691 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
2693 ${$filesref}[$i]->{'cyg_sourcepath'} = $cyg_sourcepathlist[$i];
2697 sub filter_pkgmapfile
2699 my ($pkgmapfile) = @_;
2701 my @pkgmap = ();
2703 my $line = ": 1 10\n";
2704 push(@pkgmap, $line);
2706 for ( my $i = 0; $i <= $#{$pkgmapfile}; $i++ )
2708 $line = ${$pkgmapfile}[$i];
2709 if ( $line =~ /^\s*1\si\s/ ) { push(@pkgmap, $line); }
2712 return \@pkgmap;
2715 ##############################################
2716 # Creating double packages for Solaris x86.
2717 # One package with ARCH=i386 and one with
2718 # ARCH=i86pc.
2719 ##############################################
2721 sub fix_solaris_x86_patch
2723 my ($packagename, $subdir) = @_;
2725 # changing into directory of packages, important for soft linking
2726 my $startdir = cwd();
2727 chdir($subdir);
2729 # $packagename is: "SUNWstaroffice-core01"
2730 # Current working directory is: "<path>/install/en-US_inprogress"
2732 # create new folder in "packages": $packagename . ".i"
2733 my $newpackagename = $packagename . "\.i";
2734 my $newdir = $newpackagename;
2735 installer::systemactions::create_directory($newdir);
2737 # collecting all directories in the package
2738 my $olddir = $packagename;
2739 my $allsubdirs = installer::systemactions::get_all_directories_without_path($olddir);
2741 # link all directories from $packagename to $packagename . ".i"
2742 for ( my $i = 0; $i <= $#{$allsubdirs}; $i++ )
2744 my $sourcedir = $olddir . $installer::globals::separator . ${$allsubdirs}[$i];
2745 my $destdir = $newdir . $installer::globals::separator . ${$allsubdirs}[$i];
2746 my $directory_depth = 2; # important for soft links, two directories already exist
2747 installer::systemactions::softlink_complete_directory($sourcedir, $destdir, $directory_depth);
2750 # copy "pkginfo" and "pkgmap" from $packagename to $packagename . ".i"
2751 my @allcopyfiles = ("pkginfo", "pkgmap");
2752 for ( my $i = 0; $i <= $#allcopyfiles; $i++ )
2754 my $sourcefile = $olddir . $installer::globals::separator . $allcopyfiles[$i];
2755 my $destfile = $newdir . $installer::globals::separator . $allcopyfiles[$i];
2756 installer::systemactions::copy_one_file($sourcefile, $destfile);
2759 # change in pkginfo in $packagename . ".i" the value for ARCH from i386 to i86pc
2760 my $pkginfofilename = "pkginfo";
2761 $pkginfofilename = $newdir . $installer::globals::separator . $pkginfofilename;
2763 my $pkginfofile = installer::files::read_file($pkginfofilename);
2764 set_old_architecture_string($pkginfofile);
2765 installer::files::save_file($pkginfofilename, $pkginfofile);
2767 # adapt the values in pkgmap for pkginfo file, because this file was edited
2768 my $pkgmapfilename = "pkgmap";
2769 $pkgmapfilename = $newdir . $installer::globals::separator . $pkgmapfilename;
2771 my $pkgmapfile = installer::files::read_file($pkgmapfilename);
2772 set_pkginfo_line($pkgmapfile, $pkginfofilename);
2773 installer::files::save_file($pkgmapfilename, $pkgmapfile);
2775 # changing back to startdir
2776 chdir($startdir);
2779 ###################################################
2780 # Creating double core01 package for Solaris x86.
2781 # One package with ARCH=i386 and one with
2782 # ARCH=i86pc. This is necessary, to inform the
2783 # user about the missing "small patch", if
2784 # packages with ARCH=i86pc are installed.
2785 ###################################################
2787 sub fix2_solaris_x86_patch
2789 my ($packagename, $subdir) = @_;
2791 if ( $packagename =~ /-core01\s*$/ ) # only this one package needs to be duplicated
2793 my $startdir = cwd();
2794 chdir($subdir);
2796 # $packagename is: "SUNWstaroffice-core01"
2797 # Current working directory is: "<path>/install/en-US_inprogress"
2799 # create new package in "packages": $packagename . ".i"
2800 my $olddir = $packagename;
2801 my $newpackagename = $packagename . "\.i";
2802 my $newdir = $newpackagename;
2804 installer::systemactions::create_directory($newdir);
2806 my $oldinstalldir = $olddir . $installer::globals::separator . "install";
2807 my $newinstalldir = $newdir . $installer::globals::separator . "install";
2809 installer::systemactions::copy_complete_directory($oldinstalldir, $newinstalldir);
2811 # setting time stamp of all copied files to avoid errors from pkgchk
2812 my $allinstallfiles = installer::systemactions::get_all_files_from_one_directory_without_path($newinstalldir);
2813 set_time_stamp($oldinstalldir, $newinstalldir, $allinstallfiles);
2815 # copy "pkginfo" and "pkgmap" from $packagename to $packagename . ".i"
2816 my @allcopyfiles = ("pkginfo", "pkgmap");
2817 for ( my $i = 0; $i <= $#allcopyfiles; $i++ )
2819 my $sourcefile = $olddir . $installer::globals::separator . $allcopyfiles[$i];
2820 my $destfile = $newdir . $installer::globals::separator . $allcopyfiles[$i];
2821 installer::systemactions::copy_one_file($sourcefile, $destfile);
2824 # change in pkginfo in $packagename . ".i" the value for ARCH from i386 to i86pc
2825 my $pkginfofilename = "pkginfo";
2826 $pkginfofilename = $newdir . $installer::globals::separator . $pkginfofilename;
2828 my $pkginfofile = installer::files::read_file($pkginfofilename);
2829 set_old_architecture_string($pkginfofile);
2830 check_requires_setting($pkginfofile);
2831 installer::files::save_file($pkginfofilename, $pkginfofile);
2833 # adapt the values in pkgmap for pkginfo file, because this file was edited
2834 my $pkgmapfilename = "pkgmap";
2835 $pkgmapfilename = $newdir . $installer::globals::separator . $pkgmapfilename;
2837 my $pkgmapfile = installer::files::read_file($pkgmapfilename);
2838 set_pkginfo_line($pkgmapfile, $pkginfofilename);
2839 $pkgmapfile = filter_pkgmapfile($pkgmapfile);
2840 installer::files::save_file($pkgmapfilename, $pkgmapfile);
2842 # setting time stamp of all copied files to avoid errors from pkgchk
2843 set_time_stamp($olddir, $newdir, \@allcopyfiles);
2845 # changing back to startdir
2846 chdir($startdir);
2850 ################################################
2851 # Files with flag HIDDEN get a dot at the
2852 # beginning of the file name. This cannot be
2853 # defined in scp2 project, because tooling
2854 # cannot handle files with beginning dot
2855 # correctly.
2856 ################################################
2858 sub resolving_hidden_flag
2860 my ($filesarrayref, $variableshashref, $item, $languagestringref) = @_;
2862 my $diritem = lc($item);
2863 my $infoline = "";
2865 my $hiddendirbase = installer::systemactions::create_directories("hidden_$diritem", $languagestringref);
2867 installer::logger::include_header_into_logfile("$item with flag HIDDEN:");
2869 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ )
2871 my $onefile = ${$filesarrayref}[$i];
2872 my $styles = "";
2874 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; }
2876 if ( $styles =~ /\bHIDDEN\b/ )
2878 # Language specific subdirectory
2880 my $onelanguage = $onefile->{'specificlanguage'};
2882 if ($onelanguage eq "")
2884 $onelanguage = "00"; # files without language into directory "00"
2887 my $hiddendir = $hiddendirbase . $installer::globals::separator . $onelanguage . $installer::globals::separator;
2888 installer::systemactions::create_directory($hiddendir); # creating language specific directories
2890 # copy files and edit them with the variables defined in the zip.lst
2892 my $onefilename = $onefile->{'Name'};
2893 my $newfilename = "\." . $onefilename;
2894 my $sourcefile = $onefile->{'sourcepath'};
2895 my $destfile = $hiddendir . $newfilename;
2897 my $copysuccess = installer::systemactions::copy_one_file($sourcefile, $destfile);
2899 if ( $copysuccess )
2901 # $onefile->{'Name'} = $newfilename;
2902 $onefile->{'sourcepath'} = $destfile;
2903 $destination = $onefile->{'destination'};
2904 installer::pathanalyzer::get_path_from_fullqualifiedname(\$destination);
2905 if ( $destination eq "" ) { $onefile->{'destination'} = $newfilename; }
2906 else { $onefile->{'destination'} = $destination . $installer::globals::separator . $newfilename; }
2908 $infoline = "Success: Using file with flag HIDDEN from \"$onefile->{'sourcepath'}\"!\n";
2909 push( @installer::globals::logfileinfo, $infoline);
2911 else
2913 $infoline = "Error: Failed to copy HIDDEN file from \"$sourcefile\" to \"$destfile\"!\n";
2914 push( @installer::globals::logfileinfo, $infoline);
2919 $infoline = "\n";
2920 push( @installer::globals::logfileinfo, $infoline);
2923 ################################################
2924 # Controlling that all keys in hash A are
2925 # also key in hash B.
2926 ################################################
2928 sub key_in_a_is_also_key_in_b
2930 my ( $hashref_a, $hashref_b) = @_;
2932 my $returnvalue = 1;
2934 my $key;
2935 foreach $key ( keys %{$hashref_a} )
2937 if ( ! exists($hashref_b->{$key}) )
2939 print "*****\n";
2940 foreach $keyb ( keys %{$hashref_b} ) { print "$keyb : $hashref_b->{$keyb}\n"; }
2941 print "*****\n";
2942 $returnvalue = 0;
2946 return $returnvalue;
2949 ################################################
2950 # Setting all spellchecker languages
2951 ################################################
2953 sub set_spellcheckerlanguages
2955 my ( $productlanguagesarrayref, $allvariables ) = @_;
2957 my %productlanguages = ();
2958 for ( my $i = 0; $i <= $#{$productlanguagesarrayref}; $i++ ) { $productlanguages{${$productlanguagesarrayref}[$i]} = 1; }
2960 my $spellcheckfilename = $allvariables->{'SPELLCHECKERFILE'};
2962 my $spellcheckfileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$spellcheckfilename, "", 1);
2964 if ($$spellcheckfileref eq "") { installer::exiter::exit_program("ERROR: Could not find $spellcheckfilename!", "set_spellcheckerlanguages"); }
2966 my $infoline = "Using spellchecker file: $$spellcheckfileref \n";
2967 push( @installer::globals::globallogfileinfo, $infoline);
2969 my $spellcheckfile = installer::files::read_file($$spellcheckfileref);
2970 my %spellcheckhash = ();
2972 for ( my $j = 0; $j <= $#{$spellcheckfile}; $j++ )
2974 # Analyzing all "key=value" lines
2975 my $oneline = ${$spellcheckfile}[$j];
2977 if ( $oneline =~ /^\s*(\S+)\s*\=\s*\"(.*?)\"\s*$/ ) # no white space allowed in key
2979 my $onelang = $1;
2980 my $languagelist = $2;
2981 $spellcheckhash{$onelang} = $languagelist;
2983 # Special handling for language packs. Do only include that one language of the language pack, no further language.
2984 # And this only, if the language of the language pack is also already part of the language list
2986 if ( $installer::globals::languagepack )
2988 if ( $languagelist =~ /\b$onelang\b/ ) { $spellcheckhash{$onelang} = $onelang; }
2989 else { $spellcheckhash{$onelang} = ""; }
2994 # Collecting all required languages in %installer::globals::spellcheckerlanguagehash
2996 foreach my $lang (keys %productlanguages)
2998 my $languagelist = "";
2999 if ( exists($spellcheckhash{$lang}) ) { $languagelist = $spellcheckhash{$lang}; }
3000 else { $languagelist = $spellcheckhash{'en-US'}; } # defaulting to English
3002 my $langlisthash = installer::converter::convert_stringlist_into_hash(\$languagelist, ",");
3003 foreach my $onelang ( keys %{$langlisthash} ) { $installer::globals::spellcheckerlanguagehash{$onelang} = 1; }
3006 $installer::globals::analyze_spellcheckerlanguage = 1;
3008 # Logging
3010 my $langstring = "";
3011 foreach my $lang (sort keys %installer::globals::spellcheckerlanguagehash) { $langstring = $langstring . "," . $lang }
3012 $langstring =~ s/^\s*,//;
3014 $infoline = "Collected spellchecker languages for spellchecker: $langstring \n";
3015 push( @installer::globals::globallogfileinfo, $infoline);
3018 ################################################
3019 # Including a license text into setup script
3020 ################################################
3022 sub put_license_into_setup
3024 my ($installdir, $includepatharrayref) = @_;
3026 # find and read english license file
3027 my $licenselanguage = "en-US"; # always english !
3028 my $licensefilename = "LICENSE_" . $licenselanguage;
3029 my $licenseincludepatharrayref = get_language_specific_include_pathes($includepatharrayref, $licenselanguage);
3031 my $licenseref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$licensefilename, $licenseincludepatharrayref, 0);
3032 if ($$licenseref eq "") { installer::exiter::exit_program("ERROR: Could not find License file $licensefilename!", "put_license_into_setup"); }
3033 my $licensefile = installer::files::read_file($$licenseref);
3035 # Read setup
3036 my $setupfilename = $installdir . $installer::globals::separator . "setup";
3037 my $setupfile = installer::files::read_file($setupfilename);
3039 # Replacement
3040 my $infoline = "Adding licensefile into setup script\n";
3041 push( @installer::globals::logfileinfo, $infoline);
3043 my $includestring = "";
3044 for ( my $i = 0; $i <= $#{$licensefile}; $i++ ) { $includestring = $includestring . ${$licensefile}[$i]; }
3045 for ( my $i = 0; $i <= $#{$setupfile}; $i++ ) { ${$setupfile}[$i] =~ s/LICENSEFILEPLACEHOLDER/$includestring/; }
3047 # Write setup
3048 installer::files::save_file($setupfilename, $setupfile);
3051 ################################################
3052 # Setting global path to getuid.so library
3053 ################################################
3055 sub set_getuid_path
3057 my ($includepatharrayref) = @_;
3059 my $getuidlibraryname = "getuid.so";
3060 my $getuidlibraryref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$getuidlibraryname, $includepatharrayref, 0);
3061 if ($$getuidlibraryref eq "") { installer::exiter::exit_program("ERROR: Could not find $getuidlibraryname!", "set_getuid_path"); }
3063 $installer::globals::getuidpath = $$getuidlibraryref;
3064 $installer::globals::getuidpathset = 1;
3067 #########################################################
3068 # Create a tar file from the binary package
3069 #########################################################
3071 sub tar_package
3073 my ( $installdir, $packagename, $tarfilename, $getuidlibrary) = @_;
3075 my $ldpreloadstring = "";
3076 if ( $getuidlibrary ne "" ) { $ldpreloadstring = "LD_PRELOAD=" . $getuidlibrary; }
3078 my $systemcall = "cd $installdir; $ldpreloadstring tar -cf - $packagename > $tarfilename";
3079 # my $systemcall = "cd $installdir; $ldpreloadstring tar -cf - * > $tarfilename";
3081 my $returnvalue = system($systemcall);
3083 my $infoline = "Systemcall: $systemcall\n";
3084 push( @installer::globals::logfileinfo, $infoline);
3086 if ($returnvalue)
3088 $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
3089 push( @installer::globals::logfileinfo, $infoline);
3091 else
3093 $infoline = "Success: Executed \"$systemcall\" successfully!\n";
3094 push( @installer::globals::logfileinfo, $infoline);
3097 my $localcall = "chmod 775 $tarfilename \>\/dev\/null 2\>\&1";
3098 $returnvalue = system($localcall);
3100 my $fulltarfile = $installdir . $installer::globals::separator . $tarfilename;
3101 my $filesize = ( -s $fulltarfile );
3103 return $filesize;
3106 #########################################################
3107 # Create a tar file from the binary package
3108 #########################################################
3110 sub untar_package
3112 my ( $installdir, $tarfilename, $getuidlibrary) = @_;
3114 my $ldpreloadstring = "";
3115 if ( $getuidlibrary ne "" ) { $ldpreloadstring = "LD_PRELOAD=" . $getuidlibrary; }
3117 my $systemcall = "cd $installdir; $ldpreloadstring tar -xf $tarfilename";
3119 my $returnvalue = system($systemcall);
3121 my $infoline = "Systemcall: $systemcall\n";
3122 push( @installer::globals::logfileinfo, $infoline);
3124 if ($returnvalue)
3126 $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
3127 push( @installer::globals::logfileinfo, $infoline);
3129 else
3131 $infoline = "Success: Executed \"$systemcall\" successfully!\n";
3132 push( @installer::globals::logfileinfo, $infoline);
3135 my $localcall = "chmod 775 $tarfilename \>\/dev\/null 2\>\&1";
3136 $returnvalue = system($localcall);
3139 #########################################################
3140 # Shuffle an array (Fisher Yates shuffle)
3141 #########################################################
3143 sub shuffle_array
3145 my ( $arrayref ) = @_;
3147 # my $counter = 0;
3148 # my $infoline = "Old package order: \n";
3149 # push( @installer::globals::logfileinfo, $infoline);
3150 # foreach my $onepackage ( @{$arrayref} )
3152 # $counter++;
3153 # $infoline = "$counter: $onepackage->{'module'}\n";
3154 # push( @installer::globals::logfileinfo, $infoline);
3157 my $i = @$arrayref;
3158 while (--$i)
3160 my $j = int rand ($i+1);
3161 @$arrayref[$i,$j] = @$arrayref[$j,$i];
3164 # $counter = 0;
3165 # $infoline = "New package order: \n";
3166 # push( @installer::globals::logfileinfo, $infoline);
3167 # foreach my $onepackage ( @{$arrayref} )
3169 # $counter++;
3170 # $infoline = "$counter: $onepackage->{'module'}\n";
3171 # push( @installer::globals::logfileinfo, $infoline);
3175 ################################################
3176 # Defining the English license text to add
3177 # it into Solaris packages.
3178 ################################################
3180 sub set_english_license
3182 my $additional_license_name = $installer::globals::englishsolarislicensename; # always the English file
3183 my $licensefileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$additional_license_name, "" , 0);
3184 if ( $$licensefileref eq "" ) { installer::exiter::exit_program("ERROR: Could not find license file $additional_license_name!", "set_english_license"); }
3185 $installer::globals::englishlicenseset = 1;
3186 $installer::globals::englishlicense = installer::files::read_file($$licensefileref);
3187 installer::scpzipfiles::replace_all_ziplistvariables_in_file($installer::globals::englishlicense, $variableshashref);
3190 ##############################################
3191 # Setting time stamp of copied files to avoid
3192 # errors from pkgchk.
3193 ##############################################
3195 sub set_time_stamp_for_file
3197 my ($sourcefile, $destfile) = @_;
3199 my $systemcall = "touch -r $sourcefile $destfile";
3201 my $returnvalue = system($systemcall);
3203 my $infoline = "Systemcall: $systemcall\n";
3204 push( @installer::globals::logfileinfo, $infoline);
3206 if ($returnvalue)
3208 $infoline = "ERROR: \"$systemcall\" failed!\n";
3209 push( @installer::globals::logfileinfo, $infoline);
3211 else
3213 $infoline = "Success: \"$systemcall\" !\n";
3214 push( @installer::globals::logfileinfo, $infoline);
3218 ##############################################
3219 # Setting checksum and wordcount for changed
3220 # pkginfo file into pkgmap.
3221 ##############################################
3223 sub change_onefile_in_pkgmap
3225 my ($pkgmapfile, $fullfilename, $shortfilename) = @_;
3227 # 1 i pkginfo 442 34577 1166716297
3228 # ->
3229 # 1 i pkginfo 443 34737 1166716297
3231 # wc -c pkginfo | cut -f6 -d' ' -> 442 (variable)
3232 # sum pkginfo | cut -f1 -d' ' -> 34577 (variable)
3233 # grep 'pkginfo' pkgmap | cut -f6 -d' ' -> 1166716297 (fix)
3235 my $checksum = call_sum($fullfilename);
3236 if ( $checksum =~ /^\s*(\d+)\s+.*$/ ) { $checksum = $1; }
3238 my $wordcount = call_wc($fullfilename);
3239 if ( $wordcount =~ /^\s*(\d+)\s+.*$/ ) { $wordcount = $1; }
3241 for ( my $i = 0; $i <= $#{$pkgmapfile}; $i++ )
3243 if ( ${$pkgmapfile}[$i] =~ /(^.*\b\Q$shortfilename\E\b\s+)(\d+)(\s+)(\d+)(\s+)(\d+)(\s*$)/ )
3245 my $newline = $1 . $wordcount . $3 . $checksum . $5 . $6 . $7;
3246 ${$pkgmapfile}[$i] = $newline;
3247 last;
3252 ################################################
3253 # Adding the content of the English license
3254 # file into the system integration packages.
3255 ################################################
3257 sub add_license_into_systemintegrationpackages
3259 my ($destdir, $packages) = @_;
3261 for ( my $i = 0; $i <= $#{$packages}; $i++ )
3263 my $copyrightfilename = ${$packages}[$i] . $installer::globals::separator . "install" . $installer::globals::separator . "copyright";
3264 if ( ! -f $copyrightfilename ) { installer::exiter::exit_program("ERROR: Could not find license file in system integration package: $copyrightfilename!", "add_license_into_systemintegrationpackages"); }
3265 my $copyrightfile = installer::files::read_file($copyrightfilename);
3267 # Saving time stamp of old copyrightfile
3268 my $savcopyrightfilename = $copyrightfilename . ".sav";
3269 installer::systemactions::copy_one_file($copyrightfilename, $savcopyrightfilename);
3270 set_time_stamp_for_file($copyrightfilename, $savcopyrightfilename); # now $savcopyrightfile has the time stamp of $copyrightfile
3272 # Adding license content to copyright file
3273 push(@{$copyrightfile}, "\n");
3274 for ( my $i = 0; $i <= $#{$installer::globals::englishlicense}; $i++ ) { push(@{$copyrightfile}, ${$installer::globals::englishlicense}[$i]); }
3275 installer::files::save_file($copyrightfilename, $copyrightfile);
3277 # Setting the old time stamp saved with $savcopyrightfilename
3278 set_time_stamp_for_file($savcopyrightfilename, $copyrightfilename); # now $copyrightfile has the time stamp of $savcopyrightfile
3279 unlink($savcopyrightfilename);
3281 # Changing content of copyright file in pkgmap
3282 my $pkgmapfilename = ${$packages}[$i] . $installer::globals::separator . "pkgmap";
3283 if ( ! -f $pkgmapfilename ) { installer::exiter::exit_program("ERROR: Could not find pkgmap in system integration package: $pkgmapfilename!", "add_license_into_systemintegrationpackages"); }
3284 my $pkgmap = installer::files::read_file($pkgmapfilename);
3285 change_onefile_in_pkgmap($pkgmap, $copyrightfilename, "copyright");
3286 installer::files::save_file($pkgmapfilename, $pkgmap);
3290 #########################################################
3291 # Collecting all pkgmap files from an installation set
3292 #########################################################
3294 sub collectpackagemaps
3296 my ( $installdir, $languagestringref, $allvariables ) = @_;
3298 installer::logger::include_header_into_logfile("Collecing all packagemaps (pkgmap):");
3300 my $pkgmapdir = installer::systemactions::create_directories("pkgmap", $languagestringref);
3301 my $subdirname = $allvariables->{'UNIXPRODUCTNAME'} . "_pkgmaps";
3302 my $pkgmapsubdir = $pkgmapdir . $installer::globals::separator . $subdirname;
3303 if ( -d $pkgmapsubdir ) { installer::systemactions::remove_complete_directory($pkgmapsubdir); }
3304 if ( ! -d $pkgmapsubdir ) { installer::systemactions::create_directory($pkgmapsubdir); }
3306 $installdir =~ s/\/\s*$//;
3307 # Collecting all packages in $installdir and its sub package ("packages")
3308 my $searchdir = $installdir . $installer::globals::separator . $installer::globals::epmoutpath;
3310 my $allpackages = installer::systemactions::get_all_directories_without_path($searchdir);
3312 for ( my $i = 0; $i <= $#{$allpackages}; $i++ )
3314 my $pkgmapfile = $searchdir . $installer::globals::separator . ${$allpackages}[$i] . $installer::globals::separator . "pkgmap";
3315 my $destfilename = $pkgmapsubdir . $installer::globals::separator . ${$allpackages}[$i] . "_pkgmap";
3316 installer::systemactions::copy_one_file($pkgmapfile, $destfilename);
3319 # Create a tar gz file with all package maps
3320 my $tarfilename = $subdirname . ".tar";
3321 my $targzname = $tarfilename . ".gz";
3322 # my $systemcall = "cd $pkgmapdir; tar -cf - $subdirname > $tarfilename";
3323 $systemcall = "cd $pkgmapdir; tar -cf - $subdirname | gzip > $targzname";
3324 make_systemcall($systemcall);
3325 installer::systemactions::remove_complete_directory($pkgmapsubdir, 1);