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