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