2 # This file is part of the LibreOffice project.
4 # This Source Code Form is subject to the terms of the Mozilla Public
5 # License, v. 2.0. If a copy of the MPL was not distributed with this
6 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 # This file incorporates work covered by the following license notice:
10 # Licensed to the Apache Software Foundation (ASF) under one or more
11 # contributor license agreements. See the NOTICE file distributed
12 # with this work for additional information regarding copyright
13 # ownership. The ASF licenses this file to you under the Apache
14 # License, Version 2.0 (the "License"); you may not use this file
15 # except in compliance with the License. You may obtain a copy of
16 # the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 package installer
::scriptitems
;
25 use installer
::converter
;
26 use installer
::exiter
;
27 use installer
::globals
;
28 use installer
::languages
;
29 use installer
::logger
;
30 use installer
::pathanalyzer
;
31 use installer
::remover
;
32 use installer
::systemactions
;
34 ################################################################
35 # Resolving the GID for the directories defined in setup script
36 ################################################################
38 sub resolve_all_directory_names
40 my ($directoryarrayref) = @_;
42 # After this procedure the hash shall contain the complete language
43 # dependent path, not only the language dependent HostName.
45 my ($key, $value, $parentvalue, $parentgid, $parentdirectoryhashref);
47 for ( my $i = 0; $i <= $#{$directoryarrayref}; $i++ )
49 my $directoryhashref = ${$directoryarrayref}[$i];
50 my $gid = $directoryhashref-> {'gid'};
51 my $parentid = $directoryhashref-> {'ParentID'};
53 if ( $parentid ne "PREDEFINED_PROGDIR" )
55 # find the array of the parentid, which has to be defined before in setup script
56 # and is therefore listed before in this array
58 for ( my $j = 0; $j <= $i; $j++ )
60 $parentdirectoryhashref = ${$directoryarrayref}[$j];
61 $parentgid = $parentdirectoryhashref->{'gid'};
63 if ( $parentid eq $parentgid)
69 # and now we can put the path together
70 # But take care of the languages!
72 my $dirismultilingual = $directoryhashref->{'ismultilingual'};
73 my $parentismultilingual = $parentdirectoryhashref->{'ismultilingual'};
75 # First: Both directories are language independent or both directories are language dependent
77 if ((( ! $dirismultilingual ) && ( ! $parentismultilingual )) ||
78 (( $dirismultilingual ) && ( $parentismultilingual )))
80 foreach $key (keys %{$directoryhashref})
82 # the key ("HostName (en-US)") must be usable for both hashes
84 if ( $key =~ /\bHostName\b/ )
87 $value = $directoryhashref->{$key};
88 if ( $parentdirectoryhashref->{$key} ) { $parentvalue = $parentdirectoryhashref->{$key}; }
90 # It is possible, that in scp project, a directory is defined in more languages than
91 # the directory parent (happened after automatic generation of macros.inc).
92 # Therefore this is checked now and written with a warning into the logfile.
93 # This is no error, because (in most cases) the concerned language is not build.
95 if ($parentvalue eq "")
97 $directoryhashref->{$key} = "FAILURE";
98 my $infoline = "WARNING: No hostname for $parentid with \"$key\". Needed by child directory $gid !\n";
99 push( @installer::globals
::globallogfileinfo
, $infoline);
103 $directoryhashref->{$key} = $parentvalue . $installer::globals
::separator
. $value;
109 # Second: The directory is language dependent, the parent not
111 if (( $dirismultilingual ) && ( ! $parentismultilingual ))
113 $parentvalue = $parentdirectoryhashref->{'HostName'}; # there is only one
115 foreach $key (keys %{$directoryhashref}) # the current directory
117 if ( $key =~ /\bHostName\b/ )
119 $value = $directoryhashref->{$key};
120 $directoryhashref->{$key} = $parentvalue . $installer::globals
::separator
. $value;
125 # Third: The directory is not language dependent, the parent is language dependent
127 if (( ! $dirismultilingual ) && ( $parentismultilingual ))
129 $value = $directoryhashref->{'HostName'}; # there is only one
130 delete($directoryhashref->{'HostName'});
132 foreach $key (keys %{$parentdirectoryhashref}) # the parent directory
134 if ( $key =~ /\bHostName\b/ )
136 $parentvalue = $parentdirectoryhashref->{$key}; # there is only one
137 $directoryhashref->{$key} = $parentvalue . $installer::globals
::separator
. $value;
141 $directoryhashref->{'ismultilingual'} = 1; # now this directory is also language dependent
147 #############################################################################
148 # Files with flag NOT_IN_SUITE do not need to be packed into
149 # Suite installation sets
150 #############################################################################
152 sub remove_office_start_language_files
154 my ($productarrayref) = @_;
158 for ( my $i = 0; $i <= $#{$productarrayref}; $i++ )
160 my $oneitem = ${$productarrayref}[$i];
163 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; }
165 if (!($styles =~ /\bSET_OFFICE_LANGUAGE\b/))
167 push(@newitems, $oneitem);
171 my $infoline = "INFO: Flag SET_OFFICE_LANGUAGE \-\> Removing $oneitem->{'gid'} from file list.\n";
172 push( @installer::globals
::logfileinfo
, $infoline);
179 #############################################################################
180 # Registryitems for Uninstall have to be removed
181 #############################################################################
183 sub remove_uninstall_regitems_from_script
185 my ($registryarrayref) = @_;
189 for ( my $i = 0; $i <= $#{$registryarrayref}; $i++ )
191 my $oneitem = ${$registryarrayref}[$i];
194 if ( $oneitem->{'Subkey'} ) { $subkey = $oneitem->{'Subkey'}; }
196 if ( $subkey =~ /Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall/ ) { next; }
198 push(@newitems, $oneitem);
204 ##############################################################################
205 # Searching the language module for a specified language
206 ##############################################################################
208 sub get_languagespecific_module
210 my ( $lang, $modulestring ) = @_;
212 my $langmodulestring = "";
215 foreach $module ( keys %installer::globals
::alllangmodules
)
217 if (( $installer::globals
::alllangmodules
{$module} eq $lang ) && ( $modulestring =~ /\b$module\b/ ))
219 $langmodulestring = "$langmodulestring,$module";
223 $langmodulestring =~ s/^\s*,//;
225 if ( $langmodulestring eq "" ) { installer
::exiter
::exit_program
("ERROR: No language pack module found for language $lang in string \"$modulestring\"!", "get_languagespecific_module"); }
227 return $langmodulestring;
230 ##############################################################################
231 # Removing all items in product lists which do not have the correct languages
232 ##############################################################################
234 sub resolving_all_languages_in_productlists
236 my ($productarrayref, $languagesarrayref) = @_;
238 my @itemsinalllanguages = ();
242 for ( my $i = 0; $i <= $#{$productarrayref}; $i++ )
244 my $oneitem = ${$productarrayref}[$i];
246 my $ismultilingual = $oneitem->{'ismultilingual'};
248 if (!($ismultilingual)) # nothing to do with single language items
250 $oneitem->{'specificlanguage'} = "";
251 push(@itemsinalllanguages, $oneitem);
253 else #all language dependent files
255 for ( my $j = 0; $j <= $#{$languagesarrayref}; $j++ ) # iterating over all languages
257 my $onelanguage = ${$languagesarrayref}[$j];
259 my %oneitemhash = ();
261 foreach $key (keys %{$oneitem})
263 if ( $key =~ /\(\S+\)/ ) # this are the language dependent keys
265 if ( $key =~ /\(\Q$onelanguage\E\)/ )
267 $value = $oneitem->{$key};
268 $oneitemhash{$key} = $value;
273 $value = $oneitem->{$key};
274 $oneitemhash{$key} = $value;
278 $oneitemhash{'specificlanguage'} = $onelanguage;
280 if ( $oneitemhash{'haslanguagemodule'} )
282 my $langmodulestring = get_languagespecific_module
($onelanguage, $oneitemhash{'modules'});
283 $oneitemhash{'modules'} = $langmodulestring;
286 push(@itemsinalllanguages, \
%oneitemhash);
291 return \
@itemsinalllanguages;
294 ################################################################################
295 # Removing all modules, that have the flag LANGUAGEMODULE, but do not
296 # have the correct language
297 ################################################################################
299 sub remove_not_required_language_modules
301 my ($modulesarrayref, $languagesarrayref) = @_;
305 for ( my $i = 0; $i <= $#{$modulesarrayref}; $i++ )
307 my $module = ${$modulesarrayref}[$i];
309 if ( $module->{'Styles'} ) { $styles = $module->{'Styles'}; }
311 if ( $styles =~ /\bLANGUAGEMODULE\b/ )
313 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"); }
314 my $modulelanguage = $module->{'Language'};
315 # checking, if language is required
317 for ( my $j = 0; $j <= $#{$languagesarrayref}; $j++ )
319 my $onelanguage = ${$languagesarrayref}[$j];
320 if ( $onelanguage eq $modulelanguage )
327 if ( $doinclude ) { push(@allmodules, $module); }
331 push(@allmodules, $module);
338 ################################################################################
339 # Removing all modules, that have a spellchecker language that is not
340 # required for this product (spellchecker selection).
341 # All required spellchecker languages are stored in
342 # %installer::globals::spellcheckerlanguagehash
343 ################################################################################
345 sub remove_not_required_spellcheckerlanguage_modules
347 my ($modulesarrayref) = @_;
352 for ( my $i = 0; $i <= $#{$modulesarrayref}; $i++ )
354 my $module = ${$modulesarrayref}[$i];
355 if ( $module->{'Spellcheckerlanguage'} ) # selecting modules with Spellcheckerlanguage
357 if ( exists($installer::globals
::spellcheckerlanguagehash
{$module->{'Spellcheckerlanguage'}}) )
359 push(@allmodules, $module);
363 $infoline = "Spellchecker selection: Removing module $module->{'gid'}\n";
364 push( @installer::globals
::logfileinfo
, $infoline);
366 # Collecting all files at modules that are removed
368 if ( $module->{'Files'} )
370 if ( $module->{'Files'} =~ /^\s*\((.*?)\)\s*$/ )
374 my $filelisthash = installer
::converter
::convert_stringlist_into_hash
(\
$filelist, ",");
375 foreach my $onefile ( keys %{$filelisthash} ) { $installer::globals
::spellcheckerfilehash
{$onefile} = 1; }
382 push(@allmodules, $module);
389 ################################################################################
390 # Removing all modules, that belong to a module that was removed
391 # in "remove_not_required_spellcheckerlanguage_modules" because of the
392 # spellchecker language. The files belonging to the modules are collected
393 # in %installer::globals::spellcheckerfilehash.
394 ################################################################################
396 sub remove_not_required_spellcheckerlanguage_files
398 my ($filesarrayref) = @_;
403 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ )
405 my $onefile = ${$filesarrayref}[$i];
406 # FIXME: some items don't have 'gid'
407 if ( (defined $onefile->{'gid'}) && exists($installer::globals
::spellcheckerfilehash
{$onefile->{'gid'}}) )
409 $infoline = "Spellchecker selection: Removing file $onefile->{'gid'}\n";
410 push( @installer::globals
::logfileinfo
, $infoline);
413 push(@filesarray, $onefile);
419 ################################################################################
420 # Looking for directories without correct HostName
421 ################################################################################
423 sub checking_directories_with_corrupt_hostname
425 my ($dirsref, $languagesarrayref) = @_;
427 for ( my $i = 0; $i <= $#{$dirsref}; $i++ )
429 my $onedir = ${$dirsref}[$i];
433 if ( $onedir->{'HostName'} ) { $hostname = $onedir->{'HostName'}; }
435 if ( $hostname eq "" )
438 for ( my $j = 0; $j <= $#{$languagesarrayref}; $j++ ) { $langstring .= ${$languagesarrayref}[$j] . " "; }
439 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");
442 if ( $hostname eq "FAILURE" )
444 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");
449 ################################################################################
450 # Setting global properties
451 ################################################################################
453 sub set_global_directory_hostnames
455 my ($dirsref, $allvariables) = @_;
457 for ( my $i = 0; $i <= $#{$dirsref}; $i++ )
459 my $onedir = ${$dirsref}[$i];
461 if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; }
463 if ( $styles =~ /\bOFFICEDIRECTORY\b/ )
465 $installer::globals
::officedirhostname
= $onedir->{'HostName'};
466 $installer::globals
::officedirgid
= $onedir->{'gid'};
467 $allvariables->{'OFFICEDIRECTORYHOSTNAME'} = $installer::globals
::officedirhostname
;
472 ########################################################
473 # Recursively defined procedure to order
474 # modules and directories
475 ########################################################
479 my ($allitems, $startparent, $newitemorder) = @_;
481 for ( my $i = 0; $i <= $#{$allitems}; $i++ )
483 my $gid = ${$allitems}[$i]->{'gid'};
485 if ( ${$allitems}[$i]->{'ParentID'} ) { $parent = ${$allitems}[$i]->{'ParentID'}; }
487 if ( $parent eq $startparent )
489 push(@
{$newitemorder}, ${$allitems}[$i]);
491 get_children
($allitems, $parent, $newitemorder); # recursive!
496 ################################################################################
497 # Using langpack copy action for language packs
498 ################################################################################
500 sub use_langpack_copy_scpaction
502 my ($scpactionsref) = @_;
504 for ( my $i = 0; $i <= $#{$scpactionsref}; $i++ )
506 my $onescpaction = ${$scpactionsref}[$i];
507 if (( $onescpaction->{'LangPackCopy'} ) && ( $onescpaction->{'LangPackCopy'} ne "" )) { $onescpaction->{'Copy'} = $onescpaction->{'LangPackCopy'}; }
511 ################################################################################
512 # Using dev copy patch action for developer snapshot builds
513 ################################################################################
515 sub use_devversion_copy_scpaction
517 my ($scpactionsref) = @_;
519 for ( my $i = 0; $i <= $#{$scpactionsref}; $i++ )
521 my $onescpaction = ${$scpactionsref}[$i];
522 if (( $onescpaction->{'DevVersionCopy'} ) && ( $onescpaction->{'DevVersionCopy'} ne "" )) { $onescpaction->{'Copy'} = $onescpaction->{'DevVersionCopy'}; }
526 ################################################################################
527 # Shifting parent directories of URE and Basis layer, so that
528 # these directories are located below the Brand layer.
529 # Style: SHIFT_BASIS_INTO_BRAND_LAYER
530 ################################################################################
532 sub shift_basis_directory_parents
538 my $officedirgid = "";
540 for ( my $i = 0; $i <= $#{$dirsref}; $i++ )
542 my $onedir = ${$dirsref}[$i];
544 if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; }
546 if ( $styles =~ /\bOFFICEDIRECTORY\b/ ) { $officedirgid = $onedir->{'gid'}; }
549 if ( $officedirgid ne "" )
551 for ( my $i = 0; $i <= $#{$dirsref}; $i++ )
553 my $onedir = ${$dirsref}[$i];
555 if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; }
557 if (( $styles =~ /\bBASISDIRECTORY\b/ ) || ( $styles =~ /\bUREDIRECTORY\b/ ))
559 $onedir->{'ParentID'} = $officedirgid;
563 # Sorting directories
564 my $startgid = "PREDEFINED_PROGDIR";
565 get_children
($dirsref, $startgid, \
@alldirs);
571 ################################################################################
572 # Setting the name of the directory with style OFFICEDIRECTORY.
573 # The name can be defined in property OFFICEDIRECTORYNAME.
574 ################################################################################
576 sub set_officedirectory_name
578 my ($dirsref, $officedirname) = @_;
580 for ( my $i = 0; $i <= $#{$dirsref}; $i++ )
582 my $onedir = ${$dirsref}[$i];
584 if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; }
585 if ( $styles =~ /\bOFFICEDIRECTORY\b/ )
587 $onedir->{'HostName'} = $officedirname;
593 ################################################################################
594 # Simplifying the name for language dependent items from "Name (xy)" to "Name"
595 ################################################################################
597 sub changing_name_of_language_dependent_keys
599 my ($itemsarrayref) = @_;
601 # Changing key for multilingual items from "Name ( )" to "Name" or "HostName ( )" to "HostName"
603 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
605 my $oneitem = ${$itemsarrayref}[$i];
606 my $onelanguage = $oneitem->{'specificlanguage'};
608 if (!($onelanguage eq "" )) # language dependent item
612 foreach $itemkey (keys %{$oneitem})
614 if ( $itemkey =~ /^\s*(\S+?)\s+\(\S+\)\s*$/ )
617 my $itemvalue = $oneitem->{$itemkey};
618 $oneitem->{$newitemkey} = $itemvalue;
619 delete($oneitem->{$itemkey});
626 ################################################################################
627 # Replacement of setup variables in ConfigurationItems and ProfileItems
628 # <productkey>, <buildid>, <sequence_languages>, <productcode>, <upgradecode>, <productupdate>
629 ################################################################################
631 sub replace_setup_variables
633 my ($itemsarrayref, $languagestringref, $hashref) = @_;
635 my $languagesstring = $$languagestringref;
636 $languagesstring =~ s/\_/ /g; # replacing underscore with whitespace
638 my $productname = $hashref->{'PRODUCTNAME'};
639 my $productversion = $hashref->{'PRODUCTVERSION'};
640 my $libo_version_major = "";
641 if ( $hashref->{'LIBO_VERSION_MAJOR'} ) { $libo_version_major = $hashref->{'LIBO_VERSION_MAJOR'}; }
642 my $productkey = $productname . " " . $productversion;
644 # string $buildid, which is used to replace the setup variable <buildid>
646 my $localbuild = $installer::globals
::build
;
648 if ( $localbuild =~ /^\s*(\w+?)(\d+)\s*$/ ) { $localbuild = $2; } # using "680" instead of "src680"
650 my $buildidstring = `cd $ENV{'SRCDIR'} 2>&1 >/dev/null && git log -n 1 --pretty=format:"%H"`;
651 if ($?
|| !$buildidstring) {
652 $buildidstring = $localbuild . "(Build:" . $installer::globals
::buildid
. ")";
655 my $updateid = $productname . "_" . $libo_version_major . "_" . $$languagestringref;
656 $updateid =~ s/ /_/g;
658 my $updatechannel = "";
659 if ( $ENV{'UPDATE_CONFIG'} && $ENV{'UPDATE_CONFIG'} ne "")
661 open(CONFIG
, glob($ENV{'UPDATE_CONFIG'}));
665 if (/^s*(\S+)=(\S+)$/)
669 if ($key eq "channel")
671 $updatechannel = $val;
678 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
680 my $oneitem = ${$itemsarrayref}[$i];
681 my $value = $oneitem->{'Value'};
683 $value =~ s/\<buildid\>/$buildidstring/;
684 $value =~ s/\<sequence_languages\>/$languagesstring/;
685 $value =~ s/\<productkey\>/$productkey/;
686 $value =~ s/\<productcode\>/$installer::globals::productcode/;
687 $value =~ s/\<upgradecode\>/$installer::globals::upgradecode/;
688 $value =~ s/\<alllanguages\>/$languagesstring/;
689 $value =~ s/\<sourceid\>/$installer::globals::build/;
690 $value =~ s/\<updateid\>/$updateid/;
691 $value =~ s/\<updatechannel\>/$updatechannel/;
692 $value =~ s/\<pkgformat\>/$installer::globals::packageformat/;
693 $ENV{'OOO_VENDOR'} = "" if !defined $ENV{'OOO_VENDOR'};
694 $value =~ s/\<vendor\>/$ENV{'OOO_VENDOR'}/;
696 $oneitem->{'Value'} = $value;
700 ################################################################################
701 # By defining variable LOCALUSERDIR in *.lst it is possible to change
702 # the standard destination of user directory defined in scp2 ($SYSUSERCONFIG).
703 ################################################################################
705 sub replace_userdir_variable
707 my ($itemsarrayref, $allvariableshashref) = @_;
710 if ( $allvariableshashref->{'LOCALUSERDIR'} ) { $userdir = $allvariableshashref->{'LOCALUSERDIR'}; }
711 else { $userdir = $installer::globals
::simpledefaultuserdir
; }
713 if ( $userdir ne "" )
715 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
717 my $oneitem = ${$itemsarrayref}[$i];
718 $oneitem->{'Value'} =~ s/\$SYSUSERCONFIG/$userdir/;
723 #####################################################################################
724 # Files and ConfigurationItems are not included for all languages.
725 # For instance asian fonts. These can be removed, if no "Name" is found.
726 # ConfigurationItems are not always defined in the linguistic configuration file.
727 # The "Key" cannot be found for them.
728 #####################################################################################
730 sub remove_non_existent_languages_in_productlists
732 my ($itemsarrayref, $languagestringref, $searchkey, $itemtype) = @_;
734 # Removing of all non existent files, for instance asian fonts
736 installer
::logger
::include_header_into_logfile
("Removing for this language $$languagestringref:");
738 my @allexistentitems = ();
742 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
744 my $oneitem = ${$itemsarrayref}[$i];
745 my $oneitemname = ""; # $searchkey is "Name" for files and "Key" for ConfigurationItems
747 if ( $oneitem->{$searchkey} ) { $oneitemname = $oneitem->{$searchkey} }
749 my $itemtoberemoved = 0;
751 if ($oneitemname eq "") # for instance asian font in english installation set
753 $itemtoberemoved = 1;
756 if ($itemtoberemoved)
758 $infoline = "WARNING: Language $$languagestringref: No $itemtype packed for $oneitem->{'gid'}!\n";
759 push( @installer::globals
::logfileinfo
, $infoline);
763 push(@allexistentitems, $oneitem);
768 push( @installer::globals
::logfileinfo
, $infoline);
770 return \
@allexistentitems;
773 ########################################################################
774 # Input is the directory gid, output the "HostName" of the directory
775 ########################################################################
777 sub get_Directoryname_From_Directorygid
779 my ($dirsarrayref ,$searchgid, $onelanguage, $oneitemgid) = @_;
781 my $directoryname = "";
785 for ( my $i = 0; $i <= $#{$dirsarrayref}; $i++ )
787 $onedirectory = ${$dirsarrayref}[$i];
788 my $directorygid = $onedirectory->{'gid'};
790 if ($directorygid eq $searchgid)
799 installer
::exiter
::exit_program
("ERROR: Gid $searchgid not defined in $installer::globals::setupscriptname", "get_Directoryname_From_Directorygid");
802 if ( ! ( $onedirectory->{'ismultilingual'} )) # the directory is not language dependent
804 $directoryname = $onedirectory->{'HostName'};
808 $directoryname = $onedirectory->{"HostName ($onelanguage)"};
811 # gid_Dir_Template_Wizard_Letter is defined as language dependent directory, but the file gid_Dir_Template_Wizard_Letter
812 # is not language dependent. Therefore $onelanguage is not defined. But which language is the correct language for the
814 # Perhaps better solution: In scp it must be forbidden to have a language independent file in a language dependent directory.
816 if (( ! $directoryname ) && ( $onelanguage eq "" ))
818 installer
::exiter
::exit_program
("ERROR (in scp): Directory $searchgid is language dependent, but not $oneitemgid inside this directory", "get_Directoryname_From_Directorygid");
821 return \
$directoryname;
824 ##################################################################
825 # Getting destination directory for links, files and profiles
826 ##################################################################
828 sub get_Destination_Directory_For_Item_From_Directorylist
# this is used for Files, Profiles and Links
830 my ($itemarrayref, $dirsarrayref) = @_;
832 for ( my $i = 0; $i <= $#{$itemarrayref}; $i++ )
834 my $oneitem = ${$itemarrayref}[$i];
835 my $oneitemgid = $oneitem->{'gid'};
836 my $directorygid = $oneitem->{'Dir'}; # for instance gid_Dir_Program
837 my $netdirectorygid = "";
838 my $onelanguage = $oneitem->{'specificlanguage'};
839 my $ispredefinedprogdir = 0;
840 my $ispredefinedconfigdir = 0;
842 my $oneitemname = $oneitem->{'Name'};
844 if ( $oneitem->{'NetDir'} ) { $netdirectorygid = $oneitem->{'NetDir'}; }
846 installer
::pathanalyzer
::make_absolute_filename_to_relative_filename
(\
$oneitemname); # making /registry/schema/org/openoffice/VCL.xcs to VCL.xcs
850 if ( $netdirectorygid eq "" ) # if NetDir is defined, it is privileged
852 $searchdirgid = $directorygid
856 $searchdirgid = $netdirectorygid
859 if ($searchdirgid =~ /PREDEFINED_PROGDIR/) # the root directory is not defined in setup script
861 $ispredefinedprogdir = 1;
864 if ($searchdirgid =~ /PREDEFINED_CONFIGDIR/) # the root directory is not defined in setup script
866 $ispredefinedconfigdir = 1;
871 if ($oneitem->{'DoNotMessWithSymlinks'})
873 $destfilename = $oneitem->{'Name'};
875 elsif ((!( $ispredefinedprogdir )) && (!( $ispredefinedconfigdir )))
877 my $directorynameref = get_Directoryname_From_Directorygid
($dirsarrayref, $searchdirgid, $onelanguage, $oneitemgid);
879 if ($oneitem->{'Styles'}) { $styles = $oneitem->{'Styles'}; }
880 if ($styles =~ /\bFILELIST\b/)
882 $destfilename = $$directorynameref . $installer::globals
::separator
. $oneitemname;
886 $destfilename = $$directorynameref . $installer::globals
::separator
. $oneitem->{'Name'};
891 $destfilename = $oneitemname;
894 $oneitem->{'destination'} = $destfilename;
898 ##########################################################################
899 # Searching a file in a list of paths
900 ##########################################################################
902 sub get_sourcepath_from_filename_and_includepath_classic
904 my ($searchfilenameref, $includepatharrayref, $write_logfile) = @_;
906 my ($onefile, $includepath, $infoline);
908 my $foundsourcefile = 0;
910 for ( my $j = 0; $j <= $#{$includepatharrayref}; $j++ )
912 $includepath = ${$includepatharrayref}[$j];
913 installer
::remover
::remove_leading_and_ending_whitespaces
(\
$includepath);
915 $onefile = $includepath . $installer::globals
::separator
. $$searchfilenameref;
919 $foundsourcefile = 1;
924 if (!($foundsourcefile))
926 $onefile = ""; # the sourcepath has to be empty
929 $infoline = "ERROR: Source for $$searchfilenameref not found (classic)!\n"; # Important message in log file
930 push( @installer::globals
::logfileinfo
, $infoline);
937 $infoline = "SUCCESS: Source for $$searchfilenameref: $onefile\n";
938 push( @installer::globals
::logfileinfo
, $infoline);
945 ##########################################################################
946 # Input is one file name, output the complete absolute path of this file
947 ##########################################################################
949 sub get_sourcepath_from_filename_and_includepath
951 my ($searchfilenameref, $unused, $write_logfile) = @_;
953 my ($onefile, $includepath, $infoline);
955 my $foundsourcefile = 0;
956 my $foundnewname = 0;
958 for ( my $j = 0; $j <= $#installer::globals
::allincludepaths
; $j++ )
960 my $allfiles = $installer::globals
::allincludepaths
[$j];
962 if ( exists( $allfiles->{$$searchfilenameref} ))
964 $onefile = $allfiles->{'includepath'} . $installer::globals
::separator
. $$searchfilenameref;
965 $foundsourcefile = 1;
970 if (!($foundsourcefile)) # testing with lowercase filename
972 # Attention: README01.html is copied for Windows to readme01.html, not case sensitive
974 for ( my $j = 0; $j <= $#installer::globals
::allincludepaths
; $j++ )
976 my $allfiles = $installer::globals
::allincludepaths
[$j];
978 my $newfilename = $$searchfilenameref;
979 $newfilename =~ s/readme/README/; # special handling for readme files
980 $newfilename =~ s/license/LICENSE/; # special handling for license files
982 if ( exists( $allfiles->{$newfilename} ))
984 $onefile = $allfiles->{'includepath'} . $installer::globals
::separator
. $newfilename;
985 $foundsourcefile = 1;
992 if (!($foundsourcefile))
994 $onefile = ""; # the sourcepath has to be empty
997 $infoline = "ERROR: Source for $$searchfilenameref not found!\n"; # Important message in log file
998 push( @installer::globals
::logfileinfo
, $infoline);
1003 if ( $write_logfile)
1005 if (!($foundnewname))
1007 $infoline = "SUCCESS: Source for $$searchfilenameref: $onefile\n";
1011 $infoline = "SUCCESS/WARNING: Special handling for $$searchfilenameref: $onefile\n";
1013 push( @installer::globals
::logfileinfo
, $infoline);
1020 ##############################################################
1021 # Getting all source paths for all files to be packed
1022 # $item can be "Files" or "ScpActions"
1023 ##############################################################
1025 sub get_Source_Directory_For_Files_From_Includepathlist
1027 my ($filesarrayref, $includepatharrayref, $dirsref, $item, $allvariables) = @_;
1029 installer
::logger
::include_header_into_logfile
("$item:");
1031 my ($foundit, $dontcare, $extrarootdir) =
1032 get_office_directory_gid_and_hostname
($dirsref);
1035 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ )
1037 my $onefile = ${$filesarrayref}[$i];
1038 my $onelanguage = $onefile->{'specificlanguage'};
1040 if ( ! $onefile->{'Name'} ) { installer
::exiter
::exit_program
("ERROR: $item without name ! GID: $onefile->{'gid'} ! Language: $onelanguage", "get_Source_Directory_For_Files_From_Includepathlist"); }
1042 my $onefilename = $onefile->{'Name'};
1043 if ( $item eq "ScpActions" ) { $onefilename =~ s/\//$installer::globals
::separator
/g
; }
1044 $onefilename =~ s/^\s*\Q$installer::globals::separator\E//; # filename begins with a slash, for instance /registry/schema/org/openoffice/VCL.xcs
1047 my $file_can_miss = 0;
1048 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; }
1050 if (( $installer::globals
::languagepack
) && ( ! $onefile->{'ismultilingual'} ) && ( ! ( $styles =~ /\bFORCELANGUAGEPACK\b/ ))) { $file_can_miss = 1; }
1051 if (( $installer::globals
::helppack
) && ( ! $onefile->{'ismultilingual'} ) && ( ! ( $styles =~ /\bFORCEHELPPACK\b/ ))) { $file_can_miss = 1; }
1053 my $sourcepathref = "";
1055 my $destination = $onefile->{'destination'};
1056 my $instdirdestination;
1059 if (($installer::globals
::iswindowsbuild
) && $foundit && $extrarootdir)
1061 $destination =~ s
,$extrarootdir/,,; # remove it from path
1063 if (($installer::globals
::languagepack
) && ($installer::globals
::ismacbuild
))
1064 { # source files are in $(PRODUCTNAME).app where they will
1065 # actually copied by the user executing the Language Pack.app
1066 $destination =~ s
, Language Pack
.app
/,.app/,;
1068 $instdirdestination = $ENV{'INSTDIR'} . $installer::globals
::separator
. $destination;
1070 if ($instdirdestination && -f
$instdirdestination)
1072 $infoline = "SUCCESS: INSTDIR Source for $onefilename: $instdirdestination\n";
1073 push( @installer::globals
::logfileinfo
, $infoline);
1074 $$sourcepathref = $instdirdestination;
1078 if ( $file_can_miss ) { $sourcepathref = get_sourcepath_from_filename_and_includepath
(\
$onefilename, $includepatharrayref, 0); }
1079 else { $sourcepathref = get_sourcepath_from_filename_and_includepath
(\
$onefilename, $includepatharrayref, 1); }
1082 $onefile->{'sourcepath'} = $$sourcepathref; # This $$sourcepathref is empty, if no source was found
1085 $infoline = "\n"; # empty line after listing of all files
1086 push( @installer::globals
::logfileinfo
, $infoline);
1089 #################################################################################
1090 # Removing files, that shall not be included into languagepacks
1091 # (because of rpm conflicts)
1092 #################################################################################
1094 sub remove_Files_For_Languagepacks
1096 my ($itemsarrayref) = @_;
1100 my @newitemsarray = ();
1102 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
1104 my $oneitem = ${$itemsarrayref}[$i];
1105 my $gid = $oneitem->{'gid'};
1107 # scp Todo: Remove asap after removal of old setup
1109 if (( $gid eq "gid_File_Extra_Fontunxpsprint" ) ||
1110 ( $gid eq "gid_File_Extra_Migration_Lang" ))
1112 $infoline = "ATTENTION: Removing item $oneitem->{'gid'} from the installation set.\n";
1113 push( @installer::globals
::logfileinfo
, $infoline);
1118 push(@newitemsarray, $oneitem);
1121 return \
@newitemsarray;
1124 #################################################################################
1125 # Files, whose source directory is not found, are removed now (this is an ERROR)
1126 #################################################################################
1128 sub remove_Files_Without_Sourcedirectory
1130 my ($filesarrayref) = @_;
1134 my $error_occurred = 0;
1135 my @missingfiles = ();
1136 push(@missingfiles, "ERROR: The following files could not be found: \n");
1138 my @newfilesarray = ();
1140 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ )
1142 my $onefile = ${$filesarrayref}[$i];
1143 my $sourcepath = $onefile->{'sourcepath'};
1145 if ($sourcepath eq "")
1147 my $styles = $onefile->{'Styles'};
1148 my $filename = $onefile->{'Name'};
1150 if ( ! $installer::globals
::languagepack
&& !$installer::globals
::helppack
)
1152 $infoline = "ERROR: Removing file $filename from file list.\n";
1153 push( @installer::globals
::logfileinfo
, $infoline);
1155 push(@missingfiles, "ERROR: File not found: $filename\n");
1156 $error_occurred = 1;
1158 next; # removing this file from list, if sourcepath is empty
1160 elsif ( $installer::globals
::languagepack
) # special case for language packs
1162 if (( $onefile->{'ismultilingual'} ) || ( $styles =~ /\bFORCELANGUAGEPACK\b/ ))
1164 $infoline = "ERROR: Removing file $filename from file list.\n";
1165 push( @installer::globals
::logfileinfo
, $infoline);
1167 push(@missingfiles, "ERROR: File not found: $filename\n");
1168 $error_occurred = 1;
1170 next; # removing this file from list, if sourcepath is empty
1174 $infoline = "INFO: Removing file $filename from file list. It is not language dependent.\n";
1175 push( @installer::globals
::logfileinfo
, $infoline);
1176 $infoline = "INFO: It is not language dependent and can be ignored in language packs.\n";
1177 push( @installer::globals
::logfileinfo
, $infoline);
1179 next; # removing this file from list, if sourcepath is empty
1182 else # special case for help packs
1184 if (( $onefile->{'ismultilingual'} ) || ( $styles =~ /\bFORCEHELPPACK\b/ ))
1186 $infoline = "ERROR: Removing file $filename from file list.\n";
1187 push( @installer::globals
::logfileinfo
, $infoline);
1189 push(@missingfiles, "ERROR: File not found: $filename\n");
1190 $error_occurred = 1;
1192 next; # removing this file from list, if sourcepath is empty
1196 $infoline = "INFO: Removing file $filename from file list. It is not language dependent.\n";
1197 push( @installer::globals
::logfileinfo
, $infoline);
1198 $infoline = "INFO: It is not language dependent and can be ignored in help packs.\n";
1199 push( @installer::globals
::logfileinfo
, $infoline);
1201 next; # removing this file from list, if sourcepath is empty
1206 push(@newfilesarray, $onefile);
1210 push( @installer::globals
::logfileinfo
, $infoline);
1212 if ( $error_occurred )
1214 for ( my $i = 0; $i <= $#missingfiles; $i++ ) { print "$missingfiles[$i]"; }
1215 installer
::exiter
::exit_program
("ERROR: Missing files", "remove_Files_Without_Sourcedirectory");
1218 return \
@newfilesarray;
1221 ############################################################################
1222 # License and Readme files in the default language have to be installed
1223 # in the directory with flag OFFICEDIRECTORY. If this is not defined
1224 # they have to be installed in the installation root.
1225 ############################################################################
1227 sub get_office_directory_gid_and_hostname
1229 my ($dirsarrayref) = @_;
1231 my $foundofficedir = 0;
1235 for ( my $i = 0; $i <= $#{$dirsarrayref}; $i++ )
1237 my $onedir = ${$dirsarrayref}[$i];
1238 if ( $onedir->{'Styles'} )
1240 my $styles = $onedir->{'Styles'};
1242 if ( $styles =~ /\bOFFICEDIRECTORY\b/ )
1244 $foundofficedir = 1;
1245 $gid = $onedir->{'gid'};
1246 $hostname = $onedir->{'HostName'};
1252 return ($foundofficedir, $gid, $hostname);
1255 ############################################################################
1256 # License and Readme files in the default language have to be installed
1257 # in the installation root (next to the program dir). This is in scp
1258 # project done by a post install basic script
1259 ############################################################################
1261 sub add_License_Files_into_Installdir
1263 my ($filesarrayref, $dirsarrayref, $languagesarrayref) = @_;
1267 my @newfilesarray = ();
1269 my $defaultlanguage = installer
::languages
::get_default_language
($languagesarrayref);
1271 my ($foundofficedir, $officedirectorygid, $officedirectoryhostname) = get_office_directory_gid_and_hostname
($dirsarrayref);
1273 # copy all files from directory share/readme, that contain the default language in their name
1274 # without default language into the installation root. This makes the settings of the correct
1275 # file names superfluous. On the other hand this requires a dependency to the directory
1278 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ )
1280 my $onefile = ${$filesarrayref}[$i];
1281 my $destination = $onefile->{'destination'};
1283 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; }
1285 if ( ( $destination =~ /share\Q$installer::globals::separator\Ereadme\Q$installer::globals::separator\E(\w+?)_?$defaultlanguage\.?(\w*)\s*/ )
1286 || (( $styles =~ /\bROOTLICENSEFILE\b/ ) && ( $destination =~ /\Q$installer::globals::separator\E?(\w+?)_?$defaultlanguage\.?(\w*?)\s*$/ )) )
1293 if ( $extension eq "" ) { $newfilename = $filename; }
1294 else { $newfilename = $filename . "\." . $extension; }
1297 my $newfile = \
%newfile;
1299 installer
::converter
::copy_item_object
($onefile, $newfile);
1301 $newfile->{'gid'} = $onefile->{'gid'} . "_Copy";
1302 $newfile->{'Name'} = $newfilename;
1303 $newfile->{'ismultilingual'} = "0";
1304 $newfile->{'specificlanguage'} = "";
1305 $newfile->{'haslanguagemodule'} = "0";
1307 if ( defined $newfile->{'InstallName'} )
1309 if ( $newfile->{'InstallName'} =~ /^\s*(.*?)_$defaultlanguage\.?(\w*?)\s*$/ )
1311 my $localfilename = $1;
1312 my $localextension = $2;
1314 if ( $localextension eq "" ) { $newfile->{'InstallName'} = $localfilename; }
1315 else { $newfile->{'InstallName'} = $localfilename . "\." . $localextension; }
1319 $newfile->{'removelangfromfile'} = "1"; # Important for files with an InstallName, because language also has to be removed there.
1321 if ( $foundofficedir )
1323 $newfile->{'Dir'} = $officedirectorygid;
1324 $newfile->{'destination'} = $officedirectoryhostname . $installer::globals
::separator
. $newfilename;
1328 $newfile->{'Dir'} = "PREDEFINED_PROGDIR";
1329 $newfile->{'destination'} = $newfilename;
1332 # Also setting "modules=gid_Module_Root_Brand" (module with style: ROOT_BRAND_PACKAGE)
1333 if ( $installer::globals
::rootbrandpackageset
)
1335 $newfile->{'modules'} = $installer::globals
::rootbrandpackage
;
1338 push(@newfilesarray, $newfile);
1340 $infoline = "New files: Adding file $newfilename for the installation root to the file list. Language: $defaultlanguage\n";
1341 push( @installer::globals
::logfileinfo
, $infoline);
1343 if ( defined $newfile->{'InstallName'} )
1345 $infoline = "New files: Using installation name: $newfile->{'InstallName'}\n";
1346 push( @installer::globals
::logfileinfo
, $infoline);
1350 push(@newfilesarray, $onefile);
1353 return \
@newfilesarray;
1356 ############################################################################
1357 # Some files are included for more than one language and have the same
1358 # name and the same destination directory for all languages. This would
1359 # lead to conflicts, if the filenames are not changed.
1360 # In scp project this files must have the flag MAKE_LANG_SPECIFIC
1361 # For this files, the language is included into the filename.
1362 ############################################################################
1364 sub make_filename_language_specific
1366 my ($filesarrayref) = @_;
1370 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ )
1372 my $onefile = ${$filesarrayref}[$i];
1374 if ( $onefile->{'ismultilingual'} )
1377 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; }
1378 if ( $styles =~ /\bMAKE_LANG_SPECIFIC\b/ )
1380 my $language = $onefile->{'specificlanguage'};
1381 my $olddestination = $onefile->{'destination'};
1382 my $oldname = $onefile->{'Name'};
1384 # Including the language into the file name.
1385 # But be sure, to include the language before the file extension.
1387 my $fileextension = "";
1389 if ( $onefile->{'Name'} =~ /(\.\w+?)\s*$/ ) { $fileextension = $1; }
1390 if ( $fileextension ne "" )
1392 $onefile->{'Name'} =~ s/\Q$fileextension\E\s*$/_$language$fileextension/;
1393 $onefile->{'destination'} =~ s/\Q$fileextension\E\s*$/_$language$fileextension/;
1396 $infoline = "Flag MAKE_LANG_SPECIFIC:\n";
1397 push( @installer::globals
::logfileinfo
, $infoline);
1398 $infoline = "Changing name from $oldname to $onefile->{'Name'} !\n";
1399 push( @installer::globals
::logfileinfo
, $infoline);
1400 $infoline = "Changing destination from $olddestination to $onefile->{'destination'} !\n";
1401 push( @installer::globals
::logfileinfo
, $infoline);
1407 ############################################################################
1408 # Because of the item "File" the source name must be "Name". Therefore
1409 # "Copy" is changed to "Name" and "Name" is changed to "DestinationName".
1410 ############################################################################
1412 sub change_keys_of_scpactions
1414 my ($itemsarrayref) = @_;
1416 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
1418 my $oneitem = ${$itemsarrayref}[$i];
1422 # First Name to DestinationName, then deleting Name
1423 foreach $key (keys %{$oneitem})
1425 if ( $key =~ /\bName\b/ )
1427 my $value = $oneitem->{$key};
1429 $key =~ s/Name/DestinationName/;
1430 $oneitem->{$key} = $value;
1431 delete($oneitem->{$oldkey});
1435 # Second Copy to Name, then deleting Copy
1436 foreach $key (keys %{$oneitem})
1438 if ( $key =~ /\bCopy\b/ )
1440 my $value = $oneitem->{$key};
1442 $key =~ s/Copy/Name/;
1443 $oneitem->{$key} = $value;
1444 delete($oneitem->{$oldkey});
1450 ############################################################################
1451 # Removing all language pack files from installation set (files with
1452 # the style LANGUAGEPACK), except this is a language pack.
1453 ############################################################################
1455 sub remove_Languagepacklibraries_from_Installset
1457 my ($itemsarrayref) = @_;
1461 my @newitemsarray = ();
1463 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
1465 my $oneitem = ${$itemsarrayref}[$i];
1467 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; }
1469 if ( $styles =~ /\bLANGUAGEPACK\b/ )
1471 $infoline = "Removing language pack file $oneitem->{'gid'} from the installation set.\n";
1472 push( @installer::globals
::globallogfileinfo
, $infoline);
1477 push(@newitemsarray, $oneitem);
1481 push( @installer::globals
::globallogfileinfo
, $infoline);
1483 return \
@newitemsarray;
1486 ############################################################################
1487 # Removing all help pack files from installation set (files with
1488 # the style HELPPACK), except this is a help pack.
1489 ############################################################################
1491 sub remove_Helppacklibraries_from_Installset
1493 my ($itemsarrayref) = @_;
1497 my @newitemsarray = ();
1499 for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
1501 my $oneitem = ${$itemsarrayref}[$i];
1503 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; }
1505 if ( $styles =~ /\bHELPPACK\b/ )
1507 $infoline = "Removing help pack file $oneitem->{'gid'} from the installation set.\n";
1508 push( @installer::globals
::globallogfileinfo
, $infoline);
1513 push(@newitemsarray, $oneitem);
1517 push( @installer::globals
::globallogfileinfo
, $infoline);
1519 return \
@newitemsarray;
1522 ############################################################################
1523 # Some files contain a $ in their name. epm conflicts with such files.
1524 # Solution: Renaming this files, converting "$" to "$$"
1525 ############################################################################
1527 sub quoting_illegal_filenames
1529 my ($filesarrayref) = @_;
1531 # This function has to be removed as soon as possible!
1533 installer
::logger
::include_header_into_logfile
("Renaming illegal filenames:");
1535 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ )
1537 my $onefile = ${$filesarrayref}[$i];
1538 my $filename = $onefile->{'Name'};
1540 if ( $filename =~ /\$/ )
1542 my $sourcepath = $onefile->{'sourcepath'};
1543 my $destpath = $onefile->{'destination'};
1545 # sourcepath and destination have to be quoted for epm list file
1547 $destpath =~ s/\$/\$\$/g;
1548 $sourcepath =~ s/\$/\$\$/g;
1550 my $infoline = "ATTENTION: Files: Quoting sourcepath $onefile->{'sourcepath'} to $sourcepath\n";
1551 push( @installer::globals
::logfileinfo
, $infoline);
1552 $infoline = "ATTENTION: Files: Quoting destination path $onefile->{'destination'} to $destpath\n";
1553 push( @installer::globals
::logfileinfo
, $infoline);
1555 $onefile->{'sourcepath'} = $sourcepath;
1556 $onefile->{'destination'} = $destpath;
1561 ############################################################################
1562 # Removing multiple occurrences of same module.
1563 ############################################################################
1567 my ( $longlist ) = @_;
1570 $longlist =~ s/^\s+//;
1571 $longlist =~ s/\s+$//;
1572 $longlist =~ s/\s*,\s*/,/g;
1574 @tmpHash{split /,/, $longlist} = ();
1575 return join(",", sort keys %tmpHash);
1578 ###############################################################################
1579 # Add a directory with CREATE flag; save styles for already added directories
1580 ###############################################################################
1582 sub add_directory_with_create_flag_hash
1584 my ($alldirectoryhash, $directoryname, $specificlanguage, $gid, $styles, $modules) = @_;
1585 if ( ! $directoryname ) { installer
::exiter
::exit_program
("No directory name (HostName) set for specified language in gid $gid", "add_directory_with_create_flag_hash"); }
1586 my $origdirectoryname = $directoryname;
1587 my $newdirincluded = 0;
1588 if ( $styles =~ /\bCREATE\b/ )
1590 if ( ! $modules ) { installer
::exiter
::exit_program
("No assigned modules found for directory $directoryname", "add_directory_with_create_flag_hash"); }
1591 if (!(exists($alldirectoryhash->{$directoryname})))
1593 my %directoryhash = ();
1594 $directoryhash{'HostName'} = $directoryname;
1595 $directoryhash{'specificlanguage'} = $specificlanguage;
1596 $directoryhash{'Dir'} = $gid;
1597 $directoryhash{'Styles'} = $styles;
1599 # saving also the modules
1600 $directoryhash{'modules'} = $modules;
1602 $alldirectoryhash->{$directoryname} = \
%directoryhash;
1603 $newdirincluded = 1;
1605 # Problem: The $destinationpath can be share/registry/schema/org/openoffice
1606 # but not all directories contain files and will be added to this list.
1607 # Therefore the path has to be analyzed.
1609 while ( $directoryname =~ /(^.*\S)\Q$installer::globals::separator\E(\S.*?)\s*$/ ) # as long as the path contains slashes
1611 $directoryname = $1;
1613 if (!(exists($alldirectoryhash->{$directoryname})))
1615 my %directoryhash = ();
1617 $directoryhash{'HostName'} = $directoryname;
1618 $directoryhash{'specificlanguage'} = $specificlanguage;
1619 $directoryhash{'Dir'} = $gid;
1620 if ( ! $installer::globals
::iswindowsbuild
) { $directoryhash{'Styles'} = "(CREATE)"; } # Exception for Windows?
1622 # saving also the modules
1623 $directoryhash{'modules'} = $modules;
1625 $alldirectoryhash->{$directoryname} = \
%directoryhash;
1629 # Adding the modules to the module list!
1630 $alldirectoryhash->{$directoryname}->{'modules'} = $alldirectoryhash->{$directoryname}->{'modules'} . "," . $modules;
1636 # Adding the modules to the module list!
1637 $alldirectoryhash->{$directoryname}->{'modules'} = $alldirectoryhash->{$directoryname}->{'modules'} . "," . $modules;
1639 while ( $directoryname =~ /(^.*\S)\Q$installer::globals::separator\E(\S.*?)\s*$/ ) # as long as the path contains slashes
1641 $directoryname = $1;
1642 # Adding the modules to the module list!
1643 $alldirectoryhash->{$directoryname}->{'modules'} = $alldirectoryhash->{$directoryname}->{'modules'} . "," . $modules;
1648 # Saving the styles for already added directories in function collect_directories_from_filesarray
1650 if (( ! $newdirincluded ) && ( $styles ne "" ))
1652 $styles =~ s/\bWORKSTATION\b//;
1653 $styles =~ s/\bCREATE\b//;
1655 if (( ! ( $styles =~ /^\s*\(\s*\)\s*$/ )) && ( ! ( $styles =~ /^\s*\(\s*\,\s*\)\s*$/ )) && ( ! ( $styles =~ /^\s*$/ ))) # checking, if there are styles left
1657 $directoryname = $origdirectoryname;
1659 if ( exists($alldirectoryhash->{$directoryname}) )
1661 $alldirectoryhash->{$directoryname}->{'Styles'} = $styles;
1666 return $alldirectoryhash;
1669 #######################################################################
1670 # Collecting all directories needed for the epm list
1671 # 1. Looking for all destination paths in the files array
1672 # 2. Looking for directories with CREATE flag in the directory array
1673 #######################################################################
1675 ##################################
1676 # Collecting directories: Part 1
1677 ##################################
1679 sub collect_directories_from_filesarray
1681 my ($filesarrayref, $unixlinksarrayref) = @_;
1683 my %alldirectoryhash = ();
1684 my @filteredfilesarray = (); # without empty directories
1685 foreach my $onefile (@
{$filesarrayref})
1687 # The "file" can actually be an empty directory added e.g. by gb_Package_add_empty_directory.
1688 # TODO/LATER: it would be better if gb_Package_add_empty_directory added empty directories to
1689 # "directories with CREATE flag" instead of a filelist.
1690 if (-d
$onefile->{'sourcepath'})
1692 # Do the same as collect_directories_with_create_flag_from_directoryarray does
1693 %alldirectoryhash = %{add_directory_with_create_flag_hash
(\
%alldirectoryhash, $onefile->{'destination'}, $onefile->{'specificlanguage'}, $onefile->{'gid'}, "(CREATE)", $onefile->{'modules'})};
1695 else { push(@filteredfilesarray, $onefile); }
1698 # Preparing this already as hash, although the only needed value at the moment is the HostName
1699 # But also adding: "specificlanguage" and "Dir" (for instance gid_Dir_Program)
1701 foreach my $onefile (@filteredfilesarray, @
{$unixlinksarrayref})
1703 my $destinationpath = $onefile->{'destination'};
1705 installer
::pathanalyzer
::get_path_from_fullqualifiedname
(\
$destinationpath);
1706 $destinationpath =~ s/\Q$installer::globals::separator\E\s*$//; # removing ending slashes or backslashes
1710 if (!exists($alldirectoryhash{$destinationpath}))
1712 my %directoryhash = ();
1713 $directoryhash{'HostName'} = $destinationpath;
1714 $directoryhash{'specificlanguage'} = $onefile->{'specificlanguage'};
1715 $directoryhash{'Dir'} = $onefile->{'Dir'};
1716 $directoryhash{'modules'} = $onefile->{'modules'}; # NEW, saving modules
1717 $directoryhash{'gid'} = $onefile->{'gid'};
1719 $alldirectoryhash{$destinationpath} = \
%directoryhash;
1723 # Adding the modules to the module list!
1724 $alldirectoryhash{$destinationpath}->{'modules'} .= "," . $onefile->{'modules'};
1725 # Save file's gid iff this directory appears in only a single
1726 # file's FILELIST (so that unused directories will be filtered
1727 # out in remove_not_required_spellcheckerlanguage_files, based
1729 if ($alldirectoryhash{$destinationpath}->{'gid'}
1730 ne $onefile->{'gid'})
1732 $alldirectoryhash{$destinationpath}->{'gid'} = '';
1735 } while ($destinationpath =~ s/(^.*\S)\Q$installer::globals::separator\E(\S.*?)\s*$/$1/); # as long as the path contains slashes
1738 # Creating directory array
1739 foreach my $destdir ( keys %alldirectoryhash )
1741 $alldirectoryhash{$destdir}->{'modules'} = optimize_list
($alldirectoryhash{$destdir}->{'modules'});
1744 @_[0] = \
@filteredfilesarray; # out argument
1745 return \
%alldirectoryhash;
1748 ##################################
1749 # Collecting directories: Part 2
1750 ##################################
1752 sub collect_directories_with_create_flag_from_directoryarray
1754 my ($directoryarrayref, $alldirectoryhash) = @_;
1756 my @alldirectories = ();
1758 foreach my $onedir (@
{$directoryarrayref})
1760 $alldirectoryhash = add_directory_with_create_flag_hash
($alldirectoryhash, $onedir->{'HostName'}, $onedir->{'specificlanguage'}, $onedir->{'gid'}, $onedir->{'Styles'}, $onedir->{'modules'});
1763 # Creating directory array
1764 foreach my $destdir ( sort keys %{$alldirectoryhash} )
1766 $alldirectoryhash->{$destdir}->{'modules'} = optimize_list
($alldirectoryhash->{$destdir}->{'modules'});
1767 push(@alldirectories, $alldirectoryhash->{$destdir});
1770 return \
@alldirectories;
1773 #################################################
1774 # Determining the destination file of a link
1775 #################################################
1777 sub get_destination_file_path_for_links
1779 my ($linksarrayref, $filesarrayref) = @_;
1783 for ( my $i = 0; $i <= $#{$linksarrayref}; $i++ )
1786 my $onelink = ${$linksarrayref}[$i];
1787 if ( $onelink->{'FileID'} ) { $fileid = $onelink->{'FileID'}; }
1789 if (!( $fileid eq "" ))
1793 for ( my $j = 0; $j <= $#{$filesarrayref}; $j++ )
1795 my $onefile = ${$filesarrayref}[$j];
1796 my $filegid = $onefile->{'gid'};
1798 if ( $filegid eq $fileid )
1801 $onelink->{'destinationfile'} = $onefile->{'destination'};
1808 $infoline = "Warning: FileID $fileid for Link $onelink->{'gid'} not found!\n";
1809 push( @installer::globals
::logfileinfo
, $infoline);
1815 push( @installer::globals
::logfileinfo
, $infoline);
1818 #################################################
1819 # Determining the destination link of a link
1820 #################################################
1822 sub get_destination_link_path_for_links
1824 my ($linksarrayref) = @_;
1828 for ( my $i = 0; $i <= $#{$linksarrayref}; $i++ )
1830 my $shortcutid = "";
1831 my $onelink = ${$linksarrayref}[$i];
1832 if ( $onelink->{'ShortcutID'} ) { $shortcutid = $onelink->{'ShortcutID'}; }
1834 if (!( $shortcutid eq "" ))
1838 for ( my $j = 0; $j <= $#{$linksarrayref}; $j++ )
1840 my $destlink = ${$linksarrayref}[$j];
1841 my $shortcutgid = $destlink->{'gid'};
1843 if ( $shortcutgid eq $shortcutid )
1846 $onelink->{'destinationfile'} = $destlink->{'destination'}; # making key 'destinationfile'
1853 $infoline = "Warning: ShortcutID $shortcutid for Link $onelink->{'gid'} not found!\n";
1854 push( @installer::globals
::logfileinfo
, $infoline);
1860 push( @installer::globals
::logfileinfo
, $infoline);
1863 ###################################################################################
1864 # Items with flag WORKSTATION are not needed (here: links and configurationitems)
1865 ###################################################################################
1867 sub remove_workstation_only_items
1869 my ($itemarrayref) = @_;
1871 my @newitemarray = ();
1873 for ( my $i = 0; $i <= $#{$itemarrayref}; $i++ )
1875 my $oneitem = ${$itemarrayref}[$i];
1876 my $styles = $oneitem->{'Styles'};
1878 if (( $styles =~ /\bWORKSTATION\b/ ) &&
1879 (!( $styles =~ /\bNETWORK\b/ )) &&
1880 (!( $styles =~ /\bSTANDALONE\b/ )))
1882 next; # removing this link, it is only needed for a workstation installation
1885 push(@newitemarray, $oneitem);
1888 return \
@newitemarray;
1891 ################################################
1892 # Resolving relative path in links
1893 ################################################
1895 sub resolve_links_with_flag_relative
1897 my ($linksarrayref) = @_;
1899 # Before this step is:
1900 # destination=program/libsalhelperC52.so.3, this will be the name of the link
1901 # destinationfile=program/libsalhelperC52.so.3, this will be the linked file or name
1902 # If the flag RELATIVE is set, the paths have to be analyzed. If the flag is not set
1903 # (this will not occur in the future?) destinationfile has to be an absolute path name
1905 for ( my $i = 0; $i <= $#{$linksarrayref}; $i++ )
1907 my $onelink = ${$linksarrayref}[$i];
1908 my $styles = $onelink->{'Styles'};
1910 if ( $styles =~ /\bRELATIVE\b/ )
1912 # ToDo: This is only a simple not sufficient mechanism
1914 my $destination = $onelink->{'destination'};
1915 my $destinationfile = $onelink->{'destinationfile'};
1917 my $destinationpath = $destination;
1919 installer
::pathanalyzer
::get_path_from_fullqualifiedname
(\
$destinationpath);
1921 my $destinationfilepath = $destinationfile;
1923 # it is possible, that the destinationfile is no longer part of the files collector
1924 if ($destinationfilepath) { installer
::pathanalyzer
::get_path_from_fullqualifiedname
(\
$destinationfilepath); }
1925 else { $destinationfilepath = ""; }
1927 if ( $destinationpath eq $destinationfilepath )
1929 # link and file are in the same directory
1930 # Therefore the path of the file can be removed
1932 my $newdestinationfile = $destinationfile;
1933 installer
::pathanalyzer
::make_absolute_filename_to_relative_filename
(\
$newdestinationfile);
1935 $onelink->{'destinationfile'} = $newdestinationfile;
1941 ########################################################################
1942 # This function is a helper of function "assigning_modules_to_items"
1943 ########################################################################
1945 sub insert_for_item
($$$)
1947 my ($hash, $item, $id) = @_;
1949 if (!defined $hash->{$item})
1952 $hash->{$item} = \
@gids;
1954 my $gid_list = $hash->{$item};
1955 push @
{$gid_list}, $id;
1956 $hash->{$item} = $gid_list;
1959 sub build_modulegids_table
1961 my ($modulesref, $itemname) = @_;
1963 my %module_lookup_table = ();
1965 # build map of item names to list of respective module gids
1966 # containing these items
1967 for my $onemodule (@
{$modulesref})
1969 next if ( ! defined $onemodule->{$itemname} );
1970 # these are the items contained in this module
1971 # eg. Files = (gid_a_b_c,gid_d_e_f)
1972 my $module_gids = $onemodule->{$itemname};
1974 # prune outer brackets
1975 $module_gids =~ s
|^\s
*\
(||g
;
1976 $module_gids =~ s
|\
)\s
*$||g
;
1977 for my $id (split (/,/, $module_gids))
1980 insert_for_item
(\
%module_lookup_table, lc ($id), $onemodule->{'gid'});
1984 return \
%module_lookup_table;
1987 ########################################################################
1988 # Items like files do not know their modules
1989 # This function is a helper of function "assigning_modules_to_items"
1990 ########################################################################
1992 sub get_string_of_modulegids_for_itemgid
1994 my ($module_lookup_table, $modulesref, $itemgid, $itemname) = @_;
1996 my $allmodules = "";
1997 my $haslanguagemodule = 0;
1998 my %foundmodules = ();
2000 my $gid_list = $module_lookup_table->{lc($itemgid)};
2002 for my $gid (@
{$gid_list})
2004 $foundmodules{$gid} = 1;
2005 $allmodules = $allmodules . "," . $gid;
2006 # Is this module a language module? This info should be stored at the file.
2007 if ( exists($installer::globals
::alllangmodules
{$gid}) ) { $haslanguagemodule = 1; }
2010 $allmodules =~ s/^\s*\,//; # removing leading comma
2012 # Check: All modules or no module must have flag LANGUAGEMODULE
2013 if ( $haslanguagemodule )
2015 my $isreallylanguagemodule = _key_in_a_is_also_key_in_b
(\
%foundmodules, \
%installer::globals
::alllangmodules
);
2016 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"); }
2019 return ($allmodules, $haslanguagemodule);
2022 ########################################################
2023 # Items like files do not know their modules
2024 # This function add the {'modules'} to these items
2025 ########################################################
2027 sub assigning_modules_to_items
2029 my ($modulesref, $itemsref, $itemname) = @_;
2032 my $languageassignmenterror = 0;
2033 my @languageassignmenterrors = ();
2035 my $module_lookup_table = build_modulegids_table
($modulesref, $itemname);
2037 for my $oneitem (@
{$itemsref})
2039 my $itemgid = $oneitem->{'gid'};
2042 if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; }
2043 if (( $itemname eq "Dirs" ) && ( ! ( $styles =~ /\bCREATE\b/ ))) { next; }
2045 if ( $itemgid eq "" )
2047 installer
::exiter
::exit_program
("ERROR in item collection: No gid for item $oneitem->{'Name'}", "assigning_modules_to_items");
2050 # every item can belong to many modules
2052 my ($modulegids, $haslanguagemodule) = get_string_of_modulegids_for_itemgid
($module_lookup_table, $modulesref, $itemgid, $itemname);
2054 if ($modulegids eq "")
2056 installer
::exiter
::exit_program
("ERROR in file collection: No module found for $itemname $itemgid", "assigning_modules_to_items");
2059 $oneitem->{'modules'} = $modulegids;
2060 $oneitem->{'haslanguagemodule'} = $haslanguagemodule;
2062 # Important check: "ismultilingual" and "haslanguagemodule" must have the same value !
2063 if (( $oneitem->{'ismultilingual'} ) && ( ! $oneitem->{'haslanguagemodule'} ))
2065 $infoline = "Error: \"$oneitem->{'gid'}\" is multi lingual, but not in language pack (Assigned module: $modulegids)!\n";
2066 push( @installer::globals
::globallogfileinfo
, $infoline);
2067 push( @languageassignmenterrors, $infoline );
2068 $languageassignmenterror = 1;
2070 if (( $oneitem->{'haslanguagemodule'} ) && ( ! $oneitem->{'ismultilingual'} ))
2072 $infoline = "Error: \"$oneitem->{'gid'}\" is in language pack, but not multi lingual (Assigned module: $modulegids)!\n";
2073 push( @installer::globals
::globallogfileinfo
, $infoline);
2074 push( @languageassignmenterrors, $infoline );
2075 $languageassignmenterror = 1;
2079 if ($languageassignmenterror)
2081 for ( my $i = 0; $i <= $#languageassignmenterrors; $i++ ) { print "$languageassignmenterrors[$i]"; }
2082 installer
::exiter
::exit_program
("ERROR: Incorrect assignments for language packs.", "assigning_modules_to_items");
2087 #################################################################################################
2088 # Root path (for instance /opt/openofficeorg20) needs to be added to directories, files and links
2089 #################################################################################################
2091 sub add_rootpath_to_directories
2093 my ($dirsref, $rootpath) = @_;
2095 for ( my $i = 0; $i <= $#{$dirsref}; $i++ )
2097 my $onedir = ${$dirsref}[$i];
2100 if ( $onedir->{'Dir'} ) { $dir = $onedir->{'Dir'}; }
2102 if (!($dir =~ /\bPREDEFINED_/ ))
2104 my $hostname = $onedir->{'HostName'};
2105 $hostname = $rootpath . $installer::globals
::separator
. $hostname;
2106 $onedir->{'HostName'} = $hostname;
2111 if ( $dir =~ /\bPREDEFINED_PROGDIR\b/ )
2113 my $hostname = $onedir->{'HostName'};
2114 if ( $hostname eq "" ) { $onedir->{'HostName'} = $rootpath; }
2115 else { $onedir->{'HostName'} = $rootpath . $installer::globals
::separator
. $hostname; }
2120 sub add_rootpath_to_files
2122 my ($filesref, $rootpath) = @_;
2124 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
2126 my $onefile = ${$filesref}[$i];
2127 my $destination = $onefile->{'destination'};
2128 $destination = $rootpath . $installer::globals
::separator
. $destination;
2129 $onefile->{'destination'} = $destination;
2133 sub add_rootpath_to_links
2135 my ($linksref, $rootpath) = @_;
2137 for ( my $i = 0; $i <= $#{$linksref}; $i++ )
2139 my $onelink = ${$linksref}[$i];
2140 my $styles = $onelink->{'Styles'};
2142 my $destination = $onelink->{'destination'};
2143 $destination = $rootpath . $installer::globals
::separator
. $destination;
2144 $onelink->{'destination'} = $destination;
2146 if (!($styles =~ /\bRELATIVE\b/ )) # for absolute links
2148 my $destinationfile = $onelink->{'destinationfile'};
2149 $destinationfile = $rootpath . $installer::globals
::separator
. $destinationfile;
2150 $onelink->{'destinationfile'} = $destinationfile;
2155 #################################################################################
2156 # Collecting all parent gids
2157 #################################################################################
2159 sub collect_all_parent_feature
2161 my ($modulesref) = @_;
2163 my @allparents = ();
2165 my $found_root_module = 0;
2167 for ( my $i = 0; $i <= $#{$modulesref}; $i++ )
2169 my $onefeature = ${$modulesref}[$i];
2172 if ( $onefeature->{'ParentID'} )
2174 $parentgid = $onefeature->{'ParentID'};
2177 if ( $parentgid ne "" )
2179 if (! grep {$_ eq $parentgid} @allparents)
2181 push(@allparents, $parentgid);
2185 # Setting the global root module
2187 if ( $parentgid eq "" )
2189 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"); }
2190 $installer::globals
::rootmodulegid
= $onefeature->{'gid'};
2191 $found_root_module = 1;
2192 my $infoline = "Setting Root Module: $installer::globals::rootmodulegid\n";
2193 push( @installer::globals
::globallogfileinfo
, $infoline);
2196 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"); }
2200 return \
@allparents;
2203 #################################################################################
2204 # Checking for every feature, whether it has children
2205 #################################################################################
2207 sub set_children_flag
2209 my ($modulesref) = @_;
2211 my $allparents = collect_all_parent_feature
($modulesref);
2213 for ( my $i = 0; $i <= $#{$modulesref}; $i++ )
2215 my $onefeature = ${$modulesref}[$i];
2216 my $gid = $onefeature->{'gid'};
2218 # is this gid a parent?
2220 if ( grep {$_ eq $gid} @
{$allparents} )
2222 $onefeature->{'has_children'} = 1;
2226 $onefeature->{'has_children'} = 0;
2231 #################################################################################
2232 # All modules, that use a template module, do now get the assignments of
2233 # the template module.
2234 #################################################################################
2236 sub resolve_assigned_modules
2238 my ($modulesref) = @_;
2240 # collecting all template modules
2242 my %directaccess = ();
2244 for ( my $i = 0; $i <= $#{$modulesref}; $i++ )
2246 my $onefeature = ${$modulesref}[$i];
2248 if ( $onefeature->{'Styles'} ) { $styles = $onefeature->{'Styles'}; }
2249 if ( $styles =~ /\bTEMPLATEMODULE\b/ ) { $directaccess{$onefeature->{'gid'}} = $onefeature; }
2251 # also looking for module with flag ROOT_BRAND_PACKAGE, to save is for further usage
2252 if ( $styles =~ /\bROOT_BRAND_PACKAGE\b/ )
2254 $installer::globals
::rootbrandpackage
= $onefeature->{'gid'};
2255 $installer::globals
::rootbrandpackageset
= 1;
2259 # looking, where template modules are assigned
2261 for ( my $i = 0; $i <= $#{$modulesref}; $i++ )
2263 my $onefeature = ${$modulesref}[$i];
2264 if ( $onefeature->{'Assigns'} )
2266 my $templategid = $onefeature->{'Assigns'};
2268 if ( ! exists($directaccess{$templategid}) )
2270 installer
::exiter
::exit_program
("ERROR: Did not find definition of assigned template module \"$templategid\"", "resolve_assigned_modules");
2273 # Currently no merging of Files, Dirs, ...
2274 # This has to be included here, if it is required
2275 my @items_at_modules = ("Files", "Dirs", "Unixlinks");
2276 for my $item (@items_at_modules)
2278 if ( exists($directaccess{$templategid}->{$item}) ) { $onefeature->{$item} = $directaccess{$templategid}->{$item}; }
2284 #################################################################################
2285 # Removing the template modules from the list, after all
2286 # assignments are transferred to the "real" modules.
2287 #################################################################################
2289 sub remove_template_modules
2291 my ($modulesref) = @_;
2295 for ( my $i = 0; $i <= $#{$modulesref}; $i++ )
2297 my $onefeature = ${$modulesref}[$i];
2299 if ( $onefeature->{'Styles'} ) { $styles = $onefeature->{'Styles'}; }
2300 if ( $styles =~ /\bTEMPLATEMODULE\b/ ) { next; }
2302 push(@modules, $onefeature);
2308 #################################################################################
2309 # Collecting all modules with flag LANGUAGEMODULE in a global
2311 #################################################################################
2313 sub collect_all_languagemodules
2315 my ($modulesref) = @_;
2317 for ( my $i = 0; $i <= $#{$modulesref}; $i++ )
2319 my $onefeature = ${$modulesref}[$i];
2321 if ( $onefeature->{'Styles'} ) { $styles = $onefeature->{'Styles'}; }
2322 if ( $styles =~ /\bLANGUAGEMODULE\b/ )
2324 if ( ! exists($onefeature->{'Language'}) ) { installer
::exiter
::exit_program
("ERROR: \"$onefeature->{'gid'}\" has flag LANGUAGEMODULE, but does not know its language!", "collect_all_languagemodules"); }
2325 $installer::globals
::alllangmodules
{$onefeature->{'gid'}} = $onefeature->{'Language'};
2326 # Collecting also the english names, that are used for nsis unpack directory for language packs
2327 my $lang = $onefeature->{'Language'};
2329 foreach my $localkey ( keys %{$onefeature} )
2331 if ( $localkey =~ /^\s*Name\s*\(\s*en-US\s*\)\s*$/ )
2333 $installer::globals
::all_english_languagestrings
{$lang} = $onefeature->{$localkey};
2340 #################################################################################
2341 # Selecting from all collected english language strings those, that are really
2342 # required in this installation set.
2343 #################################################################################
2345 sub select_required_language_strings
2347 my ($modulesref) = @_;
2349 for ( my $i = 0; $i <= $#{$modulesref}; $i++ )
2351 my $onefeature = ${$modulesref}[$i];
2353 if ( $onefeature->{'Styles'} ) { $styles = $onefeature->{'Styles'}; }
2354 if ( $styles =~ /\bLANGUAGEMODULE\b/ )
2356 if ( ! exists($onefeature->{'Language'}) ) { installer
::exiter
::exit_program
("ERROR: \"$onefeature->{'gid'}\" has flag LANGUAGEMODULE, but does not know its language!", "select_required_language_strings"); }
2357 my $lang = $onefeature->{'Language'};
2359 if (( exists($installer::globals
::all_english_languagestrings
{$lang}) ) && ( ! exists($installer::globals
::all_required_english_languagestrings
{$lang}) ))
2361 $installer::globals
::all_required_english_languagestrings
{$lang} = $installer::globals
::all_english_languagestrings
{$lang};
2367 ################################################
2368 # Controlling that all keys in hash A are
2369 # also key in hash B.
2370 ################################################
2372 sub _key_in_a_is_also_key_in_b
2374 my ( $hashref_a, $hashref_b) = @_;
2376 my $returnvalue = 1;
2379 foreach $key ( keys %{$hashref_a} )
2381 if ( ! exists($hashref_b->{$key}) )
2384 foreach my $keyb ( keys %{$hashref_b} ) { print "$keyb : $hashref_b->{$keyb}\n"; }
2390 return $returnvalue;