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::scriptitems; 25 26use installer::converter; 27use installer::existence; 28use installer::exiter; 29use installer::globals; 30use installer::languages; 31use installer::logger; 32use installer::pathanalyzer; 33use installer::remover; 34use installer::systemactions; 35 36use File::Spec; 37use SvnRevision; 38use ExtensionsLst; 39 40################################################################ 41# Resolving the GID for the directories defined in setup script 42################################################################ 43 44sub resolve_all_directory_names 45{ 46 my ($directoryarrayref) = @_; 47 48 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::resolve_all_directory_names : $#{$directoryarrayref}"); } 49 50 # After this procedure the hash shall contain the complete language 51 # dependent path, not only the language dependent HostName. 52 53 my ($key, $value, $parentvalue, $parentgid, $parentdirectoryhashref); 54 55 for ( my $i = 0; $i <= $#{$directoryarrayref}; $i++ ) 56 { 57 my $directoryhashref = ${$directoryarrayref}[$i]; 58 my $gid = $directoryhashref-> {'gid'}; 59 my $parentid = $directoryhashref-> {'ParentID'}; 60 61 if ( $parentid ne "PREDEFINED_PROGDIR" ) 62 { 63 # find the array of the parentid, which has to be defined before in setup script 64 # and is therefore listed before in this array 65 66 for ( my $j = 0; $j <= $i; $j++ ) 67 { 68 $parentdirectoryhashref = ${$directoryarrayref}[$j]; 69 $parentgid = $parentdirectoryhashref->{'gid'}; 70 71 if ( $parentid eq $parentgid) 72 { 73 last; 74 } 75 } 76 77 # and now we can put the path together 78 # But take care of the languages! 79 80 my $dirismultilingual = $directoryhashref->{'ismultilingual'}; 81 my $parentismultilingual = $parentdirectoryhashref->{'ismultilingual'}; 82 83 # First: Both directories are language independent or both directories are language dependent 84 85 if ((( ! $dirismultilingual ) && ( ! $parentismultilingual )) || 86 (( $dirismultilingual ) && ( $parentismultilingual ))) 87 { 88 foreach $key (keys %{$directoryhashref}) 89 { 90 # the key ("HostName (en-US)") must be usable for both hashes 91 92 if ( $key =~ /\bHostName\b/ ) 93 { 94 $parentvalue = ""; 95 $value = $directoryhashref->{$key}; 96 if ( $parentdirectoryhashref->{$key} ) { $parentvalue = $parentdirectoryhashref->{$key}; } 97 98 # It is possible, that in scp project, a directory is defined in more languages than 99 # the directory parent (happened after automatic generation of macros.inc). 100 # Therefore this is checked now and written with a warning into the logfile. 101 # This is no error, because (in most cases) the concerned language is not build. 102 103 if ($parentvalue eq "") 104 { 105 $directoryhashref->{$key} = "FAILURE"; 106 my $infoline = "WARNING: No hostname for $parentid with \"$key\". Needed by child directory $gid !\n"; 107 push( @installer::globals::globallogfileinfo, $infoline); 108 } 109 else 110 { 111 $directoryhashref->{$key} = $parentvalue . $installer::globals::separator . $value; 112 } 113 } 114 } 115 } 116 117 # Second: The directory is language dependent, the parent not 118 119 if (( $dirismultilingual ) && ( ! $parentismultilingual )) 120 { 121 $parentvalue = $parentdirectoryhashref->{'HostName'}; # there is only one 122 123 foreach $key (keys %{$directoryhashref}) # the current directory 124 { 125 if ( $key =~ /\bHostName\b/ ) 126 { 127 $value = $directoryhashref->{$key}; 128 $directoryhashref->{$key} = $parentvalue . $installer::globals::separator . $value; 129 } 130 } 131 } 132 133 # Third: The directory is not language dependent, the parent is language dependent 134 135 if (( ! $dirismultilingual ) && ( $parentismultilingual )) 136 { 137 $value = $directoryhashref->{'HostName'}; # there is only one 138 delete($directoryhashref->{'HostName'}); 139 140 foreach $key (keys %{$parentdirectoryhashref}) # the parent directory 141 { 142 if ( $key =~ /\bHostName\b/ ) 143 { 144 $parentvalue = $parentdirectoryhashref->{$key}; # there is only one 145 $directoryhashref->{$key} = $parentvalue . $installer::globals::separator . $value; 146 } 147 } 148 149 $directoryhashref->{'ismultilingual'} = 1; # now this directory is also language dependent 150 } 151 } 152 } 153} 154 155############################################################################# 156# Files with flag DELETE_ONLY do not need to be packed into installation set 157############################################################################# 158 159sub remove_delete_only_files_from_productlists 160{ 161 my ($productarrayref) = @_; 162 163 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::remove_delete_only_files_from_productlists : $#{$productarrayref}"); } 164 165 my @newitems = (); 166 167 for ( my $i = 0; $i <= $#{$productarrayref}; $i++ ) 168 { 169 my $oneitem = ${$productarrayref}[$i]; 170 my $styles = ""; 171 172 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; } 173 174 if (!($styles =~ /\bDELETE_ONLY\b/)) 175 { 176 push(@newitems, $oneitem); 177 } 178 } 179 180 return \@newitems; 181} 182 183############################################################################# 184# Files with flag NOT_IN_SUITE do not need to be packed into 185# Suite installation sets 186############################################################################# 187 188sub remove_notinsuite_files_from_productlists 189{ 190 my ($productarrayref) = @_; 191 192 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::remove_notinsuite_files_from_productlists : $#{$productarrayref}"); } 193 194 my @newitems = (); 195 196 for ( my $i = 0; $i <= $#{$productarrayref}; $i++ ) 197 { 198 my $oneitem = ${$productarrayref}[$i]; 199 my $styles = ""; 200 201 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; } 202 203 if (!($styles =~ /\bNOT_IN_SUITE\b/)) 204 { 205 push(@newitems, $oneitem); 206 } 207 else 208 { 209 my $infoline = "INFO: Flag NOT_IN_SUITE \-\> Removing $oneitem->{'gid'} from file list.\n"; 210 push( @installer::globals::globallogfileinfo, $infoline); 211 } 212 } 213 214 return \@newitems; 215} 216 217############################################################################# 218# Files with flag NOT_IN_SUITE do not need to be packed into 219# Suite installation sets 220############################################################################# 221 222sub remove_office_start_language_files 223{ 224 my ($productarrayref) = @_; 225 226 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::remove_notinsuite_files_from_productlists : $#{$productarrayref}"); } 227 228 my @newitems = (); 229 230 for ( my $i = 0; $i <= $#{$productarrayref}; $i++ ) 231 { 232 my $oneitem = ${$productarrayref}[$i]; 233 my $styles = ""; 234 235 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; } 236 237 if (!($styles =~ /\bSET_OFFICE_LANGUAGE\b/)) 238 { 239 push(@newitems, $oneitem); 240 } 241 else 242 { 243 my $infoline = "INFO: Flag SET_OFFICE_LANGUAGE \-\> Removing $oneitem->{'gid'} from file list.\n"; 244 push( @installer::globals::logfileinfo, $infoline); 245 } 246 } 247 248 return \@newitems; 249} 250 251############################################################################# 252# Registryitems for Uninstall have to be removed 253############################################################################# 254 255sub remove_uninstall_regitems_from_script 256{ 257 my ($registryarrayref) = @_; 258 259 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::remove_uninstall_regitems_from_script : $#{$registryarrayref}"); } 260 261 my @newitems = (); 262 263 for ( my $i = 0; $i <= $#{$registryarrayref}; $i++ ) 264 { 265 my $oneitem = ${$registryarrayref}[$i]; 266 my $subkey = ""; 267 268 if ( $oneitem->{'Subkey'} ) { $subkey = $oneitem->{'Subkey'}; } 269 270 if ( $subkey =~ /Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall/ ) { next; } 271 272 push(@newitems, $oneitem); 273 } 274 275 return \@newitems; 276} 277 278############################################################################## 279# Searching the language module for a specified language 280############################################################################## 281 282sub get_languagespecific_module 283{ 284 my ( $lang, $modulestring ) = @_; 285 286 my $langmodulestring = ""; 287 288 my $module; 289 foreach $module ( keys %installer::globals::alllangmodules ) 290 { 291 if (( $installer::globals::alllangmodules{$module} eq $lang ) && ( $modulestring =~ /\b$module\b/ )) 292 { 293 $langmodulestring = "$langmodulestring,$module"; 294 } 295 } 296 297 $langmodulestring =~ s/^\s*,//; 298 299 if ( $langmodulestring eq "" ) { installer::exiter::exit_program("ERROR: No language pack module found for language $lang in string \"$modulestring\"!", "get_languagespecific_module"); } 300 301 return $langmodulestring; 302} 303 304############################################################################## 305# Removing all items in product lists which do not have the correct languages 306############################################################################## 307 308sub resolving_all_languages_in_productlists 309{ 310 my ($productarrayref, $languagesarrayref) = @_; 311 312 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::resolving_all_languages_in_productlists : $#{$productarrayref} : $#{$languagesarrayref}"); } 313 314 my @itemsinalllanguages = (); 315 316 my ($key, $value); 317 318 for ( my $i = 0; $i <= $#{$productarrayref}; $i++ ) 319 { 320 my $oneitem = ${$productarrayref}[$i]; 321 322 my $ismultilingual = $oneitem->{'ismultilingual'}; 323 324 if (!($ismultilingual)) # nothing to do with single language items 325 { 326 $oneitem->{'specificlanguage'} = ""; 327 push(@itemsinalllanguages, $oneitem); 328 } 329 else #all language dependent files 330 { 331 for ( my $j = 0; $j <= $#{$languagesarrayref}; $j++ ) # iterating over all languages 332 { 333 my $onelanguage = ${$languagesarrayref}[$j]; 334 335 my %oneitemhash = (); 336 337 foreach $key (keys %{$oneitem}) 338 { 339 if ( $key =~ /\(\S+\)/ ) # this are the language dependent keys 340 { 341 if ( $key =~ /\(\Q$onelanguage\E\)/ ) 342 { 343 $value = $oneitem->{$key}; 344 $oneitemhash{$key} = $value; 345 } 346 } 347 else 348 { 349 $value = $oneitem->{$key}; 350 $oneitemhash{$key} = $value; 351 } 352 } 353 354 $oneitemhash{'specificlanguage'} = $onelanguage; 355 356 if ( $oneitemhash{'haslanguagemodule'} ) 357 { 358 my $langmodulestring = get_languagespecific_module($onelanguage, $oneitemhash{'modules'}); 359 $oneitemhash{'modules'} = $langmodulestring; 360 } 361 362 push(@itemsinalllanguages, \%oneitemhash); 363 } 364 } 365 } 366 367 return \@itemsinalllanguages; 368} 369 370################################################################################ 371# Removing all modules, that have the flag LANGUAGEMODULE, but do not 372# have the correct language 373################################################################################ 374 375sub remove_not_required_language_modules 376{ 377 my ($modulesarrayref, $languagesarrayref) = @_; 378 379 my @allmodules = (); 380 381 for ( my $i = 0; $i <= $#{$modulesarrayref}; $i++ ) 382 { 383 my $module = ${$modulesarrayref}[$i]; 384 my $styles = ""; 385 if ( $module->{'Styles'} ) { $styles = $module->{'Styles'}; } 386 387 if ( $styles =~ /\bLANGUAGEMODULE\b/ ) 388 { 389 if ( ! exists($module->{'Language'}) ) { installer::exiter::exit_program("ERROR: \"$module->{'gid'}\" has flag LANGUAGEMODULE, but does not know its language!", "remove_not_required_language_modules"); } 390 my $modulelanguage = $module->{'Language'}; 391 # checking, if language is required 392 my $doinclude = 0; 393 for ( my $j = 0; $j <= $#{$languagesarrayref}; $j++ ) 394 { 395 my $onelanguage = ${$languagesarrayref}[$j]; 396 if ( $onelanguage eq $modulelanguage ) 397 { 398 $doinclude = 1; 399 last; 400 } 401 } 402 403 if ( $doinclude ) { push(@allmodules, $module); } 404 } 405 else 406 { 407 push(@allmodules, $module); 408 } 409 } 410 411 return \@allmodules; 412} 413 414################################################################################ 415# Removing all modules, that have a spellchecker language that is not 416# required for this product (spellchecker selection). 417# All required spellchecker languages are stored in 418# %installer::globals::spellcheckerlanguagehash 419################################################################################ 420 421sub remove_not_required_spellcheckerlanguage_modules 422{ 423 my ($modulesarrayref) = @_; 424 425 my $infoline = ""; 426 my @allmodules = (); 427 428 for ( my $i = 0; $i <= $#{$modulesarrayref}; $i++ ) 429 { 430 my $module = ${$modulesarrayref}[$i]; 431 if ( $module->{'Spellcheckerlanguage'} ) # selecting modules with Spellcheckerlanguage 432 { 433 if ( exists($installer::globals::spellcheckerlanguagehash{$module->{'Spellcheckerlanguage'}}) ) 434 { 435 push(@allmodules, $module); 436 } 437 else 438 { 439 $infoline = "Spellchecker selection: Removing module $module->{'gid'}\n"; 440 push( @installer::globals::logfileinfo, $infoline); 441 442 # Collecting all files at modules that are removed 443 444 if ( $module->{'Files'} ) 445 { 446 if ( $module->{'Files'} =~ /^\s*\((.*?)\)\s*$/ ) 447 { 448 my $filelist = $1; 449 450 my $filelisthash = installer::converter::convert_stringlist_into_hash(\$filelist, ","); 451 foreach my $onefile ( keys %{$filelisthash} ) { $installer::globals::spellcheckerfilehash{$onefile} = 1; } 452 } 453 } 454 } 455 } 456 else 457 { 458 push(@allmodules, $module); 459 } 460 } 461 462 return \@allmodules; 463} 464 465################################################################################ 466# Removing all modules, that belong to a module that was removed 467# in "remove_not_required_spellcheckerlanguage_modules" because of the 468# spellchecker language. The files belonging to the modules are collected 469# in %installer::globals::spellcheckerfilehash. 470################################################################################ 471 472sub remove_not_required_spellcheckerlanguage_files 473{ 474 my ($filesarrayref) = @_; 475 476 my @filesarray = (); 477 my $infoline = ""; 478 479 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ ) 480 { 481 my $onefile = ${$filesarrayref}[$i]; 482 if ( exists($installer::globals::spellcheckerfilehash{$onefile->{'gid'}}) ) 483 { 484 $infoline = "Spellchecker selection: Removing file $onefile->{'gid'}\n"; 485 push( @installer::globals::logfileinfo, $infoline); 486 next; 487 } 488 push(@filesarray, $onefile); 489 } 490 491 return \@filesarray; 492} 493 494=head3 add_bundled_extension_blobs(@filelist) 495 496 Add entries for extension blobs to the global file list. 497 Extension blobs, unlike preregistered extensions, are not 498 extracted before included into a pack set. 499 500 The set of extensions to include is taken from the BUNDLED_EXTENSION_BLOBS 501 environment variable (typically set in configure.) 502 503 If that variable is not defined then the content of main/extensions.lst defines 504 the default set. 505 506 Extension blobs are placed in gid_Brand_Dir_Share_Extensions_Install. 507 508=cut 509sub add_bundled_extension_blobs 510{ 511 my @filelist = @{$_[0]}; 512 513 my @bundle_files = (); 514 my $bundleenv = $ENV{'BUNDLED_EXTENSION_BLOBS'}; 515 my $bundlehttpsrc = $ENV{'TARFILE_LOCATION'} . $installer::globals::separator; 516 my $bundlefilesrc = $ENV{SOLARVERSION} 517 . $installer::globals::separator . $ENV{INPATH} 518 . $installer::globals::separator . "bin" 519 . $installer::globals::separator; 520 521 if ($installer::globals::product =~ /(SDK|URE)/i ) 522 { 523 # No extensions for the SDK. 524 } 525 elsif (defined $bundleenv) 526 { 527 # Use the list of extensions that was explicitly given to configure. 528 for my $name (split(/\s+/, $bundleenv, -1)) 529 { 530 push @bundle_files, $bundlehttpsrc . $name; 531 } 532 } 533 else 534 { 535 # Add the default extensions for the current language set. 536 # http:// extensions are taken from ext_sources/. 537 for my $name (ExtensionsLst::GetExtensionList("http|https", @installer::globals::languageproducts)) 538 { 539 push @bundle_files, $bundlehttpsrc . $name; 540 } 541 # file:// extensions are taken from the solver bin/ directory. 542 for my $name (ExtensionsLst::GetExtensionList("file", @installer::globals::languageproducts)) 543 { 544 push @bundle_files, $bundlefilesrc . $name; 545 } 546 } 547 548 installer::logger::print_message( 549 sprintf("preparing %d extension blob%s for language%s %s:\n", 550 $#bundle_files + 1, 551 $#bundle_files!=0 ? "s" : "", 552 $#installer::globals::languageproducts!=0 ? "s" : "", 553 join(" ", @installer::globals::languageproducts), 554 join("\n ", @bundle_files))); 555 556 foreach my $filename ( @bundle_files) 557 { 558 my $basename = File::Basename::basename( $filename); 559 my $onefile = { 560 'Dir' => 'gid_Brand_Dir_Share_Extensions_Install', 561 'Name' => $basename, 562 'Styles' => '(PACKED)', 563 'UnixRights' => '444', 564 'sourcepath' => $filename, 565 'modules' => "gid_Module_Dictionaries", 566 'gid' => "gid_File_Extension_".$basename 567 }; 568 push( @filelist, $onefile); 569 push( @installer::globals::logfileinfo, "\tbundling \"$filename\" extension\n"); 570 571 installer::logger::print_message(" " . $basename . "\n"); 572 } 573 574 return \@filelist; 575} 576 577=head3 add_bundled_prereg_extensions(@filelist) 578 579 Add entries for preregistered extensions to the global file list. 580 581 The set of extensions to include is taken from the BUNDLED_PREREG_EXTENSIONS 582 environment variable (typically set in configure.) 583 584 If that variable is not defined then the content of main/extensions.lst defines 585 the default set. 586 587 Preregistered extensions are placed in subdirectories of gid_Brand_Dir_Share_Prereg_Bundled. 588 589=cut 590sub add_bundled_prereg_extensions 591{ 592 my @filelist = @{$_[0]}; 593 my $dirsref = $_[1]; 594 595 my @bundle_files = (); 596 my $bundleenv = $ENV{'BUNDLED_PREREG_EXTENSIONS'}; 597 598 if ($installer::globals::product =~ /(SDK|URE)/i ) 599 { 600 # No extensions for the SDK. 601 } 602 elsif (defined $bundleenv) 603 { 604 # Use the list of extensions that was explicitly given to configure. 605 @bundle_files = split(/\s+/, $bundleenv, -1); 606 } 607 else 608 { 609 # Add the default rextensions for the current language set. 610 611 # file:// URLs are currently handled by add_bundled_extension_blobs(@), therefore 612 # we may not their handling here anmore. 613 # @bundle_files = ExtensionsLst::GetExtensionList("file", @installer::globals::languageproducts); 614 } 615 616 installer::logger::print_message( 617 sprintf("preparing %d bundled extension%s for language%s %s:\n %s\n", 618 $#bundle_files + 1, 619 $#bundle_files!=0 ? "s" : "", 620 $#installer::globals::languageproducts!=0 ? "s" : "", 621 join(" ", @installer::globals::languageproducts), 622 join("\n ", @bundle_files))); 623 624 # Find the prereg directory entry so that we can create a new sub-directory. 625 my $parentdir_gid = "gid_Brand_Dir_Share_Prereg_Bundled"; 626 my $parentdir = undef; 627 foreach my $dir (@{$dirsref}) 628 { 629 if ($dir->{'gid'} eq $parentdir_gid) 630 { 631 $parentdir = $dir; 632 last; 633 } 634 } 635 636 foreach my $filename ( @bundle_files) 637 { 638 my $basename = File::Basename::basename( $filename); 639 640 # Create a new directory into which the extension will be installed. 641 my $dirgid = $parentdir_gid . "_" . $basename; 642 my $onedir = { 643 'modules' => 'gid_Module_Root_Brand', 644 'ismultilingual' => 0, 645 'Styles' => '(CREATE)', 646 'ParentID' => $parentdir_gid, 647 'specificlanguage' => "", 648 'haslanguagemodule' => 0, 649 'gid' => $dirgid, 650 'HostName' => $parentdir->{'HostName'} . $installer::globals::separator . $basename 651 }; 652 push (@{$dirsref}, $onedir); 653 654 # Create a new file entry for the extension. 655 my $onefile = { 656 'Dir' => $dirgid, 657 'Name' => $basename, 658 'Styles' => '(PACKED,ARCHIVE)', 659 'UnixRights' => '444', 660 'sourcepath' => File::Spec->catfile($ENV{'OUTDIR'}, "bin", $filename), 661 'specificlanguage' => "", 662 'modules' => "gid_Module_Dictionaries", 663 'gid' => "gid_File_Extension_".$basename 664 }; 665 push( @filelist, $onefile); 666 push( @installer::globals::logfileinfo, "\tbundling \"$filename\" extension\n"); 667 } 668 669 return (\@filelist, $dirsref); 670} 671 672################################################################################ 673# Looking for directories without correct HostName 674################################################################################ 675 676sub checking_directories_with_corrupt_hostname 677{ 678 my ($dirsref, $languagesarrayref) = @_; 679 680 for ( my $i = 0; $i <= $#{$dirsref}; $i++ ) 681 { 682 my $onedir = ${$dirsref}[$i]; 683 684 my $hostname = ""; 685 686 if ( $onedir->{'HostName'} ) { $hostname = $onedir->{'HostName'}; } 687 688 if ( $hostname eq "" ) 689 { 690 my $langstring = ""; 691 for ( my $j = 0; $j <= $#{$languagesarrayref}; $j++ ) { $langstring .= ${$languagesarrayref}[$j] . " "; } 692 installer::exiter::exit_program("ERROR: HostName not defined for $onedir->{'gid'} for specified language. Probably you wanted to create an installation set, in a language not defined in scp2 project. You selected the following language(s): $langstring", "checking_directories_with_corrupt_hostname"); 693 } 694 695 if ( $hostname eq "FAILURE" ) 696 { 697 installer::exiter::exit_program("ERROR: Could not create HostName for $onedir->{'gid'} (missing language at parent). See logfile warning for more info!", "checking_directories_with_corrupt_hostname"); 698 } 699 } 700} 701 702################################################################################ 703# Setting global properties 704################################################################################ 705 706sub set_global_directory_hostnames 707{ 708 my ($dirsref, $allvariables) = @_; 709 710 for ( my $i = 0; $i <= $#{$dirsref}; $i++ ) 711 { 712 my $onedir = ${$dirsref}[$i]; 713 my $styles = ""; 714 if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; } 715 716 if ( $styles =~ /\bOFFICEDIRECTORY\b/ ) 717 { 718 $installer::globals::officedirhostname = $onedir->{'HostName'}; 719 $installer::globals::officedirgid = $onedir->{'gid'}; 720 $allvariables->{'OFFICEDIRECTORYHOSTNAME'} = $installer::globals::officedirhostname; 721 } 722 if ( $styles =~ /\bSUNDIRECTORY\b/ ) 723 { 724 $installer::globals::sundirhostname = $onedir->{'HostName'}; 725 $installer::globals::sundirgid = $onedir->{'gid'}; 726 $allvariables->{'SUNDIRECTORYHOSTNAME'} = $installer::globals::sundirhostname; 727 } 728 } 729} 730 731######################################################## 732# Recursively defined procedure to order 733# modules and directories 734######################################################## 735 736sub get_children 737{ 738 my ($allitems, $startparent, $newitemorder) = @_; 739 740 for ( my $i = 0; $i <= $#{$allitems}; $i++ ) 741 { 742 my $gid = ${$allitems}[$i]->{'gid'}; 743 my $parent = ""; 744 if ( ${$allitems}[$i]->{'ParentID'} ) { $parent = ${$allitems}[$i]->{'ParentID'}; } 745 746 if ( $parent eq $startparent ) 747 { 748 push(@{$newitemorder}, ${$allitems}[$i]); 749 my $parent = $gid; 750 get_children($allitems, $parent, $newitemorder); # recursive! 751 } 752 } 753} 754 755################################################################################ 756# Using different HostName for language packs 757################################################################################ 758 759sub use_langpack_hostname 760{ 761 my ($dirsref) = @_; 762 763 for ( my $i = 0; $i <= $#{$dirsref}; $i++ ) 764 { 765 my $onedir = ${$dirsref}[$i]; 766 if (( $onedir->{'LangPackHostName'} ) && ( $onedir->{'LangPackHostName'} ne "" )) { $onedir->{'HostName'} = $onedir->{'LangPackHostName'}; } 767 } 768} 769 770################################################################################ 771# Using different HostName for language packs 772################################################################################ 773 774sub use_patch_hostname 775{ 776 my ($dirsref) = @_; 777 778 for ( my $i = 0; $i <= $#{$dirsref}; $i++ ) 779 { 780 my $onedir = ${$dirsref}[$i]; 781 if (( $onedir->{'PatchHostName'} ) && ( $onedir->{'PatchHostName'} ne "" )) { $onedir->{'HostName'} = $onedir->{'PatchHostName'}; } 782 } 783} 784 785################################################################################ 786# Using langpack copy action for language packs 787################################################################################ 788 789sub use_langpack_copy_scpaction 790{ 791 my ($scpactionsref) = @_; 792 793 for ( my $i = 0; $i <= $#{$scpactionsref}; $i++ ) 794 { 795 my $onescpaction = ${$scpactionsref}[$i]; 796 if (( $onescpaction->{'LangPackCopy'} ) && ( $onescpaction->{'LangPackCopy'} ne "" )) { $onescpaction->{'Copy'} = $onescpaction->{'LangPackCopy'}; } 797 } 798} 799 800################################################################################ 801# Using copy patch action 802################################################################################ 803 804sub use_patch_copy_scpaction 805{ 806 my ($scpactionsref) = @_; 807 808 for ( my $i = 0; $i <= $#{$scpactionsref}; $i++ ) 809 { 810 my $onescpaction = ${$scpactionsref}[$i]; 811 if (( $onescpaction->{'PatchCopy'} ) && ( $onescpaction->{'PatchCopy'} ne "" )) { $onescpaction->{'Copy'} = $onescpaction->{'PatchCopy'}; } 812 } 813} 814 815################################################################################ 816# Using dev copy patch action for developer snapshot builds 817################################################################################ 818 819sub use_dev_copy_scpaction 820{ 821 my ($scpactionsref) = @_; 822 823 for ( my $i = 0; $i <= $#{$scpactionsref}; $i++ ) 824 { 825 my $onescpaction = ${$scpactionsref}[$i]; 826 if (( $onescpaction->{'DevCopy'} ) && ( $onescpaction->{'DevCopy'} ne "" )) { $onescpaction->{'Copy'} = $onescpaction->{'DevCopy'}; } 827 } 828} 829 830################################################################################ 831# Shifting parent directories of URE and Basis layer, so that 832# these directories are located below the Brand layer. 833# Style: SHIFT_BASIS_INTO_BRAND_LAYER 834################################################################################ 835 836sub shift_basis_directory_parents 837{ 838 my ($dirsref) = @_; 839 840 my @alldirs = (); 841 my @savedirs = (); 842 my @shifteddirs = (); 843 844 my $officedirgid = ""; 845 846 for ( my $i = 0; $i <= $#{$dirsref}; $i++ ) 847 { 848 my $onedir = ${$dirsref}[$i]; 849 my $styles = ""; 850 if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; } 851 852 if ( $styles =~ /\bOFFICEDIRECTORY\b/ ) { $officedirgid = $onedir->{'gid'}; } 853 } 854 855 if ( $officedirgid ne "" ) 856 { 857 for ( my $i = 0; $i <= $#{$dirsref}; $i++ ) 858 { 859 my $onedir = ${$dirsref}[$i]; 860 my $styles = ""; 861 if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; } 862 863 if (( $styles =~ /\bBASISDIRECTORY\b/ ) || ( $styles =~ /\bUREDIRECTORY\b/ )) 864 { 865 $onedir->{'ParentID'} = $officedirgid; 866 } 867 } 868 869 # Sorting directories 870 my $startgid = "PREDEFINED_PROGDIR"; 871 get_children($dirsref, $startgid, \@alldirs); 872 } 873 874 return \@alldirs; 875} 876 877################################################################################ 878# Setting the name of the directory with style OFFICEDIRECTORY. 879# The name can be defined in property OFFICEDIRECTORYNAME. 880################################################################################ 881 882sub set_officedirectory_name 883{ 884 my ($dirsref, $officedirname) = @_; 885 886 for ( my $i = 0; $i <= $#{$dirsref}; $i++ ) 887 { 888 my $onedir = ${$dirsref}[$i]; 889 my $styles = ""; 890 if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; } 891 if ( $styles =~ /\bOFFICEDIRECTORY\b/ ) 892 { 893 $onedir->{'HostName'} = $officedirname; 894 last; 895 } 896 } 897} 898 899################################################################################ 900# Simplifying the name for language dependent items from "Name (xy)" to "Name" 901################################################################################ 902 903sub changing_name_of_language_dependent_keys 904{ 905 my ($itemsarrayref) = @_; 906 907 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::changing_name_of_language_dependent_keys : $#{$itemsarrayref}"); } 908 909 # Changing key for multilingual items from "Name ( )" to "Name" or "HostName ( )" to "HostName" 910 911 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ ) 912 { 913 my $oneitem = ${$itemsarrayref}[$i]; 914 my $onelanguage = $oneitem->{'specificlanguage'}; 915 916 if (!($onelanguage eq "" )) # language dependent item 917 { 918 my $itemkey; 919 920 foreach $itemkey (keys %{$oneitem}) 921 { 922 if ( $itemkey =~ /^\s*(\S+?)\s+\(\S+\)\s*$/ ) 923 { 924 my $newitemkey = $1; 925 my $itemvalue = $oneitem->{$itemkey}; 926 $oneitem->{$newitemkey} = $itemvalue; 927 delete($oneitem->{$itemkey}); 928 } 929 } 930 } 931 } 932} 933 934################################################################################ 935# Collecting language specific names for language packs 936################################################################################ 937 938sub collect_language_specific_names 939{ 940 my ($itemsarrayref) = @_; 941 942 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ ) 943 { 944 my $oneitem = ${$itemsarrayref}[$i]; 945 my $styles = ""; 946 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; } 947 948 if ( $styles =~ /\bUSELANGUAGENAME\b/ ) 949 { 950 my $language = ""; 951 if ( $oneitem->{'Language'} ) { $language = $oneitem->{'Language'}; } 952 my $specificlanguage = ""; 953 if ( $oneitem->{'specificlanguage'} ) { $specificlanguage = $oneitem->{'specificlanguage'}; } 954 955 if (( $language ne "" ) && ( $language eq $specificlanguage )) 956 { 957 if (! installer::existence::exists_in_array($oneitem->{'Name'}, \@installer::globals::languagenames )) 958 { 959 push(@installer::globals::languagenames, $oneitem->{'Name'}); 960 } 961 } 962 } 963 } 964} 965 966################################################################################ 967# Replacement of setup variables in ConfigurationItems and ProfileItems 968# <productkey>, <buildid>, <sequence_languages>, <productcode>, <upgradecode>, <productupdate> 969################################################################################ 970 971sub replace_setup_variables 972{ 973 my ($itemsarrayref, $languagestringref, $hashref) = @_; 974 975 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::replace_setup_variables : $#{$itemsarrayref} : $$languagestringref : $hashref->{'PRODUCTNAME'}"); } 976 977 my $languagesstring = $$languagestringref; 978 $languagesstring =~ s/\_/ /g; # replacing underscore with whitespace 979 # $languagesstring is "01 49" instead of "en-US de" 980 installer::languages::fake_languagesstring(\$languagesstring); 981 982 my $productname = $hashref->{'PRODUCTNAME'}; 983 my $productversion = $hashref->{'PRODUCTVERSION'}; 984 my $userdirproductversion = ""; 985 if ( $hashref->{'USERDIRPRODUCTVERSION'} ) { $userdirproductversion = $hashref->{'USERDIRPRODUCTVERSION'}; } 986 my $productkey = $productname . " " . $productversion; 987 988 my $scsrevision; 989 $scsrevision = "" unless ( $scsrevision = SvnRevision::DetectRevisionId(File::Spec->catfile($ENV{'SRC_ROOT'}, File::Spec->updir())) ); 990 991 # string $buildid, which is used to replace the setup variable <buildid> 992 993 my $localminor = "flat"; 994 if ( $installer::globals::minor ne "" ) { $localminor = $installer::globals::minor; } 995 else { $localminor = $installer::globals::lastminor; } 996 997 my $localbuild = $installer::globals::build; 998 999 if ( $localbuild =~ /^\s*(\w+?)(\d+)\s*$/ ) { $localbuild = $2; } # using "680" instead of "src680" 1000 1001 my $buildidstring = $localbuild . $localminor . "(Build:" . $installer::globals::buildid . ")"; 1002 1003 # the environment variable CWS_WORK_STAMP is set only in CWS 1004 if ( $ENV{'CWS_WORK_STAMP'} ) { $buildidstring = $buildidstring . "\[CWS\:" . $ENV{'CWS_WORK_STAMP'} . "\]"; } 1005 1006 if ( $localminor =~ /^\s*\w(\d+)\w*\s*$/ ) { $localminor = $1; } 1007 1008 # $updateid 1009 my $updateid = $productname . "_" . $userdirproductversion . "_" . $$languagestringref; 1010 $updateid =~ s/ /_/g; 1011 1012 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ ) 1013 { 1014 my $oneitem = ${$itemsarrayref}[$i]; 1015 my $value = $oneitem->{'Value'}; 1016 1017 $value =~ s/\<buildid\>/$buildidstring/; 1018 $value =~ s/\<scsrevision\>/$scsrevision/; 1019 $value =~ s/\<sequence_languages\>/$languagesstring/; 1020 $value =~ s/\<productkey\>/$productkey/; 1021 $value =~ s/\<productcode\>/$installer::globals::productcode/; 1022 $value =~ s/\<upgradecode\>/$installer::globals::upgradecode/; 1023 $value =~ s/\<alllanguages\>/$languagesstring/; 1024 $value =~ s/\<productmajor\>/$localbuild/; 1025 $value =~ s/\<productminor\>/$localminor/; 1026 $value =~ s/\<productbuildid\>/$installer::globals::buildid/; 1027 $value =~ s/\<sourceid\>/$installer::globals::build/; 1028 $value =~ s/\<updateid\>/$updateid/; 1029 $value =~ s/\<pkgformat\>/$installer::globals::packageformat/; 1030 1031 $oneitem->{'Value'} = $value; 1032 } 1033} 1034 1035################################################################################ 1036# By defining variable LOCALUSERDIR in *.lst it is possible to change 1037# the standard destination of user directory defined in scp2 ($SYSUSERCONFIG). 1038################################################################################ 1039 1040sub replace_userdir_variable 1041{ 1042 my ($itemsarrayref) = @_; 1043 1044 my $userdir = ""; 1045 if ( $allvariableshashref->{'LOCALUSERDIR'} ) { $userdir = $allvariableshashref->{'LOCALUSERDIR'}; } 1046 else { $userdir = $installer::globals::simpledefaultuserdir; } 1047 1048 if ( $userdir ne "" ) 1049 { 1050 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ ) 1051 { 1052 my $oneitem = ${$itemsarrayref}[$i]; 1053 $oneitem->{'Value'} =~ s/\$SYSUSERCONFIG/$userdir/; 1054 } 1055 } 1056} 1057 1058##################################################################################### 1059# Files and ConfigurationItems are not included for all languages. 1060# For instance asian fonts. These can be removed, if no "Name" is found. 1061# ConfigurationItems are not always defined in the linguistic configuration file. 1062# The "Key" cannot be found for them. 1063##################################################################################### 1064 1065sub remove_non_existent_languages_in_productlists 1066{ 1067 my ($itemsarrayref, $languagestringref, $searchkey, $itemtype) = @_; 1068 1069 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::remove_non_existent_languages_in_productlists : $#{$itemsarrayref} : $$languagestringref : $searchkey : $itemtype"); } 1070 1071 # Removing of all non existent files, for instance asian fonts 1072 1073 installer::logger::include_header_into_logfile("Removing for this language $$languagestringref:"); 1074 1075 my @allexistentitems = (); 1076 1077 my $infoline; 1078 1079 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ ) 1080 { 1081 my $oneitem = ${$itemsarrayref}[$i]; 1082 my $oneitemname = ""; # $searchkey is "Name" for files and "Key" for ConfigurationItems 1083 1084 if ( $oneitem->{$searchkey} ) { $oneitemname = $oneitem->{$searchkey} } 1085 1086 my $itemtoberemoved = 0; 1087 1088 if ($oneitemname eq "") # for instance asian font in english installation set 1089 { 1090 $itemtoberemoved = 1; 1091 } 1092 1093 if ($itemtoberemoved) 1094 { 1095 $infoline = "WARNING: Language $$languagestringref: No $itemtype packed for $oneitem->{'gid'}!\n"; 1096 push( @installer::globals::logfileinfo, $infoline); 1097 } 1098 else 1099 { 1100 push(@allexistentitems, $oneitem); 1101 } 1102 } 1103 1104 $infoline = "\n"; 1105 push( @installer::globals::logfileinfo, $infoline); 1106 1107 return \@allexistentitems; 1108} 1109 1110######################################################################## 1111# Input is the directory gid, output the "HostName" of the directory 1112######################################################################## 1113 1114sub get_Directoryname_From_Directorygid 1115{ 1116 my ($dirsarrayref ,$searchgid, $onelanguage, $oneitemgid) = @_; 1117 1118 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::get_Directoryname_From_Directorygid : $#{$dirsarrayref} : $searchgid : $onelanguage"); } 1119 1120 my $directoryname = ""; 1121 my $onedirectory; 1122 my $foundgid = 0; 1123 1124 for ( my $i = 0; $i <= $#{$dirsarrayref}; $i++ ) 1125 { 1126 $onedirectory = ${$dirsarrayref}[$i]; 1127 my $directorygid = $onedirectory->{'gid'}; 1128 1129 if ($directorygid eq $searchgid) 1130 { 1131 $foundgid = 1; 1132 last; 1133 } 1134 } 1135 1136 if (!($foundgid)) 1137 { 1138 installer::exiter::exit_program("ERROR: Gid $searchgid not defined in $installer::globals::setupscriptname", "get_Directoryname_From_Directorygid"); 1139 } 1140 1141 if ( ! ( $onedirectory->{'ismultilingual'} )) # the directory is not language dependent 1142 { 1143 $directoryname = $onedirectory->{'HostName'}; 1144 } 1145 else 1146 { 1147 $directoryname = $onedirectory->{"HostName ($onelanguage)"}; 1148 } 1149 1150 # gid_Dir_Template_Wizard_Letter is defined as language dependent directory, but the file gid_Dir_Template_Wizard_Letter 1151 # is not language dependent. Therefore $onelanguage is not defined. But which language is the correct language for the 1152 # directory? 1153 # Perhaps better solution: In scp it must be forbidden to have a language independent file in a language dependent directory. 1154 1155 if (( ! $directoryname ) && ( $onelanguage eq "" )) 1156 { 1157 installer::exiter::exit_program("ERROR (in scp): Directory $searchgid is language dependent, but not $oneitemgid inside this directory", "get_Directoryname_From_Directorygid"); 1158 } 1159 1160 return \$directoryname; 1161} 1162 1163################################################################## 1164# Getting destination directory for links, files and profiles 1165################################################################## 1166 1167sub get_Destination_Directory_For_Item_From_Directorylist # this is used for Files, Profiles and Links 1168{ 1169 my ($itemarrayref, $dirsarrayref) = @_; 1170 1171 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::get_Destination_Directory_For_Item_From_Directorylist : $#{$itemarrayref} : $#{$dirsarrayref}"); } 1172 1173 for ( my $i = 0; $i <= $#{$itemarrayref}; $i++ ) 1174 { 1175 my $oneitem = ${$itemarrayref}[$i]; 1176 my $oneitemgid = $oneitem->{'gid'}; 1177 my $directorygid = $oneitem->{'Dir'}; # for instance gid_Dir_Program 1178 my $netdirectorygid = ""; 1179 my $onelanguage = $oneitem->{'specificlanguage'}; 1180 my $ispredefinedprogdir = 0; 1181 my $ispredefinedconfigdir = 0; 1182 1183 my $oneitemname = $oneitem->{'Name'}; 1184 1185 if ( $oneitem->{'NetDir'} ) { $netdirectorygid = $oneitem->{'NetDir'}; } 1186 1187 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$oneitemname); # making /registry/schema/org/openoffice/VCL.xcs to VCL.xcs 1188 1189 my $searchdirgid; 1190 1191 if ( $netdirectorygid eq "" ) # if NetDir is defined, it is privileged 1192 { 1193 $searchdirgid = $directorygid 1194 } 1195 else 1196 { 1197 $searchdirgid = $netdirectorygid 1198 } 1199 1200 if ($searchdirgid =~ /PREDEFINED_PROGDIR/) # the root directory is not defined in setup script 1201 { 1202 $ispredefinedprogdir = 1; 1203 } 1204 1205 if ($searchdirgid =~ /PREDEFINED_CONFIGDIR/) # the root directory is not defined in setup script 1206 { 1207 $ispredefinedconfigdir = 1; 1208 } 1209 1210 my $destfilename; 1211 1212 if ((!( $ispredefinedprogdir )) && (!( $ispredefinedconfigdir ))) 1213 { 1214 my $directorynameref = get_Directoryname_From_Directorygid($dirsarrayref, $searchdirgid, $onelanguage, $oneitemgid); 1215 $destfilename = $$directorynameref . $installer::globals::separator . $oneitemname; 1216 } 1217 else 1218 { 1219 $destfilename = $oneitemname; 1220 } 1221 1222 $oneitem->{'destination'} = $destfilename; 1223 } 1224} 1225 1226########################################################################## 1227# Searching a file in a list of pathes 1228########################################################################## 1229 1230sub get_sourcepath_from_filename_and_includepath_classic 1231{ 1232 my ($searchfilenameref, $includepatharrayref, $write_logfile) = @_; 1233 1234 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic : $$searchfilenameref : $#{$includepatharrayref} : $write_logfile"); } 1235 1236 my ($onefile, $includepath, $infoline); 1237 1238 my $foundsourcefile = 0; 1239 1240 for ( my $j = 0; $j <= $#{$includepatharrayref}; $j++ ) 1241 { 1242 $includepath = ${$includepatharrayref}[$j]; 1243 installer::remover::remove_leading_and_ending_whitespaces(\$includepath); 1244 1245 $onefile = $includepath . $installer::globals::separator . $$searchfilenameref; 1246 1247 if ( -f $onefile ) 1248 { 1249 $foundsourcefile = 1; 1250 last; 1251 } 1252 } 1253 1254 if (!($foundsourcefile)) 1255 { 1256 $onefile = ""; # the sourcepath has to be empty 1257 if ( $write_logfile) 1258 { 1259 if ( $ENV{'DEFAULT_TO_ENGLISH_FOR_PACKING'} ) 1260 { 1261 $infoline = "WARNING: Source for $$searchfilenameref not found!\n"; # Important message in log file 1262 } 1263 else 1264 { 1265 $infoline = "ERROR: Source for $$searchfilenameref not found!\n"; # Important message in log file 1266 } 1267 1268 push( @installer::globals::logfileinfo, $infoline); 1269 } 1270 } 1271 else 1272 { 1273 if ( $write_logfile) 1274 { 1275 $infoline = "SUCCESS: Source for $$searchfilenameref: $onefile\n"; 1276 push( @installer::globals::logfileinfo, $infoline); 1277 } 1278 } 1279 1280 return \$onefile; 1281} 1282 1283########################################################################## 1284# Input is one file name, output the complete absolute path of this file 1285########################################################################## 1286 1287sub get_sourcepath_from_filename_and_includepath 1288{ 1289 my ($searchfilenameref, $unused, $write_logfile) = @_; 1290 1291 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::get_sourcepath_from_filename_and_includepath : $$searchfilenameref : $#{$includepatharrayref} : $write_logfile"); } 1292 1293 my ($onefile, $includepath, $infoline); 1294 1295 my $foundsourcefile = 0; 1296 my $foundnewname = 0; 1297 1298 for ( my $j = 0; $j <= $#installer::globals::allincludepathes; $j++ ) 1299 { 1300 my $allfiles = $installer::globals::allincludepathes[$j]; 1301 1302 if ( exists( $allfiles->{$$searchfilenameref} )) 1303 { 1304 $onefile = $allfiles->{'includepath'} . $installer::globals::separator . $$searchfilenameref; 1305 $foundsourcefile = 1; 1306 last; 1307 } 1308 } 1309 1310 if (!($foundsourcefile)) # testing with lowercase filename 1311 { 1312 # Attention: README01.html is copied for Windows to readme01.html, not case sensitive 1313 1314 for ( my $j = 0; $j <= $#installer::globals::allincludepathes; $j++ ) 1315 { 1316 my $allfiles = $installer::globals::allincludepathes[$j]; 1317 1318 my $newfilename = $$searchfilenameref; 1319 $newfilename =~ s/readme/README/; # special handling for readme files 1320 $newfilename =~ s/license/LICENSE/; # special handling for license files 1321 1322 if ( exists( $allfiles->{$newfilename} )) 1323 { 1324 $onefile = $allfiles->{'includepath'} . $installer::globals::separator . $newfilename; 1325 $foundsourcefile = 1; 1326 $foundnewname = 1; 1327 last; 1328 } 1329 } 1330 } 1331 1332 if (!($foundsourcefile)) 1333 { 1334 $onefile = ""; # the sourcepath has to be empty 1335 if ( $write_logfile) 1336 { 1337 if ( $ENV{'DEFAULT_TO_ENGLISH_FOR_PACKING'} ) 1338 { 1339 $infoline = "WARNING: Source for $$searchfilenameref not found!\n"; # Important message in log file 1340 } 1341 else 1342 { 1343 $infoline = "ERROR: Source for $$searchfilenameref not found!\n"; # Important message in log file 1344 } 1345 1346 push( @installer::globals::logfileinfo, $infoline); 1347 } 1348 } 1349 else 1350 { 1351 if ( $write_logfile) 1352 { 1353 if (!($foundnewname)) 1354 { 1355 $infoline = "SUCCESS: Source for $$searchfilenameref: $onefile\n"; 1356 } 1357 else 1358 { 1359 $infoline = "SUCCESS/WARNING: Special handling for $$searchfilenameref: $onefile\n"; 1360 } 1361 push( @installer::globals::logfileinfo, $infoline); 1362 } 1363 } 1364 1365 return \$onefile; 1366} 1367 1368############################################################## 1369# Determining, whether a specified directory is language 1370# dependent 1371############################################################## 1372 1373sub determine_directory_language_dependency 1374{ 1375 my($directorygid, $dirsref) = @_; 1376 1377 my $is_multilingual = 0; 1378 1379 for ( my $i = 0; $i <= $#{$dirsref}; $i++ ) 1380 { 1381 my $onedir = ${$dirsref}[$i]; 1382 my $gid = $onedir->{'gid'}; 1383 1384 if ( $gid eq $directorygid ) 1385 { 1386 $is_multilingual = $onedir->{'ismultilingual'}; 1387 last; 1388 } 1389 } 1390 1391 return $is_multilingual; 1392} 1393 1394############################################################## 1395# Getting all source pathes for all files to be packed 1396# $item can be "Files" or "ScpActions" 1397############################################################## 1398 1399sub get_Source_Directory_For_Files_From_Includepathlist 1400{ 1401 my ($filesarrayref, $includepatharrayref, $dirsref, $item) = @_; 1402 1403 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::get_Source_Directory_For_Files_From_Includepathlist : $#{$filesarrayref} : $#{$includepatharrayref} : $item"); } 1404 1405 installer::logger::include_header_into_logfile("$item:"); 1406 1407 my $infoline = ""; 1408 1409 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ ) 1410 { 1411 my $onefile = ${$filesarrayref}[$i]; 1412 my $onelanguage = $onefile->{'specificlanguage'}; 1413 1414 if ( ! $onefile->{'Name'} ) { installer::exiter::exit_program("ERROR: $item without name ! GID: $onefile->{'gid'} ! Language: $onelanguage", "get_Source_Directory_For_Files_From_Includepathlist"); } 1415 1416 my $onefilename = $onefile->{'Name'}; 1417 if ( $item eq "ScpActions" ) { $onefilename =~ s/\//$installer::globals::separator/g; } 1418 $onefilename =~ s/^\s*\Q$installer::globals::separator\E//; # filename begins with a slash, for instance /registry/schema/org/openoffice/VCL.xcs 1419 1420 my $styles = ""; 1421 my $file_can_miss = 0; 1422 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; } 1423 if ( $styles =~ /\bFILE_CAN_MISS\b/ ) { $file_can_miss = 1; } 1424 1425 if (( $installer::globals::languagepack ) && ( ! $onefile->{'ismultilingual'} ) && ( ! ( $styles =~ /\bFORCELANGUAGEPACK\b/ ))) { $file_can_miss = 1; } 1426 1427 my $sourcepathref = ""; 1428 1429 if ( $file_can_miss ) { $sourcepathref = get_sourcepath_from_filename_and_includepath(\$onefilename, $includepatharrayref, 0); } 1430 else { $sourcepathref = get_sourcepath_from_filename_and_includepath(\$onefilename, $includepatharrayref, 1); } 1431 1432 $onefile->{'sourcepath'} = $$sourcepathref; # This $$sourcepathref is empty, if no source was found 1433 1434 # defaulting to english for multilingual files if DEFAULT_TO_ENGLISH_FOR_PACKING is set 1435 1436 if ( $ENV{'DEFAULT_TO_ENGLISH_FOR_PACKING'} ) 1437 { 1438 if (( ! $onefile->{'sourcepath'} ) && ( $onefile->{'ismultilingual'} )) 1439 { 1440 my $oldname = $onefile->{'Name'}; 1441 my $oldlanguage = $onefile->{'specificlanguage'}; 1442 my $newlanguage = "en-US"; 1443 # $onefile->{'Name'} =~ s/$oldlanguage\./$newlanguage\./; # Example: tplwizfax_it.zip -> tplwizfax_en-US.zip 1444 $onefilename = $onefile->{'Name'}; 1445 $onefilename =~ s/$oldlanguage\./$newlanguage\./; # Example: tplwizfax_it.zip -> tplwizfax_en-US.zip 1446 $onefilename =~ s/^\s*\Q$installer::globals::separator\E//; # filename begins with a slash, for instance /registry/schema/org/openoffice/VCL.xcs 1447 $sourcepathref = get_sourcepath_from_filename_and_includepath(\$onefilename, $includepatharrayref, 1); 1448 $onefile->{'sourcepath'} = $$sourcepathref; # This $$sourcepathref is empty, if no source was found 1449 1450 if ($onefile->{'sourcepath'}) # defaulting to english was successful 1451 { 1452 $infoline = "WARNING: Using $onefilename instead of $oldname\n"; 1453 push( @installer::globals::logfileinfo, $infoline); 1454 print " $infoline"; 1455 # if ( $onefile->{'destination'} ) { $onefile->{'destination'} =~ s/\Q$oldname\E/$onefile->{'Name'}/; } 1456 1457 # If the directory, in which the new file is installed, is not language dependent, 1458 # the filename has to be changed to avoid installation conflicts 1459 # No mechanism for resource files! 1460 # -> implementing for the content of ARCHIVE files 1461 1462 if ( $onefile->{'Styles'} =~ /\bARCHIVE\b/ ) 1463 { 1464 my $directorygid = $onefile->{'Dir'}; 1465 my $islanguagedependent = determine_directory_language_dependency($directorygid, $dirsref); 1466 1467 if ( ! $islanguagedependent ) 1468 { 1469 $onefile->{'Styles'} =~ s/\bARCHIVE\b/ARCHIVE, RENAME_TO_LANGUAGE/; # Setting new flag RENAME_TO_LANGUAGE 1470 $infoline = "Setting flag RENAME_TO_LANGUAGE: File $onefile->{'Name'} in directory: $directorygid\n"; 1471 push( @installer::globals::logfileinfo, $infoline); 1472 } 1473 } 1474 } 1475 else 1476 { 1477 $infoline = "WARNING: Using $onefile->{'Name'} instead of $oldname was not successful\n"; 1478 push( @installer::globals::logfileinfo, $infoline); 1479 $onefile->{'Name'} = $oldname; # Switching back to old file name 1480 } 1481 } 1482 } 1483 } 1484 1485 $infoline = "\n"; # empty line after listing of all files 1486 push( @installer::globals::logfileinfo, $infoline); 1487} 1488 1489################################################################################# 1490# Removing files, that shall not be included into languagepacks 1491# (because of rpm conflicts) 1492################################################################################# 1493 1494sub remove_Files_For_Languagepacks 1495{ 1496 my ($itemsarrayref) = @_; 1497 1498 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::remove_Files_For_Languagepacks : $#{$filesarrayref}"); } 1499 1500 my $infoline; 1501 1502 my @newitemsarray = (); 1503 1504 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ ) 1505 { 1506 my $oneitem = ${$itemsarrayref}[$i]; 1507 my $gid = $oneitem->{'gid'}; 1508 1509 # scp Todo: Remove asap after removal of old setup 1510 1511 if (( $gid eq "gid_File_Extra_Fontunxpsprint" ) || 1512 ( $gid eq "gid_File_Extra_Migration_Lang" )) 1513 { 1514 $infoline = "ATTENTION: Removing item $oneitem->{'gid'} from the installation set.\n"; 1515 push( @installer::globals::logfileinfo, $infoline); 1516 1517 next; 1518 } 1519 1520 push(@newitemsarray, $oneitem); 1521 } 1522 1523 return \@newitemsarray; 1524} 1525 1526################################################################################# 1527# Files, whose source directory is not found, are removed now (this is an ERROR) 1528################################################################################# 1529 1530sub remove_Files_Without_Sourcedirectory 1531{ 1532 my ($filesarrayref) = @_; 1533 1534 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::remove_Files_Without_Sourcedirectory : $#{$filesarrayref}"); } 1535 1536 my $infoline; 1537 1538 my $error_occured = 0; 1539 my @missingfiles = (); 1540 push(@missingfiles, "ERROR: The following files could not be found: \n"); 1541 1542 my @newfilesarray = (); 1543 1544 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ ) 1545 { 1546 my $onefile = ${$filesarrayref}[$i]; 1547 my $sourcepath = $onefile->{'sourcepath'}; 1548 1549 if ($sourcepath eq "") 1550 { 1551 my $styles = $onefile->{'Styles'}; 1552 my $filename = $onefile->{'Name'}; 1553 1554 if ( ! $installer::globals::languagepack ) 1555 { 1556 $infoline = "ERROR: No sourcepath -> Removing file $filename from file list.\n"; 1557 push( @installer::globals::logfileinfo, $infoline); 1558 1559 push(@missingfiles, "ERROR: File not found: $filename\n"); 1560 $error_occured = 1; 1561 1562 next; # removing this file from list, if sourcepath is empty 1563 } 1564 else # special case for language packs 1565 { 1566 if (( $onefile->{'ismultilingual'} ) || ( $styles =~ /\bFORCELANGUAGEPACK\b/ )) 1567 { 1568 $infoline = "ERROR: Removing file $filename from file list.\n"; 1569 push( @installer::globals::logfileinfo, $infoline); 1570 1571 push(@missingfiles, "ERROR: File not found: $filename\n"); 1572 $error_occured = 1; 1573 1574 next; # removing this file from list, if sourcepath is empty 1575 } 1576 else 1577 { 1578 $infoline = "INFO: Removing file $filename from file list. It is not language dependent.\n"; 1579 push( @installer::globals::logfileinfo, $infoline); 1580 $infoline = "INFO: It is not language dependent and can be ignored in language packs.\n"; 1581 push( @installer::globals::logfileinfo, $infoline); 1582 1583 next; # removing this file from list, if sourcepath is empty 1584 } 1585 } 1586 } 1587 1588 push(@newfilesarray, $onefile); 1589 } 1590 1591 $infoline = "\n"; 1592 push( @installer::globals::logfileinfo, $infoline); 1593 1594 if ( $error_occured ) 1595 { 1596 for ( my $i = 0; $i <= $#missingfiles; $i++ ) { print "$missingfiles[$i]"; } 1597 installer::exiter::exit_program("ERROR: Missing files", "remove_Files_Without_Sourcedirectory"); 1598 } 1599 1600 return \@newfilesarray; 1601} 1602 1603############################################################################ 1604# License and Readme files in the default language have to be installed 1605# in the directory with flag OFFICEDIRECTORY. If this is not defined 1606# they have to be installed in the installation root. 1607############################################################################ 1608 1609sub get_office_directory_gid_and_hostname 1610{ 1611 my ($dirsarrayref) = @_; 1612 1613 my $foundofficedir = 0; 1614 my $gid = ""; 1615 my $hostname = ""; 1616 1617 for ( my $i = 0; $i <= $#{$dirsarrayref}; $i++ ) 1618 { 1619 my $onedir = ${$dirsarrayref}[$i]; 1620 if ( $onedir->{'Styles'} ) 1621 { 1622 my $styles = $onedir->{'Styles'}; 1623 1624 if ( $styles =~ /\bOFFICEDIRECTORY\b/ ) 1625 { 1626 $foundofficedir = 1; 1627 $gid = $onedir->{'gid'}; 1628 $hostname = $onedir->{'HostName'}; 1629 last; 1630 } 1631 } 1632 } 1633 1634 return ($foundofficedir, $gid, $hostname); 1635} 1636 1637############################################################################ 1638# License and Readme files in the default language have to be installed 1639# in the installation root (next to the program dir). This is in scp 1640# project done by a post install basic script 1641############################################################################ 1642 1643sub add_License_Files_into_Installdir 1644{ 1645 my ($filesarrayref, $dirsarrayref, $languagesarrayref) = @_; 1646 1647 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::add_License_Files_into_Installdir : $#{$filesarrayref} : $#{$languagesarrayref}"); } 1648 1649 my $infoline; 1650 1651 my @newfilesarray = (); 1652 1653 my $defaultlanguage = installer::languages::get_default_language($languagesarrayref); 1654 1655 my ($foundofficedir, $officedirectorygid, $officedirectoryhostname) = get_office_directory_gid_and_hostname($dirsarrayref); 1656 1657 # copy all files from directory share/readme, that contain the default language in their name 1658 # without default language into the installation root. This makes the settings of the correct 1659 # file names superfluous. On the other hand this requires a dependency to the directory 1660 # share/readme 1661 1662 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ ) 1663 { 1664 my $onefile = ${$filesarrayref}[$i]; 1665 my $destination = $onefile->{'destination'}; 1666 my $styles = ""; 1667 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; } 1668 1669 if ( ( $destination =~ /share\Q$installer::globals::separator\Ereadme\Q$installer::globals::separator\E(\w+?)_?$defaultlanguage\.?(\w*)\s*/ ) 1670 || (( $styles =~ /\bROOTLICENSEFILE\b/ ) && ( $destination =~ /\Q$installer::globals::separator\E?(\w+?)_?$defaultlanguage\.?(\w*?)\s*$/ )) ) 1671 { 1672 my $filename = $1; 1673 my $extension = $2; 1674 1675 my $newfilename; 1676 1677 if ( $extension eq "" ) { $newfilename = $filename; } 1678 else { $newfilename = $filename . "\." . $extension; } 1679 1680 my %newfile = (); 1681 my $newfile = \%newfile; 1682 1683 installer::converter::copy_item_object($onefile, $newfile); 1684 1685 $newfile->{'gid'} = $onefile->{'gid'} . "_Copy"; 1686 $newfile->{'Name'} = $newfilename; 1687 $newfile->{'ismultilingual'} = "0"; 1688 $newfile->{'specificlanguage'} = ""; 1689 $newfile->{'haslanguagemodule'} = "0"; 1690 1691 if ( defined $newfile->{'InstallName'} ) 1692 { 1693 if ( $newfile->{'InstallName'} =~ /^\s*(.*?)_$defaultlanguage\.?(\w*?)\s*$/ ) 1694 { 1695 my $localfilename = $1; 1696 my $localextension = $2; 1697 1698 if ( $localextension eq "" ) { $newfile->{'InstallName'} = $localfilename; } 1699 else { $newfile->{'InstallName'} = $localfilename . "\." . $localextension; } 1700 } 1701 } 1702 1703 $newfile->{'removelangfromfile'} = "1"; # Important for files with an InstallName, because language also has to be removed there. 1704 1705 if ( $foundofficedir ) 1706 { 1707 $newfile->{'Dir'} = $officedirectorygid; 1708 $newfile->{'destination'} = $officedirectoryhostname . $installer::globals::separator . $newfilename; 1709 } 1710 else 1711 { 1712 $newfile->{'Dir'} = "PREDEFINED_PROGDIR"; 1713 $newfile->{'destination'} = $newfilename; 1714 } 1715 1716 # Also setting "modules=gid_Module_Root_Brand" (module with style: ROOT_BRAND_PACKAGE) 1717 if ( $installer::globals::rootbrandpackageset ) 1718 { 1719 $newfile->{'modules'} = $installer::globals::rootbrandpackage; 1720 } 1721 1722 push(@newfilesarray, $newfile); 1723 1724 $infoline = "New files: Adding file $newfilename for the installation root to the file list. Language: $defaultlanguage\n"; 1725 push( @installer::globals::logfileinfo, $infoline); 1726 1727 if ( defined $newfile->{'InstallName'} ) 1728 { 1729 $infoline = "New files: Using installation name: $newfile->{'InstallName'}\n"; 1730 push( @installer::globals::logfileinfo, $infoline); 1731 } 1732 1733 # Collecting license and readme file for the installation set 1734 1735 push(@installer::globals::installsetfiles, $newfile); 1736 $infoline = "New files: Adding file $newfilename to the file collector for the installation set. Language: $defaultlanguage\n"; 1737 push( @installer::globals::logfileinfo, $infoline); 1738 } 1739 1740 push(@newfilesarray, $onefile); 1741 } 1742 1743 return \@newfilesarray; 1744} 1745 1746############################################################################ 1747# Removing files with flag ONLY_ASIA_LANGUAGE, only if no asian 1748# language is part of the product. 1749# This special files are connected to the root module and are not 1750# included into a language pack (would lead to conflicts!). 1751# But this files shall only be included into the product, if the 1752# product contains at least one asian language. 1753############################################################################ 1754 1755sub remove_onlyasialanguage_files_from_productlists 1756{ 1757 my ($filesarrayref) = @_; 1758 1759 my $infoline; 1760 1761 my @newfilesarray = (); 1762 my $returnfilesarrayref; 1763 1764 my $containsasianlanguage = installer::languages::detect_asian_language($installer::globals::alllanguagesinproductarrayref); 1765 1766 my $alllangstring = installer::converter::convert_array_to_comma_separated_string($installer::globals::alllanguagesinproductarrayref); 1767 $infoline = "\nLanguages in complete product: $alllangstring\n"; 1768 push( @installer::globals::logfileinfo, $infoline); 1769 1770 if ( ! $containsasianlanguage ) 1771 { 1772 $infoline = "Product does not contain asian language -> removing files\n"; 1773 push( @installer::globals::logfileinfo, $infoline); 1774 1775 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ ) 1776 { 1777 my $onefile = ${$filesarrayref}[$i]; 1778 my $styles = ""; 1779 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; } 1780 if ( $styles =~ /\bONLY_ASIA_LANGUAGE\b/ ) 1781 { 1782 $infoline = "Flag ONLY_ASIA_LANGUAGE: Removing file $onefile->{'Name'} from files collector!\n"; 1783 push( @installer::globals::logfileinfo, $infoline); 1784 next; 1785 } 1786 1787 push(@newfilesarray, $onefile); 1788 } 1789 1790 $returnfilesarrayref = \@newfilesarray; 1791 } 1792 else 1793 { 1794 $returnfilesarrayref = $filesarrayref; 1795 1796 $infoline = "Product contains asian language -> Nothing to do\n"; 1797 push( @installer::globals::logfileinfo, $infoline); 1798 1799 } 1800 1801 return $returnfilesarrayref; 1802} 1803 1804############################################################################ 1805# Removing files with flag ONLY_WESTERN_LANGUAGE, only if no western 1806# language is part of the product. 1807# This special files are connected to the root module and are not 1808# included into a language pack (would lead to conflicts!). 1809# But this files shall only be included into the product, if the 1810# product contains at least one western language. 1811############################################################################ 1812 1813sub remove_onlywesternlanguage_files_from_productlists 1814{ 1815 my ($filesarrayref) = @_; 1816 1817 my $infoline; 1818 1819 my @newfilesarray = (); 1820 my $returnfilesarrayref; 1821 1822 my $containswesternlanguage = installer::languages::detect_western_language($installer::globals::alllanguagesinproductarrayref); 1823 1824 my $alllangstring = installer::converter::convert_array_to_comma_separated_string($installer::globals::alllanguagesinproductarrayref); 1825 $infoline = "\nLanguages in complete product: $alllangstring\n"; 1826 push( @installer::globals::logfileinfo, $infoline); 1827 1828 if ( ! $containswesternlanguage ) 1829 { 1830 $infoline = "Product does not contain western language -> removing files\n"; 1831 push( @installer::globals::logfileinfo, $infoline); 1832 1833 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ ) 1834 { 1835 my $onefile = ${$filesarrayref}[$i]; 1836 my $styles = ""; 1837 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; } 1838 if ( $styles =~ /\bONLY_WESTERN_LANGUAGE\b/ ) 1839 { 1840 $infoline = "Flag ONLY_WESTERN_LANGUAGE: Removing file $onefile->{'Name'} from files collector!\n"; 1841 push( @installer::globals::logfileinfo, $infoline); 1842 next; 1843 } 1844 1845 push(@newfilesarray, $onefile); 1846 } 1847 1848 $returnfilesarrayref = \@newfilesarray; 1849 } 1850 else 1851 { 1852 $returnfilesarrayref = $filesarrayref; 1853 1854 $infoline = "Product contains western language -> Nothing to do\n"; 1855 push( @installer::globals::logfileinfo, $infoline); 1856 1857 } 1858 1859 return $returnfilesarrayref; 1860} 1861 1862############################################################################ 1863# Some files are included for more than one language and have the same 1864# name and the same destination directory for all languages. This would 1865# lead to conflicts, if the filenames are not changed. 1866# In scp project this files must have the flag MAKE_LANG_SPECIFIC 1867# For this files, the language is included into the filename. 1868############################################################################ 1869 1870sub make_filename_language_specific 1871{ 1872 my ($filesarrayref) = @_; 1873 1874 my $infoline = ""; 1875 1876 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ ) 1877 { 1878 my $onefile = ${$filesarrayref}[$i]; 1879 1880 if ( $onefile->{'ismultilingual'} ) 1881 { 1882 my $styles = ""; 1883 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; } 1884 if ( $styles =~ /\bMAKE_LANG_SPECIFIC\b/ ) 1885 { 1886 my $language = $onefile->{'specificlanguage'}; 1887 my $olddestination = $onefile->{'destination'}; 1888 my $oldname = $onefile->{'Name'}; 1889 1890 # Including the language into the file name. 1891 # But be sure, to include the language before the file extension. 1892 1893 my $fileextension = ""; 1894 1895 if ( $onefile->{'Name'} =~ /(\.\w+?)\s*$/ ) { $fileextension = $1; } 1896 if ( $fileextension ne "" ) 1897 { 1898 $onefile->{'Name'} =~ s/\Q$fileextension\E\s*$/_$language$fileextension/; 1899 $onefile->{'destination'} =~ s/\Q$fileextension\E\s*$/_$language$fileextension/; 1900 } 1901 1902 $infoline = "Flag MAKE_LANG_SPECIFIC:\n"; 1903 push( @installer::globals::logfileinfo, $infoline); 1904 $infoline = "Changing name from $oldname to $onefile->{'Name'} !\n"; 1905 push( @installer::globals::logfileinfo, $infoline); 1906 $infoline = "Changing destination from $olddestination to $onefile->{'destination'} !\n"; 1907 push( @installer::globals::logfileinfo, $infoline); 1908 } 1909 } 1910 } 1911} 1912 1913############################################################################ 1914# Removing all scpactions, that have no name. 1915# See: FlatLoaderZip 1916############################################################################ 1917 1918sub remove_scpactions_without_name 1919{ 1920 my ($itemsarrayref) = @_; 1921 1922 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::remove_scpactions_without_name : $#{$itemsarrayref}"); } 1923 1924 my $infoline; 1925 1926 my @newitemsarray = (); 1927 1928 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ ) 1929 { 1930 my $oneitem = ${$itemsarrayref}[$i]; 1931 my $name = ""; 1932 1933 if ( $oneitem->{'Name'} ) { $name = $oneitem->{'Name'}; } 1934 1935 if ( $name eq "" ) 1936 { 1937 $infoline = "ATTENTION: Removing scpaction $oneitem->{'gid'} from the installation set.\n"; 1938 push( @installer::globals::logfileinfo, $infoline); 1939 next; 1940 } 1941 1942 push(@newitemsarray, $oneitem); 1943 } 1944 1945 return \@newitemsarray; 1946} 1947 1948############################################################################ 1949# Because of the item "File" the source name must be "Name". Therefore 1950# "Copy" is changed to "Name" and "Name" is changed to "DestinationName". 1951############################################################################ 1952 1953sub change_keys_of_scpactions 1954{ 1955 my ($itemsarrayref) = @_; 1956 1957 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::change_keys_of_scpactions : $#{$itemsarrayref}"); } 1958 1959 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ ) 1960 { 1961 my $oneitem = ${$itemsarrayref}[$i]; 1962 1963 my $key; 1964 1965 # First Name to DestinationName, then deleting Name 1966 foreach $key (keys %{$oneitem}) 1967 { 1968 if ( $key =~ /\bName\b/ ) 1969 { 1970 my $value = $oneitem->{$key}; 1971 my $oldkey = $key; 1972 $key =~ s/Name/DestinationName/; 1973 $oneitem->{$key} = $value; 1974 delete($oneitem->{$oldkey}); 1975 } 1976 } 1977 1978 # Second Copy to Name, then deleting Copy 1979 foreach $key (keys %{$oneitem}) 1980 { 1981 if ( $key =~ /\bCopy\b/ ) 1982 { 1983 my $value = $oneitem->{$key}; 1984 my $oldkey = $key; 1985 $key =~ s/Copy/Name/; 1986 $oneitem->{$key} = $value; 1987 delete($oneitem->{$oldkey}); 1988 } 1989 } 1990 } 1991} 1992 1993############################################################################ 1994# Removing all xpd only items from installation set (scpactions with 1995# the style XPD_ONLY), except an xpd installation set is created 1996############################################################################ 1997 1998sub remove_Xpdonly_Items 1999{ 2000 my ($itemsarrayref) = @_; 2001 2002 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::remove_Xpdonly_Items : $#{$itemsarrayref}"); } 2003 2004 my $infoline; 2005 2006 my @newitemsarray = (); 2007 2008 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ ) 2009 { 2010 my $oneitem = ${$itemsarrayref}[$i]; 2011 my $styles = ""; 2012 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; } 2013 2014 if ( $styles =~ /\bXPD_ONLY\b/ ) 2015 { 2016 $infoline = "Removing \"xpd only\" item $oneitem->{'gid'} from the installation set.\n"; 2017 push( @installer::globals::globallogfileinfo, $infoline); 2018 2019 next; 2020 } 2021 2022 push(@newitemsarray, $oneitem); 2023 } 2024 2025 $infoline = "\n"; 2026 push( @installer::globals::globallogfileinfo, $infoline); 2027 2028 return \@newitemsarray; 2029} 2030 2031############################################################################ 2032# Removing all language pack files from installation set (files with 2033# the style LANGUAGEPACK), except this is a language pack. 2034############################################################################ 2035 2036sub remove_Languagepacklibraries_from_Installset 2037{ 2038 my ($itemsarrayref) = @_; 2039 2040 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::remove_Languagepacklibraries_from_Installset : $#{$itemsarrayref}"); } 2041 2042 my $infoline; 2043 2044 my @newitemsarray = (); 2045 2046 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ ) 2047 { 2048 my $oneitem = ${$itemsarrayref}[$i]; 2049 my $styles = ""; 2050 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; } 2051 2052 if ( $styles =~ /\bLANGUAGEPACK\b/ ) 2053 { 2054 $infoline = "Removing language pack file $oneitem->{'gid'} from the installation set.\n"; 2055 push( @installer::globals::globallogfileinfo, $infoline); 2056 2057 next; 2058 } 2059 2060 push(@newitemsarray, $oneitem); 2061 } 2062 2063 $infoline = "\n"; 2064 push( @installer::globals::globallogfileinfo, $infoline); 2065 2066 return \@newitemsarray; 2067} 2068 2069############################################################################ 2070# Removing all files with flag PATCH_ONLY from installation set. 2071# This function is not called during patch creation. 2072############################################################################ 2073 2074sub remove_patchonlyfiles_from_Installset 2075{ 2076 my ($itemsarrayref) = @_; 2077 2078 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::remove_patchonlyfiles_from_Installset : $#{$itemsarrayref}"); } 2079 2080 my $infoline; 2081 2082 my @newitemsarray = (); 2083 2084 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ ) 2085 { 2086 my $oneitem = ${$itemsarrayref}[$i]; 2087 my $styles = ""; 2088 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; } 2089 2090 if ( $styles =~ /\bPATCH_ONLY\b/ ) 2091 { 2092 $infoline = "Removing file with flag PATCH_ONLY $oneitem->{'gid'} from the installation set.\n"; 2093 push( @installer::globals::globallogfileinfo, $infoline); 2094 2095 next; 2096 } 2097 2098 push(@newitemsarray, $oneitem); 2099 } 2100 2101 $infoline = "\n"; 2102 push( @installer::globals::globallogfileinfo, $infoline); 2103 2104 return \@newitemsarray; 2105} 2106 2107############################################################################ 2108# Removing all files with flag TAB_ONLY from installation set. 2109# This function is not called during tab creation. 2110############################################################################ 2111 2112sub remove_tabonlyfiles_from_Installset 2113{ 2114 my ($itemsarrayref) = @_; 2115 2116 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::remove_tabonlyfiles_from_Installset : $#{$itemsarrayref}"); } 2117 2118 my $infoline; 2119 2120 my @newitemsarray = (); 2121 2122 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ ) 2123 { 2124 my $oneitem = ${$itemsarrayref}[$i]; 2125 my $styles = ""; 2126 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; } 2127 2128 if ( $styles =~ /\bTAB_ONLY\b/ ) 2129 { 2130 $infoline = "Removing tab only file $oneitem->{'gid'} from the installation set.\n"; 2131 push( @installer::globals::globallogfileinfo, $infoline); 2132 2133 next; 2134 } 2135 2136 push(@newitemsarray, $oneitem); 2137 } 2138 2139 $infoline = "\n"; 2140 push( @installer::globals::globallogfileinfo, $infoline); 2141 2142 return \@newitemsarray; 2143} 2144 2145############################################################################### 2146# Removing all files with flag ONLY_INSTALLED_PRODUCT from installation set. 2147# This function is not called for PKGFORMAT installed and archive. 2148############################################################################### 2149 2150sub remove_installedproductonlyfiles_from_Installset 2151{ 2152 my ($itemsarrayref) = @_; 2153 2154 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::remove_installedproductonlyfiles_from_Installset : $#{$itemsarrayref}"); } 2155 2156 my $infoline; 2157 2158 my @newitemsarray = (); 2159 2160 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ ) 2161 { 2162 my $oneitem = ${$itemsarrayref}[$i]; 2163 my $styles = ""; 2164 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; } 2165 2166 if ( $styles =~ /\bONLY_INSTALLED_PRODUCT\b/ ) 2167 { 2168 $infoline = "Removing file $oneitem->{'gid'} from the installation set. This file is only required for PKGFORMAT archive or installed).\n"; 2169 push( @installer::globals::globallogfileinfo, $infoline); 2170 next; 2171 } 2172 2173 push(@newitemsarray, $oneitem); 2174 } 2175 2176 $infoline = "\n"; 2177 push( @installer::globals::globallogfileinfo, $infoline); 2178 2179 return \@newitemsarray; 2180} 2181 2182############################################################################ 2183# Some files cotain a $ in their name. epm conflicts with such files. 2184# Solution: Renaming this files, converting "$" to "$$" 2185############################################################################ 2186 2187sub quoting_illegal_filenames 2188{ 2189 my ($filesarrayref) = @_; 2190 2191 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::rename_illegal_filenames : $#{$filesarrayref}"); } 2192 2193 # This function has to be removed as soon as possible! 2194 2195 installer::logger::include_header_into_logfile("Renaming illegal filenames:"); 2196 2197 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ ) 2198 { 2199 my $onefile = ${$filesarrayref}[$i]; 2200 my $filename = $onefile->{'Name'}; 2201 2202 if ( $filename =~ /\$/ ) 2203 { 2204 my $sourcepath = $onefile->{'sourcepath'}; 2205 my $destpath = $onefile->{'destination'}; 2206 2207 # sourcepath and destination have to be quoted for epm list file 2208 2209 # $filename =~ s/\$/\$\$/g; 2210 $destpath =~ s/\$/\$\$/g; 2211 $sourcepath =~ s/\$/\$\$/g; 2212 2213 # my $infoline = "ATTENTION: Files: Renaming $onefile->{'Name'} to $filename\n"; 2214 # push( @installer::globals::logfileinfo, $infoline); 2215 my $infoline = "ATTENTION: Files: Quoting sourcepath $onefile->{'sourcepath'} to $sourcepath\n"; 2216 push( @installer::globals::logfileinfo, $infoline); 2217 $infoline = "ATTENTION: Files: Quoting destination path $onefile->{'destination'} to $destpath\n"; 2218 push( @installer::globals::logfileinfo, $infoline); 2219 2220 # $onefile->{'Name'} = $filename; 2221 $onefile->{'sourcepath'} = $sourcepath; 2222 $onefile->{'destination'} = $destpath; 2223 } 2224 } 2225} 2226 2227############################################################################ 2228# Removing multiple occurences of same module. 2229############################################################################ 2230 2231sub optimize_list 2232{ 2233 my ( $longlist ) = @_; 2234 2235 my $shortlist = ""; 2236 my $hashref = installer::converter::convert_stringlist_into_hash(\$longlist, ","); 2237 foreach my $key (sort keys %{$hashref} ) { $shortlist = "$shortlist,$key"; } 2238 $shortlist =~ s/^\s*\,//; 2239 2240 return $shortlist; 2241} 2242 2243####################################################################### 2244# Collecting all directories needed for the epm list 2245# 1. Looking for all destination paths in the files array 2246# 2. Looking for directories with CREATE flag in the directory array 2247####################################################################### 2248 2249################################## 2250# Collecting directories: Part 1 2251################################## 2252 2253sub collect_directories_from_filesarray 2254{ 2255 my ($filesarrayref) = @_; 2256 2257 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::collect_directories_from_filesarray : $#{$filesarrayref}"); } 2258 2259 my @alldirectories = (); 2260 my %alldirectoryhash = (); 2261 2262 my $predefinedprogdir_added = 0; 2263 my $alreadyincluded = 0; 2264 2265 # Preparing this already as hash, although the only needed value at the moment is the HostName 2266 # But also adding: "specificlanguage" and "Dir" (for instance gid_Dir_Program) 2267 2268 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ ) 2269 { 2270 my $onefile = ${$filesarrayref}[$i]; 2271 my $destinationpath = $onefile->{'destination'}; 2272 installer::pathanalyzer::get_path_from_fullqualifiedname(\$destinationpath); 2273 $destinationpath =~ s/\Q$installer::globals::separator\E\s*$//; # removing ending slashes or backslashes 2274 2275 $alreadyincluded = 0; 2276 if ( exists($alldirectoryhash{$destinationpath}) ) { $alreadyincluded = 1; } 2277 2278 if (!($alreadyincluded)) 2279 { 2280 my %directoryhash = (); 2281 $directoryhash{'HostName'} = $destinationpath; 2282 $directoryhash{'specificlanguage'} = $onefile->{'specificlanguage'}; 2283 $directoryhash{'Dir'} = $onefile->{'Dir'}; 2284 $directoryhash{'modules'} = $onefile->{'modules'}; # NEW, saving modules 2285 # NEVER!!! if ( ! $installer::globals::iswindowsbuild ) { $directoryhash{'Styles'} = "(CREATE)"; } # this directories must be created 2286 2287 if ( $onefile->{'Dir'} eq "PREDEFINED_PROGDIR" ) { $predefinedprogdir_added = 1; } 2288 2289 $alldirectoryhash{$destinationpath} = \%directoryhash; 2290 2291 # Problem: The $destinationpath can be share/registry/schema/org/openoffice 2292 # but not all directories contain files and will be added to this list. 2293 # Therefore the path has to be analyzed. 2294 2295 while ( $destinationpath =~ /(^.*\S)\Q$installer::globals::separator\E(\S.*?)\s*$/ ) # as long as the path contains slashes 2296 { 2297 $destinationpath = $1; 2298 2299 $alreadyincluded = 0; 2300 if ( exists($alldirectoryhash{$destinationpath}) ) { $alreadyincluded = 1; } 2301 2302 if (!($alreadyincluded)) 2303 { 2304 my %directoryhash = (); 2305 2306 $directoryhash{'HostName'} = $destinationpath; 2307 $directoryhash{'specificlanguage'} = $onefile->{'specificlanguage'}; 2308 $directoryhash{'Dir'} = $onefile->{'Dir'}; 2309 $directoryhash{'modules'} = $onefile->{'modules'}; # NEW, saving modules 2310 # NEVER!!! if ( ! $installer::globals::iswindowsbuild ) { $directoryhash{'Styles'} = "(CREATE)"; } # this directories must be created 2311 2312 $alldirectoryhash{$destinationpath} = \%directoryhash; 2313 } 2314 else 2315 { 2316 # Adding the modules to the module list! 2317 $alldirectoryhash{$destinationpath}->{'modules'} = $alldirectoryhash{$destinationpath}->{'modules'} . "," . $onefile->{'modules'}; 2318 } 2319 } 2320 } 2321 else 2322 { 2323 # Adding the modules to the module list! 2324 $alldirectoryhash{$destinationpath}->{'modules'} = $alldirectoryhash{$destinationpath}->{'modules'} . "," . $onefile->{'modules'}; 2325 2326 # Also adding the module to all parents 2327 while ( $destinationpath =~ /(^.*\S)\Q$installer::globals::separator\E(\S.*?)\s*$/ ) # as long as the path contains slashes 2328 { 2329 $destinationpath = $1; 2330 $alldirectoryhash{$destinationpath}->{'modules'} = $alldirectoryhash{$destinationpath}->{'modules'} . "," . $onefile->{'modules'}; 2331 } 2332 } 2333 } 2334 2335 # if there is no file in the root directory PREDEFINED_PROGDIR, it has to be included into the directory array now 2336 # HostName= specificlanguage= Dir=PREDEFINED_PROGDIR 2337 2338 if (! $predefinedprogdir_added ) 2339 { 2340 my %directoryhash = (); 2341 $directoryhash{'HostName'} = ""; 2342 $directoryhash{'specificlanguage'} = ""; 2343 $directoryhash{'modules'} = ""; # ToDo? 2344 $directoryhash{'Dir'} = "PREDEFINED_PROGDIR"; 2345 2346 push(@alldirectories, \%directoryhash); 2347 } 2348 2349 # Creating directory array 2350 foreach my $destdir ( sort keys %alldirectoryhash ) 2351 { 2352 $alldirectoryhash{$destdir}->{'modules'} = optimize_list($alldirectoryhash{$destdir}->{'modules'}); 2353 push(@alldirectories, $alldirectoryhash{$destdir}); 2354 } 2355 2356 return (\@alldirectories, \%alldirectoryhash); 2357} 2358 2359################################## 2360# Collecting directories: Part 2 2361################################## 2362 2363sub collect_directories_with_create_flag_from_directoryarray 2364{ 2365 my ($directoryarrayref, $alldirectoryhash) = @_; 2366 2367 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::collect_directories_with_create_flag_from_directoryarray : $#{$directoryarrayref}"); } 2368 2369 my $alreadyincluded = 0; 2370 my @alldirectories = (); 2371 2372 for ( my $i = 0; $i <= $#{$directoryarrayref}; $i++ ) 2373 { 2374 my $onedir = ${$directoryarrayref}[$i]; 2375 my $styles = ""; 2376 $newdirincluded = 0; 2377 2378 if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; } 2379 2380 if ( $styles =~ /\bCREATE\b/ ) 2381 { 2382 my $directoryname = ""; 2383 2384 if ( $onedir->{'HostName'} ) { $directoryname = $onedir->{'HostName'}; } 2385 else { installer::exiter::exit_program("ERROR: No directory name (HostName) set for specified language in gid $onedir->{'gid'}", "collect_directories_with_create_flag_from_directoryarray"); } 2386 2387 $alreadyincluded = 0; 2388 if ( exists($alldirectoryhash->{$directoryname}) ) { $alreadyincluded = 1; } 2389 2390 if (!($alreadyincluded)) 2391 { 2392 my %directoryhash = (); 2393 $directoryhash{'HostName'} = $directoryname; 2394 $directoryhash{'specificlanguage'} = $onedir->{'specificlanguage'}; 2395 # $directoryhash{'gid'} = $onedir->{'gid'}; 2396 $directoryhash{'Dir'} = $onedir->{'gid'}; 2397 $directoryhash{'Styles'} = $onedir->{'Styles'}; 2398 2399 # saving also the modules 2400 if ( ! $onedir->{'modules'} ) { installer::exiter::exit_program("ERROR: No assigned modules found for directory $onedir->{'gid'}", "collect_directories_with_create_flag_from_directoryarray"); } 2401 $directoryhash{'modules'} = $onedir->{'modules'}; 2402 2403 $alldirectoryhash->{$directoryname} = \%directoryhash; 2404 $newdirincluded = 1; 2405 2406 # Problem: The $destinationpath can be share/registry/schema/org/openoffice 2407 # but not all directories contain files and will be added to this list. 2408 # Therefore the path has to be analyzed. 2409 2410 while ( $directoryname =~ /(^.*\S)\Q$installer::globals::separator\E(\S.*?)\s*$/ ) # as long as the path contains slashes 2411 { 2412 $directoryname = $1; 2413 2414 $alreadyincluded = 0; 2415 if ( exists($alldirectoryhash->{$directoryname}) ) { $alreadyincluded = 1; } 2416 2417 if (!($alreadyincluded)) 2418 { 2419 my %directoryhash = (); 2420 2421 $directoryhash{'HostName'} = $directoryname; 2422 $directoryhash{'specificlanguage'} = $onedir->{'specificlanguage'}; 2423 $directoryhash{'Dir'} = $onedir->{'gid'}; 2424 if ( ! $installer::globals::iswindowsbuild ) { $directoryhash{'Styles'} = "(CREATE)"; } # Exeception for Windows? 2425 2426 # saving also the modules 2427 $directoryhash{'modules'} = $onedir->{'modules'}; 2428 2429 $alldirectoryhash->{$directoryname} = \%directoryhash; 2430 $newdirincluded = 1; 2431 } 2432 else 2433 { 2434 # Adding the modules to the module list! 2435 $alldirectoryhash->{$directoryname}->{'modules'} = $alldirectoryhash->{$directoryname}->{'modules'} . "," . $onedir->{'modules'}; 2436 } 2437 } 2438 } 2439 else 2440 { 2441 # Adding the modules to the module list! 2442 $alldirectoryhash->{$directoryname}->{'modules'} = $alldirectoryhash->{$directoryname}->{'modules'} . "," . $onedir->{'modules'}; 2443 2444 while ( $directoryname =~ /(^.*\S)\Q$installer::globals::separator\E(\S.*?)\s*$/ ) # as long as the path contains slashes 2445 { 2446 $directoryname = $1; 2447 # Adding the modules to the module list! 2448 $alldirectoryhash->{$directoryname}->{'modules'} = $alldirectoryhash->{$directoryname}->{'modules'} . "," . $onedir->{'modules'}; 2449 } 2450 } 2451 } 2452 2453 # Saving the styles for already added directories in function collect_directories_from_filesarray 2454 2455 if (( ! $newdirincluded ) && ( $styles ne "" )) 2456 { 2457 $styles =~ s/\bWORKSTATION\b//; 2458 $styles =~ s/\bCREATE\b//; 2459 2460 if (( ! ( $styles =~ /^\s*\(\s*\)\s*$/ )) && ( ! ( $styles =~ /^\s*\(\s*\,\s*\)\s*$/ )) && ( ! ( $styles =~ /^\s*$/ ))) # checking, if there are styles left 2461 { 2462 my $directoryname = ""; 2463 if ( $onedir->{'HostName'} ) { $directoryname = $onedir->{'HostName'}; } 2464 else { installer::exiter::exit_program("ERROR: No directory name (HostName) set for specified language in gid $onedir->{'gid'}", "collect_directories_with_create_flag_from_directoryarray"); } 2465 2466 if ( exists($alldirectoryhash->{$directoryname}) ) 2467 { 2468 $alldirectoryhash->{$directoryname}->{'Styles'} = $styles; 2469 } 2470 } 2471 } 2472 } 2473 2474 # Creating directory array 2475 foreach my $destdir ( sort keys %{$alldirectoryhash} ) 2476 { 2477 $alldirectoryhash->{$destdir}->{'modules'} = optimize_list($alldirectoryhash->{$destdir}->{'modules'}); 2478 push(@alldirectories, $alldirectoryhash->{$destdir}); 2479 } 2480 2481 return (\@alldirectories, \%alldirectoryhash); 2482} 2483 2484################################################# 2485# Determining the destination file of a link 2486################################################# 2487 2488sub get_destination_file_path_for_links 2489{ 2490 my ($linksarrayref, $filesarrayref) = @_; 2491 2492 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::get_destination_file_path_for_links : $#{$linksarrayref} : $#{$filesarrayref}"); } 2493 2494 my $infoline; 2495 2496 for ( my $i = 0; $i <= $#{$linksarrayref}; $i++ ) 2497 { 2498 my $fileid = ""; 2499 my $onelink = ${$linksarrayref}[$i]; 2500 if ( $onelink->{'FileID'} ) { $fileid = $onelink->{'FileID'}; } 2501 2502 if (!( $fileid eq "" )) 2503 { 2504 my $foundfile = 0; 2505 2506 for ( my $j = 0; $j <= $#{$filesarrayref}; $j++ ) 2507 { 2508 my $onefile = ${$filesarrayref}[$j]; 2509 my $filegid = $onefile->{'gid'}; 2510 2511 if ( $filegid eq $fileid ) 2512 { 2513 $foundfile = 1; 2514 $onelink->{'destinationfile'} = $onefile->{'destination'}; 2515 last; 2516 } 2517 } 2518 2519 if (!($foundfile)) 2520 { 2521 $infoline = "Warning: FileID $fileid for Link $onelink->{'gid'} not found!\n"; 2522 push( @installer::globals::logfileinfo, $infoline); 2523 } 2524 } 2525 } 2526 2527 $infoline = "\n"; 2528 push( @installer::globals::logfileinfo, $infoline); 2529} 2530 2531################################################# 2532# Determining the destination link of a link 2533################################################# 2534 2535sub get_destination_link_path_for_links 2536{ 2537 my ($linksarrayref) = @_; 2538 2539 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::get_destination_link_path_for_links : $#{$linksarrayref}"); } 2540 2541 my $infoline; 2542 2543 for ( my $i = 0; $i <= $#{$linksarrayref}; $i++ ) 2544 { 2545 my $shortcutid = ""; 2546 my $onelink = ${$linksarrayref}[$i]; 2547 if ( $onelink->{'ShortcutID'} ) { $shortcutid = $onelink->{'ShortcutID'}; } 2548 2549 if (!( $shortcutid eq "" )) 2550 { 2551 my $foundlink = 0; 2552 2553 for ( my $j = 0; $j <= $#{$linksarrayref}; $j++ ) 2554 { 2555 my $destlink = ${$linksarrayref}[$j]; 2556 $shortcutgid = $destlink->{'gid'}; 2557 2558 if ( $shortcutgid eq $shortcutid ) 2559 { 2560 $foundlink = 1; 2561 $onelink->{'destinationfile'} = $destlink->{'destination'}; # making key 'destinationfile' 2562 last; 2563 } 2564 } 2565 2566 if (!($foundlink)) 2567 { 2568 $infoline = "Warning: ShortcutID $shortcutid for Link $onelink->{'gid'} not found!\n"; 2569 push( @installer::globals::logfileinfo, $infoline); 2570 } 2571 } 2572 } 2573 2574 $infoline = "\n"; 2575 push( @installer::globals::logfileinfo, $infoline); 2576} 2577 2578################################################################################### 2579# Items with flag WORKSTATION are not needed (here: links and configurationitems) 2580################################################################################### 2581 2582sub remove_workstation_only_items 2583{ 2584 my ($itemarrayref) = @_; 2585 2586 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::remove_workstation_only_items : $#{$itemarrayref}"); } 2587 2588 my @newitemarray = (); 2589 2590 for ( my $i = 0; $i <= $#{$itemarrayref}; $i++ ) 2591 { 2592 my $oneitem = ${$itemarrayref}[$i]; 2593 my $styles = $oneitem->{'Styles'}; 2594 2595 if (( $styles =~ /\bWORKSTATION\b/ ) && 2596 (!( $styles =~ /\bNETWORK\b/ )) && 2597 (!( $styles =~ /\bSTANDALONE\b/ ))) 2598 { 2599 next; # removing this link, it is only needed for a workstation installation 2600 } 2601 2602 push(@newitemarray, $oneitem); 2603 } 2604 2605 return \@newitemarray; 2606} 2607 2608################################################ 2609# Resolving relative path in links 2610################################################ 2611 2612sub resolve_links_with_flag_relative 2613{ 2614 my ($linksarrayref) = @_; 2615 2616 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::resolve_links_with_flag_relative : $#{$linksarrayref}"); } 2617 2618 # Before this step is: 2619 # destination=program/libsalhelperC52.so.3, this will be the name of the link 2620 # destinationfile=program/libsalhelperC52.so.3, this will be the linked file or name 2621 # If the flag RELATIVE is set, the pathes have to be analyzed. If the flag is not set 2622 # (this will not occur in the future?) destinationfile has to be an absolute path name 2623 2624 for ( my $i = 0; $i <= $#{$linksarrayref}; $i++ ) 2625 { 2626 my $onelink = ${$linksarrayref}[$i]; 2627 my $styles = $onelink->{'Styles'}; 2628 2629 if ( $styles =~ /\bRELATIVE\b/ ) 2630 { 2631 # ToDo: This is only a simple not sufficient mechanism 2632 2633 my $destination = $onelink->{'destination'}; 2634 my $destinationfile = $onelink->{'destinationfile'}; 2635 2636 my $destinationpath = $destination; 2637 2638 installer::pathanalyzer::get_path_from_fullqualifiedname(\$destinationpath); 2639 2640 my $destinationfilepath = $destinationfile; 2641 2642 # it is possible, that the destinationfile is no longer part of the files collector 2643 if ($destinationfilepath) { installer::pathanalyzer::get_path_from_fullqualifiedname(\$destinationfilepath); } 2644 else { $destinationfilepath = ""; } 2645 2646 if ( $destinationpath eq $destinationfilepath ) 2647 { 2648 # link and file are in the same directory 2649 # Therefore the path of the file can be removed 2650 2651 my $newdestinationfile = $destinationfile; 2652 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$newdestinationfile); 2653 2654 $onelink->{'destinationfile'} = $newdestinationfile; 2655 } 2656 } 2657 } 2658} 2659 2660######################################################################## 2661# This function is a helper of function "assigning_modules_to_items" 2662######################################################################## 2663 2664sub insert_for_item ($$$) 2665{ 2666 my ($hash, $item, $id) = @_; 2667 2668 # print STDERR "insert '$id' for '$item'\n"; 2669 if (!defined $hash->{$item}) 2670 { 2671 my @gids = (); 2672 $hash->{$item} = \@gids; 2673 } 2674 my $gid_list = $hash->{$item}; 2675 push @{$gid_list}, $id; 2676 $hash->{$item} = $gid_list; 2677} 2678 2679sub build_modulegids_table 2680{ 2681 my ($modulesref, $itemname) = @_; 2682 2683 my %module_lookup_table = (); 2684 2685 # build map of item names to list of respective module gids 2686 # containing these items 2687 for my $onemodule (@{$modulesref}) 2688 { 2689 next if ( ! defined $onemodule->{$itemname} ); 2690 # these are the items contained in this module 2691 # eg. Files = (gid_a_b_c,gid_d_e_f) 2692 my $module_gids = $onemodule->{$itemname}; 2693 2694 # prune outer brackets 2695 $module_gids =~ s|^\s*\(||g; 2696 $module_gids =~ s|\)\s*$||g; 2697 for my $id (split (/,/, $module_gids)) 2698 { 2699 chomp $id; 2700 insert_for_item(\%module_lookup_table, lc ($id), $onemodule->{'gid'}); 2701 } 2702 } 2703 2704 return \%module_lookup_table; 2705} 2706 2707######################################################################## 2708# Items like files do not know their modules 2709# This function is a helper of function "assigning_modules_to_items" 2710######################################################################## 2711 2712sub get_string_of_modulegids_for_itemgid 2713{ 2714 my ($module_lookup_table, $modulesref, $itemgid, $itemname) = @_; 2715 2716 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::get_string_of_modulegids_for_itemgid : $#{$modulesref} : $itemgid : $itemname"); } 2717 2718 my $allmodules = ""; 2719 my $haslanguagemodule = 0; 2720 my %foundmodules = (); 2721 2722 # print STDERR "lookup '" . lc($itemgid) . "'\n"; 2723 my $gid_list = $module_lookup_table->{lc($itemgid)}; 2724 2725 for my $gid (@{$gid_list}) 2726 { 2727 $foundmodules{$gid} = 1; 2728 $allmodules = $allmodules . "," . $gid; 2729 # Is this module a language module? This info should be stored at the file. 2730 if ( exists($installer::globals::alllangmodules{$gid}) ) { $haslanguagemodule = 1; } 2731 } 2732 2733 $allmodules =~ s/^\s*\,//; # removing leading comma 2734 2735 # Check: All modules or no module must have flag LANGUAGEMODULE 2736 if ( $haslanguagemodule ) 2737 { 2738 my $isreallylanguagemodule = installer::worker::key_in_a_is_also_key_in_b(\%foundmodules, \%installer::globals::alllangmodules); 2739 if ( ! $isreallylanguagemodule ) { installer::exiter::exit_program("ERROR: \"$itemgid\" is assigned to modules with flag \"LANGUAGEMODULE\" and also to modules without this flag! Modules: $allmodules", "get_string_of_modulegids_for_itemgid"); } 2740 } 2741 2742 # print STDERR "get_string_for_itemgid ($itemgid, $itemname) => $allmodules, $haslanguagemodule\n"; 2743 2744 return ($allmodules, $haslanguagemodule); 2745} 2746 2747######################################################## 2748# Items like files do not know their modules 2749# This function add the {'modules'} to these items 2750######################################################## 2751 2752sub assigning_modules_to_items 2753{ 2754 my ($modulesref, $itemsref, $itemname) = @_; 2755 2756 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::assigning_modules_to_items : $#{$modulesref} : $#{$itemsref} : $itemname"); } 2757 2758 my $infoline = ""; 2759 my $languageassignmenterror = 0; 2760 my @languageassignmenterrors = (); 2761 2762 my $module_lookup_table = build_modulegids_table($modulesref, $itemname); 2763 2764 for my $oneitem (@{$itemsref}) 2765 { 2766 my $itemgid = $oneitem->{'gid'}; 2767 2768 my $styles = ""; 2769 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; } 2770 if (( $itemname eq "Dirs" ) && ( ! ( $styles =~ /\bCREATE\b/ ))) { next; } 2771 2772 if ( $itemgid eq "" ) 2773 { 2774 installer::exiter::exit_program("ERROR in item collection: No gid for item $oneitem->{'Name'}", "assigning_modules_to_items"); 2775 } 2776 2777 # every item can belong to many modules 2778 2779 my ($modulegids, $haslanguagemodule) = get_string_of_modulegids_for_itemgid($module_lookup_table, $modulesref, $itemgid, $itemname); 2780 2781 if ($modulegids eq "") 2782 { 2783 installer::exiter::exit_program("ERROR in file collection: No module found for $itemname $itemgid", "assigning_modules_to_items"); 2784 } 2785 2786 $oneitem->{'modules'} = $modulegids; 2787 $oneitem->{'haslanguagemodule'} = $haslanguagemodule; 2788 2789 # Important check: "ismultilingual" and "haslanguagemodule" must have the same value ! 2790 if (( $oneitem->{'ismultilingual'} ) && ( ! $oneitem->{'haslanguagemodule'} )) 2791 { 2792 $infoline = "Error: \"$oneitem->{'gid'}\" is multi lingual, but not in language pack (Assigned module: $modulegids)!\n"; 2793 push( @installer::globals::globallogfileinfo, $infoline); 2794 push( @languageassignmenterrors, $infoline ); 2795 $languageassignmenterror = 1; 2796 } 2797 if (( $oneitem->{'haslanguagemodule'} ) && ( ! $oneitem->{'ismultilingual'} )) 2798 { 2799 $infoline = "Error: \"$oneitem->{'gid'}\" is in language pack, but not multi lingual (Assigned module: $modulegids)!\n"; 2800 push( @installer::globals::globallogfileinfo, $infoline); 2801 push( @languageassignmenterrors, $infoline ); 2802 $languageassignmenterror = 1; 2803 } 2804 } 2805 2806 if ($languageassignmenterror) 2807 { 2808 for ( my $i = 0; $i <= $#languageassignmenterrors; $i++ ) { print "$languageassignmenterrors[$i]"; } 2809 installer::exiter::exit_program("ERROR: Incorrect assignments for language packs.", "assigning_modules_to_items"); 2810 } 2811 2812} 2813 2814################################################################################################# 2815# Root path (for instance /opt/openofficeorg20) needs to be added to directories, files and links 2816################################################################################################# 2817 2818sub add_rootpath_to_directories 2819{ 2820 my ($dirsref, $rootpath) = @_; 2821 2822 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::add_rootpath_to_directories : $#{$dirsref} : $rootpath"); } 2823 2824 for ( my $i = 0; $i <= $#{$dirsref}; $i++ ) 2825 { 2826 my $onedir = ${$dirsref}[$i]; 2827 my $dir = ""; 2828 2829 if ( $onedir->{'Dir'} ) { $dir = $onedir->{'Dir'}; } 2830 2831 if (!($dir =~ /\bPREDEFINED_/ )) 2832 { 2833 my $hostname = $onedir->{'HostName'}; 2834 $hostname = $rootpath . $installer::globals::separator . $hostname; 2835 $onedir->{'HostName'} = $hostname; 2836 } 2837 2838 # added 2839 2840 if ( $dir =~ /\bPREDEFINED_PROGDIR\b/ ) 2841 { 2842 my $hostname = $onedir->{'HostName'}; 2843 if ( $hostname eq "" ) { $onedir->{'HostName'} = $rootpath; } 2844 else { $onedir->{'HostName'} = $rootpath . $installer::globals::separator . $hostname; } 2845 } 2846 } 2847} 2848 2849sub add_rootpath_to_files 2850{ 2851 my ($filesref, $rootpath) = @_; 2852 2853 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::add_rootpath_to_files : $#{$filesref} : $rootpath"); } 2854 2855 for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 2856 { 2857 my $onefile = ${$filesref}[$i]; 2858 my $destination = $onefile->{'destination'}; 2859 $destination = $rootpath . $installer::globals::separator . $destination; 2860 $onefile->{'destination'} = $destination; 2861 } 2862} 2863 2864sub add_rootpath_to_links 2865{ 2866 my ($linksref, $rootpath) = @_; 2867 2868 if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::scriptitems::add_rootpath_to_links : $#{$linksref} : $rootpath"); } 2869 2870 for ( my $i = 0; $i <= $#{$linksref}; $i++ ) 2871 { 2872 my $onelink = ${$linksref}[$i]; 2873 my $styles = $onelink->{'Styles'}; 2874 2875 my $destination = $onelink->{'destination'}; 2876 $destination = $rootpath . $installer::globals::separator . $destination; 2877 $onelink->{'destination'} = $destination; 2878 2879 if (!($styles =~ /\bRELATIVE\b/ )) # for absolute links 2880 { 2881 my $destinationfile = $onelink->{'destinationfile'}; 2882 $destinationfile = $rootpath . $installer::globals::separator . $destinationfile; 2883 $onelink->{'destinationfile'} = $destinationfile; 2884 } 2885 } 2886} 2887 2888################################################################################# 2889# Collecting all parent gids 2890################################################################################# 2891 2892sub collect_all_parent_feature 2893{ 2894 my ($modulesref) = @_; 2895 2896 my @allparents = (); 2897 2898 my $found_root_module = 0; 2899 2900 for ( my $i = 0; $i <= $#{$modulesref}; $i++ ) 2901 { 2902 my $onefeature = ${$modulesref}[$i]; 2903 2904 my $parentgid = ""; 2905 if ( $onefeature->{'ParentID'} ) 2906 { 2907 $parentgid = $onefeature->{'ParentID'}; 2908 } 2909 2910 if ( $parentgid ne "" ) 2911 { 2912 if (! installer::existence::exists_in_array($parentgid, \@allparents)) 2913 { 2914 push(@allparents, $parentgid); 2915 } 2916 } 2917 2918 # Setting the global root module 2919 2920 if ( $parentgid eq "" ) 2921 { 2922 if ( $found_root_module ) { installer::exiter::exit_program("ERROR: Only one module without ParentID or with empty ParentID allowed ($installer::globals::rootmodulegid, $onefeature->{'gid'}).", "collect_all_parent_feature"); } 2923 $installer::globals::rootmodulegid = $onefeature->{'gid'}; 2924 $found_root_module = 1; 2925 $infoline = "Setting Root Module: $installer::globals::rootmodulegid\n"; 2926 push( @installer::globals::globallogfileinfo, $infoline); 2927 } 2928 2929 if ( ! $found_root_module ) { installer::exiter::exit_program("ERROR: Could not define root module. No module without ParentID or with empty ParentID exists.", "collect_all_parent_feature"); } 2930 2931 } 2932 2933 return \@allparents; 2934} 2935 2936################################################################################# 2937# Checking for every feature, whether it has children 2938################################################################################# 2939 2940sub set_children_flag 2941{ 2942 my ($modulesref) = @_; 2943 2944 my $allparents = collect_all_parent_feature($modulesref); 2945 2946 for ( my $i = 0; $i <= $#{$modulesref}; $i++ ) 2947 { 2948 my $onefeature = ${$modulesref}[$i]; 2949 my $gid = $onefeature->{'gid'}; 2950 2951 # is this gid a parent? 2952 2953 if ( installer::existence::exists_in_array($gid, $allparents) ) 2954 { 2955 $onefeature->{'has_children'} = 1; 2956 } 2957 else 2958 { 2959 $onefeature->{'has_children'} = 0; 2960 } 2961 } 2962} 2963 2964################################################################################# 2965# All modules, that use a template module, do now get the assignments of 2966# the template module. 2967################################################################################# 2968 2969sub resolve_assigned_modules 2970{ 2971 my ($modulesref) = @_; 2972 2973 # collecting all template modules 2974 2975 my %directaccess = (); 2976 2977 for ( my $i = 0; $i <= $#{$modulesref}; $i++ ) 2978 { 2979 my $onefeature = ${$modulesref}[$i]; 2980 my $styles = ""; 2981 if ( $onefeature->{'Styles'} ) { $styles = $onefeature->{'Styles'}; } 2982 if ( $styles =~ /\bTEMPLATEMODULE\b/ ) { $directaccess{$onefeature->{'gid'}} = $onefeature; } 2983 2984 # also looking for module with flag ROOT_BRAND_PACKAGE, to save is for further usage 2985 if ( $styles =~ /\bROOT_BRAND_PACKAGE\b/ ) 2986 { 2987 $installer::globals::rootbrandpackage = $onefeature->{'gid'}; 2988 $installer::globals::rootbrandpackageset = 1; 2989 } 2990 } 2991 2992 # looking, where template modules are assigned 2993 2994 for ( my $i = 0; $i <= $#{$modulesref}; $i++ ) 2995 { 2996 my $onefeature = ${$modulesref}[$i]; 2997 if ( $onefeature->{'Assigns'} ) 2998 { 2999 my $templategid = $onefeature->{'Assigns'}; 3000 3001 if ( ! exists($directaccess{$templategid}) ) 3002 { 3003 installer::exiter::exit_program("ERROR: Did not find definition of assigned template module \"$templategid\"", "resolve_assigned_modules"); 3004 } 3005 3006 # Currently no merging of Files, Dirs, ... 3007 # This has to be included here, if it is required 3008 my $item; 3009 foreach $item (@installer::globals::items_at_modules) 3010 { 3011 if ( exists($directaccess{$templategid}->{$item}) ) { $onefeature->{$item} = $directaccess{$templategid}->{$item}; } 3012 } 3013 } 3014 } 3015} 3016 3017################################################################################# 3018# Removing the template modules from the list, after all 3019# assignments are transferred to the "real" modules. 3020################################################################################# 3021 3022sub remove_template_modules 3023{ 3024 my ($modulesref) = @_; 3025 3026 my @modules = (); 3027 3028 for ( my $i = 0; $i <= $#{$modulesref}; $i++ ) 3029 { 3030 my $onefeature = ${$modulesref}[$i]; 3031 my $styles = ""; 3032 if ( $onefeature->{'Styles'} ) { $styles = $onefeature->{'Styles'}; } 3033 if ( $styles =~ /\bTEMPLATEMODULE\b/ ) { next; } 3034 3035 push(@modules, $onefeature); 3036 } 3037 3038 return \@modules; 3039} 3040 3041################################################################################# 3042# Collecting all modules with flag LANGUAGEMODULE in a global 3043# collector. 3044################################################################################# 3045 3046sub collect_all_languagemodules 3047{ 3048 my ($modulesref) = @_; 3049 3050 for ( my $i = 0; $i <= $#{$modulesref}; $i++ ) 3051 { 3052 my $onefeature = ${$modulesref}[$i]; 3053 my $styles = ""; 3054 if ( $onefeature->{'Styles'} ) { $styles = $onefeature->{'Styles'}; } 3055 if ( $styles =~ /\bLANGUAGEMODULE\b/ ) 3056 { 3057 if ( ! exists($onefeature->{'Language'}) ) { installer::exiter::exit_program("ERROR: \"$onefeature->{'gid'}\" has flag LANGUAGEMODULE, but does not know its language!", "collect_all_languagemodules"); } 3058 $installer::globals::alllangmodules{$onefeature->{'gid'}} = $onefeature->{'Language'}; 3059 # Collecting also the english names, that are used for nsis unpack directory for language packs 3060 my $lang = $onefeature->{'Language'}; 3061 my $name = ""; 3062 foreach my $localkey ( keys %{$onefeature} ) 3063 { 3064 if ( $localkey =~ /^\s*Name\s*\(\s*en-US\s*\)\s*$/ ) 3065 { 3066 $installer::globals::all_english_languagestrings{$lang} = $onefeature->{$localkey}; 3067 } 3068 } 3069 } 3070 } 3071} 3072 3073################################################################################# 3074# Selecting from all collected english language strings those, that are really 3075# required in this installation set. 3076################################################################################# 3077 3078sub select_required_language_strings 3079{ 3080 my ($modulesref) = @_; 3081 3082 for ( my $i = 0; $i <= $#{$modulesref}; $i++ ) 3083 { 3084 my $onefeature = ${$modulesref}[$i]; 3085 my $styles = ""; 3086 if ( $onefeature->{'Styles'} ) { $styles = $onefeature->{'Styles'}; } 3087 if ( $styles =~ /\bLANGUAGEMODULE\b/ ) 3088 { 3089 if ( ! exists($onefeature->{'Language'}) ) { installer::exiter::exit_program("ERROR: \"$onefeature->{'gid'}\" has flag LANGUAGEMODULE, but does not know its language!", "select_required_language_strings"); } 3090 my $lang = $onefeature->{'Language'}; 3091 3092 if (( exists($installer::globals::all_english_languagestrings{$lang}) ) && ( ! exists($installer::globals::all_required_english_languagestrings{$lang}) )) 3093 { 3094 $installer::globals::all_required_english_languagestrings{$lang} = $installer::globals::all_english_languagestrings{$lang}; 3095 } 3096 } 3097 } 3098} 3099 3100##################################################################################### 3101# Unixlinks are not always required. For Linux RPMs and Solaris Packages they are 3102# created dynamically. Exception: For package formats "installed" or "archive". 3103# In scp2 this unixlinks have the flag LAYERLINK. 3104##################################################################################### 3105 3106sub filter_layerlinks_from_unixlinks 3107{ 3108 my ( $unixlinksref ) = @_; 3109 3110 my @alllinks = (); 3111 3112 for ( my $i = 0; $i <= $#{$unixlinksref}; $i++ ) 3113 { 3114 my $isrequired = 1; 3115 3116 my $onelink = ${$unixlinksref}[$i]; 3117 my $styles = ""; 3118 if ( $onelink->{'Styles'} ) { $styles = $onelink->{'Styles'}; } 3119 3120 if ( $styles =~ /\bLAYERLINK\b/ ) 3121 { 3122 # Platforms, that do not need the layer links 3123 if (( $installer::globals::islinuxrpmbuild ) || ( $installer::globals::issolarispkgbuild )) 3124 { 3125 $isrequired = 0; 3126 } 3127 3128 # Package formats, that need the layer link (platform independent) 3129 if (( $installer::globals::packageformat eq "installed" ) || ( $installer::globals::packageformat eq "archive" )) 3130 { 3131 $isrequired = 1; 3132 } 3133 } 3134 3135 if ( $isrequired ) { push(@alllinks, $onelink); } 3136 } 3137 3138 return \@alllinks; 3139} 3140 31411; 3142