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