Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  scriptitems.pm   Sprache: unbekannt

 
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This file incorporates work covered by the following license notice:
#
#   Licensed to the Apache Software Foundation (ASF) under one or more
#   contributor license agreements. See the NOTICE file distributed
#   with this work for additional information regarding copyright
#   ownership. The ASF licenses this file to you under the Apache
#   License, Version 2.0 (the "License"); you may not use this file
#   except in compliance with the License. You may obtain a copy of
#   the License at http://www.apache.org/licenses/LICENSE-2.0 .
#

package installer::scriptitems;

use strict;
no strict 'refs';
use warnings;

use installer::converter;
use installer::exiter;
use installer::globals;
use installer::languages;
use installer::logger;
use installer::pathanalyzer;
use installer::remover;
use installer::systemactions;

################################################################
# Resolving the GID for the directories defined in setup script
################################################################

sub resolve_all_directory_names
{
    my ($directoryarrayref) = @_;

    # After this procedure the hash shall contain the complete language
    # dependent path, not only the language dependent HostName.

    my ($key, $value, $parentvalue, $parentgid, $parentdirectoryhashref);

    for ( my $i = 0; $i <= $#{$directoryarrayref}; $i++ )
    {
        my $directoryhashref = ${$directoryarrayref}[$i];
        my $gid = $directoryhashref-> {'gid'};
        my $parentid = $directoryhashref-> {'ParentID'};

        if ( $parentid ne "PREDEFINED_PROGDIR" )
        {
            # find the array of the parentid, which has to be defined before in setup script
            # and is therefore listed before in this array

            for ( my $j = 0; $j <= $i; $j++ )
            {
                $parentdirectoryhashref = ${$directoryarrayref}[$j];
                $parentgid = $parentdirectoryhashref->{'gid'};

                if ( $parentid eq $parentgid)
                {
                    last;
                }
            }

            # and now we can put the path together
            # But take care of the languages!

            my $dirismultilingual = $directoryhashref->{'ismultilingual'};
            my $parentismultilingual = $parentdirectoryhashref->{'ismultilingual'};

            # First: Both directories are language independent or both directories are language dependent

            if ((( ! $dirismultilingual ) && ( ! $parentismultilingual )) ||
                (( $dirismultilingual ) && ( $parentismultilingual )))
            {
                foreach $key (keys %{$directoryhashref})
                {
                    # the key ("HostName (en-US)") must be usable for both hashes

                    if ( $key =~ /\bHostName\b/ )
                    {
                        $parentvalue = "";
                        $value = $directoryhashref->{$key};
                        if ( $parentdirectoryhashref->{$key} ) { $parentvalue = $parentdirectoryhashref->{$key}; }

                        # It is possible, that in scp project, a directory is defined in more languages than
                        # the directory parent (happened after automatic generation of macros.inc).
                        # Therefore this is checked now and written with a warning into the logfile.
                        # This is no error, because (in most cases) the concerned language is not build.

                        if ($parentvalue eq "")
                        {
                            $directoryhashref->{$key} = "FAILURE";
                            my $infoline = "WARNING: No hostname for $parentid with \"$key\". Needed by child directory $gid !\n";
                            push( @installer::globals::globallogfileinfo, $infoline);
                        }
                        else
                        {
                            $directoryhashref->{$key} = $parentvalue . $installer::globals::separator . $value;
                        }
                    }
                }
            }

            # Second: The directory is language dependent, the parent not

            if (( $dirismultilingual ) && ( ! $parentismultilingual ))
            {
                $parentvalue = $parentdirectoryhashref->{'HostName'};       # there is only one

                foreach $key (keys %{$directoryhashref})        # the current directory
                {
                    if ( $key =~ /\bHostName\b/ )
                    {
                        $value = $directoryhashref->{$key};
                        $directoryhashref->{$key} = $parentvalue . $installer::globals::separator . $value;
                    }
                }
            }

            # Third: The directory is not language dependent, the parent is language dependent

            if (( ! $dirismultilingual ) && ( $parentismultilingual ))
            {
                $value = $directoryhashref->{'HostName'};       # there is only one
                delete($directoryhashref->{'HostName'});

                foreach $key (keys %{$parentdirectoryhashref})      # the parent directory
                {
                    if ( $key =~ /\bHostName\b/ )
                    {
                        $parentvalue = $parentdirectoryhashref->{$key};     # there is only one
                        $directoryhashref->{$key} = $parentvalue . $installer::globals::separator . $value;
                    }
                }

                $directoryhashref->{'ismultilingual'} = 1;  # now this directory is also language dependent
            }
        }
    }
}

#############################################################################
# Registryitems for Uninstall have to be removed
#############################################################################

sub remove_uninstall_regitems_from_script
{
    my ($registryarrayref) = @_;

    my @newitems = ();

    for ( my $i = 0; $i <= $#{$registryarrayref}; $i++ )
    {
        my $oneitem = ${$registryarrayref}[$i];
        my $subkey = "";

        if ( $oneitem->{'Subkey'} ) { $subkey = $oneitem->{'Subkey'}; }

        if ( $subkey =~ /Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall/ ) { next; }

        push(@newitems, $oneitem);
    }

    return \@newitems;
}

##############################################################################
# Searching the language module for a specified language
##############################################################################

sub get_languagespecific_module
{
    my ( $lang, $modulestring ) = @_;

    my $langmodulestring = "";

    my $module;
    foreach $module ( keys %installer::globals::alllangmodules )
    {
        if (( $installer::globals::alllangmodules{$module} eq $lang ) && ( $modulestring =~ /\b$module\b/ ))
        {
            $langmodulestring = "$langmodulestring,$module";
        }
    }

    $langmodulestring =~ s/^\s*,//;

    if ( $langmodulestring eq "" ) { installer::exiter::exit_program("ERROR: No language pack module found for language $lang in string \"$modulestring\"!", "get_languagespecific_module");  }

    return $langmodulestring;
}

##############################################################################
# Removing all items in product lists which do not have the correct languages
##############################################################################

sub resolving_all_languages_in_productlists
{
    my ($productarrayref, $languagesarrayref) = @_;

    my @itemsinalllanguages = ();

    my ($key, $value);

    for ( my $i = 0; $i <= $#{$productarrayref}; $i++ )
    {
        my $oneitem = ${$productarrayref}[$i];

        my $ismultilingual = $oneitem->{'ismultilingual'};

        if (!($ismultilingual)) # nothing to do with single language items
        {
            $oneitem->{'specificlanguage'} = "";
            push(@itemsinalllanguages, $oneitem);
        }
        else    #all language dependent files
        {
            for ( my $j = 0; $j <= $#{$languagesarrayref}; $j++ )   # iterating over all languages
            {
                my $onelanguage = ${$languagesarrayref}[$j];

                my %oneitemhash = ();

                foreach $key (keys %{$oneitem})
                {
                    if ( $key =~ /\(\S+\)/ )    # this are the language dependent keys
                    {
                        if ( $key =~ /\(\Q$onelanguage\E\)/ )
                        {
                            $value = $oneitem->{$key};
                            $oneitemhash{$key} = $value;
                        }
                    }
                    else
                    {
                        $value = $oneitem->{$key};
                        $oneitemhash{$key} = $value;
                    }
                }

                $oneitemhash{'specificlanguage'} = $onelanguage;

                if ( $oneitemhash{'haslanguagemodule'} )
                {
                    my $langmodulestring = get_languagespecific_module($onelanguage, $oneitemhash{'modules'});
                    $oneitemhash{'modules'} = $langmodulestring;
                }

                push(@itemsinalllanguages, \%oneitemhash);
            }
        }
    }

    return \@itemsinalllanguages;
}

################################################################################
# Removing all modules, that have the flag LANGUAGEMODULE, but do not
# have the correct language
################################################################################

sub remove_not_required_language_modules
{
    my ($modulesarrayref, $languagesarrayref) = @_;

    my @allmodules = ();

    for ( my $i = 0; $i <= $#{$modulesarrayref}; $i++ )
    {
        my $module = ${$modulesarrayref}[$i];
        my $styles = "";
        if ( $module->{'Styles'} ) { $styles = $module->{'Styles'}; }

        if ( $styles =~ /\bLANGUAGEMODULE\b/ )
        {
            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"); }
            my $modulelanguage = $module->{'Language'};
            # checking, if language is required
            my $doinclude = 0;
            for ( my $j = 0; $j <= $#{$languagesarrayref}; $j++ )
            {
                my $onelanguage = ${$languagesarrayref}[$j];
                if ( $onelanguage eq $modulelanguage )
                {
                    $doinclude = 1;
                    last;
                }
            }

            if ( $doinclude ) { push(@allmodules, $module); }
        }
        else
        {
            push(@allmodules, $module);
        }
    }

    return \@allmodules;
}

################################################################################
# Removing all modules, that have a spellchecker language that is not
# required for this product (spellchecker selection).
# All required spellchecker languages are stored in
# %installer::globals::spellcheckerlanguagehash
################################################################################

sub remove_not_required_spellcheckerlanguage_modules
{
    my ($modulesarrayref) = @_;

    my $infoline = "";
    my @allmodules = ();

    for ( my $i = 0; $i <= $#{$modulesarrayref}; $i++ )
    {
        my $module = ${$modulesarrayref}[$i];
        if ( $module->{'Spellcheckerlanguage'} )    # selecting modules with Spellcheckerlanguage
        {
            if ( exists($installer::globals::spellcheckerlanguagehash{$module->{'Spellcheckerlanguage'}}) )
            {
                push(@allmodules, $module);
            }
            else
            {
                $infoline = "Spellchecker selection: Removing module $module->{'gid'}\n";
                push( @installer::globals::logfileinfo, $infoline);

                # Collecting all files at modules that are removed

                if ( $module->{'Files'} )
                {
                    if ( $module->{'Files'} =~ /^\s*\((.*?)\)\s*$/ )
                    {
                        my $filelist = $1;

                        my $filelisthash = installer::converter::convert_stringlist_into_hash(\$filelist, ",");
                        foreach my $onefile ( keys %{$filelisthash} ) { $installer::globals::spellcheckerfilehash{$onefile} = 1; }
                    }
                }
            }
        }
        else
        {
            push(@allmodules, $module);
        }
    }

    return \@allmodules;
}

################################################################################
# Removing all modules, that belong to a module that was removed
# in "remove_not_required_spellcheckerlanguage_modules" because of the
# spellchecker language. The files belonging to the modules are collected
# in %installer::globals::spellcheckerfilehash.
################################################################################

sub remove_not_required_spellcheckerlanguage_files
{
    my ($filesarrayref) = @_;

    my @filesarray = ();
    my $infoline = "";

    for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ )
    {
        my $onefile = ${$filesarrayref}[$i];
        # FIXME: some items don't have 'gid'
        if ( (defined $onefile->{'gid'}) && exists($installer::globals::spellcheckerfilehash{$onefile->{'gid'}}) )
        {
            $infoline = "Spellchecker selection: Removing file $onefile->{'gid'}\n";
            push( @installer::globals::logfileinfo, $infoline);
            next;
        }
        push(@filesarray, $onefile);
    }

    return \@filesarray;
}

################################################################################
# Looking for directories without correct HostName
################################################################################

sub checking_directories_with_corrupt_hostname
{
    my ($dirsref, $languagesarrayref) = @_;

    for ( my $i = 0; $i <= $#{$dirsref}; $i++ )
    {
        my $onedir = ${$dirsref}[$i];

        my $hostname = "";

        if ( $onedir->{'HostName'} ) { $hostname = $onedir->{'HostName'}; }

        if ( $hostname eq "" )
        {
            my $langstring = "";
            for ( my $j = 0; $j <= $#{$languagesarrayref}; $j++ ) { $langstring .= ${$languagesarrayref}[$j] . " "; }
            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");
        }

        if ( $hostname eq "FAILURE" )
        {
            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");
        }
    }
}

################################################################################
# Setting global properties
################################################################################

sub set_global_directory_hostnames
{
    my ($dirsref, $allvariables) = @_;

    for ( my $i = 0; $i <= $#{$dirsref}; $i++ )
    {
        my $onedir = ${$dirsref}[$i];
        my $styles = "";
        if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; }

        if ( $styles =~ /\bOFFICEDIRECTORY\b/ )
        {
            $installer::globals::officedirhostname = $onedir->{'HostName'};
            $installer::globals::officedirgid = $onedir->{'gid'};
            $allvariables->{'OFFICEDIRECTORYHOSTNAME'} = $installer::globals::officedirhostname;
        }
    }
}

########################################################
# Recursively defined procedure to order
# modules and directories
########################################################

sub get_children
{
    my ($allitems, $startparent, $newitemorder) = @_;

    for ( my $i = 0; $i <= $#{$allitems}; $i++ )
    {
        my $gid = ${$allitems}[$i]->{'gid'};
        my $parent = "";
        if ( ${$allitems}[$i]->{'ParentID'} ) { $parent = ${$allitems}[$i]->{'ParentID'}; }

        if ( $parent eq $startparent )
        {
            push(@{$newitemorder}, ${$allitems}[$i]);
            my $parent = $gid;
            get_children($allitems, $parent, $newitemorder);    # recursive!
        }
    }
}

################################################################################
# Using langpack copy action for language packs
################################################################################

sub use_langpack_copy_scpaction
{
    my ($scpactionsref) = @_;

    for ( my $i = 0; $i <= $#{$scpactionsref}; $i++ )
    {
        my $onescpaction = ${$scpactionsref}[$i];
        if (( $onescpaction->{'LangPackCopy'} ) && ( $onescpaction->{'LangPackCopy'} ne "" )) { $onescpaction->{'Copy'} = $onescpaction->{'LangPackCopy'}; }
    }
}

################################################################################
# Using dev copy patch action for developer snapshot builds
################################################################################

sub use_devversion_copy_scpaction
{
    my ($scpactionsref) = @_;

    for ( my $i = 0; $i <= $#{$scpactionsref}; $i++ )
    {
        my $onescpaction = ${$scpactionsref}[$i];
        if (( $onescpaction->{'DevVersionCopy'} ) && ( $onescpaction->{'DevVersionCopy'} ne "" )) { $onescpaction->{'Copy'} = $onescpaction->{'DevVersionCopy'}; }
    }
}

################################################################################
# Shifting parent directories of URE and Basis layer, so that
# these directories are located below the Brand layer.
# Style: SHIFT_BASIS_INTO_BRAND_LAYER
################################################################################

sub shift_basis_directory_parents
{
    my ($dirsref) = @_;

    my @alldirs = ();

    my $officedirgid = "";

    for ( my $i = 0; $i <= $#{$dirsref}; $i++ )
    {
        my $onedir = ${$dirsref}[$i];
        my $styles = "";
        if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; }

        if ( $styles =~ /\bOFFICEDIRECTORY\b/ ) { $officedirgid = $onedir->{'gid'}; }
    }

    if ( $officedirgid ne "" )
    {
        for ( my $i = 0; $i <= $#{$dirsref}; $i++ )
        {
            my $onedir = ${$dirsref}[$i];
            my $styles = "";
            if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; }

            if (( $styles =~ /\bBASISDIRECTORY\b/ ) || ( $styles =~ /\bUREDIRECTORY\b/ ))
            {
                $onedir->{'ParentID'} = $officedirgid;
            }
        }

        # Sorting directories
        my $startgid = "PREDEFINED_PROGDIR";
        get_children($dirsref, $startgid, \@alldirs);
    }

    return \@alldirs;
}

################################################################################
# Setting the name of the directory with style OFFICEDIRECTORY.
# The name can be defined in property OFFICEDIRECTORYNAME.
################################################################################

sub set_officedirectory_name
{
    my ($dirsref, $officedirname) = @_;

    for ( my $i = 0; $i <= $#{$dirsref}; $i++ )
    {
        my $onedir = ${$dirsref}[$i];
        my $styles = "";
        if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; }
        if ( $styles =~ /\bOFFICEDIRECTORY\b/ )
        {
            $onedir->{'HostName'} = $officedirname;
            last;
        }
    }
}

################################################################################
# Simplifying the name for language dependent items from "Name (xy)" to "Name"
################################################################################

sub changing_name_of_language_dependent_keys
{
    my ($itemsarrayref) = @_;

    # Changing key for multilingual items from "Name ( )" to "Name" or "HostName ( )" to "HostName"

    for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
    {
        my $oneitem = ${$itemsarrayref}[$i];
        my $onelanguage = $oneitem->{'specificlanguage'};

        if (!($onelanguage eq "" ))                 # language dependent item
        {
            my $itemkey;

            foreach $itemkey (keys %{$oneitem})
            {
                if ( $itemkey =~ /^\s*(\S+?)\s+\(\S+\)\s*$/ )
                {
                    my $newitemkey = $1;
                    my $itemvalue = $oneitem->{$itemkey};
                    $oneitem->{$newitemkey} = $itemvalue;
                    delete($oneitem->{$itemkey});
                }
            }
        }
    }
}

################################################################################
# Replacement of setup variables in ConfigurationItems and ProfileItems
# <productkey>, <buildid>, <sequence_languages>, <productupdate>
################################################################################

sub replace_setup_variables
{
    my ($itemsarrayref, $languagestringref, $hashref) = @_;

    my $languagesstring = $$languagestringref;
    $languagesstring =~ s/\_/ /g;   # replacing underscore with whitespace

    my $productname = $hashref->{'PRODUCTNAME'};
    my $productversion = $hashref->{'PRODUCTVERSION'};
    my $libo_version_major = "";
    if ( $hashref->{'LIBO_VERSION_MAJOR'} ) { $libo_version_major = $hashref->{'LIBO_VERSION_MAJOR'}; }
    my $productkey = $productname . " " . $productversion;

    # string $buildid, which is used to replace the setup variable <buildid>

    my $localbuild = $installer::globals::build;

    if ( $localbuild =~ /^\s*(\w+?)(\d+)\s*$/ ) { $localbuild = $2; }   # using "680" instead of "src680"

    my $buildidstring = `cd $ENV{'SRCDIR'} 2>&1 >/dev/null && git log -n 1 --pretty=format:"%H"`;
    if ($? || !$buildidstring) {
        $buildidstring = $localbuild . "(Build:" . $installer::globals::buildid . ")";
    }

    my $updateid = $productname . "_" . $libo_version_major . "_" . $$languagestringref;
    $updateid =~ s/ /_/g;

    my $updatechannel = 'LOOnlineUpdater';

    for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
    {
        my $oneitem = ${$itemsarrayref}[$i];
        my $value = $oneitem->{'Value'};

        $value =~ s/\<buildid\>/$buildidstring/;
        $value =~ s/\<sequence_languages\>/$languagesstring/;
        $value =~ s/\<productkey\>/$productkey/;
        $value =~ s/\<alllanguages\>/$languagesstring/;
        $value =~ s/\<sourceid\>/$installer::globals::build/;
        $value =~ s/\<updateid\>/$updateid/;
        $value =~ s/\<updatechannel\>/$updatechannel/;
        $value =~ s/\<pkgformat\>/$installer::globals::packageformat/;
        $ENV{'OOO_VENDOR'} = "" if !defined $ENV{'OOO_VENDOR'};
        $value =~ s/\<vendor\>/$ENV{'OOO_VENDOR'}/;

        $oneitem->{'Value'} = $value;
    }
}

################################################################################
# By defining variable LOCALUSERDIR in *.lst it is possible to change
# the standard destination of user directory defined in scp2 ($SYSUSERCONFIG).
################################################################################

sub replace_userdir_variable
{
    my ($itemsarrayref, $allvariableshashref) = @_;

    my $userdir = "";
    if ( $allvariableshashref->{'LOCALUSERDIR'} ) { $userdir = $allvariableshashref->{'LOCALUSERDIR'}; }
    else { $userdir = $installer::globals::simpledefaultuserdir; }

    if ( $userdir ne "" )
    {
        for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
        {
            my $oneitem = ${$itemsarrayref}[$i];
            $oneitem->{'Value'} =~ s/\$SYSUSERCONFIG/$userdir/;
        }
    }
}

#####################################################################################
# Files and ConfigurationItems are not included for all languages.
# For instance asian fonts. These can be removed, if no "Name" is found.
# ConfigurationItems are not always defined in the linguistic configuration file.
# The "Key" cannot be found for them.
#####################################################################################

sub remove_non_existent_languages_in_productlists
{
    my ($itemsarrayref, $languagestringref, $searchkey, $itemtype) = @_;

    # Removing of all non existent files, for instance asian fonts

    installer::logger::include_header_into_logfile("Removing for this language $$languagestringref:");

    my @allexistentitems = ();

    my $infoline;

    for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
    {
        my $oneitem = ${$itemsarrayref}[$i];
        my $oneitemname = "";       # $searchkey is "Name" for files and "Key" for ConfigurationItems

        if ( $oneitem->{$searchkey} ) { $oneitemname = $oneitem->{$searchkey} }

        my $itemtoberemoved = 0;

        if ($oneitemname eq "")                     # for instance asian font in english installation set
        {
            $itemtoberemoved = 1;
        }

        if ($itemtoberemoved)
        {
            $infoline = "WARNING: Language $$languagestringref: No $itemtype packed for $oneitem->{'gid'}!\n";
            push( @installer::globals::logfileinfo, $infoline);
        }
        else
        {
            push(@allexistentitems, $oneitem);
        }
    }

    $infoline = "\n";
    push( @installer::globals::logfileinfo, $infoline);

    return \@allexistentitems;
}

########################################################################
# Input is the directory gid, output the "HostName" of the directory
########################################################################

sub get_Directoryname_From_Directorygid
{
    my ($dirsarrayref ,$searchgid, $onelanguage, $oneitemgid) = @_;

    my $directoryname = "";
    my $onedirectory;
    my $foundgid = 0;

    for ( my $i = 0; $i <= $#{$dirsarrayref}; $i++ )
    {
        $onedirectory = ${$dirsarrayref}[$i];
        my $directorygid = $onedirectory->{'gid'};

        if ($directorygid eq $searchgid)
        {
            $foundgid = 1;
            last;
        }
    }

    if (!($foundgid))
    {
        installer::exiter::exit_program("ERROR: Gid $searchgid not defined in $installer::globals::setupscriptname", "get_Directoryname_From_Directorygid");
    }

    if ( ! ( $onedirectory->{'ismultilingual'} ))   # the directory is not language dependent
    {
         $directoryname = $onedirectory->{'HostName'};
    }
    else
    {
        $directoryname = $onedirectory->{"HostName ($onelanguage)"};
    }

    # gid_Dir_Template_Wizard_Letter is defined as language dependent directory, but the file gid_Dir_Template_Wizard_Letter
    # is not language dependent. Therefore $onelanguage is not defined. But which language is the correct language for the
    # directory?
    # Perhaps better solution: In scp it must be forbidden to have a language independent file in a language dependent directory.

    if (( ! $directoryname ) && ( $onelanguage eq "" ))
    {
        installer::exiter::exit_program("ERROR (in scp): Directory $searchgid is language dependent, but not $oneitemgid inside this directory", "get_Directoryname_From_Directorygid");
    }

    return \$directoryname;
}

##################################################################
# Getting destination directory for links, files and profiles
##################################################################

sub get_Destination_Directory_For_Item_From_Directorylist       # this is used for Files, Profiles and Links
{
    my ($itemarrayref, $dirsarrayref) = @_;

    for ( my $i = 0; $i <= $#{$itemarrayref}; $i++ )
    {
        my $oneitem = ${$itemarrayref}[$i];
        my $oneitemgid = $oneitem->{'gid'};
        my $directorygid = $oneitem->{'Dir'};       # for instance gid_Dir_Program
        my $netdirectorygid = "";
        my $onelanguage = $oneitem->{'specificlanguage'};
        my $ispredefinedprogdir = 0;
        my $ispredefinedconfigdir = 0;

        my $oneitemname = $oneitem->{'Name'};

        if ( $oneitem->{'NetDir'} ) { $netdirectorygid = $oneitem->{'NetDir'}; }

        installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$oneitemname);    # making /registry/schema/org/openoffice/VCL.xcs to VCL.xcs

        my $searchdirgid;

        if ( $netdirectorygid eq "" )   # if NetDir is defined, it is privileged
        {
            $searchdirgid = $directorygid
        }
        else
        {
            $searchdirgid = $netdirectorygid
        }

        if ($searchdirgid =~ /PREDEFINED_PROGDIR/)  # the root directory is not defined in setup script
        {
            $ispredefinedprogdir = 1;
        }

        if ($searchdirgid =~ /PREDEFINED_CONFIGDIR/)    # the root directory is not defined in setup script
        {
            $ispredefinedconfigdir = 1;
        }

        my $destfilename;

        if ($oneitem->{'DoNotMessWithSymlinks'})
        {
            $destfilename = $oneitem->{'Name'};
        }
        elsif ((!( $ispredefinedprogdir )) && (!( $ispredefinedconfigdir )))
        {
            my $directorynameref = get_Directoryname_From_Directorygid($dirsarrayref, $searchdirgid, $onelanguage, $oneitemgid);
            my $styles = "";
            if ($oneitem->{'Styles'}) { $styles = $oneitem->{'Styles'}; }
            if ($styles =~ /\bFILELIST\b/)
            {
                $destfilename = $$directorynameref . $installer::globals::separator . $oneitemname;
            }
            else
            {
                $destfilename = $$directorynameref . $installer::globals::separator . $oneitem->{'Name'};
            }
        }
        else
        {
            $destfilename = $oneitemname;
        }

        $oneitem->{'destination'} = $destfilename;
    }
}

##########################################################################
# Searching a file in a list of paths
##########################################################################

sub get_sourcepath_from_filename_and_includepath_classic
{
    my ($searchfilenameref, $includepatharrayref, $write_logfile) = @_;

    my ($onefile, $includepath, $infoline);

    my $foundsourcefile = 0;

    for ( my $j = 0; $j <= $#{$includepatharrayref}; $j++ )
    {
        $includepath = ${$includepatharrayref}[$j];
        installer::remover::remove_leading_and_ending_whitespaces(\$includepath);

        $onefile = $includepath . $installer::globals::separator . $$searchfilenameref;

        if ( -f $onefile )
        {
            $foundsourcefile = 1;
            last;
        }
    }

    if (!($foundsourcefile))
    {
        $onefile = "";  # the sourcepath has to be empty
        if ( $write_logfile)
        {
            $infoline = "ERROR: Source for $$searchfilenameref not found (classic)!\n";    # Important message in log file
            push( @installer::globals::logfileinfo, $infoline);
        }
    }
    else
    {
        if ( $write_logfile)
        {
            $infoline = "SUCCESS: Source for $$searchfilenameref: $onefile\n";
            push( @installer::globals::logfileinfo, $infoline);
        }
    }

    return \$onefile;
}

##########################################################################
# Input is one file name, output the complete absolute path of this file
##########################################################################

sub get_sourcepath_from_filename_and_includepath
{
    my ($searchfilenameref, $unused, $write_logfile) = @_;

    my ($onefile, $includepath, $infoline);

    my $foundsourcefile = 0;
    my $foundnewname = 0;

    for ( my $j = 0; $j <= $#installer::globals::allincludepaths; $j++ )
    {
        my $allfiles = $installer::globals::allincludepaths[$j];

        if ( exists( $allfiles->{$$searchfilenameref} ))
        {
            $onefile = $allfiles->{'includepath'} . $installer::globals::separator . $$searchfilenameref;
            $foundsourcefile = 1;
            last;
        }
    }

    if (!($foundsourcefile))    # testing with lowercase filename
    {
        # Attention: README01.html is copied for Windows to readme01.html, not case sensitive

        for ( my $j = 0; $j <= $#installer::globals::allincludepaths; $j++ )
        {
            my $allfiles = $installer::globals::allincludepaths[$j];

            my $newfilename = $$searchfilenameref;
            $newfilename =~ s/readme/README/;       # special handling for readme files
            $newfilename =~ s/license/LICENSE/;     # special handling for license files

            if ( exists( $allfiles->{$newfilename} ))
            {
                $onefile = $allfiles->{'includepath'} . $installer::globals::separator . $newfilename;
                $foundsourcefile = 1;
                $foundnewname = 1;
                last;
            }
        }
    }

    if (!($foundsourcefile))
    {
        $onefile = "";  # the sourcepath has to be empty
        if ( $write_logfile)
        {
            $infoline = "ERROR: Source for $$searchfilenameref not found!\n";    # Important message in log file
            push( @installer::globals::logfileinfo, $infoline);
        }
    }
    else
    {
        if ( $write_logfile)
        {
            if (!($foundnewname))
            {
                $infoline = "SUCCESS: Source for $$searchfilenameref: $onefile\n";
            }
            else
            {
                $infoline = "SUCCESS/WARNING: Special handling for $$searchfilenameref: $onefile\n";
            }
            push( @installer::globals::logfileinfo, $infoline);
        }
    }

    return \$onefile;
}

##############################################################
# Getting all source paths for all files to be packed
# $item can be "Files" or "ScpActions"
##############################################################

sub get_Source_Directory_For_Files_From_Includepathlist
{
    my ($filesarrayref, $includepatharrayref, $dirsref, $item, $allvariables) = @_;

    installer::logger::include_header_into_logfile("$item:");

    my ($foundit, $dontcare, $extrarootdir) =
        get_office_directory_gid_and_hostname($dirsref);
    my $infoline = "";

    for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ )
    {
        my $onefile = ${$filesarrayref}[$i];
        my $onelanguage = $onefile->{'specificlanguage'};

        if ( ! $onefile->{'Name'} ) { installer::exiter::exit_program("ERROR: $item without name ! GID: $onefile->{'gid'} ! Language: $onelanguage", "get_Source_Directory_For_Files_From_Includepathlist"); }

        my $onefilename = $onefile->{'Name'};
        if ( $item eq "ScpActions" ) { $onefilename =~ s/\//$installer::globals::separator/g; }
        $onefilename =~ s/^\s*\Q$installer::globals::separator\E//;     # filename begins with a slash, for instance /registry/schema/org/openoffice/VCL.xcs

        my $styles = "";
        my $file_can_miss = 0;
        if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; }

        if (( $installer::globals::languagepack ) && ( ! $onefile->{'ismultilingual'} ) && ( ! ( $styles =~ /\bFORCELANGUAGEPACK\b/ ))) { $file_can_miss = 1; }
        if (( $installer::globals::helppack ) && ( ! $onefile->{'ismultilingual'} ) && ( ! ( $styles =~ /\bFORCEHELPPACK\b/ ))) { $file_can_miss = 1; }

        my $sourcepathref = "";

        my $destination = $onefile->{'destination'};
        my $instdirdestination;
        if ($destination)
        {
            if (($installer::globals::iswindowsbuild) && $foundit && $extrarootdir)
            {
                $destination =~ s,$extrarootdir/,,; # remove it from path
            }
            if (($installer::globals::languagepack) && ($installer::globals::ismacbuild))
            {   # source files are in $(PRODUCTNAME).app where they will
                # actually copied by the user executing the Language Pack.app
                $destination =~ s, Language Pack.app/,.app/,;
            }
            $instdirdestination = $ENV{'INSTDIR'} . $installer::globals::separator . $destination;
        }
        if ($instdirdestination && -f $instdirdestination)
        {
            $infoline = "SUCCESS: INSTDIR Source for $onefilename: $instdirdestination\n";
            push( @installer::globals::logfileinfo, $infoline);
            $$sourcepathref = $instdirdestination;
        }
        else
        {
        if ( $file_can_miss ) { $sourcepathref = get_sourcepath_from_filename_and_includepath(\$onefilename, $includepatharrayref, 0); }
        else { $sourcepathref = get_sourcepath_from_filename_and_includepath(\$onefilename, $includepatharrayref, 1); }
        }

        $onefile->{'sourcepath'} = $$sourcepathref; # This $$sourcepathref is empty, if no source was found
    }

    $infoline = "\n";   # empty line after listing of all files
    push( @installer::globals::logfileinfo, $infoline);
}

#################################################################################
# Removing files, that shall not be included into languagepacks
# (because of rpm conflicts)
#################################################################################

sub remove_Files_For_Languagepacks
{
    my ($itemsarrayref) = @_;

    my $infoline;

    my @newitemsarray = ();

    for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
    {
        my $oneitem = ${$itemsarrayref}[$i];
        my $gid = $oneitem->{'gid'};

        # scp Todo: Remove asap after removal of old setup

        if (( $gid eq "gid_File_Extra_Fontunxpsprint" ) ||
            ( $gid eq "gid_File_Extra_Migration_Lang" ))
        {
            $infoline = "ATTENTION: Removing item $oneitem->{'gid'} from the installation set.\n";
            push( @installer::globals::logfileinfo, $infoline);

            next;
        }

        push(@newitemsarray, $oneitem);
    }

    return \@newitemsarray;
}

#################################################################################
# Files, whose source directory is not found, are removed now (this is an ERROR)
#################################################################################

sub remove_Files_Without_Sourcedirectory
{
    my ($filesarrayref) = @_;

    my $infoline;

    my $error_occurred = 0;
    my $missingfiles = "The following files could not be found:\n";

    my @newfilesarray = ();

    for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ )
    {
        my $onefile = ${$filesarrayref}[$i];
        my $sourcepath = $onefile->{'sourcepath'};

        if ($sourcepath eq "")
        {
            my $styles = $onefile->{'Styles'};
            my $filename = $onefile->{'Name'};

            if ( ! $installer::globals::languagepack && !$installer::globals::helppack)
            {
                $infoline = "ERROR: Removing file $filename from file list.\n";
                push( @installer::globals::logfileinfo, $infoline);

                $missingfiles = "$missingfiles  $filename\n";
                $error_occurred = 1;

                next;   # removing this file from list, if sourcepath is empty
            }
            elsif ( $installer::globals::languagepack ) # special case for language packs
            {
                if (( $onefile->{'ismultilingual'} ) || ( $styles =~ /\bFORCELANGUAGEPACK\b/ ))
                {
                    $infoline = "ERROR: Removing file $filename from file list.\n";
                    push( @installer::globals::logfileinfo, $infoline);

                    $missingfiles = "$missingfiles  $filename\n";
                    $error_occurred = 1;

                    next;   # removing this file from list, if sourcepath is empty
                }
                else
                {
                    $infoline = "INFO: Removing file $filename from file list. It is not language dependent.\n";
                    push( @installer::globals::logfileinfo, $infoline);
                    $infoline = "INFO: It is not language dependent and can be ignored in language packs.\n";
                    push( @installer::globals::logfileinfo, $infoline);

                    next;   # removing this file from list, if sourcepath is empty
                }
            }
            else # special case for help packs
            {
                if (( $onefile->{'ismultilingual'} ) || ( $styles =~ /\bFORCEHELPPACK\b/ ))
                {
                    $infoline = "ERROR: Removing file $filename from file list.\n";
                    push( @installer::globals::logfileinfo, $infoline);

                    $missingfiles = "$missingfiles  $filename\n";
                    $error_occurred = 1;

                    next;   # removing this file from list, if sourcepath is empty
                }
                else
                {
                    $infoline = "INFO: Removing file $filename from file list. It is not language dependent.\n";
                    push( @installer::globals::logfileinfo, $infoline);
                    $infoline = "INFO: It is not language dependent and can be ignored in help packs.\n";
                    push( @installer::globals::logfileinfo, $infoline);

                    next;   # removing this file from list, if sourcepath is empty
                }
           }
        }

        push(@newfilesarray, $onefile);
    }

    $infoline = "\n";
    push( @installer::globals::logfileinfo, $infoline);

    if ( $error_occurred )
    {
        installer::exiter::exit_program($missingfiles, "remove_Files_Without_Sourcedirectory");
    }

    return \@newfilesarray;
}

############################################################################
# License and Readme files in the default language have to be installed
# in the directory with flag OFFICEDIRECTORY. If this is not defined
# they have to be installed in the installation root.
############################################################################

sub get_office_directory_gid_and_hostname
{
    my ($dirsarrayref) = @_;

    my $foundofficedir = 0;
    my $gid = "";
    my $hostname = "";

    for ( my $i = 0; $i <= $#{$dirsarrayref}; $i++ )
    {
        my $onedir = ${$dirsarrayref}[$i];
        if ( $onedir->{'Styles'} )
        {
            my $styles = $onedir->{'Styles'};

            if ( $styles =~ /\bOFFICEDIRECTORY\b/ )
            {
                $foundofficedir = 1;
                $gid = $onedir->{'gid'};
                $hostname = $onedir->{'HostName'};
                last;
            }
        }
    }

    return ($foundofficedir, $gid, $hostname);
}

############################################################################
# License and Readme files in the default language have to be installed
# in the installation root (next to the program dir). This is in scp
# project done by a post install basic script
############################################################################

sub add_License_Files_into_Installdir
{
    my ($filesarrayref, $dirsarrayref, $languagesarrayref) = @_;

    my $infoline;

    my @newfilesarray = ();

    my $defaultlanguage = installer::languages::get_default_language($languagesarrayref);

    my ($foundofficedir, $officedirectorygid, $officedirectoryhostname) = get_office_directory_gid_and_hostname($dirsarrayref);

    # copy all files from directory share/readme, that contain the default language in their name
    # without default language into the installation root. This makes the settings of the correct
    # file names superfluous. On the other hand this requires a dependency to the directory
    # share/readme

    for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ )
    {
        my $onefile = ${$filesarrayref}[$i];
        my $destination = $onefile->{'destination'};
        my $styles = "";
        if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; }

        if ( ( $destination =~ /share\Q$installer::globals::separator\Ereadme\Q$installer::globals::separator\E(\w+?)_?$defaultlanguage\.?(\w*)\s*/ )
            || (( $styles =~ /\bROOTLICENSEFILE\b/ ) && ( $destination =~ /\Q$installer::globals::separator\E?(\w+?)_?$defaultlanguage\.?(\w*?)\s*$/ )) )
        {
            my $filename = $1;
            my $extension = $2;

            my $newfilename;

            if ( $extension eq "" ) { $newfilename = $filename; }
            else { $newfilename = $filename . "\." . $extension; }

            my %newfile = ();
            my $newfile = \%newfile;

            installer::converter::copy_item_object($onefile, $newfile);

            $newfile->{'gid'} = $onefile->{'gid'} . "_Copy";
            $newfile->{'Name'} = $newfilename;
            $newfile->{'ismultilingual'} = "0";
            $newfile->{'specificlanguage'} = "";
            $newfile->{'haslanguagemodule'} = "0";

            if ( defined $newfile->{'InstallName'} )
            {
                if ( $newfile->{'InstallName'} =~ /^\s*(.*?)_$defaultlanguage\.?(\w*?)\s*$/ )
                {
                    my $localfilename = $1;
                    my $localextension = $2;

                    if ( $localextension eq "" ) { $newfile->{'InstallName'} = $localfilename; }
                    else { $newfile->{'InstallName'} = $localfilename . "\." . $localextension; }
                }
            }

            $newfile->{'removelangfromfile'} = "1"; # Important for files with an InstallName, because language also has to be removed there.

            if ( $foundofficedir )
            {
                $newfile->{'Dir'} = $officedirectorygid;
                $newfile->{'destination'} = $officedirectoryhostname . $installer::globals::separator . $newfilename;
            }
            else
            {
                $newfile->{'Dir'} = "PREDEFINED_PROGDIR";
                $newfile->{'destination'} = $newfilename;
            }

            # Also setting "modules=gid_Module_Root_Brand" (module with style: ROOT_BRAND_PACKAGE)
            if ( $installer::globals::rootbrandpackageset )
            {
                $newfile->{'modules'} = $installer::globals::rootbrandpackage;
            }

            push(@newfilesarray, $newfile);

            $infoline = "New files: Adding file $newfilename for the installation root to the file list. Language: $defaultlanguage\n";
            push( @installer::globals::logfileinfo, $infoline);

            if ( defined $newfile->{'InstallName'} )
            {
                $infoline = "New files: Using installation name: $newfile->{'InstallName'}\n";
                push( @installer::globals::logfileinfo, $infoline);
            }
        }

        push(@newfilesarray, $onefile);
    }

    return \@newfilesarray;
}

############################################################################
# Some files are included for more than one language and have the same
# name and the same destination directory for all languages. This would
# lead to conflicts, if the filenames are not changed.
# In scp project this files must have the flag MAKE_LANG_SPECIFIC
# For this files, the language is included into the filename.
############################################################################

sub make_filename_language_specific
{
    my ($filesarrayref) = @_;

    my $infoline = "";

    for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ )
    {
        my $onefile = ${$filesarrayref}[$i];

        if ( $onefile->{'ismultilingual'} )
        {
            my $styles = "";
            if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; }
            if ( $styles =~ /\bMAKE_LANG_SPECIFIC\b/ )
            {
                my $language = $onefile->{'specificlanguage'};
                my $olddestination = $onefile->{'destination'};
                my $oldname = $onefile->{'Name'};

                # Including the language into the file name.
                # But be sure, to include the language before the file extension.

                my $fileextension = "";

                if ( $onefile->{'Name'} =~ /(\.\w+?)\s*$/ ) { $fileextension = $1; }
                if ( $fileextension ne "" )
                {
                    $onefile->{'Name'} =~ s/\Q$fileextension\E\s*$/_$language$fileextension/;
                    $onefile->{'destination'} =~ s/\Q$fileextension\E\s*$/_$language$fileextension/;
                }

                $infoline = "Flag MAKE_LANG_SPECIFIC:\n";
                push( @installer::globals::logfileinfo, $infoline);
                $infoline = "Changing name from $oldname to $onefile->{'Name'} !\n";
                push( @installer::globals::logfileinfo, $infoline);
                $infoline = "Changing destination from $olddestination to $onefile->{'destination'} !\n";
                push( @installer::globals::logfileinfo, $infoline);
            }
        }
    }
}

############################################################################
# Because of the item "File" the source name must be "Name". Therefore
# "Copy" is changed to "Name" and "Name" is changed to "DestinationName".
############################################################################

sub change_keys_of_scpactions
{
    my ($itemsarrayref) = @_;

    for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
    {
        my $oneitem = ${$itemsarrayref}[$i];

        my $key;

        # First Name to DestinationName, then deleting Name
        foreach $key (keys %{$oneitem})
        {
            if ( $key =~ /\bName\b/ )
            {
                my $value = $oneitem->{$key};
                my $oldkey = $key;
                $key =~ s/Name/DestinationName/;
                $oneitem->{$key} = $value;
                delete($oneitem->{$oldkey});
            }
        }

        # Second Copy to Name, then deleting Copy
        foreach $key (keys %{$oneitem})
        {
            if ( $key =~ /\bCopy\b/ )
            {
                my $value = $oneitem->{$key};
                my $oldkey = $key;
                $key =~ s/Copy/Name/;
                $oneitem->{$key} = $value;
                delete($oneitem->{$oldkey});
            }
        }
    }
}

############################################################################
# Removing all language pack files from installation set (files with
# the style LANGUAGEPACK), except this is a language pack.
############################################################################

sub remove_Languagepacklibraries_from_Installset
{
    my ($itemsarrayref) = @_;

    my $infoline;

    my @newitemsarray = ();

    for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
    {
        my $oneitem = ${$itemsarrayref}[$i];
        my $styles = "";
        if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; }

        if ( $styles =~ /\bLANGUAGEPACK\b/ )
        {
            $infoline = "Removing language pack file $oneitem->{'gid'} from the installation set.\n";
            push( @installer::globals::globallogfileinfo, $infoline);

            next;
        }

        push(@newitemsarray, $oneitem);
    }

    $infoline = "\n";
    push( @installer::globals::globallogfileinfo, $infoline);

    return \@newitemsarray;
}

############################################################################
# Removing all help pack files from installation set (files with
# the style HELPPACK), except this is a help pack.
############################################################################

sub remove_Helppacklibraries_from_Installset
{
    my ($itemsarrayref) = @_;

    my $infoline;

    my @newitemsarray = ();

    for ( my $i = 0; $i <= $#{$itemsarrayref}; $i++ )
    {
        my $oneitem = ${$itemsarrayref}[$i];
        my $styles = "";
        if ( $oneitem->{'Styles'} ) { $styles = $oneitem->{'Styles'}; }

        if ( $styles =~ /\bHELPPACK\b/ )
        {
            $infoline = "Removing help pack file $oneitem->{'gid'} from the installation set.\n";
            push( @installer::globals::globallogfileinfo, $infoline);

            next;
        }

        push(@newitemsarray, $oneitem);
    }

    $infoline = "\n";
    push( @installer::globals::globallogfileinfo, $infoline);

    return \@newitemsarray;
}

############################################################################
# Some files contain a $ in their name. epm conflicts with such files.
# Solution: Renaming this files, converting "$" to "$$"
############################################################################

sub quoting_illegal_filenames
{
    my ($filesarrayref) = @_;

    # This function has to be removed as soon as possible!

    installer::logger::include_header_into_logfile("Renaming illegal filenames:");

    for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ )
    {
        my $onefile = ${$filesarrayref}[$i];
        my $filename = $onefile->{'Name'};

        if ( $filename =~ /\$/ )
        {
            my $sourcepath = $onefile->{'sourcepath'};
            my $destpath = $onefile->{'destination'};

            # sourcepath and destination have to be quoted for epm list file

            $destpath =~ s/\$/\$\$/g;
            $sourcepath =~ s/\$/\$\$/g;

            my $infoline = "ATTENTION: Files: Quoting sourcepath $onefile->{'sourcepath'} to $sourcepath\n";
            push( @installer::globals::logfileinfo, $infoline);
            $infoline = "ATTENTION: Files: Quoting destination path $onefile->{'destination'} to $destpath\n";
            push( @installer::globals::logfileinfo, $infoline);

            $onefile->{'sourcepath'} = $sourcepath;
            $onefile->{'destination'} = $destpath;
        }
    }
}

############################################################################
# Removing multiple occurrences of same module.
############################################################################

sub optimize_list
{
    my ( $longlist ) = @_;
    my %tmpHash;

    $longlist =~ s/^\s+//;
    $longlist =~ s/\s+$//;
    $longlist =~ s/\s*,\s*/,/g;

    @tmpHash{split /,/, $longlist} = ();
    return join(",", sort keys %tmpHash);
}

###############################################################################
# Add a directory with CREATE flag; save styles for already added directories
###############################################################################

sub add_directory_with_create_flag_hash
{
    my ($alldirectoryhash, $directoryname, $specificlanguage, $gid, $styles, $modules) = @_;
    if ( ! $directoryname ) { installer::exiter::exit_program("No directory name (HostName) set for specified language in gid $gid", "add_directory_with_create_flag_hash"); }
    my $origdirectoryname = $directoryname;
    my $newdirincluded = 0;
    if ( $styles =~ /\bCREATE\b/ )
    {
        if ( ! $modules ) { installer::exiter::exit_program("No assigned modules found for directory $directoryname", "add_directory_with_create_flag_hash"); }
        if (!(exists($alldirectoryhash->{$directoryname})))
        {
            my %directoryhash = ();
            $directoryhash{'HostName'} = $directoryname;
            $directoryhash{'specificlanguage'} = $specificlanguage;
            $directoryhash{'Dir'} = $gid;
            $directoryhash{'Styles'} = $styles;

            # saving also the modules
            $directoryhash{'modules'} = $modules;

            $alldirectoryhash->{$directoryname} = \%directoryhash;
            $newdirincluded = 1;

            # Problem: The $destinationpath can be share/registry/schema/org/openoffice
            # but not all directories contain files and will be added to this list.
            # Therefore the path has to be analyzed.

            while ( $directoryname =~ /(^.*\S)\Q$installer::globals::separator\E(\S.*?)\s*$/ )  # as long as the path contains slashes
            {
                $directoryname = $1;

                if (!(exists($alldirectoryhash->{$directoryname})))
                {
                    my %directoryhash = ();

                    $directoryhash{'HostName'} = $directoryname;
                    $directoryhash{'specificlanguage'} = $specificlanguage;
                    $directoryhash{'Dir'} = $gid;
                    if ( ! $installer::globals::iswindowsbuild ) { $directoryhash{'Styles'} = "(CREATE)"; } # Exception for Windows?

                    # saving also the modules
                    $directoryhash{'modules'} = $modules;

                    $alldirectoryhash->{$directoryname} = \%directoryhash;
                }
                else
                {
                    # Adding the modules to the module list!
                    $alldirectoryhash->{$directoryname}->{'modules'} = $alldirectoryhash->{$directoryname}->{'modules'} . "," . $modules;
                }
            }
        }
        else
        {
            # Adding the modules to the module list!
            $alldirectoryhash->{$directoryname}->{'modules'} = $alldirectoryhash->{$directoryname}->{'modules'} . "," . $modules;

            while ( $directoryname =~ /(^.*\S)\Q$installer::globals::separator\E(\S.*?)\s*$/ )  # as long as the path contains slashes
            {
                $directoryname = $1;
                # Adding the modules to the module list!
                $alldirectoryhash->{$directoryname}->{'modules'} = $alldirectoryhash->{$directoryname}->{'modules'} . "," . $modules;
            }
        }
    }

    # Saving the styles for already added directories in function collect_directories_from_filesarray

    if (( ! $newdirincluded ) && ( $styles ne "" ))
    {
        $styles =~ s/\bWORKSTATION\b//;
        $styles =~ s/\bCREATE\b//;

        if (( ! ( $styles =~ /^\s*\(\s*\)\s*$/ )) && ( ! ( $styles =~ /^\s*\(\s*\,\s*\)\s*$/ )) && ( ! ( $styles =~ /^\s*$/ ))) # checking, if there are styles left
        {
            $directoryname = $origdirectoryname;

            if ( exists($alldirectoryhash->{$directoryname}) )
            {
                $alldirectoryhash->{$directoryname}->{'Styles'} = $styles;
            }
        }
    }

    return $alldirectoryhash;
}

#######################################################################
# Collecting all directories needed for the epm list
# 1. Looking for all destination paths in the files array
# 2. Looking for directories with CREATE flag in the directory array
#######################################################################

##################################
# Collecting directories: Part 1
##################################

sub collect_directories_from_filesarray
{
    my ($filesarrayref, $unixlinksarrayref) = @_;

    my %alldirectoryhash = ();
    my @filteredfilesarray = (); # without empty directories
    foreach my $onefile (@{$filesarrayref})
    {
        # The "file" can actually be an empty directory added e.g. by gb_Package_add_empty_directory.
        # TODO/LATER: it would be better if gb_Package_add_empty_directory added empty directories to
        # "directories with CREATE flag" instead of a filelist.
        if (-d $onefile->{'sourcepath'})
        {
            # Do the same as collect_directories_with_create_flag_from_directoryarray does
            %alldirectoryhash = %{add_directory_with_create_flag_hash(\%alldirectoryhash, $onefile->{'destination'}, $onefile->{'specificlanguage'}, $onefile->{'gid'}, "(CREATE)", $onefile->{'modules'})};
        }
        else { push(@filteredfilesarray, $onefile); }
    }

    # Preparing this already as hash, although the only needed value at the moment is the HostName
    # But also adding: "specificlanguage" and "Dir" (for instance gid_Dir_Program)

    foreach my $onefile (@filteredfilesarray, @{$unixlinksarrayref})
    {
        my $destinationpath = $onefile->{'destination'};

        installer::pathanalyzer::get_path_from_fullqualifiedname(\$destinationpath);
        $destinationpath =~ s/\Q$installer::globals::separator\E\s*$//;     # removing ending slashes or backslashes

        do
        {
            if (!exists($alldirectoryhash{$destinationpath}))
            {
                my %directoryhash = ();
                $directoryhash{'HostName'} = $destinationpath;
                $directoryhash{'specificlanguage'} = $onefile->{'specificlanguage'};
                $directoryhash{'Dir'} = $onefile->{'Dir'};
                $directoryhash{'modules'} = $onefile->{'modules'}; # NEW, saving modules
                $directoryhash{'gid'} = $onefile->{'gid'};

                $alldirectoryhash{$destinationpath} = \%directoryhash;
            }
            else
            {
                # Adding the modules to the module list!
                $alldirectoryhash{$destinationpath}->{'modules'} .= "," . $onefile->{'modules'};
                # Save file's gid iff this directory appears in only a single
                # file's FILELIST (so that unused directories will be filtered
                # out in remove_not_required_spellcheckerlanguage_files, based
                # on gid):
                if ($alldirectoryhash{$destinationpath}->{'gid'}
                    ne $onefile->{'gid'})
                {
                    $alldirectoryhash{$destinationpath}->{'gid'} = '';
                }
            }
        } while ($destinationpath =~ s/(^.*\S)\Q$installer::globals::separator\E(\S.*?)\s*$/$1/);  # as long as the path contains slashes
    }

    # Creating directory array
    foreach my $destdir ( keys %alldirectoryhash )
    {
        $alldirectoryhash{$destdir}->{'modules'} = optimize_list($alldirectoryhash{$destdir}->{'modules'});
    }

    @_[0] = \@filteredfilesarray; # out argument
    return \%alldirectoryhash;
}

##################################
# Collecting directories: Part 2
##################################

sub collect_directories_with_create_flag_from_directoryarray
{
    my ($directoryarrayref, $alldirectoryhash) = @_;

    my @alldirectories = ();

    foreach my $onedir (@{$directoryarrayref})
    {
        $alldirectoryhash = add_directory_with_create_flag_hash($alldirectoryhash, $onedir->{'HostName'}, $onedir->{'specificlanguage'}, $onedir->{'gid'}, $onedir->{'Styles'}, $onedir->{'modules'});
    }

    # Creating directory array
    foreach my $destdir ( sort keys %{$alldirectoryhash} )
    {
        $alldirectoryhash->{$destdir}->{'modules'} = optimize_list($alldirectoryhash->{$destdir}->{'modules'});
        push(@alldirectories, $alldirectoryhash->{$destdir});
    }

    return \@alldirectories;
}

#################################################
# Determining the destination file of a link
#################################################

sub get_destination_file_path_for_links
{
    my ($linksarrayref, $filesarrayref) = @_;

    my $infoline;

    for ( my $i = 0; $i <= $#{$linksarrayref}; $i++ )
    {
        my $fileid = "";
        my $onelink = ${$linksarrayref}[$i];
        if ( $onelink->{'FileID'} ) { $fileid = $onelink->{'FileID'}; }

        if (!( $fileid eq "" ))
        {
            my $foundfile = 0;

            for ( my $j = 0; $j <= $#{$filesarrayref}; $j++ )
            {
                my $onefile = ${$filesarrayref}[$j];
                my $filegid = $onefile->{'gid'};

                if ( $filegid eq $fileid )
                {
                    $foundfile = 1;
                    $onelink->{'destinationfile'} = $onefile->{'destination'};
                    last;
                }
            }

            if (!($foundfile))
            {
                $infoline = "Warning: FileID $fileid for Link $onelink->{'gid'} not found!\n";
                push( @installer::globals::logfileinfo, $infoline);
            }
        }
    }

    $infoline = "\n";
    push( @installer::globals::logfileinfo, $infoline);
}

#################################################
# Determining the destination link of a link
#################################################

sub get_destination_link_path_for_links
{
    my ($linksarrayref) = @_;

    my $infoline;

    for ( my $i = 0; $i <= $#{$linksarrayref}; $i++ )
    {
        my $shortcutid = "";
        my $onelink = ${$linksarrayref}[$i];
        if ( $onelink->{'ShortcutID'} ) { $shortcutid = $onelink->{'ShortcutID'}; }

        if (!( $shortcutid eq "" ))
        {
            my $foundlink = 0;

            for ( my $j = 0; $j <= $#{$linksarrayref}; $j++ )
            {
                my $destlink = ${$linksarrayref}[$j];
                my $shortcutgid = $destlink->{'gid'};

                if ( $shortcutgid eq $shortcutid )
                {
                    $foundlink = 1;
                    $onelink->{'destinationfile'} = $destlink->{'destination'};     # making key 'destinationfile'
                    last;
                }
            }

            if (!($foundlink))
            {
                $infoline = "Warning: ShortcutID $shortcutid for Link $onelink->{'gid'} not found!\n";
                push( @installer::globals::logfileinfo, $infoline);
            }
        }
    }

    $infoline = "\n";
    push( @installer::globals::logfileinfo, $infoline);
}

###################################################################################
# Items with flag WORKSTATION are not needed (here: links and configurationitems)
###################################################################################

sub remove_workstation_only_items
{
    my ($itemarrayref) = @_;

    my @newitemarray = ();

    for ( my $i = 0; $i <= $#{$itemarrayref}; $i++ )
    {
        my $oneitem = ${$itemarrayref}[$i];
        my $styles = $oneitem->{'Styles'};

        if (( $styles =~ /\bWORKSTATION\b/ ) &&
--> --------------------

--> maximum size reached

--> --------------------

[ Dauer der Verarbeitung: 0.24 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge