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