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