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