1#
2# This file is part of the LibreOffice project.
3#
4# This Source Code Form is subject to the terms of the Mozilla Public
5# License, v. 2.0. If a copy of the MPL was not distributed with this
6# file, You can obtain one at http://mozilla.org/MPL/2.0/.
7#
8# This file incorporates work covered by the following license notice:
9#
10#   Licensed to the Apache Software Foundation (ASF) under one or more
11#   contributor license agreements. See the NOTICE file distributed
12#   with this work for additional information regarding copyright
13#   ownership. The ASF licenses this file to you under the Apache
14#   License, Version 2.0 (the "License"); you may not use this file
15#   except in compliance with the License. You may obtain a copy of
16#   the License at http://www.apache.org/licenses/LICENSE-2.0 .
17#
18
19package installer::simplepackage;
20
21use Cwd;
22use File::Copy;
23use installer::download;
24use installer::exiter;
25use installer::globals;
26use installer::logger;
27use installer::strip qw(strip_libraries);
28use installer::systemactions;
29use installer::worker;
30
31####################################################
32# Checking if the simple packager is required.
33# This can be achieved by setting the global
34# variable SIMPLE_PACKAGE in *.lst file or by
35# setting the environment variable SIMPLE_PACKAGE.
36####################################################
37
38sub check_simple_packager_project
39{
40    my ( $allvariables ) = @_;
41
42    if (( $installer::globals::packageformat eq "installed" ) ||
43        ( $installer::globals::packageformat eq "archive" ))
44    {
45        $installer::globals::is_simple_packager_project = 1;
46        $installer::globals::patch_user_dir = 1;
47    }
48    elsif( $installer::globals::packageformat eq "dmg" )
49    {
50        $installer::globals::is_simple_packager_project = 1;
51    }
52}
53
54####################################################
55# Detecting the directory with extensions
56####################################################
57
58sub get_extensions_dir
59{
60    my ( $subfolderdir ) = @_;
61
62    my $extensiondir = $subfolderdir . $installer::globals::separator;
63    if ( $installer::globals::officedirhostname ne "" ) { $extensiondir = $extensiondir . $installer::globals::officedirhostname . $installer::globals::separator; }
64    my $extensionsdir = $extensiondir . "share" . $installer::globals::separator . "extensions";
65
66    return $extensionsdir;
67}
68
69##################################################################
70# Collecting all identifier from ulf file
71##################################################################
72
73sub get_identifier
74{
75    my ( $translationfile ) = @_;
76
77    my @identifier = ();
78
79    for ( my $i = 0; $i <= $#{$translationfile}; $i++ )
80    {
81        my $oneline = ${$translationfile}[$i];
82
83        if ( $oneline =~ /^\s*\[(.+)\]\s*$/ )
84        {
85            my $identifier = $1;
86            push(@identifier, $identifier);
87        }
88    }
89
90    return \@identifier;
91}
92
93##############################################################
94# Returning the complete block in all languages
95# for a specified string
96##############################################################
97
98sub get_language_block_from_language_file
99{
100    my ($searchstring, $languagefile) = @_;
101
102    my @language_block = ();
103
104    for ( my $i = 0; $i <= $#{$languagefile}; $i++ )
105    {
106        if ( ${$languagefile}[$i] =~ /^\s*\[\s*$searchstring\s*\]\s*$/ )
107        {
108            my $counter = $i;
109
110            push(@language_block, ${$languagefile}[$counter]);
111            $counter++;
112
113            while (( $counter <= $#{$languagefile} ) && (!( ${$languagefile}[$counter] =~ /^\s*\[/ )))
114            {
115                push(@language_block, ${$languagefile}[$counter]);
116                $counter++;
117            }
118
119            last;
120        }
121    }
122
123    return \@language_block;
124}
125
126##############################################################
127# Returning a specific language string from the block
128# of all translations
129##############################################################
130
131sub get_language_string_from_language_block
132{
133    my ($language_block, $language) = @_;
134
135    my $newstring = "";
136
137    for ( my $i = 0; $i <= $#{$language_block}; $i++ )
138    {
139        if ( ${$language_block}[$i] =~ /^\s*$language\s*\=\s*\"(.*)\"\s*$/ )
140        {
141            $newstring = $1;
142            last;
143        }
144    }
145
146    if ( $newstring eq "" )
147    {
148        $language = "en-US";    # defaulting to english
149
150        for ( my $i = 0; $i <= $#{$language_block}; $i++ )
151        {
152            if ( ${$language_block}[$i] =~ /^\s*$language\s*\=\s*\"(.*)\"\s*$/ )
153            {
154                $newstring = $1;
155                last;
156            }
157        }
158    }
159
160    return $newstring;
161}
162
163########################################################################
164# Localizing the script for the Mac Language Pack installer
165########################################################################
166
167sub localize_scriptfile
168{
169    my ($scriptfile, $translationfile, $languagestringref) = @_;
170
171    my $onelanguage = $$languagestringref;
172    if ( $onelanguage =~ /^\s*(.*?)_/ ) { $onelanguage = $1; }
173
174    # Analyzing the ulf file, collecting all Identifier
175    my $allidentifier = get_identifier($translationfile);
176
177    for ( my $i = 0; $i <= $#{$allidentifier}; $i++ )
178    {
179        my $identifier = ${$allidentifier}[$i];
180        my $language_block = get_language_block_from_language_file($identifier, $translationfile);
181        my $newstring = get_language_string_from_language_block($language_block, $onelanguage);
182
183        # removing mask
184        $newstring =~ s/\\\'/\'/g;
185
186        replace_one_variable_in_shellscript($scriptfile, $newstring, $identifier);
187    }
188}
189
190#################################################################################
191# Replacing one variable in Mac shell script
192#################################################################################
193
194sub replace_one_variable_in_shellscript
195{
196    my ($scriptfile, $variable, $searchstring) = @_;
197
198    for ( my $i = 0; $i <= $#{$scriptfile}; $i++ )
199    {
200        ${$scriptfile}[$i] =~ s/\[$searchstring\]/$variable/g;
201    }
202}
203
204#############################################
205# Replacing variables in Mac shell script
206#############################################
207
208sub replace_variables_in_scriptfile
209{
210    my ($scriptfile, $volume_name, $volume_name_app, $allvariables) = @_;
211
212    replace_one_variable_in_shellscript($scriptfile, $volume_name, "FULLPRODUCTNAME" );
213    replace_one_variable_in_shellscript($scriptfile, $volume_name_app, "FULLAPPPRODUCTNAME" );
214    replace_one_variable_in_shellscript($scriptfile, $allvariables->{'PRODUCTNAME'}, "PRODUCTNAME" );
215    replace_one_variable_in_shellscript($scriptfile, $allvariables->{'PRODUCTVERSION'}, "PRODUCTVERSION" );
216
217    my $scriptname = $allvariables->{'BUNDLEIDENTIFIER'};
218
219    replace_one_variable_in_shellscript($scriptfile, $scriptname, "SEARCHSCRIPTNAME" );
220}
221
222#############################################
223# Creating the "simple" package.
224# "zip" for Windows
225# "tar.gz" for all other platforms
226# additionally "dmg" on macOS
227#############################################
228
229sub create_package
230{
231    my ( $installdir, $archivedir, $packagename, $allvariables, $includepatharrayref, $languagestringref, $format ) = @_;
232
233    installer::logger::print_message( "... creating $installer::globals::packageformat file ...\n" );
234    installer::logger::include_header_into_logfile("Creating $installer::globals::packageformat file:");
235
236    # moving dir into temporary directory
237    my $pid = $$; # process id
238    my $tempdir = $installdir . "_temp" . "." . $pid;
239    my $systemcall = "";
240    my $from = "";
241    my $makesystemcall = 1;
242    my $return_to_start = 0;
243    installer::systemactions::rename_directory($installdir, $tempdir);
244
245    # creating new directory with original name
246    installer::systemactions::create_directory($archivedir);
247
248    my $archive = $archivedir . $installer::globals::separator . $packagename . $format;
249
250    if ( $archive =~ /zip$/ )
251    {
252        $from = cwd();
253        $return_to_start = 1;
254        chdir($tempdir);
255        $systemcall = "$installer::globals::zippath -qr $archive .";
256
257        # Using Archive::Zip fails because of very long path names below "share/uno_packages/cache"
258        # my $packzip = Archive::Zip->new();
259        # $packzip->addTree(".");   # after changing into $tempdir
260        # $packzip->writeToFileNamed($archive);
261        # $makesystemcall = 0;
262    }
263     elsif ( $archive =~ /dmg$/ )
264    {
265        my $folder = (( -l "$tempdir/$packagename/Applications" ) or ( -l "$tempdir/$packagename/opt" )) ? $packagename : "\.";
266
267        if ( $allvariables->{'PACK_INSTALLED'} ) {
268            $folder = $packagename;
269        }
270
271        my $volume_name = $allvariables->{'PRODUCTNAME'};
272        my $volume_name_classic = $allvariables->{'PRODUCTNAME'} . ' ' . $allvariables->{'PRODUCTVERSION'};
273        my $volume_name_classic_app = $volume_name;  # "app" should not contain version number
274        if ( $allvariables->{'DMG_VOLUMEEXTENSION'} ) {
275            $volume_name = $volume_name . ' ' . $allvariables->{'DMG_VOLUMEEXTENSION'};
276            $volume_name_classic = $volume_name_classic . ' ' . $allvariables->{'DMG_VOLUMEEXTENSION'};
277            $volume_name_classic_app = $volume_name_classic_app . ' ' . $allvariables->{'DMG_VOLUMEEXTENSION'};
278        }
279
280        my $sla = 'sla.r';
281        my $ref = "";
282
283        if ( ! $allvariables->{'HIDELICENSEDIALOG'} )
284        {
285            installer::scriptitems::get_sourcepath_from_filename_and_includepath( \$sla, $includepatharrayref, 0);
286        }
287
288        my $localtempdir = $tempdir;
289
290        if (( $installer::globals::languagepack ) || ( $installer::globals::helppack ))
291        {
292            # LanguagePack and HelpPack files are collected in $srcfolder, packaged into
293            # tarball.tar.bz2 and finally the Language Pack.app is assembled in $appfolder
294            $localtempdir = "$tempdir/$packagename";
295            my $srcfolder = $localtempdir . "/" . $volume_name_classic_app . "\.app";
296
297            $volume_name             .= " " . $$languagestringref . " Language Pack";
298            $volume_name_classic     .= " Language Pack";
299            $volume_name_classic_app .= " Language Pack";
300
301            my $appfolder = $localtempdir . "/" . $volume_name_classic_app . "\.app";
302            my $contentsfolder = $appfolder . "/Contents";
303            my $tarballname = "tarball.tar.bz2";
304
305            my $localfrom = cwd();
306            chdir $srcfolder;
307
308            $systemcall = "tar -cjf $tarballname Contents/";
309
310            print "... $systemcall ...\n";
311            my $localreturnvalue = system($systemcall);
312            $infoline = "Systemcall: $systemcall\n";
313            push( @installer::globals::logfileinfo, $infoline);
314
315            if ($localreturnvalue)
316            {
317                $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
318                push( @installer::globals::logfileinfo, $infoline);
319            }
320            else
321            {
322                $infoline = "Success: Executed \"$systemcall\" successfully!\n";
323                push( @installer::globals::logfileinfo, $infoline);
324            }
325
326            my $sourcefile = $srcfolder . "/" . $tarballname;
327            my $destfile = $contentsfolder . "/Resources/" . $tarballname;
328
329            installer::systemactions::remove_complete_directory($appfolder);
330            installer::systemactions::create_directory($appfolder);
331            installer::systemactions::create_directory($contentsfolder);
332            installer::systemactions::create_directory($contentsfolder . "/Resources");
333
334            installer::systemactions::copy_one_file($sourcefile, $destfile);
335            installer::systemactions::remove_complete_directory($srcfolder);
336
337            # Copy two files into installation set next to the tar ball
338            # 1. "osx_install.applescript"
339            # 2 "OpenOffice.org Languagepack"
340
341            my $scriptrealfilename = "osx_install.applescript";
342            my $scriptfilename = "";
343            if ( $installer::globals::languagepack ) { $scriptfilename = "osx_install_languagepack.applescript"; }
344            if ( $installer::globals::helppack ) { $scriptfilename = "osx_install_helppack.applescript"; }
345            my $scripthelperfilename = $ENV{'SRCDIR'} . "/setup_native/scripts/mac_install.script";
346            my $scripthelperrealfilename = $volume_name_classic_app;
347
348            # Finding both files in source tree
349
350            my $scriptref = $ENV{'SRCDIR'} . "/setup_native/scripts/" . $scriptfilename;
351            if (! -f $scriptref) { installer::exiter::exit_program("ERROR: Could not find Apple script $scriptfilename ($scriptref)!", "create_package"); }
352            if (! -f $scripthelperfilename) { installer::exiter::exit_program("ERROR: Could not find Apple script $scripthelperfilename!", "create_package"); }
353
354            $scriptfilename = $contentsfolder . "/Resources/" . $scriptrealfilename;
355            $scripthelperrealfilename = $contentsfolder . "/" . $scripthelperrealfilename;
356
357            installer::systemactions::copy_one_file($scriptref, $scriptfilename);
358            installer::systemactions::copy_one_file($scripthelperfilename, $scripthelperrealfilename);
359
360            # Replacing variables in script $scriptfilename
361            # Localizing script $scriptfilename
362            my $scriptfilecontent = installer::files::read_file($scriptfilename);
363            my $translationfilecontent = installer::files::read_file($installer::globals::macinstallfilename);
364            localize_scriptfile($scriptfilecontent, $translationfilecontent, $languagestringref);
365
366            replace_variables_in_scriptfile($scriptfilecontent, $volume_name_classic, $volume_name_classic_app, $allvariables);
367            installer::files::save_file($scriptfilename, $scriptfilecontent);
368
369            chmod 0775, $scriptfilename;
370            chmod 0775, $scripthelperrealfilename;
371
372            # Copy also Info.plist and icon file
373            # Finding both files in source tree
374            my $iconfile = "ooo3_installer.icns";
375            my $iconfileref = $ENV{'SRCDIR'} . "/setup_native/source/mac/" . $iconfile;
376            if (! -f $iconfileref) { installer::exiter::exit_program("ERROR: Could not find Apple script icon file $iconfile ($iconfileref)!", "create_package"); }
377            my $subdir = $contentsfolder . "/" . "Resources";
378            if ( ! -d $subdir ) { installer::systemactions::create_directory($subdir); }
379            $destfile = $subdir . "/" . $iconfile;
380            installer::systemactions::copy_one_file($iconfileref, $destfile);
381
382            my $infoplistfile = $ENV{'SRCDIR'} . "/setup_native/source/mac/Info.plist.langpack";
383            if (! -f $infoplistfile) { installer::exiter::exit_program("ERROR: Could not find Apple script Info.plist: $infoplistfile!", "create_package"); }
384            $destfile = "$contentsfolder/Info.plist";
385            # Replacing variables in Info.plist
386            $scriptfilecontent = installer::files::read_file($infoplistfile);
387
388            replace_one_variable_in_shellscript($scriptfilecontent, $volume_name_classic_app, "FULLAPPPRODUCTNAME" ); # OpenOffice.org Language Pack
389            replace_one_variable_in_shellscript($scriptfilecontent, $ENV{'MACOSX_BUNDLE_IDENTIFIER'}, "BUNDLEIDENTIFIER" );
390            installer::files::save_file($destfile, $scriptfilecontent);
391
392            chdir $localfrom;
393
394            if ( $ENV{'MACOSX_CODESIGNING_IDENTITY'} ) {
395                my @lp_sign = ('codesign', '--verbose', '--sign', $ENV{'MACOSX_CODESIGNING_IDENTITY'}, '--deep', $appfolder);
396                if (system(@lp_sign) == 0) {
397                    $infoline = "Success: \"@lp_sign\" executed successfully!\n";
398                } else {
399                    $infoline = "ERROR: Could not codesign the languagepack using \"@lp_sign\"!\n";
400                }
401                push( @installer::globals::logfileinfo, $infoline);
402            }
403        }
404        elsif ($volume_name_classic_app eq 'LibreOffice' || $volume_name_classic_app eq 'LibreOfficeDev')
405        {
406            my $subdir = "$tempdir/$packagename/$volume_name_classic_app.app/Contents/Resources";
407            if ( ! -d $subdir ) { installer::systemactions::create_directory($subdir); }
408            if ( $ENV{'MACOSX_CODESIGNING_IDENTITY'} )
409            {
410                $systemcall = "$ENV{'SRCDIR'}/solenv/bin/macosx-codesign-app-bundle $localtempdir/$folder/$volume_name_classic_app.app";
411                print "... $systemcall ...\n";
412                $infoline = "Systemcall: $systemcall\n";
413                push( @installer::globals::logfileinfo, $infoline);
414                my $output = `$systemcall 2>&1`;
415                if ($?)
416                {
417                    $infoline = "ERROR: Could not execute \"$systemcall\"!\n$output\n";
418                    push( @installer::globals::logfileinfo, $infoline);
419                }
420                else
421                {
422                    $infoline = "Success: Executed \"$systemcall\" successfully!\n";
423                    push( @installer::globals::logfileinfo, $infoline);
424                }
425            }
426        }
427        elsif ($volume_name_classic_app eq 'LibreOffice SDK' || $volume_name_classic_app eq 'LibreOfficeDev SDK')
428        {
429            if ( $ENV{'MACOSX_CODESIGNING_IDENTITY'} )
430            {
431                my $sdkbindir = "$localtempdir/$folder/$allvariables->{'PRODUCTNAME'}$allvariables->{'PRODUCTVERSION'}_SDK/bin";
432                opendir(my $dh, $sdkbindir);
433                foreach my $sdkbinary (readdir $dh) {
434                    next unless -f "$sdkbindir/$sdkbinary";
435                    $systemcall = "codesign --force --verbose --options=runtime --identifier='$ENV{MACOSX_BUNDLE_IDENTIFIER}.$sdkbinary' --sign '$ENV{MACOSX_CODESIGNING_IDENTITY}' --entitlements $ENV{BUILDDIR}/hardened_runtime.xcent $sdkbindir/$sdkbinary > /tmp/codesign_losdk_$sdkbinary.log 2>&1";
436                    print "... $systemcall ...\n";
437                    my $returnvalue = system($systemcall);
438                    $infoline = "Systemcall: $systemcall\n";
439                    push( @installer::globals::logfileinfo, $infoline);
440
441                    if ($returnvalue)
442                    {
443                        $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
444                        push( @installer::globals::logfileinfo, $infoline);
445                    }
446                    else
447                    {
448                        $infoline = "Success: Executed \"$systemcall\" successfully!\n";
449                        push( @installer::globals::logfileinfo, $infoline);
450                        unlink "/tmp/codesign_losdk_$sdkbinary.log";
451                    }
452                }
453                closedir($dh);
454            }
455        }
456        my $megabytes = 1500;
457        $megabytes = 2000 if $ENV{'ENABLE_DEBUG'};
458        $systemcall = "cd $localtempdir && hdiutil create -megabytes $megabytes -srcfolder $folder $archive -ov -fs HFS+ -volname \"$volume_name\" -format UDBZ";
459        if (( $ref ne "" ) && ( $$ref ne "" )) {
460            $systemcall .= " && hdiutil unflatten $archive && Rez -a $$ref -o $archive && hdiutil flatten $archive &&";
461        }
462    }
463    else
464    {
465        # use fakeroot (only required for Solaris and Linux)
466        my $fakerootstring = "";
467        if (( $installer::globals::issolarisbuild ) || ( $installer::globals::islinuxbuild ))
468        {
469            $fakerootstring = "fakeroot";
470        }
471
472        $systemcall = "cd $tempdir; $fakerootstring tar -cf - . | gzip > $archive";
473    }
474
475    if ( $makesystemcall )
476    {
477        print "... $systemcall ...\n";
478        my $returnvalue = system($systemcall);
479        my $infoline = "Systemcall: $systemcall\n";
480        push( @installer::globals::logfileinfo, $infoline);
481
482        if ($returnvalue)
483        {
484            $infoline = "ERROR: Could not execute \"$systemcall\": $returnvalue\n";
485            push( @installer::globals::logfileinfo, $infoline);
486        }
487        else
488        {
489            $infoline = "Success: Executed \"$systemcall\" successfully!\n";
490            push( @installer::globals::logfileinfo, $infoline);
491        }
492    }
493
494    if ( $return_to_start ) { chdir($from); }
495
496    print "... removing $tempdir ...\n";
497    installer::systemactions::remove_complete_directory($tempdir);
498}
499
500####################################################
501# Main method for creating the simple package
502# installation sets
503####################################################
504
505sub create_simple_package
506{
507    my ( $filesref, $dirsref, $scpactionsref, $linksref, $unixlinksref, $loggingdir, $languagestringref, $shipinstalldir, $allsettingsarrayref, $allvariables, $includepatharrayref ) = @_;
508
509    # Creating directories
510
511    my $current_install_number = "";
512    my $infoline = "";
513
514    installer::logger::print_message( "... creating installation directory ...\n" );
515    installer::logger::include_header_into_logfile("Creating installation directory");
516
517    $installer::globals::csp_installdir = installer::worker::create_installation_directory($shipinstalldir, $languagestringref, \$current_install_number);
518    $installer::globals::csp_installlogdir = installer::systemactions::create_directory_next_to_directory($installer::globals::csp_installdir, "log");
519
520    my $installdir = $installer::globals::csp_installdir;
521    my $installlogdir = $installer::globals::csp_installlogdir;
522
523    # Setting package name (similar to the download name)
524    my $packagename = "";
525
526    if ( $installer::globals::packageformat eq "archive"  ||
527        $installer::globals::packageformat eq "dmg" )
528    {
529        $installer::globals::csp_languagestring = $$languagestringref;
530
531        my $locallanguage = $installer::globals::csp_languagestring;
532
533        $packagename = installer::download::set_download_filename(\$locallanguage, $allvariables);
534    }
535
536    # Work around Windows problems with long pathnames (see issue 50885) by
537    # putting the to-be-archived installation tree into the temp directory
538    # instead of the module output tree (unless LOCALINSTALLDIR dictates
539    # otherwise, anyway); can be removed once issue 50885 is fixed:
540    my $tempinstalldir = $installdir;
541    if ( $installer::globals::iswindowsbuild &&
542         $installer::globals::packageformat eq "archive" &&
543         !$installer::globals::localinstalldirset )
544    {
545        $tempinstalldir = File::Temp::tempdir;
546    }
547
548    # Creating subfolder in installdir, which shall become the root of package or zip file
549    my $subfolderdir = "";
550    if ( $packagename ne "" ) { $subfolderdir = $tempinstalldir . $installer::globals::separator . $packagename; }
551    else { $subfolderdir = $tempinstalldir; }
552
553    if ( ! -d $subfolderdir ) { installer::systemactions::create_directory($subfolderdir); }
554
555    # Create directories, copy files and ScpActions
556
557    installer::logger::print_message( "... creating directories ...\n" );
558    installer::logger::include_header_into_logfile("Creating directories:");
559
560    for ( my $i = 0; $i <= $#{$dirsref}; $i++ )
561    {
562        my $onedir = ${$dirsref}[$i];
563
564        if ( $onedir->{'HostName'} )
565        {
566            my $destdir = $subfolderdir . $installer::globals::separator . $onedir->{'HostName'};
567
568            if ( ! -d $destdir )
569            {
570                if ( $^O =~ /cygwin/i ) # Cygwin performance check
571                {
572                    $infoline = "Try to create directory $destdir\n";
573                    push(@installer::globals::logfileinfo, $infoline);
574                    # Directories in $dirsref are sorted and all parents were added -> "mkdir" works without parent creation!
575                    if ( ! ( -d $destdir )) { mkdir($destdir, 0775); }
576                }
577                else
578                {
579                    installer::systemactions::create_directory_structure($destdir);
580                }
581            }
582        }
583    }
584
585    # stripping files ?!
586    if (( $installer::globals::strip ) && ( ! $installer::globals::iswindowsbuild )) { strip_libraries($filesref, $languagestringref); }
587
588    # copy Files
589    installer::logger::print_message( "... copying files ...\n" );
590    installer::logger::include_header_into_logfile("Copying files:");
591
592    for ( my $i = 0; $i <= $#{$filesref}; $i++ )
593    {
594        my $onefile = ${$filesref}[$i];
595
596        if (( $onefile->{'Styles'} ) && ( $onefile->{'Styles'} =~ /\bBINARYTABLE_ONLY\b/ )) { next; }
597
598        my $source = $onefile->{'sourcepath'};
599        my $destination = $onefile->{'destination'};
600        $destination = $subfolderdir . $installer::globals::separator . $destination;
601
602        # Replacing $$ by $ is necessary to install files with $ in its name (back-masquerading)
603        # Otherwise, the following shell command does not work and the file list is not correct
604        $source =~ s/\$\$/\$/;
605        $destination =~ s/\$\$/\$/;
606
607        if ( $^O =~ /cygwin/i ) # Cygwin performance, do not use copy_one_file. "chmod -R" at the end
608        {
609            my $copyreturn = copy($source, $destination);
610
611            if ($copyreturn)
612            {
613                $infoline = "Copy: $source to $destination\n";
614                $returnvalue = 1;
615            }
616            else
617            {
618                $infoline = "ERROR: Could not copy $source to $destination $!\n";
619                $returnvalue = 0;
620            }
621
622            push(@installer::globals::logfileinfo, $infoline);
623        }
624        else
625        {
626            installer::systemactions::copy_one_file($source, $destination);
627
628            if ( ! $installer::globals::iswindowsbuild )
629            {
630                # see issue 102274
631                if ( $onefile->{'UnixRights'} )
632                {
633                    if ( ! -l $destination ) # that would be rather pointless
634                    {
635                        chmod oct($onefile->{'UnixRights'}), $destination;
636                    }
637                }
638            }
639        }
640    }
641
642    # creating Links
643
644    installer::logger::print_message( "... creating links ...\n" );
645    installer::logger::include_header_into_logfile("Creating links:");
646
647    for ( my $i = 0; $i <= $#{$linksref}; $i++ )
648    {
649        my $onelink = ${$linksref}[$i];
650
651        my $destination = $onelink->{'destination'};
652        $destination = $subfolderdir . $installer::globals::separator . $destination;
653        my $destinationfile = $onelink->{'destinationfile'};
654
655        my $localcall = "ln -sf \'$destinationfile\' \'$destination\' \>\/dev\/null 2\>\&1";
656        system($localcall);
657
658        $infoline = "Creating link: \"ln -sf $destinationfile $destination\"\n";
659        push(@installer::globals::logfileinfo, $infoline);
660    }
661
662    for ( my $i = 0; $i <= $#{$unixlinksref}; $i++ )
663    {
664        my $onelink = ${$unixlinksref}[$i];
665
666        my $target = $onelink->{'Target'};
667        my $destination = $subfolderdir . $installer::globals::separator . $onelink->{'destination'};
668
669        my @localcall = ('ln', '-sf', $target, $destination);
670        system(@localcall) == 0 or die "system @localcall failed: $?";
671
672        $infoline = "Creating Unix link: \"@localcall\"\n";
673        push(@installer::globals::logfileinfo, $infoline);
674    }
675
676    # Setting privileges for cygwin globally
677
678    if ( $^O =~ /cygwin/i )
679    {
680        installer::logger::print_message( "... changing privileges in $subfolderdir ...\n" );
681        installer::logger::include_header_into_logfile("Changing privileges in $subfolderdir:");
682
683        my $localcall = "chmod -R 755 " . "\"" . $subfolderdir . "\"";
684        system($localcall);
685    }
686
687    installer::logger::print_message( "... removing superfluous directories ...\n" );
688    installer::logger::include_header_into_logfile("Removing superfluous directories:");
689
690    my $extensionfolder = get_extensions_dir($subfolderdir);
691    installer::systemactions::remove_empty_dirs_in_folder($extensionfolder);
692
693    if ( $installer::globals::ismacbuild )
694    {
695        installer::worker::put_scpactions_into_installset("$installdir/$packagename");
696    }
697
698    # Creating archive file
699    if ( $installer::globals::packageformat eq "archive" )
700    {
701        create_package($tempinstalldir, $installdir, $packagename, $allvariables, $includepatharrayref, $languagestringref, $installer::globals::archiveformat);
702    }
703    elsif ( $installer::globals::packageformat eq "dmg" )
704    {
705        create_package($installdir, $installdir, $packagename, $allvariables, $includepatharrayref, $languagestringref, ".dmg");
706    }
707
708    # Analyzing the log file
709
710    installer::worker::clean_output_tree(); # removing directories created in the output tree
711    installer::worker::analyze_and_save_logfile($loggingdir, $installdir, $installlogdir, $allsettingsarrayref, $languagestringref, $current_install_number);
712}
713
7141;
715
716# vim: set shiftwidth=4 softtabstop=4 expandtab:
717