1#************************************************************************* 2# 3# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4# 5# Copyright 2000, 2010 Oracle and/or its affiliates. 6# 7# OpenOffice.org - a multi-platform office productivity suite 8# 9# This file is part of OpenOffice.org. 10# 11# OpenOffice.org is free software: you can redistribute it and/or modify 12# it under the terms of the GNU Lesser General Public License version 3 13# only, as published by the Free Software Foundation. 14# 15# OpenOffice.org is distributed in the hope that it will be useful, 16# but WITHOUT ANY WARRANTY; without even the implied warranty of 17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18# GNU Lesser General Public License version 3 for more details 19# (a copy is included in the LICENSE file that accompanied this code). 20# 21# You should have received a copy of the GNU Lesser General Public License 22# version 3 along with OpenOffice.org. If not, see 23# <http://www.openoffice.org/license.html> 24# for a copy of the LGPLv3 License. 25# 26#************************************************************************* 27 28package installer::worker; 29 30use Cwd; 31use File::Copy; 32use File::stat; 33use File::Temp qw(tmpnam); 34use installer::control; 35use installer::converter; 36use installer::existence; 37use installer::exiter; 38use installer::files; 39use installer::globals; 40use installer::logger; 41use installer::mail; 42use installer::pathanalyzer; 43use installer::scpzipfiles; 44use installer::scriptitems; 45use installer::sorter; 46use installer::systemactions; 47use installer::windows::language; 48 49##################################################################### 50# Unpacking all files ending with tar.gz in a specified directory 51##################################################################### 52 53sub unpack_all_targzfiles_in_directory 54{ 55 my ( $directory ) = @_; 56 57 installer::logger::include_header_into_logfile("Unpacking tar.gz files:"); 58 59 installer::logger::print_message( "... unpacking tar.gz files ... \n" ); 60 61 my $localdirectory = $directory . $installer::globals::separator . "packages"; 62 my $alltargzfiles = installer::systemactions::find_file_with_file_extension("tar.gz", $localdirectory); 63 64 for ( my $i = 0; $i <= $#{$alltargzfiles}; $i++ ) 65 { 66 my $onefile = $localdirectory . $installer::globals::separator . ${$alltargzfiles}[$i]; 67 68 my $systemcall = "cd $localdirectory; cat ${$alltargzfiles}[$i] \| gunzip \| tar -xf -"; 69 $returnvalue = system($systemcall); 70 71 my $infoline = "Systemcall: $systemcall\n"; 72 push( @installer::globals::logfileinfo, $infoline); 73 74 if ($returnvalue) 75 { 76 $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; 77 push( @installer::globals::logfileinfo, $infoline); 78 } 79 else 80 { 81 $infoline = "Success: Executed \"$systemcall\" successfully!\n"; 82 push( @installer::globals::logfileinfo, $infoline); 83 } 84 } 85} 86 87######################################### 88# Copying installation sets to ship 89######################################### 90 91sub copy_install_sets_to_ship 92{ 93 my ( $destdir, $shipinstalldir ) = @_; 94 95 installer::logger::include_header_into_logfile("Copying installation set to ship:"); 96 97 my $dirname = $destdir; 98 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$dirname); 99 $dirname = $dirname . "_inprogress"; 100 my $localshipinstalldir = $shipinstalldir . $installer::globals::separator . $dirname; 101 if ( ! -d $localshipinstalldir ) { installer::systemactions::create_directory_structure($localshipinstalldir); } 102 103 # copy installation set to /ship ($localshipinstalldir) 104 installer::logger::print_message( "... copy installation set from " . $destdir . " to " . $localshipinstalldir . "\n" ); 105 installer::systemactions::copy_complete_directory($destdir, $localshipinstalldir); 106 107 if (( ! $installer::globals::iswindowsbuild ) && ( $installer::globals::addjavainstaller )) 108 { 109 # Setting Unix rights for Java starter ("setup") 110 my $localcall = "chmod 775 $localshipinstalldir/setup \>\/dev\/null 2\>\&1"; 111 system($localcall); 112 } 113 114 # unpacking the tar.gz file for Solaris 115 if ( $installer::globals::issolarisbuild ) { unpack_all_targzfiles_in_directory($localshipinstalldir); } 116 117 $localshipinstalldir = installer::systemactions::rename_string_in_directory($localshipinstalldir, "_inprogress", ""); 118 119 return $localshipinstalldir; 120} 121 122######################################### 123# Copying installation sets to ship 124######################################### 125 126sub link_install_sets_to_ship 127{ 128 my ( $destdir, $shipinstalldir ) = @_; 129 130 installer::logger::include_header_into_logfile("Linking installation set to ship:"); 131 132 my $infoline = "... destination directory: $shipinstalldir ...\n"; 133 installer::logger::print_message( $infoline ); 134 push( @installer::globals::logfileinfo, $infoline); 135 136 if ( ! -d $shipinstalldir) 137 { 138 $infoline = "Creating directory: $shipinstalldir\n"; 139 push( @installer::globals::logfileinfo, $infoline); 140 installer::systemactions::create_directory_structure($shipinstalldir); 141 $infoline = "Created directory: $shipinstalldir\n"; 142 push( @installer::globals::logfileinfo, $infoline); 143 } 144 145 my $dirname = $destdir; 146 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$dirname); 147 148 my $localshipinstalldir = $shipinstalldir . $installer::globals::separator . $dirname; 149 150 # link installation set to /ship ($localshipinstalldir) 151 installer::logger::print_message( "... linking installation set from " . $destdir . " to " . $localshipinstalldir . "\n" ); 152 153 my $systemcall = "ln -s $destdir $localshipinstalldir"; 154 155 $returnvalue = system($systemcall); 156 157 $infoline = "Systemcall: $systemcall\n"; 158 push( @installer::globals::logfileinfo, $infoline); 159 160 if ($returnvalue) 161 { 162 $infoline = "ERROR: Could not create link \"$localshipinstalldir\"!\n"; 163 push( @installer::globals::logfileinfo, $infoline); 164 } 165 else 166 { 167 $infoline = "Success: Created link \"$localshipinstalldir\"!\n"; 168 push( @installer::globals::logfileinfo, $infoline); 169 } 170 171 return $localshipinstalldir; 172} 173 174######################################### 175# Create checksum file 176######################################### 177 178sub make_checksum_file 179{ 180 my ( $filesref, $includepatharrayref ) = @_; 181 182 my @checksum = (); 183 184 my $checksumfileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$installer::globals::checksumfile, $includepatharrayref, 1); 185 if ( $$checksumfileref eq "" ) { installer::exiter::exit_program("ERROR: Could not find file $installer::globals::checksumfile !", "make_checksum_file"); } 186 187# # very slow on Windows 188# for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 189# { 190# my $onefile = ${$filesref}[$i]; 191# my $systemcall = "$$checksumfileref $onefile->{'sourcepath'} |"; 192# open (CHECK, "$systemcall"); 193# my $localchecksum = <CHECK>; 194# close (CHECK); 195# push(@checksum, $localchecksum); 196# } 197 198 my $systemcall = "$$checksumfileref"; 199 200 for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 201 { 202 my $onefile = ${$filesref}[$i]; 203 $systemcall = $systemcall . " " . $onefile->{'sourcepath'}; # very very long systemcall 204 205 if ((( $i > 0 ) && ( $i%100 == 0 )) || ( $i == $#{$filesref} )) # limiting to 100 files 206 { 207 $systemcall = $systemcall . " \|"; 208 209 my @localchecksum = (); 210 open (CHECK, "$systemcall"); 211 @localchecksum = <CHECK>; 212 close (CHECK); 213 214 for ( my $j = 0; $j <= $#localchecksum; $j++ ) { push(@checksum, $localchecksum[$j]); } 215 216 $systemcall = "$$checksumfileref"; # reset the system call 217 } 218 } 219 220 return \@checksum; 221} 222 223######################################### 224# Saving the checksum file 225######################################### 226 227sub save_checksum_file 228{ 229 my ($current_install_number, $installchecksumdir, $checksumfile) = @_; 230 231 my $numberedchecksumfilename = $installer::globals::checksumfilename; 232 $numberedchecksumfilename =~ s/\./_$current_install_number\./; # checksum.txt -> checksum_01.txt 233 installer::files::save_file($installchecksumdir . $installer::globals::separator . $numberedchecksumfilename, $checksumfile); 234} 235 236################################################# 237# Writing some global information into 238# the list of files without flag PATCH 239################################################# 240 241sub write_nopatchlist_header 242{ 243 my ( $content ) = @_; 244 245 my @header = (); 246 my $infoline = "This is a list of files, that are defined in scp-projects without\n"; 247 push(@header, $infoline); 248 $infoline = "flag \"PATCH\". Important: This does not mean in any case, that \n"; 249 push(@header, $infoline); 250 $infoline = "this files are included into or excluded from a patch. \n\n"; 251 push(@header, $infoline); 252 $infoline = "Exception Linux: A patch rpm is a complete rpm. This means that all \n"; 253 push(@header, $infoline); 254 $infoline = "files are included into a patch rpm, if only one file of the rpm has the \n"; 255 push(@header, $infoline); 256 $infoline = "style \"PATCH\". \n\n"; 257 push(@header, $infoline); 258 259 for ( my $i = 0; $i <= $#header; $i++ ) { push(@{$content},$header[$i]); } 260} 261 262################################################# 263# Creating the content of the list of files 264# without flag PATCH. 265# All files are saved in 266# @{$installer::globals::nopatchfilecollector} 267################################################# 268 269sub create_nopatchlist 270{ 271 my @content =(); 272 273 write_nopatchlist_header(\@content); 274 275 for ( my $i = 0; $i <= $#{$installer::globals::nopatchfilecollector}; $i++ ) 276 { 277 my $onefile = ${$installer::globals::nopatchfilecollector}[$i]; 278 my $oneline = $onefile->{'destination'}; 279 if ( $onefile->{'zipfilename'} ) { $oneline = $oneline . " (" . $onefile->{'zipfilename'} . ")"; } 280 $oneline = $oneline . "\n"; 281 push(@content, $oneline); 282 } 283 284 return \@content; 285} 286 287######################################### 288# Saving the patchlist file 289######################################### 290 291sub save_patchlist_file 292{ 293 my ($installlogdir, $patchlistfilename) = @_; 294 295 my $installpatchlistdir = installer::systemactions::create_directory_next_to_directory($installlogdir, "patchlist"); 296 $patchlistfilename =~ s/log\_/patchfiles\_/; 297 $patchlistfilename =~ s/\.log/\.txt/; 298 installer::files::save_file($installpatchlistdir . $installer::globals::separator . $patchlistfilename, \@installer::globals::patchfilecollector); 299 installer::logger::print_message( "... creating patchlist file $patchlistfilename \n" ); 300 301 if (( $installer::globals::patch ) && ( ! $installer::globals::creating_windows_installer_patch )) # only for non-Windows patches 302 { 303 $patchlistfilename =~ s/patchfiles\_/nopatchfiles\_/; 304 my $nopatchlist = create_nopatchlist(); 305 installer::files::save_file($installpatchlistdir . $installer::globals::separator . $patchlistfilename, $nopatchlist); 306 installer::logger::print_message( "... creating patch exclusion file $patchlistfilename \n" ); 307 } 308 309} 310 311############################################################### 312# Removing all directories of a special language 313# in the directory $basedir 314############################################################### 315 316sub remove_old_installation_sets 317{ 318 my ($basedir) = @_; 319 320 installer::logger::print_message( "... removing old installation directories ...\n" ); 321 322 my $removedir = $basedir; 323 324 if ( -d $removedir ) { installer::systemactions::remove_complete_directory($removedir, 1); } 325 326 # looking for non successful old installation sets 327 328 $removedir = $basedir . "_witherror"; 329 if ( -d $removedir ) { installer::systemactions::remove_complete_directory($removedir, 1); } 330 331 $removedir = $basedir . "_inprogress"; 332 if ( -d $removedir ) { installer::systemactions::remove_complete_directory($removedir, 1); } 333 334 # finally the $basedir can be created empty 335 336 if ( $installer::globals::localinstalldirset ) { installer::systemactions::create_directory_structure($basedir); } 337 338 installer::systemactions::create_directory($basedir); 339} 340 341############################################################### 342# Removing all non successful installation sets on ship 343############################################################### 344 345sub remove_old_ship_installation_sets 346{ 347 my ($fulldir, $counter) = @_; 348 349 installer::logger::print_message( "... removing old installation directories ...\n" ); 350 351 my $basedir = $fulldir; 352 installer::pathanalyzer::get_path_from_fullqualifiedname(\$basedir); 353 354 # collecting all directories next to the new installation directory 355 my $alldirs = installer::systemactions::get_all_directories($basedir); 356 357 if ( $fulldir =~ /^\s*(.*?inprogress\-)(\d+)(.*?)\s*$/ ) 358 { 359 my $pre_inprogress = $1; # $pre still contains "inprogress" 360 my $number = $2; 361 my $post = $3; 362 my $pre_witherror = $pre_inprogress; 363 $pre_witherror =~ s/inprogress/witherror/; 364 365 for ( my $i = 0; $i <= $#{$alldirs}; $i++ ) 366 { 367 if ( ${$alldirs}[$i] eq $fulldir ) { next; } # do not delete the newly created directory 368 369 if ( ${$alldirs}[$i] =~ /^\s*\Q$pre_inprogress\E\d+\Q$post\E\s*$/ ) # removing old "inprogress" directories 370 { 371 installer::systemactions::remove_complete_directory(${$alldirs}[$i], 1); 372 } 373 374 if ( ${$alldirs}[$i] =~ /^\s*\Q$pre_witherror\E\d+\Q$post\E\s*$/ ) # removing old "witherror" directories 375 { 376 installer::systemactions::remove_complete_directory(${$alldirs}[$i], 1); 377 } 378 } 379 } 380} 381 382############################################################### 383# Creating the installation directory structure 384############################################################### 385 386sub create_installation_directory 387{ 388 my ($shipinstalldir, $languagestringref, $current_install_number_ref) = @_; 389 390 my $installdir = ""; 391 392 my $languageref = $languagestringref; 393 394 if ( $installer::globals::updatepack ) 395 { 396 $installdir = $shipinstalldir; 397 installer::systemactions::create_directory_structure($installdir); 398 $$current_install_number_ref = installer::systemactions::determine_maximum_number($installdir, $languageref); 399 $installdir = installer::systemactions::rename_string_in_directory($installdir, "number", $$current_install_number_ref); 400 remove_old_ship_installation_sets($installdir); 401 } 402 else 403 { 404 $installdir = installer::systemactions::create_directories("install", $languageref); 405 installer::logger::print_message( "... creating installation set in $installdir ...\n" ); 406 remove_old_installation_sets($installdir); 407 my $inprogressinstalldir = $installdir . "_inprogress"; 408 installer::systemactions::rename_directory($installdir, $inprogressinstalldir); 409 $installdir = $inprogressinstalldir; 410 } 411 412 $installer::globals::saveinstalldir = $installdir; # saving directory globally, in case of exiting 413 414 return $installdir; 415} 416 417############################################################### 418# Analyzing and creating the log file 419############################################################### 420 421sub analyze_and_save_logfile 422{ 423 my ($loggingdir, $installdir, $installlogdir, $allsettingsarrayref, $languagestringref, $current_install_number) = @_; 424 425 my $is_success = 1; 426 my $finalinstalldir = ""; 427 428 installer::logger::print_message( "... checking log file " . $loggingdir . $installer::globals::logfilename . "\n" ); 429 430 my $contains_error = installer::control::check_logfile(\@installer::globals::logfileinfo); 431 432 # Dependent from the success, the installation directory can be renamed and mails can be send. 433 434 if ( $contains_error ) 435 { 436 my $errordir = installer::systemactions::rename_string_in_directory($installdir, "_inprogress", "_witherror"); 437 if ( $installer::globals::updatepack ) { installer::mail::send_fail_mail($allsettingsarrayref, $languagestringref, $errordir); } 438 # Error output to STDERR 439 for ( my $j = 0; $j <= $#installer::globals::errorlogfileinfo; $j++ ) 440 { 441 my $line = $installer::globals::errorlogfileinfo[$j]; 442 $line =~ s/\s*$//g; 443 installer::logger::print_error( $line ); 444 } 445 $is_success = 0; 446 447 $finalinstalldir = $errordir; 448 } 449 else 450 { 451 my $destdir = ""; 452 453 if ( $installer::globals::updatepack ) 454 { 455 if ( $installdir =~ /_download_inprogress/ ) { $destdir = installer::systemactions::rename_string_in_directory($installdir, "_download_inprogress", "_download"); } 456 elsif ( $installdir =~ /_jds_inprogress/ ) { $destdir = installer::systemactions::rename_string_in_directory($installdir, "_jds_inprogress", "_jds"); } 457 elsif ( $installdir =~ /_msp_inprogress/ ) { $destdir = installer::systemactions::rename_string_in_directory($installdir, "_msp_inprogress", "_msp"); } 458 else 459 { 460 if ( $installdir =~ /_packed/ ) { $destdir = installer::systemactions::rename_string_in_directory($installdir, "_inprogress", ""); } 461 else { $destdir = installer::systemactions::rename_string_in_directory($installdir, "_inprogress", "_packed"); } 462 } 463 installer::mail::send_success_mail($allsettingsarrayref, $languagestringref, $destdir); 464 } 465 else 466 { 467 $destdir = installer::systemactions::rename_string_in_directory($installdir, "_inprogress", ""); 468 } 469 470 $finalinstalldir = $destdir; 471 } 472 473 # Saving the logfile in the log file directory and additionally in a log directory in the install directory 474 475 my $numberedlogfilename = $installer::globals::logfilename; 476 if ( $installer::globals::updatepack ) { $numberedlogfilename =~ s /log_/log_$current_install_number\_/; } 477 installer::logger::print_message( "... creating log file $numberedlogfilename \n" ); 478 installer::files::save_file($loggingdir . $numberedlogfilename, \@installer::globals::logfileinfo); 479 installer::files::save_file($installlogdir . $installer::globals::separator . $numberedlogfilename, \@installer::globals::logfileinfo); 480 481 # Saving the checksumfile in a checksum directory in the install directory 482 # installer::worker::save_checksum_file($current_install_number, $installchecksumdir, $checksumfile); 483 484 # Saving the list of patchfiles in a patchlist directory in the install directory 485 if (( $installer::globals::patch ) || ( $installer::globals::creating_windows_installer_patch )) { installer::worker::save_patchlist_file($installlogdir, $numberedlogfilename); } 486 487 if ( $installer::globals::creating_windows_installer_patch ) { $installer::globals::creating_windows_installer_patch = 0; } 488 489 # Exiting the packaging process, if an error occured. 490 # This is important, to get an error code "-1", if an error was found in the log file, 491 # that did not break the packaging process 492 493 if ( ! $is_success) { installer::exiter::exit_program("ERROR: Found an error in the logfile. Packaging failed.", "analyze_and_save_logfile"); } 494 495 return ($is_success, $finalinstalldir); 496} 497 498############################################################### 499# Analyzing and creating the log file 500############################################################### 501 502sub save_logfile_after_linking 503{ 504 my ($loggingdir, $installlogdir, $current_install_number) = @_; 505 506 # Saving the logfile in the log file directory and additionally in a log directory in the install directory 507 my $numberedlogfilename = $installer::globals::logfilename; 508 if ( $installer::globals::updatepack ) { $numberedlogfilename =~ s /log_/log_$current_install_number\_/; } 509 installer::logger::print_message( "... creating log file $numberedlogfilename \n" ); 510 installer::files::save_file($loggingdir . $numberedlogfilename, \@installer::globals::logfileinfo); 511 installer::files::save_file($installlogdir . $installer::globals::separator . $numberedlogfilename, \@installer::globals::logfileinfo); 512} 513 514############################################################### 515# Removing all directories that are saved in the 516# global directory @installer::globals::removedirs 517############################################################### 518 519sub clean_output_tree 520{ 521 installer::logger::print_message( "... cleaning the output tree ...\n" ); 522 523 for ( my $i = 0; $i <= $#installer::globals::removedirs; $i++ ) 524 { 525 if ( -d $installer::globals::removedirs[$i] ) 526 { 527 installer::logger::print_message( "... removing directory $installer::globals::removedirs[$i] ...\n" ); 528 installer::systemactions::remove_complete_directory($installer::globals::removedirs[$i], 1); 529 } 530 } 531 532 # Last try to remove the ship test directory 533 534 if ( $installer::globals::shiptestdirectory ) 535 { 536 if ( -d $installer::globals::shiptestdirectory ) 537 { 538 my $infoline = "Last try to remove $installer::globals::shiptestdirectory . \n"; 539 push(@installer::globals::logfileinfo, $infoline); 540 my $systemcall = "rmdir $installer::globals::shiptestdirectory"; 541 my $returnvalue = system($systemcall); 542 } 543 } 544} 545 546############################################################### 547# Removing all directories that are saved in the 548# global directory @installer::globals::jdsremovedirs 549############################################################### 550 551sub clean_jds_temp_dirs 552{ 553 installer::logger::print_message( "... cleaning jds directories ...\n" ); 554 555 for ( my $i = 0; $i <= $#installer::globals::jdsremovedirs; $i++ ) 556 { 557 if ( -d $installer::globals::jdsremovedirs[$i] ) 558 { 559 installer::logger::print_message( "... removing directory $installer::globals::jdsremovedirs[$i] ...\n" ); 560 installer::systemactions::remove_complete_directory($installer::globals::jdsremovedirs[$i], 1); 561 } 562 } 563} 564 565########################################################### 566# Copying a reference array 567########################################################### 568 569sub copy_array_from_references 570{ 571 my ( $arrayref ) = @_; 572 573 my @newarray = (); 574 575 for ( my $i = 0; $i <= $#{$arrayref}; $i++ ) 576 { 577 push(@newarray, ${$arrayref}[$i]); 578 } 579 580 return \@newarray; 581} 582 583########################################################### 584# Copying a reference hash 585########################################################### 586 587sub copy_hash_from_references 588{ 589 my ($hashref) = @_; 590 591 my %newhash = (); 592 my $key; 593 594 foreach $key (keys %{$hashref}) 595 { 596 $newhash{$key} = $hashref->{$key}; 597 } 598 599 return \%newhash; 600} 601 602########################################################### 603# Setting one language in the language independent 604# array of include pathes with $(LANG) 605########################################################### 606 607sub get_language_specific_include_pathes 608{ 609 my ( $patharrayref, $onelanguage ) = @_; 610 611 my @patharray = (); 612 613 for ( my $i = 0; $i <= $#{$patharrayref}; $i++ ) 614 { 615 my $line = ${$patharrayref}[$i]; 616 $line =~ s/\$\(LANG\)/$onelanguage/g; 617 push(@patharray ,$line); 618 } 619 620 return \@patharray; 621} 622 623############################################################## 624# Returning the first item with a defined flag 625############################################################## 626 627sub return_first_item_with_special_flag 628{ 629 my ($itemsref, $flag) = @_; 630 631 my $firstitem = ""; 632 633 for ( my $i = 0; $i <= $#{$itemsref}; $i++ ) 634 { 635 my $oneitem = ${$itemsref}[$i]; 636 my $styles = ""; 637 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'} }; 638 639 if ( $styles =~ /\b$flag\b/ ) 640 { 641 $firstitem = $oneitem; 642 last; 643 } 644 } 645 646 return $firstitem; 647} 648 649############################################################## 650# Collecting all items with a defined flag 651############################################################## 652 653sub collect_all_items_with_special_flag 654{ 655 my ($itemsref, $flag) = @_; 656 657 my @allitems = (); 658 659 for ( my $i = 0; $i <= $#{$itemsref}; $i++ ) 660 { 661 my $oneitem = ${$itemsref}[$i]; 662 my $styles = ""; 663 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'} }; 664 665 if ( $styles =~ /\b$flag\b/ ) 666 { 667 push( @allitems, $oneitem ); 668 } 669 } 670 671 return \@allitems; 672} 673 674############################################################## 675# Collecting all files without patch flag in 676# $installer::globals::nopatchfilecollector 677############################################################## 678 679sub collect_all_files_without_patch_flag 680{ 681 my ($filesref) = @_; 682 683 my $newfiles = collect_all_items_without_special_flag($filesref, "PATCH"); 684 685 for ( my $i = 0; $i <= $#{$newfiles}; $i++ ) { push(@{$installer::globals::nopatchfilecollector}, ${$newfiles}[$i]); } 686} 687 688############################################################## 689# Collecting all items without a defined flag 690############################################################## 691 692sub collect_all_items_without_special_flag 693{ 694 my ($itemsref, $flag) = @_; 695 696 my @allitems = (); 697 698 for ( my $i = 0; $i <= $#{$itemsref}; $i++ ) 699 { 700 my $oneitem = ${$itemsref}[$i]; 701 my $styles = ""; 702 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'} }; 703 704 if ( !( $styles =~ /\b$flag\b/ )) 705 { 706 push( @allitems, $oneitem ); 707 } 708 } 709 710 return \@allitems; 711} 712 713############################################################## 714# Removing all items with a defined flag from collector 715############################################################## 716 717sub remove_all_items_with_special_flag 718{ 719 my ($itemsref, $flag) = @_; 720 721 my @allitems = (); 722 723 for ( my $i = 0; $i <= $#{$itemsref}; $i++ ) 724 { 725 my $oneitem = ${$itemsref}[$i]; 726 my $styles = ""; 727 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'} }; 728 if ( $styles =~ /\b$flag\b/ ) 729 { 730 my $infoline = "Attention: Removing from collector: $oneitem->{'Name'} !\n"; 731 push( @installer::globals::logfileinfo, $infoline); 732 if ( $flag eq "BINARYTABLE_ONLY" ) { push(@installer::globals::binarytableonlyfiles, $oneitem); } 733 next; 734 } 735 push( @allitems, $oneitem ); 736 } 737 738 return \@allitems; 739} 740 741########################################################### 742# Mechanism for simple installation without packing 743########################################################### 744 745sub install_simple ($$$$$$) 746{ 747 my ($packagename, $languagestring, $directoriesarray, $filesarray, $linksarray, $unixlinksarray) = @_; 748 749 # locate GNU cp on the system 750 my $gnucp = 'cp'; 751 if ( $ENV{'GNUCOPY'} ) { $gnucp = $ENV{'GNUCOPY'}; } 752 my $copyopts = '-af'; 753 $copyopts = '-PpRf' unless ( $ENV{'GNUCOPY'} ); # if not gnucopy, assume POSIX copy 754 755 installer::logger::print_message( "... installing module $packagename ...\n" ); 756 757 my $destdir = $installer::globals::destdir; 758 my @lines = (); 759 760 installer::logger::print_message( "DestDir: $destdir \n" ); 761 installer::logger::print_message( "Rootpath: $installer::globals::rootpath \n" ); 762 763 `mkdir -p $destdir` if $destdir ne ""; 764 `mkdir -p $destdir$installer::globals::rootpath`; 765 766 # Create Directories 767 for ( my $i = 0; $i <= $#{$directoriesarray}; $i++ ) 768 { 769 my $onedir = ${$directoriesarray}[$i]; 770 my $dir = ""; 771 772 if ( $onedir->{'Dir'} ) { $dir = $onedir->{'Dir'}; } 773 774 if ((!($dir =~ /\bPREDEFINED_/ )) || ( $dir =~ /\bPREDEFINED_PROGDIR\b/ )) 775 { 776 # printf "mkdir $destdir$onedir->{'HostName'}\n"; 777 mkdir $destdir . $onedir->{'HostName'}; 778 push @lines, "%dir " . $onedir->{'HostName'} . "\n"; 779 } 780 } 781 782 for ( my $i = 0; $i <= $#{$filesarray}; $i++ ) 783 { 784 my $onefile = ${$filesarray}[$i]; 785 my $unixrights = $onefile->{'UnixRights'}; 786 my $destination = $onefile->{'destination'}; 787 my $sourcepath = $onefile->{'sourcepath'}; 788 789 # This is necessary to install SDK that includes files with $ in its name 790 # Otherwise, the following shell commands does not work and the file list 791 # is not correct 792 $destination =~ s/\$\$/\$/; 793 $sourcepath =~ s/\$\$/\$/; 794 795 push @lines, "$destination\n"; 796 # printf "cp $sourcepath $destdir$destination\n"; 797 copy ("$sourcepath", "$destdir$destination") || die "Can't copy file: $sourcepath -> $destdir$destination $!"; 798 my $sourcestat = stat($sourcepath); 799 utime ($sourcestat->atime, $sourcestat->mtime, "$destdir$destination"); 800 chmod (oct($unixrights), "$destdir$destination") || die "Can't change permissions: $!"; 801 push @lines, "$destination\n"; 802 } 803 804 for ( my $i = 0; $i <= $#{$linksarray}; $i++ ) 805 { 806 my $onelink = ${$linksarray}[$i]; 807 my $destination = $onelink->{'destination'}; 808 my $destinationfile = $onelink->{'destinationfile'}; 809 810 # print "link $destinationfile -> $destdir$destination\n"; 811 symlink ("$destinationfile", "$destdir$destination") || die "Can't create symlink: $!"; 812 push @lines, "$destination\n"; 813 } 814 815 for ( my $i = 0; $i <= $#{$unixlinksarray}; $i++ ) 816 { 817 my $onelink = ${$unixlinksarray}[$i]; 818 my $target = $onelink->{'Target'}; 819 my $destination = $onelink->{'destination'}; 820 821 # print "Unix link $target -> $destdir$destination\n"; 822 `ln -sf '$target' '$destdir$destination'`; 823 push @lines, "$destination\n"; 824 } 825 826 if ( $destdir ne "" ) 827 { 828 my $filelist; 829 my $fname = $installer::globals::destdir . "/$packagename"; 830 if ($installer::globals::languagepack) { $fname .= ".$languagestring"; } 831 open ($filelist, ">$fname") || die "Can't open $fname: $!"; 832 print $filelist @lines; 833 close ($filelist); 834 } 835 836} 837 838########################################################### 839# Adding shellnew files into files collector for 840# user installation 841########################################################### 842 843sub add_shellnewfile_into_filesarray 844{ 845 my ($filesref, $onefile, $inffile) = @_; 846 847 my %shellnewfile = (); 848 my $shellnewfileref = \%shellnewfile; 849 850 installer::converter::copy_item_object($inffile, $shellnewfileref); 851 852 $shellnewfileref->{'Name'} = $onefile->{'Name'}; 853 $shellnewfileref->{'sourcepath'} = $onefile->{'sourcepath'}; 854 $shellnewfileref->{'gid'} = $onefile->{'gid'} . "_Userinstall"; 855 856 # the destination has to be adapted 857 my $destination = $inffile->{'destination'}; 858 installer::pathanalyzer::get_path_from_fullqualifiedname(\$destination); 859 $destination = $destination . $onefile->{'Name'}; 860 $shellnewfileref->{'destination'} = $destination; 861 862 # add language specific inffile into filesarray 863 push(@{$filesref}, $shellnewfileref); 864} 865 866########################################################### 867# Replacing one placehoder in template file 868########################################################### 869 870sub replace_in_template_file 871{ 872 my ($templatefile, $placeholder, $newstring) = @_; 873 874 for ( my $i = 0; $i <= $#{$templatefile}; $i++ ) 875 { 876 ${$templatefile}[$i] =~ s/\Q$placeholder\E/$newstring/g; 877 } 878} 879 880########################################################### 881# Replacing one placehoder with an array in template file 882########################################################### 883 884sub replace_array_in_template_file 885{ 886 my ($templatefile, $placeholder, $arrayref) = @_; 887 888 for ( my $i = 0; $i <= $#{$templatefile}; $i++ ) 889 { 890 if ( ${$templatefile}[$i] =~ /\Q$placeholder\E/ ) 891 { 892 my @return = splice(@{$templatefile}, $i, 1, @{$arrayref}); 893 } 894 } 895} 896 897########################################################### 898# Collecting all modules from registry items 899########################################################### 900 901sub collect_all_modules 902{ 903 my ($registryitemsref) = @_; 904 905 my @allmodules = (); 906 907 for ( my $i = 0; $i <= $#{$registryitemsref}; $i++ ) 908 { 909 $registryitem = ${$registryitemsref}[$i]; 910 my $module = $registryitem->{'ModuleID'}; 911 912 if ( ! installer::existence::exists_in_array($module, \@allmodules) ) 913 { 914 push(@allmodules, $module); 915 } 916 } 917 918 return \@allmodules; 919} 920 921########################################################### 922# Changing the content of the inf file 923########################################################### 924 925sub write_content_into_inf_file 926{ 927 my ($templatefile, $filesref, $registryitemsref, $folderref, $folderitemsref, $modulesref, $onelanguage, $inffile, $firstlanguage, $allvariableshashref) = @_; 928 929 # First part: Shellnew files 930 # SHELLNEWFILESPLACEHOLDER 931 932 my $rootmodule = 0; 933 # inf files can be assigned to "gid_Module_Root_Files_2" 934 if ( $inffile->{'modules'} =~ /Module_Root/i ) { $rootmodule = 1; } 935 936 if ( $rootmodule ) 937 { 938 my $shellnewstring = ""; 939 940 for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 941 { 942 my $onefile = ${$filesref}[$i]; 943 my $directory = $onefile->{'Dir'}; 944 945 if ( $directory =~ /\bPREDEFINED_OSSHELLNEWDIR\b/ ) 946 { 947 $shellnewstring = $shellnewstring . $onefile->{'Name'} . "\n"; 948 if (( $firstlanguage ) && ( ! $installer::globals::shellnewfilesadded )) { add_shellnewfile_into_filesarray($filesref, $onefile, $inffile); } 949 } 950 } 951 952 $shellnewstring =~ s/\s*$//; 953 replace_in_template_file($templatefile, "SHELLNEWFILESPLACEHOLDER", $shellnewstring); 954 955 $installer::globals::shellnewfilesadded = 1; 956 } 957 958 # Second part: Start menu entries 959 960 # The OfficeMenuFolder is defined as: $productname . " " . $productversion; 961 962 my $productname = $allvariableshashref->{'PRODUCTNAME'}; 963 my $productversion = $allvariableshashref->{'PRODUCTVERSION'}; 964 my $productkey = $productname . " " . $productversion; 965 966 replace_in_template_file($templatefile, "OFFICEFOLDERPLACEHOLDER", $productkey); 967 968 # Setting name target and infotip for all applications 969 970 for ( my $i = 0; $i <= $#{$folderitemsref}; $i++ ) 971 { 972 my $folderitem = ${$folderitemsref}[$i]; 973 974 my $styles = ""; 975 if ( $folderitem->{'Styles'} ) { $styles = $folderitem->{'Styles'}; } 976 if ( $styles =~ /\bNON_ADVERTISED\b/ ) { next; } # no entry for non-advertised shortcuts 977 978 if (( ! $folderitem->{'ismultilingual'} ) || (( $folderitem->{'ismultilingual'} ) && ( $folderitem->{'specificlanguage'} eq $onelanguage ))) 979 { 980 my $gid = $folderitem->{'gid'}; 981 my $app = $gid; 982 $app =~ s/gid_Folderitem_//; 983 $app = uc($app); 984 985 my $name = $folderitem->{'Name'}; 986 my $placeholder = "PLACEHOLDER_FOLDERITEM_NAME_" . $app; 987 replace_in_template_file($templatefile, $placeholder, $name); 988 989 my $tooltip = $folderitem->{'Tooltip'}; 990 $placeholder = "PLACEHOLDER_FOLDERITEM_TOOLTIP_" . $app; 991 replace_in_template_file($templatefile, $placeholder, $tooltip); 992 993 my $executablegid = $folderitem->{'FileID'}; 994 my $exefile = installer::existence::get_specified_file($filesref, $executablegid); 995 my $exefilename = $exefile->{'Name'}; 996 $placeholder = "PLACEHOLDER_FOLDERITEM_TARGET_" . $app; 997 replace_in_template_file($templatefile, $placeholder, $exefilename); 998 } 999 } 1000 1001 # Third part: Windows registry entries 1002 1003 # collecting all modules 1004 1005 my $allmodules = collect_all_modules($registryitemsref); 1006 1007 my @registryitems = (); 1008 my $allsectionsstring = ""; 1009 1010 for ( my $j = 0; $j <= $#{$allmodules}; $j++ ) 1011 { 1012 my $moduleid = ${$allmodules}[$j]; 1013 1014 my $inffilemodule = $inffile->{'modules'}; 1015 # inf files can be assigned to "gid_Module_Root_Files_2", but RegistryItems to "gid_Module_Root" 1016 if ( $inffilemodule =~ /Module_Root/i ) { $inffilemodule = $installer::globals::rootmodulegid; } 1017 1018 if ( ! ( $moduleid eq $inffilemodule )) { next; } 1019 1020 my $shortmodulename = $moduleid; 1021 $shortmodulename =~ s/gid_Module_//; 1022 my $sectionname = "InstRegKeys." . $shortmodulename; 1023 $allsectionsstring = $allsectionsstring . $sectionname . ","; 1024 my $sectionheader = "\[" . $sectionname . "\]" . "\n"; 1025 push(@registryitems, $sectionheader); 1026 1027 for ( my $i = 0; $i <= $#{$registryitemsref}; $i++ ) 1028 { 1029 my $registryitem = ${$registryitemsref}[$i]; 1030 1031 if ( ! ( $registryitem->{'ModuleID'} eq $moduleid )) { next; } 1032 1033 if (( ! $registryitem->{'ismultilingual'} ) || (( $registryitem->{'ismultilingual'} ) && ( $registryitem->{'specificlanguage'} eq $onelanguage ))) 1034 { 1035 # Syntax: HKCR,".bau",,,"soffice.StarConfigFile.6" 1036 1037 my $regroot = ""; 1038 my $parentid = ""; 1039 if ( $registryitem->{'ParentID'} ) { $parentid = $registryitem->{'ParentID'}; } 1040 if ( $parentid eq "PREDEFINED_HKEY_CLASSES_ROOT" ) { $regroot = "HKCR"; } 1041 if ( $parentid eq "PREDEFINED_HKEY_LOCAL_MACHINE" ) { $regroot = "HKCU"; } 1042 1043 my $subkey = ""; 1044 if ( $registryitem->{'Subkey'} ) { $subkey = $registryitem->{'Subkey'}; } 1045 if ( $subkey ne "" ) { $subkey = "\"" . $subkey . "\""; } 1046 1047 my $valueentryname = ""; 1048 if ( $registryitem->{'Name'} ) { $valueentryname = $registryitem->{'Name'}; } 1049 if ( $valueentryname ne "" ) { $valueentryname = "\"" . $valueentryname . "\""; } 1050 1051 my $flag = ""; 1052 1053 my $value = ""; 1054 if ( $registryitem->{'Value'} ) { $value = $registryitem->{'Value'}; } 1055 if ( $value =~ /\<progpath\>/ ) { $value =~ s/\\\"/\"\"/g; } # Quoting for INF is done by double "" 1056 $value =~ s/\\\"/\"/g; # no more masquerading of '"' 1057 $value =~ s/\<progpath\>/\%INSTALLLOCATION\%/g; 1058 if ( $value ne "" ) { $value = "\"" . $value . "\""; } 1059 1060 my $oneline = $regroot . "," . $subkey . "," . $valueentryname . "," . $flag . "," . $value . "\n"; 1061 1062 push(@registryitems, $oneline); 1063 } 1064 } 1065 1066 push(@registryitems, "\n"); # empty line after each section 1067 } 1068 1069 # replacing the $allsectionsstring 1070 $allsectionsstring =~ s/\,\s*$//; 1071 replace_in_template_file($templatefile, "ALLREGISTRYSECTIONSPLACEHOLDER", $allsectionsstring); 1072 1073 # replacing the placeholder for all registry keys 1074 replace_array_in_template_file($templatefile, "REGISTRYKEYSPLACEHOLDER", \@registryitems); 1075 1076} 1077 1078########################################################### 1079# Creating inf files for local user system integration 1080########################################################### 1081 1082sub create_inf_file 1083{ 1084 my ($filesref, $registryitemsref, $folderref, $folderitemsref, $modulesref, $languagesarrayref, $languagestringref, $allvariableshashref) = @_; 1085 1086 # collecting all files with flag INFFILE 1087 1088 my $inf_files = collect_all_items_with_special_flag($filesref ,"INFFILE"); 1089 1090 if ( $#{$inf_files} > -1 ) 1091 { 1092 # create new language specific inffile 1093 installer::logger::include_header_into_logfile("Creating inf files:"); 1094 1095 my $infdirname = "inffiles"; 1096 my $infdir = installer::systemactions::create_directories($infdirname, $languagestringref); 1097 1098 my $infoline = "Number of inf files: $#{$inf_files} + 1 \n"; 1099 push( @installer::globals::logfileinfo, $infoline); 1100 1101 # there are inffiles for all modules 1102 1103 for ( my $i = 0; $i <= $#{$inf_files}; $i++ ) 1104 { 1105 my $inffile = ${$inf_files}[$i]; 1106 my $inf_file_name = $inffile->{'Name'}; 1107 1108 my $templatefilename = $inffile->{'sourcepath'}; 1109 1110 if ( ! -f $templatefilename ) { installer::exiter::exit_program("ERROR: Could not find file $templatefilename !", "create_inf_file"); } 1111 1112 # iterating over all languages 1113 1114 for ( my $j = 0; $j <= $#{$languagesarrayref}; $j++ ) # iterating over all languages 1115 { 1116 my $firstlanguage = 0; 1117 if ( $j == 0 ) { $firstlanguage = 1; } 1118 1119 my $onelanguage = ${$languagesarrayref}[$j]; 1120 1121 $infoline = "Templatefile: $inf_file_name, Language: $onelanguage \n"; 1122 push( @installer::globals::logfileinfo, $infoline); 1123 1124 my $templatefile = installer::files::read_file($templatefilename); 1125 1126 my $linesbefore = $#{$templatefile}; 1127 1128 write_content_into_inf_file($templatefile, $filesref, $registryitemsref, $folderref, $folderitemsref, $modulesref, $onelanguage, $inffile, $firstlanguage, $allvariableshashref); 1129 1130 $infoline = "Lines change: From $linesbefore to $#{$templatefile}.\n"; 1131 push( @installer::globals::logfileinfo, $infoline); 1132 1133 # rename language specific inffile 1134 my $language_inf_file_name = $inf_file_name; 1135 my $windowslanguage = installer::windows::language::get_windows_language($onelanguage); 1136 $language_inf_file_name =~ s/\.inf/_$windowslanguage\.inf/; 1137 1138 my $sourcepath = $infdir . $installer::globals::separator . $language_inf_file_name; 1139 installer::files::save_file($sourcepath, $templatefile); 1140 1141 $infoline = "Saving file: $sourcepath\n"; 1142 push( @installer::globals::logfileinfo, $infoline); 1143 1144 # creating new file object 1145 1146 my %languageinffile = (); 1147 my $languageinifileref = \%languageinffile; 1148 1149 if ( $j < $#{$languagesarrayref} ) { installer::converter::copy_item_object($inffile, $languageinifileref); } 1150 else { $languageinifileref = $inffile; } 1151 1152 $languageinifileref->{'Name'} = $language_inf_file_name; 1153 $languageinifileref->{'sourcepath'} = $sourcepath; 1154 # destination and gid also have to be adapted 1155 $languageinifileref->{'gid'} = $languageinifileref->{'gid'} . "_" . $onelanguage; 1156 my $destination = $languageinifileref->{'destination'}; 1157 installer::pathanalyzer::get_path_from_fullqualifiedname(\$destination); 1158 $destination = $destination . $language_inf_file_name; 1159 $languageinifileref->{'destination'} = $destination; 1160 1161 # add language specific inffile into filesarray 1162 if ( $j < $#{$languagesarrayref} ) { push(@{$filesref}, $languageinifileref); } 1163 } 1164 } 1165 } 1166} 1167 1168########################################################### 1169# Selecting patch items 1170########################################################### 1171 1172sub select_patch_items 1173{ 1174 my ( $itemsref, $itemname ) = @_; 1175 1176 installer::logger::include_header_into_logfile("Selecting items for patches. Item: $itemname"); 1177 1178 my @itemsarray = (); 1179 1180 for ( my $i = 0; $i <= $#{$itemsref}; $i++ ) 1181 { 1182 my $oneitem = ${$itemsref}[$i]; 1183 1184 my $name = $oneitem->{'Name'}; 1185 if (( $name =~ /\bLICENSE/ ) || ( $name =~ /\bREADME/ )) 1186 { 1187 push(@itemsarray, $oneitem); 1188 next; 1189 } 1190 1191 # Items with style "PATCH" have to be included into the patch 1192 my $styles = ""; 1193 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; } 1194 if ( $styles =~ /\bPATCH\b/ ) { push(@itemsarray, $oneitem); } 1195 } 1196 1197 return \@itemsarray; 1198} 1199 1200########################################################### 1201# Selecting patch items 1202########################################################### 1203 1204sub select_patch_items_without_name 1205{ 1206 my ( $itemsref, $itemname ) = @_; 1207 1208 installer::logger::include_header_into_logfile("Selecting RegistryItems for patches"); 1209 1210 my @itemsarray = (); 1211 1212 for ( my $i = 0; $i <= $#{$itemsref}; $i++ ) 1213 { 1214 my $oneitem = ${$itemsref}[$i]; 1215 1216 # Items with style "PATCH" have to be included into the patch 1217 my $styles = ""; 1218 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; } 1219 if ( $styles =~ /\bPATCH\b/ ) { push(@itemsarray, $oneitem); } 1220 } 1221 1222 return \@itemsarray; 1223} 1224 1225########################################################### 1226# Selecting patch items 1227########################################################### 1228 1229sub select_langpack_items 1230{ 1231 my ( $itemsref, $itemname ) = @_; 1232 1233 installer::logger::include_header_into_logfile("Selecting RegistryItems for Language Packs"); 1234 1235 my @itemsarray = (); 1236 1237 for ( my $i = 0; $i <= $#{$itemsref}; $i++ ) 1238 { 1239 my $oneitem = ${$itemsref}[$i]; 1240 1241 # Items with style "LANGUAGEPACK" have to be included into the patch 1242 my $styles = ""; 1243 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; } 1244 if (( $styles =~ /\bLANGUAGEPACK\b/ ) || ( $styles =~ /\bFORCELANGUAGEPACK\b/ )) { push(@itemsarray, $oneitem); } 1245 } 1246 1247 return \@itemsarray; 1248} 1249 1250########################################################### 1251# Searching if LICENSE and README, which are not removed 1252# in select_patch_items are really needed for the patch. 1253# If not, they are removed now. 1254########################################################### 1255 1256sub analyze_patch_files 1257{ 1258 my ( $filesref ) = @_; 1259 1260 installer::logger::include_header_into_logfile("Analyzing patch files"); 1261 1262 my @filesarray = (); 1263 1264 for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 1265 { 1266 my $onefile = ${$filesref}[$i]; 1267 my $styles = ""; 1268 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; } 1269 if ( !( $styles =~ /\bPATCH\b/) ) { next; } # removing all files without flag PATCH (LICENSE, README, ...) 1270 1271 if ( $installer::globals::iswindowsbuild ) 1272 { 1273 # all files of the Windows patch belong to the root module 1274 $onefile->{'modules'} = $installer::globals::rootmodulegid; 1275 } 1276 1277 push(@filesarray, $onefile); 1278 } 1279 1280 return \@filesarray; 1281} 1282 1283########################################################### 1284# Sorting an array 1285########################################################### 1286 1287sub sort_array 1288{ 1289 my ( $arrayref ) = @_; 1290 1291 for ( my $i = 0; $i <= $#{$arrayref}; $i++ ) 1292 { 1293 my $under = ${$arrayref}[$i]; 1294 1295 for ( my $j = $i + 1; $j <= $#{$arrayref}; $j++ ) 1296 { 1297 my $over = ${$arrayref}[$j]; 1298 1299 if ( $under gt $over) 1300 { 1301 ${$arrayref}[$i] = $over; 1302 ${$arrayref}[$j] = $under; 1303 $under = $over; 1304 } 1305 } 1306 } 1307} 1308 1309########################################################### 1310# Renaming linux files with flag LINUXLINK 1311########################################################### 1312 1313sub prepare_linuxlinkfiles 1314{ 1315 my ( $filesref ) = @_; 1316 1317 @installer::globals::linuxlinks = (); # empty this array, because it could be already used 1318 @installer::globals::linuxpatchfiles = (); # empty this array, because it could be already used 1319 @installer::globals::allfilessav = (); # empty this array, because it could be already used. Required for forced links 1320 1321 my @filesarray = (); 1322 1323 for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 1324 { 1325 my $onefile = ${$filesref}[$i]; 1326 my %linkfilehash = (); 1327 my $linkfile = \%linkfilehash; 1328 installer::converter::copy_item_object($onefile, $linkfile); 1329 1330 my $ispatchfile = 0; 1331 my $styles = ""; 1332 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; } 1333 if ( $styles =~ /\bPATCH\b/ ) { $ispatchfile = 1; } 1334 1335 # Collecting all files for the mechanism with forced links 1336 # Saving a copy 1337 my %copyfilehash = (); 1338 my $copyfile = \%copyfilehash; 1339 installer::converter::copy_item_object($onefile, $copyfile); 1340 push( @installer::globals::allfilessav, $copyfile); 1341 1342 my $original_destination = $onefile->{'destination'}; 1343 # $onefile->{'destination'} is used in the epm list file. This value can be changed now! 1344 1345 if ( $ispatchfile ) { $onefile->{'destination'} = $onefile->{'destination'} . "\.$installer::globals::linuxlibrarypatchlevel"; } 1346 else { $onefile->{'destination'} = $onefile->{'destination'} . "\.$installer::globals::linuxlibrarybaselevel"; } 1347 1348 my $infoline = "LINUXLINK: Changing file destination from $original_destination to $onefile->{'destination'} !\n"; 1349 push( @installer::globals::logfileinfo, $infoline); 1350 1351 # all files without PATCH flag are included into the RPM 1352 if ( ! $ispatchfile ) { push( @filesarray, $onefile); } 1353 else { push( @installer::globals::linuxpatchfiles, $onefile); } 1354 1355 # Preparing the collector for the links 1356 # Setting the new file name as destination of the link 1357 my $linkdestination = $linkfile->{'Name'}; 1358 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$linkdestination); 1359 if ( $ispatchfile ) { $linkfile->{'destinationfile'} = $linkdestination . "\.$installer::globals::linuxlibrarypatchlevel"; } 1360 else { $linkfile->{'destinationfile'} = $linkdestination . "\.$installer::globals::linuxlibrarybaselevel"; } 1361 push( @installer::globals::linuxlinks, $linkfile ); 1362 1363 $infoline = "LINUXLINK: Created link: $linkfile->{'destination'} pointing to $linkfile->{'destinationfile'} !\n"; 1364 push( @installer::globals::logfileinfo, $infoline); 1365 } 1366 1367 return \@filesarray; 1368} 1369 1370########################################################### 1371# Adding links into "u-RPMs", that have the flag 1372# FORCE_INTO_UPDATE_PACKAGE 1373# This is only relevant for Linux 1374########################################################### 1375 1376sub prepare_forced_linuxlinkfiles 1377{ 1378 my ( $linksref ) = @_; 1379 1380 my @linksarray = (); 1381 1382 for ( my $i = 0; $i <= $#{$linksref}; $i++ ) 1383 { 1384 my $onelink = ${$linksref}[$i]; 1385 1386 my $isforcedlink = 0; 1387 my $styles = ""; 1388 if ( $onelink->{'Styles'} ) { $styles = $onelink->{'Styles'}; } 1389 if ( $styles =~ /\bFORCE_INTO_UPDATE_PACKAGE\b/ ) { $isforcedlink = 1; } 1390 1391 if ( $isforcedlink ) 1392 { 1393 my $fileid = ""; 1394 1395 if ( $onelink->{'ShortcutID'} ) 1396 { 1397 $fileid = $onelink->{'ShortcutID'}; 1398 1399 my $searchedlinkfile = find_file_by_id($linksref, $fileid); 1400 1401 # making a copy! 1402 my %linkfilehash = (); 1403 my $linkfile = \%linkfilehash; 1404 installer::converter::copy_item_object($searchedlinkfile, $linkfile); 1405 1406 $linkfile->{'Name'} = $onelink->{'Name'}; 1407 $linkfile->{'destinationfile'} = $linkfile->{'destination'}; 1408 my $linkdestination = $linkfile->{'destinationfile'}; 1409 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$linkdestination); 1410 $linkfile->{'destinationfile'} = $linkdestination; 1411 1412 my $localdestination = $linkfile->{'destination'}; 1413 # Getting the path 1414 installer::pathanalyzer::get_path_from_fullqualifiedname(\$localdestination); 1415 $localdestination =~ s/\Q$installer::globals::separator\E\s*$//; 1416 $linkfile->{'destination'} = $localdestination . $installer::globals::separator . $onelink->{'Name'}; 1417 1418 $infoline = "Forced link into update file: $linkfile->{'destination'} pointing to $linkfile->{'destinationfile'} !\n"; 1419 push( @installer::globals::logfileinfo, $infoline); 1420 1421 # The file, defined by the link, has to be included into the 1422 # link array @installer::globals::linuxlinks 1423 push( @installer::globals::linuxlinks, $linkfile ); 1424 } 1425 1426 if ( $onelink->{'FileID'} ) 1427 { 1428 $fileid = $onelink->{'FileID'}; 1429 1430 my $searchedlinkfile = find_file_by_id(\@installer::globals::allfilessav, $fileid); 1431 1432 # making a copy! 1433 my %linkfilehash = (); 1434 my $linkfile = \%linkfilehash; 1435 installer::converter::copy_item_object($searchedlinkfile, $linkfile); 1436 1437 $linkfile->{'Name'} = $onelink->{'Name'}; 1438 $linkfile->{'destinationfile'} = $linkfile->{'destination'}; 1439 my $linkdestination = $linkfile->{'destinationfile'}; 1440 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$linkdestination); 1441 $linkfile->{'destinationfile'} = $linkdestination; 1442 1443 my $localdestination = $linkfile->{'destination'}; 1444 # Getting the path 1445 installer::pathanalyzer::get_path_from_fullqualifiedname(\$localdestination); 1446 $localdestination =~ s/\Q$installer::globals::separator\E\s*$//; 1447 $linkfile->{'destination'} = $localdestination . $installer::globals::separator . $onelink->{'Name'}; 1448 1449 $infoline = "Forced link into update file: $linkfile->{'destination'} pointing to $linkfile->{'destinationfile'} !\n"; 1450 push( @installer::globals::logfileinfo, $infoline); 1451 1452 # The file, defined by the link, has to be included into the 1453 # link array @installer::globals::linuxlinks 1454 push( @installer::globals::linuxlinks, $linkfile ); 1455 } 1456 1457 if ( $fileid eq "" ) { installer::exiter::exit_program("ERROR: No FileID assigned to forced link $onelink->{'gid'} !", "prepare_forced_linuxlinkfiles"); } 1458 1459 } 1460 else 1461 { 1462 # Links with flag FORCE_INTO_UPDATE_PACKAGE are forced into "u"-RPM. All other 1463 # links are included into the non-"u"-package. 1464 push( @linksarray, $onelink ); 1465 } 1466 } 1467 1468 return \@linksarray; 1469} 1470 1471########################################################### 1472# reorganizing the patchfile content, 1473# sorting for directory to decrease the file size 1474########################################################### 1475 1476sub reorg_patchfile 1477{ 1478 my ($patchfiles, $patchfiledirectories) = @_; 1479 1480 my @patchfilesarray = (); 1481 my $line = ""; 1482 my $directory = ""; 1483 1484 # iterating over all directories, writing content into new patchfiles list 1485 1486 for ( my $i = 0; $i <= $#{$patchfiledirectories}; $i++ ) 1487 { 1488 $directory = ${$patchfiledirectories}[$i]; 1489 $line = "[" . $directory . "]" . "\n"; 1490 push(@patchfilesarray, $line); 1491 1492 for ( my $j = 0; $j <= $#{$patchfiles}; $j++ ) 1493 { 1494 # "\tXXXXX\t" . $olddestination . "\n"; 1495 if ( ${$patchfiles}[$j] =~ /^\s*(.*?)\s*\tXXXXX\t\Q$directory\E\s*$/ ) 1496 { 1497 $line = $1 . "\n"; 1498 push(@patchfilesarray, $line); 1499 } 1500 } 1501 } 1502 1503 return \@patchfilesarray; 1504} 1505 1506########################################################### 1507# One special file has to be the last in patchfile.txt. 1508# Controlling this file, guarantees, that all files were 1509# patch correctly. Using version.ini makes it easy to 1510# control this by looking into the about box 1511# -> shifting one section to the end 1512########################################################### 1513 1514sub shift_section_to_end 1515{ 1516 my ($patchfilelist) = @_; 1517 1518 my @patchfile = (); 1519 my @lastsection = (); 1520 my $lastsection = "program"; 1521 my $notlastsection = "Basis\\program"; 1522 my $record = 0; 1523 1524 for ( my $i = 0; $i <= $#{$patchfilelist}; $i++ ) 1525 { 1526 my $line = ${$patchfilelist}[$i]; 1527 1528 if (( $record ) && ( $line =~ /^\s*\[/ )) { $record = 0; } 1529 1530 if (( $line =~ /^\s*\[\Q$lastsection\E\\\]\s*$/ ) && ( ! ( $line =~ /\Q$notlastsection\E\\\]\s*$/ ))) { $record = 1; } 1531 1532 if ( $record ) { push(@lastsection, $line); } 1533 else { push(@patchfile, $line); } 1534 } 1535 1536 if ( $#lastsection > -1 ) 1537 { 1538 for ( my $i = 0; $i <= $#lastsection; $i++ ) 1539 { 1540 push(@patchfile, $lastsection[$i]); 1541 } 1542 } 1543 1544 return \@patchfile; 1545} 1546 1547########################################################### 1548# One special file has to be the last in patchfile.txt. 1549# Controlling this file, guarantees, that all files were 1550# patch correctly. Using version.ini makes it easy to 1551# control this by looking into the about box 1552# -> shifting one file of the last section to the end 1553########################################################### 1554 1555sub shift_file_to_end 1556{ 1557 my ($patchfilelist) = @_; 1558 1559 my @patchfile = (); 1560 my $lastfilename = "version.ini"; 1561 my $lastfileline = ""; 1562 my $foundfile = 0; 1563 1564 # Only searching this file in the last section 1565 my $lastsectionname = ""; 1566 1567 for ( my $i = 0; $i <= $#{$patchfilelist}; $i++ ) 1568 { 1569 my $line = ${$patchfilelist}[$i]; 1570 if ( $line =~ /^\s*\[(.*?)\]\s*$/ ) { $lastsectionname = $1; } 1571 } 1572 1573 my $record = 0; 1574 for ( my $i = 0; $i <= $#{$patchfilelist}; $i++ ) 1575 { 1576 my $line = ${$patchfilelist}[$i]; 1577 1578 if ( $line =~ /^\s*\[\Q$lastsectionname\E\]\s*$/ ) { $record = 1; } 1579 1580 if (( $line =~ /^\s*\"\Q$lastfilename\E\"\=/ ) && ( $record )) 1581 { 1582 $lastfileline = $line; 1583 $foundfile = 1; 1584 $record = 0; 1585 next; 1586 } 1587 1588 push(@patchfile, $line); 1589 } 1590 1591 if ( $foundfile ) { push(@patchfile, $lastfileline); } 1592 1593 return \@patchfile; 1594} 1595 1596########################################################### 1597# Putting hash content into array and sorting it 1598########################################################### 1599 1600sub sort_hash 1601{ 1602 my ( $hashref ) = @_; 1603 1604 my $item = ""; 1605 my @sortedarray = (); 1606 1607 foreach $item (keys %{$hashref}) { push(@sortedarray, $item); } 1608 installer::sorter::sorting_array_of_strings(\@sortedarray); 1609 1610 return \@sortedarray; 1611} 1612 1613########################################################### 1614# Renaming Windows files in Patch and creating file 1615# patchfiles.txt 1616########################################################### 1617 1618sub prepare_windows_patchfiles 1619{ 1620 my ( $filesref, $languagestringref, $allvariableshashref ) = @_; 1621 1622 my @patchfiles = (); 1623 my %patchfiledirectories = (); 1624 my $patchfilename = "patchlist.txt"; 1625 my $patchfilename2 = "patchmsi.dll"; 1626 1627 if ( ! $allvariableshashref->{'WINDOWSPATCHLEVEL'} ) { installer::exiter::exit_program("ERROR: No Windows patch level defined in list file (WINDOWSPATCHLEVEL) !", "prepare_windows_patchfiles"); } 1628 # my $windowspatchlevel = $allvariableshashref->{'WINDOWSPATCHLEVEL'}; 1629 my $windowspatchlevel = $installer::globals::buildid; 1630 1631 # the environment variable CWS_WORK_STAMP is set only in CWS 1632 if ( $ENV{'CWS_WORK_STAMP'} ) { $windowspatchlevel = $ENV{'CWS_WORK_STAMP'} . $windowspatchlevel; } 1633 1634 for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 1635 { 1636 my $onefile = ${$filesref}[$i]; 1637 1638 my $filename = $onefile->{'Name'}; 1639 if (( $filename eq $patchfilename ) || ( $filename eq $patchfilename2 )) { next; } 1640 1641 my $styles = ""; 1642 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; } 1643 if ( $styles =~ /\bDONTRENAMEINPATCH\b/ ) { next; } 1644 1645 # special handling for files with flag DONTSHOW. This files get the extension ".dontshow" to be filtered by dialogs. 1646 my $localwindowspatchlevel = $windowspatchlevel; 1647 if ( $styles =~ /\bDONTSHOW\b/ ) { $localwindowspatchlevel = $localwindowspatchlevel . "\.dontshow"; } 1648 1649 my $olddestination = $onefile->{'destination'}; 1650 my $newdestination = $olddestination . "." . $localwindowspatchlevel; 1651 my $localfilename = $olddestination; 1652 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$localfilename); # file name part 1653 my $line = "\"" . $localfilename . "\"" . "=" . "\"" . "\." . $localwindowspatchlevel . "\""; 1654 $onefile->{'destination'} = $newdestination; 1655 1656 my $newfilename = $onefile->{'Name'} . "." . $localwindowspatchlevel; 1657 $onefile->{'Name'} = $newfilename; 1658 1659 # adding section information (section is the directory) 1660 my $origolddestination = $olddestination; 1661 installer::pathanalyzer::get_path_from_fullqualifiedname(\$olddestination); # directory part 1662 if ( ! $olddestination ) { $olddestination = "_root"; } 1663 if ( ! exists($patchfiledirectories{$olddestination}) ) { $patchfiledirectories{$olddestination} = 1; } 1664 $line = $line . "\tXXXXX\t" . $olddestination . "\n"; 1665 1666 push(@patchfiles, $line); 1667 1668 # also collecting all files from patch in @installer::globals::patchfilecollector 1669 my $patchfileline = $origolddestination . "\n"; 1670 push(@installer::globals::patchfilecollector, $patchfileline); 1671 } 1672 1673 my $winpatchdirname = "winpatch"; 1674 my $winpatchdir = installer::systemactions::create_directories($winpatchdirname, $languagestringref); 1675 1676 my $patchlistfile = installer::existence::get_specified_file_by_name($filesref, $patchfilename); 1677 1678 # reorganizing the patchfile content, sorting for directory to decrease the file size 1679 my $sorteddirectorylist = sort_hash(\%patchfiledirectories); 1680 my $patchfilelist = reorg_patchfile(\@patchfiles, $sorteddirectorylist); 1681 1682 # shifting version.ini to the end of the list, to guarantee, that all files are patched 1683 # if the correct version is shown in the about box 1684 $patchfilelist = shift_section_to_end($patchfilelist); 1685 $patchfilelist = shift_file_to_end($patchfilelist); 1686 1687 # saving the file 1688 $patchfilename = $winpatchdir . $installer::globals::separator . $patchfilename; 1689 installer::files::save_file($patchfilename, $patchfilelist); 1690 1691 my $infoline = "\nCreated list of patch files: $patchfilename\n"; 1692 push( @installer::globals::logfileinfo, $infoline); 1693 1694 # and assigning the new source 1695 $patchlistfile->{'sourcepath'} = $patchfilename; 1696 1697 # and finally checking the file size 1698 if ( -f $patchfilename ) # test of existence 1699 { 1700 my $filesize = ( -s $patchfilename ); 1701 $infoline = "Size of patch file list: $filesize\n\n"; 1702 push( @installer::globals::logfileinfo, $infoline); 1703 installer::logger::print_message( "... size of patch list file: $filesize Byte ... \n" ); 1704 1705 # Win 98: Maximum size of ini file is 65 kB 1706 # 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"); } 1707 } 1708 1709} 1710 1711########################################################### 1712# Replacing %-variables with the content 1713# of $allvariableshashref 1714########################################################### 1715 1716sub replace_variables_in_string 1717{ 1718 my ( $string, $variableshashref ) = @_; 1719 1720 if ( $string =~ /^.*\%\w+.*$/ ) 1721 { 1722 my $key; 1723 1724 foreach $key (keys %{$variableshashref}) 1725 { 1726 my $value = $variableshashref->{$key}; 1727 $key = "\%" . $key; 1728 $string =~ s/\Q$key\E/$value/g; 1729 } 1730 } 1731 1732 return $string; 1733} 1734 1735########################################################### 1736# Replacing %-variables with the content 1737# of $allvariableshashref 1738########################################################### 1739 1740sub replace_dollar_variables_in_string 1741{ 1742 my ( $string, $variableshashref ) = @_; 1743 1744 if ( $string =~ /^.*\$\{\w+\}.*$/ ) 1745 { 1746 my $key; 1747 1748 foreach $key (keys %{$variableshashref}) 1749 { 1750 my $value = $variableshashref->{$key}; 1751 $key = "\$\{" . $key . "\}"; 1752 $string =~ s/\Q$key\E/$value/g; 1753 } 1754 } 1755 1756 return $string; 1757} 1758 1759########################################################### 1760# The list file contains the list of packages/RPMs that 1761# have to be copied. 1762########################################################### 1763 1764sub get_all_files_from_filelist 1765{ 1766 my ( $listfile, $section ) = @_; 1767 1768 my @allpackages = (); 1769 1770 for ( my $i = 0; $i <= $#{$listfile}; $i++ ) 1771 { 1772 my $line = ${$listfile}[$i]; 1773 if ( $line =~ /^\s*\#/ ) { next; } # this is a comment line 1774 if ( $line =~ /^\s*$/ ) { next; } # empty line 1775 $line =~ s/^\s*//; 1776 $line =~ s/\s*$//; 1777 push(@allpackages, $line); 1778 } 1779 1780 return \@allpackages; 1781} 1782 1783########################################################### 1784# Getting one section from a file. Section begins with 1785# [xyz] and ends with file end or next [abc]. 1786########################################################### 1787 1788sub get_section_from_file 1789{ 1790 my ($file, $sectionname) = @_; 1791 1792 my @section = (); 1793 my $record = 0; 1794 1795 for ( my $i = 0; $i <= $#{$file}; $i++ ) 1796 { 1797 my $line = ${$file}[$i]; 1798 1799 if (( $record ) && ( $line =~ /^\s*\[/ )) 1800 { 1801 $record = 0; 1802 last; 1803 } 1804 1805 if ( $line =~ /^\s*\[\Q$sectionname\E\]\s*$/ ) { $record = 1; } 1806 1807 if ( $line =~ /^\s*\[/ ) { next; } # this is a section line 1808 if ( $line =~ /^\s*\#/ ) { next; } # this is a comment line 1809 if ( $line =~ /^\s*$/ ) { next; } # empty line 1810 $line =~ s/^\s*//; 1811 $line =~ s/\s*$//; 1812 if ( $record ) { push(@section, $line); } 1813 } 1814 1815 return \@section; 1816 1817} 1818 1819####################################################### 1820# Substituting one variable in the xml file 1821####################################################### 1822 1823sub replace_one_dollar_variable 1824{ 1825 my ($file, $variable, $searchstring) = @_; 1826 1827 for ( my $i = 0; $i <= $#{$file}; $i++ ) 1828 { 1829 ${$file}[$i] =~ s/\$\{$searchstring\}/$variable/g; 1830 } 1831} 1832 1833####################################################### 1834# Substituting the variables in the xml file 1835####################################################### 1836 1837sub substitute_dollar_variables 1838{ 1839 my ($file, $variableshashref) = @_; 1840 1841 my $key; 1842 1843 foreach $key (keys %{$variableshashref}) 1844 { 1845 my $value = $variableshashref->{$key}; 1846 replace_one_dollar_variable($file, $value, $key); 1847 } 1848} 1849 1850############################################################################# 1851# Collecting all packages or rpms located in the installation directory 1852############################################################################# 1853 1854sub get_all_packages_in_installdir 1855{ 1856 my ($directory) = @_; 1857 1858 my $infoline = ""; 1859 1860 my @allpackages = (); 1861 my $allpackages = \@allpackages; 1862 1863 if ( $installer::globals::islinuxrpmbuild ) 1864 { 1865 $allpackages = installer::systemactions::find_file_with_file_extension("rpm", $directory); 1866 } 1867 1868 if ( $installer::globals::issolarisbuild ) 1869 { 1870 $allpackages = installer::systemactions::get_all_directories($directory); 1871 } 1872 1873 return $allpackages; 1874} 1875 1876############################################################### 1877# The list of exclude packages can contain the 1878# beginning of the package name, not the complete name. 1879############################################################### 1880 1881sub is_matching 1882{ 1883 my ($onepackage, $allexcludepackages ) = @_; 1884 1885 my $matches = 0; 1886 1887 for ( my $i = 0; $i <= $#{$allexcludepackages}; $i++ ) 1888 { 1889 my $oneexcludepackage = ${$allexcludepackages}[$i]; 1890 1891 if ( $onepackage =~ /^\s*$oneexcludepackage/ ) 1892 { 1893 $matches = 1; 1894 last; 1895 } 1896 } 1897 1898 return $matches; 1899} 1900 1901############################################################### 1902# Copying all Solaris packages or RPMs from installation set 1903############################################################### 1904 1905sub copy_all_packages 1906{ 1907 my ($allexcludepackages, $sourcedir, $destdir) = @_; 1908 1909 my $infoline = ""; 1910 1911 $sourcedir =~ s/\/\s*$//; 1912 $destdir =~ s/\/\s*$//; 1913 1914 # $allexcludepackages is a list of RPMs and packages, that shall NOT be included into jds product 1915 my $allpackages = get_all_packages_in_installdir($sourcedir); 1916 1917 for ( my $i = 0; $i <= $#{$allpackages}; $i++ ) 1918 { 1919 my $onepackage = ${$allpackages}[$i]; 1920 1921 my $packagename = $onepackage; 1922 1923 if ( $installer::globals::issolarispkgbuild ) # on Solaris $onepackage contains the complete path 1924 { 1925 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$packagename); 1926 } 1927 1928 if ( ! installer::existence::exists_in_array($packagename, $allexcludepackages)) 1929 { 1930 if ( ! is_matching($packagename, $allexcludepackages ) ) 1931 { 1932 1933 if ( $installer::globals::islinuxrpmbuild ) 1934 { 1935 my $sourcepackage = $sourcedir . $installer::globals::separator . $packagename; 1936 my $destfile = $destdir . $installer::globals::separator . $packagename; 1937 if ( ! -f $sourcepackage ) { installer::exiter::exit_program("ERROR: Could not find RPM $sourcepackage!", "copy_all_packages"); } 1938 installer::systemactions::hardlink_one_file($sourcepackage, $destfile); 1939 } 1940 1941 if ( $installer::globals::issolarispkgbuild ) 1942 { 1943 my $destinationdir = $destdir . $installer::globals::separator . $packagename; 1944 if ( ! -d $onepackage ) { installer::exiter::exit_program("ERROR: Could not find Solaris package $onepackage!", "copy_all_packages"); } 1945 # installer::systemactions::hardlink_complete_directory($onepackage, $destinationdir); 1946 # installer::systemactions::copy_complete_directory($onepackage, $destinationdir); 1947 1948 my $systemcall = "cp -p -R $onepackage $destinationdir"; 1949 make_systemcall($systemcall); 1950 } 1951 } 1952 else 1953 { 1954 $infoline = "Excluding package (matching): $onepackage\n"; 1955 push( @installer::globals::logfileinfo, $infoline); 1956 } 1957 } 1958 else 1959 { 1960 $infoline = "Excluding package (precise name): $onepackage\n"; 1961 push( @installer::globals::logfileinfo, $infoline); 1962 } 1963 } 1964} 1965 1966###################################################### 1967# Making systemcall 1968###################################################### 1969 1970sub make_systemcall 1971{ 1972 my ($systemcall) = @_; 1973 1974 my $returnvalue = system($systemcall); 1975 1976 my $infoline = "Systemcall: $systemcall\n"; 1977 push( @installer::globals::logfileinfo, $infoline); 1978 1979 if ($returnvalue) 1980 { 1981 $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; 1982 push( @installer::globals::logfileinfo, $infoline); 1983 } 1984 else 1985 { 1986 $infoline = "Success: Executed \"$systemcall\" successfully!\n"; 1987 push( @installer::globals::logfileinfo, $infoline); 1988 } 1989} 1990 1991########################################################### 1992# Copying all Solaris packages or RPMs from solver 1993########################################################### 1994 1995sub copy_additional_packages 1996{ 1997 my ($allcopypackages, $destdir, $includepatharrayref) = @_; 1998 1999 my $infoline = "Copy additional packages into installation set.\n"; 2000 push( @installer::globals::logfileinfo, $infoline); 2001 2002 $destdir =~ s/\/\s*$//; 2003 2004 for ( my $i = 0; $i <= $#{$allcopypackages}; $i++ ) 2005 { 2006 my $onepackage = ${$allcopypackages}[$i]; 2007 $infoline = "Copy package: $onepackage\n"; 2008 push( @installer::globals::logfileinfo, $infoline); 2009 2010 # this package must be delivered into the solver 2011 2012 my $packagesourceref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$onepackage, $includepatharrayref, 0); 2013 if ($$packagesourceref eq "") { installer::exiter::exit_program("ERROR: Could not find jds file $onepackage!", "copy_additional_packages"); } 2014 2015 if ( $onepackage =~ /\.tar\.gz\s*$/ ) 2016 { 2017 my $systemcall = "cd $destdir; cat $$packagesourceref | gunzip | tar -xf -"; 2018 make_systemcall($systemcall); 2019 } 2020 else 2021 { 2022 my $destfile = $destdir . $installer::globals::separator . $onepackage; 2023 installer::systemactions::copy_one_file($$packagesourceref, $destfile); 2024 } 2025 } 2026} 2027 2028########################################################### 2029# Creating jds installation sets 2030########################################################### 2031 2032sub create_jds_sets 2033{ 2034 my ($installationdir, $allvariableshashref, $languagestringref, $languagesarrayref, $includepatharrayref) = @_; 2035 2036 installer::logger::print_message( "\n******************************************\n" ); 2037 installer::logger::print_message( "... creating jds installation set ...\n" ); 2038 installer::logger::print_message( "******************************************\n" ); 2039 2040 installer::logger::include_header_into_logfile("Creating jds installation sets:"); 2041 2042 my $firstdir = $installationdir; 2043 installer::pathanalyzer::get_path_from_fullqualifiedname(\$firstdir); 2044 2045 my $lastdir = $installationdir; 2046 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$lastdir); 2047 2048 if ( $lastdir =~ /\./ ) { $lastdir =~ s/\./_jds_inprogress\./ } 2049 else { $lastdir = $lastdir . "_jds_inprogress"; } 2050 2051 # removing existing directory "_native_packed_inprogress" and "_native_packed_witherror" and "_native_packed" 2052 2053 my $jdsdir = $firstdir . $lastdir; 2054 if ( -d $jdsdir ) { installer::systemactions::remove_complete_directory($jdsdir); } 2055 2056 my $olddir = $jdsdir; 2057 $olddir =~ s/_inprogress/_witherror/; 2058 if ( -d $olddir ) { installer::systemactions::remove_complete_directory($olddir); } 2059 2060 $olddir = $jdsdir; 2061 $olddir =~ s/_inprogress//; 2062 if ( -d $olddir ) { installer::systemactions::remove_complete_directory($olddir); } 2063 2064 # creating the new directory 2065 2066 installer::systemactions::create_directory($jdsdir); 2067 2068 $installer::globals::saveinstalldir = $jdsdir; 2069 2070 # find and read jds files list 2071 my $filelistname = $installer::globals::jdsexcludefilename; 2072 2073 my $filelistnameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filelistname, "", 0); 2074 if ($$filelistnameref eq "") { installer::exiter::exit_program("ERROR: Could not find jds list file $filelistname!", "create_jds_sets"); } 2075 2076 my $listfile = installer::files::read_file($$filelistnameref); 2077 2078 my $infoline = "Found jds list file: $$filelistnameref\n"; 2079 push( @installer::globals::logfileinfo, $infoline); 2080 2081 # substituting the variables 2082 substitute_dollar_variables($listfile, $allvariableshashref); 2083 2084 # determining the packages/RPMs to copy 2085 my $allexcludepackages = get_section_from_file($listfile, "excludefiles"); 2086 my $allcopypackages = get_section_from_file($listfile, "copyfiles"); 2087 2088 # determining the source directory 2089 my $alldirs = installer::systemactions::get_all_directories($installationdir); 2090 my $sourcedir = ${$alldirs}[0]; # there is only one directory 2091 2092 if ( $installer::globals::issolarisbuild ) { $sourcedir = $installer::globals::saved_packages_path; } 2093 2094 # copy all packages/RPMs 2095 copy_all_packages($allexcludepackages, $sourcedir, $jdsdir); 2096 copy_additional_packages($allcopypackages, $jdsdir, $includepatharrayref); 2097 2098 return $jdsdir; 2099} 2100 2101############################################################################# 2102# Checking, whether this installation set contains the correct languages 2103############################################################################# 2104 2105sub check_jds_language 2106{ 2107 my ($allvariableshashref, $languagestringref) = @_; 2108 2109 my $infoline = ""; 2110 2111 # languagesarrayref and $allvariableshashref->{'JDSLANG'} 2112 2113 if ( ! $allvariableshashref->{'JDSLANG'} ) { installer::exiter::exit_program("ERROR: For building JDS installation sets \"JDSLANG\" must be defined!", "check_jds_language"); } 2114 my $languagestring = $allvariableshashref->{'JDSLANG'}; 2115 2116 my $sortedarray1 = installer::converter::convert_stringlist_into_array(\$languagestring, ","); 2117 2118 installer::sorter::sorting_array_of_strings($sortedarray1); 2119 2120 my $sortedarray2 = installer::converter::convert_stringlist_into_array($languagestringref, "_"); 2121 installer::sorter::sorting_array_of_strings($sortedarray2); 2122 2123 my $string1 = installer::converter::convert_array_to_comma_separated_string($sortedarray1); 2124 my $string2 = installer::converter::convert_array_to_comma_separated_string($sortedarray2); 2125 2126 my $arrays_are_equal = compare_arrays($sortedarray1, $sortedarray2); 2127 2128 return $arrays_are_equal; 2129} 2130 2131################################################################################### 2132# Comparing two arrays. The arrays are equal, if the complete content is equal. 2133################################################################################### 2134 2135sub compare_arrays 2136{ 2137 my ($array1, $array2) = @_; 2138 2139 my $arrays_are_equal = 1; 2140 2141 # checking the size 2142 2143 if ( ! ( $#{$array1} == $#{$array2} )) { $arrays_are_equal = 0; } # different size 2144 2145 if ( $arrays_are_equal ) # only make further investigations if size is equal 2146 { 2147 for ( my $i = 0; $i <= $#{$array1}; $i++ ) 2148 { 2149 # ingnoring whitespaces at end and beginning 2150 ${$array1}[$i] =~ s/^\s*//; 2151 ${$array2}[$i] =~ s/^\s*//; 2152 ${$array1}[$i] =~ s/\s*$//; 2153 ${$array2}[$i] =~ s/\s*$//; 2154 2155 if ( ! ( ${$array1}[$i] eq ${$array2}[$i] )) 2156 { 2157 $arrays_are_equal = 0; 2158 last; 2159 } 2160 } 2161 } 2162 2163 return $arrays_are_equal; 2164} 2165 2166################################################################# 2167# Copying the files defined as ScpActions into the 2168# installation set. 2169################################################################# 2170 2171sub put_scpactions_into_installset 2172{ 2173 my ($installdir) = @_; 2174 2175 installer::logger::include_header_into_logfile("Start: Copying scp action files into installation set"); 2176 2177 for ( my $i = 0; $i <= $#installer::globals::allscpactions; $i++ ) 2178 { 2179 my $onescpaction = $installer::globals::allscpactions[$i]; 2180 2181 my $subdir = ""; 2182 if ( $onescpaction->{'Subdir'} ) { $subdir = $onescpaction->{'Subdir'}; } 2183 2184 if ( $onescpaction->{'Name'} eq "loader.exe" ) { next; } # do not copy this ScpAction loader 2185 2186 my $destdir = $installdir; 2187 $destdir =~ s/\Q$installer::globals::separator\E\s*$//; 2188 if ( $subdir ) { $destdir = $destdir . $installer::globals::separator . $subdir; } 2189 2190 my $sourcefile = $onescpaction->{'sourcepath'}; 2191 my $destfile = $destdir . $installer::globals::separator . $onescpaction->{'DestinationName'}; 2192 2193 my $styles = ""; 2194 if ( $onescpaction->{'Styles'} ) { $styles = $onescpaction->{'Styles'}; } 2195 if (( $styles =~ /\bFILE_CAN_MISS\b/ ) && ( $sourcefile eq "" )) { next; } 2196 2197 if (( $subdir =~ /\// ) || ( $subdir =~ /\\/ )) 2198 { 2199 installer::systemactions::create_directory_structure($destdir); 2200 } 2201 else 2202 { 2203 installer::systemactions::create_directory($destdir); 2204 } 2205 2206 installer::systemactions::copy_one_file($sourcefile, $destfile); 2207 2208 if ( $onescpaction->{'UnixRights'} ) 2209 { 2210 my $localcall = "chmod $onescpaction->{'UnixRights'} $destfile \>\/dev\/null 2\>\&1"; 2211 system($localcall); 2212 } 2213 2214 } 2215 2216 installer::logger::include_header_into_logfile("End: Copying scp action files into installation set"); 2217 2218} 2219 2220################################################################# 2221# Collecting scp actions for all languages 2222################################################################# 2223 2224sub collect_scpactions 2225{ 2226 my ($allscpactions) = @_; 2227 2228 for ( my $i = 0; $i <= $#{$allscpactions}; $i++ ) 2229 { 2230 push(@installer::globals::allscpactions, ${$allscpactions}[$i]); 2231 } 2232} 2233 2234################################################################# 2235# Setting the platform name for download 2236################################################################# 2237 2238sub get_platform_name 2239{ 2240 my $platformname = ""; 2241 2242 if (( $installer::globals::islinuxintelrpmbuild ) || ( $installer::globals::islinuxinteldebbuild )) 2243 { 2244 $platformname = "LinuxIntel"; 2245 } 2246 elsif (( $installer::globals::islinuxppcrpmbuild ) || ( $installer::globals::islinuxppcdebbuild )) 2247 { 2248 $platformname = "LinuxPowerPC"; 2249 } 2250 elsif (( $installer::globals::islinuxx86_64rpmbuild ) || ( $installer::globals::islinuxx86_64debbuild )) 2251 { 2252 $platformname = "LinuxX86-64"; 2253 } 2254 elsif ( $installer::globals::issolarissparcbuild ) 2255 { 2256 $platformname = "SolarisSparc"; 2257 } 2258 elsif ( $installer::globals::issolarisx86build ) 2259 { 2260 $platformname = "Solarisx86"; 2261 } 2262 elsif ( $installer::globals::iswindowsbuild ) 2263 { 2264 $platformname = "Win32Intel"; 2265 } 2266 elsif ( $installer::globals::compiler =~ /^unxmacxi/ ) 2267 { 2268 $platformname = "MacOSXIntel"; 2269 } 2270 elsif ( $installer::globals::compiler =~ /^unxmacxp/ ) 2271 { 2272 $platformname = "MacOSXPowerPC"; 2273 } 2274 else 2275 { 2276 # $platformname = $installer::globals::packageformat; 2277 $platformname = $installer::globals::compiler; 2278 } 2279 2280 return $platformname; 2281} 2282 2283########################################################### 2284# Adding additional variables into the variableshashref, 2285# that are defined in include files in the solver. The 2286# names of the include files are stored in 2287# ADD_INCLUDE_FILES (comma separated list). 2288########################################################### 2289 2290sub add_variables_from_inc_to_hashref 2291{ 2292 my ($allvariables, $includepatharrayref) = @_; 2293 2294 my $infoline = ""; 2295 my $includefilelist = ""; 2296 if ( $allvariables->{'ADD_INCLUDE_FILES'} ) { $includefilelist = $allvariables->{'ADD_INCLUDE_FILES'}; } 2297 2298 my $includefiles = installer::converter::convert_stringlist_into_array_without_linebreak_and_quotes(\$includefilelist, ","); 2299 2300 for ( my $i = 0; $i <= $#{$includefiles}; $i++ ) 2301 { 2302 my $includefilename = ${$includefiles}[$i]; 2303 $includefilename =~ s/^\s*//; 2304 $includefilename =~ s/\s*$//; 2305 $includefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$includefilename, $includepatharrayref, 1); 2306 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"); } 2307 2308 $infoline = "Including inc file: $$includefilenameref \n"; 2309 push( @installer::globals::globallogfileinfo, $infoline); 2310 2311 my $includefile = installer::files::read_file($$includefilenameref); 2312 2313 for ( my $j = 0; $j <= $#{$includefile}; $j++ ) 2314 { 2315 # Analyzing all "key=value" lines 2316 my $oneline = ${$includefile}[$j]; 2317 2318 if ( $oneline =~ /^\s*(\S+)\s*\=\s*(.*?)\s*$/ ) # no white space allowed in key 2319 { 2320 my $key = $1; 2321 my $value = $2; 2322 $allvariables->{$key} = $value; 2323 $infoline = "Setting of variable: $key = $value\n"; 2324 push( @installer::globals::globallogfileinfo, $infoline); 2325 } 2326 } 2327 } 2328 2329 # Allowing different Java versions for Windows and Unix. Instead of "JAVAVERSION" 2330 # the property "WINDOWSJAVAVERSION" has to be used, if it is set. 2331 2332 if ( $installer::globals::iswindowsbuild ) 2333 { 2334 if (( exists($allvariables->{'WINDOWSJAVAVERSION'})) && ( $allvariables->{'WINDOWSJAVAVERSION'} ne "" )) 2335 { 2336 $allvariables->{'JAVAVERSION'} = $allvariables->{'WINDOWSJAVAVERSION'}; 2337 $infoline = "Changing value of property \"JAVAVERSION\" to $allvariables->{'JAVAVERSION'} (property \"WINDOWSJAVAVERSION\").\n"; 2338 push( @installer::globals::globallogfileinfo, $infoline); 2339 } 2340 } 2341} 2342 2343############################################## 2344# Collecting all files from include pathes 2345############################################## 2346 2347sub collect_all_files_from_includepathes 2348{ 2349 my ($patharrayref) = @_; 2350 2351 installer::logger::globallog("Reading all directories: Start"); 2352 installer::logger::print_message( "... reading include pathes ...\n" ); 2353 # empty the global 2354 2355 @installer::globals::allincludepathes =(); 2356 my $infoline; 2357 2358 for ( my $i = 0; $i <= $#{$patharrayref}; $i++ ) 2359 { 2360 $includepath = ${$patharrayref}[$i]; 2361 installer::remover::remove_leading_and_ending_whitespaces(\$includepath); 2362 2363 if ( ! -d $includepath ) 2364 { 2365 $infoline = "$includepath does not exist. (Can be removed from include path list?)\n"; 2366 push( @installer::globals::globallogfileinfo, $infoline); 2367 next; 2368 } 2369 2370 my @sourcefiles = (); 2371 my $pathstring = ""; 2372 # installer::systemactions::read_complete_directory($includepath, $pathstring, \@sourcefiles); 2373 installer::systemactions::read_full_directory($includepath, $pathstring, \@sourcefiles); 2374 2375 if ( ! ( $#sourcefiles > -1 )) 2376 { 2377 $infoline = "$includepath is empty. (Can be removed from include path list?)\n"; 2378 push( @installer::globals::globallogfileinfo, $infoline); 2379 } 2380 else 2381 { 2382 my $number = $#sourcefiles + 1; 2383 $infoline = "Directory $includepath contains $number files (including subdirs)\n"; 2384 push( @installer::globals::globallogfileinfo, $infoline); 2385 2386 my %allfileshash = (); 2387 $allfileshash{'includepath'} = $includepath; 2388 2389 for ( my $j = 0; $j <= $#sourcefiles; $j++ ) 2390 { 2391 $allfileshash{$sourcefiles[$j]} = 1; 2392 } 2393 2394 push(@installer::globals::allincludepathes, \%allfileshash); 2395 } 2396 } 2397 2398 $installer::globals::include_pathes_read = 1; 2399 2400 installer::logger::globallog("Reading all directories: End"); 2401 push( @installer::globals::globallogfileinfo, "\n"); 2402} 2403 2404############################################## 2405# Searching for a file with the gid 2406############################################## 2407 2408sub find_file_by_id 2409{ 2410 my ( $filesref, $gid ) = @_; 2411 2412 my $foundfile = 0; 2413 my $onefile; 2414 2415 for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 2416 { 2417 $onefile = ${$filesref}[$i]; 2418 my $filegid = $onefile->{'gid'}; 2419 2420 if ( $filegid eq $gid ) 2421 { 2422 $foundfile = 1; 2423 last; 2424 } 2425 } 2426 2427 # It does not need to exist. For example products that do not contain the libraries. 2428 # if (! $foundfile ) { installer::exiter::exit_program("ERROR: No unique file name found for $filename !", "get_selfreg_file"); } 2429 2430 if (! $foundfile ) { $onefile = ""; } 2431 2432 return $onefile; 2433} 2434 2435############################################## 2436# Searching for an item with the gid 2437############################################## 2438 2439sub find_item_by_gid 2440{ 2441 my ( $itemsref, $gid ) = @_; 2442 2443 my $founditem = 0; 2444 my $oneitem = ""; 2445 2446 for ( my $i = 0; $i <= $#{$itemsref}; $i++ ) 2447 { 2448 my $localitem = ${$itemsref}[$i]; 2449 my $itemgid = $localitem->{'gid'}; 2450 2451 if ( $itemgid eq $gid ) 2452 { 2453 $oneitem = $localitem; 2454 $founditem = 1; 2455 last; 2456 } 2457 } 2458 2459 return $oneitem; 2460} 2461 2462######################################################### 2463# Calling sum 2464######################################################### 2465 2466sub call_sum 2467{ 2468 my ($filename) = @_; 2469 2470 $sumfile = "/usr/bin/sum"; 2471 2472 if ( ! -f $sumfile ) { installer::exiter::exit_program("ERROR: No file /usr/bin/sum", "call_sum"); } 2473 2474 my $systemcall = "$sumfile $filename |"; 2475 2476 my $sumoutput = ""; 2477 2478 open (SUM, "$systemcall"); 2479 $sumoutput = <SUM>; 2480 close (SUM); 2481 2482 my $returnvalue = $?; # $? contains the return value of the systemcall 2483 2484 my $infoline = "Systemcall: $systemcall\n"; 2485 push( @installer::globals::logfileinfo, $infoline); 2486 2487 if ($returnvalue) 2488 { 2489 $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; 2490 push( @installer::globals::logfileinfo, $infoline); 2491 } 2492 else 2493 { 2494 $infoline = "Success: Executed \"$systemcall\" successfully!\n"; 2495 push( @installer::globals::logfileinfo, $infoline); 2496 } 2497 2498 return $sumoutput; 2499} 2500 2501######################################################### 2502# Calling wc 2503# wc -c pkginfo | cut -f6 -d' ' 2504######################################################### 2505 2506sub call_wc 2507{ 2508 my ($filename) = @_; 2509 2510 $wcfile = "/usr/bin/wc"; 2511 2512 if ( ! -f $wcfile ) { installer::exiter::exit_program("ERROR: No file /usr/bin/wc", "call_wc"); } 2513 2514 my $systemcall = "$wcfile -c $filename |"; 2515 2516 my $wcoutput = ""; 2517 2518 open (WC, "$systemcall"); 2519 $wcoutput = <WC>; 2520 close (WC); 2521 2522 my $returnvalue = $?; # $? contains the return value of the systemcall 2523 2524 my $infoline = "Systemcall: $systemcall\n"; 2525 push( @installer::globals::logfileinfo, $infoline); 2526 2527 if ($returnvalue) 2528 { 2529 $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; 2530 push( @installer::globals::logfileinfo, $infoline); 2531 } 2532 else 2533 { 2534 $infoline = "Success: Executed \"$systemcall\" successfully!\n"; 2535 push( @installer::globals::logfileinfo, $infoline); 2536 } 2537 2538 return $wcoutput; 2539} 2540 2541############################################## 2542# Setting architecture ARCH=i86pc 2543# instead of ARCH=i386. 2544############################################## 2545 2546sub set_old_architecture_string 2547{ 2548 my ($pkginfofile) = @_; 2549 2550 for ( my $i = 0; $i <= $#{$pkginfofile}; $i++ ) 2551 { 2552 if ( ${$pkginfofile}[$i] =~ /^\s*ARCH=i386\s*$/ ) 2553 { 2554 ${$pkginfofile}[$i] =~ s/i386/i86pc/; 2555 last; 2556 } 2557 } 2558} 2559 2560############################################## 2561# For the new copied package, it is necessary 2562# that a value for the key SUNW_REQUIRES 2563# is set. Otherwise this copied package 2564# with ARCH=i86pc would be useless. 2565############################################## 2566 2567sub check_requires_setting 2568{ 2569 my ($pkginfofile) = @_; 2570 2571 my $found = 0; 2572 my $patchid = ""; 2573 2574 for ( my $i = 0; $i <= $#{$pkginfofile}; $i++ ) 2575 { 2576 if ( ${$pkginfofile}[$i] =~ /^\s*SUNW_REQUIRES=(\S*?)\s*$/ ) 2577 { 2578 $patchid = $1; 2579 $found = 1; 2580 last; 2581 } 2582 } 2583 2584 if (( ! $found ) || ( $patchid eq "" )) { installer::exiter::exit_program("ERROR: No patch id defined for SUNW_REQUIRES in patch pkginfo file!", "check_requires_setting"); } 2585} 2586 2587############################################## 2588# Setting checksum and wordcount for changed 2589# pkginfo file into pkgmap. 2590############################################## 2591 2592sub set_pkginfo_line 2593{ 2594 my ($pkgmapfile, $pkginfofilename) = @_; 2595 2596 # 1 i pkginfo 442 34577 1166716297 2597 # -> 2598 # 1 i pkginfo 443 34737 1166716297 2599 # 2600 # wc -c pkginfo | cut -f6 -d' ' -> 442 (variable) 2601 # sum pkginfo | cut -f1 -d' ' -> 34577 (variable) 2602 # grep 'pkginfo' pkgmap | cut -f6 -d' ' -> 1166716297 (fix) 2603 2604 my $checksum = call_sum($pkginfofilename); 2605 if ( $checksum =~ /^\s*(\d+)\s+.*$/ ) { $checksum = $1; } 2606 2607 my $wordcount = call_wc($pkginfofilename); 2608 if ( $wordcount =~ /^\s*(\d+)\s+.*$/ ) { $wordcount = $1; } 2609 2610 for ( my $i = 0; $i <= $#{$pkgmapfile}; $i++ ) 2611 { 2612 if ( ${$pkgmapfile}[$i] =~ /(^.*\bpkginfo\b\s+)(\d+)(\s+)(\d+)(\s+)(\d+)(\s*$)/ ) 2613 { 2614 my $newline = $1 . $wordcount . $3 . $checksum . $5 . $6 . $7; 2615 ${$pkgmapfile}[$i] = $newline; 2616 last; 2617 } 2618 } 2619} 2620 2621############################################## 2622# Setting time stamp of copied files to avoid 2623# errors from pkgchk. 2624############################################## 2625 2626sub set_time_stamp 2627{ 2628 my ($olddir, $newdir, $copyfiles) = @_; 2629 2630 for ( my $i = 0; $i <= $#{$copyfiles}; $i++ ) 2631 { 2632 my $sourcefile = $olddir . $installer::globals::separator . ${$copyfiles}[$i]; 2633 my $destfile = $newdir . $installer::globals::separator . ${$copyfiles}[$i]; 2634 2635 my $systemcall = "touch -r $sourcefile $destfile"; 2636 2637 my $returnvalue = system($systemcall); 2638 2639 my $infoline = "Systemcall: $systemcall\n"; 2640 push( @installer::globals::logfileinfo, $infoline); 2641 2642 if ($returnvalue) 2643 { 2644 $infoline = "ERROR: \"$systemcall\" failed!\n"; 2645 push( @installer::globals::logfileinfo, $infoline); 2646 } 2647 else 2648 { 2649 $infoline = "Success: \"$systemcall\" !\n"; 2650 push( @installer::globals::logfileinfo, $infoline); 2651 } 2652 } 2653} 2654 2655############################################################ 2656# Generating pathes for cygwin (first version) 2657# This function has problems with cygwin, if $tmpfilename 2658# contains many thousand files (OpenOffice SDK). 2659############################################################ 2660 2661sub generate_cygwin_pathes_old 2662{ 2663 my ($filesref) = @_; 2664 2665 my ($tmpfilehandle, $tmpfilename) = tmpnam(); 2666 open SOURCEPATHLIST, ">$tmpfilename" or die "oops...\n"; 2667 for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 2668 { 2669 print SOURCEPATHLIST "${$filesref}[$i]->{'sourcepath'}\n"; 2670 } 2671 close SOURCEPATHLIST; 2672 my @cyg_sourcepathlist = qx{cygpath -w -f "$tmpfilename"}; 2673 chomp @cyg_sourcepathlist; 2674 unlink "$tmpfilename" or die "oops\n"; 2675 for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 2676 { 2677 ${$filesref}[$i]->{'cyg_sourcepath'} = $cyg_sourcepathlist[$i]; 2678 } 2679 2680} 2681 2682################################################# 2683# Generating pathes for cygwin (second version) 2684# This function generates smaller files for 2685################################################# 2686 2687sub generate_cygwin_pathes 2688{ 2689 my ($filesref) = @_; 2690 2691 installer::logger::include_timestamp_into_logfile("Starting generating cygwin pathes"); 2692 2693 my $infoline = "Generating cygwin pathes (generate_cygwin_pathes)\n"; 2694 push( @installer::globals::logfileinfo, $infoline); 2695 2696 my $max = 5000; # number of pathes in one file 2697 2698 my @pathcollector = (); 2699 my $startnumber = 0; 2700 my $counter = 0; 2701 2702 for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 2703 { 2704 my $line = ${$filesref}[$i]->{'sourcepath'} . "\n"; 2705 push(@pathcollector, $line); 2706 $counter++; 2707 2708 if (( $i == $#{$filesref} ) || ((( $counter % $max ) == 0 ) && ( $i > 0 ))) 2709 { 2710 my $tmpfilename = "cygwinhelper_" . $i . ".txt"; 2711 my $temppath = $installer::globals::temppath; 2712 $temppath =~ s/\Q$installer::globals::separator\E\s*$//; 2713 $tmpfilename = $temppath . $installer::globals::separator . $tmpfilename; 2714 $infoline = "Creating temporary file for cygwin conversion: $tmpfilename (contains $counter pathes)\n"; 2715 push( @installer::globals::logfileinfo, $infoline); 2716 if ( -f $tmpfilename ) { unlink $tmpfilename; } 2717 2718 installer::files::save_file($tmpfilename, \@pathcollector); 2719 2720 my $success = 0; 2721 my @cyg_sourcepathlist = qx{cygpath -w -f "$tmpfilename"}; 2722 chomp @cyg_sourcepathlist; 2723 2724 # Validating the array, it has to contain the correct number of values 2725 my $new_pathes = $#cyg_sourcepathlist + 1; 2726 if ( $new_pathes == $counter ) { $success = 1; } 2727 2728 if ($success) 2729 { 2730 $infoline = "Success: Successfully converted to cygwin pathes!\n"; 2731 push( @installer::globals::logfileinfo, $infoline); 2732 } 2733 else 2734 { 2735 $infoline = "ERROR: Failed to convert to cygwin pathes!\n"; 2736 push( @installer::globals::logfileinfo, $infoline); 2737 installer::exiter::exit_program("ERROR: Failed to convert to cygwin pathes!", "generate_cygwin_pathes"); 2738 } 2739 2740 for ( my $j = 0; $j <= $#cyg_sourcepathlist; $j++ ) 2741 { 2742 my $number = $startnumber + $j; 2743 ${$filesref}[$number]->{'cyg_sourcepath'} = $cyg_sourcepathlist[$j]; 2744 } 2745 2746 if ( -f $tmpfilename ) { unlink $tmpfilename; } 2747 2748 @pathcollector = (); 2749 $startnumber = $startnumber + $max; 2750 $counter = 0; 2751 } 2752 } 2753 2754 # Checking existence fo cyg_sourcepath for every file 2755 for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 2756 { 2757 if (( ! exists(${$filesref}[$i]->{'cyg_sourcepath'}) ) || ( ${$filesref}[$i]->{'cyg_sourcepath'} eq "" )) 2758 { 2759 $infoline = "ERROR: No cygwin sourcepath defined for file ${$filesref}[$i]->{'sourcepath'}\n"; 2760 push( @installer::globals::logfileinfo, $infoline); 2761 installer::exiter::exit_program("ERROR: No cygwin sourcepath defined for file ${$filesref}[$i]->{'sourcepath'}!", "generate_cygwin_pathes"); 2762 } 2763 } 2764 2765 installer::logger::include_timestamp_into_logfile("Ending generating cygwin pathes"); 2766} 2767 2768############################################## 2769# Include only files from install directory 2770# in pkgmap file. 2771############################################## 2772 2773sub filter_pkgmapfile 2774{ 2775 my ($pkgmapfile) = @_; 2776 2777 my @pkgmap = (); 2778 2779 my $line = ": 1 10\n"; 2780 push(@pkgmap, $line); 2781 2782 for ( my $i = 0; $i <= $#{$pkgmapfile}; $i++ ) 2783 { 2784 $line = ${$pkgmapfile}[$i]; 2785 if ( $line =~ /^\s*1\si\s/ ) { push(@pkgmap, $line); } 2786 } 2787 2788 return \@pkgmap; 2789} 2790 2791############################################## 2792# Creating double packages for Solaris x86. 2793# One package with ARCH=i386 and one with 2794# ARCH=i86pc. 2795############################################## 2796 2797sub fix_solaris_x86_patch 2798{ 2799 my ($packagename, $subdir) = @_; 2800 2801 # changing into directory of packages, important for soft linking 2802 my $startdir = cwd(); 2803 chdir($subdir); 2804 2805 # $packagename is: "SUNWstaroffice-core01" 2806 # Current working directory is: "<path>/install/en-US_inprogress" 2807 2808 # create new folder in "packages": $packagename . ".i" 2809 my $newpackagename = $packagename . "\.i"; 2810 my $newdir = $newpackagename; 2811 installer::systemactions::create_directory($newdir); 2812 2813 # collecting all directories in the package 2814 my $olddir = $packagename; 2815 my $allsubdirs = installer::systemactions::get_all_directories_without_path($olddir); 2816 2817 # link all directories from $packagename to $packagename . ".i" 2818 for ( my $i = 0; $i <= $#{$allsubdirs}; $i++ ) 2819 { 2820 my $sourcedir = $olddir . $installer::globals::separator . ${$allsubdirs}[$i]; 2821 my $destdir = $newdir . $installer::globals::separator . ${$allsubdirs}[$i]; 2822 my $directory_depth = 2; # important for soft links, two directories already exist 2823 installer::systemactions::softlink_complete_directory($sourcedir, $destdir, $directory_depth); 2824 } 2825 2826 # copy "pkginfo" and "pkgmap" from $packagename to $packagename . ".i" 2827 my @allcopyfiles = ("pkginfo", "pkgmap"); 2828 for ( my $i = 0; $i <= $#allcopyfiles; $i++ ) 2829 { 2830 my $sourcefile = $olddir . $installer::globals::separator . $allcopyfiles[$i]; 2831 my $destfile = $newdir . $installer::globals::separator . $allcopyfiles[$i]; 2832 installer::systemactions::copy_one_file($sourcefile, $destfile); 2833 } 2834 2835 # change in pkginfo in $packagename . ".i" the value for ARCH from i386 to i86pc 2836 my $pkginfofilename = "pkginfo"; 2837 $pkginfofilename = $newdir . $installer::globals::separator . $pkginfofilename; 2838 2839 my $pkginfofile = installer::files::read_file($pkginfofilename); 2840 set_old_architecture_string($pkginfofile); 2841 installer::files::save_file($pkginfofilename, $pkginfofile); 2842 2843 # adapt the values in pkgmap for pkginfo file, because this file was edited 2844 my $pkgmapfilename = "pkgmap"; 2845 $pkgmapfilename = $newdir . $installer::globals::separator . $pkgmapfilename; 2846 2847 my $pkgmapfile = installer::files::read_file($pkgmapfilename); 2848 set_pkginfo_line($pkgmapfile, $pkginfofilename); 2849 installer::files::save_file($pkgmapfilename, $pkgmapfile); 2850 2851 # changing back to startdir 2852 chdir($startdir); 2853} 2854 2855################################################### 2856# Creating double core01 package for Solaris x86. 2857# One package with ARCH=i386 and one with 2858# ARCH=i86pc. This is necessary, to inform the 2859# user about the missing "small patch", if 2860# packages with ARCH=i86pc are installed. 2861################################################### 2862 2863sub fix2_solaris_x86_patch 2864{ 2865 my ($packagename, $subdir) = @_; 2866 2867 if ( $packagename =~ /-core01\s*$/ ) # only this one package needs to be duplicated 2868 { 2869 my $startdir = cwd(); 2870 chdir($subdir); 2871 2872 # $packagename is: "SUNWstaroffice-core01" 2873 # Current working directory is: "<path>/install/en-US_inprogress" 2874 2875 # create new package in "packages": $packagename . ".i" 2876 my $olddir = $packagename; 2877 my $newpackagename = $packagename . "\.i"; 2878 my $newdir = $newpackagename; 2879 2880 installer::systemactions::create_directory($newdir); 2881 2882 my $oldinstalldir = $olddir . $installer::globals::separator . "install"; 2883 my $newinstalldir = $newdir . $installer::globals::separator . "install"; 2884 2885 installer::systemactions::copy_complete_directory($oldinstalldir, $newinstalldir); 2886 2887 # setting time stamp of all copied files to avoid errors from pkgchk 2888 my $allinstallfiles = installer::systemactions::get_all_files_from_one_directory_without_path($newinstalldir); 2889 set_time_stamp($oldinstalldir, $newinstalldir, $allinstallfiles); 2890 2891 # copy "pkginfo" and "pkgmap" from $packagename to $packagename . ".i" 2892 my @allcopyfiles = ("pkginfo", "pkgmap"); 2893 for ( my $i = 0; $i <= $#allcopyfiles; $i++ ) 2894 { 2895 my $sourcefile = $olddir . $installer::globals::separator . $allcopyfiles[$i]; 2896 my $destfile = $newdir . $installer::globals::separator . $allcopyfiles[$i]; 2897 installer::systemactions::copy_one_file($sourcefile, $destfile); 2898 } 2899 2900 # change in pkginfo in $packagename . ".i" the value for ARCH from i386 to i86pc 2901 my $pkginfofilename = "pkginfo"; 2902 $pkginfofilename = $newdir . $installer::globals::separator . $pkginfofilename; 2903 2904 my $pkginfofile = installer::files::read_file($pkginfofilename); 2905 set_old_architecture_string($pkginfofile); 2906 check_requires_setting($pkginfofile); 2907 installer::files::save_file($pkginfofilename, $pkginfofile); 2908 2909 # adapt the values in pkgmap for pkginfo file, because this file was edited 2910 my $pkgmapfilename = "pkgmap"; 2911 $pkgmapfilename = $newdir . $installer::globals::separator . $pkgmapfilename; 2912 2913 my $pkgmapfile = installer::files::read_file($pkgmapfilename); 2914 set_pkginfo_line($pkgmapfile, $pkginfofilename); 2915 $pkgmapfile = filter_pkgmapfile($pkgmapfile); 2916 installer::files::save_file($pkgmapfilename, $pkgmapfile); 2917 2918 # setting time stamp of all copied files to avoid errors from pkgchk 2919 set_time_stamp($olddir, $newdir, \@allcopyfiles); 2920 2921 # changing back to startdir 2922 chdir($startdir); 2923 } 2924} 2925 2926################################################ 2927# Files with flag HIDDEN get a dot at the 2928# beginning of the file name. This cannot be 2929# defined in scp2 project, because tooling 2930# cannot handle files with beginning dot 2931# correctly. 2932################################################ 2933 2934sub resolving_hidden_flag 2935{ 2936 my ($filesarrayref, $variableshashref, $item, $languagestringref) = @_; 2937 2938 my $diritem = lc($item); 2939 my $infoline = ""; 2940 2941 my $hiddendirbase = installer::systemactions::create_directories("hidden_$diritem", $languagestringref); 2942 2943 installer::logger::include_header_into_logfile("$item with flag HIDDEN:"); 2944 2945 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ ) 2946 { 2947 my $onefile = ${$filesarrayref}[$i]; 2948 my $styles = ""; 2949 2950 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; } 2951 2952 if ( $styles =~ /\bHIDDEN\b/ ) 2953 { 2954 # Language specific subdirectory 2955 2956 my $onelanguage = $onefile->{'specificlanguage'}; 2957 2958 if ($onelanguage eq "") 2959 { 2960 $onelanguage = "00"; # files without language into directory "00" 2961 } 2962 2963 my $hiddendir = $hiddendirbase . $installer::globals::separator . $onelanguage . $installer::globals::separator; 2964 installer::systemactions::create_directory($hiddendir); # creating language specific directories 2965 2966 # copy files and edit them with the variables defined in the zip.lst 2967 2968 my $onefilename = $onefile->{'Name'}; 2969 my $newfilename = "\." . $onefilename; 2970 my $sourcefile = $onefile->{'sourcepath'}; 2971 my $destfile = $hiddendir . $newfilename; 2972 2973 my $copysuccess = installer::systemactions::copy_one_file($sourcefile, $destfile); 2974 2975 if ( $copysuccess ) 2976 { 2977 # $onefile->{'Name'} = $newfilename; 2978 $onefile->{'sourcepath'} = $destfile; 2979 $destination = $onefile->{'destination'}; 2980 installer::pathanalyzer::get_path_from_fullqualifiedname(\$destination); 2981 if ( $destination eq "" ) { $onefile->{'destination'} = $newfilename; } 2982 else { $onefile->{'destination'} = $destination . $installer::globals::separator . $newfilename; } 2983 2984 $infoline = "Success: Using file with flag HIDDEN from \"$onefile->{'sourcepath'}\"!\n"; 2985 push( @installer::globals::logfileinfo, $infoline); 2986 } 2987 else 2988 { 2989 $infoline = "Error: Failed to copy HIDDEN file from \"$sourcefile\" to \"$destfile\"!\n"; 2990 push( @installer::globals::logfileinfo, $infoline); 2991 } 2992 } 2993 } 2994 2995 $infoline = "\n"; 2996 push( @installer::globals::logfileinfo, $infoline); 2997} 2998 2999################################################ 3000# Controlling that all keys in hash A are 3001# also key in hash B. 3002################################################ 3003 3004sub key_in_a_is_also_key_in_b 3005{ 3006 my ( $hashref_a, $hashref_b) = @_; 3007 3008 my $returnvalue = 1; 3009 3010 my $key; 3011 foreach $key ( keys %{$hashref_a} ) 3012 { 3013 if ( ! exists($hashref_b->{$key}) ) 3014 { 3015 print "*****\n"; 3016 foreach $keyb ( keys %{$hashref_b} ) { print "$keyb : $hashref_b->{$keyb}\n"; } 3017 print "*****\n"; 3018 $returnvalue = 0; 3019 } 3020 } 3021 3022 return $returnvalue; 3023} 3024 3025###################################################### 3026# Getting the first entry from a list of languages 3027###################################################### 3028 3029sub get_first_from_list 3030{ 3031 my ( $list ) = @_; 3032 3033 my $first = $list; 3034 3035 if ( $list =~ /^\s*(.+?),(.+)\s*$/) # "?" for minimal matching 3036 { 3037 $first = $1; 3038 } 3039 3040 return $first; 3041} 3042 3043################################################ 3044# Setting all spellchecker languages 3045################################################ 3046 3047sub set_spellcheckerlanguages 3048{ 3049 my ( $productlanguagesarrayref, $allvariables ) = @_; 3050 3051 my %productlanguages = (); 3052 for ( my $i = 0; $i <= $#{$productlanguagesarrayref}; $i++ ) { $productlanguages{${$productlanguagesarrayref}[$i]} = 1; } 3053 3054 my $spellcheckfilename = $allvariables->{'SPELLCHECKERFILE'}; 3055 3056 my $spellcheckfileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$spellcheckfilename, "", 1); 3057 3058 if ($$spellcheckfileref eq "") { installer::exiter::exit_program("ERROR: Could not find $spellcheckfilename!", "set_spellcheckerlanguages"); } 3059 3060 my $infoline = "Using spellchecker file: $$spellcheckfileref \n"; 3061 push( @installer::globals::globallogfileinfo, $infoline); 3062 3063 my $spellcheckfile = installer::files::read_file($$spellcheckfileref); 3064 my %spellcheckhash = (); 3065 3066 for ( my $j = 0; $j <= $#{$spellcheckfile}; $j++ ) 3067 { 3068 # Analyzing all "key=value" lines 3069 my $oneline = ${$spellcheckfile}[$j]; 3070 3071 if ( $oneline =~ /^\s*(\S+)\s*\=\s*\"(.*?)\"\s*$/ ) # no white space allowed in key 3072 { 3073 my $onelang = $1; 3074 my $languagelist = $2; 3075 3076 # Special handling for language packs. Only include the first language of the language list. 3077 # If no spellchecker shall be included, the keyword "EMPTY" can be used. 3078 3079 if ( $installer::globals::languagepack ) 3080 { 3081 my $first = get_first_from_list($languagelist); 3082 3083 if ( $first eq "EMPTY" ) # no spellchecker into language pack 3084 { 3085 $languagelist = ""; 3086 } 3087 else 3088 { 3089 $languagelist = $first; 3090 } 3091 } 3092 else # no language pack, so EMPTY is not required 3093 { 3094 $languagelist =~ s/^\s*EMPTY\s*,//; # removing the entry EMPTY 3095 } 3096 3097 $spellcheckhash{$onelang} = $languagelist; 3098 } 3099 } 3100 3101 # Collecting all required languages in %installer::globals::spellcheckerlanguagehash 3102 3103 foreach my $lang (keys %productlanguages) 3104 { 3105 my $languagelist = ""; 3106 if ( exists($spellcheckhash{$lang}) ) { $languagelist = $spellcheckhash{$lang}; } 3107 else { $languagelist = $spellcheckhash{'en-US'}; } # defaulting to English 3108 3109 my $langlisthash = installer::converter::convert_stringlist_into_hash(\$languagelist, ","); 3110 foreach my $onelang ( keys %{$langlisthash} ) { $installer::globals::spellcheckerlanguagehash{$onelang} = 1; } 3111 } 3112 3113 $installer::globals::analyze_spellcheckerlanguage = 1; 3114 3115 # Logging 3116 3117 my $langstring = ""; 3118 foreach my $lang (sort keys %installer::globals::spellcheckerlanguagehash) { $langstring = $langstring . "," . $lang } 3119 $langstring =~ s/^\s*,//; 3120 3121 $infoline = "Collected spellchecker languages for spellchecker: $langstring \n"; 3122 push( @installer::globals::globallogfileinfo, $infoline); 3123} 3124 3125################################################ 3126# Including a license text into setup script 3127################################################ 3128 3129sub put_license_into_setup 3130{ 3131 my ($installdir, $includepatharrayref) = @_; 3132 3133 # find and read english license file 3134 my $licenselanguage = "en-US"; # always english ! 3135 # my $licensefilename = "LICENSE_" . $licenselanguage; 3136 my $licensefilename = "license_" . $licenselanguage . ".txt"; 3137 my $licenseincludepatharrayref = get_language_specific_include_pathes($includepatharrayref, $licenselanguage); 3138 3139 my $licenseref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$licensefilename, $licenseincludepatharrayref, 0); 3140 if ($$licenseref eq "") { installer::exiter::exit_program("ERROR: Could not find License file $licensefilename!", "put_license_into_setup"); } 3141 my $licensefile = installer::files::read_file($$licenseref); 3142 3143 # Read setup 3144 my $setupfilename = $installdir . $installer::globals::separator . "setup"; 3145 my $setupfile = installer::files::read_file($setupfilename); 3146 3147 # Replacement 3148 my $infoline = "Adding licensefile into setup script\n"; 3149 push( @installer::globals::logfileinfo, $infoline); 3150 3151 my $includestring = ""; 3152 for ( my $i = 0; $i <= $#{$licensefile}; $i++ ) { $includestring = $includestring . ${$licensefile}[$i]; } 3153 for ( my $i = 0; $i <= $#{$setupfile}; $i++ ) { ${$setupfile}[$i] =~ s/LICENSEFILEPLACEHOLDER/$includestring/; } 3154 3155 # Write setup 3156 installer::files::save_file($setupfilename, $setupfile); 3157} 3158 3159################################################ 3160# Setting global path to getuid.so library 3161################################################ 3162 3163sub set_getuid_path 3164{ 3165 my ($includepatharrayref) = @_; 3166 3167 my $getuidlibraryname = "getuid.so"; 3168 my $getuidlibraryref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$getuidlibraryname, $includepatharrayref, 0); 3169 if ($$getuidlibraryref eq "") { installer::exiter::exit_program("ERROR: Could not find $getuidlibraryname!", "set_getuid_path"); } 3170 3171 $installer::globals::getuidpath = $$getuidlibraryref; 3172 $installer::globals::getuidpathset = 1; 3173} 3174 3175######################################################### 3176# Create a tar file from the binary package 3177######################################################### 3178 3179sub tar_package 3180{ 3181 my ( $installdir, $packagename, $tarfilename, $getuidlibrary) = @_; 3182 3183 my $ldpreloadstring = ""; 3184 if ( $getuidlibrary ne "" ) { $ldpreloadstring = "LD_PRELOAD=" . $getuidlibrary; } 3185 3186 my $systemcall = "cd $installdir; $ldpreloadstring tar -cf - $packagename > $tarfilename"; 3187 # my $systemcall = "cd $installdir; $ldpreloadstring tar -cf - * > $tarfilename"; 3188 3189 my $returnvalue = system($systemcall); 3190 3191 my $infoline = "Systemcall: $systemcall\n"; 3192 push( @installer::globals::logfileinfo, $infoline); 3193 3194 if ($returnvalue) 3195 { 3196 $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; 3197 push( @installer::globals::logfileinfo, $infoline); 3198 } 3199 else 3200 { 3201 $infoline = "Success: Executed \"$systemcall\" successfully!\n"; 3202 push( @installer::globals::logfileinfo, $infoline); 3203 } 3204 3205 my $localcall = "chmod 775 $tarfilename \>\/dev\/null 2\>\&1"; 3206 $returnvalue = system($localcall); 3207 3208 my $fulltarfile = $installdir . $installer::globals::separator . $tarfilename; 3209 my $filesize = ( -s $fulltarfile ); 3210 3211 return $filesize; 3212} 3213 3214######################################################### 3215# Create a tar file from the binary package 3216######################################################### 3217 3218sub untar_package 3219{ 3220 my ( $installdir, $tarfilename, $getuidlibrary) = @_; 3221 3222 my $ldpreloadstring = ""; 3223 if ( $getuidlibrary ne "" ) { $ldpreloadstring = "LD_PRELOAD=" . $getuidlibrary; } 3224 3225 my $systemcall = "cd $installdir; $ldpreloadstring tar -xf $tarfilename"; 3226 3227 my $returnvalue = system($systemcall); 3228 3229 my $infoline = "Systemcall: $systemcall\n"; 3230 push( @installer::globals::logfileinfo, $infoline); 3231 3232 if ($returnvalue) 3233 { 3234 $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; 3235 push( @installer::globals::logfileinfo, $infoline); 3236 } 3237 else 3238 { 3239 $infoline = "Success: Executed \"$systemcall\" successfully!\n"; 3240 push( @installer::globals::logfileinfo, $infoline); 3241 } 3242 3243 my $localcall = "chmod 775 $tarfilename \>\/dev\/null 2\>\&1"; 3244 $returnvalue = system($localcall); 3245} 3246 3247######################################################### 3248# Shuffle an array (Fisher Yates shuffle) 3249######################################################### 3250 3251sub shuffle_array 3252{ 3253 my ( $arrayref ) = @_; 3254 3255 # my $counter = 0; 3256 # my $infoline = "Old package order: \n"; 3257 # push( @installer::globals::logfileinfo, $infoline); 3258 # foreach my $onepackage ( @{$arrayref} ) 3259 # { 3260 # $counter++; 3261 # $infoline = "$counter: $onepackage->{'module'}\n"; 3262 # push( @installer::globals::logfileinfo, $infoline); 3263 # } 3264 3265 my $i = @$arrayref; 3266 while (--$i) 3267 { 3268 my $j = int rand ($i+1); 3269 @$arrayref[$i,$j] = @$arrayref[$j,$i]; 3270 } 3271 3272 # $counter = 0; 3273 # $infoline = "New package order: \n"; 3274 # push( @installer::globals::logfileinfo, $infoline); 3275 # foreach my $onepackage ( @{$arrayref} ) 3276 # { 3277 # $counter++; 3278 # $infoline = "$counter: $onepackage->{'module'}\n"; 3279 # push( @installer::globals::logfileinfo, $infoline); 3280 # } 3281} 3282 3283################################################ 3284# Defining the English license text to add 3285# it into Solaris packages. 3286################################################ 3287 3288sub set_english_license 3289{ 3290 my $additional_license_name = $installer::globals::englishsolarislicensename; # always the English file 3291 my $licensefileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$additional_license_name, "" , 0); 3292 if ( $$licensefileref eq "" ) { installer::exiter::exit_program("ERROR: Could not find license file $additional_license_name!", "set_english_license"); } 3293 $installer::globals::englishlicenseset = 1; 3294 $installer::globals::englishlicense = installer::files::read_file($$licensefileref); 3295 installer::scpzipfiles::replace_all_ziplistvariables_in_file($installer::globals::englishlicense, $variableshashref); 3296} 3297 3298############################################## 3299# Setting time stamp of copied files to avoid 3300# errors from pkgchk. 3301############################################## 3302 3303sub set_time_stamp_for_file 3304{ 3305 my ($sourcefile, $destfile) = @_; 3306 3307 my $systemcall = "touch -r $sourcefile $destfile"; 3308 3309 my $returnvalue = system($systemcall); 3310 3311 my $infoline = "Systemcall: $systemcall\n"; 3312 push( @installer::globals::logfileinfo, $infoline); 3313 3314 if ($returnvalue) 3315 { 3316 $infoline = "ERROR: \"$systemcall\" failed!\n"; 3317 push( @installer::globals::logfileinfo, $infoline); 3318 } 3319 else 3320 { 3321 $infoline = "Success: \"$systemcall\" !\n"; 3322 push( @installer::globals::logfileinfo, $infoline); 3323 } 3324} 3325 3326############################################## 3327# Setting checksum and wordcount for changed 3328# pkginfo file into pkgmap. 3329############################################## 3330 3331sub change_onefile_in_pkgmap 3332{ 3333 my ($pkgmapfile, $fullfilename, $shortfilename) = @_; 3334 3335 # 1 i pkginfo 442 34577 1166716297 3336 # -> 3337 # 1 i pkginfo 443 34737 1166716297 3338 # 3339 # wc -c pkginfo | cut -f6 -d' ' -> 442 (variable) 3340 # sum pkginfo | cut -f1 -d' ' -> 34577 (variable) 3341 # grep 'pkginfo' pkgmap | cut -f6 -d' ' -> 1166716297 (fix) 3342 3343 my $checksum = call_sum($fullfilename); 3344 if ( $checksum =~ /^\s*(\d+)\s+.*$/ ) { $checksum = $1; } 3345 3346 my $wordcount = call_wc($fullfilename); 3347 if ( $wordcount =~ /^\s*(\d+)\s+.*$/ ) { $wordcount = $1; } 3348 3349 for ( my $i = 0; $i <= $#{$pkgmapfile}; $i++ ) 3350 { 3351 if ( ${$pkgmapfile}[$i] =~ /(^.*\b\Q$shortfilename\E\b\s+)(\d+)(\s+)(\d+)(\s+)(\d+)(\s*$)/ ) 3352 { 3353 my $newline = $1 . $wordcount . $3 . $checksum . $5 . $6 . $7; 3354 ${$pkgmapfile}[$i] = $newline; 3355 last; 3356 } 3357 } 3358} 3359 3360################################################ 3361# Adding the content of the English license 3362# file into the system integration packages. 3363################################################ 3364 3365sub add_license_into_systemintegrationpackages 3366{ 3367 my ($destdir, $packages) = @_; 3368 3369 for ( my $i = 0; $i <= $#{$packages}; $i++ ) 3370 { 3371 my $copyrightfilename = ${$packages}[$i] . $installer::globals::separator . "install" . $installer::globals::separator . "copyright"; 3372 if ( ! -f $copyrightfilename ) { installer::exiter::exit_program("ERROR: Could not find license file in system integration package: $copyrightfilename!", "add_license_into_systemintegrationpackages"); } 3373 my $copyrightfile = installer::files::read_file($copyrightfilename); 3374 3375 # Saving time stamp of old copyrightfile 3376 my $savcopyrightfilename = $copyrightfilename . ".sav"; 3377 installer::systemactions::copy_one_file($copyrightfilename, $savcopyrightfilename); 3378 set_time_stamp_for_file($copyrightfilename, $savcopyrightfilename); # now $savcopyrightfile has the time stamp of $copyrightfile 3379 3380 # Adding license content to copyright file 3381 push(@{$copyrightfile}, "\n"); 3382 for ( my $i = 0; $i <= $#{$installer::globals::englishlicense}; $i++ ) { push(@{$copyrightfile}, ${$installer::globals::englishlicense}[$i]); } 3383 installer::files::save_file($copyrightfilename, $copyrightfile); 3384 3385 # Setting the old time stamp saved with $savcopyrightfilename 3386 set_time_stamp_for_file($savcopyrightfilename, $copyrightfilename); # now $copyrightfile has the time stamp of $savcopyrightfile 3387 unlink($savcopyrightfilename); 3388 3389 # Changing content of copyright file in pkgmap 3390 my $pkgmapfilename = ${$packages}[$i] . $installer::globals::separator . "pkgmap"; 3391 if ( ! -f $pkgmapfilename ) { installer::exiter::exit_program("ERROR: Could not find pkgmap in system integration package: $pkgmapfilename!", "add_license_into_systemintegrationpackages"); } 3392 my $pkgmap = installer::files::read_file($pkgmapfilename); 3393 change_onefile_in_pkgmap($pkgmap, $copyrightfilename, "copyright"); 3394 installer::files::save_file($pkgmapfilename, $pkgmap); 3395 } 3396} 3397 3398######################################################### 3399# Collecting all pkgmap files from an installation set 3400######################################################### 3401 3402sub collectpackagemaps 3403{ 3404 my ( $installdir, $languagestringref, $allvariables ) = @_; 3405 3406 installer::logger::include_header_into_logfile("Collecing all packagemaps (pkgmap):"); 3407 3408 my $pkgmapdir = installer::systemactions::create_directories("pkgmap", $languagestringref); 3409 my $subdirname = $allvariables->{'UNIXPRODUCTNAME'} . "_pkgmaps"; 3410 my $pkgmapsubdir = $pkgmapdir . $installer::globals::separator . $subdirname; 3411 if ( -d $pkgmapsubdir ) { installer::systemactions::remove_complete_directory($pkgmapsubdir); } 3412 if ( ! -d $pkgmapsubdir ) { installer::systemactions::create_directory($pkgmapsubdir); } 3413 3414 $installdir =~ s/\/\s*$//; 3415 # Collecting all packages in $installdir and its sub package ("packages") 3416 my $searchdir = $installdir . $installer::globals::separator . $installer::globals::epmoutpath; 3417 3418 my $allpackages = installer::systemactions::get_all_directories_without_path($searchdir); 3419 3420 for ( my $i = 0; $i <= $#{$allpackages}; $i++ ) 3421 { 3422 my $pkgmapfile = $searchdir . $installer::globals::separator . ${$allpackages}[$i] . $installer::globals::separator . "pkgmap"; 3423 my $destfilename = $pkgmapsubdir . $installer::globals::separator . ${$allpackages}[$i] . "_pkgmap"; 3424 installer::systemactions::copy_one_file($pkgmapfile, $destfilename); 3425 } 3426 3427 # Create a tar gz file with all package maps 3428 my $tarfilename = $subdirname . ".tar"; 3429 my $targzname = $tarfilename . ".gz"; 3430 # my $systemcall = "cd $pkgmapdir; tar -cf - $subdirname > $tarfilename"; 3431 $systemcall = "cd $pkgmapdir; tar -cf - $subdirname | gzip > $targzname"; 3432 make_systemcall($systemcall); 3433 installer::systemactions::remove_complete_directory($pkgmapsubdir, 1); 3434} 3435 34361; 3437