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