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