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