xref: /trunk/main/solenv/bin/modules/installer/simplepackage.pm (revision ef1ef8e674fabf3a541d12c6e6c14cecdfc2f9e7)
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::simplepackage;
29
30# use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
31use Cwd;
32use File::Copy;
33use installer::download;
34use installer::exiter;
35use installer::globals;
36use installer::logger;
37use installer::strip;
38use installer::systemactions;
39use installer::worker;
40
41####################################################
42# Checking if the simple packager is required.
43# This can be achieved by setting the global
44# variable SIMPLE_PACKAGE in *.lst file or by
45# setting the environment variable SIMPLE_PACKAGE.
46####################################################
47
48sub check_simple_packager_project
49{
50    my ( $allvariables ) = @_;
51
52    if (( $installer::globals::packageformat eq "installed" ) ||
53        ( $installer::globals::packageformat eq "archive" ))
54    {
55        $installer::globals::is_simple_packager_project = 1;
56        $installer::globals::patch_user_dir = 1;
57    }
58    elsif( $installer::globals::packageformat eq "dmg" )
59    {
60        $installer::globals::is_simple_packager_project = 1;
61    }
62}
63
64####################################################
65# Detecting the directory with extensions
66####################################################
67
68sub get_extensions_dir
69{
70    my ( $subfolderdir ) = @_;
71
72    my $extensiondir = $subfolderdir . $installer::globals::separator;
73    if ( $installer::globals::officedirhostname ne "" ) { $extensiondir = $extensiondir . $installer::globals::officedirhostname . $installer::globals::separator; }
74    my $extensionsdir = $extensiondir . "share" . $installer::globals::separator . "extensions";
75    my $preregdir = $extensiondir . "share" . $installer::globals::separator . "prereg" . $installer::globals::separator . "bundled";
76
77    return ( $extensionsdir, $preregdir );
78}
79
80####################################################
81# Registering extensions
82####################################################
83
84sub register_extensions
85{
86    my ($officedir, $languagestringref, $preregdir) = @_;
87
88    my $infoline = "";
89
90    if ( $preregdir eq "" )
91    {
92        $infoline = "ERROR: Failed to determine directory \"prereg\" for extension registration! Please check your installation set.\n";
93        push( @installer::globals::logfileinfo, $infoline);
94        installer::exiter::exit_program($infoline, "register_extensions");
95    }
96
97    my $programdir = $officedir . $installer::globals::separator;
98    if ( $installer::globals::officedirhostname ne "" ) { $programdir = $programdir . $installer::globals::officedirhostname . $installer::globals::separator; }
99    $programdir = $programdir . "program";
100
101    my $from = cwd();
102    chdir($programdir);
103
104    my $unopkgfile = $installer::globals::unopkgfile;
105
106    my $unopkgexists = 1;
107    if (( $installer::globals::languagepack ) && ( ! -f $unopkgfile ))
108    {
109        $unopkgexists = 0;
110        $infoline = "Language packs do not contain unopkg!\n";
111        push( @installer::globals::logfileinfo, $infoline);
112    }
113
114    if ( ! -f $unopkgfile )
115    {
116        $unopkgexists = 0;
117        $infoline = "Info: File $unopkgfile does not exist! Extensions cannot be registered.\n";
118        push( @installer::globals::logfileinfo, $infoline);
119    }
120
121    if ( $unopkgexists )
122    {
123        my $currentdir = cwd();
124        print "... current dir: $currentdir ...\n";
125        $infoline = "Current dir: $currentdir\n";
126        push( @installer::globals::logfileinfo, $infoline);
127
128        if ( ! -f $unopkgfile ) { installer::exiter::exit_program("ERROR: $unopkgfile not found!", "register_extensions"); }
129
130        my $systemcall = $unopkgfile . " sync --verbose" . " -env:UNO_JAVA_JFW_ENV_JREHOME=true 2\>\&1 |";
131
132        print "... $systemcall ...\n";
133
134        $infoline = "Systemcall: $systemcall\n";
135        push( @installer::globals::logfileinfo, $infoline);
136
137        my @unopkgoutput = ();
138
139        open (UNOPKG, $systemcall);
140        while (<UNOPKG>)
141        {
142            my $lastline = $_;
143            push(@unopkgoutput, $lastline);
144        }
145        close (UNOPKG);
146
147        my $returnvalue = $?;   # $? contains the return value of the systemcall
148
149        if ($returnvalue)
150        {
151            # Writing content of @unopkgoutput only in the error case into the log file. Sometimes it
152            # contains strings like "Error" even in the case of success. This causes a packaging error
153            # when the log file is analyzed at the end, even if there is no real error.
154            for ( my $j = 0; $j <= $#unopkgoutput; $j++ ) { push( @installer::globals::logfileinfo, "$unopkgoutput[$j]"); }
155
156            $infoline = "ERROR: Could not execute \"$systemcall\"!\nExitcode: '$returnvalue'\n";
157            push( @installer::globals::logfileinfo, $infoline);
158            installer::exiter::exit_program("ERROR: $systemcall failed!", "register_extensions");
159        }
160        else
161        {
162            $infoline = "Success: Executed \"$systemcall\" successfully!\n";
163            push( @installer::globals::logfileinfo, $infoline);
164        }
165    }
166
167    chdir($from);
168}
169
170########################################################################
171# Getting the translation file for the Mac Language Pack installer
172########################################################################
173
174sub get_mac_translation_file
175{
176    my $translationfilename = $installer::globals::maclangpackfilename;
177    # my $translationfilename = $installer::globals::idtlanguagepath . $installer::globals::separator . $installer::globals::maclangpackfilename;
178    # if ( $installer::globals::unicodensis ) { $translationfilename = $translationfilename . ".uulf"; }
179    # else { $translationfilename = $translationfilename . ".mlf"; }
180    if ( ! -f $translationfilename ) { installer::exiter::exit_program("ERROR: Could not find language file $translationfilename!", "get_mac_translation_file"); }
181    my $translationfile = installer::files::read_file($translationfilename);
182
183    my $infoline = "Reading translation file: $translationfilename\n";
184    push( @installer::globals::logfileinfo, $infoline);
185
186    return $translationfile;
187}
188
189##################################################################
190# Collecting all identifier from ulf file
191##################################################################
192
193sub get_identifier
194{
195    my ( $translationfile ) = @_;
196
197    my @identifier = ();
198
199    for ( my $i = 0; $i <= $#{$translationfile}; $i++ )
200    {
201        my $oneline = ${$translationfile}[$i];
202
203        if ( $oneline =~ /^\s*\[(.+)\]\s*$/ )
204        {
205            my $identifier = $1;
206            push(@identifier, $identifier);
207        }
208    }
209
210    return \@identifier;
211}
212
213##############################################################
214# Returning the complete block in all languages
215# for a specified string
216##############################################################
217
218sub get_language_block_from_language_file
219{
220    my ($searchstring, $languagefile) = @_;
221
222    my @language_block = ();
223
224    for ( my $i = 0; $i <= $#{$languagefile}; $i++ )
225    {
226        if ( ${$languagefile}[$i] =~ /^\s*\[\s*$searchstring\s*\]\s*$/ )
227        {
228            my $counter = $i;
229
230            push(@language_block, ${$languagefile}[$counter]);
231            $counter++;
232
233            while (( $counter <= $#{$languagefile} ) && (!( ${$languagefile}[$counter] =~ /^\s*\[/ )))
234            {
235                push(@language_block, ${$languagefile}[$counter]);
236                $counter++;
237            }
238
239            last;
240        }
241    }
242
243    return \@language_block;
244}
245
246##############################################################
247# Returning a specific language string from the block
248# of all translations
249##############################################################
250
251sub get_language_string_from_language_block
252{
253    my ($language_block, $language) = @_;
254
255    my $newstring = "";
256
257    for ( my $i = 0; $i <= $#{$language_block}; $i++ )
258    {
259        if ( ${$language_block}[$i] =~ /^\s*$language\s*\=\s*\"(.*)\"\s*$/ )
260        {
261            $newstring = $1;
262            last;
263        }
264    }
265
266    if ( $newstring eq "" )
267    {
268        $language = "en-US";    # defaulting to english
269
270        for ( my $i = 0; $i <= $#{$language_block}; $i++ )
271        {
272            if ( ${$language_block}[$i] =~ /^\s*$language\s*\=\s*\"(.*)\"\s*$/ )
273            {
274                $newstring = $1;
275                last;
276            }
277        }
278    }
279
280    return $newstring;
281}
282
283########################################################################
284# Localizing the script for the Mac Language Pack installer
285########################################################################
286
287sub localize_scriptfile
288{
289    my ($scriptfile, $translationfile, $languagestringref) = @_;
290
291    # my $translationfile = get_mac_translation_file();
292
293    my $onelanguage = $$languagestringref;
294    if ( $onelanguage =~ /^\s*(.*?)_/ ) { $onelanguage = $1; }
295
296    # Analyzing the ulf file, collecting all Identifier
297    my $allidentifier = get_identifier($translationfile);
298
299    for ( my $i = 0; $i <= $#{$allidentifier}; $i++ )
300    {
301        my $identifier = ${$allidentifier}[$i];
302        my $language_block = get_language_block_from_language_file($identifier, $translationfile);
303        my $newstring = get_language_string_from_language_block($language_block, $onelanguage);
304
305        # removing mask
306        $newstring =~ s/\\\'/\'/g;
307
308        replace_one_variable_in_shellscript($scriptfile, $newstring, $identifier);
309    }
310}
311
312#################################################################################
313# Replacing one variable in Mac shell script
314#################################################################################
315
316sub replace_one_variable_in_shellscript
317{
318    my ($scriptfile, $variable, $searchstring) = @_;
319
320    for ( my $i = 0; $i <= $#{$scriptfile}; $i++ )
321    {
322        ${$scriptfile}[$i] =~ s/\[$searchstring\]/$variable/g;
323    }
324}
325
326#############################################
327# Replacing variables in Mac shell script
328#############################################
329
330sub replace_variables_in_scriptfile
331{
332    my ($scriptfile, $volume_name, $volume_name_app, $allvariables) = @_;
333
334    replace_one_variable_in_shellscript($scriptfile, $volume_name, "FULLPRODUCTNAME" );
335    replace_one_variable_in_shellscript($scriptfile, $volume_name_app, "FULLAPPPRODUCTNAME" );
336    replace_one_variable_in_shellscript($scriptfile, $allvariables->{'PRODUCTNAME'}, "PRODUCTNAME" );
337    replace_one_variable_in_shellscript($scriptfile, $allvariables->{'PRODUCTVERSION'}, "PRODUCTVERSION" );
338
339    my $scriptname = lc($allvariables->{'PRODUCTNAME'}) . "\.script";
340    if ( $allvariables->{'PRODUCTNAME'} eq "OpenOffice.org" ) { $scriptname = "org.openoffice.script"; }
341
342    replace_one_variable_in_shellscript($scriptfile, $scriptname, "SEARCHSCRIPTNAME" );
343}
344
345#############################################
346# Creating the "simple" package.
347# "zip" for Windows
348# "tar.gz" for all other platforms
349# additionally "dmg" on Mac OS X
350#############################################
351
352sub create_package
353{
354    my ( $installdir, $archivedir, $packagename, $allvariables, $includepatharrayref, $languagestringref, $format ) = @_;
355
356    installer::logger::print_message( "... creating $installer::globals::packageformat file ...\n" );
357    installer::logger::include_header_into_logfile("Creating $installer::globals::packageformat file:");
358
359    # moving dir into temporary directory
360    my $pid = $$; # process id
361    my $tempdir = $installdir . "_temp" . "." . $pid;
362    my $systemcall = "";
363    my $from = "";
364    my $makesystemcall = 1;
365    my $return_to_start = 0;
366    installer::systemactions::rename_directory($installdir, $tempdir);
367
368    # creating new directory with original name
369    installer::systemactions::create_directory($archivedir);
370
371    my $archive = $archivedir . $installer::globals::separator . $packagename . $format;
372
373    if ( $archive =~ /zip$/ )
374    {
375        $from = cwd();
376        $return_to_start = 1;
377        chdir($tempdir);
378        $systemcall = "$installer::globals::zippath -qr $archive .";
379
380        # Using Archive::Zip fails because of very long path names below "share/uno_packages/cache"
381        # my $packzip = Archive::Zip->new();
382        # $packzip->addTree(".");   # after changing into $tempdir
383        # $packzip->writeToFileNamed($archive);
384        # $makesystemcall = 0;
385    }
386    elsif ( $archive =~ /dmg$/ )
387    {
388        my $folder = (( -l "$tempdir/$packagename/Applications" ) or ( -l "$tempdir/$packagename/opt" )) ? $packagename : "\.";
389
390        if ( $allvariables->{'PACK_INSTALLED'} ) {
391            $folder = $packagename;
392        }
393
394        # my $volume_name = $allvariables->{'PRODUCTNAME'} . ' ' . $allvariables->{'PRODUCTVERSION'}; # Adding PRODUCTVERSION makes this difficult to maintain!
395        my $volume_name = $allvariables->{'PRODUCTNAME'};
396        my $volume_name_classic = $allvariables->{'PRODUCTNAME'} . ' ' . $allvariables->{'PRODUCTVERSION'};
397        my $volume_name_classic_app = $volume_name;  # "app" should not contain version number
398        # $volume_name = $volume_name . ' ' . $allvariables->{'PRODUCTEXTENSION'} if $allvariables->{'PRODUCTEXTENSION'}; # Adding PRODUCTEXTENSION makes this difficult to maintain!
399        $volume_name_classic = $volume_name_classic . ' ' . $allvariables->{'PRODUCTEXTENSION'} if $allvariables->{'PRODUCTEXTENSION'};
400        $volume_name_classic_app = $volume_name_classic_app . ' ' . $allvariables->{'PRODUCTEXTENSION'} if $allvariables->{'PRODUCTEXTENSION'};
401        if ( $allvariables->{'DMG_VOLUMEEXTENSION'} ) {
402            $volume_name = $volume_name . ' ' . $allvariables->{'DMG_VOLUMEEXTENSION'};
403            $volume_name_classic = $volume_name_classic . ' ' . $allvariables->{'DMG_VOLUMEEXTENSION'};
404            $volume_name_classic_app = $volume_name_classic_app . ' ' . $allvariables->{'DMG_VOLUMEEXTENSION'};
405        }
406
407        my $sla = 'sla.r';
408        my $ref = "";
409
410        if ( ! $allvariables->{'HIDELICENSEDIALOG'} )
411        {
412            installer::scriptitems::get_sourcepath_from_filename_and_includepath( \$sla, $includepatharrayref, 0);
413        }
414
415        my $localtempdir = $tempdir;
416
417        if (( $installer::globals::languagepack ) || ( $installer::globals::patch ))
418        {
419            $localtempdir = "$tempdir/$packagename";
420            if ( $installer::globals::languagepack )
421            {
422                $volume_name = "$volume_name Language Pack";
423                $volume_name_classic = "$volume_name_classic Language Pack";
424                $volume_name_classic_app = "$volume_name_classic_app Language Pack";
425            }
426            if ( $installer::globals::patch )
427            {
428                $volume_name = "$volume_name Patch";
429                $volume_name_classic = "$volume_name_classic Patch";
430                $volume_name_classic_app = "$volume_name_classic_app Patch";
431            }
432
433            # Create tar ball named tarball.tar.bz2
434            # my $appfolder = $localtempdir . "/" . $volume_name . "\.app";
435            my $appfolder = $localtempdir . "/" . $volume_name_classic_app . "\.app";
436            my $contentsfolder = $appfolder . "/Contents";
437            my $tarballname = "tarball.tar.bz2";
438
439            my $localfrom = cwd();
440            chdir $appfolder;
441
442            $systemcall = "tar -cjf $tarballname Contents/";
443
444            print "... $systemcall ...\n";
445            my $localreturnvalue = system($systemcall);
446            $infoline = "Systemcall: $systemcall\n";
447            push( @installer::globals::logfileinfo, $infoline);
448
449            if ($localreturnvalue)
450            {
451                $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
452                push( @installer::globals::logfileinfo, $infoline);
453            }
454            else
455            {
456                $infoline = "Success: Executed \"$systemcall\" successfully!\n";
457                push( @installer::globals::logfileinfo, $infoline);
458            }
459
460            my $sourcefile = $appfolder . "/" . $tarballname;
461            my $destfile = $contentsfolder . "/" . $tarballname;
462
463            installer::systemactions::remove_complete_directory($contentsfolder);
464            installer::systemactions::create_directory($contentsfolder);
465
466            installer::systemactions::copy_one_file($sourcefile, $destfile);
467            unlink($sourcefile);
468
469            # Copy two files into installation set next to the tar ball
470            # 1. "osx_install.applescript"
471            # 2 "OpenOffice.org Languagepack"
472
473            my $scriptrealfilename = "osx_install.applescript";
474            my $scriptfilename = "";
475            if ( $installer::globals::languagepack ) { $scriptfilename = "osx_install_languagepack.applescript"; }
476            if ( $installer::globals::patch ) { $scriptfilename = "osx_install_patch.applescript"; }
477            my $scripthelpersolverfilename = "mac_install.script";
478            # my $scripthelperrealfilename = $volume_name;
479            my $scripthelperrealfilename = $volume_name_classic_app;
480            my $translationfilename = $installer::globals::macinstallfilename;
481
482            # Finding both files in solver
483
484            my $scriptref = installer::scriptitems::get_sourcepath_from_filename_and_includepath( \$scriptfilename, $includepatharrayref, 0);
485            if ($$scriptref eq "") { installer::exiter::exit_program("ERROR: Could not find Apple script $scriptfilename!", "create_package"); }
486            my $scripthelperref = installer::scriptitems::get_sourcepath_from_filename_and_includepath( \$scripthelpersolverfilename, $includepatharrayref, 0);
487            if ($$scripthelperref eq "") { installer::exiter::exit_program("ERROR: Could not find Apple script $scripthelpersolverfilename!", "create_package"); }
488            my $translationfileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath( \$translationfilename, $includepatharrayref, 0);
489            if ($$translationfileref eq "") { installer::exiter::exit_program("ERROR: Could not find Apple script translation file $translationfilename!", "create_package"); }
490
491            $scriptfilename = $contentsfolder . "/" . $scriptrealfilename;
492            $scripthelperrealfilename = $contentsfolder . "/" . $scripthelperrealfilename;
493
494            installer::systemactions::copy_one_file($$scriptref, $scriptfilename);
495            installer::systemactions::copy_one_file($$scripthelperref, $scripthelperrealfilename);
496
497            # Replacing variables in script $scriptfilename
498            # Localizing script $scriptfilename
499            my $scriptfilecontent = installer::files::read_file($scriptfilename);
500            my $translationfilecontent = installer::files::read_file($$translationfileref);
501            localize_scriptfile($scriptfilecontent, $translationfilecontent, $languagestringref);
502            # replace_variables_in_scriptfile($scriptfilecontent, $volume_name, $allvariables);
503            replace_variables_in_scriptfile($scriptfilecontent, $volume_name_classic, $volume_name_classic_app, $allvariables);
504            installer::files::save_file($scriptfilename, $scriptfilecontent);
505
506            $systemcall = "chmod 775 " . "\"" . $scriptfilename . "\"";
507            system($systemcall);
508            $systemcall = "chmod 775 " . "\"" . $scripthelperrealfilename . "\"";
509            system($systemcall);
510
511            # Copy also Info.plist and icon file
512            # Finding both files in solver
513            my $iconfile = "ooo3_installer.icns";
514            my $iconfileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath( \$iconfile, $includepatharrayref, 0);
515            if ($$iconfileref eq "") { installer::exiter::exit_program("ERROR: Could not find Apple script icon file $iconfile!", "create_package"); }
516            my $subdir = $contentsfolder . "/" . "Resources";
517            if ( ! -d $subdir ) { installer::systemactions::create_directory($subdir); }
518            $destfile = $subdir . "/" . $iconfile;
519            installer::systemactions::copy_one_file($$iconfileref, $destfile);
520
521            my $infoplistfile = "Info.plist.langpack";
522            my $installname = "Info.plist";
523            my $infoplistfileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath( \$infoplistfile, $includepatharrayref, 0);
524            if ($$infoplistfileref eq "") { installer::exiter::exit_program("ERROR: Could not find Apple script Info.plist: $infoplistfile!", "create_package"); }
525            $destfile = $contentsfolder . "/" . $installname;
526            installer::systemactions::copy_one_file($$infoplistfileref, $destfile);
527
528            # Replacing variables in Info.plist
529            $scriptfilecontent = installer::files::read_file($destfile);
530            # replace_one_variable_in_shellscript($scriptfilecontent, $volume_name, "FULLPRODUCTNAME" );
531            replace_one_variable_in_shellscript($scriptfilecontent, $volume_name_classic_app, "FULLAPPPRODUCTNAME" ); # OpenOffice.org Language Pack
532            installer::files::save_file($destfile, $scriptfilecontent);
533
534            chdir $localfrom;
535        }
536
537        $systemcall = "cd $localtempdir && hdiutil makehybrid -hfs -hfs-openfolder $folder $folder -hfs-volume-name \"$volume_name\" -ov -o $installdir/tmp && hdiutil convert -ov -format UDZO $installdir/tmp.dmg -o $archive && ";
538        if (( $ref ne "" ) && ( $$ref ne "" )) {
539            $systemcall .= "hdiutil unflatten $archive && Rez -a $$ref -o $archive && hdiutil flatten $archive &&";
540        }
541        $systemcall .= "rm -f $installdir/tmp.dmg";
542    }
543    else
544    {
545        # getting the path of the getuid.so (only required for Solaris and Linux)
546        my $getuidlibrary = "";
547        my $ldpreloadstring = "";
548        if (( $installer::globals::issolarisbuild ) || ( $installer::globals::islinuxbuild ))
549        {
550            $getuidlibrary = installer::download::get_path_for_library($includepatharrayref);
551            if ( $getuidlibrary ne "" ) { $ldpreloadstring = "LD_PRELOAD=" . $getuidlibrary; }
552        }
553
554        $systemcall = "cd $tempdir; $ldpreloadstring tar -cf - . | gzip > $archive";
555    }
556
557    if ( $makesystemcall )
558    {
559        print "... $systemcall ...\n";
560        my $returnvalue = system($systemcall);
561        my $infoline = "Systemcall: $systemcall\n";
562        push( @installer::globals::logfileinfo, $infoline);
563
564        if ($returnvalue)
565        {
566            $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
567            push( @installer::globals::logfileinfo, $infoline);
568        }
569        else
570        {
571            $infoline = "Success: Executed \"$systemcall\" successfully!\n";
572            push( @installer::globals::logfileinfo, $infoline);
573        }
574    }
575
576    if ( $return_to_start ) { chdir($from); }
577
578    print "... removing $tempdir ...\n";
579    installer::systemactions::remove_complete_directory($tempdir);
580}
581
582####################################################
583# Main method for creating the simple package
584# installation sets
585####################################################
586
587sub create_simple_package
588{
589    my ( $filesref, $dirsref, $scpactionsref, $linksref, $unixlinksref, $loggingdir, $languagestringref, $shipinstalldir, $allsettingsarrayref, $allvariables, $includepatharrayref ) = @_;
590
591    # Creating directories
592
593    my $current_install_number = "";
594    my $infoline = "";
595
596    installer::logger::print_message( "... creating installation directory ...\n" );
597    installer::logger::include_header_into_logfile("Creating installation directory");
598
599    $installer::globals::csp_installdir = installer::worker::create_installation_directory($shipinstalldir, $languagestringref, \$current_install_number);
600    $installer::globals::csp_installlogdir = installer::systemactions::create_directory_next_to_directory($installer::globals::csp_installdir, "log");
601
602    my $installdir = $installer::globals::csp_installdir;
603    my $installlogdir = $installer::globals::csp_installlogdir;
604
605    # Setting package name (similar to the download name)
606    my $packagename = "";
607
608    if ( $installer::globals::packageformat eq "archive"  ||
609        $installer::globals::packageformat eq "dmg" )
610    {
611        $installer::globals::csp_languagestring = $$languagestringref;
612
613        my $locallanguage = $installer::globals::csp_languagestring;
614
615        if ( $allvariables->{'OOODOWNLOADNAME'} )
616        {
617            $packagename = installer::download::set_download_filename(\$locallanguage, $allvariables);
618        }
619        else
620        {
621            $downloadname = installer::ziplist::getinfofromziplist($allsettingsarrayref, "downloadname");
622            if ( $installer::globals::languagepack ) { $downloadname = installer::ziplist::getinfofromziplist($allsettingsarrayref, "langpackdownloadname"); }
623            if ( $installer::globals::patch ) { $downloadname = installer::ziplist::getinfofromziplist($allsettingsarrayref, "patchdownloadname"); }
624            $packagename = installer::download::resolve_variables_in_downloadname($allvariables, $$downloadname, \$locallanguage);
625        }
626    }
627
628    # Work around Windows problems with long pathnames (see issue 50885) by
629    # putting the to-be-archived installation tree into the temp directory
630    # instead of the module output tree (unless LOCALINSTALLDIR dictates
631    # otherwise, anyway); can be removed once issue 50885 is fixed:
632    my $tempinstalldir = $installdir;
633    if ( $installer::globals::iswindowsbuild &&
634         $installer::globals::packageformat eq "archive" &&
635         !$installer::globals::localinstalldirset )
636    {
637        $tempinstalldir = File::Temp::tempdir;
638    }
639
640    # Creating subfolder in installdir, which shall become the root of package or zip file
641    my $subfolderdir = "";
642    if ( $packagename ne "" ) { $subfolderdir = $tempinstalldir . $installer::globals::separator . $packagename; }
643    else { $subfolderdir = $tempinstalldir; }
644
645    if ( ! -d $subfolderdir ) { installer::systemactions::create_directory($subfolderdir); }
646
647    # Create directories, copy files and ScpActions
648
649    installer::logger::print_message( "... creating directories ...\n" );
650    installer::logger::include_header_into_logfile("Creating directories:");
651
652    for ( my $i = 0; $i <= $#{$dirsref}; $i++ )
653    {
654        my $onedir = ${$dirsref}[$i];
655
656        if ( $onedir->{'HostName'} )
657        {
658            my $destdir = $subfolderdir . $installer::globals::separator . $onedir->{'HostName'};
659
660            if ( ! -d $destdir )
661            {
662                if ( $^O =~ /cygwin/i ) # Cygwin performance check
663                {
664                    $infoline = "Try to create directory $destdir\n";
665                    push(@installer::globals::logfileinfo, $infoline);
666                    # Directories in $dirsref are sorted and all parents were added -> "mkdir" works without parent creation!
667                    if ( ! ( -d $destdir )) { mkdir($destdir, 0775); }
668                }
669                else
670                {
671                    installer::systemactions::create_directory_structure($destdir);
672                }
673            }
674        }
675    }
676
677    # stripping files ?!
678    if (( $installer::globals::strip ) && ( ! $installer::globals::iswindowsbuild )) { installer::strip::strip_libraries($filesref, $languagestringref); }
679
680    # copy Files
681    installer::logger::print_message( "... copying files ...\n" );
682    installer::logger::include_header_into_logfile("Copying files:");
683
684    for ( my $i = 0; $i <= $#{$filesref}; $i++ )
685    {
686        my $onefile = ${$filesref}[$i];
687
688        if (( $onefile->{'Styles'} ) && ( $onefile->{'Styles'} =~ /\bBINARYTABLE_ONLY\b/ )) { next; }
689        if (( $installer::globals::patch ) && ( $onefile->{'Styles'} ) && ( ! ( $onefile->{'Styles'} =~ /\bPATCH\b/ ))) { next; }
690        if (( $installer::globals::patch ) && ( $installer::globals::packageformat eq "dmg" )) { push(@installer::globals::patchfilecollector, "$onefile->{'destination'}\n"); }
691
692        my $source = $onefile->{'sourcepath'};
693        my $destination = $onefile->{'destination'};
694        $destination = $subfolderdir . $installer::globals::separator . $destination;
695
696        # Replacing $$ by $ is necessary to install files with $ in its name (back-masquerading)
697        # Otherwise, the following shell command does not work and the file list is not correct
698        $source =~ s/\$\$/\$/;
699        $destination =~ s/\$\$/\$/;
700
701        if ( $^O =~ /cygwin/i ) # Cygwin performance, do not use copy_one_file. "chmod -R" at the end
702        {
703            my $copyreturn = copy($source, $destination);
704
705            if ($copyreturn)
706            {
707                $infoline = "Copy: $source to $destination\n";
708                $returnvalue = 1;
709            }
710            else
711            {
712                $infoline = "ERROR: Could not copy $source to $destination\n";
713                $returnvalue = 0;
714            }
715
716            push(@installer::globals::logfileinfo, $infoline);
717        }
718        else
719        {
720            installer::systemactions::copy_one_file($source, $destination);
721
722            if ( ! $installer::globals::iswindowsbuild )
723            {
724                # see issue 102274
725                my $unixrights = "";
726                if ( $onefile->{'UnixRights'} )
727                {
728                    $unixrights = $onefile->{'UnixRights'};
729
730                    my $localcall = "$installer::globals::wrapcmd chmod $unixrights \'$destination\' \>\/dev\/null 2\>\&1";
731                    system($localcall);
732                }
733            }
734        }
735    }
736
737    # creating Links
738
739    installer::logger::print_message( "... creating links ...\n" );
740    installer::logger::include_header_into_logfile("Creating links:");
741
742    for ( my $i = 0; $i <= $#{$linksref}; $i++ )
743    {
744        my $onelink = ${$linksref}[$i];
745
746        if (( $installer::globals::patch ) && ( $onelink->{'Styles'} ) && ( ! ( $onelink->{'Styles'} =~ /\bPATCH\b/ ))) { next; }
747
748        my $destination = $onelink->{'destination'};
749        $destination = $subfolderdir . $installer::globals::separator . $destination;
750        my $destinationfile = $onelink->{'destinationfile'};
751
752        my $localcall = "ln -sf \'$destinationfile\' \'$destination\' \>\/dev\/null 2\>\&1";
753        system($localcall);
754
755        $infoline = "Creating link: \"ln -sf $destinationfile $destination\"\n";
756        push(@installer::globals::logfileinfo, $infoline);
757    }
758
759    for ( my $i = 0; $i <= $#{$unixlinksref}; $i++ )
760    {
761        my $onelink = ${$unixlinksref}[$i];
762
763        if (( $installer::globals::patch ) && ( $onelink->{'Styles'} ) && ( ! ( $onelink->{'Styles'} =~ /\bPATCH\b/ ))) { next; }
764
765        my $target = $onelink->{'Target'};
766        my $destination = $subfolderdir . $installer::globals::separator . $onelink->{'destination'};
767
768        my $localcall = "ln -sf \'$target\' \'$destination\' \>\/dev\/null 2\>\&1";
769        system($localcall);
770
771        $infoline = "Creating Unix link: \"ln -sf $target $destination\"\n";
772        push(@installer::globals::logfileinfo, $infoline);
773    }
774
775    # Setting privileges for cygwin globally
776
777    if ( $^O =~ /cygwin/i )
778    {
779        installer::logger::print_message( "... changing privileges in $subfolderdir ...\n" );
780        installer::logger::include_header_into_logfile("Changing privileges in $subfolderdir:");
781
782        my $localcall = "chmod -R 755 " . "\"" . $subfolderdir . "\"";
783        system($localcall);
784    }
785
786    installer::logger::print_message( "... removing superfluous directories ...\n" );
787    installer::logger::include_header_into_logfile("Removing superfluous directories:");
788
789    my ( $extensionfolder, $preregdir ) = get_extensions_dir($subfolderdir);
790    installer::systemactions::remove_empty_dirs_in_folder($extensionfolder);
791
792    # Registering the extensions
793
794    installer::logger::print_message( "... registering extensions ...\n" );
795    installer::logger::include_header_into_logfile("Registering extensions:");
796    register_extensions($subfolderdir, $languagestringref, $preregdir);
797
798    if ( $installer::globals::compiler =~ /^unxmacx/ )
799    {
800        installer::worker::put_scpactions_into_installset("$installdir/$packagename");
801    }
802
803    # Creating archive file
804    if ( $installer::globals::packageformat eq "archive" )
805    {
806        create_package($tempinstalldir, $installdir, $packagename, $allvariables, $includepatharrayref, $languagestringref, $installer::globals::archiveformat);
807    }
808    elsif ( $installer::globals::packageformat eq "dmg" )
809    {
810        create_package($installdir, $installdir, $packagename, $allvariables, $includepatharrayref, $languagestringref, ".dmg");
811    }
812
813    # Analyzing the log file
814
815    installer::worker::clean_output_tree(); # removing directories created in the output tree
816    installer::worker::analyze_and_save_logfile($loggingdir, $installdir, $installlogdir, $allsettingsarrayref, $languagestringref, $current_install_number);
817}
818
8191;
820