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