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