cid#1606940 Check of thread-shared field evades lock acquisition
[LibreOffice.git] / solenv / bin / modules / installer / simplepackage.pm
bloba8b98a222e5fb5521f79a49c89d301270dc983f4
2 # This file is part of the LibreOffice project.
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/.
8 # This file incorporates work covered by the following license notice:
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 .
19 package installer::simplepackage;
21 use strict;
22 use warnings;
24 use Cwd;
25 use File::Copy;
26 use installer::download;
27 use installer::exiter;
28 use installer::globals;
29 use installer::logger;
30 use installer::strip qw(strip_libraries);
31 use installer::systemactions;
32 use installer::worker;
34 ####################################################
35 # Checking if the simple packager is required.
36 # This can be achieved by setting the global
37 # variable SIMPLE_PACKAGE in *.lst file or by
38 # setting the environment variable SIMPLE_PACKAGE.
39 ####################################################
41 sub check_simple_packager_project
43 my ( $allvariables ) = @_;
45 if ( $installer::globals::packageformat eq "installed" )
47 $installer::globals::is_simple_packager_project = 1;
48 $installer::globals::patch_user_dir = 1;
50 elsif(( $installer::globals::packageformat eq "archive" ) ||
51 ( $installer::globals::packageformat eq "dmg" ) )
53 $installer::globals::is_simple_packager_project = 1;
57 ####################################################
58 # Detecting the directory with extensions
59 ####################################################
61 sub get_extensions_dir
63 my ( $subfolderdir ) = @_;
65 my $extensiondir = $subfolderdir . $installer::globals::separator;
66 if ( $installer::globals::officedirhostname ne "" ) { $extensiondir = $extensiondir . $installer::globals::officedirhostname . $installer::globals::separator; }
67 my $extensionsdir = $extensiondir . "share" . $installer::globals::separator . "extensions";
69 return $extensionsdir;
72 ##################################################################
73 # Collecting all identifier from ulf file
74 ##################################################################
76 sub get_identifier
78 my ( $translationfile ) = @_;
80 my @identifier = ();
82 for ( my $i = 0; $i <= $#{$translationfile}; $i++ )
84 my $oneline = ${$translationfile}[$i];
86 if ( $oneline =~ /^\s*\[(.+)\]\s*$/ )
88 my $identifier = $1;
89 push(@identifier, $identifier);
93 return \@identifier;
96 ##############################################################
97 # Returning the complete block in all languages
98 # for a specified string
99 ##############################################################
101 sub get_language_block_from_language_file
103 my ($searchstring, $languagefile) = @_;
105 my @language_block = ();
107 for ( my $i = 0; $i <= $#{$languagefile}; $i++ )
109 if ( ${$languagefile}[$i] =~ /^\s*\[\s*$searchstring\s*\]\s*$/ )
111 my $counter = $i;
113 push(@language_block, ${$languagefile}[$counter]);
114 $counter++;
116 while (( $counter <= $#{$languagefile} ) && (!( ${$languagefile}[$counter] =~ /^\s*\[/ )))
118 push(@language_block, ${$languagefile}[$counter]);
119 $counter++;
122 last;
126 return \@language_block;
129 ##############################################################
130 # Returning a specific language string from the block
131 # of all translations
132 ##############################################################
134 sub get_language_string_from_language_block
136 my ($language_block, $language) = @_;
138 my $newstring = "";
140 for ( my $i = 0; $i <= $#{$language_block}; $i++ )
142 if ( ${$language_block}[$i] =~ /^\s*$language\s*\=\s*\"(.*)\"\s*$/ )
144 $newstring = $1;
145 last;
149 if ( $newstring eq "" )
151 $language = "en-US"; # defaulting to english
153 for ( my $i = 0; $i <= $#{$language_block}; $i++ )
155 if ( ${$language_block}[$i] =~ /^\s*$language\s*\=\s*\"(.*)\"\s*$/ )
157 $newstring = $1;
158 last;
163 return $newstring;
166 ########################################################################
167 # Localizing the script for the Mac Language Pack installer
168 ########################################################################
170 sub localize_scriptfile
172 my ($scriptfile, $translationfile, $languagestringref) = @_;
174 my $onelanguage = $$languagestringref;
175 if ( $onelanguage =~ /^\s*(.*?)_/ ) { $onelanguage = $1; }
177 # Analyzing the ulf file, collecting all Identifier
178 my $allidentifier = get_identifier($translationfile);
180 for ( my $i = 0; $i <= $#{$allidentifier}; $i++ )
182 my $identifier = ${$allidentifier}[$i];
183 my $language_block = get_language_block_from_language_file($identifier, $translationfile);
184 my $newstring = get_language_string_from_language_block($language_block, $onelanguage);
186 # removing mask
187 $newstring =~ s/\\\'/\'/g;
189 replace_one_variable_in_shellscript($scriptfile, $newstring, $identifier);
193 #################################################################################
194 # Replacing one variable in Mac shell script
195 #################################################################################
197 sub replace_one_variable_in_shellscript
199 my ($scriptfile, $variable, $searchstring) = @_;
201 for ( my $i = 0; $i <= $#{$scriptfile}; $i++ )
203 ${$scriptfile}[$i] =~ s/\[$searchstring\]/$variable/g;
207 #############################################
208 # Replacing variables in Mac shell script
209 #############################################
211 sub replace_variables_in_scriptfile
213 my ($scriptfile, $volume_name, $volume_name_app, $allvariables) = @_;
215 replace_one_variable_in_shellscript($scriptfile, $volume_name, "FULLPRODUCTNAME" );
216 replace_one_variable_in_shellscript($scriptfile, $volume_name_app, "FULLAPPPRODUCTNAME" );
217 replace_one_variable_in_shellscript($scriptfile, $allvariables->{'PRODUCTNAME'}, "PRODUCTNAME" );
218 replace_one_variable_in_shellscript($scriptfile, $allvariables->{'PRODUCTVERSION'}, "PRODUCTVERSION" );
220 my $scriptname = $allvariables->{'BUNDLEIDENTIFIER'};
222 replace_one_variable_in_shellscript($scriptfile, $scriptname, "SEARCHSCRIPTNAME" );
225 #############################################
226 # Creating the "simple" package.
227 # "zip" for Windows
228 # "tar.gz" for all other platforms
229 # additionally "dmg" on macOS
230 #############################################
232 sub create_package
234 my ( $installdir, $archivedir, $packagename, $allvariables, $includepatharrayref, $languagestringref, $format ) = @_;
236 installer::logger::print_message( "... creating $installer::globals::packageformat file ...\n" );
237 installer::logger::include_header_into_logfile("Creating $installer::globals::packageformat file:");
239 # moving dir into temporary directory
240 my $pid = $$; # process id
241 my $tempdir = $installdir . "_temp" . "." . $pid;
242 my $systemcall = "";
243 my $from = "";
244 my $makesystemcall = 1;
245 my $return_to_start = 0;
246 installer::systemactions::rename_directory($installdir, $tempdir);
248 # creating new directory with original name
249 installer::systemactions::create_directory($archivedir);
251 my $archive = $archivedir . $installer::globals::separator . $packagename . $format;
253 if ( $archive =~ /zip$/ )
255 $from = cwd();
256 $return_to_start = 1;
257 chdir($tempdir);
258 $systemcall = "$installer::globals::zippath -qr $archive .";
260 # Using Archive::Zip fails because of very long path names below "share/uno_packages/cache"
261 # my $packzip = Archive::Zip->new();
262 # $packzip->addTree("."); # after changing into $tempdir
263 # $packzip->writeToFileNamed($archive);
264 # $makesystemcall = 0;
266 elsif ( $archive =~ /dmg$/ )
268 my $folder = (( -l "$tempdir/$packagename/Applications" ) or ( -l "$tempdir/$packagename/opt" )) ? $packagename : "\.";
270 if ( $allvariables->{'PACK_INSTALLED'} ) {
271 $folder = $packagename;
274 my $volume_name = $allvariables->{'PRODUCTNAME'};
275 my $volume_name_classic = $allvariables->{'PRODUCTNAME'} . ' ' . $allvariables->{'PRODUCTVERSION'};
276 my $volume_name_classic_app = $volume_name; # "app" should not contain version number
277 if ( $allvariables->{'DMG_VOLUMEEXTENSION'} ) {
278 $volume_name = $volume_name . ' ' . $allvariables->{'DMG_VOLUMEEXTENSION'};
279 $volume_name_classic = $volume_name_classic . ' ' . $allvariables->{'DMG_VOLUMEEXTENSION'};
280 $volume_name_classic_app = $volume_name_classic_app . ' ' . $allvariables->{'DMG_VOLUMEEXTENSION'};
283 my $sla = 'sla.r';
284 my $ref = "";
286 if ( ! $allvariables->{'HIDELICENSEDIALOG'} )
288 installer::scriptitems::get_sourcepath_from_filename_and_includepath( \$sla, $includepatharrayref, 0);
291 my $localtempdir = $tempdir;
293 if (( $installer::globals::languagepack ) || ( $installer::globals::helppack ))
295 # LanguagePack and HelpPack files are collected in $srcfolder, packaged into
296 # tarball.tar.bz2 and finally the Language Pack.app is assembled in $appfolder
297 $localtempdir = "$tempdir/$packagename";
298 my $srcfolder = $localtempdir . "/" . $volume_name_classic_app . "\.app";
300 $volume_name .= " " . $$languagestringref . " Language Pack";
301 $volume_name_classic .= " Language Pack";
302 $volume_name_classic_app .= " Language Pack";
304 my $appfolder = $localtempdir . "/" . $volume_name_classic_app . "\.app";
305 my $contentsfolder = $appfolder . "/Contents";
306 my $tarballname = "tarball.tar.bz2";
308 my $localfrom = cwd();
309 chdir $srcfolder;
311 $systemcall = "tar -cjf $tarballname Contents/";
313 print "... $systemcall ...\n";
314 my $localreturnvalue = system($systemcall);
315 my $infoline = "Systemcall: $systemcall\n";
316 push( @installer::globals::logfileinfo, $infoline);
318 if ($localreturnvalue)
320 $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
321 push( @installer::globals::logfileinfo, $infoline);
323 else
325 $infoline = "Success: Executed \"$systemcall\" successfully!\n";
326 push( @installer::globals::logfileinfo, $infoline);
329 my $sourcefile = $srcfolder . "/" . $tarballname;
330 my $destfile = $contentsfolder . "/Resources/" . $tarballname;
332 installer::systemactions::remove_complete_directory($appfolder);
333 installer::systemactions::create_directory($appfolder);
334 installer::systemactions::create_directory($contentsfolder);
335 installer::systemactions::create_directory($contentsfolder . "/Resources");
337 installer::systemactions::copy_one_file($sourcefile, $destfile);
338 installer::systemactions::remove_complete_directory($srcfolder);
340 # Copy two files into installation set next to the tar ball
341 # 1. "osx_install.applescript"
342 # 2 "OpenOffice.org Languagepack"
344 my $scriptrealfilename = "osx_install.applescript";
345 my $scriptfilename = "";
346 if ( $installer::globals::languagepack ) { $scriptfilename = "osx_install_languagepack.applescript"; }
347 if ( $installer::globals::helppack ) { $scriptfilename = "osx_install_helppack.applescript"; }
348 my $scripthelperfilename = $ENV{'SRCDIR'} . "/setup_native/scripts/mac_install.script";
349 my $scripthelperrealfilename = $volume_name_classic_app;
351 # Finding both files in source tree
353 my $scriptref = $ENV{'SRCDIR'} . "/setup_native/scripts/" . $scriptfilename;
354 if (! -f $scriptref) { installer::exiter::exit_program("ERROR: Could not find Apple script $scriptfilename ($scriptref)!", "create_package"); }
355 if (! -f $scripthelperfilename) { installer::exiter::exit_program("ERROR: Could not find Apple script $scripthelperfilename!", "create_package"); }
357 $scriptfilename = $contentsfolder . "/Resources/" . $scriptrealfilename;
358 $scripthelperrealfilename = $contentsfolder . "/" . $scripthelperrealfilename;
360 installer::systemactions::copy_one_file($scriptref, $scriptfilename);
361 installer::systemactions::copy_one_file($scripthelperfilename, $scripthelperrealfilename);
363 # Replacing variables in script $scriptfilename
364 # Localizing script $scriptfilename
365 my $scriptfilecontent = installer::files::read_file($scriptfilename);
366 my $translationfilecontent = installer::files::read_file($installer::globals::macinstallfilename);
367 localize_scriptfile($scriptfilecontent, $translationfilecontent, $languagestringref);
369 replace_variables_in_scriptfile($scriptfilecontent, $volume_name_classic, $volume_name_classic_app, $allvariables);
370 installer::files::save_file($scriptfilename, $scriptfilecontent);
372 chmod 0775, $scriptfilename;
373 chmod 0775, $scripthelperrealfilename;
375 # Copy also Info.plist and icon file
376 # Finding both files in source tree
377 my $iconfile = "ooo3_installer.icns";
378 my $iconfileref = $ENV{'SRCDIR'} . "/setup_native/source/mac/" . $iconfile;
379 if (! -f $iconfileref) { installer::exiter::exit_program("ERROR: Could not find Apple script icon file $iconfile ($iconfileref)!", "create_package"); }
380 my $subdir = $contentsfolder . "/" . "Resources";
381 if ( ! -d $subdir ) { installer::systemactions::create_directory($subdir); }
382 $destfile = $subdir . "/" . $iconfile;
383 installer::systemactions::copy_one_file($iconfileref, $destfile);
385 my $infoplistfile = $ENV{'SRCDIR'} . "/setup_native/source/mac/Info.plist.langpack";
386 if (! -f $infoplistfile) { installer::exiter::exit_program("ERROR: Could not find Apple script Info.plist: $infoplistfile!", "create_package"); }
387 $destfile = "$contentsfolder/Info.plist";
388 # Replacing variables in Info.plist
389 $scriptfilecontent = installer::files::read_file($infoplistfile);
391 replace_one_variable_in_shellscript($scriptfilecontent, $volume_name_classic_app, "FULLAPPPRODUCTNAME" ); # OpenOffice.org Language Pack
392 replace_one_variable_in_shellscript($scriptfilecontent, $ENV{'MACOSX_BUNDLE_IDENTIFIER'}, "BUNDLEIDENTIFIER" );
393 installer::files::save_file($destfile, $scriptfilecontent);
395 chdir $localfrom;
397 if ( $ENV{'MACOSX_CODESIGNING_IDENTITY'} ) {
398 my $lp_sign = "codesign --verbose --sign $ENV{'MACOSX_CODESIGNING_IDENTITY'} --deep '$appfolder'" ;
399 my $output = `$lp_sign 2>&1`;
400 unless ($?) {
401 $infoline = "Success: \"$lp_sign\" executed successfully!\n";
402 } else {
403 $infoline = "ERROR: Could not codesign the languagepack using \"$lp_sign\"!\n$output\n";
405 push( @installer::globals::logfileinfo, $infoline);
408 elsif ($volume_name_classic_app eq 'LibreOffice' || $volume_name_classic_app eq 'LibreOfficeDev')
410 my $subdir = "$tempdir/$packagename/$volume_name_classic_app.app/Contents/Resources";
411 if ( ! -d $subdir ) { installer::systemactions::create_directory($subdir); }
412 # For non-release builds where no identity is, set entitlements
413 # to allow Xcode's Instruments application to connect to the
414 # application
415 if ( $ENV{'MACOSX_CODESIGNING_IDENTITY'} || !$ENV{'ENABLE_RELEASE_BUILD'} )
417 $systemcall = "$ENV{'SRCDIR'}/solenv/bin/macosx-codesign-app-bundle $localtempdir/$folder/$volume_name_classic_app.app";
418 print "... $systemcall ...\n";
419 my $infoline = "Systemcall: $systemcall\n";
420 push( @installer::globals::logfileinfo, $infoline);
421 my $output = `$systemcall 2>&1`;
422 if ($?)
424 $infoline = "ERROR: Could not execute \"$systemcall\"!\n$output\n";
425 push( @installer::globals::logfileinfo, $infoline);
427 else
429 $infoline = "Success: Executed \"$systemcall\" successfully!\n";
430 push( @installer::globals::logfileinfo, $infoline);
434 elsif ($volume_name_classic_app eq 'LibreOffice SDK' || $volume_name_classic_app eq 'LibreOfficeDev SDK')
436 if ( $ENV{'MACOSX_CODESIGNING_IDENTITY'} )
438 my $sdkbindir = "$localtempdir/$folder/$allvariables->{'PRODUCTNAME'}$allvariables->{'PRODUCTVERSION'}_SDK/bin";
439 opendir(my $dh, $sdkbindir);
440 foreach my $sdkbinary (readdir $dh) {
441 next unless -f "$sdkbindir/$sdkbinary";
442 $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";
443 print "... $systemcall ...\n";
444 my $returnvalue = system($systemcall);
445 my $infoline = "Systemcall: $systemcall\n";
446 push( @installer::globals::logfileinfo, $infoline);
448 if ($returnvalue)
450 $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
451 push( @installer::globals::logfileinfo, $infoline);
453 else
455 $infoline = "Success: Executed \"$systemcall\" successfully!\n";
456 push( @installer::globals::logfileinfo, $infoline);
457 unlink "/tmp/codesign_losdk_$sdkbinary.log";
460 closedir($dh);
463 my $megabytes = 1500;
464 $megabytes = 3000 if $ENV{'ENABLE_DEBUG'};
466 # tdf#151341 Use lzfse compression instead of bzip2
467 # Several users reported that copying the LibreOffice.app package
468 # in the Finder from a .dmg file compressed with lzfse compression
469 # copies the package several times faster than from a .dmg compressed
470 # with bzip2 compression.
471 # On a mid-2015 Intel MacBook Pro running macOS, copying in the Finder
472 # was at least 5 times faster with lzfse than with bzip2. Also, the
473 # hdiutil man page as of macOS Monterey 12.6.2 has marked bzip2 as
474 # deprecated. lzfse is marked as supported since macOS El Capitan 10.11
475 # so this change appears safe.
476 # The one thing that bzip2 has is better compression so a .dmg with
477 # bzip2 should be smaller than with lzfse. A .dmg built from a debug
478 # build was 262M with bzip2 and 273MB for lzfse. So it appears that
479 # lzfse creates .dmg files that are only 4% or 5% larger than bzip2.
480 $systemcall = "cd $localtempdir && hdiutil create -megabytes $megabytes -srcfolder $folder $archive -ov -fs HFS+ -volname \"$volume_name\" -format ULFO";
481 if (( $ref ne "" ) && ( $$ref ne "" ) && system("hdiutil 2>&1 | grep unflatten") == 0) {
482 $systemcall .= " && hdiutil unflatten $archive && Rez -a $$ref -o $archive && hdiutil flatten $archive &&";
485 else
487 # use fakeroot (only required for Solaris and Linux)
488 my $fakerootstring = "";
489 if (( $installer::globals::issolarisbuild ) || ( $installer::globals::islinuxbuild ))
491 $fakerootstring = "fakeroot";
494 $systemcall = "cd $tempdir; $fakerootstring tar -cf - . | $installer::globals::packertool > $archive";
497 if ( $makesystemcall )
499 print "... $systemcall ...\n";
500 my $systemcall_output = `$systemcall`;
501 my $returnvalue = $? >> 8;
502 my $infoline = "Systemcall: $systemcall\n";
503 push( @installer::globals::logfileinfo, $infoline);
505 if ($returnvalue)
507 $infoline = "ERROR: Could not execute \"$systemcall\" - exitcode: $returnvalue - output:\n$systemcall_output\n";
508 push( @installer::globals::logfileinfo, $infoline);
510 else
512 $infoline = "Success: Executed \"$systemcall\" successfully!\n";
513 push( @installer::globals::logfileinfo, $infoline);
517 if ( $return_to_start ) { chdir($from); }
519 print "... removing $tempdir ...\n";
520 installer::systemactions::remove_complete_directory($tempdir);
523 ####################################################
524 # Main method for creating the simple package
525 # installation sets
526 ####################################################
528 sub create_simple_package
530 my ( $filesref, $dirsref, $scpactionsref, $linksref, $unixlinksref, $loggingdir, $languagestringref, $shipinstalldir, $allsettingsarrayref, $allvariables, $includepatharrayref ) = @_;
532 # Creating directories
534 my $current_install_number = "";
535 my $infoline = "";
537 installer::logger::print_message( "... creating installation directory ...\n" );
538 installer::logger::include_header_into_logfile("Creating installation directory");
540 $installer::globals::csp_installdir = installer::worker::create_installation_directory($shipinstalldir, $languagestringref, \$current_install_number);
541 $installer::globals::csp_installlogdir = installer::systemactions::create_directory_next_to_directory($installer::globals::csp_installdir, "log");
543 my $installdir = $installer::globals::csp_installdir;
544 my $installlogdir = $installer::globals::csp_installlogdir;
546 # Setting package name (similar to the download name)
547 my $packagename = "";
549 if ( $installer::globals::packageformat eq "archive" ||
550 $installer::globals::packageformat eq "dmg" )
552 $installer::globals::csp_languagestring = $$languagestringref;
554 my $locallanguage = $installer::globals::csp_languagestring;
556 $packagename = installer::download::set_download_filename(\$locallanguage, $allvariables);
559 # Work around Windows problems with long pathnames (see issue 50885) by
560 # putting the to-be-archived installation tree into the temp directory
561 # instead of the module output tree (unless LOCALINSTALLDIR dictates
562 # otherwise, anyway); can be removed once issue 50885 is fixed:
563 my $tempinstalldir = $installdir;
564 if ( $installer::globals::iswindowsbuild &&
565 $installer::globals::packageformat eq "archive" &&
566 !$installer::globals::localinstalldirset )
568 $tempinstalldir = File::Temp::tempdir;
571 # Creating subfolder in installdir, which shall become the root of package or zip file
572 my $subfolderdir = "";
573 if ( $packagename ne "" ) { $subfolderdir = $tempinstalldir . $installer::globals::separator . $packagename; }
574 else { $subfolderdir = $tempinstalldir; }
576 if ( ! -d $subfolderdir ) { installer::systemactions::create_directory($subfolderdir); }
578 # Create directories, copy files and ScpActions
580 installer::logger::print_message( "... creating directories ...\n" );
581 installer::logger::include_header_into_logfile("Creating directories:");
583 for ( my $i = 0; $i <= $#{$dirsref}; $i++ )
585 my $onedir = ${$dirsref}[$i];
587 if ( $onedir->{'HostName'} )
589 my $destdir = $subfolderdir . $installer::globals::separator . $onedir->{'HostName'};
591 if ( ! -d $destdir )
593 if ( $^O =~ /cygwin/i ) # Cygwin performance check
595 $infoline = "Try to create directory $destdir\n";
596 push(@installer::globals::logfileinfo, $infoline);
597 # Directories in $dirsref are sorted and all parents were added -> "mkdir" works without parent creation!
598 if ( ! ( -d $destdir )) { mkdir($destdir, 0775); }
600 else
602 installer::systemactions::create_directory_structure($destdir);
608 # stripping files ?!
609 if (( $installer::globals::strip ) && ( ! $installer::globals::iswindowsbuild )) { strip_libraries($filesref, $languagestringref); }
611 # copy Files
612 installer::logger::print_message( "... copying files ...\n" );
613 installer::logger::include_header_into_logfile("Copying files:");
615 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
617 my $onefile = ${$filesref}[$i];
619 if (( $onefile->{'Styles'} ) && ( $onefile->{'Styles'} =~ /\bBINARYTABLE_ONLY\b/ )) { next; }
621 my $source = $onefile->{'sourcepath'};
622 my $destination = $onefile->{'destination'};
623 $destination = $subfolderdir . $installer::globals::separator . $destination;
625 # Replacing $$ by $ is necessary to install files with $ in its name (back-masquerading)
626 # Otherwise, the following shell command does not work and the file list is not correct
627 $source =~ s/\$\$/\$/;
628 $destination =~ s/\$\$/\$/;
630 if ( $^O =~ /cygwin/i ) # Cygwin performance, do not use copy_one_file. "chmod -R" at the end
632 my $copyreturn = copy($source, $destination);
634 if ($copyreturn)
636 $infoline = "Copy: $source to $destination\n";
638 else
640 $infoline = "ERROR: Could not copy $source to $destination $!\n";
643 push(@installer::globals::logfileinfo, $infoline);
645 else
647 installer::systemactions::copy_one_file($source, $destination);
649 if ( ! $installer::globals::iswindowsbuild )
651 # see issue 102274
652 if ( $onefile->{'UnixRights'} )
654 if ( ! -l $destination ) # that would be rather pointless
656 chmod oct($onefile->{'UnixRights'}), $destination;
663 # creating Links
665 installer::logger::print_message( "... creating links ...\n" );
666 installer::logger::include_header_into_logfile("Creating links:");
668 for ( my $i = 0; $i <= $#{$linksref}; $i++ )
670 my $onelink = ${$linksref}[$i];
672 my $destination = $onelink->{'destination'};
673 $destination = $subfolderdir . $installer::globals::separator . $destination;
674 my $destinationfile = $onelink->{'destinationfile'};
676 my $localcall = "ln -sf \'$destinationfile\' \'$destination\' \>\/dev\/null 2\>\&1";
677 system($localcall);
679 $infoline = "Creating link: \"ln -sf $destinationfile $destination\"\n";
680 push(@installer::globals::logfileinfo, $infoline);
683 for ( my $i = 0; $i <= $#{$unixlinksref}; $i++ )
685 my $onelink = ${$unixlinksref}[$i];
687 my $target = $onelink->{'Target'};
688 my $destination = $subfolderdir . $installer::globals::separator . $onelink->{'destination'};
690 my @localcall = ('ln', '-sf', $target, $destination);
691 system(@localcall) == 0 or die "system @localcall failed: $?";
693 $infoline = "Creating Unix link: \"@localcall\"\n";
694 push(@installer::globals::logfileinfo, $infoline);
697 # Setting privileges for cygwin globally
699 if ( $^O =~ /cygwin/i )
701 installer::logger::print_message( "... changing privileges in $subfolderdir ...\n" );
702 installer::logger::include_header_into_logfile("Changing privileges in $subfolderdir:");
704 my $localcall = "chmod -R 755 " . "\"" . $subfolderdir . "\"";
705 system($localcall);
708 installer::logger::print_message( "... removing superfluous directories ...\n" );
709 installer::logger::include_header_into_logfile("Removing superfluous directories:");
711 my $extensionfolder = get_extensions_dir($subfolderdir);
712 installer::systemactions::remove_empty_dirs_in_folder($extensionfolder);
714 if ( $installer::globals::ismacbuild )
716 installer::worker::put_scpactions_into_installset("$installdir/$packagename");
719 # Creating archive file
720 if ( $installer::globals::packageformat eq "archive" )
722 create_package($tempinstalldir, $installdir, $packagename, $allvariables, $includepatharrayref, $languagestringref, $installer::globals::archiveformat);
724 elsif ( $installer::globals::packageformat eq "dmg" )
726 create_package($installdir, $installdir, $packagename, $allvariables, $includepatharrayref, $languagestringref, ".dmg");
729 # Analyzing the log file
731 installer::worker::clean_output_tree(); # removing directories created in the output tree
732 installer::worker::analyze_and_save_logfile($loggingdir, $installdir, $installlogdir, $allsettingsarrayref, $languagestringref, $current_install_number);
737 # vim: set shiftwidth=4 softtabstop=4 expandtab: