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